def visit(self, node, scope=None): scope = Scope() self.current_function = self.register_function('main') instance = self.define_internal_local(scope=scope, name="instance") result = self.define_internal_local(scope=scope, name="result") self.register_instruction(CIL_AST.Allocate('Main', self.context.get_type('Main').tag, instance)) self.register_instruction(CIL_AST.Call(result, 'Main_init', [CIL_AST.Arg(instance)], "Main")) self.register_instruction( CIL_AST.Call(result, self.to_function_name('main', 'Main'), [CIL_AST.Arg(instance)], "Main")) self.register_instruction(CIL_AST.Return(None)) self.current_function = None self.register_data('Abort called from class ') self.register_data('\n') self.dotdata['empty_str'] = '' # Add built-in types in .TYPES section self.register_builtin_types(scope) # Add string equals function self.build_string_equals_function(scope) for klass in node.declarations: self.visit(klass, scope.create_child()) return CIL_AST.Program(self.dottypes, self.dotdata, self.dotcode)
def visit(self, node: BranchNode, scope: Scope, types_used, return_of_case): error_type = self.context.get_type(BasicTypes.ERROR.value) try: var_type = self.context.get_type(node.type) except SemanticError as error: self.errors.append(TYPE_ERROR % (node.lineno, node.colno, error.text)) var_type = error_type if var_type.name != BasicTypes.ERROR.value: if var_type.name in types_used: self.errors.append(SEMANTIC_ERROR % ( node.lineno, node.colno, f'In method "{self.current_method.name}", type "{self.current_type.name}", more than one ' f'branch variable has type "{var_type.name}". ')) types_used.add(var_type.name) self.scope_id += 1 child_scope = scope.create_child(self.scope_id) if node.id == "self": self.errors.append(TYPE_ERROR % ( node.lineno, node.colno, f'In method "{self.current_method.name}", type "{self.current_type.name}", a branch has "self" as ' f"variable name. ")) else: child_scope.define_variable(node.id, var_type) expr_type = self.visit(node.action, child_scope) if return_of_case is None: return_of_case = expr_type return_of_case = self.context.find_first_common_ancestor( expr_type, return_of_case) return return_of_case
def visit(self, node, scope=None): if scope is None: scope = Scope() for declaration in node.declarations: current = self.context.get_type(declaration.id) parent = current.parent while parent is not None: current.depth += 1 parent = parent.parent for declaration in node.declarations: self.visit(declaration, scope.create_child()) return scope
def visit(self, node, scope=None, set_type=None): to_revisit = [] scope = Scope(self.scope_id) self.scope_id += 1 for declaration in node.declarations: child_scope = scope.create_child(self.scope_id) self.scope_id += 1 visited = self.visit(declaration, child_scope) if not visited: to_revisit.append(declaration) while to_revisit: declaration = to_revisit.pop(0) visited = self.visit(declaration, None) if not visited: to_revisit.append(declaration) return scope