Skip to content

Commit

Permalink
Add support for aggregates in relations in pyrflx
Browse files Browse the repository at this point in the history
Ref. #964
  • Loading branch information
rssen committed Mar 31, 2022
1 parent f81d80f commit f3cd449
Show file tree
Hide file tree
Showing 5 changed files with 62 additions and 1 deletion.
2 changes: 2 additions & 0 deletions rflx/expression.py
Original file line number Diff line number Diff line change
Expand Up @@ -1712,6 +1712,8 @@ def _simplified(self, relation_operator: Callable[[Expr, Expr], bool]) -> Expr:
return mapping[(relation_operator, left, right)]
if isinstance(left, Number) and isinstance(right, Number):
return TRUE if relation_operator(left, right) else FALSE
if isinstance(left, Number) and isinstance(right, Aggregate):
return TRUE if any(relation_operator(left, e) for e in right.elements) else FALSE
return self.__class__(left, right)

@property
Expand Down
19 changes: 19 additions & 0 deletions rflx/pyrflx/typevalue.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,13 +12,15 @@
TRUE,
UNDEFINED,
Add,
Aggregate,
And,
Attribute,
Expr,
First,
Last,
Name,
Number,
Relation,
Size,
Sub,
ValidChecksum,
Expand Down Expand Up @@ -1356,6 +1358,23 @@ def subst(expression: Expr) -> Expr:
if expression in self._parameters:
assert isinstance(expression, Name)
return self._parameters[expression]
if (
isinstance(expression, Relation)
and isinstance(expression.left, Variable)
and isinstance(expression.right, Aggregate)
and self._fields[expression.left.identifier.flat].set
):
field_value = self._fields[expression.left.identifier.flat].typeval.value
assert isinstance(field_value, bytes)
return expression.__class__(
Number(
int.from_bytes(
field_value,
"big",
)
),
expression.right,
)
return expression

return expr.substituted(func=subst).substituted(func=subst).simplified()
Expand Down
8 changes: 7 additions & 1 deletion tests/data/fixtures/pyrflx.py
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ def fixture_pyrflx() -> pyrflx.PyRFLX:
f"{SPEC_DIR}/parameterized.rflx",
f"{SPEC_DIR}/endianness.rflx",
f"{SPEC_DIR}/low_order.rflx",
f"{SPEC_DIR}/aggregate_in_relation.rflx",
],
skip_model_verification=True,
)
Expand Down Expand Up @@ -235,5 +236,10 @@ def fixture_endianness_package(pyrflx_: pyrflx.PyRFLX) -> pyrflx.Package:


@pytest.fixture(name="low_order_package", scope="session")
def fixure_low_order_package(pyrflx_: pyrflx.PyRFLX) -> pyrflx.Package:
def fixture_low_order_package(pyrflx_: pyrflx.PyRFLX) -> pyrflx.Package:
return pyrflx_.package("Low_Order")


@pytest.fixture(name="aggregate_in_relation_package", scope="session")
def fixture_aggregate_in_relation_package(pyrflx_: pyrflx.PyRFLX) -> pyrflx.Package:
return pyrflx_.package("Aggregate_In_Relation")
16 changes: 16 additions & 0 deletions tests/data/specs/aggregate_in_relation.rflx
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
package Aggregate_In_Relation is

type B is mod 2 ** 8;

type Aggregate_In_Relation_Msg is
message
Fld_A : Opaque
with Size => 16
then Fld_B
if Fld_A /= [16#01#, 16#02#]
then null
if Fld_A = [16#01#, 16#02#];
Fld_B : B;
end message;

end Aggregate_In_Relation;
18 changes: 18 additions & 0 deletions tests/unit/pyrflx_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -78,6 +78,7 @@ def test_pyrflx_iterator(pyrflx_: PyRFLX) -> None:
"Message_Type_Size_Condition",
"Always_Valid_Aspect",
"Low_Order",
"Aggregate_In_Relation",
}


Expand Down Expand Up @@ -1515,3 +1516,20 @@ def test_low_order(low_order_package: Package) -> None:

assert m1.valid_message
assert m1.bytestring == b"\x01\x00"


def test_aggregate_in_relation(aggregate_in_relation_package: Package) -> None:
msg = aggregate_in_relation_package.new_message("Aggregate_In_Relation_Msg")
with pytest.raises(
PyRFLXError,
match=(
"^"
"pyrflx: error: Bitstring representing the message is too short"
" - stopped while parsing field: Fld_B"
"$"
),
):
msg.parse(b"\x00\x03")

msg.parse(b"\x00\x02")
assert msg.valid_message

0 comments on commit f3cd449

Please sign in to comment.