Skip to content

Commit 4d5c905

Browse files
authored
Merge pull request #95 from klauer/fix_pointer_init
FIX: init arguments for pointer type specifications
2 parents 5e20aa3 + 2250af6 commit 4d5c905

File tree

3 files changed

+48
-8
lines changed

3 files changed

+48
-8
lines changed

blark/iec.lark

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -287,7 +287,7 @@ indirection_type: REFERENCE_TO
287287
| REFERENCE_TO POINTER_TO+
288288
pointer_type: POINTER_TO+
289289

290-
simple_spec_init: [ indirection_type ] simple_specification [ ":=" expression ]
290+
simple_spec_init: ( simple_specification | indirect_simple_specification ) [ ":=" expression ]
291291

292292
simple_specification: elementary_type_name
293293
| simple_type_name
@@ -532,7 +532,12 @@ string_type_specification: (STRING | WSTRING) [ string_spec_length ]
532532
// B.1.5.1
533533
?derived_function_name: IDENTIFIER
534534

535-
indirect_simple_specification: [ indirection_type ] simple_specification
535+
indirect_simple_specification: [ indirection_type ] simple_specification [ input_param_args ]
536+
537+
input_param_args: "(" [ input_param_assignment ( "," input_param_assignment )* ","? ] ")"
538+
539+
input_param_assignment: variable_name ":=" [ expression ]
540+
| expression
536541

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

blark/tests/test_transformer.py

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -115,6 +115,7 @@ def test_check_unhandled_rules(grammar: lark.Lark):
115115
# handled as tree
116116
"global_var_list",
117117
"var_body",
118+
"input_param_args",
118119
}
119120

120121
todo_rules = set()
@@ -367,6 +368,8 @@ def test_bool_literal_roundtrip(name, value, expected):
367368
param("simple_type_declaration", "TypeName : POINTER TO INT"),
368369
param("simple_type_declaration", "TypeName : POINTER TO POINTER TO INT"),
369370
param("simple_type_declaration", "TypeName : REFERENCE TO POINTER TO INT"),
371+
param("simple_type_declaration", "TypeName : POINTER TO fbSomething(1, 2, 3)"),
372+
param("simple_type_declaration", "TypeName : POINTER TO fbSomething(1, 2, C := 4)"), # noqa: E501
370373
param("simple_type_declaration", "TypeName EXTENDS a.b : POINTER TO INT"),
371374
param("subrange_specification", "TypeName"), # aliased and not usually hit
372375
param("subrange_type_declaration", "TypeName : INT (1..2)"),

blark/transform.py

Lines changed: 38 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -312,10 +312,9 @@ def from_init(
312312
)
313313
spec_type = cls.from_spec(init.spec)
314314
if isinstance(init, TypeInitialization):
315-
full_type_name = join_if(init.indirection, " ", spec_type.full_type_name)
316315
return cls(
317316
base_type_name=spec_type.base_type_name,
318-
full_type_name=full_type_name,
317+
full_type_name=spec_type.full_type_name,
319318
context=init,
320319
)
321320
return spec_type
@@ -1174,8 +1173,7 @@ class TypeInitialization(TypeInitializationBase):
11741173
TypeName := Value1
11751174
STRING[100] := "value"
11761175
"""
1177-
indirection: Optional[IndirectionType]
1178-
spec: SimpleSpecification
1176+
spec: Union[SimpleSpecification, IndirectSimpleSpecification]
11791177
value: Optional[Expression]
11801178
meta: Optional[Meta] = meta_field()
11811179

@@ -1581,13 +1579,47 @@ class IndirectSimpleSpecification(TypeSpecificationBase):
15811579
POINTER TO TypeName
15821580
REFERENCE TO TypeName
15831581
REFERENCE TO POINTER TO TypeName
1582+
1583+
Initialization parameters such as these are parsed but otherwise ignored
1584+
by TwinCAT::
1585+
1586+
POINTER TO TypeName(1, 2)
1587+
POINTER TO TypeName(1, 2, C := 4)
15841588
"""
15851589
indirection: Optional[IndirectionType]
15861590
type: SimpleSpecification
1591+
init_parameters: Optional[List[InputParameterAssignment]]
15871592
meta: Optional[Meta] = meta_field()
15881593

1594+
@staticmethod
1595+
def from_lark(
1596+
indirection: Optional[IndirectionType],
1597+
type_: SimpleSpecification,
1598+
init_parameters_tree: Optional[lark.Tree],
1599+
) -> IndirectSimpleSpecification:
1600+
if init_parameters_tree is None:
1601+
init_parameters = None
1602+
else:
1603+
init_parameters = typing.cast(
1604+
List[InputParameterAssignment],
1605+
list(init_parameters_tree.children)
1606+
)
1607+
return IndirectSimpleSpecification(
1608+
indirection,
1609+
type_,
1610+
init_parameters,
1611+
)
1612+
15891613
def __str__(self) -> str:
1590-
return join_if(self.indirection, " ", self.type)
1614+
full_type = join_if(self.indirection, " ", self.type)
1615+
if not self.init_parameters:
1616+
return full_type
1617+
1618+
initializers = ", ".join(
1619+
str(init)
1620+
for init in self.init_parameters
1621+
)
1622+
return f"{full_type}({initializers})"
15911623

15921624

15931625
# _array_spec_type
@@ -2673,7 +2705,7 @@ class ParameterAssignment:
26732705

26742706

26752707
@dataclass
2676-
@_rule_handler("param_assignment")
2708+
@_rule_handler("param_assignment", "input_param_assignment")
26772709
class InputParameterAssignment(ParameterAssignment):
26782710
"""
26792711
An input parameter in a function call.

0 commit comments

Comments
 (0)