def create_attr(self, frame, anchor, name): if name == 'append': return self.SequenceAppender('list.append', self, args=[ANY]) elif name == 'count': return BuiltinConstMethod('list.count', IntType.get_object(), [ANY]) elif name == 'extend': return self.SequenceExtender('list.extend', self, args=[ANY]) elif name == 'index': return BuiltinConstMethod( 'list.index', IntType.get_object(), [ANY], [IntType, IntType], expts=[ErrorConfig.MaybeElementNotFound()]) elif name == 'insert': return self.InsertMethod('list.insert', self, [IntType, ANY]) elif name == 'pop': return BuiltinConstMethod( 'list.pop', self.elemall, [], [IntType], expts=[ErrorConfig.MaybeElementNotRemovable()]) elif name == 'remove': return BuiltinConstMethod( 'list.remove', NoneType.get_object(), [ANY], expts=[ErrorConfig.MaybeElementNotRemovable()]) elif name == 'reverse': return BuiltinConstMethod('list.remove', NoneType.get_object()) elif name == 'sort': return self.SortMethod('list.sort', self) raise NodeAttrError(name)
def process_args(self, frame, anchor, args, kwargs): if kwargs: frame.raise_expt(ErrorConfig.NoKeywordArgs()) return UndefinedTypeNode.get_object() elemall = TupleType.create_tuple( [IntType.get_object(), IterElement(frame, anchor, args[0])]) return IterObject(self.get_typeobj(), elemall=elemall)
def recv_fcmp(self, src): for obj in src: if obj in self.received_fcmp: continue self.received_fcmp.add(obj) try: checker = TypeChecker(self.frame, IntType.get_typeobj(), 'the return value of comparison function') obj.call(self.frame, self.anchor, (self.key, self.key), {}).connect(checker.recv) except NodeTypeError: self.frame.raise_expt(ErrorConfig.NotCallable(obj)) return
def recv_fcmp(self, src): for obj in src: if obj in self.received_fcmp: continue self.received_fcmp.add(obj) try: checker = TypeChecker( self.frame, IntType.get_typeobj(), 'the return value of comparison function') obj.call(self.frame, self.anchor, (self.key, self.key), {}).connect(checker.recv) except NodeTypeError: self.frame.raise_expt(ErrorConfig.NotCallable(obj)) return
def create_attr(self, frame, anchor, name): if name == 'append': return self.SequenceAppender('list.append', self, args=[ANY]) elif name == 'count': return BuiltinConstMethod('list.count', IntType.get_object(), [ANY]) elif name == 'extend': return self.SequenceExtender('list.extend', self, args=[ANY]) elif name == 'index': return BuiltinConstMethod('list.index', IntType.get_object(), [ANY], [IntType, IntType], expts=[ErrorConfig.MaybeElementNotFound()]) elif name == 'insert': return self.InsertMethod('list.insert', self, [IntType, ANY]) elif name == 'pop': return BuiltinConstMethod('list.pop', self.elemall, [], [IntType], expts=[ErrorConfig.MaybeElementNotRemovable()]) elif name == 'remove': return BuiltinConstMethod('list.remove', NoneType.get_object(), [ANY], expts=[ErrorConfig.MaybeElementNotRemovable()]) elif name == 'reverse': return BuiltinConstMethod('list.remove', NoneType.get_object()) elif name == 'sort': return self.SortMethod('list.sort', self) raise NodeAttrError(name)
def process_args_nokwd(self, frame, anchor, args): self.LengthChecker(frame, anchor, args[0]) return IntType.get_object()
def __init__(self): BuiltinConstFunc.__init__(self, 'id', IntType.get_object(), [ANY]) 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
def __init__(self): BuiltinConstFunc.__init__(self, 'range', ListType.create_list(IntType.get_object()), [IntType], [IntType, IntType]) return
def __init__(self): BuiltinConstFunc.__init__(self, 'ord', IntType.get_object(), [BaseStringType]) return
def update_op(self, lobj, robj): from pyntch.basic_types import NumberType, IntType, BaseStringType, BUILTIN_OBJECT from pyntch.aggregate_types import ListType, ListObject, TupleType from pyntch.klass import InstanceObject if (lobj, robj) in self.received: return self.received.add((lobj, robj)) # special handling for a formatting (%) operator ltype = lobj.get_type() rtype = robj.get_type() if (lobj.is_type(BaseStringType.get_typeobj()) and self.op == 'Mod'): self.computed.add((lobj, robj)) lobj.connect(self.recv) return # for numeric operation, the one with a higher rank is chosen. if (lobj.is_type(NumberType.get_typeobj()) and robj.is_type(NumberType.get_typeobj()) and self.op in ('Add', 'Sub', 'Mul', 'Div', 'Mod', 'FloorDiv', 'Power', 'LeftShift', 'RightShift')): self.computed.add((lobj, robj)) if ltype.get_rank() < rtype.get_rank(): robj.connect(self.recv) else: lobj.connect(self.recv) return if (lobj.is_type(IntType.get_typeobj()) and robj.is_type(IntType.get_typeobj()) and self.op in ('Bitand', 'Bitor', 'Bitxor')): self.computed.add((lobj, robj)) robj.connect(self.recv) return # for string operation, only Add is supported. if (lobj.is_type(BaseStringType.get_typeobj()) and robj.is_type(BaseStringType.get_typeobj()) and self.op == 'Add'): self.computed.add((lobj, robj)) robj.connect(self.recv) return # adding lists. if (self.op == 'Add' and (lobj.is_type(ListType.get_typeobj()) and robj.is_type(ListType.get_typeobj()))): if not self.listobj: self.listobj = ListType.create_list() self.listobj.connect(self.recv) self.computed.add((lobj, robj)) lobj.connect_element(self.listobj) robj.connect_element(self.listobj) return # multiplying a list by an integer. if self.op == 'Mul': if lobj.is_type(ListType.get_typeobj()) and robj.is_type( IntType.get_typeobj()): self.computed.add((lobj, robj)) lobj.connect(self.recv) return elif lobj.is_type(IntType.get_typeobj()) and robj.is_type( ListType.get_typeobj()): self.computed.add((lobj, robj)) robj.connect(self.recv) return # adding tuples. if (self.op == 'Add' and (lobj.is_type(TupleType.get_typeobj()) and robj.is_type(TupleType.get_typeobj()))): if not self.tupleobj: self.tupleobj = TupleType.create_tuple() self.tupleobj.connect(self.recv) self.computed.add((lobj, robj)) lobj.connect_element(self.tupleobj) robj.connect_element(self.tupleobj) return # multiplying a tuple by an integer. if self.op == 'Mul': if lobj.is_type(TupleType.get_typeobj()) and robj.is_type( IntType.get_typeobj()): self.computed.add((lobj, robj)) lobj.connect(self.recv) return elif lobj.is_type(IntType.get_typeobj()) and robj.is_type( TupleType.get_typeobj()): self.computed.add((lobj, robj)) robj.connect(self.recv) return # other valid operations. k = (ltype.typename(), self.op, rtype.typename()) if k in self.VALID_TYPES: self.computed.add((lobj, robj)) BUILTIN_OBJECT[self.VALID_TYPES[k]].connect(self.recv) return # Handle optional methods. if isinstance(lobj, InstanceObject): result = OptMethodCall(self.frame, self.anchor, lobj, self.LMETHOD[self.op], [robj]) result.connect(lambda src: self.recv_result(src, (lobj, robj))) if isinstance(robj, InstanceObject): result = OptMethodCall(self.frame, self.anchor, robj, self.RMETHOD[self.op], [lobj]) result.connect(lambda src: self.recv_result(src, (lobj, robj))) return
def get_length(self, frame, anchor): return IntType.get_object()
def process_args(self, frame, anchor, args, kwargs): if kwargs: frame.raise_expt(ErrorConfig.NoKeywordArgs()) return UndefinedTypeNode.get_object() elemall = TupleType.create_tuple([IntType.get_object(), IterElement(frame, anchor, args[0])]) return IterObject(self.get_typeobj(), elemall=elemall)
def update_op(self, lobj, robj): from pyntch.basic_types import NumberType, IntType, BaseStringType, BUILTIN_OBJECT from pyntch.aggregate_types import ListType, ListObject, TupleType from pyntch.klass import InstanceObject if (lobj,robj) in self.received: return self.received.add((lobj,robj)) # special handling for a formatting (%) operator ltype = lobj.get_type() rtype = robj.get_type() if (lobj.is_type(BaseStringType.get_typeobj()) and self.op == 'Mod'): self.computed.add((lobj,robj)) lobj.connect(self.recv) return # for numeric operation, the one with a higher rank is chosen. if (lobj.is_type(NumberType.get_typeobj()) and robj.is_type(NumberType.get_typeobj()) and self.op in ('Add','Sub','Mul','Div','Mod','FloorDiv','Power','LeftShift','RightShift')): self.computed.add((lobj,robj)) if ltype.get_rank() < rtype.get_rank(): robj.connect(self.recv) else: lobj.connect(self.recv) return if (lobj.is_type(IntType.get_typeobj()) and robj.is_type(IntType.get_typeobj()) and self.op in ('Bitand','Bitor','Bitxor')): self.computed.add((lobj,robj)) robj.connect(self.recv) return # for string operation, only Add is supported. if (lobj.is_type(BaseStringType.get_typeobj()) and robj.is_type(BaseStringType.get_typeobj()) and self.op == 'Add'): self.computed.add((lobj,robj)) robj.connect(self.recv) return # adding lists. if (self.op == 'Add' and (lobj.is_type(ListType.get_typeobj()) and robj.is_type(ListType.get_typeobj()))): if not self.listobj: self.listobj = ListType.create_list() self.listobj.connect(self.recv) self.computed.add((lobj,robj)) lobj.connect_element(self.listobj) robj.connect_element(self.listobj) return # multiplying a list by an integer. if self.op == 'Mul': if lobj.is_type(ListType.get_typeobj()) and robj.is_type(IntType.get_typeobj()): self.computed.add((lobj,robj)) lobj.connect(self.recv) return elif lobj.is_type(IntType.get_typeobj()) and robj.is_type(ListType.get_typeobj()): self.computed.add((lobj,robj)) robj.connect(self.recv) return # adding tuples. if (self.op == 'Add' and (lobj.is_type(TupleType.get_typeobj()) and robj.is_type(TupleType.get_typeobj()))): if not self.tupleobj: self.tupleobj = TupleType.create_tuple() self.tupleobj.connect(self.recv) self.computed.add((lobj,robj)) lobj.connect_element(self.tupleobj) robj.connect_element(self.tupleobj) return # multiplying a tuple by an integer. if self.op == 'Mul': if lobj.is_type(TupleType.get_typeobj()) and robj.is_type(IntType.get_typeobj()): self.computed.add((lobj,robj)) lobj.connect(self.recv) return elif lobj.is_type(IntType.get_typeobj()) and robj.is_type(TupleType.get_typeobj()): self.computed.add((lobj,robj)) robj.connect(self.recv) return # other valid operations. k = (ltype.typename(), self.op, rtype.typename()) if k in self.VALID_TYPES: self.computed.add((lobj,robj)) BUILTIN_OBJECT[self.VALID_TYPES[k]].connect(self.recv) return # Handle optional methods. if isinstance(lobj, InstanceObject): result = OptMethodCall(self.frame, self.anchor, lobj, self.LMETHOD[self.op], [robj]) result.connect(lambda src: self.recv_result(src, (lobj, robj))) if isinstance(robj, InstanceObject): result = OptMethodCall(self.frame, self.anchor, robj, self.RMETHOD[self.op], [lobj]) result.connect(lambda src: self.recv_result(src, (lobj, robj))) return