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