Skip to content

Commit

Permalink
Improve code generation for Reset_Dependent_Fields
Browse files Browse the repository at this point in the history
Use a loop rather than case statement + explicit assignments to
reset the fields.

Closes #840
  • Loading branch information
kanigsson committed Nov 9, 2021
1 parent dd4eb1b commit daf64fc
Show file tree
Hide file tree
Showing 43 changed files with 312 additions and 1,523 deletions.
34 changes: 34 additions & 0 deletions rflx/ada.py
Original file line number Diff line number Diff line change
Expand Up @@ -771,6 +771,20 @@ def precedence(self) -> Precedence:
return Precedence.LITERAL


class Succ(Expr):
def __init__(self, type_identifier: StrID, expression: Expr) -> None:
super().__init__()
self.type_identifier = ID(type_identifier)
self.expression = expression

def _update_str(self) -> None:
self._str = intern(f"{self.type_identifier}'Succ ({self.expression})")

@property
def precedence(self) -> Precedence:
raise NotImplementedError


class QualifiedExpr(Expr):
def __init__(self, type_identifier: StrID, expression: Expr) -> None:
super().__init__()
Expand Down Expand Up @@ -1596,6 +1610,26 @@ def __str__(self) -> str:
return f"for {self.identifier} of {reverse}{self.iterator} loop\n{statements}\nend loop;"


class ForIn(Statement):
def __init__(
self,
identifier: StrID,
iterator: Expr,
statements: Sequence[Statement],
reverse: bool = False,
) -> None:
assert len(statements) > 0
self.identifier = identifier
self.iterator = iterator
self.statements = statements
self.reverse = reverse

def __str__(self) -> str:
statements = indent("\n".join(str(s) for s in self.statements), 3)
reverse = "reverse " if self.reverse else ""
return f"for {self.identifier} in {reverse}{self.iterator} loop\n{statements}\nend loop;"


class Declare(Statement):
def __init__(
self, declarations: Sequence[Declaration], statements: Sequence[Statement]
Expand Down
71 changes: 32 additions & 39 deletions rflx/generator/generator.py
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,6 @@
Call,
CallStatement,
Case,
CaseStatement,
Component,
Constrained,
ContextItem,
Expand All @@ -40,6 +39,7 @@
ExpressionFunctionDeclaration,
First,
ForAllIn,
ForIn,
FormalDeclaration,
FormalSubprogramDeclaration,
FunctionSpecification,
Expand Down Expand Up @@ -99,6 +99,7 @@
SubprogramBody,
SubprogramDeclaration,
SubprogramUnitPart,
Succ,
Unit,
UnitPart,
UsePackageClause,
Expand Down Expand Up @@ -1940,48 +1941,40 @@ def __create_reset_dependent_fields_procedure(message: Message) -> UnitPart:
],
[
field_location_invariant,
CaseStatement(
Variable("Fld"),
ForIn(
"F",
ValueRange(Succ("Field", Variable("Fld")), Last("Field")),
[
(
Variable(f.affixed_name),
ty.cast(ty.List[Statement], [])
+ [
Assignment(
Indexed(
Variable("Ctx.Cursors"),
Variable(s.affixed_name),
),
Aggregate(
Variable("S_Invalid"),
Variable(FINAL.affixed_name),
),
)
for s in reversed(message.successors(f))
]
+ [
Assignment(
Indexed(
Variable("Ctx.Cursors"),
Variable(f.affixed_name),
),
Aggregate(
Variable("S_Invalid"),
Selected(
Indexed(
Variable("Ctx.Cursors"),
Variable(f.affixed_name),
),
"Predecessor",
),
),
)
]
+ [field_location_invariant],
Assignment(
Indexed(
Variable("Ctx.Cursors"),
Variable("F"),
),
Aggregate(
Variable("S_Invalid"),
Variable(FINAL.affixed_name),
),
)
for f in message.fields
],
reverse=True,
),
Assignment(
Indexed(
Variable("Ctx.Cursors"),
Variable("Fld"),
),
Aggregate(
Variable("S_Invalid"),
Selected(
Indexed(
Variable("Ctx.Cursors"),
Variable("Fld"),
),
"Predecessor",
),
),
),
field_location_invariant,
],
[
Precondition(
Expand Down
57 changes: 6 additions & 51 deletions tests/integration/messages/generated/rflx-universal-message.adb
Original file line number Diff line number Diff line change
Expand Up @@ -184,57 +184,12 @@ is
begin
pragma Assert (Field_First (Ctx, Fld) = First
and Field_Size (Ctx, Fld) = Size);
case Fld is
when F_Message_Type =>
Ctx.Cursors (F_Values) := (S_Invalid, F_Final);
Ctx.Cursors (F_Value) := (S_Invalid, F_Final);
Ctx.Cursors (F_Options) := (S_Invalid, F_Final);
Ctx.Cursors (F_Option_Types) := (S_Invalid, F_Final);
Ctx.Cursors (F_Data) := (S_Invalid, F_Final);
Ctx.Cursors (F_Length) := (S_Invalid, F_Final);
Ctx.Cursors (F_Message_Type) := (S_Invalid, Ctx.Cursors (F_Message_Type).Predecessor);
pragma Assert (Field_First (Ctx, Fld) = First
and Field_Size (Ctx, Fld) = Size);
when F_Length =>
Ctx.Cursors (F_Values) := (S_Invalid, F_Final);
Ctx.Cursors (F_Value) := (S_Invalid, F_Final);
Ctx.Cursors (F_Options) := (S_Invalid, F_Final);
Ctx.Cursors (F_Option_Types) := (S_Invalid, F_Final);
Ctx.Cursors (F_Data) := (S_Invalid, F_Final);
Ctx.Cursors (F_Length) := (S_Invalid, Ctx.Cursors (F_Length).Predecessor);
pragma Assert (Field_First (Ctx, Fld) = First
and Field_Size (Ctx, Fld) = Size);
when F_Data =>
Ctx.Cursors (F_Values) := (S_Invalid, F_Final);
Ctx.Cursors (F_Value) := (S_Invalid, F_Final);
Ctx.Cursors (F_Options) := (S_Invalid, F_Final);
Ctx.Cursors (F_Option_Types) := (S_Invalid, F_Final);
Ctx.Cursors (F_Data) := (S_Invalid, Ctx.Cursors (F_Data).Predecessor);
pragma Assert (Field_First (Ctx, Fld) = First
and Field_Size (Ctx, Fld) = Size);
when F_Option_Types =>
Ctx.Cursors (F_Values) := (S_Invalid, F_Final);
Ctx.Cursors (F_Value) := (S_Invalid, F_Final);
Ctx.Cursors (F_Options) := (S_Invalid, F_Final);
Ctx.Cursors (F_Option_Types) := (S_Invalid, Ctx.Cursors (F_Option_Types).Predecessor);
pragma Assert (Field_First (Ctx, Fld) = First
and Field_Size (Ctx, Fld) = Size);
when F_Options =>
Ctx.Cursors (F_Values) := (S_Invalid, F_Final);
Ctx.Cursors (F_Value) := (S_Invalid, F_Final);
Ctx.Cursors (F_Options) := (S_Invalid, Ctx.Cursors (F_Options).Predecessor);
pragma Assert (Field_First (Ctx, Fld) = First
and Field_Size (Ctx, Fld) = Size);
when F_Value =>
Ctx.Cursors (F_Values) := (S_Invalid, F_Final);
Ctx.Cursors (F_Value) := (S_Invalid, Ctx.Cursors (F_Value).Predecessor);
pragma Assert (Field_First (Ctx, Fld) = First
and Field_Size (Ctx, Fld) = Size);
when F_Values =>
Ctx.Cursors (F_Values) := (S_Invalid, Ctx.Cursors (F_Values).Predecessor);
pragma Assert (Field_First (Ctx, Fld) = First
and Field_Size (Ctx, Fld) = Size);
end case;
for F in reverse Field'Succ (Fld) .. Field'Last loop
Ctx.Cursors (F) := (S_Invalid, F_Final);
end loop;
Ctx.Cursors (Fld) := (S_Invalid, Ctx.Cursors (Fld).Predecessor);
pragma Assert (Field_First (Ctx, Fld) = First
and Field_Size (Ctx, Fld) = Size);
end Reset_Dependent_Fields;

function Composite_Field (Fld : Field) return Boolean is
Expand Down
23 changes: 6 additions & 17 deletions tests/integration/messages/generated/rflx-universal-option.adb
Original file line number Diff line number Diff line change
Expand Up @@ -146,23 +146,12 @@ is
begin
pragma Assert (Field_First (Ctx, Fld) = First
and Field_Size (Ctx, Fld) = Size);
case Fld is
when F_Option_Type =>
Ctx.Cursors (F_Data) := (S_Invalid, F_Final);
Ctx.Cursors (F_Length) := (S_Invalid, F_Final);
Ctx.Cursors (F_Option_Type) := (S_Invalid, Ctx.Cursors (F_Option_Type).Predecessor);
pragma Assert (Field_First (Ctx, Fld) = First
and Field_Size (Ctx, Fld) = Size);
when F_Length =>
Ctx.Cursors (F_Data) := (S_Invalid, F_Final);
Ctx.Cursors (F_Length) := (S_Invalid, Ctx.Cursors (F_Length).Predecessor);
pragma Assert (Field_First (Ctx, Fld) = First
and Field_Size (Ctx, Fld) = Size);
when F_Data =>
Ctx.Cursors (F_Data) := (S_Invalid, Ctx.Cursors (F_Data).Predecessor);
pragma Assert (Field_First (Ctx, Fld) = First
and Field_Size (Ctx, Fld) = Size);
end case;
for F in reverse Field'Succ (Fld) .. Field'Last loop
Ctx.Cursors (F) := (S_Invalid, F_Final);
end loop;
Ctx.Cursors (Fld) := (S_Invalid, Ctx.Cursors (Fld).Predecessor);
pragma Assert (Field_First (Ctx, Fld) = First
and Field_Size (Ctx, Fld) = Size);
end Reset_Dependent_Fields;

function Composite_Field (Fld : Field) return Boolean is
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -142,17 +142,12 @@ is
begin
pragma Assert (Field_First (Ctx, Fld) = First
and Field_Size (Ctx, Fld) = Size);
case Fld is
when F_Data =>
Ctx.Cursors (F_Extension) := (S_Invalid, F_Final);
Ctx.Cursors (F_Data) := (S_Invalid, Ctx.Cursors (F_Data).Predecessor);
pragma Assert (Field_First (Ctx, Fld) = First
and Field_Size (Ctx, Fld) = Size);
when F_Extension =>
Ctx.Cursors (F_Extension) := (S_Invalid, Ctx.Cursors (F_Extension).Predecessor);
pragma Assert (Field_First (Ctx, Fld) = First
and Field_Size (Ctx, Fld) = Size);
end case;
for F in reverse Field'Succ (Fld) .. Field'Last loop
Ctx.Cursors (F) := (S_Invalid, F_Final);
end loop;
Ctx.Cursors (Fld) := (S_Invalid, Ctx.Cursors (Fld).Predecessor);
pragma Assert (Field_First (Ctx, Fld) = First
and Field_Size (Ctx, Fld) = Size);
end Reset_Dependent_Fields;

function Get_Field_Value (Ctx : Context; Fld : Field) return Field_Dependent_Value with
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -184,57 +184,12 @@ is
begin
pragma Assert (Field_First (Ctx, Fld) = First
and Field_Size (Ctx, Fld) = Size);
case Fld is
when F_Message_Type =>
Ctx.Cursors (F_Values) := (S_Invalid, F_Final);
Ctx.Cursors (F_Value) := (S_Invalid, F_Final);
Ctx.Cursors (F_Options) := (S_Invalid, F_Final);
Ctx.Cursors (F_Option_Types) := (S_Invalid, F_Final);
Ctx.Cursors (F_Data) := (S_Invalid, F_Final);
Ctx.Cursors (F_Length) := (S_Invalid, F_Final);
Ctx.Cursors (F_Message_Type) := (S_Invalid, Ctx.Cursors (F_Message_Type).Predecessor);
pragma Assert (Field_First (Ctx, Fld) = First
and Field_Size (Ctx, Fld) = Size);
when F_Length =>
Ctx.Cursors (F_Values) := (S_Invalid, F_Final);
Ctx.Cursors (F_Value) := (S_Invalid, F_Final);
Ctx.Cursors (F_Options) := (S_Invalid, F_Final);
Ctx.Cursors (F_Option_Types) := (S_Invalid, F_Final);
Ctx.Cursors (F_Data) := (S_Invalid, F_Final);
Ctx.Cursors (F_Length) := (S_Invalid, Ctx.Cursors (F_Length).Predecessor);
pragma Assert (Field_First (Ctx, Fld) = First
and Field_Size (Ctx, Fld) = Size);
when F_Data =>
Ctx.Cursors (F_Values) := (S_Invalid, F_Final);
Ctx.Cursors (F_Value) := (S_Invalid, F_Final);
Ctx.Cursors (F_Options) := (S_Invalid, F_Final);
Ctx.Cursors (F_Option_Types) := (S_Invalid, F_Final);
Ctx.Cursors (F_Data) := (S_Invalid, Ctx.Cursors (F_Data).Predecessor);
pragma Assert (Field_First (Ctx, Fld) = First
and Field_Size (Ctx, Fld) = Size);
when F_Option_Types =>
Ctx.Cursors (F_Values) := (S_Invalid, F_Final);
Ctx.Cursors (F_Value) := (S_Invalid, F_Final);
Ctx.Cursors (F_Options) := (S_Invalid, F_Final);
Ctx.Cursors (F_Option_Types) := (S_Invalid, Ctx.Cursors (F_Option_Types).Predecessor);
pragma Assert (Field_First (Ctx, Fld) = First
and Field_Size (Ctx, Fld) = Size);
when F_Options =>
Ctx.Cursors (F_Values) := (S_Invalid, F_Final);
Ctx.Cursors (F_Value) := (S_Invalid, F_Final);
Ctx.Cursors (F_Options) := (S_Invalid, Ctx.Cursors (F_Options).Predecessor);
pragma Assert (Field_First (Ctx, Fld) = First
and Field_Size (Ctx, Fld) = Size);
when F_Value =>
Ctx.Cursors (F_Values) := (S_Invalid, F_Final);
Ctx.Cursors (F_Value) := (S_Invalid, Ctx.Cursors (F_Value).Predecessor);
pragma Assert (Field_First (Ctx, Fld) = First
and Field_Size (Ctx, Fld) = Size);
when F_Values =>
Ctx.Cursors (F_Values) := (S_Invalid, Ctx.Cursors (F_Values).Predecessor);
pragma Assert (Field_First (Ctx, Fld) = First
and Field_Size (Ctx, Fld) = Size);
end case;
for F in reverse Field'Succ (Fld) .. Field'Last loop
Ctx.Cursors (F) := (S_Invalid, F_Final);
end loop;
Ctx.Cursors (Fld) := (S_Invalid, Ctx.Cursors (Fld).Predecessor);
pragma Assert (Field_First (Ctx, Fld) = First
and Field_Size (Ctx, Fld) = Size);
end Reset_Dependent_Fields;

function Composite_Field (Fld : Field) return Boolean is
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -146,23 +146,12 @@ is
begin
pragma Assert (Field_First (Ctx, Fld) = First
and Field_Size (Ctx, Fld) = Size);
case Fld is
when F_Option_Type =>
Ctx.Cursors (F_Data) := (S_Invalid, F_Final);
Ctx.Cursors (F_Length) := (S_Invalid, F_Final);
Ctx.Cursors (F_Option_Type) := (S_Invalid, Ctx.Cursors (F_Option_Type).Predecessor);
pragma Assert (Field_First (Ctx, Fld) = First
and Field_Size (Ctx, Fld) = Size);
when F_Length =>
Ctx.Cursors (F_Data) := (S_Invalid, F_Final);
Ctx.Cursors (F_Length) := (S_Invalid, Ctx.Cursors (F_Length).Predecessor);
pragma Assert (Field_First (Ctx, Fld) = First
and Field_Size (Ctx, Fld) = Size);
when F_Data =>
Ctx.Cursors (F_Data) := (S_Invalid, Ctx.Cursors (F_Data).Predecessor);
pragma Assert (Field_First (Ctx, Fld) = First
and Field_Size (Ctx, Fld) = Size);
end case;
for F in reverse Field'Succ (Fld) .. Field'Last loop
Ctx.Cursors (F) := (S_Invalid, F_Final);
end loop;
Ctx.Cursors (Fld) := (S_Invalid, Ctx.Cursors (Fld).Predecessor);
pragma Assert (Field_First (Ctx, Fld) = First
and Field_Size (Ctx, Fld) = Size);
end Reset_Dependent_Fields;

function Composite_Field (Fld : Field) return Boolean is
Expand Down
Loading

0 comments on commit daf64fc

Please sign in to comment.