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:
parent
dfa24f2d67
commit
1bf549eda4
2 changed files with 34 additions and 11 deletions
|
|
@ -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()
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -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)
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue