diff --git a/trlc/ast.py b/trlc/ast.py index d36900c..b51db9a 100644 --- a/trlc/ast.py +++ b/trlc/ast.py @@ -2998,6 +2998,9 @@ def to_python_dict(self): """ return {name: value.to_python_object() for name, value in self.field.items()} + + def is_component_implicit_null(self, component) -> bool: + return not isinstance(self.field[component.name], Implicit_Null) def assign(self, component, value): assert isinstance(component, Composite_Component) @@ -3008,6 +3011,8 @@ def assign(self, component, value): Implicit_Null, Unary_Expression)), \ "value is %s" % value.__class__.__name__ + if self.is_component_implicit_null(component): + raise KeyError(f"Component {component.name} already assigned to {self.n_typ.name} {self.name}!") self.field[component.name] = value def dump(self, indent=0): # pragma: no cover diff --git a/trlc/parser.py b/trlc/parser.py index c227ee0..387b308 100644 --- a/trlc/parser.py +++ b/trlc/parser.py @@ -1810,11 +1810,19 @@ def parse_record_object_declaration(self): comp = r_typ.components.lookup(self.mh, self.ct, ast.Composite_Component) + + if obj.is_component_implicit_null(comp): + self.mh.error(self.ct.location, + "component '%s' already assigned at line %i" % + (comp.name, + obj.field[comp.name].location.line_no)) + comp.set_ast_link(self.ct) if r_typ.is_frozen(comp): self.mh.error(self.ct.location, "cannot overwrite frozen component %s" % comp.name) + self.match("ASSIGN") comp.set_ast_link(self.ct) value = self.parse_value(comp.n_typ)