コード例 #1
0
 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
コード例 #2
0
    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
コード例 #3
0
    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
コード例 #4
0
    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
コード例 #5
0
    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
コード例 #6
0
    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
コード例 #7
0
    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])
コード例 #8
0
    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
コード例 #9
0
    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
コード例 #10
0
    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
コード例 #11
0
 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)