diff --git a/compiler/nodes.py b/compiler/nodes.py index b34e0c1..b456534 100644 --- a/compiler/nodes.py +++ b/compiler/nodes.py @@ -48,7 +48,7 @@ class Node: def _pprint(self, depth: int | None, indent: str, _depth: int = 0) -> list[str]: if depth is not None and _depth >= depth: - return [f"{indent}{self.__class__.__name__} {{ ... }}"] + return [f"{indent}{self.__class__.__name__}(pure={self.pure}) {{ ... }}"] vals = self._values() try: @@ -56,7 +56,7 @@ class Node: except TypeError: vals = (vals,) - result = [f"{self.__class__.__name__} {{"] + result = [f"{self.__class__.__name__}(pure={self.pure}) {{"] for val in vals: if isinstance(val, Node): result += val._pprint(depth=depth, indent=indent, _depth=_depth + 1) @@ -68,6 +68,10 @@ class Node: return result + @property + def pure(self) -> bool: + return all(v.pure for v in self._values()) + @abstractmethod def intermediate_representation(self) -> list[ir.IRItem]: raise OverrideMandatoryError() @@ -97,6 +101,9 @@ class Literal(Node, ABC): def location(self) -> SourceLocation: return self.loc + def pure(self) -> bool: + return True + def _values(self) -> list[Node | Any]: return [self.value] @@ -274,6 +281,14 @@ class Block(Statement): super().__init__(*nodes) self.name = name + def intermediate_representation(self) -> list[ir.IRItem]: + result: list[ir.IRItem] = [] + for node in self.nodes[:-1]: + if not node.pure: + result += node.intermediate_representation() + result += self.nodes[-1].intermediate_representation() + return result + def semantic_analysis(self, context: semantic.Context | None): child_context = semantic.Context(name=self.name, parent=context) if context is not None: