def visit(self, node: ast.VariableNode, scope: Scope): variable = scope.find_variable(node.lex) if variable is None: self.errors.append(err.VARIABLE_NOT_DEFINED % (node.lex, self.current_method.name)) return ErrorType() return variable.type
def visit(self, node: ast.AssignNode, scope: Scope): variable_info = scope.find_variable(node.id) if variable_info is None: self.current_instance.set_attribute_instance(node.id, self.visit(node.expr, scope)) return self.current_instance.get_attribute_instance(node.id) variable_info.instance = self.visit(node.expr, scope) return variable_info.instance
def visit(self, node: ast.VariableNode, scope: Scope): var_info = scope.find_variable(node.lex) if var_info is not None: if var_info.type.name == "AUTO_TYPE": return self.variables[var_info] else: return AtomNode(var_info.type) else: return None
def visit(self, node: ast.AttrDeclarationNode, scope: Scope): attr_type = self.context.get_type(node.type) var_info = scope.find_variable(node.id) if node.expr is not None: self.visit(node.expr, scope.children[node.index]) if attr_type == self.context.get_type("AUTO_TYPE"): if var_info.type == self.context.get_type("AUTO_TYPE"): self.errors.append(err.INFERENCE_ERROR_ATTRIBUTE % node.id) node.type = var_info.type.name
def visit(self, node: ast.VariableNode, scope: Scope): variable = scope.find_variable(node.lex) if variable is None: if self.current_attribute is not None: name = self.current_attribute.name else: name = self.current_method.name self.errors.append(err.UNDEFINED_VARIABLE % (node.line, node.column, node.lex, name)) return ErrorType() return variable.type
def visit(self, node: ast.AssignNode, scope: Scope): var_info = scope.find_variable(node.id) expr_type = self.visit(node.expr, scope.create_child()) if var_info is None: self.errors.append(err.VARIABLE_NOT_DEFINED % (node.id, self.current_method.name)) else: if not expr_type.conforms_to(var_info.type): self.errors.append(err.INCOMPATIBLE_TYPES % (expr_type.name, var_info.type.name)) return expr_type
def visit(self, node: ast.LetNode, scope: Scope): child_index = 0 for i, (_id, _type, _expr) in enumerate(node.declarations): variable_info = scope.find_variable(_id) if _expr is not None: self.visit(_expr, scope.children[child_index]) child_index += 1 if _type == "AUTO_TYPE": if variable_info.type == self.context.get_type("AUTO_TYPE"): self.errors.append(err.INFERENCE_ERROR_ATTRIBUTE % _id) node.declarations[i] = (_id, variable_info.type.name, _expr) self.visit(node.expr, scope.children[child_index])
def visit(self, node: ast.MethodDeclarationNode, scope: Scope): self.current_method = self.current_type.get_method(node.id) return_type = self.context.get_type(node.return_type) for i, (name, expr_body_type) in enumerate(node.params): variable_info = scope.find_variable(name) if variable_info.type == self.context.get_type('AUTO_TYPE'): self.errors.append(err.INFERENCE_ERROR_ATTRIBUTE % name) node.params[i] = (name, variable_info.type.name) self.visit(node.body, scope) if return_type == self.context.get_type('AUTO_TYPE'): if self.current_method.return_type == self.context.get_type('AUTO_TYPE'): self.errors.append(err.INFERENCE_ERROR_ATTRIBUTE % node.id) node.return_type = self.current_method.return_type.name
def visit(self, node: ast.AssignNode, scope: Scope): var_info = scope.find_variable(node.id) expr_node = self.visit(node.expr, scope.create_child()) if var_info is not None: if expr_node.type.name != 'AUTO_TYPE' and var_info.type.name == 'AUTO_TYPE': self.graph.add_edge(expr_node, self.variables[var_info]) elif var_info.type.name != 'AUTO_TYPE' and expr_node.type.name == 'AUTO_TYPE': self.graph.add_edge(AtomNode(self.context.get_type(var_info.type.name)), expr_node) elif var_info.type.name == 'AUTO_TYPE' and expr_node.type.name == 'AUTO_TYPE': # Create a cycle self.graph.add_edge(expr_node, self.variables[var_info]) self.graph.add_edge(self.variables[var_info], expr_node) else: pass return expr_node
def visit(self, node: ast.AssignNode, scope: Scope): var_info = scope.find_variable(node.id) if var_info.name == "self": self.errors.append(err.SELF_IS_READONLY % (node.line, node.column)) expr_type = self.visit(node.expr, scope.create_child()) if var_info is None: self.errors.append( err.UNDEFINED_VARIABLE % (node.line, node.column, node.id, self.current_method.name)) else: if not expr_type.conforms_to(var_info.type): self.errors.append(err.INCOMPATIBLE_TYPES % (node.line, node.column, expr_type.name, var_info.type.name)) return expr_type
def visit(self, node: ast.VariableNode, scope: Scope): variable_info = scope.find_variable(node.lex) if variable_info is not None: return variable_info.instance else: return self.current_instance.get_attribute_instance(node.lex)