semantic: better handle builtins

Attach them to a pseudo-node "builtin" for the sake of better diagnostics and assignment tracking
This commit is contained in:
Antoine Viallon 2024-01-05 23:40:31 +01:00
parent dfa24f2d67
commit 1bf549eda4
Signed by: aviallon
GPG key ID: 186FC35EDEB25716
2 changed files with 34 additions and 11 deletions

View file

@ -63,6 +63,8 @@ def main():
print("\n---\n", repr(context))
# architecture = optimizations.ArchitectureConstraints(registers=["A", "B", "C"], direct_memory_store=True)
register_alloc = optimizations.RegisterAllocation(intermediate_representation)
register_alloc.analyze()

View file

@ -3,19 +3,29 @@ from __future__ import annotations
import abc
from typing import Literal
from . import nodes
from .errors import SemanticAnalysisError
from . import nodes, lexer, source
from .errors import SemanticAnalysisError, CompilationWarning
from .logger import Logger, Tracer, LogLevel
from .typechecking import typecheck
logger = Logger(__name__)
tracer = Tracer(logger=logger, level=LogLevel.Debug)
builtin_node = nodes.PseudoNode(
lexer.Token(
kind=lexer.Tokens.Unknown,
value="__compiler_internal__",
loc=source.SourceLocation(begin=source.Location(internal=True), source="__compiler_internal__")
)
)
class SymbolABC(abc.ABC):
def __init__(self, context: Context, name: str,
definition: nodes.Node | None = None,
value: nodes.Node | None | Literal["builtin"] = None):
value: nodes.Node | None | Literal["builtin"] = None,
builtin: bool = False):
self.context = context
self.name = name
self.writes: list[nodes.Node] = []
@ -24,6 +34,10 @@ class SymbolABC(abc.ABC):
self.definition = definition
if builtin:
self.writes += [builtin_node]
self.definition = builtin_node
self.reads: list[nodes.Node] = []
self._repr_guard: bool = False
@ -46,8 +60,11 @@ class SymbolABC(abc.ABC):
class Type(SymbolABC):
def __init__(self, context: Context, name: str,
definition: nodes.Node | None = None,
value: nodes.Value | None | Literal["builtin"] = None):
super().__init__(context, name, definition=definition, value=value)
value: nodes.Value | None | Literal["builtin"] = None,
builtin: bool = False):
if builtin:
value = "builtin"
super().__init__(context, name, definition=definition, value=value, builtin=builtin)
class Function(Type):
@ -59,8 +76,9 @@ class Variable(SymbolABC):
def __init__(self, context: Context, name: str,
definition: nodes.Definition | None = None,
value: nodes.Value | None = None,
typedef: Type | None = None):
super().__init__(context, name, definition=definition, value=value)
typedef: Type | None = None,
builtin: bool = False):
super().__init__(context, name, definition=definition, value=value, builtin=builtin)
self.type = typedef if typedef is not None else context.get_type("__unknown")
def __str__(self):
@ -190,6 +208,9 @@ class Context:
for read in variable.reads:
previous_write = None
for write in variable.writes:
if write == "builtin":
continue
if write.location() < read.location():
previous_write = write
break
@ -214,10 +235,10 @@ class BuiltinContext(Context):
def __init__(self):
super().__init__(name="builtins", parent=None)
self.types = {
"__unknown": Type(self, "__unknown", value="builtin"),
"__function": Function(self, "__function", value="builtin"),
"uint32": Type(self, "uint32", value="builtin")
"__unknown": Type(self, "__unknown", builtin=True),
"__function": Function(self, "__function", builtin=True),
"uint32": Type(self, "uint32", builtin=True)
}
self.variables = {
"display": Variable(self, "display", typedef=self.types["__function"])
"display": Variable(self, "display", typedef=self.types["__function"], builtin=True)
}