Example #1
0
    def exec_Call(self, node, scope):
        #first let's find out which function should be called. This should be easy when doing func()
        #call, but it can be tricky when using constructs such as 'a.b.c.func()'
        self_type=None
        #covers func() case
        if isinstance(node.func,ast.Name):
            logger.debug("? exec_Call "+node.func.id +" "+str(node))
            call_type=scope.resolve(node.func.id,'cascade')
        #covers a.b.c.func() case
        elif isinstance(node.func, ast.Attribute):
            logger.debug("? exec_Call "+node.func.attr +" "+str(node))
            call_type=self.eval_code(node.func, scope)
            if typez.is_none(call_type):
                self.warn(node.func, message='nonexistent_attribute', symbol=node.func.attr)
                return typez.none_type

            #whether we are dealing with function or with a method should be already resolved by
            #exec_Attribute
            if hasattr(call_type, 'is_method'):
                if call_type.is_method:
                    self_type=self.eval_code(node.func.value, scope)
        else:
            raise Exception('should not get here')

        #now we know what to invoke. Now we must distinguist whether it is func/method call or 'new'
        #statement.

        #Call-ing function or method
        if call_type.kind=='func':
            args=[self.eval_code(arg,scope) for arg in node.args]
            if self_type:
                args=[self_type]+args
            return self._exec_fun(call_type, args, call_type.scope)

        #Call-ing as a 'new' statement 
        if call_type.kind=='class':
            args=[self.eval_code(arg,scope) for arg in node.args]
            new=Typez(kind='obj', scope=Scope(parent=call_type.scope))
            args=[new]+args
            new.scope['__class__']=call_type
            constructor=call_type.resolve('__init__', 'straight')
            new.obj=self._exec_fun(constructor, args, new.scope)
            return new
        raise Exception('calling node must be either function or class')
Example #2
0
    def exec_Call(self, node, scope):
        #first let's find out which function should be called. This should be easy when doing func()
        #call, but it can be tricky when using constructs such as 'a.b.c.func()'

        #covers func() case
        if isinstance(node.func, ast.Name):
            logger.debug("? exec_Call "+node.func.id +" "+str(node))
            call_type = scope.resolve(node.func.id,'cascade')
            if call_type is None:
               call_type = any_type 
        #covers a.b.c.func() case
        elif isinstance(node.func, ast.Attribute):
            logger.debug("? exec_Call "+node.func.attr +" "+str(node))
            call_type = self.eval_code(node.func, scope)
            if call_type.kind == 'any':
                return any_type

        else:
            raise Exception('should not get here')

        #now we know what to invoke. Now we must distinguish whether it is func/method call or 'new'
        #statement.

        #TODO: dorobit spustanie 'any' kind
        #Call-ing function or method
        if call_type.kind == 'func':
            args = [self.eval_code(arg, scope) for arg in node.args]
            if call_type.is_method:
                args = [call_type.self_obj]+args
            return self._exec_fun(call_type, args, call_type.scope, node=node)

        #Call-ing as a 'new' statement 
        if call_type.kind == 'class':
            args = [self.eval_code(arg,scope) for arg in node.args]
            new = Typez(kind = 'obj', parent_scope = scope)
            args = [new]+args
            new.scope['__class__'] = call_type
            constructor = call_type.resolve('__init__', 'class')
            if constructor:
                new.obj = self._exec_fun(constructor, args, new.scope, node=node)
            return new
        self.warn(node, message = 'nonexistent_function', symbol = node.func.id)