Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
sagemathinc
GitHub Repository: sagemathinc/python-wasm
Path: blob/main/python/pylang/src/baselib/containers.py
1398 views
1
# vim:fileencoding=utf-8
2
# License: BSD
3
# Copyright: 2015, Kovid Goyal <kovid at kovidgoyal.net>
4
5
# globals:ρσ_iterator_symbol, ρσ_kwargs_symbol, ρσ_arraylike, ρσ_repr
6
7
def ρσ_equals(a, b):
8
if a is b:
9
return True
10
type_a = jstype(a)
11
type_b = jstype(b)
12
# WARNING: We have to use "is" here to avoid recursive call to ρσ_equals by getting "===".
13
# However, in genuine Python is comparison with a constant is a WARNING/Error.
14
if type_a is type_b and (type_a is 'number' or type_a is 'string'
15
or type_a is 'boolean'):
16
return a is b
17
if a and jstype(a.__eq__) is 'function':
18
return a.__eq__(b)
19
if b and jstype(b.__eq__) is 'function':
20
return b.__eq__(a)
21
if ρσ_arraylike(a) and ρσ_arraylike(b):
22
if a.length != b.length:
23
return False
24
for i in range(len(a)):
25
if not (a[i] == b[i]):
26
return False
27
return True
28
if jstype(a) is 'object' and jstype(
29
b) is 'object' and a is not None and b is not None and (
30
(a.constructor is Object or Object.getPrototypeOf(a) is None)
31
and
32
(b.constructor is Object or Object.getPrototypeOf(b) is None)):
33
# Do a dict like comparison as this is most likely either a JS has
34
# (Object.create(null) or a JS object used as a hash (v"{}"))
35
akeys, bkeys = Object.keys(a), Object.keys(b)
36
if akeys.length is not bkeys.length:
37
return False
38
for j in range(len(akeys)):
39
key = akeys[j]
40
if not (a[key] == b[key]):
41
return False
42
return True
43
return False
44
45
def ρσ_not_equals(a, b):
46
if a is b:
47
return False
48
if a and jstype(a.__ne__) is 'function':
49
return a.__ne__(b)
50
if b and jstype(b.__ne__) is 'function':
51
return b.__ne__(a)
52
return not ρσ_equals(a, b)
53
54
v'var equals = ρσ_equals'
55
56
# list {{{
57
58
def ρσ_list_extend(iterable):
59
if Array.isArray(iterable) or jstype(iterable) is 'string':
60
# Allocate all new memory in one operation
61
start = this.length
62
this.length += iterable.length
63
for v'var i = 0; i < iterable.length; i++':
64
this[start + i] = iterable[i] # noqa:undef
65
else:
66
iterator = iterable.keys() if jstype(Map) is 'function' and v'iterable instanceof Map' else iterable[ρσ_iterator_symbol]()
67
result = iterator.next()
68
while not result.done:
69
this.push(result.value)
70
result = iterator.next()
71
72
def ρσ_list_index(val, start, stop):
73
start = start or 0
74
if start < 0:
75
start = this.length + start
76
if start < 0:
77
raise ValueError(val + ' is not in list')
78
if stop is undefined:
79
idx = this.indexOf(val, start)
80
if idx is -1:
81
raise ValueError(val + ' is not in list')
82
return idx
83
if stop < 0:
84
stop = this.length + stop
85
for v'var i = start; i < stop; i++':
86
if this[i] == val:
87
return i # noqa:undef
88
raise ValueError(val + ' is not in list')
89
90
def ρσ_list_pop(index):
91
if this.length is 0:
92
raise IndexError('list is empty')
93
if index is undefined:
94
index = -1
95
ans = this.splice(index, 1)
96
if not ans.length:
97
raise IndexError('pop index out of range')
98
return ans[0]
99
100
def ρσ_list_remove(value):
101
idx = this.indexOf(value)
102
if idx is -1:
103
raise ValueError(value + ' not in list')
104
this.splice(idx, 1)
105
106
def ρσ_list_to_string():
107
return '[' + this.join(', ') + ']'
108
109
def ρσ_list_insert(index, val):
110
if index < 0:
111
index += this.length
112
index = min(this.length, max(index, 0))
113
if index is 0:
114
this.unshift(val)
115
return
116
for v'var i = this.length; i > index; i--':
117
this[i] = this[i - 1] # noqa:undef
118
this[index] = val
119
120
def ρσ_list_copy():
121
return ρσ_list_constructor(this)
122
123
def ρσ_list_clear():
124
this.length = 0
125
126
def ρσ_list_as_array():
127
return Array.prototype.slice.call(this)
128
129
def ρσ_list_count(value):
130
return this.reduce(def(n, val): return n + (val is value);, 0)
131
132
def ρσ_list_sort_key(value):
133
t = jstype(value)
134
if t is 'string' or t is 'number':
135
return value
136
return value.toString()
137
138
def ρσ_list_sort_cmp(a, b, ap, bp):
139
if a < b:
140
return -1
141
if a > b:
142
return 1
143
return ap - bp
144
145
def ρσ_list_sort(key=None, reverse=False):
146
key = key or ρσ_list_sort_key
147
mult = -1 if reverse else 1
148
keymap = dict()
149
posmap = dict()
150
for v'var i=0; i < this.length; i++':
151
k = this[i] # noqa:undef
152
keymap.set(k, key(k))
153
posmap.set(k, i)
154
this.sort(def (a, b): return mult * ρσ_list_sort_cmp(keymap.get(a), keymap.get(b), posmap.get(a), posmap.get(b));)
155
156
def ρσ_list_concat(): # ensure concat() returns an object of type list
157
ans = Array.prototype.concat.apply(this, arguments)
158
ρσ_list_decorate(ans)
159
return ans
160
161
def ρσ_list_slice(): # ensure slice() returns an object of type list
162
ans = Array.prototype.slice.apply(this, arguments)
163
ρσ_list_decorate(ans)
164
return ans
165
166
def ρσ_list_iterator(value):
167
self = this
168
return {
169
'_i':-1,
170
'_list':self,
171
'next':def():
172
this._i += 1
173
if this._i >= this._list.length:
174
return {'done':True}
175
return {'done':False, 'value':this._list[this._i]}
176
,
177
}
178
179
def ρσ_list_len():
180
return this.length
181
182
def ρσ_list_contains(val):
183
for v'var i = 0; i < this.length; i++':
184
if this[i] == val:
185
return True
186
return False
187
188
def ρσ_list_eq(other):
189
if not ρσ_arraylike(other):
190
return False
191
if this.length != other.length:
192
return False
193
for v'var i = 0; i < this.length; i++':
194
if not (this[i] == other[i]):
195
return False
196
return True
197
198
def ρσ_list_mul(other):
199
# In Javascript it seems that the fastest way
200
# is to directly assign using a for loop. Everything
201
# else seems much slower. This is something that
202
# Python is just much faster at, perhaps because Javascript
203
# doesn't really have arrays (they are really hash maps).
204
ans = []
205
k = int(other)
206
n = this.length
207
r"%js let s=0; for(let i=0; i<k; i++) { for(let j=0; j<n; j++) {ans[s++]=this[j];}}"
208
return ans
209
210
def ρσ_list_decorate(ans):
211
ans.append = Array.prototype.push
212
ans.toString = ρσ_list_to_string
213
ans.inspect = ρσ_list_to_string
214
ans.extend = ρσ_list_extend
215
ans.index = ρσ_list_index
216
ans.pypop = ρσ_list_pop
217
ans.remove = ρσ_list_remove
218
ans.insert = ρσ_list_insert
219
ans.copy = ρσ_list_copy
220
ans.clear = ρσ_list_clear
221
ans.count = ρσ_list_count
222
ans.concat = ρσ_list_concat
223
ans.pysort = ρσ_list_sort
224
ans.slice = ρσ_list_slice
225
ans.as_array = ρσ_list_as_array
226
ans.__len__ = ρσ_list_len
227
ans.__contains__ = ρσ_list_contains
228
ans.__eq__ = ρσ_list_eq
229
ans.__mul__ = ρσ_list_mul
230
ans.constructor = ρσ_list_constructor
231
if jstype(ans[ρσ_iterator_symbol]) is not 'function':
232
# Happens on ES 5 runtimes
233
ans[ρσ_iterator_symbol] = ρσ_list_iterator
234
return ans
235
236
def ρσ_list_constructor(iterable):
237
if iterable is undefined:
238
ans = v'[]'
239
elif ρσ_arraylike(iterable):
240
ans = new Array(iterable.length)
241
for v'var i = 0; i < iterable.length; i++':
242
ans[i] = iterable[i] # noqa:undef
243
elif jstype(iterable[ρσ_iterator_symbol]) is 'function':
244
ans = Array.from(iterable)
245
elif jstype(iterable) is 'number':
246
# non-pythonic optimization to allocate all needed memory in a single operation
247
ans = new Array(iterable)
248
else:
249
ans = Object.keys(iterable)
250
return ρσ_list_decorate(ans)
251
ρσ_list_constructor.__name__ = 'list'
252
253
v'var list = ρσ_list_constructor, list_wrap = ρσ_list_decorate'
254
255
def sorted(iterable, key=None, reverse=False):
256
ans = ρσ_list_constructor(iterable)
257
ans.pysort(key, reverse)
258
return ans
259
# }}}
260
261
# set {{{
262
v'var ρσ_global_object_id = 0, ρσ_set_implementation'
263
264
def ρσ_set_keyfor(x):
265
t = jstype(x)
266
if t is 'string' or t is 'number' or t is 'boolean':
267
return '_' + t[0] + x
268
if v'x === null': # also matches undefined
269
return "__!@#$0"
270
ans = x.ρσ_hash_key_prop
271
if ans is undefined:
272
v'ans = "_!@#$" + (++ρσ_global_object_id)'
273
Object.defineProperty(x, 'ρσ_hash_key_prop', { 'value': ans })
274
return ans
275
276
def ρσ_set_polyfill():
277
this._store = {}
278
this.size = 0
279
280
ρσ_set_polyfill.prototype.add = def(x):
281
key = ρσ_set_keyfor(x)
282
if not Object.prototype.hasOwnProperty.call(this._store, key):
283
this.size += 1
284
this._store[key] = x
285
return this
286
287
ρσ_set_polyfill.prototype.clear = def(x):
288
this._store = {}
289
this.size = 0
290
291
ρσ_set_polyfill.prototype.delete = def(x):
292
key = ρσ_set_keyfor(x)
293
if Object.prototype.hasOwnProperty.call(this._store, key):
294
this.size -= 1
295
v'delete this._store[key]'
296
return True
297
return False
298
299
ρσ_set_polyfill.prototype.has = def(x):
300
return Object.prototype.hasOwnProperty.call(this._store, ρσ_set_keyfor(x))
301
302
ρσ_set_polyfill.prototype.values = def(x):
303
ans = v"{'_keys': Object.keys(this._store), '_i':-1, '_s':this._store}"
304
ans[ρσ_iterator_symbol] = def():
305
return this
306
ans['next'] = def():
307
this._i += 1
308
if this._i >= this._keys.length:
309
return v"{'done': true}"
310
return v"{'done':false, 'value':this._s[this._keys[this._i]]}"
311
return ans
312
313
if jstype(Set) is not 'function' or jstype(Set.prototype.delete) is not 'function':
314
v'ρσ_set_implementation = ρσ_set_polyfill'
315
else:
316
v'ρσ_set_implementation = Set'
317
318
def ρσ_set(iterable):
319
if v'this instanceof ρσ_set':
320
this.jsset = new ρσ_set_implementation() # noqa:undef
321
ans = this
322
if iterable is undefined:
323
return ans
324
s = ans.jsset
325
if ρσ_arraylike(iterable):
326
for v'var i = 0; i < iterable.length; i++':
327
s.add(iterable[i])
328
elif jstype(iterable[ρσ_iterator_symbol]) is 'function':
329
iterator = iterable.keys() if jstype(Map) is 'function' and v'iterable instanceof Map' else iterable[ρσ_iterator_symbol]()
330
result = iterator.next()
331
while not result.done:
332
s.add(result.value)
333
result = iterator.next()
334
else:
335
keys = Object.keys(iterable)
336
for v'var j=0; j < keys.length; j++':
337
s.add(keys[j])
338
return ans
339
else:
340
return new ρσ_set(iterable)
341
ρσ_set.prototype.__name__ = 'set'
342
343
# These are for JavaScript users' convenience
344
Object.defineProperties(ρσ_set.prototype, {
345
'length': { 'get': def(): return this.jsset.size; },
346
'size': { 'get': def(): return this.jsset.size; },
347
})
348
349
ρσ_set.prototype.__len__ = def(): return this.jsset.size
350
ρσ_set.prototype.has = ρσ_set.prototype.__contains__ = def(x): return this.jsset.has(x)
351
ρσ_set.prototype.add = def(x): this.jsset.add(x)
352
ρσ_set.prototype.clear = def(): this.jsset.clear()
353
ρσ_set.prototype.copy = def(): return ρσ_set(this)
354
ρσ_set.prototype.discard = def(x): this.jsset.delete(x)
355
ρσ_set.prototype[ρσ_iterator_symbol] = def(): return this.jsset.values()
356
357
ρσ_set.prototype.difference = def():
358
ans = new ρσ_set()
359
s = ans.jsset
360
iterator = this.jsset.values()
361
r = iterator.next()
362
while not r.done:
363
x = r.value
364
has = False
365
for v'var i = 0; i < arguments.length; i++':
366
if arguments[i].has(x): # noqa:undef
367
has = True
368
break
369
if not has:
370
s.add(x)
371
r = iterator.next()
372
return ans
373
374
ρσ_set.prototype.difference_update = def():
375
s = this.jsset
376
remove = v'[]'
377
iterator = s.values()
378
r = iterator.next()
379
while not r.done:
380
x = r.value
381
for v'var i = 0; i < arguments.length; i++':
382
if arguments[i].has(x): # noqa:undef
383
remove.push(x)
384
break
385
r = iterator.next()
386
for v'var j = 0; j < remove.length; j++':
387
s.delete(remove[j]) # noqa:undef
388
389
ρσ_set.prototype.intersection = def():
390
ans = new ρσ_set()
391
s = ans.jsset
392
iterator = this.jsset.values()
393
r = iterator.next()
394
while not r.done:
395
x = r.value
396
has = True
397
for v'var i = 0; i < arguments.length; i++':
398
if not arguments[i].has(x): # noqa:undef
399
has = False
400
break
401
if has:
402
s.add(x)
403
r = iterator.next()
404
return ans
405
406
ρσ_set.prototype.intersection_update = def():
407
s = this.jsset
408
remove = v'[]'
409
iterator = s.values()
410
r = iterator.next()
411
while not r.done:
412
x = r.value
413
for v'var i = 0; i < arguments.length; i++':
414
if not arguments[i].has(x): # noqa:undef
415
remove.push(x)
416
break
417
r = iterator.next()
418
for v'var j = 0; j < remove.length; j++':
419
s.delete(remove[j]) # noqa:undef
420
421
ρσ_set.prototype.isdisjoint = def(other):
422
iterator = this.jsset.values()
423
r = iterator.next()
424
while not r.done:
425
x = r.value
426
if other.has(x):
427
return False
428
r = iterator.next()
429
return True
430
431
ρσ_set.prototype.issubset = def(other):
432
iterator = this.jsset.values()
433
r = iterator.next()
434
while not r.done:
435
x = r.value
436
if not other.has(x):
437
return False
438
r = iterator.next()
439
return True
440
441
ρσ_set.prototype.issuperset = def(other):
442
s = this.jsset
443
iterator = other.jsset.values()
444
r = iterator.next()
445
while not r.done:
446
x = r.value
447
if not s.has(x):
448
return False
449
r = iterator.next()
450
return True
451
452
ρσ_set.prototype.pop = def():
453
iterator = this.jsset.values()
454
r = iterator.next()
455
if r.done:
456
raise KeyError('pop from an empty set')
457
this.jsset.delete(r.value)
458
return r.value
459
460
ρσ_set.prototype.remove = def(x):
461
if not this.jsset.delete(x):
462
raise KeyError(x.toString())
463
464
ρσ_set.prototype.symmetric_difference = def(other):
465
return this.union(other).difference(this.intersection(other))
466
467
ρσ_set.prototype.symmetric_difference_update = def(other):
468
common = this.intersection(other)
469
this.update(other)
470
this.difference_update(common)
471
472
ρσ_set.prototype.union = def():
473
ans = ρσ_set(this)
474
ans.update.apply(ans, arguments)
475
return ans
476
477
ρσ_set.prototype.update = def():
478
s = this.jsset
479
for v'var i=0; i < arguments.length; i++':
480
iterator = arguments[i][ρσ_iterator_symbol]() # noqa:undef
481
r = iterator.next()
482
while not r.done:
483
s.add(r.value)
484
r = iterator.next()
485
486
ρσ_set.prototype.toString = ρσ_set.prototype.__repr__ = ρσ_set.prototype.__str__ = ρσ_set.prototype.inspect = def():
487
return '{' + list(this).join(', ') + '}'
488
489
ρσ_set.prototype.__eq__ = def(other):
490
if not v'other instanceof this.constructor':
491
return False
492
if other.size is not this.size:
493
return False
494
if other.size is 0:
495
return True
496
iterator = other[ρσ_iterator_symbol]()
497
r = iterator.next()
498
while not r.done:
499
if not this.has(r.value):
500
return False
501
r = iterator.next()
502
return True
503
504
def ρσ_set_wrap(x):
505
ans = new ρσ_set()
506
ans.jsset = x
507
return ans
508
509
v'var set = ρσ_set, set_wrap = ρσ_set_wrap'
510
# }}}
511
512
# dict {{{
513
v'var ρσ_dict_implementation'
514
515
def ρσ_dict_polyfill():
516
this._store = {}
517
this.size = 0
518
519
ρσ_dict_polyfill.prototype.set = def(x, value):
520
key = ρσ_set_keyfor(x)
521
if not Object.prototype.hasOwnProperty.call(this._store, key):
522
this.size += 1
523
this._store[key] = v'[x, value]'
524
return this
525
526
ρσ_dict_polyfill.prototype.clear = def(x):
527
this._store = {}
528
this.size = 0
529
530
ρσ_dict_polyfill.prototype.delete = def(x):
531
key = ρσ_set_keyfor(x)
532
if Object.prototype.hasOwnProperty.call(this._store, key):
533
this.size -= 1
534
v'delete this._store[key]'
535
return True
536
return False
537
538
ρσ_dict_polyfill.prototype.has = def(x):
539
return Object.prototype.hasOwnProperty.call(this._store, ρσ_set_keyfor(x))
540
541
ρσ_dict_polyfill.prototype.get = def(x):
542
try:
543
return this._store[ρσ_set_keyfor(x)][1]
544
except TypeError: # Key is not present
545
return undefined
546
547
ρσ_dict_polyfill.prototype.values = def(x):
548
ans = v"{'_keys': Object.keys(this._store), '_i':-1, '_s':this._store}"
549
ans[ρσ_iterator_symbol] = def():
550
return this
551
ans['next'] = def():
552
this._i += 1
553
if this._i >= this._keys.length:
554
return v"{'done': true}"
555
return v"{'done':false, 'value':this._s[this._keys[this._i]][1]}"
556
return ans
557
558
ρσ_dict_polyfill.prototype.keys = def(x):
559
ans = v"{'_keys': Object.keys(this._store), '_i':-1, '_s':this._store}"
560
ans[ρσ_iterator_symbol] = def():
561
return this
562
ans['next'] = def():
563
this._i += 1
564
if this._i >= this._keys.length:
565
return v"{'done': true}"
566
return v"{'done':false, 'value':this._s[this._keys[this._i]][0]}"
567
return ans
568
569
ρσ_dict_polyfill.prototype.entries = def(x):
570
ans = v"{'_keys': Object.keys(this._store), '_i':-1, '_s':this._store}"
571
ans[ρσ_iterator_symbol] = def():
572
return this
573
ans['next'] = def():
574
this._i += 1
575
if this._i >= this._keys.length:
576
return v"{'done': true}"
577
return v"{'done':false, 'value':this._s[this._keys[this._i]]}"
578
return ans
579
580
if jstype(Map) is not 'function' or jstype(Map.prototype.delete) is not 'function':
581
v'ρσ_dict_implementation = ρσ_dict_polyfill'
582
else:
583
v'ρσ_dict_implementation = Map'
584
585
def ρσ_dict(iterable, **kw):
586
if v'this instanceof ρσ_dict':
587
# TODO: this is really for copying dicts.
588
this.jsmap = new ρσ_dict_implementation() # noqa:undef
589
if iterable is not undefined:
590
this.update(iterable)
591
this.update(kw)
592
return this
593
else:
594
return new ρσ_dict(iterable, **kw)
595
ρσ_dict.prototype.__name__ = 'dict'
596
597
598
# These are for JavaScript users' convenience
599
Object.defineProperties(ρσ_dict.prototype, {
600
'length': { 'get': def(): return this.jsmap.size; },
601
'size': { 'get': def(): return this.jsmap.size; },
602
})
603
604
ρσ_dict.prototype.__len__ = def(): return this.jsmap.size
605
ρσ_dict.prototype.has = ρσ_dict.prototype.__contains__ = def(x): return this.jsmap.has(x)
606
ρσ_dict.prototype.set = ρσ_dict.prototype.__setitem__ = def(key, value): this.jsmap.set(key, value)
607
ρσ_dict.prototype.__delitem__ = def (key): this.jsmap.delete(key)
608
ρσ_dict.prototype.clear = def(): this.jsmap.clear()
609
ρσ_dict.prototype.copy = def(): return ρσ_dict(this)
610
ρσ_dict.prototype.keys = def(): return this.jsmap.keys()
611
ρσ_dict.prototype.values = def(): return this.jsmap.values()
612
ρσ_dict.prototype.items = ρσ_dict.prototype.entries = def(): return this.jsmap.entries()
613
ρσ_dict.prototype[ρσ_iterator_symbol] = def(): return this.jsmap.keys()
614
615
ρσ_dict.prototype.__getitem__ = def (key):
616
ans = this.jsmap.get(key)
617
if ans is undefined and not this.jsmap.has(key):
618
raise KeyError(key + '')
619
return ans
620
621
ρσ_dict.prototype.get = def (key, defval):
622
ans = this.jsmap.get(key)
623
if ans is undefined and not this.jsmap.has(key):
624
return None if defval is undefined else defval
625
return ans
626
627
ρσ_dict.prototype.set_default = def (key, defval):
628
j = this.jsmap
629
if not j.has(key):
630
j.set(key, defval)
631
return defval
632
return j.get(key)
633
634
ρσ_dict.fromkeys = ρσ_dict.prototype.fromkeys = def (iterable, value=None):
635
ans = ρσ_dict()
636
iterator = iter(iterable)
637
r = iterator.next()
638
while not r.done:
639
ans.set(r.value, value)
640
r = iterator.next()
641
return ans
642
643
ρσ_dict.prototype.pop = def (key, defval):
644
ans = this.jsmap.get(key)
645
if ans is undefined and not this.jsmap.has(key):
646
if defval is undefined:
647
raise KeyError(key)
648
return defval
649
this.jsmap.delete(key)
650
return ans
651
652
ρσ_dict.prototype.popitem = def ():
653
r = this.jsmap.entries().next()
654
if r.done:
655
raise KeyError('dict is empty')
656
this.jsmap.delete(r.value[0])
657
return r.value
658
659
ρσ_dict.prototype.update = def ():
660
if arguments.length is 0:
661
return
662
m = this.jsmap
663
iterable = arguments[0]
664
if Array.isArray(iterable):
665
for v'var i = 0; i < iterable.length; i++':
666
m.set(iterable[i][0], iterable[i][1])
667
elif v'iterable instanceof ρσ_dict':
668
iterator = iterable.items()
669
result = iterator.next()
670
while not result.done:
671
m.set(result.value[0], result.value[1])
672
result = iterator.next()
673
elif jstype(Map) is 'function' and v'iterable instanceof Map':
674
iterator = iterable.entries()
675
result = iterator.next()
676
while not result.done:
677
m.set(result.value[0], result.value[1])
678
result = iterator.next()
679
elif jstype(iterable[ρσ_iterator_symbol]) is 'function':
680
iterator = iterable[ρσ_iterator_symbol]()
681
result = iterator.next()
682
while not result.done:
683
m.set(result.value[0], result.value[1])
684
result = iterator.next()
685
else:
686
keys = Object.keys(iterable)
687
for v'var j=0; j < keys.length; j++':
688
if keys[j] is not ρσ_iterator_symbol:
689
m.set(keys[j], iterable[keys[j]])
690
if arguments.length > 1:
691
ρσ_dict.prototype.update.call(this, arguments[1])
692
693
ρσ_dict.prototype.toString = ρσ_dict.prototype.inspect = ρσ_dict.prototype.__str__ = ρσ_dict.prototype.__repr__ = def():
694
entries = v'[]'
695
iterator = this.jsmap.entries()
696
r = iterator.next()
697
while not r.done:
698
entries.push(ρσ_repr(r.value[0]) + ': ' + ρσ_repr(r.value[1]))
699
r = iterator.next()
700
return '{' + entries.join(', ') + '}'
701
702
ρσ_dict.prototype.__eq__ = def(other):
703
if not v'(other instanceof this.constructor)':
704
return False
705
if other.size is not this.size:
706
return False
707
if other.size is 0:
708
return True
709
iterator = other.items()
710
r = iterator.next()
711
while not r.done:
712
x = this.jsmap.get(r.value[0])
713
if (x is undefined and not this.jsmap.has(r.value[0])) or x is not r.value[1]:
714
return False
715
r = iterator.next()
716
return True
717
718
ρσ_dict.prototype.as_object = def(other):
719
ans = {}
720
iterator = this.jsmap.entries()
721
r = iterator.next()
722
while not r.done:
723
ans[r.value[0]] = r.value[1]
724
r = iterator.next()
725
return ans
726
727
def ρσ_dict_wrap(x):
728
ans = new ρσ_dict()
729
ans.jsmap = x
730
return ans
731
732
v'var dict = ρσ_dict, dict_wrap = ρσ_dict_wrap'
733
734
# }}}
735
736