def call(self, frame, anchor, args, kwargs): from pyntch.basic_types import StrType from pyntch.aggregate_types import DictType, TupleType from pyntch.expression import TupleUnpack, TupleSlice # Process keyword arguments first. varsleft = list(self.argvars) varikwargs = [] for (kwname, kwvalue) in kwargs.iteritems(): for var1 in varsleft: if isinstance(var1, Variable) and var1.name == kwname: var1.bind(kwvalue) # When a keyword argument is given, remove that name from the remaining arguments. varsleft.remove(var1) break else: if self.kwarg: varikwargs.append(kwvalue) else: frame.raise_expt(ErrorConfig.InvalidKeywordArgs(kwname)) # Process standard arguments. variargs = [] for arg1 in args: assert arg1 != None, args if varsleft: var1 = varsleft.pop(0) assign_arg(frame, anchor, var1, arg1) elif self.variarg: variargs.append(arg1) else: # Too many arguments. frame.raise_expt( ErrorConfig.InvalidNumOfArgs(len(self.argvars), len(args))) if len(self.defaults) < len(varsleft): # Too few arguments. frame.raise_expt( ErrorConfig.InvalidNumOfArgs(len(self.argvars), len(args))) # Handle remaining arguments: kwargs and variargs. if self.variarg and variargs: self.space[self.variarg].bind(TupleType.create_tuple(variargs)) if self.kwarg: if varikwargs: self.space[self.kwarg].bind( DictType.create_dict(key=StrType.get_object(), value=varikwargs)) else: self.space[self.kwarg].bind(DictType.create_null( frame, anchor)) # Remember where this is called from. self.frames.add(frame) # Propagate the exceptions upward. self.frame.connect(frame.recv) return self.body
def call(self, frame, anchor, args, kwargs): from pyntch.basic_types import StrType from pyntch.aggregate_types import DictType, TupleType from pyntch.expression import TupleUnpack, TupleSlice # Process keyword arguments first. varsleft = list(self.argvars) varikwargs = [] for (kwname, kwvalue) in kwargs.iteritems(): for var1 in varsleft: if isinstance(var1, Variable) and var1.name == kwname: var1.bind(kwvalue) # When a keyword argument is given, remove that name from the remaining arguments. varsleft.remove(var1) break else: if self.kwarg: varikwargs.append(kwvalue) else: frame.raise_expt(ErrorConfig.InvalidKeywordArgs(kwname)) # Process standard arguments. variargs = [] for arg1 in args: assert arg1 != None, args if varsleft: var1 = varsleft.pop(0) assign_arg(frame, anchor, var1, arg1) elif self.variarg: variargs.append(arg1) else: # Too many arguments. frame.raise_expt(ErrorConfig.InvalidNumOfArgs(len(self.argvars), len(args))) if len(self.defaults) < len(varsleft): # Too few arguments. frame.raise_expt(ErrorConfig.InvalidNumOfArgs(len(self.argvars), len(args))) # Handle remaining arguments: kwargs and variargs. if self.variarg and variargs: self.space[self.variarg].bind(TupleType.create_tuple(variargs)) if self.kwarg: if varikwargs: self.space[self.kwarg].bind(DictType.create_dict(key=StrType.get_object(), value=varikwargs)) else: self.space[self.kwarg].bind(DictType.create_null(frame, anchor)) # Remember where this is called from. self.frames.add(frame) # Propagate the exceptions upward. self.frame.connect(frame.recv) return self.body
def recv_target(self, src): from pyntch.aggregate_types import DictType for obj in src: if obj in self.received: continue self.received.add(obj) if obj.is_type(DictType.get_typeobj()): MethodCall(self.frame, self.anchor, obj, 'iteritems').connect(self.recv) else: self.raise_expt(ErrorConfig.TypeCheckerError(src, obj, 'dict')) return
def build_expr(reporter, frame, space, tree, evals): from pyntch.basic_types import BUILTIN_OBJECT, IntType from pyntch.aggregate_types import IterType, GeneratorType, ListType, SetType, DictType, TupleType if isinstance(tree, ast.Const): typename = type(tree.value).__name__ expr = BUILTIN_OBJECT[typename] elif isinstance(tree, ast.Name): try: expr = space[tree.name] except KeyError: ExecutionFrame(frame, tree).raise_expt(ErrorConfig.NameUndefined(tree.name)) expr = UndefinedTypeNode(tree.name) elif isinstance(tree, ast.CallFunc): func = build_expr(reporter, frame, space, tree.node, evals) args = tuple( build_expr(reporter, frame, space, arg1, evals) for arg1 in tree.args if not isinstance(arg1, ast.Keyword) ) kwargs = dict( (arg1.name, build_expr(reporter, frame, space, arg1.expr, evals)) for arg1 in tree.args if isinstance(arg1, ast.Keyword) ) star = dstar = None if tree.star_args: star = build_expr(reporter, frame, space, tree.star_args, evals) if tree.dstar_args: dstar = build_expr(reporter, frame, space, tree.dstar_args, evals) expr = FunCall(ExecutionFrame(frame, tree), tree, func, args, kwargs, star, dstar) elif isinstance(tree, ast.Getattr): obj = build_expr(reporter, frame, space, tree.expr, evals) expr = AttrRef(ExecutionFrame(frame, tree), tree, obj, tree.attrname) elif isinstance(tree, ast.Subscript): obj = build_expr(reporter, frame, space, tree.expr, evals) subs = [ build_expr(reporter, frame, space, sub, evals) for sub in tree.subs ] if len(subs) == 1: expr = SubRef(ExecutionFrame(frame, tree), tree, obj, subs[0]) else: expr = SliceRef(ExecutionFrame(frame, tree), tree, obj, subs) elif isinstance(tree, ast.Slice): obj = build_expr(reporter, frame, space, tree.expr, evals) lower = upper = IntType.get_object() # maxint is given when omitted. if tree.lower: lower = build_expr(reporter, frame, space, tree.lower, evals) if tree.upper: upper = build_expr(reporter, frame, space, tree.upper, evals) assert lower != None and upper != None expr = SliceRef(ExecutionFrame(frame, tree), tree, obj, [lower, upper]) elif isinstance(tree, ast.Sliceobj): elements = [ build_expr(reporter, frame, space, node, evals) for node in tree.nodes ] expr = SliceObject(ExecutionFrame(frame, tree), tree, elements) elif isinstance(tree, ast.Tuple): elements = [ build_expr(reporter, frame, space, node, evals) for node in tree.nodes ] expr = TupleType.create_tuple(elements) elif isinstance(tree, ast.List): elements = [ build_expr(reporter, frame, space, node, evals) for node in tree.nodes ] expr = ListType.create_list(CompoundTypeNode(elements)) elif isinstance(tree, ast.Set): elements = [ build_expr(reporter, frame, space, node, evals) for node in tree.nodes ] expr = SetType.create_set(CompoundTypeNode(elements)) elif isinstance(tree, ast.Dict): items = [ (build_expr(reporter, frame, space, k, evals), build_expr(reporter, frame, space, v, evals)) for (k,v) in tree.items ] expr = DictType.create_dict(items) # +, -, *, /, %, //, **, <<, >> elif isinstance(tree, (ast.Add, ast.Sub, ast.Mul, ast.Div, ast.Mod, ast.FloorDiv, ast.Power, ast.LeftShift, ast.RightShift)): op = tree.__class__.__name__ left = build_expr(reporter, frame, space, tree.left, evals) right = build_expr(reporter, frame, space, tree.right, evals) expr = BinaryOp(ExecutionFrame(frame, tree), tree, op, left, right) # &, |, ^ elif isinstance(tree, (ast.Bitand, ast.Bitor, ast.Bitxor)): op = tree.__class__.__name__ nodes = [ build_expr(reporter, frame, space, node, evals) for node in tree.nodes ] expr = nodes.pop(0) for right in nodes: expr = BinaryOp(ExecutionFrame(frame, tree), tree, op, expr, right) # ==, !=, <=, >=, <, >, in, not in, is, is not elif isinstance(tree, ast.Compare): left = build_expr(reporter, frame, space, tree.expr, evals) for (op,node) in tree.ops: right = build_expr(reporter, frame, space, node, evals) expr = CompareOp(ExecutionFrame(frame, tree), tree, op, left, right) left = right # +,-,~ elif isinstance(tree, (ast.UnaryAdd, ast.UnarySub, ast.Invert)): op = tree.__class__.__name__ value = build_expr(reporter, frame, space, tree.expr, evals) expr = UnaryOp(ExecutionFrame(frame, tree), tree, op, value) # and, or elif isinstance(tree, (ast.And, ast.Or)): op = tree.__class__.__name__ nodes = [ build_expr(reporter, frame, space, node, evals) for node in tree.nodes ] expr = BooleanOp(ExecutionFrame(frame, tree), tree, op, nodes) # not elif isinstance(tree, ast.Not): value = build_expr(reporter, frame, space, tree.expr, evals) expr = NotOp(ExecutionFrame(frame, tree), tree, value) # lambda elif isinstance(tree, ast.Lambda): defaults = [ build_expr(reporter, frame, space, value, evals) for value in tree.defaults ] expr = LambdaFuncType(reporter, frame, space, tree, tree.argnames, defaults, tree.varargs, tree.kwargs, tree) # list comprehension elif isinstance(tree, ast.ListComp): elements = [ build_expr(reporter, frame, space, tree.expr, evals) ] expr = ListType.create_list(CompoundTypeNode(elements)) for qual in tree.quals: seq = build_expr(reporter, frame, space, qual.list, evals) elem = IterElement(ExecutionFrame(frame, qual.list), qual.list, seq) build_assign(reporter, frame, space, qual.assign, elem, evals) for qif in qual.ifs: build_expr(reporter, frame, space, qif.test, evals) # generator expression elif isinstance(tree, ast.GenExpr): gen = tree.code elements = [ build_expr(reporter, frame, space, gen.expr, evals) ] expr = IterType.create_iter(CompoundTypeNode(elements)) for qual in gen.quals: seq = build_expr(reporter, frame, space, qual.iter, evals) elem = IterElement(ExecutionFrame(frame, qual.iter), qual.iter, seq) build_assign(reporter, frame, space, qual.assign, elem, evals) for qif in qual.ifs: build_expr(reporter, frame, space, qif.test, evals) # yield (for python 2.5) elif isinstance(tree, ast.Yield): value = build_expr(reporter, frame, space, tree.value, evals) slot = GeneratorType.create_slot(value) evals.append(('y', slot)) expr = slot.received # ifexp elif isinstance(tree, ast.IfExp): test = build_expr(reporter, frame, space, tree.test, evals) then = build_expr(reporter, frame, space, tree.then, evals) else_ = build_expr(reporter, frame, space, tree.else_, evals) expr = IfExpOp(ExecutionFrame(frame, tree), tree, test, then, else_) # Backquote (unsupported) elif isinstance(tree, ast.Backquote): ExecutionFrame(frame, tree).raise_expt(ErrorConfig.NotSupported('backquote notation')) expr = UndefinedTypeNode('backquote') # Ellipsis elif isinstance(tree, ast.Ellipsis): ExecutionFrame(frame, tree).raise_expt(ErrorConfig.NotSupported('ellipsis')) expr = UndefinedTypeNode('ellipsis') else: # unsupported AST. raise SyntaxError('unsupported syntax: %r (%s:%r)' % (tree, tree._module.get_path(), tree.lineno)) assert isinstance(expr, (TypeNode, tuple)), expr evals.append((None, expr)) return expr