import hutn_compiler.symbol_table as st from hutn_compiler.visitor import Visitor from hutn_compiler.hutnparser import Tree # Declare the function but do not visit its body class DeclareFunctionsVisitor(Visitor): def __init__(self, symbol_table, inputfiles): Visitor.__init__(self, []) self.symbol_table = symbol_table self.inputfiles = inputfiles def compute_parameter_types(self, tree): parameter_types = [] for parameter in Tree.get_children(tree, 'parameter'): type_specifier = Tree.get_text(Tree.get_children(parameter, "type_specifier")[0]) parameter_types.append(type_specifier) return parameter_types def compute_func_type(self, tree): self.visit(Tree.get_tail(tree)[0]) func_type = self.get_type(Tree.get_tail(tree)[0]) return func_type def visit_funcdecl(self, tree): func_name = Tree.get_text(Tree.get_children(tree, "func_name")[0]) func_type = self.compute_func_type(tree) parameter_types = self.compute_parameter_types(tree) self.set_type(tree, func_type) #TODO should check type compatibility if declared multiple times try: s = {"name": func_name, "type": func_type, "is_global": True, "node": None, "params": parameter_types} self.symbol_table.add(s) except Exception: if "COLON" in Tree.get_tail(tree) or "ASSIGN" in Tree.get_tail(tree): raise RuntimeError( "{}:{}:{}: error: redeclaration of '{}'".format( self.inputfiles[0], tree['startpos']['line'], tree['startpos']['column'], func_name)) self.set_symbol(tree, s) def visit_func_type(self, tree): self.set_type(tree, Tree.get_text(tree))