コード例 #1
0
 def visit(self, node: VariableNode, scope: Scope):
     try:
         typex = scope.find_local(node.lex).type
         name = self.toVarName(node.lex)
         return name, Utils.GetType(typex, self.current[TYPE])
     except:
         var_info = scope.find_attribute(node.lex)
         local_var = self.generateLocalNode(var_info.name)
         self.saveCilInstruction(CILGetAttribNode(
             SELF_LOWERCASE, var_info.name, self.current[TYPE].name, local_var, var_info.type.name))
         return local_var, Utils.GetType(var_info.type, self.current[TYPE])
コード例 #2
0
    def visit(self, node:FuncDeclarationNode, scope:Scope):
        parent = self.current_type.parent
        method = self.current_type.get_method(node.id, node.pos)
        self.current_method = self.current_type.get_method(node.id, node.pos)

        if parent is not None:
            try:
                old_method = parent.get_method(node.id, node.pos)
                if old_method.return_type.name != method.return_type.name:
                    error_text = SemanticError.WRONG_SIGNATURE_RETURN % (node.id, method.return_type.name, old_method.return_type.name)
                    self.errors.append(SemanticError(*node.type_pos, error_text))
                if len(method.param_names) != len(old_method.param_names):
                    error_text = SemanticError.WRONG_NUMBER_PARAM % node.id
                    self.errors.append(SemanticError(*node.pos, error_text))
                for (name,param),type1,type2 in zip(node.params, method.param_types, old_method.param_types):
                    if type1.name != type2.name:
                        error_text = SemanticError.WRONG_SIGNATURE_PARAMETER % (name, type1.name, type2.name)
                        self.errors.append(SemanticError(*param.pos, error_text))
            except SemanticError:
                pass

        result = self.visit(node.body, scope)
        return_type = Utils.GetType(method.return_type, self.current_type)

        if not result.conforms_to(return_type):
            error_text = TypesError.RETURN_TYPE_ERROR % (result.name, return_type.name)
            self.errors.append(TypesError(*node.type_pos, error_text))
コード例 #3
0
 def visit(self, node:InstantiateNode, scope:Scope):
     try:
         typex = self.context.get_type(node.lex, node.pos)
     except SemanticError:
         typex = ErrorType()
         error_text = TypesError.NEW_UNDEFINED_CLASS % node.lex
         self.errors.append(TypesError(*node.pos, error_text))
     return Utils.GetType(typex, self.current_type)
コード例 #4
0
 def visit(self, node:AssignNode, scope:Scope):
     var_info = self.find_variable(scope, node.id)
     var_type = Utils.GetType(var_info.type, self.current_type) 
     typex = self.visit(node.expr, scope)
     if not typex.conforms_to(var_type):
         error_text = TypesError.UNCONFORMS_TYPE % (typex.name, node.id, var_type.name)
         self.errors.append(TypesError(*node.pos, error_text))
     return typex
コード例 #5
0
 def visit(self, node:VarDeclarationNode, scope:Scope):
     var_type = self._get_type(node.type, node.type_pos)
     var_type = Utils.GetType(var_type, self.current_type)
     if node.expr != None:
         typex = self.visit(node.expr, scope)
         if not typex.conforms_to(var_type):
             error_text = TypesError.UNCONFORMS_TYPE % (typex.name, node.id, var_type.name)
             self.errors.append(TypesError(*node.type_pos, error_text))
         return typex
     return var_type
コード例 #6
0
    def visit(self, node:AttrDeclarationNode, scope:Scope):
        attr = self.current_type.get_attribute(node.id, node.pos)
        var_type = Utils.GetType(attr.type, self.current_type)
        typex = self.visit(node.expr, scope)

        if not typex.conforms_to(var_type):
            error_text = TypesError.ATTR_TYPE_ERROR % (typex.name, attr.name, var_type.name)
            self.errors.append(TypesError(*node.pos, error_text))
            return ErrorType()
        return typex
コード例 #7
0
    def visit(self, node: InstantiateNode, scope: Scope):
        instance = self.generateLocalNode(LOCAL)
        typex = self.context.get_type(node.lex, node.pos)
        typex = Utils.GetType(typex, self.current[TYPE])
        self.saveCilInstruction(CILAllocateNode(typex.name, instance))

        if typex.all_attributes():
            self.saveCilInstruction(CILStaticCallNode(
                typex.name, typex.name, instance, [CILArgNode(instance)], typex.name))

        return instance, typex
コード例 #8
0
    def visit(self, node: VarDeclarationNode, scope: Scope):
        var_info = scope.find_variable(node.id)
        vtype = Utils.GetType(var_info.type, self.current[TYPE])
        local_var = self.generateLocalNode(var_info.name)

        value, typex = self.visit(node.expr, scope)
        if vtype.name == OBJECT and typex.name in [STRING, INT, BOOL]:
            self.saveCilInstruction(CILBoxingNode(local_var, typex.name))
        else:
            self.saveCilInstruction(CILAssignNode(local_var, value))
        return local_var, vtype
コード例 #9
0
 def visit(self, node:BaseCallNode, scope:Scope):
     obj = self.visit(node.obj, scope)
     typex = self._get_type(node.type, node.type_pos)
     if not obj.conforms_to(typex):
         error_text = TypesError.INCOMPATIBLE_TYPES_DISPATCH % (typex.name, obj.name)
         self.errors.append(TypesError(*node.type_pos, error_text))
         return ErrorType()
     method = self._get_method(typex, node.id, node.pos)
     if not isinstance(method, MethodError):
         self.check_args(method, scope, node.args, node.pos)
     return Utils.GetType(method.return_type, typex)
コード例 #10
0
 def rt_type(self, typex: Type, node):
     meth = typex.get_method(node.id, node.pos)
     return Utils.GetType(meth.return_type, self.current[TYPE])
コード例 #11
0
 def visit(self, node:VariableNode, scope:Scope):
     typex = self.find_variable(scope, node.lex).type
     return Utils.GetType(typex, self.current_type)
コード例 #12
0
 def visit(self, node:StaticCallNode, scope:Scope):
     typex = self.current_type
     method = self._get_method(typex, node.id, node.pos)
     if not isinstance(method, MethodError):
         self.check_args(method, scope, node.args, node.pos)
     return Utils.GetType(method.return_type, typex)
コード例 #13
0
 def visit(self, node:CallNode, scope:Scope):
     stype = self.visit(node.obj, scope)
     method = self._get_method(stype, node.id, node.pos)
     if not isinstance(method, MethodError):
         self.check_args(method, scope, node.args, node.pos)
     return Utils.GetType(method.return_type, stype)