def walkNodeFuncDecl(self, node: NodeFuncDecl, scope: Scope): func = Function(node.return_type, None, None) # NOTE: This is jank ?MAYBE? just use the the Functionparam class of the interpreter? # Also note that the variable identifier is not used to build the signature it's just add. info. func_sign = FuncSign( node.identifier, [Functionparam(p[0], p[1]) for p in node.parameters]) scope.addSymbol(func_sign, func)
def walkNodeBlockStatements(self, node: NodeBlockStatements, scope: Scope, copy_scope: Scope = None): block_scope = copy_scope if copy_scope else Scope(scope) for statement in node.statements: self.walkNode(statement, block_scope)
def walkNodeFuncDef(self, node: NodeFuncDef, scope: Scope): func_sign = FuncSign( node.identifier, [Functionparam(p[0], p[1]) for p in node.parameters]) func: Function = scope.translate(func_sign) if not func: self._raise(node, scope, "Function not declared") func.body = node.block func.parameters = node.parameters
def walkNodeFuncCall(self, node: NodeFuncCall, scope: Scope): # @HACK: passing node.arguments instead of proper parameter list because we know only the length # will be used to generate the function signature func_sign = FuncSign(node.identifier, node.arguments) func: Function = scope.translate(func_sign) if not func: self._raise(node, scope, "Function not declared") copy_scope = Scope(scope) for arg_expr, var in zip(node.arguments, func.parameters): # TODO: typecheck type (var[0]) agains type of var_value var_sign = VariableSign(var[1]) var_value = Variable(var[0], self.walkNode(arg_expr, scope)) copy_scope.addSymbol(var_sign, var_value) # Don't dispatch because we need to set the scope try: self.walkNodeBlockStatements(func.body, scope, copy_scope) except Return as e: # TODO: check type? return e.ret_value
def walkNodeFor(self, node: NodeFor, scope: Scope): block_scope = Scope(scope) self.walkNode(node.initialization, block_scope) while self.walkNode(node.condition, block_scope): try: self.walkNode(node.body, block_scope) except Break as b: break except Continue as c: pass self.walkNode(node.loop_excution, block_scope)
def walkNodeVariableAssign(self, node: NodeVariableAssign, scope: Scope): var: Variable = scope.translate(VariableSign(node.identifier)) if not var: self._raise(node, scope, "Variable not declared") var.value = self.walkNode(node.node, scope)
def walkNodeVariableDecl(self, node: NodeVariableDecl, scope: Scope): var = Variable(node.type) # wrapping this wouldn't strictly be neccessary but it keeps things clean var_sign = VariableSign(node.identifier) scope.addSymbol(var_sign, var)
def walkNodeVariable(self, node: NodeVariable, scope: Scope): var_sign = VariableSign(node.identifier) var: Variable = scope.translate(var_sign) if not var: self._raise(node, scope, "Variable not declared") return var.value
def __init__(self, ast: Node): # The complete ast self.ast = ast self.global_scope = Scope(None)