nodes: add source location to AST nodes

This commit is contained in:
Antoine Viallon 2023-05-08 23:13:00 +02:00
parent 585910a60b
commit caffa92c1e
Signed by: aviallon
GPG key ID: D126B13AB555E16F
2 changed files with 43 additions and 8 deletions

View file

@ -16,10 +16,20 @@ class Node:
def _values(self) -> Any | list[Node]:
raise NotImplementedError(f"Please override {__name__}")
@functools.cache
def location(self) -> SourceLocation:
locations = [v.location() for v in self._values()]
begin = min([loc.begin for loc in locations])
end = max([loc.end for loc in locations])
loc = SourceLocation(begin=begin, end=end)
return loc
def __repr__(self):
vals = self._values()
if type(vals) == list:
vals = ", ".join(repr(val) for val in vals)
else:
vals = repr(vals)
return f"{self.__class__.__name__}({vals})"
def pprint(self, depth: int | None = None, indent: str = "\t"):
@ -48,9 +58,13 @@ class Node:
return result
class Literal(Node):
def __init__(self, value: Any):
class Literal(Node, ABC):
def __init__(self, location: SourceLocation, value: Any):
self.value = value
self.loc = location
def location(self) -> SourceLocation:
return self.loc
def _values(self) -> Any | list[Node]:
return self.value
@ -96,14 +110,15 @@ BinaryOperation = Sum | Sub | Product | Division
@beartype
class Float(Literal):
def __init__(self, value: float):
super().__init__(value)
def __init__(self, location: SourceLocation, value: float):
super().__init__(location, value)
@beartype
class Integer(Literal):
def __init__(self, value: int):
super().__init__(value)
def __init__(self, location: SourceLocation, value: int):
super().__init__(location, value)
class Expression(Node):
@ -113,6 +128,26 @@ class Expression(Node):
def _values(self) -> Any | list[Node]:
return self.node
def location(self) -> SourceLocation:
return self.node.location()
class Identifier(Literal):
def __init__(self, name: str):
super().__init__(name)
class Assignment(Node):
def intermediate_representation(self, context: semantic.Context) -> list[ir.IRItem]:
return self.value.intermediate_representation(context)
def __init__(self, identifier: Identifier, value: Value):
self.identifier = identifier
self.value = value
def _values(self) -> Any | list[Node]:
return [self.identifier, self.value]
Number = Float | Integer
Value = BinaryOperation | Number

View file

@ -68,10 +68,10 @@ class Parser:
def number(self, mandatory: bool = False):
if tok := self.accept(Tokens.Float):
logger.debug(f"Found float {tok}")
return Float(value=float(tok.value))
return Float(location=tok.loc, value=float(tok.value))
elif tok := self.accept(Tokens.Integer):
logger.debug(f"Found integer {tok}")
return Integer(value=int(tok.value))
return Integer(location=tok.loc, value=int(tok.value))
elif mandatory:
raise UnexpectedTokenError(self.token, "integer or float")