class GeneratorObject(IterObject): # Send class Send(BuiltinConstMethod): def __init__(self, name, target, retobj=NoneType.get_object(), args=None, expts=None): self.target = target BuiltinConstMethod.__init__(self, name, retobj, args=args, expts=expts) return def accept_arg(self, frame, anchor, i, arg1): arg1.connect(self.target.sent.recv) return # GeneratorObject def __init__(self, typeobj, elemall=None, elements=None): IterObject.__init__(self, typeobj, elemall=elemall) self.sent = CompoundTypeNode() if elements: for obj in elements: if isinstance(obj, GeneratorSlot): self.sent.connect(obj.received.recv) obj.connect(self.elemall.recv) return def create_attr(self, frame, anchor, name): if name == 'send': return self.Send( 'generator.send', self, self.elemall, [ANY], expts=[StopIterationType.maybe('might raise StopIteration')]) if name == 'next': NoneType.get_object().connect(self.sent.recv) return self.Send( 'generator.next', self, self.elemall, expts=[StopIterationType.maybe('might raise StopIteration')]) if name == 'throw': # XXX do nothing for now return BuiltinConstMethod('generator.throw', NoneType.get_object(), [ANY], [ANY, ANY]) if name == 'close': return self.Send('generator.close', self, NoneType.get_object(), [ANY]) return IterObject.create_attr(self, frame, anchor, name)
class GeneratorObject(IterObject): # Send class Send(BuiltinConstMethod): def __init__(self, name, target, retobj=NoneType.get_object(), args=None, expts=None): self.target = target BuiltinConstMethod.__init__(self, name, retobj, args=args, expts=expts) return def accept_arg(self, frame, anchor, i, arg1): arg1.connect(self.target.sent.recv) return # GeneratorObject def __init__(self, typeobj, elemall=None, elements=None): IterObject.__init__(self, typeobj, elemall=elemall) self.sent = CompoundTypeNode() if elements: for obj in elements: if isinstance(obj, GeneratorSlot): self.sent.connect(obj.received.recv) obj.connect(self.elemall.recv) return def create_attr(self, frame, anchor, name): if name == 'send': return self.Send('generator.send', self, self.elemall, [ANY], expts=[StopIterationType.maybe('might raise StopIteration')]) if name == 'next': NoneType.get_object().connect(self.sent.recv) return self.Send('generator.next', self, self.elemall, expts=[StopIterationType.maybe('might raise StopIteration')]) if name == 'throw': # XXX do nothing for now return BuiltinConstMethod('generator.throw', NoneType.get_object(), [ANY], [ANY, ANY]) if name == 'close': return self.Send('generator.close', self, NoneType.get_object(), [ANY]) return IterObject.create_attr(self, frame, anchor, name)
class DictObject(BuiltinAggregateObject): # convert class DictConverter(CompoundTypeNode): def __init__(self, frame, anchor, target): self.frame = frame self.anchor = anchor self.target = target CompoundTypeNode.__init__(self) return def __repr__(self): return 'convert(%r)' % self.target def recv(self, src): for obj in src: IterElement(self.frame, self.anchor, obj).connect(self.recv_pair) return def recv_pair(self, src): for obj in src: if obj.is_type(TupleType.get_typeobj()) and obj.elements: if len(obj.elements) == 2: (k, v) = obj.elements k.connect(self.target.key.recv) v.connect(self.target.value.recv) else: self.frame.raise_expt( ErrorConfig.NotConvertable('(key,value)')) continue elem = IterElement(self.frame, self.anchor, obj) elem.connect(self.target.key.recv) elem.connect(self.target.value.recv) self.frame.raise_expt(ErrorConfig.NotConvertable('dict')) return # fromkeys class DictConverterFromKeys(CompoundTypeNode): def __init__(self, frame, anchor, target): self.frame = frame self.anchor = anchor self.target = target CompoundTypeNode.__init__(self) return def recv(self, src): for obj in src: IterElement(self.frame, self.anchor, obj).connect(self.target.key.recv) return # dict.get class Get(BuiltinConstMethod): def __init__(self, dictobj, name): self.dictobj = dictobj self.found = CompoundTypeNode([dictobj.value]) BuiltinConstMethod.__init__(self, name, self.found, [ANY], [ANY]) return def process_args(self, frame, anchor, args, kwargs): if len(args) == 1: self.found.update_type(NoneType.get_object()) return BuiltinConstMethod.process_args(self, frame, anchor, args, kwargs) def accept_arg(self, frame, anchor, i, arg1): if i != 0: arg1.connect(self.found.recv) return # dict.pop class Pop(BuiltinConstMethod): def __init__(self, dictobj, name): self.dictobj = dictobj self.found = CompoundTypeNode([dictobj.value]) BuiltinConstMethod.__init__(self, name, self.found, [ANY], [ANY]) return def process_args(self, frame, anchor, args, kwargs): if len(args) == 1: frame.raise_expt(ErrorConfig.MaybeKeyNotFound()) return BuiltinConstMethod.process_args(self, frame, anchor, args, kwargs) def accept_arg(self, frame, anchor, i, arg1): if i != 0: arg1.connect(self.found.recv) return # dict.setdefault class SetDefault(BuiltinConstMethod): def __init__(self, dictobj, name): self.dictobj = dictobj self.found = CompoundTypeNode([dictobj.value]) BuiltinConstMethod.__init__(self, name, self.found, [ANY], [ANY]) return def __repr__(self): return '%r.setdefault' % self.dictobj def process_args(self, frame, anchor, args, kwargs): if len(args) == 1: self.found.update_type(NoneType.get_object()) return BuiltinConstMethod.process_args(self, frame, anchor, args, kwargs) def accept_arg(self, frame, anchor, i, arg1): if i == 0: arg1.connect(self.dictobj.value.recv) else: arg1.connect(self.found.recv) return # dict.update class Update(BuiltinConstMethod): def __init__(self, dictobj, name): self.cache_update = {} self.dictobj = dictobj BuiltinConstMethod.__init__(self, name, NoneType.get_object(), [ANY]) return def process_args(self, frame, anchor, args, kwargs): v = args[0] if v not in self.cache_update: converter = DictObject.DictConverterFromKeys( frame, anchor, self.dictobj) self.cache_update[v] = converter v.connect(converter.recv) return NoneType.get_object() # DictObject def __init__(self, typeobj, items=None, key=None, value=None): if items != None: assert key == None and value == None self.key = CompoundTypeNode(k for (k, v) in items) self.value = CompoundTypeNode(v for (k, v) in items) else: self.key = CompoundTypeNode(key) self.value = CompoundTypeNode(value) self.default = CompoundTypeNode([NoneType.get_object()]) self.value.connect(self.default.recv) self.iter = None BuiltinAggregateObject.__init__(self, typeobj) return def __repr__(self): return '{%r: %r}' % (self.key, self.value) def __str__(self): return self.desctxt({}) def desctxt(self, done): if self in done: return '...' else: done[self] = len(done) return '{%s: %s}' % (self.key.desctxt(done), self.value.desctxt(done)) def descxml(self, done): if self in done: e = Element('ref', id=str(done[self])) else: done[self] = len(done) e = Element('dict', id=str(done[self])) e.append(self.key.descxml(done)) e.append(self.value.descxml(done)) return e def create_attr(self, frame, anchor, name): if name == 'clear': return BuiltinConstMethod('dict.clear', NoneType.get_object()) elif name == 'copy': dictobj = self.get_type().create_copy(frame, anchor, self) return BuiltinConstMethod('dict.copy', dictobj) elif name == 'fromkeys': return DictType.FromKeys('dict.fromkeys') elif name == 'get': return DictObject.Get(self, 'dict.get') elif name == 'has_key': return BuiltinConstMethod('dict.has_key', BoolType.get_object(), [ANY]) elif name == 'keys': return BuiltinConstMethod('dict.keys', ListType.create_list(self.key)) elif name == 'values': return BuiltinConstMethod('dict.values', ListType.create_list(self.value)) elif name == 'items': return BuiltinConstMethod( 'dict.items', ListType.create_list( TupleType.create_tuple([self.key, self.value]))) elif name == 'iterkeys': return BuiltinConstMethod('dict.iterkeys', IterType.create_iter(self.key)) elif name == 'itervalues': return BuiltinConstMethod('dict.itervalues', IterType.create_iter(self.value)) elif name == 'iteritems': return BuiltinConstMethod( 'dict.iteritems', IterType.create_iter( TupleType.create_tuple([self.key, self.value]))) elif name == 'pop': return DictObject.Pop(self, 'dict.pop') elif name == 'popitem': return BuiltinConstMethod( 'dict.popitem', TupleType.create_tuple([self.key, self.value]), expts=[ErrorConfig.MaybeElementNotFound()]) elif name == 'setdefault': return DictObject.SetDefault(self, 'dict.setdefault') elif name == 'update': return DictObject.Update(self, 'dict.update') raise NodeAttrError(name) def get_element(self, frame, anchor, key, write=False): if write: key.connect(self.key.recv) else: frame.raise_expt(ErrorConfig.MaybeKeyNotFound()) return self.value def get_iter(self, frame, anchor): if not self.iter: self.iter = IterType.create_iter(self.key) return self.iter def get_length(self, frame, anchor): return IntType.get_object()
class BuiltinSequenceObject(BuiltinAggregateObject): # SequenceExtender class SequenceExtender(BuiltinConstMethod): def __init__(self, name, target, retobj=NoneType.get_object(), args=None, optargs=None): self.target = target self.cache_extend = {} BuiltinConstMethod.__init__(self, name, retobj, args=args, optargs=optargs) return def __repr__(self): return '%r.extend' % self.target def accept_arg(self, frame, anchor, i, arg1): if arg1 in self.cache_extend: elem = self.cache_extend[arg1] else: elem = IterElement(frame, anchor, arg1) self.cache_extend[arg1] = elem elem.connect(self.target.elemall.recv) return # SequenceAppender class SequenceAppender(BuiltinConstMethod): def __init__(self, name, target, retobj=NoneType.get_object(), args=None, optargs=None): self.target = target BuiltinConstMethod.__init__(self, name, retobj, args=args, optargs=optargs) return def __repr__(self): return '%r.append' % self.target def accept_arg(self, frame, anchor, i, arg1): arg1.connect(self.target.elemall.recv) return # BuiltinSequenceObject def __init__(self, typeobj, elemall=None): self.elemall = CompoundTypeNode() if elemall: elemall.connect(self.elemall.recv) self.iter = None BuiltinAggregateObject.__init__(self, typeobj) return def get_iter(self, frame, anchor): if not self.iter: self.iter = IterType.create_iter(self.elemall) return self.iter def get_length(self, frame, anchor): return IntType.get_object() get_reversed = get_iter def connect_element(self, seqobj): assert isinstance(seqobj, BuiltinSequenceObject) self.elemall.connect(seqobj.elemall.recv) return
class DictObject(BuiltinAggregateObject): # convert class DictConverter(CompoundTypeNode): def __init__(self, frame, anchor, target): self.frame = frame self.anchor = anchor self.target = target CompoundTypeNode.__init__(self) return def __repr__(self): return 'convert(%r)' % self.target def recv(self, src): for obj in src: IterElement(self.frame, self.anchor, obj).connect(self.recv_pair) return def recv_pair(self, src): for obj in src: if obj.is_type(TupleType.get_typeobj()) and obj.elements: if len(obj.elements) == 2: (k,v) = obj.elements k.connect(self.target.key.recv) v.connect(self.target.value.recv) else: self.frame.raise_expt(ErrorConfig.NotConvertable('(key,value)')) continue elem = IterElement(self.frame, self.anchor, obj) elem.connect(self.target.key.recv) elem.connect(self.target.value.recv) self.frame.raise_expt(ErrorConfig.NotConvertable('dict')) return # fromkeys class DictConverterFromKeys(CompoundTypeNode): def __init__(self, frame, anchor, target): self.frame = frame self.anchor = anchor self.target = target CompoundTypeNode.__init__(self) return def recv(self, src): for obj in src: IterElement(self.frame, self.anchor, obj).connect(self.target.key.recv) return # dict.get class Get(BuiltinConstMethod): def __init__(self, dictobj, name): self.dictobj = dictobj self.found = CompoundTypeNode([dictobj.value]) BuiltinConstMethod.__init__(self, name, self.found, [ANY], [ANY]) return def process_args(self, frame, anchor, args, kwargs): if len(args) == 1: self.found.update_type(NoneType.get_object()) return BuiltinConstMethod.process_args(self, frame, anchor, args, kwargs) def accept_arg(self, frame, anchor, i, arg1): if i != 0: arg1.connect(self.found.recv) return # dict.pop class Pop(BuiltinConstMethod): def __init__(self, dictobj, name): self.dictobj = dictobj self.found = CompoundTypeNode([dictobj.value]) BuiltinConstMethod.__init__(self, name, self.found, [ANY], [ANY]) return def process_args(self, frame, anchor, args, kwargs): if len(args) == 1: frame.raise_expt(ErrorConfig.MaybeKeyNotFound()) return BuiltinConstMethod.process_args(self, frame, anchor, args, kwargs) def accept_arg(self, frame, anchor, i, arg1): if i != 0: arg1.connect(self.found.recv) return # dict.setdefault class SetDefault(BuiltinConstMethod): def __init__(self, dictobj, name): self.dictobj = dictobj self.found = CompoundTypeNode([dictobj.value]) BuiltinConstMethod.__init__(self, name, self.found, [ANY], [ANY]) return def __repr__(self): return '%r.setdefault' % self.dictobj def process_args(self, frame, anchor, args, kwargs): if len(args) == 1: self.found.update_type(NoneType.get_object()) return BuiltinConstMethod.process_args(self, frame, anchor, args, kwargs) def accept_arg(self, frame, anchor, i, arg1): if i == 0: arg1.connect(self.dictobj.value.recv) else: arg1.connect(self.found.recv) return # dict.update class Update(BuiltinConstMethod): def __init__(self, dictobj, name): self.cache_update = {} self.dictobj = dictobj BuiltinConstMethod.__init__(self, name, NoneType.get_object(), [ANY]) return def process_args(self, frame, anchor, args, kwargs): v = args[0] if v not in self.cache_update: converter = DictObject.DictConverterFromKeys(frame, anchor, self.dictobj) self.cache_update[v] = converter v.connect(converter.recv) return NoneType.get_object() # DictObject def __init__(self, typeobj, items=None, key=None, value=None): if items != None: assert key == None and value == None self.key = CompoundTypeNode( k for (k,v) in items ) self.value = CompoundTypeNode( v for (k,v) in items ) else: self.key = CompoundTypeNode(key) self.value = CompoundTypeNode(value) self.default = CompoundTypeNode([NoneType.get_object()]) self.value.connect(self.default.recv) self.iter = None BuiltinAggregateObject.__init__(self, typeobj) return def __repr__(self): return '{%r: %r}' % (self.key, self.value) def __str__(self): return self.desctxt({}) def desctxt(self, done): if self in done: return '...' else: done[self] = len(done) return '{%s: %s}' % (self.key.desctxt(done), self.value.desctxt(done)) def descxml(self, done): if self in done: e = Element('ref', id=str(done[self])) else: done[self] = len(done) e = Element('dict', id=str(done[self])) e.append(self.key.descxml(done)) e.append(self.value.descxml(done)) return e def create_attr(self, frame, anchor, name): if name == 'clear': return BuiltinConstMethod('dict.clear', NoneType.get_object()) elif name == 'copy': dictobj = self.get_type().create_copy(frame, anchor, self) return BuiltinConstMethod('dict.copy', dictobj) elif name == 'fromkeys': return DictType.FromKeys('dict.fromkeys') elif name == 'get': return DictObject.Get(self, 'dict.get') elif name == 'has_key': return BuiltinConstMethod('dict.has_key', BoolType.get_object(), [ANY]) elif name == 'keys': return BuiltinConstMethod('dict.keys', ListType.create_list(self.key)) elif name == 'values': return BuiltinConstMethod('dict.values', ListType.create_list(self.value)) elif name == 'items': return BuiltinConstMethod('dict.items', ListType.create_list(TupleType.create_tuple([self.key, self.value]))) elif name == 'iterkeys': return BuiltinConstMethod('dict.iterkeys', IterType.create_iter(self.key)) elif name == 'itervalues': return BuiltinConstMethod('dict.itervalues', IterType.create_iter(self.value)) elif name == 'iteritems': return BuiltinConstMethod('dict.iteritems', IterType.create_iter(TupleType.create_tuple([self.key, self.value]))) elif name == 'pop': return DictObject.Pop(self, 'dict.pop') elif name == 'popitem': return BuiltinConstMethod('dict.popitem', TupleType.create_tuple([self.key, self.value]), expts=[ErrorConfig.MaybeElementNotFound()]) elif name == 'setdefault': return DictObject.SetDefault(self, 'dict.setdefault') elif name == 'update': return DictObject.Update(self, 'dict.update') raise NodeAttrError(name) def get_element(self, frame, anchor, key, write=False): if write: key.connect(self.key.recv) else: frame.raise_expt(ErrorConfig.MaybeKeyNotFound()) return self.value def get_iter(self, frame, anchor): if not self.iter: self.iter = IterType.create_iter(self.key) return self.iter def get_length(self, frame, anchor): return IntType.get_object()