parser: parse function calls

This commit is contained in:
Antoine Viallon 2023-05-23 23:24:36 +02:00
parent a092c11216
commit ec1001bfd3
Signed by: aviallon
GPG key ID: D126B13AB555E16F
2 changed files with 23 additions and 4 deletions

View file

@ -44,6 +44,7 @@ class Tokens(enum.Enum):
Equal = re.compile(r"=")
Colon = re.compile(r":")
Semicolon = re.compile(r";")
Comma = re.compile(r",")
Newline = re.compile(r"\n", flags=re.MULTILINE)
EOF = re.compile(r"\Z")

View file

@ -6,7 +6,7 @@ from .errors import CompilationError, UnexpectedTokenError
from .lexer import Tokens, Token
from .logger import Logger, Tracer, LogLevel
from .nodes import Float, Sum, Value, Product, Node, Division, Sub, Integer, Expression, Identifier, Assignment, \
Variable, Statement, PseudoNode, Block, Definition
Variable, Statement, PseudoNode, Block, Definition, Call
logger = Logger(__name__)
tracer = Tracer(logger, level=LogLevel.Debug)
@ -108,12 +108,14 @@ class Parser:
@tracer.trace_method
def factor(self, mandatory: bool = False) -> Value:
if self.accept(Tokens.Parens_Left):
v = self.expression()
v = self.expression(mandatory=True)
self.expect(Tokens.Parens_Right)
return v
elif num := self.number():
elif num := self.number(mandatory=False):
return num
elif variable := self.variable():
elif call := self.call(mandatory=False):
return call
elif variable := self.variable(mandatory=False):
return variable
elif mandatory:
raise UnexpectedTokenError(self.token, "parenthesized expression, number or variable")
@ -141,6 +143,22 @@ class Parser:
elif mandatory:
raise UnexpectedTokenError(self.token, "assignment")
@tracer.trace_method
def call(self, mandatory: bool = False) -> Call:
if self.peek_several(Tokens.Identifier, Tokens.Parens_Left):
ident = self.identifier(mandatory=True)
lparens = self.expect(Tokens.Parens_Left)
expressions: list[Expression] = []
if expr := self.expression(mandatory=False):
expressions += [expr]
while self.accept(Tokens.Comma):
expressions += [self.expression(mandatory=True)]
rparens = self.expect(Tokens.Parens_Right)
return Call(identifier=ident, arguments=expressions,
pseudo_nodes=[PseudoNode(lparens), PseudoNode(rparens)])
elif mandatory:
raise UnexpectedTokenError(self.token, "function call")
@tracer.trace_method
def definition(self, mandatory: bool = False) -> Definition:
if let_kw := self.accept(Tokens.KwLet):