Skip to content

Commit

Permalink
Merge pull request PLC-lang#785 from PLC-lang/784-binary-expression-w…
Browse files Browse the repository at this point in the history
…ith-dword-resolves-to-dint

PLC-lang#784 binary expression with bit types resolve correctly
  • Loading branch information
99NIMI authored Feb 21, 2023
2 parents 543ef45 + 39970ab commit d2772eb
Show file tree
Hide file tree
Showing 5 changed files with 30 additions and 4 deletions.
4 changes: 4 additions & 0 deletions src/ast.rs
Original file line number Diff line number Diff line change
Expand Up @@ -160,6 +160,10 @@ impl TypeNature {
pub fn is_real(&self) -> bool {
self.derives(TypeNature::Real)
}

pub fn is_bit(&self) -> bool {
self.derives(TypeNature::Bit)
}
}

impl DirectAccessType {
Expand Down
8 changes: 6 additions & 2 deletions src/resolver.rs
Original file line number Diff line number Diff line change
Expand Up @@ -898,10 +898,14 @@ impl<'i> TypeAnnotator<'i> {
let bigger_type = if l_intrinsic_type.is_bool() && r_intrinsic_type.is_bool() {
left_type
} else {
let dint = self.index.get_type_or_panic(DINT_TYPE);
let ty = if left_type.is_bit() && right_type.is_bit() {
right_type
} else {
self.index.get_type_or_panic(DINT_TYPE)
};
get_bigger_type(
get_bigger_type(left_type, right_type, self.index),
dint,
ty,
self.index,
)
};
Expand Down
4 changes: 2 additions & 2 deletions src/resolver/tests/resolve_expressions_tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -557,7 +557,7 @@ fn resolve_binary_expressions() {
let statements = &unit.implementations[0].statements;

let expected_types = vec![
"DINT", "DINT", "DINT", "LWORD", "DINT", "DINT", "DINT", "DINT", "DINT", "DINT", "LINT", "ULINT",
"BYTE", "WORD", "DWORD", "LWORD", "DINT", "DINT", "DINT", "DINT", "DINT", "DINT", "LINT", "ULINT",
];
let type_names: Vec<&str> =
statements.iter().map(|s| annotations.get_type_or_void(s, &index).get_name()).collect();
Expand Down Expand Up @@ -805,7 +805,7 @@ fn qualified_expressions_resolve_types() {
let (annotations, _) = TypeAnnotator::visit_unit(&index, &unit, id_provider);
let statements = &unit.implementations[1].statements;

let expected_types = vec!["BYTE", "WORD", "DWORD", "LWORD", "DINT", "DINT", "LWORD"];
let expected_types = vec!["BYTE", "WORD", "DWORD", "LWORD", "WORD", "DWORD", "LWORD"];
let type_names: Vec<&str> =
statements.iter().map(|s| annotations.get_type_or_void(s, &index).get_name()).collect();

Expand Down
4 changes: 4 additions & 0 deletions src/typesystem.rs
Original file line number Diff line number Diff line change
Expand Up @@ -138,6 +138,10 @@ impl DataType {
self.nature.is_real()
}

pub fn is_bit(&self) -> bool {
self.nature.is_bit()
}

/// returns true if this type is an internal, auto-generated type
pub fn is_internal(&self) -> bool {
self.location.is_internal()
Expand Down
14 changes: 14 additions & 0 deletions src/validation/tests/generic_validation_tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1118,6 +1118,20 @@ fn any_bit_allows_bits() {
FUNCTION func3 : INT VAR x : WORD; END_VAR test(x); END_FUNCTION
FUNCTION func4 : INT VAR x : DWORD; END_VAR test(x); END_FUNCTION
FUNCTION func5 : INT VAR x : LWORD; END_VAR test(x); END_FUNCTION
// binary expressions
FUNCTION func6 : INT
VAR
a : BOOL;
b : BYTE;
c : WORD;
d : DWORD;
e : LWORD;
END_VAR
test(a + b);
test(d - c);
test(d * d);
test(b + e);
END_FUNCTION
";

let diagnostics = parse_and_validate(src);
Expand Down

0 comments on commit d2772eb

Please sign in to comment.