Skip to content
Permalink
Newer
Older
100644 672 lines (578 sloc) 18.5 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(){
145
var $ = $B.args('__contains__', 2, {self:null, item:null},
146
['self', 'item'], arguments, {}, null, null),
147
self=$.self, item=$.item
Sep 5, 2014
148
if(self.$jsobj) return self.$jsobj[item]!==undefined
149
switch(typeof item) {
150
case 'string':
151
return self.$string_dict[item] !==undefined
152
case 'number':
153
return self.$numeric_dict[item] !==undefined
155
156
var _key=hash(item)
157
if (self.$str_hash[_key]!==undefined &&
158
_b_.getattr(item,'__eq__')(self.$str_hash[_key])){return true}
159
if (self.$numeric_dict[_key]!==undefined &&
160
_b_.getattr(item,'__eq__')(_key)){return true}
161
if (self.$object_dict[_key] !== undefined) {
162
var _eq = getattr(item, '__eq__')
163
var i=self.$object_dict[_key].length
164
while(i--) {
165
if (_eq(self.$object_dict[_key][i][0])) return true
166
}
167
}
168
return false
Sep 5, 2014
169
}
170
171
$DictDict.__delitem__ = function(self,arg){
172
if(self.$jsobj){
173
if(self.$jsobj[arg]===undefined){throw KeyError(arg)}
174
delete self.$jsobj[arg]
177
switch(typeof arg) {
178
case 'string':
179
if (self.$string_dict[arg] === undefined) throw KeyError(_b_.str(arg))
180
delete self.$string_dict[arg]
181
delete self.$str_hash[str_hash(arg)]
183
case 'number':
184
if (self.$numeric_dict[arg] === undefined) throw KeyError(_b_.str(arg))
185
delete self.$numeric_dict[arg]
188
// go with defaults
190
var _key=hash(arg)
191
if (self.$object_dict[_key] !== undefined) {
192
var _eq=getattr(arg, '__eq__')
193
var i=self.$object_dict[_key].length
194
while(i--) {
195
if (_eq(self.$object_dict[_key][i][0])) {
196
delete self.$object_dict[_key][i];
197
break;
198
}
199
}
200
}
201
202
if(self.$jsobj) delete self.$jsobj[arg]
Sep 5, 2014
204
}
205
206
$DictDict.__eq__ = function(self,other){
207
if(other===undefined){ // compare self to class "dict"
208
return self===dict
209
}
210
if(!isinstance(other,dict)) return false
212
if ($DictDict.__len__(self) != $DictDict.__len__(other)){return false}
214
var _l = new $item_generator(self).as_list()
215
var i=_l.length
216
while(i--) {
217
var key=_l[i][0]
218
if (!$DictDict.__contains__(other, key)) {return false}
219
var v1=_l[i][1]
220
var v2=$DictDict.__getitem__(other, key)
221
if (!getattr(v1, '__eq__')(v2)) {return false}
Sep 5, 2014
225
}
226
227
$DictDict.__getitem__ = function(self,arg){
228
229
if(self.$jsobj){
230
if(self.$jsobj[arg]===undefined){return None}
231
return self.$jsobj[arg]
232
}
233
234
switch(typeof arg) {
235
case 'string':
236
if (self.$string_dict[arg] !== undefined) return self.$string_dict[arg]
237
break
238
case 'number':
239
if (self.$numeric_dict[arg] !== undefined) return self.$numeric_dict[arg]
242
// since the key is more complex use 'default' method of getting item
243
244
var _key=hash(arg)
245
var sk = self.$str_hash[_key]
246
if (sk!==undefined && _b_.getattr(arg,'__eq__')(sk)){
247
return self.$string_dict[sk]
248
}
249
if (self.$numeric_dict[_key]!==undefined &&
250
_b_.getattr(arg,'__eq__')(_key)){
251
return self.$numeric_dict[_key]
252
}
253
if (self.$object_dict[_key] !== undefined) {
254
var _eq=getattr(arg, '__eq__')
255
var i=self.$object_dict[_key].length
256
while(i--) {
257
if (_eq(self.$object_dict[_key][i][0])) {
258
return self.$object_dict[_key][i][1]
259
}
260
}
261
}
262
263
if(hasattr(self, '__missing__')) return getattr(self, '__missing__')(arg)
264
Sep 5, 2014
265
throw KeyError(_b_.str(arg))
266
}
267
268
$DictDict.__hash__ = function(self) {
269
if (self === undefined) {
270
return $DictDict.__hashvalue__ || $B.$py_next_hash-- // for hash of dict type (not instance of dict)
271
}
272
throw _b_.TypeError("unhashable type: 'dict'");
273
}
Sep 5, 2014
274
275
$DictDict.__init__ = function(self){
276
var args = [], pos=0
277
for(var i=1;i<arguments.length;i++){args[pos++]=arguments[i]}
280
switch(args.length) {
281
case 0:
282
return
283
case 1:
Sep 5, 2014
284
var obj = args[0]
285
if(Array.isArray(obj)){
286
var i = obj.length
287
var si = $DictDict.__setitem__
288
while(i-->0) si(self, obj[i-1][0], obj[i-1][1])
290
}else if(isinstance(obj,dict)){
Sep 5, 2014
293
}
Sep 5, 2014
295
if(obj.__class__===$B.JSObject.$dict){
296
// convert a JSObject into a Python dictionary
297
var si = $DictDict.__setitem__
298
for(var attr in obj.js) si(self,attr,obj.js[attr])
299
300
// Attribute $jsobj is used to update the original JS object
301
// when the dictionary is modified
Sep 5, 2014
304
}
307
var $ns=$B.args('dict',0,{},[],args,{},'args','kw')
Sep 5, 2014
308
var args = $ns['args']
309
var kw = $ns['kw']
Sep 5, 2014
312
if(isinstance(args[0],dict)){
Sep 5, 2014
315
}
Sep 5, 2014
317
// format dict([(k1,v1),(k2,v2)...])
318
319
if(Array.isArray(args[0])){
320
var src = args[0]
322
var si=$DictDict.__setitem__
323
while(i-->0) si(self, src[i-1][0], src[i-1][1])
324
}else{
325
var iterable = iter(args[0])
326
while(1){
327
try{
328
var elt = next(iterable)
329
var key = getattr(elt,'__getitem__')(0)
330
var value = getattr(elt,'__getitem__')(1)
331
$DictDict.__setitem__(self, key, value)
332
}catch(err){
333
if(err.__name__==='StopIteration'){break}
Sep 5, 2014
336
}
337
}
339
if($DictDict.__len__(kw) > 0) $copy_dict(self, kw)
Sep 5, 2014
341
}
342
343
var $dict_iterator = $B.$iterator_class('dict iterator')
344
$DictDict.__iter__ = function(self) {
345
return $DictDict.keys(self)
Sep 5, 2014
346
}
347
348
$DictDict.__len__ = function(self) {
349
var _count=0
350
351
if(self.$jsobj){
352
for(var attr in self.$jsobj){if(attr.charAt(0)!='$'){_count++}}
353
return _count
354
}
356
for (var k in self.$numeric_dict) _count++
357
for (var k in self.$string_dict) _count++
358
for (var k in self.$object_dict) _count+= self.$object_dict[k].length
360
return _count
Sep 5, 2014
362
363
$DictDict.__mro__ = [$DictDict,$ObjectDict]
364
365
$DictDict.__ne__ = function(self,other){return !$DictDict.__eq__(self,other)}
366
367
$DictDict.__next__ = function(self){
369
self.$iter = new $item_generator(self)
370
}
371
try {
372
return self.$iter.next()
373
} catch (err) {
374
if (err.__name__ !== "StopIteration") { throw err }
Sep 5, 2014
375
}
376
}
377
378
$DictDict.__repr__ = function(self){
379
if(self===undefined) return "<class 'dict'>"
380
if(self.$jsobj){ // wrapper around Javascript object
381
var res = []
382
for(var attr in self.$jsobj){
383
if(attr.charAt(0)=='$' || attr=='__class__'){continue}
Nov 4, 2015
384
else{
385
try{
386
res.push("'"+attr+"': "+_b_.repr(self.$jsobj[attr]))
387
}catch(err){
388
// FIX ME
389
}
390
}
391
}
392
return '{'+res.join(', ')+'}'
393
}
394
var _objs=[self] // used to elimate recursion
395
var res=[], pos=0
396
var items = new $item_generator(self).as_list()
397
for (var i=0; i < items.length; i++) {
398
var itm = items[i]
Jan 18, 2015
399
if (_objs.indexOf(itm[1]) > -1 && _b_.isinstance(itm[1], [_b_.dict,_b_.list,_b_.set, _b_.tuple])) {
400
var value='?'+_b_.type(itm[1])
401
if(isinstance(itm[1], dict)) value='{...}'
402
res[pos++]=repr(itm[0])+': '+ value
403
} else {
Jan 18, 2015
404
if (_objs.indexOf(itm[1]) == -1) _objs.push(itm[1])
405
res[pos++]=repr(itm[0])+': '+repr(itm[1])
Sep 5, 2014
407
}
408
return '{'+ res.join(', ') +'}'
Sep 5, 2014
409
}
410
411
$DictDict.__setitem__ = function(self,key,value){
412
413
if(self.$jsobj){self.$jsobj[key]=value;return}
414
415
switch(typeof key) {
416
case 'string':
417
self.$string_dict[key]=value
418
self.$str_hash[str_hash(key)]=key
420
case 'number':
421
self.$numeric_dict[key]=value
425
// if we got here the key is more complex, use default method
427
var _key=hash(key)
428
var _eq=getattr(key, '__eq__')
429
430
if(self.$numeric_dict[_key]!==undefined && _eq(_key)){
431
self.$numeric_dict[_key] = value
433
}
434
var sk = self.$str_hash[_key]
435
if(sk!==undefined && _eq(sk)){
436
self.$string_dict[sk] = value
438
}
439
440
441
if (self.$object_dict[_key] != undefined) {
442
var i=self.$object_dict[_key].length
443
while(i--) {
444
if (_eq(self.$object_dict[_key][i][0])) {
445
self.$object_dict[_key][i]=[key, value]
447
}
448
}
449
// if we got here this key is not in the object
450
self.$object_dict[_key].push([key, value])
451
} else {
452
self.$object_dict[_key]=[[key, value]]
Sep 5, 2014
455
}
456
457
$DictDict.__str__ = $DictDict.__repr__
458
459
// add "reflected" methods
460
$B.make_rmethods($DictDict)
461
462
$DictDict.clear = function(){
Sep 5, 2014
463
// Remove all items from the dictionary.
464
var $ = $B.args('clear',1,{self:null},['self'],arguments,{},null,null),
465
self = $.self
467
self.$numeric_dict={}
468
self.$string_dict={}
469
self.$str_hash={}
470
self.$object_dict={}
Sep 5, 2014
472
if(self.$jsobj) self.$jsobj={}
Sep 5, 2014
474
}
475
476
$DictDict.copy = function(self){
477
// Return a shallow copy of the dictionary
478
var $ = $B.args('copy',1,{self:null},['self'],arguments,{},null,null),
479
self = $.self,
480
res = _b_.dict()
Sep 5, 2014
482
return res
483
}
484
485
$DictDict.fromkeys = function(keys,value){
Sep 5, 2014
486
// class method
487
if(value===undefined) value=None
Sep 5, 2014
488
var res = dict()
489
var keys_iter = _b_.iter(keys)
490
while(1){
491
try{
492
var key = _b_.next(keys_iter)
493
$DictDict.__setitem__(res,key,value)
494
}catch(err){
495
if($B.is_exc(err,[_b_.StopIteration])){
496
return res
497
}
498
throw err
499
}
500
}
501
}
502
503
$DictDict.get = function(self, key, _default){
504
var $ = $B.args('get', 3, {self:null, key:null, _default:null},
505
['self', 'key', '_default'], arguments, {_default:$N}, null, null)
506
507
try{return $DictDict.__getitem__($.self, $.key)}
508
catch(err){
509
if(_b_.isinstance(err, _b_.KeyError)){return $._default}
510
else{throw err}
511
}
512
}
513
514
var $dict_itemsDict = $B.$iterator_class('dict_items')
515
516
$DictDict.items = function(self){
517
if (arguments.length > 1) {
518
var _len=arguments.length - 1
519
var _msg="items() takes no arguments ("+_len+" given)"
520
throw _b_.TypeError(_msg)
521
}
522
return $iterator_wrapper(new $item_iterator(self), $dict_itemsDict)
523
}
524
Sep 5, 2014
525
$DictDict.pop = function(self,key,_default){
526
try{
527
var res = $DictDict.__getitem__(self,key)
528
$DictDict.__delitem__(self,key)
529
return res
530
}catch(err){
531
if(err.__name__==='KeyError'){
532
if(_default!==undefined) return _default
533
throw err
534
}
535
throw err
536
}
537
}
538
539
$DictDict.popitem = function(self){
540
try{
541
var itm = new $item_iterator(self).next()
542
$DictDict.__delitem__(self,itm[0])
543
return _b_.tuple(itm)
544
}catch(err) {
545
if (err.__name__ == "StopIteration") {
546
throw KeyError("'popitem(): dictionary is empty'")
547
}
548
}
Sep 5, 2014
549
}
550
551
$DictDict.setdefault = function(self,key,_default){
552
try{return $DictDict.__getitem__(self,key)}
553
catch(err){
554
if(_default===undefined) _default=None
555
$DictDict.__setitem__(self,key,_default)
556
return _default
557
}
558
}
559
560
$DictDict.update = function(self){
561
var params = [], pos=0
562
for(var i=1;i<arguments.length;i++){params[pos++]=arguments[i]}
563
var $ns=$B.args('$DictDict.update',0,{},[],params,{},'args','kw')
Sep 5, 2014
564
var args = $ns['args']
565
if(args.length>0) {
566
var o=args[0]
567
if (isinstance(o,dict)){
568
$copy_dict(self, o)
569
} else if (hasattr(o, '__getitem__') && hasattr(o, 'keys')) {
570
var _keys=_b_.list(getattr(o, 'keys')())
571
var si=$DictDict.__setitem__
572
var i=_keys.length
573
while(i--) {
574
//for (var i=0; i < _keys.length; i++) {
575
var _value = getattr(o, '__getitem__')(_keys[i])
576
si(self, _keys[i], _value)
Sep 5, 2014
579
}
580
var kw = $ns['kw']
Sep 5, 2014
583
}
584
585
function dict(args, second){
587
if(second===undefined && Array.isArray(args)){
588
// Form "dict([[key1, value1], [key2,value2], ...])"
589
var res = {__class__:$DictDict,
590
$numeric_dict : {},
591
$object_dict : {},
592
$string_dict : {},
593
$str_hash: {},
596
var i = -1, stop = args.length-1
597
var si = $DictDict.__setitem__
598
while(i++<stop){
599
var item=args[i]
600
switch(typeof item[0]) {
601
case 'string':
602
res.$string_dict[item[0]]=item[1]
603
res.$str_hash[str_hash(item[0])]=item[0]
604
break;
605
case 'number':
606
res.$numeric_dict[item[0]]=item[1]
607
break
608
default:
609
si(res, item[0], item[1])
613
return res
614
}
615
Sep 5, 2014
616
// apply __init__ with arguments of dict()
617
var res = {__class__:$DictDict}
618
$DictDict.clear(res)
619
var _args = [res], pos=1
620
for(var i=0, _len_i = arguments.length; i < _len_i;i++){_args[pos++]=arguments[i]}
621
$DictDict.__init__.apply(null,_args)
Sep 5, 2014
622
return res
623
}
Sep 5, 2014
625
dict.__class__ = $B.$factory
626
dict.$dict = $DictDict
627
$DictDict.$factory = dict
628
$DictDict.__new__ = $B.$__new__(dict)
629
630
_b_.dict = dict
632
// following are used for faster access elsewhere
633
$B.$dict_iterator = function(d) { return new $item_generator(d) }
634
$B.$dict_length = $DictDict.__len__
635
$B.$dict_getitem = $DictDict.__getitem__
636
$B.$dict_get = $DictDict.get
637
$B.$dict_set = $DictDict.__setitem__
638
$B.$dict_contains = $DictDict.__contains__
639
$B.$dict_items = function(d) { return new $item_generator(d).as_list() }
640
$B.$copy_dict = $copy_dict // copy from right to left
641
$B.$dict_get_copy = $DictDict.copy // return a shallow copy
642
644
// Class for attribute __dict__ of classes
645
var mappingproxyDict = {
646
__class__ : $B.$type,
647
__name__ : "mappingproxy"
648
}
649
mappingproxyDict.__mro__ = [mappingproxyDict, _b_.object.$dict]
650
651
mappingproxyDict.__setitem__ = function(){
652
throw _b_.TypeError("'mappingproxy' object does not support item assignment")
653
}
654
656
function mappingproxy(obj){
657
var res = obj_dict(obj)
658
res.__class__ = mappingproxyDict
659
return res
660
}
661
mappingproxy.__class__ = $B.$factory
662
mappingproxy.$dict = mappingproxyDict
663
mappingproxyDict.$factory = mappingproxy
664
$B.mappingproxy = mappingproxy
665
666
$B.obj_dict = function(obj){
667
var res = dict()
668
res.$jsobj = obj
669
return res
670
}
671
Sep 5, 2014
672
})(__BRYTHON__)