예제 #1
0
    def visit(self, node):
        arg_names, arg_types = [], []
        for ids, types in node.params:
            try:
                arg_type = self.context.get_type(types.lex)
            except SemanticError as se:
                self.errors.append(ERROR_ON_LN_COL % (node.line, node.column) +
                                   se.text)
                arg_type = ErrorType()
            else:
                if isinstance(arg_type, SelfType):
                    self.errors.append(
                        ERROR_ON_LN_COL % (node.line, node.column) +
                        f'Type "{arg_type.name}" can not be used as a parameter type'
                    )
                    arg_type = ErrorType()

            arg_names.append(ids.lex)
            arg_types.append(arg_type)

        try:
            ret_type = self.context.get_type(node.type.lex)
        except SemanticError as se:
            self.errors.append(ERROR_ON_LN_COL % (node.line, node.column) +
                               se.text)
            ret_type = ErrorType()

        try:
            self.current_type.define_method(node.id.lex, arg_names, arg_types,
                                            ret_type)
        except SemanticError as se:
            self.errors.append(ERROR_ON_LN_COL % (node.line, node.column) +
                               se.text)
예제 #2
0
    def visit(self, node, scope):
        obj_type = self.current_type
        
        try:
            obj_method = obj_type.get_method(node.id.lex)
                       
            node_type = obj_type if isinstance(obj_method.return_type, SelfType) else obj_method.return_type
        except SemanticError as ex:
            self.errors.append(ERROR_ON_LN_COL % (node.line, node.column) + ex.text)
            node_type = ErrorType()
            obj_method = None

        for arg in node.args:
            self.visit(arg, scope.create_child())

        if obj_method and len(node.args) == len(obj_method.param_types):
            for arg, param_type in zip(node.args, obj_method.param_types):
                arg_type = arg.static_type
                    
                if not arg_type.conforms_to(param_type):
                    self.errors.append(ERROR_ON_LN_COL % (arg.line, arg.column) + INCOMPATIBLE_TYPES % (arg_type.name, param_type.name))
        else:
           self.errors.append(ERROR_ON_LN_COL % (node.line, node.column) + f'Method "{node.id.lex}" canot be dispatched')
            
        node.static_type = node_type
예제 #3
0
    def visit(self, node, scope, expected_type=None):
        try:
            node_type = self.context.get_type(node.type.lex)
        except SemanticError:
            node_type = ErrorType()

        node.static_type = node_type
예제 #4
0
 def visit(self, node, scope):
     try:
         node_type = self.context.get_type(node.type.lex)
     except SemanticError as ex:
         self.errors.append(ERROR_ON_LN_COL % (node.line, node.column) + ex.text)
         node_type = ErrorType()
         
     node.static_type = node_type
예제 #5
0
 def visit(self, node, scope):
     if scope.is_defined(node.token.lex):
         var = scope.find_variable(node.token.lex)
         node_type = var.type       
     else:
         self.errors.append(ERROR_ON_LN_COL % (node.line, node.column) + VARIABLE_NOT_DEFINED % (node.token.lex, self.current_method.name))
         node_type = ErrorType()
     
     node.static_type = node_type
예제 #6
0
    def visit(self, node, scope, expected_type=None):
        if scope.is_defined(node.token.lex):
            var = scope.find_variable(node.token.lex)

            if expected_type:
                var.set_calls(expected_type)

            node_type = var.type if var.infered else AutoType()
        else:
            node_type = ErrorType()

        node.static_type = node_type
예제 #7
0
    def visit(self, node):
        try:
            attr_type = self.context.get_type(node.type.lex)
        except SemanticError as se:
            self.errors.append(ERROR_ON_LN_COL % (node.line, node.column) +
                               se.text)
            attr_type = ErrorType()

        try:
            self.current_type.define_attribute(node.id.lex, attr_type)
        except SemanticError as se:
            self.errors.append(ERROR_ON_LN_COL % (node.line, node.column) +
                               se.text)
예제 #8
0
    def visit(self, node, scope, expected_type=None):
        node_type = None
        if node.type:
            try:
                node_type = self.context.get_type(node.type.lex)
            except SemanticError:
                node_type = ErrorType()
            else:
                if isinstance(node_type, SelfType) or isinstance(
                        node_type, AutoType):
                    node_type = ErrorType()

        self.visit(node.obj, scope.children[0], node_type)
        obj_type = node.obj.static_type

        try:
            obj_type = node_type if node_type else obj_type

            obj_method = obj_type.get_method(node.id.lex)

            # setear el expected_type al retorno
            node_type = obj_type if isinstance(
                obj_method.return_type, SelfType) else obj_method.return_type
        except SemanticError:
            node_type = ErrorType()
            obj_method = None

        if obj_method and len(node.args) == len(obj_method.param_types):
            for arg, var, child_scope in zip(node.args, obj_method.param_infos,
                                             scope.children[1:]):
                self.visit(arg, child_scope, var.type if var.infered else None)
                # inferir var.type por arg_type
        else:
            for arg, child_scope in zip(node.args, scope.children[1:]):
                self.visit(arg, child_scope)

        node.static_type = node_type
예제 #9
0
    def visit(self, node, scope):
        self.visit(node.expression, scope.create_child())

        node.static_type = None

        for idx, typex, expr in node.branches:
            try:
                node_type = self.context.get_type(typex.lex)
            except SemanticError as ex:
                self.errors.append(ERROR_ON_LN_COL % (typex.line, typex.column) + ex.text)
                node_type = ErrorType()
            else:
                if isinstance(node_type, SelfType) or isinstance(node_type, AutoType):
                    self.errors.append(ERROR_ON_LN_COL % (typex.line, typex.column) + f'Type "{node_type.name}" can not be used as case type')
                    node_type = ErrorType()

            id_type = node_type

            child_scope = scope.create_child()
            child_scope.define_variable(idx.lex, id_type)
            self.visit(expr, child_scope)
            expr_type = expr.static_type

            node.static_type = node.static_type.type_union(expr_type) if node.static_type else expr_type
예제 #10
0
    def visit(self, node, scope):
        for idx, typex, expr in node.let_body:
            try:
                node_type = self.context.get_type(typex.lex)
            except SemanticError as ex:
                self.errors.append(ERROR_ON_LN_COL % (typex.line, typex.column) + ex.text)
                node_type = ErrorType()
            
            id_type = self.current_type if isinstance(node_type, SelfType) else node_type
            child = scope.create_child()

            if expr:
                self.visit(expr, child)
                expr_type = expr.static_type
                if not expr_type.conforms_to(id_type):
                    self.errors.append(ERROR_ON_LN_COL % (expr.line, expr.column) + INCOMPATIBLE_TYPES % (expr_type.name, id_type.name))

            scope.define_variable(idx.lex, id_type)

        self.visit(node.in_body, scope.create_child())

        node.static_type = node.in_body.static_type