nodes: add source location to AST nodes
This commit is contained in:
parent
585910a60b
commit
caffa92c1e
2 changed files with 43 additions and 8 deletions
|
|
@ -16,10 +16,20 @@ class Node:
|
||||||
def _values(self) -> Any | list[Node]:
|
def _values(self) -> Any | list[Node]:
|
||||||
raise NotImplementedError(f"Please override {__name__}")
|
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):
|
def __repr__(self):
|
||||||
vals = self._values()
|
vals = self._values()
|
||||||
if type(vals) == list:
|
if type(vals) == list:
|
||||||
vals = ", ".join(repr(val) for val in vals)
|
vals = ", ".join(repr(val) for val in vals)
|
||||||
|
else:
|
||||||
|
vals = repr(vals)
|
||||||
return f"{self.__class__.__name__}({vals})"
|
return f"{self.__class__.__name__}({vals})"
|
||||||
|
|
||||||
def pprint(self, depth: int | None = None, indent: str = "\t"):
|
def pprint(self, depth: int | None = None, indent: str = "\t"):
|
||||||
|
|
@ -48,9 +58,13 @@ class Node:
|
||||||
return result
|
return result
|
||||||
|
|
||||||
|
|
||||||
class Literal(Node):
|
class Literal(Node, ABC):
|
||||||
def __init__(self, value: Any):
|
def __init__(self, location: SourceLocation, value: Any):
|
||||||
self.value = value
|
self.value = value
|
||||||
|
self.loc = location
|
||||||
|
|
||||||
|
def location(self) -> SourceLocation:
|
||||||
|
return self.loc
|
||||||
|
|
||||||
def _values(self) -> Any | list[Node]:
|
def _values(self) -> Any | list[Node]:
|
||||||
return self.value
|
return self.value
|
||||||
|
|
@ -96,14 +110,15 @@ BinaryOperation = Sum | Sub | Product | Division
|
||||||
|
|
||||||
@beartype
|
@beartype
|
||||||
class Float(Literal):
|
class Float(Literal):
|
||||||
def __init__(self, value: float):
|
def __init__(self, location: SourceLocation, value: float):
|
||||||
super().__init__(value)
|
super().__init__(location, value)
|
||||||
|
|
||||||
|
|
||||||
@beartype
|
@beartype
|
||||||
class Integer(Literal):
|
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):
|
class Expression(Node):
|
||||||
|
|
@ -113,6 +128,26 @@ class Expression(Node):
|
||||||
def _values(self) -> Any | list[Node]:
|
def _values(self) -> Any | list[Node]:
|
||||||
return self.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
|
Number = Float | Integer
|
||||||
Value = BinaryOperation | Number
|
Value = BinaryOperation | Number
|
||||||
|
|
|
||||||
|
|
@ -68,10 +68,10 @@ class Parser:
|
||||||
def number(self, mandatory: bool = False):
|
def number(self, mandatory: bool = False):
|
||||||
if tok := self.accept(Tokens.Float):
|
if tok := self.accept(Tokens.Float):
|
||||||
logger.debug(f"Found float {tok}")
|
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):
|
elif tok := self.accept(Tokens.Integer):
|
||||||
logger.debug(f"Found integer {tok}")
|
logger.debug(f"Found integer {tok}")
|
||||||
return Integer(value=int(tok.value))
|
return Integer(location=tok.loc, value=int(tok.value))
|
||||||
elif mandatory:
|
elif mandatory:
|
||||||
raise UnexpectedTokenError(self.token, "integer or float")
|
raise UnexpectedTokenError(self.token, "integer or float")
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue