Skip to content
Permalink
Newer
Older
100644 678 lines (586 sloc) 18.7 KB
Sep 5, 2014
1
;(function($B){
2
3
eval($B.InjectBuiltins())
Sep 5, 2014
5
var $ObjectDict = _b_.object.$dict
6
var str_hash = _b_.str.$dict.__hash__
Sep 5, 2014
7
8
// dictionary
9
function $DictClass($keys,$values){
10
this.iter = null
11
this.__class__ = $DictDict
Feb 9, 2015
13
14
var setitem=$DictDict.__setitem__
15
var i=$keys.length
16
while(i--) setitem($keys[i], $values[i])
Sep 5, 2014
19
var $DictDict = {__class__:$B.$type,
20
__name__ : 'dict',
21
$native:true,
22
__dir__:$ObjectDict.__dir__
Sep 5, 2014
23
}
24
25
var $key_iterator = function(d) {
26
this.d = d
27
this.current = 0
28
this.iter = new $item_generator(d)
29
}
30
$key_iterator.prototype.length = function() { return this.iter.length }
31
$key_iterator.prototype.next = function() { return this.iter.next()[0] }
32
33
var $value_iterator = function(d) {
34
this.d = d
35
this.current = 0
36
this.iter = new $item_generator(d)
37
}
38
$value_iterator.prototype.length = function() { return this.iter.length }
39
$value_iterator.prototype.next = function() { return this.iter.next()[1] }
40
41
var $item_generator = function(d) {
42
this.i = 0
44
var items=[]
47
items[pos++]=[parseFloat(k), d.$numeric_dict[k]]
51
items[pos++]=[k, d.$string_dict[k]]
54
for (var k in d.$object_dict) {
55
var i=d.$object_dict[k].length
56
while(i--) items[pos++]=d.$object_dict[k][i]
58
59
this.items=items
60
this.length=items.length
Feb 9, 2015
62
63
$item_generator.prototype.next = function() {
64
if (this.i < this.items.length) {
65
return this.items[this.i++]
66
}
67
throw _b_.StopIteration("StopIteration")
68
}
69
$item_generator.prototype.as_list = function() {
70
return this.items
71
}
72
73
var $item_iterator = function(d) {
74
this.d = d
75
this.current = 0
76
this.iter = new $item_generator(d)
77
}
78
$item_iterator.prototype.length = function() {return this.iter.items.length }
79
$item_iterator.prototype.next = function() { return _b_.tuple(this.iter.next()) }
80
81
var $copy_dict = function(left, right) {
82
var _l=new $item_generator(right).as_list()
83
var si=$DictDict.__setitem__
84
var i=_l.length
85
while(i--) si(left, _l[i][0], _l[i][1])
86
}
87
88
$iterator_wrapper = function(items,klass){
89
var res = {
90
__class__:klass,
91
__iter__:function(){items.iter.i=0; return res},
92
__len__:function(){return items.length()},
93
__next__:function(){
94
//if (items.length() !== items.iter.used) {
95
// throw _b_.RuntimeError("dictionary changed size during iteration")
96
//}
97
return items.next()
98
//return items[counter++]
99
},
100
__repr__:function(){return "<"+klass.__name__+" object>"},
102
}
103
res.__str__ = res.toString = res.__repr__
104
return res
105
}
106
108
var $dict_keysDict = $B.$iterator_class('dict_keys')
109
110
$DictDict.keys = function(self){
111
if (arguments.length > 1) {
112
var _len=arguments.length - 1
113
var _msg="keys() takes no arguments ("+_len+" given)"
114
throw _b_.TypeError(_msg)
115
}
116
return $iterator_wrapper(new $key_iterator(self),$dict_keysDict)
117
}
118
119
var $dict_valuesDict = $B.$iterator_class('dict_values')
120
121
$DictDict.values = function(self){
122
if (arguments.length > 1) {
123
var _len=arguments.length - 1
124
var _msg="values() takes no arguments ("+_len+" given)"
125
throw _b_.TypeError(_msg)
126
}
127
return $iterator_wrapper(new $value_iterator(self), $dict_valuesDict)
128
}
129
130
$DictDict.__bool__ = function (self) {return $DictDict.__len__(self) > 0}
Sep 5, 2014
131
132
$DictDict.__contains__ = function(self,item){
133
if(self.$jsobj) return self.$jsobj[item]!==undefined
134
switch(typeof item) {
135
case 'string':
136
return self.$string_dict[item] !==undefined
137
case 'number':
138
return self.$numeric_dict[item] !==undefined
140
141
var _key=hash(item)
142
if (self.$str_hash[_key]!==undefined &&
143
_b_.getattr(item,'__eq__')(self.$str_hash[_key])){return true}
144
if (self.$numeric_dict[_key]!==undefined &&
145
_b_.getattr(item,'__eq__')(_key)){return true}
146
if (self.$object_dict[_key] !== undefined) {
147
var _eq = getattr(item, '__eq__')
148
var i=self.$object_dict[_key].length
149
while(i--) {
150
if (_eq(self.$object_dict[_key][i][0])) return true
151
}
152
}
153
return false
Sep 5, 2014
154
}
155
156
$DictDict.__delitem__ = function(self,arg){
157
switch(typeof arg) {
158
case 'string':
159
if (self.$string_dict[arg] === undefined) throw KeyError(_b_.str(arg))
160
delete self.$string_dict[arg]
161
delete self.$str_hash[str_hash(arg)]
162
if (self.$jsobj) delete self.$jsobj[arg]
163
return
164
case 'number':
165
if (self.$numeric_dict[arg] === undefined) throw KeyError(_b_.str(arg))
166
delete self.$numeric_dict[arg]
167
if (self.$jsobj) delete self.$jsobj[arg]
168
return
170
// go with defaults
172
var _key=hash(arg)
173
if (self.$object_dict[_key] !== undefined) {
174
var _eq=getattr(arg, '__eq__')
175
var i=self.$object_dict[_key].length
176
while(i--) {
177
if (_eq(self.$object_dict[_key][i][0])) {
178
delete self.$object_dict[_key][i];
179
break;
180
}
181
}
182
}
183
184
if(self.$jsobj) delete self.$jsobj[arg]
Sep 5, 2014
185
}
186
187
$DictDict.__eq__ = function(self,other){
188
if(other===undefined){ // compare self to class "dict"
189
return self===dict
190
}
191
if(!isinstance(other,dict)) return false
192
193
if ($DictDict.__len__(self) != $DictDict.__len__(other)) return false
194
195
var _l = new $item_generator(self).as_list()
196
var i=_l.length
197
while(i--) {
198
var key=_l[i][0]
199
if (!$DictDict.__contains__(other, key)) return false
200
var v1=_l[i][1]
201
var v2=$DictDict.__getitem__(other, key)
202
if (!getattr(v1, '__eq__')(v2)) return false
203
}
204
205
return true
Sep 5, 2014
206
}
207
208
$DictDict.__getitem__ = function(self,arg){
209
if(self.$jsobj && self.$jsobj[arg] !== undefined) return self.$jsobj[arg]
210
211
switch(typeof arg) {
212
case 'string':
213
if (self.$string_dict[arg] !== undefined) return self.$string_dict[arg]
214
break
215
case 'number':
216
if (self.$numeric_dict[arg] !== undefined) return self.$numeric_dict[arg]
217
}
218
// since the key is more complex use 'default' method of getting item
219
220
var _key=hash(arg)
221
var sk = self.$str_hash[_key]
222
if (sk!==undefined && _b_.getattr(arg,'__eq__')(sk)){
223
return self.$string_dict[sk]
224
}
225
if (self.$numeric_dict[_key]!==undefined &&
226
_b_.getattr(arg,'__eq__')(_key)){
227
return self.$numeric_dict[_key]
228
}
229
if (self.$object_dict[_key] !== undefined) {
230
var _eq=getattr(arg, '__eq__')
231
var i=self.$object_dict[_key].length
232
while(i--) {
233
if (_eq(self.$object_dict[_key][i][0])) {
234
return self.$object_dict[_key][i][1]
235
}
236
}
237
}
238
239
if(hasattr(self, '__missing__')) return getattr(self, '__missing__')(arg)
240
Sep 5, 2014
241
throw KeyError(_b_.str(arg))
242
}
243
244
$DictDict.__hash__ = function(self) {
245
if (self === undefined) {
246
return $DictDict.__hashvalue__ || $B.$py_next_hash-- // for hash of dict type (not instance of dict)
247
}
248
throw _b_.TypeError("unhashable type: 'dict'");
249
}
Sep 5, 2014
250
251
$DictDict.__init__ = function(self){
252
var args = [], pos=0
253
for(var i=1;i<arguments.length;i++){args[pos++]=arguments[i]}
254
$DictDict.clear(self)
255
switch(args.length) {
256
case 0:
257
return
258
case 1:
Sep 5, 2014
259
var obj = args[0]
260
if(Array.isArray(obj)){
261
var i = obj.length
262
var si = $DictDict.__setitem__
263
while(i--) si(self, obj[i][0], obj[i][1])
264
return
265
}else if(isinstance(obj,dict)){
Sep 5, 2014
267
return
268
}
Sep 5, 2014
270
if(obj.__class__===$B.JSObject.$dict){
271
// convert a JSObject into a Python dictionary
272
var si = $DictDict.__setitem__
273
for(var attr in obj.js) si(self,attr,obj.js[attr])
274
275
// Attribute $jsobj is used to update the original JS object
276
// when the dictionary is modified
Sep 5, 2014
278
return
279
}
Sep 5, 2014
282
var $ns=$B.$MakeArgs('dict',args,[],[],'args','kw')
283
var args = $ns['args']
284
var kw = $ns['kw']
Sep 5, 2014
287
if(isinstance(args[0],dict)){
Sep 5, 2014
289
return
290
}
Sep 5, 2014
292
// format dict([(k1,v1),(k2,v2)...])
293
294
if(Array.isArray(args[0])){
295
var src = args[0]
296
var i = src.length
297
var si=$DictDict.__setitem__
298
while(i--) si(self, src[i][0], src[i][1])
299
}else{
300
var iterable = iter(args[0])
301
while(1){
302
try{
303
var elt = next(iterable)
304
var key = getattr(elt,'__getitem__')(0)
305
var value = getattr(elt,'__getitem__')(1)
306
$DictDict.__setitem__(self, key, value)
307
}catch(err){
308
if(err.__name__==='StopIteration'){$B.$pop_exc();break}
309
throw err
310
}
Sep 5, 2014
311
}
312
}
314
if($DictDict.__len__(kw) > 0) $copy_dict(self, kw)
Sep 5, 2014
315
}
316
317
var $dict_iterator = $B.$iterator_class('dict iterator')
318
$DictDict.__iter__ = function(self) {
319
return $DictDict.keys(self)
Sep 5, 2014
320
}
321
322
$DictDict.__len__ = function(self) {
323
var _count=0
325
for (var k in self.$numeric_dict) _count++
326
for (var k in self.$string_dict) _count++
327
for (var k in self.$object_dict) _count+= self.$object_dict[k].length
329
return _count
Sep 5, 2014
331
332
$DictDict.__mro__ = [$DictDict,$ObjectDict]
333
334
$DictDict.__ne__ = function(self,other){return !$DictDict.__eq__(self,other)}
335
336
$DictDict.__next__ = function(self){
338
self.$iter = new $item_generator(self)
339
}
340
try {
341
return self.$iter.next()
342
} catch (err) {
343
if (err.__name__ !== "StopIteration") { throw err } else { $B.$pop_exc() }
Sep 5, 2014
344
}
345
}
346
347
$DictDict.__repr__ = function(self){
348
if(self===undefined) return "<class 'dict'>"
349
var _objs=[self] // used to elimate recursion
350
var res=[], pos=0
351
var items = new $item_generator(self).as_list()
352
for (var i=0; i < items.length; i++) {
353
var itm = items[i]
Jan 18, 2015
354
if (_objs.indexOf(itm[1]) > -1 && _b_.isinstance(itm[1], [_b_.dict,_b_.list,_b_.set, _b_.tuple])) {
355
var value='?'+_b_.type(itm[1])
356
if(isinstance(itm[1], dict)) value='{...}'
357
res[pos++]=repr(itm[0])+': '+ value
358
} else {
Jan 18, 2015
359
if (_objs.indexOf(itm[1]) == -1) _objs.push(itm[1])
360
res[pos++]=repr(itm[0])+': '+repr(itm[1])
Sep 5, 2014
362
}
363
return '{'+ res.join(', ') +'}'
Sep 5, 2014
364
}
365
366
$DictDict.__setitem__ = function(self,key,value){
367
switch(typeof key) {
368
case 'string':
369
self.$string_dict[key]=value
370
self.$str_hash[str_hash(key)]=key
371
if(self.$jsobj) self.$jsobj[key]=value
372
return
373
case 'number':
374
self.$numeric_dict[key]=value
375
if(self.$jsobj) self.$jsobj[key]=value
376
return
379
// if we got here the key is more complex, use default method
381
var _key=hash(key)
382
var _eq=getattr(key, '__eq__')
383
384
if(self.$numeric_dict[_key]!==undefined && _eq(_key)){
385
self.$numeric_dict[_key] = value
386
return
387
}
388
var sk = self.$str_hash[_key]
389
if(sk!==undefined && _eq(sk)){
390
self.$string_dict[sk] = value
391
return
392
}
393
394
395
if (self.$object_dict[_key] != undefined) {
396
var i=self.$object_dict[_key].length
397
while(i--) {
398
if (_eq(self.$object_dict[_key][i][0])) {
399
self.$object_dict[_key][i]=[key, value]
400
if(self.$jsobj) self.$jsobj[key]=value
401
return
402
}
403
}
404
// if we got here this key is not in the object
405
self.$object_dict[_key].push([key, value])
406
} else {
407
self.$object_dict[_key]=[[key, value]]
Sep 5, 2014
410
if(self.$jsobj) self.$jsobj[key]=value
411
}
412
413
$DictDict.__str__ = $DictDict.__repr__
414
415
// add "reflected" methods
416
$B.make_rmethods($DictDict)
417
418
$DictDict.clear = function(self){
419
// Remove all items from the dictionary.
421
self.$numeric_dict={}
422
self.$string_dict={}
423
self.$str_hash={}
424
self.$object_dict={}
Sep 5, 2014
426
if(self.$jsobj) self.$jsobj={}
427
}
428
429
$DictDict.copy = function(self){
430
// Return a shallow copy of the dictionary
431
var res = _b_.dict()
432
$copy_dict(res, self)
Sep 5, 2014
433
return res
434
}
435
436
$DictDict.get = function(self, key, _default){
437
if (_default === undefined) _default=None
438
switch(typeof key) {
439
case 'string':
440
return self.$string_dict[key] || _default
441
case 'number':
442
return self.$numeric_dict[key] || _default
Sep 5, 2014
443
}
445
var _key=hash(key)
446
if (self.$object_dict[_key] != undefined) {
447
var _eq=getattr(key, '__eq__')
448
var i=self.$object_dict[_key].length
449
while(i--) {
450
if (_eq(self.$object_dict[_key][i][0]))
451
return self.$object_dict[_key][i][1]
452
}
453
}
454
455
if(_default!==undefined) return _default
456
return None
Sep 5, 2014
457
}
458
459
var $dict_itemsDict = $B.$iterator_class('dict_items')
Sep 5, 2014
460
461
$DictDict.items = function(self){
462
if (arguments.length > 1) {
463
var _len=arguments.length - 1
464
var _msg="items() takes no arguments ("+_len+" given)"
465
throw _b_.TypeError(_msg)
466
}
467
return $iterator_wrapper(new $item_iterator(self), $dict_itemsDict)
Sep 5, 2014
468
}
469
470
$DictDict.fromkeys = function(keys,value){
Sep 5, 2014
471
// class method
472
if(value===undefined) value=None
Sep 5, 2014
473
var res = dict()
474
var keys_iter = _b_.iter(keys)
475
while(1){
476
try{
477
var key = _b_.next(keys_iter)
478
$DictDict.__setitem__(res,key,value)
479
}catch(err){
480
if($B.is_exc(err,[_b_.StopIteration])){
481
$B.$pop_exc()
482
return res
483
}
484
throw err
485
}
486
}
487
}
488
489
$DictDict.pop = function(self,key,_default){
490
try{
491
var res = $DictDict.__getitem__(self,key)
492
$DictDict.__delitem__(self,key)
493
return res
494
}catch(err){
495
$B.$pop_exc()
496
if(err.__name__==='KeyError'){
497
if(_default!==undefined) return _default
498
throw err
499
}
500
throw err
501
}
502
}
503
504
$DictDict.popitem = function(self){
505
try{
506
var itm = new $item_iterator(self).next()
507
$DictDict.__delitem__(self,itm[0])
508
return _b_.tuple(itm)
509
}catch(err) {
510
if (err.__name__ == "StopIteration") {
511
$B.$pop_exc()
512
throw KeyError("'popitem(): dictionary is empty'")
513
}
514
}
Sep 5, 2014
515
}
516
517
$DictDict.setdefault = function(self,key,_default){
518
try{return $DictDict.__getitem__(self,key)}
519
catch(err){
520
if(_default===undefined) _default=None
521
$DictDict.__setitem__(self,key,_default)
522
return _default
523
}
524
}
525
526
$DictDict.update = function(self){
527
var params = [], pos=0
528
for(var i=1;i<arguments.length;i++){params[pos++]=arguments[i]}
Sep 5, 2014
529
var $ns=$B.$MakeArgs('$DictDict.update',params,[],[],'args','kw')
530
var args = $ns['args']
531
if(args.length>0) {
532
var o=args[0]
533
if (isinstance(o,dict)){
534
$copy_dict(self, o)
535
} else if (hasattr(o, '__getitem__') && hasattr(o, 'keys')) {
536
var _keys=_b_.list(getattr(o, 'keys')())
537
var si=$DictDict.__setitem__
538
var i=_keys.length
539
while(i--) {
540
//for (var i=0; i < _keys.length; i++) {
541
var _value = getattr(o, '__getitem__')(_keys[i])
542
si(self, _keys[i], _value)
Sep 5, 2014
545
}
546
var kw = $ns['kw']
Sep 5, 2014
548
}
549
550
function dict(args, second){
552
if(second===undefined && Array.isArray(args)){
553
// Form "dict([[key1, value1], [key2,value2], ...])"
554
var res = {__class__:$DictDict,
555
$numeric_dict : {},
556
$object_dict : {},
557
$string_dict : {},
558
$str_hash: {},
561
var i = -1, stop = args.length-1
562
var si = $DictDict.__setitem__
563
while(i++<stop){
564
var item=args[i]
565
switch(typeof item[0]) {
566
case 'string':
567
res.$string_dict[item[0]]=item[1]
568
res.$str_hash[str_hash(item[0])]=item[0]
569
break;
570
case 'number':
571
res.$numeric_dict[item[0]]=item[1]
572
break
573
default:
574
si(res, item[0], item[1])
578
return res
579
}
580
Sep 5, 2014
581
// apply __init__ with arguments of dict()
582
var res = {__class__:$DictDict}
583
$DictDict.clear(res)
584
var _args = [res], pos=1
585
for(var i=0, _len_i = arguments.length; i < _len_i;i++){_args[pos++]=arguments[i]}
586
$DictDict.__init__.apply(null,_args)
Sep 5, 2014
587
return res
588
}
Sep 5, 2014
590
dict.__class__ = $B.$factory
591
dict.$dict = $DictDict
592
$DictDict.$factory = dict
593
$DictDict.__new__ = $B.$__new__(dict)
594
595
_b_.dict = dict
597
// following are used for faster access elsewhere
598
$B.$dict_iterator = function(d) { return new $item_generator(d) }
599
$B.$dict_length = $DictDict.__len__
600
$B.$dict_getitem = $DictDict.__getitem__
601
$B.$dict_get = $DictDict.get
602
$B.$dict_set = $DictDict.__setitem__
603
$B.$dict_contains = $DictDict.__contains__
604
$B.$dict_items = function(d) { return new $item_generator(d).as_list() }
605
$B.$copy_dict = $copy_dict // copy from right to left
606
$B.$dict_get_copy = $DictDict.copy // return a shallow copy
607
608
// Class used for attribute __dict__ of objects
609
610
$ObjDictDict = {__class__:$B.$type,__name__:'mapping_proxy'}
611
$ObjDictDict.__mro__ = [$ObjDictDict, $DictDict, $ObjectDict]
612
613
$ObjDictDict.__delitem__ = function(self, key){
614
$DictDict.__delitem__(self, key)
615
delete self.$obj[key]
616
}
617
618
$ObjDictDict.__setitem__ = function(self, key, value){
619
$DictDict.__setitem__(self, key, value)
620
self.$obj[key] = value
621
}
622
623
$ObjDictDict.clear = function(self){
624
$DictDict.clear(self)
625
for(var key in self.$obj){delete self.$obj[key]}
626
}
627
628
$ObjDictDict.pop = function(self, key, _default){
629
$DictDict.pop(self, key, _default)
630
delete self.$obj[key]
631
return key
632
}
633
634
$ObjDictDict.popitem = function(self){
635
var res = $DictDict.popitem(self) // tuple
636
var key = res[0]
637
delete self.$obj[key]
638
return res
639
}
640
641
$ObjDictDict.update = function(self){
642
$DictDict.update.apply(null, arguments)
643
// Update attributes of underlying object by iterating on self.items()
644
var it = $DictDict.items(self)
645
while(true){
646
try{
647
var item = next(it)
648
self.$obj[item[0]] = item[1]
649
}catch(err){
650
if($B.is_exc(err,[_b_.StopIteration])){
651
$B.$pop_exc();return
652
}
653
throw err
654
}
655
}
659
// Function called to get attribute "__dict__" of an object
660
if(obj.__class__===$B.$factory){
661
// For classes, use the class dictionary
662
obj = obj.$dict
663
}
664
var res = {__class__:$ObjDictDict,$obj:obj}
665
$DictDict.clear(res)
666
var si=$DictDict.__setitem__
668
if(attr.charAt(0)!='$') si(res, attr, obj[attr])
669
}
670
return res
671
}
672
obj_dict.$dict = $ObjDictDict
673
obj_dict.__class__ = $B.$factory
674
$ObjDictDict.$factory = obj_dict
675
676
$B.obj_dict = obj_dict
677
Sep 5, 2014
678
})(__BRYTHON__)