rapydscript-ns 0.9.2 → 0.9.4

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.
Files changed (88) hide show
  1. package/CHANGELOG.md +28 -0
  2. package/PYTHON_GAPS.md +352 -0
  3. package/README.md +176 -32
  4. package/TODO.md +1 -128
  5. package/bin/rapydscript +70 -70
  6. package/language-service/index.js +242 -11
  7. package/memory/project_string_impl.md +43 -0
  8. package/package.json +1 -1
  9. package/release/baselib-plain-pretty.js +248 -38
  10. package/release/baselib-plain-ugly.js +8 -8
  11. package/release/compiler.js +778 -277
  12. package/release/signatures.json +30 -30
  13. package/src/ast.pyj +10 -1
  14. package/src/baselib-builtins.pyj +56 -2
  15. package/src/baselib-containers.pyj +25 -1
  16. package/src/baselib-errors.pyj +7 -3
  17. package/src/baselib-internal.pyj +51 -6
  18. package/src/baselib-str.pyj +18 -5
  19. package/src/lib/asyncio.pyj +534 -0
  20. package/src/lib/base64.pyj +399 -0
  21. package/src/lib/bisect.pyj +73 -0
  22. package/src/lib/collections.pyj +228 -4
  23. package/src/lib/csv.pyj +494 -0
  24. package/src/lib/heapq.pyj +98 -0
  25. package/src/lib/html.pyj +382 -0
  26. package/src/lib/http/__init__.pyj +98 -0
  27. package/src/lib/http/client.pyj +304 -0
  28. package/src/lib/http/cookies.pyj +236 -0
  29. package/src/lib/logging.pyj +672 -0
  30. package/src/lib/pprint.pyj +455 -0
  31. package/src/lib/pythonize.pyj +20 -20
  32. package/src/lib/statistics.pyj +0 -0
  33. package/src/lib/string.pyj +357 -0
  34. package/src/lib/textwrap.pyj +329 -0
  35. package/src/lib/urllib/__init__.pyj +14 -0
  36. package/src/lib/urllib/error.pyj +66 -0
  37. package/src/lib/urllib/parse.pyj +475 -0
  38. package/src/lib/urllib/request.pyj +86 -0
  39. package/src/monaco-language-service/analyzer.js +5 -2
  40. package/src/monaco-language-service/completions.js +26 -0
  41. package/src/monaco-language-service/diagnostics.js +203 -4
  42. package/src/monaco-language-service/scope.js +1 -0
  43. package/src/output/codegen.pyj +4 -1
  44. package/src/output/functions.pyj +152 -6
  45. package/src/output/loops.pyj +17 -2
  46. package/src/output/modules.pyj +1 -1
  47. package/src/output/operators.pyj +15 -0
  48. package/src/output/stream.pyj +0 -1
  49. package/src/parse.pyj +108 -24
  50. package/src/tokenizer.pyj +19 -3
  51. package/test/async_generators.pyj +144 -0
  52. package/test/asyncio.pyj +307 -0
  53. package/test/base64.pyj +202 -0
  54. package/test/baselib.pyj +23 -0
  55. package/test/bisect.pyj +178 -0
  56. package/test/chainmap.pyj +185 -0
  57. package/test/csv.pyj +405 -0
  58. package/test/float_special.pyj +64 -0
  59. package/test/heapq.pyj +174 -0
  60. package/test/html.pyj +212 -0
  61. package/test/http.pyj +259 -0
  62. package/test/imports.pyj +79 -72
  63. package/test/logging.pyj +356 -0
  64. package/test/long.pyj +130 -0
  65. package/test/parenthesized_with.pyj +141 -0
  66. package/test/pprint.pyj +232 -0
  67. package/test/python_compat.pyj +3 -5
  68. package/test/python_modulo.pyj +76 -0
  69. package/test/python_modulo_off.pyj +21 -0
  70. package/test/statistics.pyj +224 -0
  71. package/test/str.pyj +14 -0
  72. package/test/string.pyj +245 -0
  73. package/test/textwrap.pyj +172 -0
  74. package/test/type_display.pyj +48 -0
  75. package/test/type_enforcement.pyj +164 -0
  76. package/test/unit/index.js +94 -6
  77. package/test/unit/language-service-completions.js +121 -0
  78. package/test/unit/language-service-scope.js +32 -0
  79. package/test/unit/language-service.js +190 -5
  80. package/test/unit/run-language-service.js +17 -3
  81. package/test/unit/web-repl.js +2401 -13
  82. package/test/urllib.pyj +193 -0
  83. package/tools/compile.js +1 -1
  84. package/tools/embedded_compiler.js +7 -7
  85. package/tools/export.js +4 -2
  86. package/web-repl/main.js +1 -1
  87. package/web-repl/rapydscript.js +7 -5
  88. package/test/omit_function_metadata.pyj +0 -20
@@ -1,34 +1,34 @@
1
1
  {
2
- "ast": "88027aa403dfe55fcf8d475115897d141717d17c",
3
- "baselib-builtins": "284e14536cfdd0b497abeb6f110ae49a20f2a172",
2
+ "ast": "1f915bd707f37c2eca90633cbe291b6c030e68a3",
3
+ "baselib-builtins": "1be74e1e78642c5cbf448f8f2a94aae0f1a3d59c",
4
4
  "baselib-bytes": "057ab581c276ef03ce91fecdd4213e412198251c",
5
- "baselib-containers": "d2f534e6530dfb309b074bf7fac082c65779e778",
6
- "baselib-errors": "8efbb59deb88ede0995768f63f57103f2f0fd02d",
7
- "baselib-internal": "bb1eff32c1c50d5d25ea3074a968e765a136108c",
5
+ "baselib-containers": "6c480319b9d2ba5d2ee9376e02b67fcd45375912",
6
+ "baselib-errors": "c7e514d89ad79f2da41fe924f5ad93fc6f2cdf8e",
7
+ "baselib-internal": "19a95012b2bc1d18c47262ac908a6017e5092f49",
8
8
  "baselib-itertools": "268b7b7af79506e9a01023e8cd3b1741599bb6a5",
9
- "baselib-str": "0e8d1ee658690412140cc138adf9681425de5084",
10
- "compiler": "bb16e915c60dc4ffb5bfe98bef411736d19fa297",
11
- "errors": "257eca38b6de987e5fd80672bec9b9981847e1bd",
12
- "output\\classes": "469c47511692e04eb1bc2b079af3f65b47165865",
13
- "output\\codegen": "69151b2cd53ff8b3270a122c65e1a0f56735150e",
14
- "output\\comments": "63b39620f9d6f407aa2d4ddb557d1c60ef296b05",
15
- "output\\exceptions": "e7d9119550403e6c5730d40b9bc9c923a23d6eb7",
16
- "output\\functions": "5fe055661a45cf9de8ef024c758bb8214a87cd80",
17
- "output\\jsx": "14f32c048301965de7764c5b74b651bc279de937",
18
- "output\\literals": "287ec4222c79f1ebfa2c6efae925e794cbb931ab",
19
- "output\\loops": "4e644417e6f2dd1fe8d289eddf774be166a4d4a4",
20
- "output\\modules": "15735b9b07260d11ba231fc3439818bd1a54947e",
21
- "output\\operators": "14b23f4a3ab3b1997411b8ec9f0f57d3e76a7da0",
22
- "output\\statements": "94ee0cd084f22aea451b96eb1a9a831084cc4267",
23
- "output\\stream": "2723d80bc398468e0828f50fb0837095c52f45dc",
24
- "output\\treeshake": "4a490ba097739d924db9e3cd9eb7718db5e24cae",
25
- "output\\utils": "e957919bfccb9a3ab510d824a8f2ee3fc2689795",
26
- "output\\__init__": "da39a3ee5e6b4b0d3255bfef95601890afd80709",
27
- "parse": "0643834ed3c98d350ceb9ec71179f8923974c08c",
28
- "string_interpolation": "88dce6c2c5ee75126a6838a1506841c6531a0d15",
29
- "tokenizer": "79cf9d42ec2613b409b4dc6ed0e3ce112e4bd8c0",
30
- "unicode_aliases": "7fbcbc9c24adcb2e33fac8d69aaafe5047fcc2c2",
31
- "utils": "35a2a707c841da851e18c64edac54e7c20b7dfc9",
32
- "#compiler#": "21a89c9ec81e3f4907eba75bf4c3d8b6aade4ad6",
33
- "#compiled_with#": "21a89c9ec81e3f4907eba75bf4c3d8b6aade4ad6"
9
+ "baselib-str": "3fa63a0bf3bcf91cba4666093c3960633c6eed2e",
10
+ "compiler": "4c728d81b441b4b9c590f9330271f54b47cc11eb",
11
+ "errors": "d1b33848d19b141e19cc079cf78421f29b6d2c05",
12
+ "output/__init__": "da39a3ee5e6b4b0d3255bfef95601890afd80709",
13
+ "output/classes": "469c47511692e04eb1bc2b079af3f65b47165865",
14
+ "output/codegen": "69151b2cd53ff8b3270a122c65e1a0f56735150e",
15
+ "output/comments": "78ec38d8b34da96c078653e2d0d4049d7003906b",
16
+ "output/exceptions": "d45bc62bc6b011bae182ed7c8df8ea5e392f6fb8",
17
+ "output/functions": "263416b49c60c78abee42fef83ec460e886fb243",
18
+ "output/jsx": "0a174c39378155c19dfa669e833c14d63190127b",
19
+ "output/literals": "287ec4222c79f1ebfa2c6efae925e794cbb931ab",
20
+ "output/loops": "1c9bbd6a2772dd2fc287c0b1aebfac7f5426eb27",
21
+ "output/modules": "8383da8f58a79921d24e4e0261360a7d0708c4db",
22
+ "output/operators": "8f7b1cf4f8a91102fc04104f8a799dcd8849963e",
23
+ "output/statements": "94ee0cd084f22aea451b96eb1a9a831084cc4267",
24
+ "output/stream": "9bd250ebb7ee43374d69c24357f8c985f95397d4",
25
+ "output/treeshake": "c1d65269ff21cfd046e947755a3489d0e670a74a",
26
+ "output/utils": "595968f96f6fdcc51eb41c34d64c92bb595e3cb1",
27
+ "parse": "d4ad97b80e3cbf810c55285bd47281bedfe027f9",
28
+ "string_interpolation": "bff1cc76d772d24d35707f6c794f38734ca08376",
29
+ "tokenizer": "7b8fb7855dc09aeeb16f6a513ae664951dd070e1",
30
+ "unicode_aliases": "79ac6eaa5e6be44a5397d62c561f854a8fe7528e",
31
+ "utils": "c1666db819aa7c8db38697e34e18362e3cb45869",
32
+ "#compiler#": "ce0d8d902910ca87ffa150b4d56775144ed6ec25",
33
+ "#compiled_with#": "ce0d8d902910ca87ffa150b4d56775144ed6ec25"
34
34
  }
package/src/ast.pyj CHANGED
@@ -247,7 +247,8 @@ class AST_ForIn(AST_StatementWithBody):
247
247
  'init': "[AST_Node] the `for/in` initialization code",
248
248
  'name': "[AST_SymbolRef?] the loop variable, only if `init` is AST_Var",
249
249
  'object': "[AST_Node] the object that we're looping through",
250
- 'belse': "[AST_Else?] the `else` clause, run when no break occurred"
250
+ 'belse': "[AST_Else?] the `else` clause, run when no break occurred",
251
+ 'is_async': "[bool*] True iff this is an `async for` (uses `for await ... of`)"
251
252
  }
252
253
 
253
254
  def _walk(self, visitor):
@@ -562,6 +563,7 @@ class AST_Lambda(AST_Scope):
562
563
  'is_expression': "[bool*] True iff this function is a function expression",
563
564
  'is_anonymous': "[bool*] True iff this function is an anonymous function",
564
565
  "return_annotation": "[AST_Node?] The return type annotation provided (if any)",
566
+ 'type_enforce': "[bool*] True iff type_enforcement scoped flag is active for this function",
565
567
  }
566
568
 
567
569
  def _walk(self, visitor):
@@ -989,6 +991,7 @@ class AST_Binary(AST_Node):
989
991
  'right': "[AST_Node] right-hand side expression",
990
992
  'overloaded': "[bool] Whether to use Python-style operator overloading dispatch",
991
993
  'strict_arith': "[bool] Whether incompatible operand types raise TypeError (default True when overloaded; disable with no_strict_arithmetic)",
994
+ 'python_mod': "[bool] Whether `%` uses Python-style modulo (sign of divisor); disable with no_python_modulo",
992
995
  'python_truthiness': "[bool] Whether to use Python truthiness (from __python__ import truthiness)"
993
996
  }
994
997
 
@@ -1277,6 +1280,12 @@ class AST_Number(AST_Constant):
1277
1280
  'value': "[number] the numeric value"
1278
1281
  }
1279
1282
 
1283
+ class AST_BigInt(AST_Constant):
1284
+ "A BigInt literal (e.g. 42n)"
1285
+ properties = {
1286
+ 'value': "[string] the raw numeric string (without n suffix)"
1287
+ }
1288
+
1280
1289
  class AST_RegExp(AST_Constant):
1281
1290
  "A regexp literal"
1282
1291
  properties = {
@@ -44,10 +44,51 @@ def ρσ_float(val):
44
44
  else:
45
45
  ans = parseFloat(val)
46
46
  if isNaN(ans):
47
+ if jstype(val) is 'string':
48
+ s = val.trim().toLowerCase()
49
+ if s is 'inf' or s is '+inf' or s is 'infinity' or s is '+infinity':
50
+ return v'Infinity'
51
+ if s is '-inf' or s is '-infinity':
52
+ return v'-Infinity'
53
+ if s is 'nan' or s is '+nan' or s is '-nan':
54
+ return v'NaN'
47
55
  raise ValueError('Could not convert string to float: ' + arguments[0])
48
56
  return ans
49
57
  ρσ_float.__name__ = 'float'
50
58
 
59
+ def ρσ_long(val, base):
60
+ t = jstype(val)
61
+ if t is 'bigint':
62
+ return val
63
+ if t is 'boolean':
64
+ return v'BigInt(val ? 1 : 0)'
65
+ if t is 'number':
66
+ if not Number.isInteger(val):
67
+ raise TypeError("long() can't convert non-integer float to long")
68
+ v'try { return BigInt(val); } catch(e) { throw new ValueError("long() argument out of range: " + val); }'
69
+ if t is 'string':
70
+ b = base if (base is not None and base is not undefined) else 10
71
+ v'var ρσ_ls = val.trim()'
72
+ try:
73
+ if b is 16:
74
+ if v'ρσ_ls.slice(0, 2).toLowerCase()' is not '0x':
75
+ v'ρσ_ls = "0x" + ρσ_ls'
76
+ return v'BigInt(ρσ_ls)'
77
+ elif b is 2:
78
+ if v'ρσ_ls.slice(0, 2).toLowerCase()' is not '0b':
79
+ v'ρσ_ls = "0b" + ρσ_ls'
80
+ return v'BigInt(ρσ_ls)'
81
+ elif b is 8:
82
+ if v'ρσ_ls.slice(0, 2).toLowerCase()' is not '0o':
83
+ v'ρσ_ls = "0o" + ρσ_ls'
84
+ return v'BigInt(ρσ_ls)'
85
+ else:
86
+ return v'BigInt(ρσ_ls)'
87
+ except:
88
+ raise ValueError('Invalid literal for long() with base ' + b + ': ' + val)
89
+ raise TypeError("long() argument must be a string, a number, or a boolean, not '" + t + "'")
90
+ ρσ_long.__name__ = 'long'
91
+
51
92
  def ρσ_arraylike_creator():
52
93
  names = 'Int8Array Uint8Array Uint8ClampedArray Int16Array Uint16Array Int32Array Uint32Array Float32Array Float64Array'.split(' ')
53
94
  if jstype(HTMLCollection) is 'function':
@@ -308,8 +349,21 @@ def ρσ_pow(x, y, z):
308
349
  ans %= z
309
350
  return ans
310
351
 
352
+ ρσ_NoneType = v'{"__name__": "NoneType"}'
353
+ ρσ_NoneType.toString = def(): return "<class 'NoneType'>";
354
+ ρσ_js_builtin_names = v'{"Number": "float", "String": "str", "Boolean": "bool", "Array": "list", "Object": "object", "Function": "function", "RegExp": "RegExp", "Date": "datetime", "Map": "dict", "Set": "set", "Uint8Array": "bytes"}'
355
+
311
356
  def ρσ_type(x):
312
- return x.constructor
357
+ if x is None or x is undefined:
358
+ return ρσ_NoneType
359
+ c = x.constructor
360
+ if not c:
361
+ return ρσ_NoneType
362
+ if not v'Object.prototype.hasOwnProperty.call(c, "__ρσ_ts")':
363
+ n = c.__name__ or ρσ_js_builtin_names[c.name] or c.name or 'object'
364
+ c.toString = def(): return "<class '" + n + "'>";
365
+ c.__ρσ_ts = True
366
+ return c
313
367
 
314
368
 
315
369
  def ρσ_issubclass(cls, base):
@@ -793,7 +847,7 @@ class ρσ_complex:
793
847
  ρσ_complex.__name__ = 'complex'
794
848
 
795
849
  v'var abs = ρσ_abs, max = ρσ_max.bind(Math.max), min = ρσ_max.bind(Math.min), bool = ρσ_bool, type = ρσ_type'
796
- v'var float = ρσ_float, int = ρσ_int, complex = ρσ_complex, arraylike = ρσ_arraylike_creator(), ρσ_arraylike = arraylike'
850
+ v'var float = ρσ_float, int = ρσ_int, long = ρσ_long, complex = ρσ_complex, arraylike = ρσ_arraylike_creator(), ρσ_arraylike = arraylike'
797
851
  v'var id = ρσ_id, get_module = ρσ_get_module, pow = ρσ_pow, divmod = ρσ_divmod, __import__ = ρσ__import__'
798
852
  v'var dir = ρσ_dir, ord = ρσ_ord, chr = ρσ_chr, bin = ρσ_bin, hex = ρσ_hex, callable = ρσ_callable, round = ρσ_round'
799
853
  v'var enumerate = ρσ_enumerate, iter = ρσ_iter, reversed = ρσ_reversed, len = ρσ_len'
@@ -122,9 +122,22 @@ def ρσ_list_sort_key(value):
122
122
  t = jstype(value)
123
123
  if t is 'string' or t is 'number':
124
124
  return value
125
+ # Keep objects that define __lt__ unchanged so ρσ_list_sort_cmp can
126
+ # dispatch the dunder; everything else falls back to a string key.
127
+ if value is not None and value is not undefined and jstype(value.__lt__) is 'function':
128
+ return value
125
129
  return value.toString()
126
130
 
127
131
  def ρσ_list_sort_cmp(a, b, ap, bp):
132
+ # When the elements define __lt__, order them the Pythonic way via
133
+ # ρσ_op_lt (which also handles a reflected __gt__); otherwise compare
134
+ # the precomputed primitive keys directly.
135
+ if a is not None and a is not undefined and jstype(a.__lt__) is 'function':
136
+ if ρσ_op_lt(a, b):
137
+ return -1
138
+ if ρσ_op_lt(b, a):
139
+ return 1
140
+ return ap - bp
128
141
  if a < b:
129
142
  return -1
130
143
  if a > b:
@@ -132,8 +145,17 @@ def ρσ_list_sort_cmp(a, b, ap, bp):
132
145
  return ap - bp
133
146
 
134
147
  def ρσ_list_sort(key=None, reverse=False):
135
- key = key or ρσ_list_sort_key
136
148
  mult = -1 if reverse else 1
149
+ if key is not None and key is not undefined and jstype(key) is 'function' and key.length is 2:
150
+ # A two-argument function is treated as a comparator (à la
151
+ # functools.cmp_to_key) rather than a key function, so a JS-style
152
+ # `.sort((a, b) => ...)` callback works as expected.
153
+ cmpposmap = dict()
154
+ for v'var i=0; i < this.length; i++':
155
+ cmpposmap.set(this[i], i) # noqa:undef
156
+ Array.prototype.sort.call(this, def (a, b): return (mult * key(a, b)) or (cmpposmap.get(a) - cmpposmap.get(b));)
157
+ return
158
+ key = key or ρσ_list_sort_key
137
159
  keymap = dict()
138
160
  posmap = dict()
139
161
  for v'var i=0; i < this.length; i++':
@@ -511,6 +533,7 @@ def ρσ_set_wrap(x):
511
533
  ans.jsset = x
512
534
  return ans
513
535
 
536
+ ρσ_set.__name__ = 'set'
514
537
  v'var set = ρσ_set, set_wrap = ρσ_set_wrap'
515
538
  # }}}
516
539
 
@@ -902,6 +925,7 @@ def ρσ_dict_wrap(x):
902
925
  ans.jsmap = x
903
926
  return ans
904
927
 
928
+ ρσ_dict.__name__ = 'dict'
905
929
  v'var dict = ρσ_dict, dict_wrap = ρσ_dict_wrap'
906
930
 
907
931
  v'''
@@ -4,12 +4,13 @@
4
4
  # globals: ρσ_str
5
5
 
6
6
  v'var NameError = ReferenceError'
7
+ v'var _ρσ_NativeError = Error'
7
8
 
8
9
  class Exception(Error):
9
10
 
10
11
  def __init__(self, message):
11
12
  self.message = message
12
- self.stack = Error().stack
13
+ self.stack = v'_ρσ_NativeError'().stack
13
14
  self.name = self.constructor.name
14
15
 
15
16
  def __repr__(self):
@@ -18,10 +19,13 @@ class Exception(Error):
18
19
  class AttributeError(Exception):
19
20
  pass
20
21
 
21
- class IndexError(Exception):
22
+ class LookupError(Exception):
22
23
  pass
23
24
 
24
- class KeyError(Exception):
25
+ class IndexError(LookupError):
26
+ pass
27
+
28
+ class KeyError(LookupError):
25
29
  pass
26
30
 
27
31
  class ValueError(Exception):
@@ -282,6 +282,8 @@ def ρσ_arith_type_name(v):
282
282
  t = jstype(v)
283
283
  if t is 'boolean':
284
284
  return 'bool'
285
+ if t is 'bigint':
286
+ return 'long'
285
287
  if t is 'number':
286
288
  return 'int' if Number.isInteger(v) else 'float'
287
289
  if t is 'string' or v'v instanceof String':
@@ -303,6 +305,7 @@ def ρσ_op_add(a, b):
303
305
  ta = jstype(a)
304
306
  tb = jstype(b)
305
307
  if (ta is 'number' or ta is 'boolean') and (tb is 'number' or tb is 'boolean'): return v'a + b'
308
+ if ta is 'bigint' and tb is 'bigint': return v'a + b'
306
309
  if (ta is 'string' or v'a instanceof String') and (tb is 'string' or v'b instanceof String'): return v'a + b'
307
310
  raise TypeError("unsupported operand type(s) for +: '" + ρσ_arith_type_name(a) + "' and '" + ρσ_arith_type_name(b) + "'")
308
311
 
@@ -312,6 +315,7 @@ def ρσ_op_sub(a, b):
312
315
  ta = jstype(a)
313
316
  tb = jstype(b)
314
317
  if (ta is 'number' or ta is 'boolean') and (tb is 'number' or tb is 'boolean'): return a - b
318
+ if ta is 'bigint' and tb is 'bigint': return v'a - b'
315
319
  raise TypeError("unsupported operand type(s) for -: '" + ρσ_arith_type_name(a) + "' and '" + ρσ_arith_type_name(b) + "'")
316
320
 
317
321
  def ρσ_op_mul(a, b):
@@ -332,6 +336,7 @@ def ρσ_op_mul(a, b):
332
336
  result = result.concat(b) # noqa:undef
333
337
  return ρσ_list_constructor(result)
334
338
  if (ta is 'number' or ta is 'boolean') and (tb is 'number' or tb is 'boolean'): return a * b
339
+ if ta is 'bigint' and tb is 'bigint': return v'a * b'
335
340
  raise TypeError("unsupported operand type(s) for *: '" + ρσ_arith_type_name(a) + "' and '" + ρσ_arith_type_name(b) + "'")
336
341
 
337
342
  def ρσ_op_truediv(a, b):
@@ -340,6 +345,8 @@ def ρσ_op_truediv(a, b):
340
345
  ta = jstype(a)
341
346
  tb = jstype(b)
342
347
  if (ta is 'number' or ta is 'boolean') and (tb is 'number' or tb is 'boolean'): return a / b
348
+ if ta is 'bigint' and tb is 'bigint':
349
+ raise TypeError("unsupported operand type(s) for /: 'long' and 'long' — use // for integer division of long values")
343
350
  raise TypeError("unsupported operand type(s) for /: '" + ρσ_arith_type_name(a) + "' and '" + ρσ_arith_type_name(b) + "'")
344
351
 
345
352
  def ρσ_op_floordiv(a, b):
@@ -348,6 +355,8 @@ def ρσ_op_floordiv(a, b):
348
355
  ta = jstype(a)
349
356
  tb = jstype(b)
350
357
  if (ta is 'number' or ta is 'boolean') and (tb is 'number' or tb is 'boolean'): return Math.floor(a / b)
358
+ if ta is 'bigint' and tb is 'bigint':
359
+ v'var ρσ_bq = a / b, ρσ_br = a % b; if (ρσ_br !== 0n && (ρσ_br < 0n) !== (b < 0n)) { return ρσ_bq - 1n; } return ρσ_bq;'
351
360
  raise TypeError("unsupported operand type(s) for //: '" + ρσ_arith_type_name(a) + "' and '" + ρσ_arith_type_name(b) + "'")
352
361
 
353
362
  def ρσ_op_mod(a, b):
@@ -355,7 +364,10 @@ def ρσ_op_mod(a, b):
355
364
  if b is not None and jstype(b.__rmod__) is 'function': return b.__rmod__(a)
356
365
  ta = jstype(a)
357
366
  tb = jstype(b)
358
- if (ta is 'number' or ta is 'boolean') and (tb is 'number' or tb is 'boolean'): return a % b
367
+ if (ta is 'number' or ta is 'boolean') and (tb is 'number' or tb is 'boolean'):
368
+ v'var ρσ_mr = a % b; if (ρσ_mr !== 0 && (ρσ_mr < 0) !== (b < 0)) { return ρσ_mr + Number(b); } return ρσ_mr;'
369
+ if ta is 'bigint' and tb is 'bigint':
370
+ v'var ρσ_mr = a % b; if (ρσ_mr !== 0n && (ρσ_mr < 0n) !== (b < 0n)) { return ρσ_mr + b; } return ρσ_mr;'
359
371
  raise TypeError("unsupported operand type(s) for %: '" + ρσ_arith_type_name(a) + "' and '" + ρσ_arith_type_name(b) + "'")
360
372
 
361
373
  def ρσ_op_pow(a, b):
@@ -364,32 +376,46 @@ def ρσ_op_pow(a, b):
364
376
  ta = jstype(a)
365
377
  tb = jstype(b)
366
378
  if (ta is 'number' or ta is 'boolean') and (tb is 'number' or tb is 'boolean'): return Math.pow(a, b)
379
+ if ta is 'bigint' and tb is 'bigint':
380
+ if v'b < 0n':
381
+ raise ValueError("negative exponent not supported for long values")
382
+ return v'a ** b'
367
383
  raise TypeError("unsupported operand type(s) for **: '" + ρσ_arith_type_name(a) + "' and '" + ρσ_arith_type_name(b) + "'")
368
384
 
369
385
  def ρσ_op_and(a, b):
370
386
  if a is not None and jstype(a.__and__) is 'function': return a.__and__(b)
371
387
  if b is not None and jstype(b.__rand__) is 'function': return b.__rand__(a)
372
- return a & b
388
+ if (jstype(a) is 'bigint') is not (jstype(b) is 'bigint'):
389
+ raise TypeError("unsupported operand type(s) for &: '" + ρσ_arith_type_name(a) + "' and '" + ρσ_arith_type_name(b) + "'")
390
+ return v'a & b'
373
391
 
374
392
  def ρσ_op_or(a, b):
375
393
  if a is not None and jstype(a.__or__) is 'function': return a.__or__(b)
376
394
  if b is not None and jstype(b.__ror__) is 'function': return b.__ror__(a)
377
- return a | b
395
+ if (jstype(a) is 'bigint') is not (jstype(b) is 'bigint'):
396
+ raise TypeError("unsupported operand type(s) for |: '" + ρσ_arith_type_name(a) + "' and '" + ρσ_arith_type_name(b) + "'")
397
+ return v'a | b'
378
398
 
379
399
  def ρσ_op_xor(a, b):
380
400
  if a is not None and jstype(a.__xor__) is 'function': return a.__xor__(b)
381
401
  if b is not None and jstype(b.__rxor__) is 'function': return b.__rxor__(a)
382
- return a ^ b
402
+ if (jstype(a) is 'bigint') is not (jstype(b) is 'bigint'):
403
+ raise TypeError("unsupported operand type(s) for ^: '" + ρσ_arith_type_name(a) + "' and '" + ρσ_arith_type_name(b) + "'")
404
+ return v'a ^ b'
383
405
 
384
406
  def ρσ_op_lshift(a, b):
385
407
  if a is not None and jstype(a.__lshift__) is 'function': return a.__lshift__(b)
386
408
  if b is not None and jstype(b.__rlshift__) is 'function': return b.__rlshift__(a)
387
- return a << b
409
+ if (jstype(a) is 'bigint') is not (jstype(b) is 'bigint'):
410
+ raise TypeError("unsupported operand type(s) for <<: '" + ρσ_arith_type_name(a) + "' and '" + ρσ_arith_type_name(b) + "'")
411
+ return v'a << b'
388
412
 
389
413
  def ρσ_op_rshift(a, b):
390
414
  if a is not None and jstype(a.__rshift__) is 'function': return a.__rshift__(b)
391
415
  if b is not None and jstype(b.__rrshift__) is 'function': return b.__rrshift__(a)
392
- return a >> b
416
+ if (jstype(a) is 'bigint') is not (jstype(b) is 'bigint'):
417
+ raise TypeError("unsupported operand type(s) for >>: '" + ρσ_arith_type_name(a) + "' and '" + ρσ_arith_type_name(b) + "'")
418
+ return v'a >> b'
393
419
 
394
420
  # Ordered-comparison operator overloading helpers.
395
421
  # ρσ_op_lt dispatches __lt__ (forward) then __gt__ (reflected), handles lists
@@ -409,6 +435,7 @@ def ρσ_op_lt(a, b):
409
435
  ta = jstype(a)
410
436
  tb = jstype(b)
411
437
  if (ta is 'number' or ta is 'boolean') and (tb is 'number' or tb is 'boolean'): return v'a < b'
438
+ if ta is 'bigint' and tb is 'bigint': return v'a < b'
412
439
  if (ta is 'string' or v'a instanceof String') and (tb is 'string' or v'b instanceof String'): return v'a < b'
413
440
  raise TypeError("'<' not supported between instances of '" + ρσ_arith_type_name(a) + "' and '" + ρσ_arith_type_name(b) + "'")
414
441
 
@@ -426,6 +453,7 @@ def ρσ_op_le(a, b):
426
453
  ta = jstype(a)
427
454
  tb = jstype(b)
428
455
  if (ta is 'number' or ta is 'boolean') and (tb is 'number' or tb is 'boolean'): return v'a <= b'
456
+ if ta is 'bigint' and tb is 'bigint': return v'a <= b'
429
457
  if (ta is 'string' or v'a instanceof String') and (tb is 'string' or v'b instanceof String'): return v'a <= b'
430
458
  raise TypeError("'<=' not supported between instances of '" + ρσ_arith_type_name(a) + "' and '" + ρσ_arith_type_name(b) + "'")
431
459
 
@@ -436,6 +464,7 @@ def ρσ_op_gt(a, b):
436
464
  ta = jstype(a)
437
465
  tb = jstype(b)
438
466
  if (ta is 'number' or ta is 'boolean') and (tb is 'number' or tb is 'boolean'): return v'a > b'
467
+ if ta is 'bigint' and tb is 'bigint': return v'a > b'
439
468
  if (ta is 'string' or v'a instanceof String') and (tb is 'string' or v'b instanceof String'): return v'a > b'
440
469
  raise TypeError("'>' not supported between instances of '" + ρσ_arith_type_name(a) + "' and '" + ρσ_arith_type_name(b) + "'")
441
470
 
@@ -446,6 +475,7 @@ def ρσ_op_ge(a, b):
446
475
  ta = jstype(a)
447
476
  tb = jstype(b)
448
477
  if (ta is 'number' or ta is 'boolean') and (tb is 'number' or tb is 'boolean'): return v'a >= b'
478
+ if ta is 'bigint' and tb is 'bigint': return v'a >= b'
449
479
  if (ta is 'string' or v'a instanceof String') and (tb is 'string' or v'b instanceof String'): return v'a >= b'
450
480
  raise TypeError("'>=' not supported between instances of '" + ρσ_arith_type_name(a) + "' and '" + ρσ_arith_type_name(b) + "'")
451
481
 
@@ -575,16 +605,25 @@ def ρσ_op_truediv_ns(a, b):
575
605
  def ρσ_op_floordiv_ns(a, b):
576
606
  if a is not None and jstype(a.__floordiv__) is 'function': return a.__floordiv__(b)
577
607
  if b is not None and jstype(b.__rfloordiv__) is 'function': return b.__rfloordiv__(a)
608
+ if jstype(a) is 'bigint' and jstype(b) is 'bigint':
609
+ v'var ρσ_bq = a / b, ρσ_br = a % b; if (ρσ_br !== 0n && (ρσ_br < 0n) !== (b < 0n)) { return ρσ_bq - 1n; } return ρσ_bq;'
578
610
  return Math.floor(v'a / b')
579
611
 
580
612
  def ρσ_op_mod_ns(a, b):
581
613
  if a is not None and jstype(a.__mod__) is 'function': return a.__mod__(b)
582
614
  if b is not None and jstype(b.__rmod__) is 'function': return b.__rmod__(a)
615
+ ta = jstype(a)
616
+ tb = jstype(b)
617
+ if (ta is 'number' or ta is 'boolean') and (tb is 'number' or tb is 'boolean'):
618
+ v'var ρσ_mr = a % b; if (ρσ_mr !== 0 && (ρσ_mr < 0) !== (b < 0)) { return ρσ_mr + Number(b); } return ρσ_mr;'
619
+ if ta is 'bigint' and tb is 'bigint':
620
+ v'var ρσ_mr = a % b; if (ρσ_mr !== 0n && (ρσ_mr < 0n) !== (b < 0n)) { return ρσ_mr + b; } return ρσ_mr;'
583
621
  return v'a % b'
584
622
 
585
623
  def ρσ_op_pow_ns(a, b):
586
624
  if a is not None and jstype(a.__pow__) is 'function': return a.__pow__(b)
587
625
  if b is not None and jstype(b.__rpow__) is 'function': return b.__rpow__(a)
626
+ if jstype(a) is 'bigint' and jstype(b) is 'bigint': return v'a ** b'
588
627
  return Math.pow(a, b)
589
628
 
590
629
  def ρσ_op_lt_ns(a, b):
@@ -665,12 +704,18 @@ def ρσ_instanceof():
665
704
  return True
666
705
  if (q is Array or q is ρσ_list_constructor) and Array.isArray(obj):
667
706
  return True
707
+ if q is ρσ_tuple_constructor and Array.isArray(obj):
708
+ return True
668
709
  if q is ρσ_str and (jstype(obj) is 'string' or v'obj instanceof String'):
669
710
  return True
711
+ if q is ρσ_bool and (jstype(obj) is 'boolean' or v'obj instanceof Boolean'):
712
+ return True
670
713
  if q is ρσ_int and (jstype(obj) is 'number' and Number.isInteger(obj)):
671
714
  return True
672
715
  if q is ρσ_float and (jstype(obj) is 'number' and not Number.isInteger(obj)):
673
716
  return True
717
+ if q is ρσ_long and jstype(obj) is 'bigint':
718
+ return True
674
719
  if bases.length > 1:
675
720
  for v'var c = 1; c < bases.length; c++':
676
721
  cls = bases[c]
@@ -78,6 +78,8 @@ def ρσ_str(x):
78
78
  return 'None'
79
79
  if x is undefined:
80
80
  return 'undefined'
81
+ if v'typeof x === "bigint"':
82
+ return v'String(x)'
81
83
  ans = x
82
84
  if v'typeof x.__str__ === "function"':
83
85
  ans = x.__str__()
@@ -109,8 +111,19 @@ define_str_func = def(name, func):
109
111
  if func.__argnames__:
110
112
  Object.defineProperty(f, '__argnames__', {'value':v"['string']".concat(func.__argnames__)})
111
113
 
112
- ρσ_orig_split = String.prototype.split.call.bind(String.prototype.split)
113
- ρσ_orig_replace = String.prototype.replace.call.bind(String.prototype.replace)
114
+ # Guard against multiple evaluations of the baselib in the same JS context
115
+ # (e.g. web_repl()/create_compiler() being called repeatedly). Without this,
116
+ # each eval captures the PREVIOUS patched String.prototype.split as ρσ_orig_split,
117
+ # creating a chain that eventually overflows the call stack.
118
+ if v'typeof globalThis !== "undefined" && globalThis._ρσ_orig_split':
119
+ ρσ_orig_split = v'globalThis._ρσ_orig_split'
120
+ ρσ_orig_replace = v'globalThis._ρσ_orig_replace'
121
+ else:
122
+ ρσ_orig_split = String.prototype.split.call.bind(String.prototype.split)
123
+ ρσ_orig_replace = String.prototype.replace.call.bind(String.prototype.replace)
124
+ if v'typeof globalThis !== "undefined"':
125
+ v'globalThis._ρσ_orig_split = ρσ_orig_split'
126
+ v'globalThis._ρσ_orig_replace = ρσ_orig_replace'
114
127
 
115
128
  # format() {{{
116
129
  define_str_func('format', def ():
@@ -661,11 +674,11 @@ define_str_func('rpartition', def(sep):
661
674
 
662
675
  define_str_func('replace', def(old, repl, count):
663
676
  string = this
664
- if count is 1:
677
+ if v'old instanceof RegExp':
665
678
  return ρσ_orig_replace(string, old, repl)
666
- if count < 1:
679
+ if count is 0:
667
680
  return string
668
- count = count or Number.MAX_VALUE
681
+ count = count if count > 0 else Number.MAX_VALUE
669
682
  pos = 0
670
683
  while count > 0:
671
684
  count -= 1