diff --git a/compiler/semantic.py b/compiler/semantic.py index 750724a..53f4cc6 100644 --- a/compiler/semantic.py +++ b/compiler/semantic.py @@ -11,12 +11,21 @@ class Variable: self.context = context self.name = name self.definitions = [value] + self._repr_guard: bool = False def fully_qualified_name(self) -> str: return f"{self.context.fully_qualified_name()}.{self.name}" + def __str__(self): + return f"{self.__class__.__name__}({self.name})" + def __repr__(self): - return f"{self.__class__.__name__}({self.name}) [definitions: {', '.join(repr(d) for d in self.definitions)}]" + if self._repr_guard: + return str(self) + self._repr_guard = True + definitions = [str(d.location().begin) for d in self.definitions] + self._repr_guard = False + return f"{str(self)} [definitions: {', '.join(definitions)}]" class Context: @@ -25,6 +34,7 @@ class Context: def __init__(self, name: str | None = None, parent: Context | None = None): self.parent = parent self.variables: dict[str, Variable] = {} + self.child_contexts: dict[str, Context] = {} self.name = str(Context._id_sequence) if name is not None: self.name = f"{name}_{Context._id_sequence}" @@ -45,6 +55,9 @@ class Context: return None + def add_context(self, context: Context) -> None: + self.child_contexts[context.name] = context + def set_variable(self, name: str, value: nodes.Value) -> Variable: variable: Variable if name in self.variables: @@ -57,13 +70,23 @@ class Context: return variable - def __repr__(self) -> str: - result = [f"{self.__class__.__name__}(id={self.name})"] + def __str__(self): + return f"{self.__class__.__name__}(id={repr(self.name)})" + + def _pprint(self, depth: int = 0) -> str: + result = [str(self)] if self.parent is not None: result += [f"\tParent ID: {self.parent.name}"] if len(self.variables) > 0: result += [f"\tVariables ({len(self.variables)}):"] for key, value in self.variables.items(): - definitions = (repr(e) for e in value.definitions) - result += [f"\t\t- {repr(key)} : {', '.join(definitions)}"] + result += [f"\t\t- {repr(value)}"] + if len(self.child_contexts) > 0: + result += [f"\tChild contexts ({len(self.child_contexts)}):"] + for key, value in self.child_contexts.items(): + ctx_repr = value._pprint(depth=depth + 1).splitlines(keepends=False) + result += [f"\t\t{line}" for line in ctx_repr] return "\n".join(result) + + def __repr__(self) -> str: + return self._pprint()