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)) print("\n---\n", repr(context))
# architecture = optimizations.ArchitectureConstraints(registers=["A", "B", "C"], direct_memory_store=True)
register_alloc = optimizations.RegisterAllocation(intermediate_representation) register_alloc = optimizations.RegisterAllocation(intermediate_representation)
register_alloc.analyze() register_alloc.analyze()

View file

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