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')
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)