def visit(self, node: cool_ast.MethodDeclarationNode, scope: Scope) -> None: function = self.functions.get_function(self.current_type, self.current_method.name) for param_type, param in zip(function.params_types, node.params): scope.define_variable(param.id, param_type) body_type = self.visit(node.body, scope) self.unify(function.return_type, body_type)
def visit(self, node: cool_ast.VarDeclarationNode, scope: Scope) -> Type: try: var_type = self.context.get_type(node.typex) except SemanticError: return TypeVariable() if node.typex == "AUTO_TYPE": var_type = TypeVariable() if node.expr is not None: expr_type = self.visit(node.expr, scope) self.unify(var_type, expr_type) scope.define_variable(node.id, var_type) return var_type
def visit(self, node: cool_ast.VarDeclarationNode, scope: Scope): try: var_type = self.context.get_type(node.typex) except SemanticError as error: self.errors.append(str(error)) var_type = ErrorType() if scope.is_defined(node.id): self.errors.append(LOCAL_ALREADY_DEFINED % (node.id, self.current_method.name)) else: scope.define_variable(node.id, var_type) expr_type = self.visit(node.expr, scope) if not expr_type.conforms_to(var_type): self.errors.append(INCOMPATIBLE_TYPES % (expr_type.name, var_type.name))
def visit(self, node: cool_ast.ClassDeclarationNode, scope: Scope) -> None: attrs = [ feature for feature in node.features if isinstance(feature, cool_ast.AttrDeclarationNode) ] methods = [ feature for feature in node.features if isinstance(feature, cool_ast.MethodDeclarationNode) ] scope.define_variable('self', self.current_type) for attr in attrs: self.visit(attr, scope) for method in methods: self.current_method = self.current_type.get_method(method.id) self.visit(method, scope.create_child())
def visit(self, node: cool_ast.ClassDeclarationNode, scope: Scope): self.current_type: Type = self.context.get_type(node.id) scope.define_variable('self', self.current_type) for feature in node.features: self.visit(feature, scope)