rapydscript-ns 0.9.3 → 0.9.5
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.agignore +1 -1
- package/.github/workflows/ci.yml +38 -38
- package/=template.pyj +5 -5
- package/CHANGELOG.md +18 -0
- package/HACKING.md +103 -103
- package/LICENSE +24 -24
- package/PYTHON_GAPS.md +52 -142
- package/README.md +51 -21
- package/TODO.md +1 -26
- package/add-toc-to-readme +2 -2
- package/bin/export +75 -75
- package/bin/rapydscript +0 -0
- package/bin/web-repl-export +102 -102
- package/build +2 -2
- package/language-service/index.js +88 -36
- package/package.json +1 -1
- package/publish.py +37 -37
- package/release/baselib-plain-pretty.js +157 -31
- package/release/baselib-plain-ugly.js +5 -5
- package/release/compiler.js +724 -426
- package/release/signatures.json +29 -29
- package/session.vim +4 -4
- package/setup.cfg +2 -2
- package/src/ast.pyj +7 -0
- package/src/baselib-containers.pyj +41 -4
- package/src/baselib-errors.pyj +4 -3
- package/src/baselib-internal.pyj +47 -18
- package/src/baselib-str.pyj +16 -3
- package/src/compiler.pyj +36 -36
- package/src/errors.pyj +30 -30
- package/src/lib/aes.pyj +646 -646
- package/src/lib/collections.pyj +227 -3
- package/src/lib/copy.pyj +120 -120
- package/src/lib/elementmaker.pyj +83 -83
- package/src/lib/encodings.pyj +126 -126
- package/src/lib/gettext.pyj +569 -569
- package/src/lib/itertools.pyj +580 -580
- package/src/lib/math.pyj +193 -193
- package/src/lib/operator.pyj +11 -11
- package/src/lib/pprint.pyj +455 -0
- package/src/lib/random.pyj +118 -118
- package/src/lib/react.pyj +74 -74
- package/src/lib/statistics.pyj +0 -0
- package/src/lib/traceback.pyj +63 -63
- package/src/lib/uuid.pyj +77 -77
- package/src/monaco-language-service/completions.js +21 -14
- package/src/monaco-language-service/diagnostics.js +2 -2
- package/src/monaco-language-service/dts.js +58 -15
- package/src/monaco-language-service/package.json +3 -0
- package/src/output/classes.pyj +25 -2
- package/src/output/codegen.pyj +4 -1
- package/src/output/comments.pyj +45 -45
- package/src/output/exceptions.pyj +201 -201
- package/src/output/jsx.pyj +164 -164
- package/src/output/treeshake.pyj +182 -182
- package/src/output/utils.pyj +72 -72
- package/src/parse.pyj +42 -7
- package/src/string_interpolation.pyj +72 -72
- package/src/tokenizer.pyj +18 -2
- package/src/unicode_aliases.pyj +576 -576
- package/src/utils.pyj +192 -192
- package/test/_import_one.pyj +37 -37
- package/test/_import_two/__init__.pyj +11 -11
- package/test/_import_two/level2/deep.pyj +4 -4
- package/test/_import_two/other.pyj +6 -6
- package/test/_import_two/sub.pyj +13 -13
- package/test/aes_vectors.pyj +421 -421
- package/test/annotations.pyj +80 -80
- package/test/baselib.pyj +23 -0
- package/test/chainmap.pyj +185 -0
- package/test/dataclasses.pyj +3 -4
- package/test/decorators.pyj +77 -77
- package/test/docstrings.pyj +39 -39
- package/test/elementmaker_test.pyj +45 -45
- package/test/enum.pyj +1 -1
- package/test/functions.pyj +151 -151
- package/test/generators.pyj +41 -41
- package/test/generic.pyj +370 -370
- package/test/internationalization.pyj +73 -73
- package/test/lint.pyj +164 -164
- package/test/loops.pyj +85 -85
- package/test/numpy.pyj +734 -734
- package/test/pprint.pyj +232 -0
- package/test/python_features.pyj +1 -1
- package/test/repl.pyj +121 -121
- package/test/scoped_flags.pyj +76 -76
- package/test/statistics.pyj +224 -0
- package/test/str.pyj +4 -4
- package/test/unit/index.js +455 -0
- package/test/unit/language-service-completions.js +2 -0
- package/test/unit/language-service-dts.js +113 -0
- package/test/unit/language-service-hover.js +455 -455
- package/test/unit/language-service.js +135 -2
- package/test/unit/web-repl.js +349 -1
- package/tools/compiler.d.ts +367 -367
- package/tools/completer.js +131 -131
- package/tools/export.js +4 -2
- package/tools/gettext.js +185 -185
- package/tools/ini.js +65 -65
- package/tools/msgfmt.js +187 -187
- package/tools/repl.js +223 -223
- package/tools/test.js +118 -118
- package/tools/utils.js +141 -128
- package/tools/web_repl.js +95 -95
- package/try +41 -41
- package/web-repl/env.js +196 -196
- package/web-repl/index.html +163 -163
- package/web-repl/prism.css +139 -139
- package/web-repl/prism.js +113 -113
- package/web-repl/rapydscript.js +228 -226
- package/web-repl/sha1.js +25 -25
package/release/signatures.json
CHANGED
|
@@ -1,34 +1,34 @@
|
|
|
1
1
|
{
|
|
2
|
-
"ast": "
|
|
2
|
+
"ast": "9c7c4c0132da3d1e4af19a00c1c0387423484a82",
|
|
3
3
|
"baselib-builtins": "1be74e1e78642c5cbf448f8f2a94aae0f1a3d59c",
|
|
4
4
|
"baselib-bytes": "057ab581c276ef03ce91fecdd4213e412198251c",
|
|
5
|
-
"baselib-containers": "
|
|
6
|
-
"baselib-errors": "
|
|
7
|
-
"baselib-internal": "
|
|
5
|
+
"baselib-containers": "b25e5a999657f3195573679b9eb544cba48c52ba",
|
|
6
|
+
"baselib-errors": "b4c055341bca1943ede820c5d179cfa7e08bb3fe",
|
|
7
|
+
"baselib-internal": "11fb673a8eef58fad100c43e83ef5274e4b6694e",
|
|
8
8
|
"baselib-itertools": "268b7b7af79506e9a01023e8cd3b1741599bb6a5",
|
|
9
|
-
"baselib-str": "
|
|
10
|
-
"compiler": "
|
|
11
|
-
"errors": "
|
|
12
|
-
"output
|
|
13
|
-
"output
|
|
14
|
-
"output
|
|
15
|
-
"output
|
|
16
|
-
"output
|
|
17
|
-
"output
|
|
18
|
-
"output
|
|
19
|
-
"output
|
|
20
|
-
"output
|
|
21
|
-
"output
|
|
22
|
-
"output
|
|
23
|
-
"output
|
|
24
|
-
"output
|
|
25
|
-
"output
|
|
26
|
-
"output
|
|
27
|
-
"parse": "
|
|
28
|
-
"string_interpolation": "
|
|
29
|
-
"tokenizer": "
|
|
30
|
-
"unicode_aliases": "
|
|
31
|
-
"utils": "
|
|
32
|
-
"#compiler#": "
|
|
33
|
-
"#compiled_with#": "
|
|
9
|
+
"baselib-str": "0183cdb36d8bee149e6bd50f03017e5baa1c49e6",
|
|
10
|
+
"compiler": "bb16e915c60dc4ffb5bfe98bef411736d19fa297",
|
|
11
|
+
"errors": "257eca38b6de987e5fd80672bec9b9981847e1bd",
|
|
12
|
+
"output\\classes": "fd465d02dc11e532be40d3d45d14bf57bc668ed0",
|
|
13
|
+
"output\\codegen": "aaf15f93f7ab0de23d9076cc5b1a9a415ffe5690",
|
|
14
|
+
"output\\comments": "63b39620f9d6f407aa2d4ddb557d1c60ef296b05",
|
|
15
|
+
"output\\exceptions": "e7d9119550403e6c5730d40b9bc9c923a23d6eb7",
|
|
16
|
+
"output\\functions": "263416b49c60c78abee42fef83ec460e886fb243",
|
|
17
|
+
"output\\jsx": "14f32c048301965de7764c5b74b651bc279de937",
|
|
18
|
+
"output\\literals": "287ec4222c79f1ebfa2c6efae925e794cbb931ab",
|
|
19
|
+
"output\\loops": "1c9bbd6a2772dd2fc287c0b1aebfac7f5426eb27",
|
|
20
|
+
"output\\modules": "8383da8f58a79921d24e4e0261360a7d0708c4db",
|
|
21
|
+
"output\\operators": "8f7b1cf4f8a91102fc04104f8a799dcd8849963e",
|
|
22
|
+
"output\\statements": "94ee0cd084f22aea451b96eb1a9a831084cc4267",
|
|
23
|
+
"output\\stream": "9bd250ebb7ee43374d69c24357f8c985f95397d4",
|
|
24
|
+
"output\\treeshake": "4a490ba097739d924db9e3cd9eb7718db5e24cae",
|
|
25
|
+
"output\\utils": "e957919bfccb9a3ab510d824a8f2ee3fc2689795",
|
|
26
|
+
"output\\__init__": "da39a3ee5e6b4b0d3255bfef95601890afd80709",
|
|
27
|
+
"parse": "d3f79e2e958219ddea28d483e8b337abd16793f1",
|
|
28
|
+
"string_interpolation": "88dce6c2c5ee75126a6838a1506841c6531a0d15",
|
|
29
|
+
"tokenizer": "4a043b2805688a59a21eb99e57567c52ee7b3952",
|
|
30
|
+
"unicode_aliases": "7fbcbc9c24adcb2e33fac8d69aaafe5047fcc2c2",
|
|
31
|
+
"utils": "35a2a707c841da851e18c64edac54e7c20b7dfc9",
|
|
32
|
+
"#compiler#": "a8443467a8034f2a29d201a7264eb0cdbe61ff4e",
|
|
33
|
+
"#compiled_with#": "a8443467a8034f2a29d201a7264eb0cdbe61ff4e"
|
|
34
34
|
}
|
package/session.vim
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
set wildignore+=*.pyj-cached
|
|
2
|
-
set wildignore+=node_modules
|
|
3
|
-
imap <F4> ρσ_
|
|
4
|
-
cmap <F4> ρσ_
|
|
1
|
+
set wildignore+=*.pyj-cached
|
|
2
|
+
set wildignore+=node_modules
|
|
3
|
+
imap <F4> ρσ_
|
|
4
|
+
cmap <F4> ρσ_
|
package/setup.cfg
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
[rapydscript]
|
|
2
|
-
globals=assert,RapydScript
|
|
1
|
+
[rapydscript]
|
|
2
|
+
globals=assert,RapydScript
|
package/src/ast.pyj
CHANGED
|
@@ -605,6 +605,7 @@ class AST_Class(AST_Scope):
|
|
|
605
605
|
'has_new': "[boolean] true if the class defines a __new__ method",
|
|
606
606
|
'has_attr_dunders': "[boolean] true if the class defines any of __getattr__/__setattr__/__delattr__/__getattribute__",
|
|
607
607
|
'class_kwargs': "[array] keyword arguments from class header (e.g. class C(Base, key=val):) as [[key_node, value_node], ...]",
|
|
608
|
+
'slots': "[array|null] list of __slots__ attribute names, null if not defined",
|
|
608
609
|
}
|
|
609
610
|
|
|
610
611
|
def _walk(self, visitor):
|
|
@@ -1280,6 +1281,12 @@ class AST_Number(AST_Constant):
|
|
|
1280
1281
|
'value': "[number] the numeric value"
|
|
1281
1282
|
}
|
|
1282
1283
|
|
|
1284
|
+
class AST_BigInt(AST_Constant):
|
|
1285
|
+
"A BigInt literal (e.g. 42n)"
|
|
1286
|
+
properties = {
|
|
1287
|
+
'value': "[string] the raw numeric string (without n suffix)"
|
|
1288
|
+
}
|
|
1289
|
+
|
|
1283
1290
|
class AST_RegExp(AST_Constant):
|
|
1284
1291
|
"A regexp literal"
|
|
1285
1292
|
properties = {
|
|
@@ -93,7 +93,10 @@ def ρσ_list_remove(value):
|
|
|
93
93
|
raise ValueError(value + ' not in list')
|
|
94
94
|
|
|
95
95
|
def ρσ_list_to_string():
|
|
96
|
-
|
|
96
|
+
ans = v'[]'
|
|
97
|
+
for v'var i = 0; i < this.length; i++':
|
|
98
|
+
ans.push(ρσ_repr(this[i]))
|
|
99
|
+
return '[' + ans.join(', ') + ']'
|
|
97
100
|
|
|
98
101
|
def ρσ_list_insert(index, val):
|
|
99
102
|
if index < 0:
|
|
@@ -122,9 +125,22 @@ def ρσ_list_sort_key(value):
|
|
|
122
125
|
t = jstype(value)
|
|
123
126
|
if t is 'string' or t is 'number':
|
|
124
127
|
return value
|
|
128
|
+
# Keep objects that define __lt__ unchanged so ρσ_list_sort_cmp can
|
|
129
|
+
# dispatch the dunder; everything else falls back to a string key.
|
|
130
|
+
if value is not None and value is not undefined and jstype(value.__lt__) is 'function':
|
|
131
|
+
return value
|
|
125
132
|
return value.toString()
|
|
126
133
|
|
|
127
134
|
def ρσ_list_sort_cmp(a, b, ap, bp):
|
|
135
|
+
# When the elements define __lt__, order them the Pythonic way via
|
|
136
|
+
# ρσ_op_lt (which also handles a reflected __gt__); otherwise compare
|
|
137
|
+
# the precomputed primitive keys directly.
|
|
138
|
+
if a is not None and a is not undefined and jstype(a.__lt__) is 'function':
|
|
139
|
+
if ρσ_op_lt(a, b):
|
|
140
|
+
return -1
|
|
141
|
+
if ρσ_op_lt(b, a):
|
|
142
|
+
return 1
|
|
143
|
+
return ap - bp
|
|
128
144
|
if a < b:
|
|
129
145
|
return -1
|
|
130
146
|
if a > b:
|
|
@@ -132,8 +148,17 @@ def ρσ_list_sort_cmp(a, b, ap, bp):
|
|
|
132
148
|
return ap - bp
|
|
133
149
|
|
|
134
150
|
def ρσ_list_sort(key=None, reverse=False):
|
|
135
|
-
key = key or ρσ_list_sort_key
|
|
136
151
|
mult = -1 if reverse else 1
|
|
152
|
+
if key is not None and key is not undefined and jstype(key) is 'function' and key.length is 2:
|
|
153
|
+
# A two-argument function is treated as a comparator (à la
|
|
154
|
+
# functools.cmp_to_key) rather than a key function, so a JS-style
|
|
155
|
+
# `.sort((a, b) => ...)` callback works as expected.
|
|
156
|
+
cmpposmap = dict()
|
|
157
|
+
for v'var i=0; i < this.length; i++':
|
|
158
|
+
cmpposmap.set(this[i], i) # noqa:undef
|
|
159
|
+
Array.prototype.sort.call(this, def (a, b): return (mult * key(a, b)) or (cmpposmap.get(a) - cmpposmap.get(b));)
|
|
160
|
+
return
|
|
161
|
+
key = key or ρσ_list_sort_key
|
|
137
162
|
keymap = dict()
|
|
138
163
|
posmap = dict()
|
|
139
164
|
for v'var i=0; i < this.length; i++':
|
|
@@ -489,7 +514,13 @@ Object.defineProperties(ρσ_set.prototype, {
|
|
|
489
514
|
r = iterator.next()
|
|
490
515
|
|
|
491
516
|
ρσ_set.prototype.toString = ρσ_set.prototype.__repr__ = ρσ_set.prototype.__str__ = ρσ_set.prototype.inspect = def():
|
|
492
|
-
|
|
517
|
+
ans = v'[]'
|
|
518
|
+
iterator = this.jsset.values()
|
|
519
|
+
r = iterator.next()
|
|
520
|
+
while not r.done:
|
|
521
|
+
ans.push(ρσ_repr(r.value))
|
|
522
|
+
r = iterator.next()
|
|
523
|
+
return '{' + ans.join(', ') + '}'
|
|
493
524
|
|
|
494
525
|
ρσ_set.prototype.__eq__ = def(other):
|
|
495
526
|
if v'!other || !other.jsset':
|
|
@@ -631,7 +662,13 @@ Object.defineProperties(ρσ_frozenset.prototype, {
|
|
|
631
662
|
return ans
|
|
632
663
|
|
|
633
664
|
ρσ_frozenset.prototype.toString = ρσ_frozenset.prototype.__repr__ = ρσ_frozenset.prototype.__str__ = ρσ_frozenset.prototype.inspect = def():
|
|
634
|
-
|
|
665
|
+
ans = v'[]'
|
|
666
|
+
iterator = this.jsset.values()
|
|
667
|
+
r = iterator.next()
|
|
668
|
+
while not r.done:
|
|
669
|
+
ans.push(ρσ_repr(r.value))
|
|
670
|
+
r = iterator.next()
|
|
671
|
+
return 'frozenset({' + ans.join(', ') + '})'
|
|
635
672
|
|
|
636
673
|
ρσ_frozenset.prototype.__eq__ = def(other):
|
|
637
674
|
if v'!other || !other.jsset':
|
package/src/baselib-errors.pyj
CHANGED
|
@@ -8,8 +8,9 @@ v'var _ρσ_NativeError = Error'
|
|
|
8
8
|
|
|
9
9
|
class Exception(Error):
|
|
10
10
|
|
|
11
|
-
def __init__(self
|
|
12
|
-
self.
|
|
11
|
+
def __init__(self):
|
|
12
|
+
self.args = v'Array.prototype.slice.call(arguments)'
|
|
13
|
+
self.message = self.args[0] if self.args.length > 0 else ''
|
|
13
14
|
self.stack = v'_ρσ_NativeError'().stack
|
|
14
15
|
self.name = self.constructor.name
|
|
15
16
|
|
|
@@ -57,7 +58,7 @@ def _is_exc_class(obj):
|
|
|
57
58
|
class ExceptionGroup(Exception):
|
|
58
59
|
|
|
59
60
|
def __init__(self, message, exceptions):
|
|
60
|
-
Exception.__init__(self, message)
|
|
61
|
+
Exception.__init__(self, message, exceptions)
|
|
61
62
|
self.exceptions = exceptions if exceptions else []
|
|
62
63
|
|
|
63
64
|
def subgroup(self, condition):
|
package/src/baselib-internal.pyj
CHANGED
|
@@ -385,37 +385,49 @@ def ρσ_op_pow(a, b):
|
|
|
385
385
|
def ρσ_op_and(a, b):
|
|
386
386
|
if a is not None and jstype(a.__and__) is 'function': return a.__and__(b)
|
|
387
387
|
if b is not None and jstype(b.__rand__) is 'function': return b.__rand__(a)
|
|
388
|
-
|
|
389
|
-
|
|
390
|
-
return v'a & b'
|
|
388
|
+
ta = jstype(a)
|
|
389
|
+
tb = jstype(b)
|
|
390
|
+
if (ta is 'number' or ta is 'boolean') and (tb is 'number' or tb is 'boolean'): return v'a & b'
|
|
391
|
+
if ta is 'bigint' and tb is 'bigint': return v'a & b'
|
|
392
|
+
raise TypeError("unsupported operand type(s) for &: '" + ρσ_arith_type_name(a) + "' and '" + ρσ_arith_type_name(b) + "'")
|
|
391
393
|
|
|
392
394
|
def ρσ_op_or(a, b):
|
|
393
395
|
if a is not None and jstype(a.__or__) is 'function': return a.__or__(b)
|
|
394
396
|
if b is not None and jstype(b.__ror__) is 'function': return b.__ror__(a)
|
|
395
|
-
|
|
396
|
-
|
|
397
|
-
|
|
397
|
+
ta = jstype(a)
|
|
398
|
+
tb = jstype(b)
|
|
399
|
+
if ta is 'object' and tb is 'object' and a is not None and b is not None and not Array.isArray(a) and not Array.isArray(b) and v'a.constructor === Object' and v'b.constructor === Object':
|
|
400
|
+
return Object.assign({}, a, b)
|
|
401
|
+
if (ta is 'number' or ta is 'boolean') and (tb is 'number' or tb is 'boolean'): return v'a | b'
|
|
402
|
+
if ta is 'bigint' and tb is 'bigint': return v'a | b'
|
|
403
|
+
raise TypeError("unsupported operand type(s) for |: '" + ρσ_arith_type_name(a) + "' and '" + ρσ_arith_type_name(b) + "'")
|
|
398
404
|
|
|
399
405
|
def ρσ_op_xor(a, b):
|
|
400
406
|
if a is not None and jstype(a.__xor__) is 'function': return a.__xor__(b)
|
|
401
407
|
if b is not None and jstype(b.__rxor__) is 'function': return b.__rxor__(a)
|
|
402
|
-
|
|
403
|
-
|
|
404
|
-
return v'a ^ b'
|
|
408
|
+
ta = jstype(a)
|
|
409
|
+
tb = jstype(b)
|
|
410
|
+
if (ta is 'number' or ta is 'boolean') and (tb is 'number' or tb is 'boolean'): return v'a ^ b'
|
|
411
|
+
if ta is 'bigint' and tb is 'bigint': return v'a ^ b'
|
|
412
|
+
raise TypeError("unsupported operand type(s) for ^: '" + ρσ_arith_type_name(a) + "' and '" + ρσ_arith_type_name(b) + "'")
|
|
405
413
|
|
|
406
414
|
def ρσ_op_lshift(a, b):
|
|
407
415
|
if a is not None and jstype(a.__lshift__) is 'function': return a.__lshift__(b)
|
|
408
416
|
if b is not None and jstype(b.__rlshift__) is 'function': return b.__rlshift__(a)
|
|
409
|
-
|
|
410
|
-
|
|
411
|
-
return v'a << b'
|
|
417
|
+
ta = jstype(a)
|
|
418
|
+
tb = jstype(b)
|
|
419
|
+
if (ta is 'number' or ta is 'boolean') and (tb is 'number' or tb is 'boolean'): return v'a << b'
|
|
420
|
+
if ta is 'bigint' and tb is 'bigint': return v'a << b'
|
|
421
|
+
raise TypeError("unsupported operand type(s) for <<: '" + ρσ_arith_type_name(a) + "' and '" + ρσ_arith_type_name(b) + "'")
|
|
412
422
|
|
|
413
423
|
def ρσ_op_rshift(a, b):
|
|
414
424
|
if a is not None and jstype(a.__rshift__) is 'function': return a.__rshift__(b)
|
|
415
425
|
if b is not None and jstype(b.__rrshift__) is 'function': return b.__rrshift__(a)
|
|
416
|
-
|
|
417
|
-
|
|
418
|
-
return v'a >> b'
|
|
426
|
+
ta = jstype(a)
|
|
427
|
+
tb = jstype(b)
|
|
428
|
+
if (ta is 'number' or ta is 'boolean') and (tb is 'number' or tb is 'boolean'): return v'a >> b'
|
|
429
|
+
if ta is 'bigint' and tb is 'bigint': return v'a >> b'
|
|
430
|
+
raise TypeError("unsupported operand type(s) for >>: '" + ρσ_arith_type_name(a) + "' and '" + ρσ_arith_type_name(b) + "'")
|
|
419
431
|
|
|
420
432
|
# Ordered-comparison operator overloading helpers.
|
|
421
433
|
# ρσ_op_lt dispatches __lt__ (forward) then __gt__ (reflected), handles lists
|
|
@@ -505,15 +517,22 @@ def ρσ_list_iadd(a, b):
|
|
|
505
517
|
# Unary operator overloading helpers
|
|
506
518
|
def ρσ_op_neg(a):
|
|
507
519
|
if a is not None and jstype(a.__neg__) is 'function': return a.__neg__()
|
|
508
|
-
|
|
520
|
+
ta = jstype(a)
|
|
521
|
+
if ta is 'number' or ta is 'boolean' or ta is 'bigint': return -a
|
|
522
|
+
raise TypeError("bad operand type for unary -: '" + ρσ_arith_type_name(a) + "'")
|
|
509
523
|
|
|
510
524
|
def ρσ_op_pos(a):
|
|
511
525
|
if a is not None and jstype(a.__pos__) is 'function': return a.__pos__()
|
|
512
|
-
|
|
526
|
+
ta = jstype(a)
|
|
527
|
+
if ta is 'number' or ta is 'boolean': return +a
|
|
528
|
+
if ta is 'bigint': return a
|
|
529
|
+
raise TypeError("bad operand type for unary +: '" + ρσ_arith_type_name(a) + "'")
|
|
513
530
|
|
|
514
531
|
def ρσ_op_invert(a):
|
|
515
532
|
if a is not None and jstype(a.__invert__) is 'function': return a.__invert__()
|
|
516
|
-
|
|
533
|
+
ta = jstype(a)
|
|
534
|
+
if ta is 'number' or ta is 'boolean' or ta is 'bigint': return ~a
|
|
535
|
+
raise TypeError("bad operand type for unary ~: '" + ρσ_arith_type_name(a) + "'")
|
|
517
536
|
|
|
518
537
|
# Augmented-assignment helpers: try __i<op>__ first, fall back to binary op
|
|
519
538
|
def ρσ_op_iadd(a, b):
|
|
@@ -550,6 +569,11 @@ def ρσ_op_iand(a, b):
|
|
|
550
569
|
|
|
551
570
|
def ρσ_op_ior(a, b):
|
|
552
571
|
if a is not None and jstype(a.__ior__) is 'function': return a.__ior__(b)
|
|
572
|
+
ta = jstype(a)
|
|
573
|
+
tb = jstype(b)
|
|
574
|
+
if ta is 'object' and tb is 'object' and a is not None and b is not None and not Array.isArray(a) and not Array.isArray(b) and v'a.constructor === Object' and v'b.constructor === Object':
|
|
575
|
+
Object.assign(a, b)
|
|
576
|
+
return a
|
|
553
577
|
return ρσ_op_or(a, b)
|
|
554
578
|
|
|
555
579
|
def ρσ_op_ixor(a, b):
|
|
@@ -766,6 +790,11 @@ v'var ρσ_proxy_target_symbol = typeof Symbol === "function" ? Symbol("ρσ_pro
|
|
|
766
790
|
if jstype(target.__setattr__) is 'function':
|
|
767
791
|
target.__setattr__.call(receiver, prop, value)
|
|
768
792
|
return True
|
|
793
|
+
# __slots__ enforcement: check if the class restricts instance attributes.
|
|
794
|
+
if jstype(prop) is 'string' and prop[0] is not 'ρ':
|
|
795
|
+
slots = v'target.constructor && target.constructor.prototype.__ρσ_slots__'
|
|
796
|
+
if slots and not v'slots.hasOwnProperty(prop)':
|
|
797
|
+
raise AttributeError("'" + (target.constructor.__name__ or 'object') + "' object has no attribute '" + prop + "'")
|
|
769
798
|
# Pass 'target' as receiver (not proxy) to avoid infinite recursion through the Proxy set trap.
|
|
770
799
|
return v'Reflect.set(target, prop, value, target)'
|
|
771
800
|
,
|
package/src/baselib-str.pyj
CHANGED
|
@@ -23,7 +23,7 @@ def ρσ_repr_js_builtin(x, as_array):
|
|
|
23
23
|
keys = Object.keys(x)
|
|
24
24
|
for v'var k = 0; k < keys.length; k++':
|
|
25
25
|
key = keys[k]
|
|
26
|
-
ans.push(
|
|
26
|
+
ans.push(ρσ_repr(key) + ': ' + ρσ_repr(x[key]))
|
|
27
27
|
return b[0] + ans.join(', ') + b[1]
|
|
28
28
|
|
|
29
29
|
def ρσ_html_element_to_string(elem):
|
|
@@ -49,6 +49,8 @@ def ρσ_repr(x):
|
|
|
49
49
|
ans = x.__repr__()
|
|
50
50
|
elif x is True or x is False:
|
|
51
51
|
ans = 'True' if x else 'False'
|
|
52
|
+
elif jstype(x) is 'string':
|
|
53
|
+
ans = "'" + x.replace("\\", "\\\\").replace("'", "\\'").replace("\n", "\\n").replace("\r", "\\r").replace("\t", "\\t") + "'"
|
|
52
54
|
elif Array.isArray(x):
|
|
53
55
|
ans = ρσ_repr_js_builtin(x, True)
|
|
54
56
|
elif jstype(x) is 'function':
|
|
@@ -111,8 +113,19 @@ define_str_func = def(name, func):
|
|
|
111
113
|
if func.__argnames__:
|
|
112
114
|
Object.defineProperty(f, '__argnames__', {'value':v"['string']".concat(func.__argnames__)})
|
|
113
115
|
|
|
114
|
-
|
|
115
|
-
|
|
116
|
+
# Guard against multiple evaluations of the baselib in the same JS context
|
|
117
|
+
# (e.g. web_repl()/create_compiler() being called repeatedly). Without this,
|
|
118
|
+
# each eval captures the PREVIOUS patched String.prototype.split as ρσ_orig_split,
|
|
119
|
+
# creating a chain that eventually overflows the call stack.
|
|
120
|
+
if v'typeof globalThis !== "undefined" && globalThis._ρσ_orig_split':
|
|
121
|
+
ρσ_orig_split = v'globalThis._ρσ_orig_split'
|
|
122
|
+
ρσ_orig_replace = v'globalThis._ρσ_orig_replace'
|
|
123
|
+
else:
|
|
124
|
+
ρσ_orig_split = String.prototype.split.call.bind(String.prototype.split)
|
|
125
|
+
ρσ_orig_replace = String.prototype.replace.call.bind(String.prototype.replace)
|
|
126
|
+
if v'typeof globalThis !== "undefined"':
|
|
127
|
+
v'globalThis._ρσ_orig_split = ρσ_orig_split'
|
|
128
|
+
v'globalThis._ρσ_orig_replace = ρσ_orig_replace'
|
|
116
129
|
|
|
117
130
|
# format() {{{
|
|
118
131
|
define_str_func('format', def ():
|
package/src/compiler.pyj
CHANGED
|
@@ -1,36 +1,36 @@
|
|
|
1
|
-
# vim:fileencoding=utf-8
|
|
2
|
-
# License: BSD
|
|
3
|
-
# Copyright: 2015, Kovid Goyal <kovid at kovidgoyal.net>
|
|
4
|
-
# globals: console
|
|
5
|
-
|
|
6
|
-
from utils import DefaultsError, string_template
|
|
7
|
-
from errors import ImportError, SyntaxError
|
|
8
|
-
from tokenizer import ALL_KEYWORDS, IDENTIFIER_PAT, tokenizer
|
|
9
|
-
from parse import parse, NATIVE_CLASSES, compile_time_decorators
|
|
10
|
-
from output.stream import OutputStream
|
|
11
|
-
from output.codegen import generate_code
|
|
12
|
-
from output.treeshake import tree_shake
|
|
13
|
-
|
|
14
|
-
generate_code() # create the print methods on the AST nodes
|
|
15
|
-
|
|
16
|
-
# The following allows this module to be used from a pure javascript, require()
|
|
17
|
-
# based environment like Node.js
|
|
18
|
-
if jstype(exports) is 'object':
|
|
19
|
-
exports.DefaultsError = DefaultsError
|
|
20
|
-
exports.parse = parse
|
|
21
|
-
exports.compile_time_decorators = compile_time_decorators
|
|
22
|
-
exports.OutputStream = OutputStream
|
|
23
|
-
exports.string_template = string_template # noqa:undef
|
|
24
|
-
# Needed for REPL and linter
|
|
25
|
-
exports.ALL_KEYWORDS = ALL_KEYWORDS
|
|
26
|
-
exports.IDENTIFIER_PAT = IDENTIFIER_PAT
|
|
27
|
-
exports.NATIVE_CLASSES = NATIVE_CLASSES
|
|
28
|
-
exports.ImportError = ImportError
|
|
29
|
-
exports.SyntaxError = SyntaxError
|
|
30
|
-
exports.tokenizer = tokenizer
|
|
31
|
-
exports.tree_shake = tree_shake
|
|
32
|
-
# Magic! Export all the AST_* nodes
|
|
33
|
-
ast = ρσ_modules['ast']
|
|
34
|
-
for ast_node in ast:
|
|
35
|
-
if ast_node.substr(0, 4) is 'AST_':
|
|
36
|
-
exports[ast_node] = ast[ast_node] # noqa:undef
|
|
1
|
+
# vim:fileencoding=utf-8
|
|
2
|
+
# License: BSD
|
|
3
|
+
# Copyright: 2015, Kovid Goyal <kovid at kovidgoyal.net>
|
|
4
|
+
# globals: console
|
|
5
|
+
|
|
6
|
+
from utils import DefaultsError, string_template
|
|
7
|
+
from errors import ImportError, SyntaxError
|
|
8
|
+
from tokenizer import ALL_KEYWORDS, IDENTIFIER_PAT, tokenizer
|
|
9
|
+
from parse import parse, NATIVE_CLASSES, compile_time_decorators
|
|
10
|
+
from output.stream import OutputStream
|
|
11
|
+
from output.codegen import generate_code
|
|
12
|
+
from output.treeshake import tree_shake
|
|
13
|
+
|
|
14
|
+
generate_code() # create the print methods on the AST nodes
|
|
15
|
+
|
|
16
|
+
# The following allows this module to be used from a pure javascript, require()
|
|
17
|
+
# based environment like Node.js
|
|
18
|
+
if jstype(exports) is 'object':
|
|
19
|
+
exports.DefaultsError = DefaultsError
|
|
20
|
+
exports.parse = parse
|
|
21
|
+
exports.compile_time_decorators = compile_time_decorators
|
|
22
|
+
exports.OutputStream = OutputStream
|
|
23
|
+
exports.string_template = string_template # noqa:undef
|
|
24
|
+
# Needed for REPL and linter
|
|
25
|
+
exports.ALL_KEYWORDS = ALL_KEYWORDS
|
|
26
|
+
exports.IDENTIFIER_PAT = IDENTIFIER_PAT
|
|
27
|
+
exports.NATIVE_CLASSES = NATIVE_CLASSES
|
|
28
|
+
exports.ImportError = ImportError
|
|
29
|
+
exports.SyntaxError = SyntaxError
|
|
30
|
+
exports.tokenizer = tokenizer
|
|
31
|
+
exports.tree_shake = tree_shake
|
|
32
|
+
# Magic! Export all the AST_* nodes
|
|
33
|
+
ast = ρσ_modules['ast']
|
|
34
|
+
for ast_node in ast:
|
|
35
|
+
if ast_node.substr(0, 4) is 'AST_':
|
|
36
|
+
exports[ast_node] = ast[ast_node] # noqa:undef
|
package/src/errors.pyj
CHANGED
|
@@ -1,30 +1,30 @@
|
|
|
1
|
-
# vim:fileencoding=utf-8
|
|
2
|
-
# License: BSD Copyright: 2016, Kovid Goyal <kovid at kovidgoyal.net>
|
|
3
|
-
from __python__ import hash_literals
|
|
4
|
-
|
|
5
|
-
class SyntaxError(Error):
|
|
6
|
-
|
|
7
|
-
def __init__(self, message, filename, line, col, pos, is_eof):
|
|
8
|
-
self.stack = Error().stack
|
|
9
|
-
self.message = message
|
|
10
|
-
self.line = line
|
|
11
|
-
self.col = col
|
|
12
|
-
self.pos = pos
|
|
13
|
-
self.is_eof = is_eof
|
|
14
|
-
self.filename = filename
|
|
15
|
-
# The "standard" form for these error attributes
|
|
16
|
-
self.lineNumber = line
|
|
17
|
-
self.fileName = filename
|
|
18
|
-
|
|
19
|
-
def toString(self):
|
|
20
|
-
ans = self.message + " (line: " + self.line + ", col: " + self.col + ", pos: " + self.pos + ")"
|
|
21
|
-
if self.filename:
|
|
22
|
-
ans = self.filename + ':' + ans
|
|
23
|
-
if self.stack:
|
|
24
|
-
ans += "\n\n" + self.stack
|
|
25
|
-
return ans
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
class ImportError(SyntaxError):
|
|
29
|
-
pass
|
|
30
|
-
|
|
1
|
+
# vim:fileencoding=utf-8
|
|
2
|
+
# License: BSD Copyright: 2016, Kovid Goyal <kovid at kovidgoyal.net>
|
|
3
|
+
from __python__ import hash_literals
|
|
4
|
+
|
|
5
|
+
class SyntaxError(Error):
|
|
6
|
+
|
|
7
|
+
def __init__(self, message, filename, line, col, pos, is_eof):
|
|
8
|
+
self.stack = Error().stack
|
|
9
|
+
self.message = message
|
|
10
|
+
self.line = line
|
|
11
|
+
self.col = col
|
|
12
|
+
self.pos = pos
|
|
13
|
+
self.is_eof = is_eof
|
|
14
|
+
self.filename = filename
|
|
15
|
+
# The "standard" form for these error attributes
|
|
16
|
+
self.lineNumber = line
|
|
17
|
+
self.fileName = filename
|
|
18
|
+
|
|
19
|
+
def toString(self):
|
|
20
|
+
ans = self.message + " (line: " + self.line + ", col: " + self.col + ", pos: " + self.pos + ")"
|
|
21
|
+
if self.filename:
|
|
22
|
+
ans = self.filename + ':' + ans
|
|
23
|
+
if self.stack:
|
|
24
|
+
ans += "\n\n" + self.stack
|
|
25
|
+
return ans
|
|
26
|
+
|
|
27
|
+
|
|
28
|
+
class ImportError(SyntaxError):
|
|
29
|
+
pass
|
|
30
|
+
|