Skip to content

Commit

Permalink
FIX: init arguments for pointer type specifications
Browse files Browse the repository at this point in the history
  • Loading branch information
klauer committed Nov 17, 2023
1 parent 5e20aa3 commit 2250af6
Show file tree
Hide file tree
Showing 3 changed files with 48 additions and 8 deletions.
9 changes: 7 additions & 2 deletions blark/iec.lark
Original file line number Diff line number Diff line change
Expand Up @@ -287,7 +287,7 @@ indirection_type: REFERENCE_TO
| REFERENCE_TO POINTER_TO+
pointer_type: POINTER_TO+

simple_spec_init: [ indirection_type ] simple_specification [ ":=" expression ]
simple_spec_init: ( simple_specification | indirect_simple_specification ) [ ":=" expression ]

simple_specification: elementary_type_name
| simple_type_name
Expand Down Expand Up @@ -532,7 +532,12 @@ string_type_specification: (STRING | WSTRING) [ string_spec_length ]
// B.1.5.1
?derived_function_name: IDENTIFIER

indirect_simple_specification: [ indirection_type ] simple_specification
indirect_simple_specification: [ indirection_type ] simple_specification [ input_param_args ]

input_param_args: "(" [ input_param_assignment ( "," input_param_assignment )* ","? ] ")"

input_param_assignment: variable_name ":=" [ expression ]
| expression

function_declaration: "FUNCTION"i [ access_specifier ] derived_function_name [ ":" indirect_simple_specification ] ";"* [ function_var_block+ ] [ function_body ] "END_FUNCTION"i ";"*

Expand Down
3 changes: 3 additions & 0 deletions blark/tests/test_transformer.py
Original file line number Diff line number Diff line change
Expand Up @@ -115,6 +115,7 @@ def test_check_unhandled_rules(grammar: lark.Lark):
# handled as tree
"global_var_list",
"var_body",
"input_param_args",
}

todo_rules = set()
Expand Down Expand Up @@ -367,6 +368,8 @@ def test_bool_literal_roundtrip(name, value, expected):
param("simple_type_declaration", "TypeName : POINTER TO INT"),
param("simple_type_declaration", "TypeName : POINTER TO POINTER TO INT"),
param("simple_type_declaration", "TypeName : REFERENCE TO POINTER TO INT"),
param("simple_type_declaration", "TypeName : POINTER TO fbSomething(1, 2, 3)"),
param("simple_type_declaration", "TypeName : POINTER TO fbSomething(1, 2, C := 4)"), # noqa: E501
param("simple_type_declaration", "TypeName EXTENDS a.b : POINTER TO INT"),
param("subrange_specification", "TypeName"), # aliased and not usually hit
param("subrange_type_declaration", "TypeName : INT (1..2)"),
Expand Down
44 changes: 38 additions & 6 deletions blark/transform.py
Original file line number Diff line number Diff line change
Expand Up @@ -312,10 +312,9 @@ def from_init(
)
spec_type = cls.from_spec(init.spec)
if isinstance(init, TypeInitialization):
full_type_name = join_if(init.indirection, " ", spec_type.full_type_name)
return cls(
base_type_name=spec_type.base_type_name,
full_type_name=full_type_name,
full_type_name=spec_type.full_type_name,
context=init,
)
return spec_type
Expand Down Expand Up @@ -1174,8 +1173,7 @@ class TypeInitialization(TypeInitializationBase):
TypeName := Value1
STRING[100] := "value"
"""
indirection: Optional[IndirectionType]
spec: SimpleSpecification
spec: Union[SimpleSpecification, IndirectSimpleSpecification]
value: Optional[Expression]
meta: Optional[Meta] = meta_field()

Expand Down Expand Up @@ -1581,13 +1579,47 @@ class IndirectSimpleSpecification(TypeSpecificationBase):
POINTER TO TypeName
REFERENCE TO TypeName
REFERENCE TO POINTER TO TypeName
Initialization parameters such as these are parsed but otherwise ignored
by TwinCAT::
POINTER TO TypeName(1, 2)
POINTER TO TypeName(1, 2, C := 4)
"""
indirection: Optional[IndirectionType]
type: SimpleSpecification
init_parameters: Optional[List[InputParameterAssignment]]
meta: Optional[Meta] = meta_field()

@staticmethod
def from_lark(
indirection: Optional[IndirectionType],
type_: SimpleSpecification,
init_parameters_tree: Optional[lark.Tree],
) -> IndirectSimpleSpecification:
if init_parameters_tree is None:
init_parameters = None
else:
init_parameters = typing.cast(
List[InputParameterAssignment],
list(init_parameters_tree.children)
)
return IndirectSimpleSpecification(
indirection,
type_,
init_parameters,
)

def __str__(self) -> str:
return join_if(self.indirection, " ", self.type)
full_type = join_if(self.indirection, " ", self.type)
if not self.init_parameters:
return full_type

initializers = ", ".join(
str(init)
for init in self.init_parameters
)
return f"{full_type}({initializers})"


# _array_spec_type
Expand Down Expand Up @@ -2673,7 +2705,7 @@ class ParameterAssignment:


@dataclass
@_rule_handler("param_assignment")
@_rule_handler("param_assignment", "input_param_assignment")
class InputParameterAssignment(ParameterAssignment):
"""
An input parameter in a function call.
Expand Down

0 comments on commit 2250af6

Please sign in to comment.