class IterObject(BuiltinAggregateObject): def __init__(self, typeobj, elemall=None): self.elemall = CompoundTypeNode() if elemall: elemall.connect(self.elemall.recv) BuiltinAggregateObject.__init__(self, typeobj) return def __repr__(self): return '(%r, ...)' % self.elemall def __str__(self): return self.desctxt({}) def desctxt(self, done): if self in done: return '...' else: done[self] = len(done) return '(%s, ...)' % self.elemall.desctxt(done) def descxml(self, done): if self in done: e = Element('ref', id=str(done[self])) else: done[self] = len(done) e = Element('iter', id=str(done[self])) e.append(self.elemall.descxml(done)) return e def get_iter(self, frame, anchor): return self def create_attr(self, frame, anchor, name): if name == 'next': return BuiltinConstMethod( 'iter.next', self.elemall, expts=[StopIterationType.maybe('might raise StopIteration')]) raise NodeAttrError(name)
class IterObject(BuiltinAggregateObject): def __init__(self, typeobj, elemall=None): self.elemall = CompoundTypeNode() if elemall: elemall.connect(self.elemall.recv) BuiltinAggregateObject.__init__(self, typeobj) return def __repr__(self): return '(%r, ...)' % self.elemall def __str__(self): return self.desctxt({}) def desctxt(self, done): if self in done: return '...' else: done[self] = len(done) return '(%s, ...)' % self.elemall.desctxt(done) def descxml(self, done): if self in done: e = Element('ref', id=str(done[self])) else: done[self] = len(done) e = Element('iter', id=str(done[self])) e.append(self.elemall.descxml(done)) return e def get_iter(self, frame, anchor): return self def create_attr(self, frame, anchor, name): if name == 'next': return BuiltinConstMethod('iter.next', self.elemall, expts=[StopIterationType.maybe('might raise StopIteration')]) raise NodeAttrError(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 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()