rapydscript-ns 0.8.3 → 0.9.0

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 (72) hide show
  1. package/CHANGELOG.md +26 -0
  2. package/README.md +1351 -141
  3. package/TODO.md +12 -6
  4. package/language-service/index.js +184 -26
  5. package/package.json +1 -1
  6. package/release/baselib-plain-pretty.js +5895 -1928
  7. package/release/baselib-plain-ugly.js +140 -3
  8. package/release/compiler.js +16282 -5408
  9. package/release/signatures.json +25 -22
  10. package/src/ast.pyj +94 -1
  11. package/src/baselib-builtins.pyj +362 -3
  12. package/src/baselib-bytes.pyj +664 -0
  13. package/src/baselib-containers.pyj +99 -0
  14. package/src/baselib-errors.pyj +45 -1
  15. package/src/baselib-internal.pyj +346 -49
  16. package/src/baselib-itertools.pyj +17 -4
  17. package/src/baselib-str.pyj +46 -4
  18. package/src/lib/abc.pyj +317 -0
  19. package/src/lib/copy.pyj +120 -0
  20. package/src/lib/dataclasses.pyj +532 -0
  21. package/src/lib/enum.pyj +125 -0
  22. package/src/lib/pythonize.pyj +1 -1
  23. package/src/lib/re.pyj +35 -1
  24. package/src/lib/react.pyj +74 -0
  25. package/src/lib/typing.pyj +577 -0
  26. package/src/monaco-language-service/builtins.js +19 -4
  27. package/src/monaco-language-service/diagnostics.js +40 -19
  28. package/src/output/classes.pyj +161 -25
  29. package/src/output/codegen.pyj +16 -2
  30. package/src/output/exceptions.pyj +97 -1
  31. package/src/output/functions.pyj +87 -5
  32. package/src/output/jsx.pyj +164 -0
  33. package/src/output/literals.pyj +28 -2
  34. package/src/output/loops.pyj +5 -2
  35. package/src/output/modules.pyj +1 -1
  36. package/src/output/operators.pyj +108 -36
  37. package/src/output/statements.pyj +2 -2
  38. package/src/output/stream.pyj +1 -0
  39. package/src/parse.pyj +496 -128
  40. package/src/tokenizer.pyj +38 -4
  41. package/test/abc.pyj +291 -0
  42. package/test/arithmetic_nostrict.pyj +88 -0
  43. package/test/arithmetic_types.pyj +169 -0
  44. package/test/baselib.pyj +91 -0
  45. package/test/bytes.pyj +467 -0
  46. package/test/classes.pyj +1 -0
  47. package/test/comparison_ops.pyj +173 -0
  48. package/test/dataclasses.pyj +253 -0
  49. package/test/enum.pyj +134 -0
  50. package/test/eval_exec.pyj +56 -0
  51. package/test/format.pyj +148 -0
  52. package/test/object.pyj +64 -0
  53. package/test/python_compat.pyj +17 -15
  54. package/test/python_features.pyj +89 -21
  55. package/test/regexp.pyj +29 -1
  56. package/test/tuples.pyj +96 -0
  57. package/test/typing.pyj +469 -0
  58. package/test/unit/index.js +2292 -70
  59. package/test/unit/language-service.js +674 -4
  60. package/test/unit/web-repl.js +1106 -0
  61. package/test/vars_locals_globals.pyj +94 -0
  62. package/tools/cli.js +11 -0
  63. package/tools/compile.js +5 -0
  64. package/tools/embedded_compiler.js +15 -4
  65. package/tools/lint.js +16 -19
  66. package/tools/repl.js +1 -1
  67. package/web-repl/env.js +122 -0
  68. package/web-repl/main.js +1 -3
  69. package/web-repl/rapydscript.js +125 -3
  70. package/PYTHON_DIFFERENCES_REPORT.md +0 -291
  71. package/PYTHON_FEATURE_COVERAGE.md +0 -200
  72. package/hack_demo.pyj +0 -112
@@ -1,31 +1,34 @@
1
1
  {
2
- "ast": "7a1a1800d9ee7af7f7153eee38002e4e9dcfb71e",
3
- "baselib-builtins": "50927b38fded9bd9dbe14c42a20dd8e930ac021f",
4
- "baselib-containers": "f7ac21a4dfc6311693239ea1eb45e74fae45a3f5",
5
- "baselib-errors": "f2423e1e2489bdd7fb8c8725bb76436898c8008c",
6
- "baselib-internal": "1b77d40970a8ef2d886132dc7c21c9510d2eb4cd",
7
- "baselib-itertools": "ab1f3257642c8d26fab1ff9d392814a459a60cdb",
8
- "baselib-str": "8c396e4fae02ae34b6d3d805becf7bfdd36625ee",
9
- "compiler": "cfbfceb0439fed3302f78d80b303dca713b25e7b",
2
+ "ast": "88027aa403dfe55fcf8d475115897d141717d17c",
3
+ "baselib-builtins": "284e14536cfdd0b497abeb6f110ae49a20f2a172",
4
+ "baselib-bytes": "057ab581c276ef03ce91fecdd4213e412198251c",
5
+ "baselib-containers": "d2f534e6530dfb309b074bf7fac082c65779e778",
6
+ "baselib-errors": "8efbb59deb88ede0995768f63f57103f2f0fd02d",
7
+ "baselib-internal": "bb1eff32c1c50d5d25ea3074a968e765a136108c",
8
+ "baselib-itertools": "268b7b7af79506e9a01023e8cd3b1741599bb6a5",
9
+ "baselib-str": "0e8d1ee658690412140cc138adf9681425de5084",
10
+ "compiler": "4c728d81b441b4b9c590f9330271f54b47cc11eb",
10
11
  "errors": "d1b33848d19b141e19cc079cf78421f29b6d2c05",
11
12
  "output/__init__": "da39a3ee5e6b4b0d3255bfef95601890afd80709",
12
- "output/classes": "d05c1992cc91b337a4e4ff137b0aa3d626e6624b",
13
- "output/codegen": "0519a88c2704fe60b98fe747ca39f6be43b9abf3",
13
+ "output/classes": "469c47511692e04eb1bc2b079af3f65b47165865",
14
+ "output/codegen": "69151b2cd53ff8b3270a122c65e1a0f56735150e",
14
15
  "output/comments": "78ec38d8b34da96c078653e2d0d4049d7003906b",
15
- "output/exceptions": "c7d90155694c7108e94d0940a160ae83725421d7",
16
- "output/functions": "abaa81b171359eb77be6ea87cbdf9d7421d4622b",
17
- "output/literals": "fdbfb744fec8dfea1e1c62cb49767c60160fd402",
18
- "output/loops": "f59cc623320f57edb01953f7877d712758e9f825",
19
- "output/modules": "bd3e3f3f6794fb6e401867b4d011c4e3aab98893",
20
- "output/operators": "f8142836a13b75680cb4874391db9e871fad0cad",
21
- "output/statements": "7d8dfdc0b43e3e430be7ce3b23ffaf1b41408d8c",
22
- "output/stream": "46375cb467477ac898546e818bfdfa5be738c352",
16
+ "output/exceptions": "d45bc62bc6b011bae182ed7c8df8ea5e392f6fb8",
17
+ "output/functions": "5fe055661a45cf9de8ef024c758bb8214a87cd80",
18
+ "output/jsx": "0a174c39378155c19dfa669e833c14d63190127b",
19
+ "output/literals": "287ec4222c79f1ebfa2c6efae925e794cbb931ab",
20
+ "output/loops": "8a0dd93b95e1b9c2a29344e6b41cb5cec6b7afc5",
21
+ "output/modules": "15735b9b07260d11ba231fc3439818bd1a54947e",
22
+ "output/operators": "14b23f4a3ab3b1997411b8ec9f0f57d3e76a7da0",
23
+ "output/statements": "94ee0cd084f22aea451b96eb1a9a831084cc4267",
24
+ "output/stream": "2723d80bc398468e0828f50fb0837095c52f45dc",
25
+ "output/treeshake": "c1d65269ff21cfd046e947755a3489d0e670a74a",
23
26
  "output/utils": "595968f96f6fdcc51eb41c34d64c92bb595e3cb1",
24
- "parse": "d5c1a77662dfcff841dfcd368d5dbb129a592f5d",
27
+ "parse": "0643834ed3c98d350ceb9ec71179f8923974c08c",
25
28
  "string_interpolation": "bff1cc76d772d24d35707f6c794f38734ca08376",
26
- "tokenizer": "00fc24a41edac9f9b31735e6290348005a623cef",
29
+ "tokenizer": "134f46d5a10576c6a27d4fe024c63f45e111fefe",
27
30
  "unicode_aliases": "79ac6eaa5e6be44a5397d62c561f854a8fe7528e",
28
31
  "utils": "c1666db819aa7c8db38697e34e18362e3cb45869",
29
- "#compiler#": "d98fcbb15d08dae74d9c7371ea28fea676642e67",
30
- "#compiled_with#": "d98fcbb15d08dae74d9c7371ea28fea676642e67"
32
+ "#compiler#": "d41c267ea92de4937495c7d35c8d50e1b48f550c",
33
+ "#compiled_with#": "d41c267ea92de4937495c7d35c8d50e1b48f550c"
31
34
  }
package/src/ast.pyj CHANGED
@@ -600,6 +600,9 @@ class AST_Class(AST_Scope):
600
600
  'statements': "[AST_Node*] list of statements in the class scope (excluding method definitions)",
601
601
  'dynamic_properties': '[dict] map of dynamic property names to property descriptors of the form {getter:AST_Method, setter:AST_Method',
602
602
  'classvars': '[dict] map containing all class variables as keys, to be used to easily test for existence of a class variable',
603
+ 'has_new': "[boolean] true if the class defines a __new__ method",
604
+ 'has_attr_dunders': "[boolean] true if the class defines any of __getattr__/__setattr__/__delattr__/__getattribute__",
605
+ 'class_kwargs': "[array] keyword arguments from class header (e.g. class C(Base, key=val):) as [[key_node, value_node], ...]",
603
606
  }
604
607
 
605
608
  def _walk(self, visitor):
@@ -610,6 +613,9 @@ class AST_Class(AST_Scope):
610
613
  self.name._walk(visitor)
611
614
  walk_body(self, visitor)
612
615
  if (self.parent) self.parent._walk(visitor)
616
+ if self.class_kwargs:
617
+ for kw in self.class_kwargs:
618
+ kw[1]._walk(visitor)
613
619
  )
614
620
 
615
621
  class AST_Method(AST_Lambda):
@@ -725,7 +731,8 @@ class AST_Except(AST_Block):
725
731
  "An `except` node for RapydScript, which resides inside the catch block"
726
732
  properties = {
727
733
  'argname': "[AST_SymbolCatch] symbol for the exception",
728
- 'errors': "[AST_SymbolVar*] error classes to catch in this block"
734
+ 'errors': "[AST_SymbolVar*] error classes to catch in this block",
735
+ 'is_star': '[bool] True for except* (exception group) clauses',
729
736
  }
730
737
 
731
738
  def _walk(self, visitor):
@@ -981,6 +988,7 @@ class AST_Binary(AST_Node):
981
988
  'operator': "[string] the operator",
982
989
  'right': "[AST_Node] right-hand side expression",
983
990
  'overloaded': "[bool] Whether to use Python-style operator overloading dispatch",
991
+ 'strict_arith': "[bool] Whether incompatible operand types raise TypeError (default True when overloaded; disable with no_strict_arithmetic)",
984
992
  'python_truthiness': "[bool] Whether to use Python truthiness (from __python__ import truthiness)"
985
993
  }
986
994
 
@@ -1161,6 +1169,17 @@ class AST_ObjectSpread(AST_Node):
1161
1169
  self.value._walk(visitor)
1162
1170
  )
1163
1171
 
1172
+ class AST_Spread(AST_Node):
1173
+ "A *expr spread item inside a list or set literal: [1, *a, 2]"
1174
+ properties = {
1175
+ 'expression': "[AST_Node] the expression being spread",
1176
+ }
1177
+
1178
+ def _walk(self, visitor):
1179
+ return visitor._visit(self, def():
1180
+ self.expression._walk(visitor)
1181
+ )
1182
+
1164
1183
  class AST_Set(AST_Node):
1165
1184
  "A set literal"
1166
1185
  properties = {
@@ -1360,6 +1379,80 @@ class TreeWalker:
1360
1379
  self = p
1361
1380
  # }}}
1362
1381
 
1382
+ # JSX nodes {{{
1383
+
1384
+ class AST_JSXElement(AST_Node):
1385
+ "A JSX element like <div>...</div> or <Component />"
1386
+ properties = {
1387
+ 'tag': "[string] The tag name (e.g. 'div', 'MyComponent')",
1388
+ 'props': "[AST_JSXAttribute[]] The props/attributes",
1389
+ 'children': "[AST_Node[]] The children",
1390
+ 'self_closing': "[bool] Whether self-closing (no children)"
1391
+ }
1392
+
1393
+ def _walk(self, visitor):
1394
+ return visitor._visit(self, def():
1395
+ for prop in self.props:
1396
+ prop._walk(visitor)
1397
+ for child in self.children:
1398
+ child._walk(visitor)
1399
+ )
1400
+
1401
+ class AST_JSXFragment(AST_Node):
1402
+ "A JSX fragment <>...</>"
1403
+ properties = {
1404
+ 'children': "[AST_Node[]] The children"
1405
+ }
1406
+
1407
+ def _walk(self, visitor):
1408
+ return visitor._visit(self, def():
1409
+ for child in self.children:
1410
+ child._walk(visitor)
1411
+ )
1412
+
1413
+ class AST_JSXAttribute(AST_Node):
1414
+ "A JSX attribute like prop='val', prop={expr}, or just prop (boolean)"
1415
+ properties = {
1416
+ 'name': "[string] The attribute name",
1417
+ 'value': "[AST_Node|null] The value (null for boolean attrs)"
1418
+ }
1419
+
1420
+ def _walk(self, visitor):
1421
+ return visitor._visit(self, def():
1422
+ if self.value:
1423
+ self.value._walk(visitor)
1424
+ )
1425
+
1426
+ class AST_JSXSpread(AST_Node):
1427
+ "A JSX spread attribute {...expr}"
1428
+ properties = {
1429
+ 'expression': "[AST_Node] The spread expression"
1430
+ }
1431
+
1432
+ def _walk(self, visitor):
1433
+ return visitor._visit(self, def():
1434
+ self.expression._walk(visitor)
1435
+ )
1436
+
1437
+ class AST_JSXText(AST_Node):
1438
+ "Text content inside a JSX element"
1439
+ properties = {
1440
+ 'value': "[string] The text content"
1441
+ }
1442
+
1443
+ class AST_JSXExprContainer(AST_Node):
1444
+ "A JSX expression container {expr}"
1445
+ properties = {
1446
+ 'expression': "[AST_Node] The expression"
1447
+ }
1448
+
1449
+ def _walk(self, visitor):
1450
+ return visitor._visit(self, def():
1451
+ self.expression._walk(visitor)
1452
+ )
1453
+
1454
+ # }}}
1455
+
1363
1456
  class Found(Exception):
1364
1457
  pass
1365
1458
 
@@ -20,6 +20,7 @@ def ρσ_bool(val):
20
20
  v'if ((typeof Set === "function" && val instanceof Set) || (typeof Map === "function" && val instanceof Map)) return val.size > 0'
21
21
  v'if (!val.constructor || val.constructor === Object) return Object.keys(val).length > 0'
22
22
  return True
23
+ ρσ_bool.__name__ = 'bool'
23
24
 
24
25
  def ρσ_print(*args, **kwargs):
25
26
  if v'typeof console' is 'object':
@@ -35,6 +36,7 @@ def ρσ_int(val, base):
35
36
  if isNaN(ans):
36
37
  raise ValueError('Invalid literal for int with base ' + (base or 10) + ': ' + val)
37
38
  return ans
39
+ ρσ_int.__name__ = 'int'
38
40
 
39
41
  def ρσ_float(val):
40
42
  if jstype(val) is "number":
@@ -44,6 +46,7 @@ def ρσ_float(val):
44
46
  if isNaN(ans):
45
47
  raise ValueError('Could not convert string to float: ' + arguments[0])
46
48
  return ans
49
+ ρσ_float.__name__ = 'float'
47
50
 
48
51
  def ρσ_arraylike_creator():
49
52
  names = 'Int8Array Uint8Array Uint8ClampedArray Int16Array Uint16Array Int32Array Uint32Array Float32Array Float64Array'.split(' ')
@@ -282,6 +285,23 @@ def ρσ_hasattr(obj, name):
282
285
  def ρσ_get_module(name):
283
286
  return ρσ_modules[name]
284
287
 
288
+ def ρσ__import__(name, globals, locals, fromlist, level):
289
+ # Return the module from the already-compiled ρσ_modules registry.
290
+ # Like Python: without fromlist (or empty fromlist) returns the top-level
291
+ # package; with a non-empty fromlist returns the named (possibly dotted) module.
292
+ # NOTE: the module must have been statically imported elsewhere in the source;
293
+ # __import__ only provides a runtime reference to an already-compiled module.
294
+ if v'typeof ρσ_modules' is 'undefined':
295
+ raise ImportError('No module named \'' + name + '\'')
296
+ if fromlist is not undefined and fromlist is not None and fromlist.length:
297
+ lookup = name
298
+ else:
299
+ lookup = name.split('.')[0]
300
+ module = ρσ_modules[lookup]
301
+ if module is undefined:
302
+ raise ModuleNotFoundError('No module named \'' + lookup + '\'')
303
+ return module
304
+
285
305
  def ρσ_pow(x, y, z):
286
306
  ans = Math.pow(x, y)
287
307
  if z is not undefined:
@@ -322,6 +342,7 @@ def ρσ_hash(obj):
322
342
  }
323
343
  return ρσ_h;
324
344
  }'''
345
+ v'if (obj.__hash__ === null) throw new TypeError("unhashable type: \'" + (obj.constructor && obj.constructor.name ? obj.constructor.name : "object") + "\'")'
325
346
  v'if (typeof obj.__hash__ === "function") return obj.__hash__()'
326
347
  v'if (Array.isArray(obj)) throw new TypeError("unhashable type: \'list\'")'
327
348
  v'if (typeof ρσ_set === "function" && obj instanceof ρσ_set) throw new TypeError("unhashable type: \'set\'")'
@@ -438,12 +459,350 @@ class ρσ_slice:
438
459
  raise TypeError("unhashable type: 'slice'")
439
460
 
440
461
 
441
- v'var abs = Math.abs, max = ρσ_max.bind(Math.max), min = ρσ_max.bind(Math.min), bool = ρσ_bool, type = ρσ_type'
442
- v'var float = ρσ_float, int = ρσ_int, arraylike = ρσ_arraylike_creator(), ρσ_arraylike = arraylike'
443
- v'var id = ρσ_id, get_module = ρσ_get_module, pow = ρσ_pow, divmod = ρσ_divmod'
462
+ class ρσ_object:
463
+ def __init__(self):
464
+ pass
465
+
466
+ def __repr__(self):
467
+ v'if (this.ρσ_object_id === undefined) this.ρσ_object_id = ++ρσ_hash_id_counter'
468
+ return '<object object at 0x' + v'this.ρσ_object_id.toString(16)'+ '>'
469
+
470
+ def __str__(self):
471
+ return self.__repr__()
472
+
473
+ def __eq__(self, other):
474
+ return self is other
475
+
476
+ def __hash__(self):
477
+ v'if (this.ρσ_object_id === undefined) this.ρσ_object_id = ++ρσ_hash_id_counter'
478
+ return self.ρσ_object_id
479
+
480
+ ρσ_object.__name__ = 'object'
481
+
482
+
483
+ def ρσ_exec(code, globals, locals):
484
+ # Execute a string of JavaScript/RapydScript-compiled code, like Python's exec.
485
+ # Always returns None. Without globals/locals uses indirect eval (global scope).
486
+ # With globals/locals uses the Function constructor so the code can reference the
487
+ # supplied variables; mutable object arguments (lists, dicts) are passed by
488
+ # reference so side-effects (e.g. array.push) are visible in the caller.
489
+ # Handles both plain JS objects and Python ρσ_dict instances (jsmap-backed Map).
490
+ # ρσ_ helpers referenced in compiled strings are injected from the current scope.
491
+ if globals is undefined:
492
+ v'eval(code)'
493
+ return None
494
+ v'''
495
+ function _ρσ_to_obj(d) {
496
+ if (d == null) return {};
497
+ if (typeof ρσ_dict === "function" && d instanceof ρσ_dict) {
498
+ var _r = {}; d.jsmap.forEach(function(v, k) { _r[k] = v; }); return _r;
499
+ }
500
+ return Object.assign({}, d);
501
+ }
502
+ var _ctx = _ρσ_to_obj(globals);
503
+ if (locals !== undefined) Object.assign(_ctx, _ρσ_to_obj(locals));
504
+ var _rσ_refs = code.match(/ρσ_\w+/g) || [];
505
+ _rσ_refs.forEach(function(name) {
506
+ if (!Object.prototype.hasOwnProperty.call(_ctx, name)) {
507
+ try { var _v = eval(name); if (_v !== undefined) _ctx[name] = _v; } catch(e) {}
508
+ }
509
+ });
510
+ var _keys = Object.keys(_ctx);
511
+ var _vals = _keys.map(function(k) { return _ctx[k]; });
512
+ Function.apply(null, _keys.concat([code])).apply(null, _vals);
513
+ '''
514
+ return None
515
+ ρσ_exec.__name__ = 'exec'
516
+
517
+ def ρσ_eval(expr, globals, locals):
518
+ # Called only when 2 or 3 args are provided (scoped eval via Function constructor).
519
+ # The compiler emits ρσ_eval() only when globals/locals are supplied; the
520
+ # plain 1-arg eval(expr) stays as a native direct JS eval call.
521
+ # Handles both plain JS objects and Python ρσ_dict instances (jsmap-backed Map).
522
+ # ρσ_ helpers referenced in compiled strings are injected from the current scope.
523
+ v'''
524
+ function _ρσ_to_obj(d) {
525
+ if (d == null) return {};
526
+ if (typeof ρσ_dict === "function" && d instanceof ρσ_dict) {
527
+ var _r = {}; d.jsmap.forEach(function(v, k) { _r[k] = v; }); return _r;
528
+ }
529
+ return Object.assign({}, d);
530
+ }
531
+ var _ctx = (globals !== undefined) ? _ρσ_to_obj(globals) : {};
532
+ if (locals !== undefined) Object.assign(_ctx, _ρσ_to_obj(locals));
533
+ var _rσ_refs = expr.match(/ρσ_\w+/g) || [];
534
+ _rσ_refs.forEach(function(name) {
535
+ if (!Object.prototype.hasOwnProperty.call(_ctx, name)) {
536
+ try { var _v = eval(name); if (_v !== undefined) _ctx[name] = _v; } catch(e) {}
537
+ }
538
+ });
539
+ var _keys = Object.keys(_ctx);
540
+ var _vals = _keys.map(function(k) { return _ctx[k]; });
541
+ return Function.apply(null, _keys.concat(['return (' + expr + ')'])).apply(null, _vals);
542
+ '''
543
+ ρσ_eval.__name__ = 'eval'
544
+
545
+ def ρσ_vars(obj):
546
+ # vars(obj) -> dict of obj's own instance attributes (like Python's obj.__dict__)
547
+ # vars() -> compiler rewrites to vars(this) — see output/functions.pyj
548
+ v'''
549
+ var _d;
550
+ if (typeof ρσ_dict === "function") {
551
+ _d = new ρσ_dict();
552
+ if (obj !== undefined && obj !== null) {
553
+ Object.keys(obj).forEach(function(k) {
554
+ if (k.charCodeAt(0) !== 0x03c1) { _d.jsmap.set(k, obj[k]); }
555
+ });
556
+ }
557
+ } else {
558
+ _d = Object.create(null);
559
+ if (obj !== undefined && obj !== null) {
560
+ Object.keys(obj).forEach(function(k) {
561
+ if (k.charCodeAt(0) !== 0x03c1) { _d[k] = obj[k]; }
562
+ });
563
+ }
564
+ }
565
+ '''
566
+ return v'_d'
567
+ ρσ_vars.__name__ = 'vars'
568
+
569
+ def ρσ_locals():
570
+ # In JavaScript, local scope cannot be introspected at runtime.
571
+ # Returns an empty dict as an approximation.
572
+ v'''
573
+ var _d;
574
+ if (typeof ρσ_dict === "function") { _d = new ρσ_dict(); } else { _d = Object.create(null); }
575
+ '''
576
+ return v'_d'
577
+ ρσ_locals.__name__ = 'locals'
578
+
579
+ def ρσ_globals():
580
+ # Returns a snapshot dict of the JS global object's own enumerable properties.
581
+ # In a browser this covers window.*; in Node.js this covers globalThis/global.*.
582
+ # Note: module-level RapydScript variables compiled inside an IIFE/module
583
+ # wrapper will NOT appear here — use a plain dict to share state instead.
584
+ v'''
585
+ var _g = (typeof globalThis !== "undefined") ? globalThis : (typeof window !== "undefined" ? window : (typeof global !== "undefined" ? global : {}));
586
+ var _d;
587
+ if (typeof ρσ_dict === "function") {
588
+ _d = new ρσ_dict();
589
+ Object.getOwnPropertyNames(_g).forEach(function(k) { _d.jsmap.set(k, _g[k]); });
590
+ } else {
591
+ _d = Object.create(null);
592
+ Object.getOwnPropertyNames(_g).forEach(function(k) { _d[k] = _g[k]; });
593
+ }
594
+ '''
595
+ return v'_d'
596
+ ρσ_globals.__name__ = 'globals'
597
+
598
+ def ρσ_abs(x):
599
+ if x is not None and jstype(x.__abs__) is 'function':
600
+ return x.__abs__()
601
+ return Math.abs(x)
602
+ ρσ_abs.__name__ = 'abs'
603
+
604
+ class ρσ_complex:
605
+ def __init__(self, real, imag):
606
+ nargs = arguments.length
607
+ if nargs is 0:
608
+ self.real = 0.0
609
+ self.imag = 0.0
610
+ elif nargs >= 2:
611
+ if jstype(real) is not 'number' and jstype(real) is not 'boolean':
612
+ raise TypeError("complex() first argument must be a number, not '" + jstype(real) + "'")
613
+ if jstype(imag) is not 'number' and jstype(imag) is not 'boolean':
614
+ raise TypeError("complex() second argument must be a number, not '" + jstype(imag) + "'")
615
+ self.real = +real
616
+ self.imag = +imag
617
+ else:
618
+ x = real
619
+ if v'x instanceof ρσ_complex':
620
+ self.real = x.real
621
+ self.imag = x.imag
622
+ elif jstype(x) is 'number' or jstype(x) is 'boolean':
623
+ self.real = +x
624
+ self.imag = 0.0
625
+ elif jstype(x) is 'string' or v'x instanceof String':
626
+ s = String(x).trim()
627
+ m_mixed = v'/^([+-]?(?:\d+\.?\d*|\.\d+)(?:[eE][+-]?\d+)?)([+-](?:(?:\d+\.?\d*|\.\d+)(?:[eE][+-]?\d+)?)?)[jJ]$/.exec(s)'
628
+ m_imag = v'/^([+-]?(?:(?:\d+\.?\d*|\.\d+)(?:[eE][+-]?\d+)?)?)[jJ]$/.exec(s)'
629
+ m_real = v'/^([+-]?(?:\d+\.?\d*|\.\d+)(?:[eE][+-]?\d+)?)$/.exec(s)'
630
+ if m_mixed:
631
+ self.real = parseFloat(m_mixed[1])
632
+ ims = m_mixed[2]
633
+ if ims is '+': self.imag = 1.0
634
+ elif ims is '-': self.imag = -1.0
635
+ else: self.imag = parseFloat(ims)
636
+ elif m_imag:
637
+ self.real = 0.0
638
+ ims = m_imag[1]
639
+ if not ims or ims is '+': self.imag = 1.0
640
+ elif ims is '-': self.imag = -1.0
641
+ else: self.imag = parseFloat(ims)
642
+ elif m_real:
643
+ self.real = parseFloat(m_real[1])
644
+ self.imag = 0.0
645
+ else:
646
+ raise ValueError("complex() arg is a malformed string")
647
+ else:
648
+ raise TypeError("complex() argument must be a string or a number")
649
+
650
+ def __add__(self, other):
651
+ if v'other instanceof ρσ_complex':
652
+ return new ρσ_complex(self.real + other.real, self.imag + other.imag)
653
+ if jstype(other) is 'number' or jstype(other) is 'boolean':
654
+ return new ρσ_complex(self.real + other, self.imag)
655
+ raise TypeError("unsupported operand type(s) for +: 'complex' and '" + jstype(other) + "'")
656
+
657
+ def __radd__(self, other):
658
+ if jstype(other) is 'number' or jstype(other) is 'boolean':
659
+ return new ρσ_complex(other + self.real, self.imag)
660
+ if v'other instanceof ρσ_complex':
661
+ return new ρσ_complex(other.real + self.real, other.imag + self.imag)
662
+ raise TypeError("unsupported operand type(s) for +: '" + jstype(other) + "' and 'complex'")
663
+
664
+ def __sub__(self, other):
665
+ if v'other instanceof ρσ_complex':
666
+ return new ρσ_complex(self.real - other.real, self.imag - other.imag)
667
+ if jstype(other) is 'number' or jstype(other) is 'boolean':
668
+ return new ρσ_complex(self.real - other, self.imag)
669
+ raise TypeError("unsupported operand type(s) for -: 'complex' and '" + jstype(other) + "'")
670
+
671
+ def __rsub__(self, other):
672
+ if jstype(other) is 'number' or jstype(other) is 'boolean':
673
+ return new ρσ_complex(other - self.real, -self.imag)
674
+ if v'other instanceof ρσ_complex':
675
+ return new ρσ_complex(other.real - self.real, other.imag - self.imag)
676
+ raise TypeError("unsupported operand type(s) for -: '" + jstype(other) + "' and 'complex'")
677
+
678
+ def __mul__(self, other):
679
+ if v'other instanceof ρσ_complex':
680
+ return new ρσ_complex(
681
+ self.real * other.real - self.imag * other.imag,
682
+ self.real * other.imag + self.imag * other.real
683
+ )
684
+ if jstype(other) is 'number' or jstype(other) is 'boolean':
685
+ return new ρσ_complex(self.real * other, self.imag * other)
686
+ raise TypeError("unsupported operand type(s) for *: 'complex' and '" + jstype(other) + "'")
687
+
688
+ def __rmul__(self, other):
689
+ if jstype(other) is 'number' or jstype(other) is 'boolean':
690
+ return new ρσ_complex(other * self.real, other * self.imag)
691
+ if v'other instanceof ρσ_complex':
692
+ return new ρσ_complex(
693
+ other.real * self.real - other.imag * self.imag,
694
+ other.real * self.imag + other.imag * self.real
695
+ )
696
+ raise TypeError("unsupported operand type(s) for *: '" + jstype(other) + "' and 'complex'")
697
+
698
+ def __truediv__(self, other):
699
+ if v'other instanceof ρσ_complex':
700
+ denom = other.real * other.real + other.imag * other.imag
701
+ if denom is 0: raise ZeroDivisionError('complex division by zero')
702
+ return new ρσ_complex(
703
+ (self.real * other.real + self.imag * other.imag) / denom,
704
+ (self.imag * other.real - self.real * other.imag) / denom
705
+ )
706
+ if jstype(other) is 'number' or jstype(other) is 'boolean':
707
+ if other is 0: raise ZeroDivisionError('complex division by zero')
708
+ return new ρσ_complex(self.real / other, self.imag / other)
709
+ raise TypeError("unsupported operand type(s) for /: 'complex' and '" + jstype(other) + "'")
710
+
711
+ def __rtruediv__(self, other):
712
+ denom = self.real * self.real + self.imag * self.imag
713
+ if denom is 0: raise ZeroDivisionError('complex division by zero')
714
+ if jstype(other) is 'number' or jstype(other) is 'boolean':
715
+ return new ρσ_complex(other * self.real / denom, -other * self.imag / denom)
716
+ if v'other instanceof ρσ_complex':
717
+ return new ρσ_complex(
718
+ (other.real * self.real + other.imag * self.imag) / denom,
719
+ (other.imag * self.real - other.real * self.imag) / denom
720
+ )
721
+ raise TypeError("unsupported operand type(s) for /: '" + jstype(other) + "' and 'complex'")
722
+
723
+ def __pow__(self, other):
724
+ if jstype(other) is 'number' or jstype(other) is 'boolean':
725
+ r = Math.sqrt(self.real * self.real + self.imag * self.imag)
726
+ if r is 0: return new ρσ_complex(0, 0)
727
+ theta = Math.atan2(self.imag, self.real)
728
+ rn = Math.pow(r, other)
729
+ return new ρσ_complex(rn * Math.cos(other * theta), rn * Math.sin(other * theta))
730
+ if v'other instanceof ρσ_complex':
731
+ r = Math.sqrt(self.real * self.real + self.imag * self.imag)
732
+ if r is 0: return new ρσ_complex(0, 0)
733
+ theta = Math.atan2(self.imag, self.real)
734
+ log_r = Math.log(r)
735
+ c = other.real
736
+ d = other.imag
737
+ re_prod = c * log_r - d * theta
738
+ im_prod = d * log_r + c * theta
739
+ exp_re = Math.exp(re_prod)
740
+ return new ρσ_complex(exp_re * Math.cos(im_prod), exp_re * Math.sin(im_prod))
741
+ raise TypeError("unsupported operand type(s) for **: 'complex' and '" + jstype(other) + "'")
742
+
743
+ def __rpow__(self, other):
744
+ if jstype(other) is 'number' or jstype(other) is 'boolean':
745
+ base = new ρσ_complex(other, 0)
746
+ return base.__pow__(self)
747
+ if v'other instanceof ρσ_complex':
748
+ return other.__pow__(self)
749
+ raise TypeError("unsupported operand type(s) for **: '" + jstype(other) + "' and 'complex'")
750
+
751
+ def __neg__(self):
752
+ return new ρσ_complex(-self.real, -self.imag)
753
+
754
+ def __pos__(self):
755
+ return new ρσ_complex(self.real, self.imag)
756
+
757
+ def __abs__(self):
758
+ return Math.sqrt(self.real * self.real + self.imag * self.imag)
759
+
760
+ def __bool__(self):
761
+ return self.real is not 0 or self.imag is not 0
762
+
763
+ def __eq__(self, other):
764
+ if v'other instanceof ρσ_complex':
765
+ return self.real is other.real and self.imag is other.imag
766
+ if jstype(other) is 'number' or jstype(other) is 'boolean':
767
+ return self.imag is 0 and self.real is other
768
+ return False
769
+
770
+ def __hash__(self):
771
+ if self.imag is 0:
772
+ return self.real | 0
773
+ return v'(self.real * 1000003 ^ self.imag) | 0'
774
+
775
+ def conjugate(self):
776
+ return new ρσ_complex(self.real, -self.imag)
777
+
778
+ def __repr__(self):
779
+ r = self.real
780
+ i = self.imag
781
+ if r is 0 and i is 0: return '0j'
782
+ r_str = String(r)
783
+ i_str = String(i)
784
+ if r is 0:
785
+ return i_str + 'j'
786
+ if i >= 0 or isNaN(i):
787
+ return '(' + r_str + '+' + i_str + 'j)'
788
+ return '(' + r_str + i_str + 'j)'
789
+
790
+ def __str__(self):
791
+ return self.__repr__()
792
+
793
+ ρσ_complex.__name__ = 'complex'
794
+
795
+ 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'
797
+ v'var id = ρσ_id, get_module = ρσ_get_module, pow = ρσ_pow, divmod = ρσ_divmod, __import__ = ρσ__import__'
444
798
  v'var dir = ρσ_dir, ord = ρσ_ord, chr = ρσ_chr, bin = ρσ_bin, hex = ρσ_hex, callable = ρσ_callable, round = ρσ_round'
445
799
  v'var enumerate = ρσ_enumerate, iter = ρσ_iter, reversed = ρσ_reversed, len = ρσ_len'
446
800
  v'var range = ρσ_range, getattr = ρσ_getattr, setattr = ρσ_setattr, hasattr = ρσ_hasattr, issubclass = ρσ_issubclass, hash = ρσ_hash, next = ρσ_next'
801
+ v'var exec = ρσ_exec'
802
+ v'var vars = ρσ_vars, locals = ρσ_locals, globals = ρσ_globals'
447
803
  v'var ρσ_Ellipsis = Object.freeze({toString: function(){return "Ellipsis";}, __repr__: function(){return "Ellipsis";}})'
448
804
  v'var Ellipsis = ρσ_Ellipsis'
449
805
  v'var slice = ρσ_slice'
806
+ v'var object = ρσ_object'
807
+ v'Number.prototype.is_integer = function() { return isFinite(+this) && (+this) % 1 === 0; }'
808
+ v'Number.prototype.bit_length = function() { var n = Math.abs(Math.trunc(+this)); if (n === 0) return 0; return Math.floor(Math.log2(n)) + 1; }'