From a092c11216c3af2740e7519ce62a9fa3521bf61c Mon Sep 17 00:00:00 2001 From: Antoine Viallon Date: Tue, 23 May 2023 23:23:20 +0200 Subject: [PATCH] nodes: add Call node --- compiler/nodes.py | 49 +++++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 47 insertions(+), 2 deletions(-) diff --git a/compiler/nodes.py b/compiler/nodes.py index 115afc0..b0c0982 100644 --- a/compiler/nodes.py +++ b/compiler/nodes.py @@ -327,8 +327,53 @@ class Variable(Node): assert self.value is not None dest = ir.IRRegister(location=self.location()) - immediate = ir.IRVariable(location=self.location(), fq_identifier=self.value.fully_qualified_name()) - result = [ir.IRMove(location=self.location(), dest=dest, source=immediate)] + source = ir.IRVariable(location=self.location(), fq_identifier=self.value.fully_qualified_name()) + result = [ir.IRMove(location=self.location(), dest=dest, source=source)] + return result + + +class Call(Node): + def __init__(self, identifier: Identifier, arguments: list[Value], pseudo_nodes: list[PseudoNode] | None = None): + super().__init__() + self.value: semantic.Variable | None = None + self.identifier = identifier + self.arguments = arguments + self.pseudo_nodes = pseudo_nodes + + def _values(self) -> list[Node | Any]: + nodes: list[Node] = [self.identifier] + nodes += self.arguments + if self.pseudo_nodes is not None: + nodes += self.pseudo_nodes + return nodes + + @property + def pure(self) -> bool: + return False + + def semantic_analysis(self, context: semantic.Context): + super(Call, self).semantic_analysis(context) + + variable = context.get_variable(self.identifier.value) + if variable is None: + raise SemanticAnalysisError(location=self.location(), message=f"Unknown function '{self.identifier.value}'") + + if not isinstance(variable.type, semantic.Function): + raise SemanticAnalysisError(location=self.location(), message=f"'{self.identifier.value}' is not callable") + + self.value = variable + logger.debug(f"Linked function reference to function {variable}") + + def intermediate_representation(self) -> list[ir.IRItem]: + assert self.value is not None + + result: list[ir.IRAction] = [] + + arguments_results = Node._prepare_sources_ir(result=result, values=self.arguments) + + dest = ir.IRRegister(location=self.location()) + function = ir.IRVariable(location=self.location(), fq_identifier=self.value.fully_qualified_name()) + result += [ir.IRCall(location=self.location(), dest=dest, function=function, arguments=arguments_results)] return result