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