rapydscript-ns 0.8.2 → 0.8.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 (141) hide show
  1. package/.agignore +1 -1
  2. package/.github/workflows/ci.yml +38 -38
  3. package/=template.pyj +5 -5
  4. package/CHANGELOG.md +39 -0
  5. package/HACKING.md +103 -103
  6. package/LICENSE +24 -24
  7. package/PYTHON_DIFFERENCES_REPORT.md +291 -0
  8. package/PYTHON_FEATURE_COVERAGE.md +106 -15
  9. package/README.md +831 -52
  10. package/TODO.md +4 -286
  11. package/add-toc-to-readme +2 -2
  12. package/bin/export +75 -75
  13. package/bin/rapydscript +70 -70
  14. package/bin/web-repl-export +102 -102
  15. package/build +2 -2
  16. package/language-service/index.js +4623 -0
  17. package/language-service/language-service.d.ts +40 -0
  18. package/package.json +9 -7
  19. package/publish.py +37 -37
  20. package/release/baselib-plain-pretty.js +2006 -229
  21. package/release/baselib-plain-ugly.js +70 -3
  22. package/release/compiler.js +11554 -3870
  23. package/release/signatures.json +31 -29
  24. package/session.vim +4 -4
  25. package/setup.cfg +2 -2
  26. package/src/ast.pyj +93 -1
  27. package/src/baselib-builtins.pyj +99 -2
  28. package/src/baselib-containers.pyj +107 -4
  29. package/src/baselib-errors.pyj +44 -0
  30. package/src/baselib-internal.pyj +124 -5
  31. package/src/baselib-itertools.pyj +97 -97
  32. package/src/baselib-str.pyj +32 -1
  33. package/src/compiler.pyj +36 -36
  34. package/src/errors.pyj +30 -30
  35. package/src/lib/aes.pyj +646 -646
  36. package/src/lib/collections.pyj +1 -1
  37. package/src/lib/copy.pyj +120 -0
  38. package/src/lib/elementmaker.pyj +83 -83
  39. package/src/lib/encodings.pyj +126 -126
  40. package/src/lib/gettext.pyj +569 -569
  41. package/src/lib/itertools.pyj +580 -580
  42. package/src/lib/math.pyj +193 -193
  43. package/src/lib/numpy.pyj +10 -10
  44. package/src/lib/operator.pyj +11 -11
  45. package/src/lib/pythonize.pyj +20 -20
  46. package/src/lib/random.pyj +118 -118
  47. package/src/lib/re.pyj +470 -470
  48. package/src/lib/react.pyj +74 -0
  49. package/src/lib/traceback.pyj +63 -63
  50. package/src/lib/uuid.pyj +77 -77
  51. package/src/monaco-language-service/analyzer.js +131 -9
  52. package/src/monaco-language-service/builtins.js +17 -2
  53. package/src/monaco-language-service/completions.js +170 -1
  54. package/src/monaco-language-service/diagnostics.js +25 -3
  55. package/src/monaco-language-service/dts.js +550 -550
  56. package/src/monaco-language-service/index.js +17 -0
  57. package/src/monaco-language-service/scope.js +3 -0
  58. package/src/output/classes.pyj +128 -11
  59. package/src/output/codegen.pyj +17 -3
  60. package/src/output/comments.pyj +45 -45
  61. package/src/output/exceptions.pyj +201 -105
  62. package/src/output/functions.pyj +13 -16
  63. package/src/output/jsx.pyj +164 -0
  64. package/src/output/literals.pyj +28 -2
  65. package/src/output/loops.pyj +0 -9
  66. package/src/output/modules.pyj +2 -5
  67. package/src/output/operators.pyj +22 -2
  68. package/src/output/statements.pyj +2 -2
  69. package/src/output/stream.pyj +1 -13
  70. package/src/output/treeshake.pyj +182 -182
  71. package/src/output/utils.pyj +72 -72
  72. package/src/parse.pyj +434 -114
  73. package/src/string_interpolation.pyj +72 -72
  74. package/src/tokenizer.pyj +29 -0
  75. package/src/unicode_aliases.pyj +576 -576
  76. package/src/utils.pyj +192 -192
  77. package/test/_import_one.pyj +37 -37
  78. package/test/_import_two/__init__.pyj +11 -11
  79. package/test/_import_two/level2/deep.pyj +4 -4
  80. package/test/_import_two/other.pyj +6 -6
  81. package/test/_import_two/sub.pyj +13 -13
  82. package/test/aes_vectors.pyj +421 -421
  83. package/test/annotations.pyj +80 -80
  84. package/test/baselib.pyj +4 -4
  85. package/test/classes.pyj +56 -17
  86. package/test/collections.pyj +5 -5
  87. package/test/decorators.pyj +77 -77
  88. package/test/docstrings.pyj +39 -39
  89. package/test/elementmaker_test.pyj +45 -45
  90. package/test/functions.pyj +151 -151
  91. package/test/generators.pyj +41 -41
  92. package/test/generic.pyj +370 -370
  93. package/test/imports.pyj +72 -72
  94. package/test/internationalization.pyj +73 -73
  95. package/test/lint.pyj +164 -164
  96. package/test/loops.pyj +85 -85
  97. package/test/numpy.pyj +734 -734
  98. package/test/omit_function_metadata.pyj +20 -20
  99. package/test/python_compat.pyj +326 -0
  100. package/test/python_features.pyj +129 -29
  101. package/test/regexp.pyj +55 -55
  102. package/test/repl.pyj +121 -121
  103. package/test/scoped_flags.pyj +76 -76
  104. package/test/slice.pyj +105 -0
  105. package/test/str.pyj +25 -0
  106. package/test/unit/fixtures/fibonacci_expected.js +1 -1
  107. package/test/unit/index.js +2296 -71
  108. package/test/unit/language-service-builtins.js +70 -0
  109. package/test/unit/language-service-bundle.js +5 -5
  110. package/test/unit/language-service-completions.js +180 -0
  111. package/test/unit/language-service-dts.js +543 -543
  112. package/test/unit/language-service-hover.js +455 -455
  113. package/test/unit/language-service-index.js +350 -0
  114. package/test/unit/language-service-scope.js +255 -0
  115. package/test/unit/language-service.js +625 -4
  116. package/test/unit/run-language-service.js +1 -0
  117. package/test/unit/web-repl.js +437 -0
  118. package/tools/build-language-service.js +2 -2
  119. package/tools/cli.js +547 -547
  120. package/tools/compile.js +219 -219
  121. package/tools/compiler.js +0 -24
  122. package/tools/completer.js +131 -131
  123. package/tools/embedded_compiler.js +251 -251
  124. package/tools/export.js +3 -37
  125. package/tools/gettext.js +185 -185
  126. package/tools/ini.js +65 -65
  127. package/tools/msgfmt.js +187 -187
  128. package/tools/repl.js +223 -223
  129. package/tools/test.js +118 -118
  130. package/tools/utils.js +128 -128
  131. package/tools/web_repl.js +95 -95
  132. package/try +41 -41
  133. package/web-repl/env.js +196 -74
  134. package/web-repl/index.html +163 -163
  135. package/web-repl/main.js +252 -254
  136. package/web-repl/prism.css +139 -139
  137. package/web-repl/prism.js +113 -113
  138. package/web-repl/rapydscript.js +227 -139
  139. package/web-repl/sha1.js +25 -25
  140. package/hack_demo.pyj +0 -112
  141. package/web-repl/language-service.js +0 -4187
@@ -1,7 +1,7 @@
1
1
  # vim:fileencoding=utf-8
2
2
  # License: BSD
3
3
 
4
- # globals: exports, console, ρσ_iterator_symbol, ρσ_kwargs_symbol, ρσ_arraylike, ρσ_list_contains, ρσ_list_constructor, ρσ_str, ρσ_int, ρσ_float
4
+ # globals: exports, console, ρσ_iterator_symbol, ρσ_kwargs_symbol, ρσ_arraylike, ρσ_list_contains, ρσ_list_constructor, ρσ_str, ρσ_int, ρσ_float, ρσ_slice
5
5
 
6
6
  def ρσ_eslice(arr, step, start, end):
7
7
  if jstype(arr) is 'string' or v'arr instanceof String':
@@ -87,6 +87,14 @@ def ρσ_extends(child, parent):
87
87
  child.prototype.constructor = child
88
88
  Object.setPrototypeOf(child, parent)
89
89
 
90
+ def ρσ_object_new(cls):
91
+ return v'Object.create(cls.prototype)'
92
+
93
+ def ρσ_new(parent, cls):
94
+ if parent and jstype(parent.__new__) is 'function':
95
+ return parent.__new__.apply(parent, v'Array.prototype.slice.call(arguments, 1)')
96
+ return v'Object.create(cls.prototype)'
97
+
90
98
  ρσ_in = (def ():
91
99
  if jstype(Map) is 'function' and jstype(Set) is 'function':
92
100
  return def(val, arr):
@@ -131,15 +139,23 @@ def ρσ_Iterable(iterable):
131
139
  ans = Object.create(None)
132
140
  ans[ρσ_kwargs_symbol] = True
133
141
  for v'var i = 0; i < arguments.length; i++':
134
- Object.assign(ans, arguments[i])
142
+ arg = arguments[i]
143
+ if v'arg && arg.jsmap && typeof arg.jsmap.forEach === "function"':
144
+ v'arg.jsmap.forEach(function(v, k) { ans[k] = v; })'
145
+ else:
146
+ Object.assign(ans, arg)
135
147
  return ans
136
148
  return def():
137
149
  ans = Object.create(None)
138
150
  ans[ρσ_kwargs_symbol] = True
139
151
  for v'var i = 0; i < arguments.length; i++':
140
- keys = Object.keys(arguments[i])
141
- for v'var j = 0; j < keys.length; j++':
142
- ans[keys[j]] = arguments[i][keys[j]]
152
+ arg = arguments[i]
153
+ if v'arg && arg.jsmap && typeof arg.jsmap.forEach === "function"':
154
+ v'arg.jsmap.forEach(function(v, k) { ans[k] = v; })'
155
+ else:
156
+ keys = Object.keys(arg)
157
+ for v'var j = 0; j < keys.length; j++':
158
+ ans[keys[j]] = arg[keys[j]]
143
159
  return ans
144
160
  )()
145
161
 
@@ -177,8 +193,15 @@ def ρσ_interpolate_kwargs_constructor(apply, f, supplied_args):
177
193
  return this
178
194
 
179
195
  def ρσ_getitem(obj, key):
196
+ if v'typeof obj === "function"' and obj.__class_getitem__:
197
+ return obj.__class_getitem__(key)
180
198
  if obj.__getitem__:
181
199
  return obj.__getitem__(key)
200
+ if v'typeof ρσ_slice !== "undefined" && key instanceof ρσ_slice':
201
+ return ρσ_eslice(obj,
202
+ v'(key.step !== null && key.step !== undefined) ? key.step : 1',
203
+ v'(key.start !== null && key.start !== undefined) ? key.start : undefined',
204
+ v'(key.stop !== null && key.stop !== undefined) ? key.stop : undefined')
182
205
  if jstype(key) is 'number' and key < 0:
183
206
  key += obj.length
184
207
  return obj[key]
@@ -186,6 +209,10 @@ def ρσ_getitem(obj, key):
186
209
  def ρσ_setitem(obj, key, val):
187
210
  if obj.__setitem__:
188
211
  obj.__setitem__(key, val)
212
+ elif v'typeof ρσ_slice !== "undefined" && key instanceof ρσ_slice':
213
+ ρσ_splice(obj, val,
214
+ v'(key.start !== null && key.start !== undefined) ? key.start : 0',
215
+ v'(key.stop !== null && key.stop !== undefined) ? key.stop : obj.length')
189
216
  else:
190
217
  if jstype(key) is 'number' and key < 0:
191
218
  key += obj.length
@@ -195,6 +222,11 @@ def ρσ_setitem(obj, key, val):
195
222
  def ρσ_delitem(obj, key):
196
223
  if obj.__delitem__:
197
224
  obj.__delitem__(key)
225
+ elif v'typeof ρσ_slice !== "undefined" && key instanceof ρσ_slice':
226
+ ρσ_delslice(obj,
227
+ v'(key.step !== null && key.step !== undefined) ? key.step : 1',
228
+ v'(key.start !== null && key.start !== undefined) ? key.start : undefined',
229
+ v'(key.stop !== null && key.stop !== undefined) ? key.stop : undefined')
198
230
  elif jstype(obj.splice) is 'function':
199
231
  obj.splice(key, 1)
200
232
  else:
@@ -339,6 +371,21 @@ def ρσ_op_rshift(a, b):
339
371
  if b is not None and jstype(b.__rrshift__) is 'function': return b.__rrshift__(a)
340
372
  return a >> b
341
373
 
374
+ # List-concatenation helpers (always available, no overload_operators required).
375
+ # ρσ_list_add: used for the + operator; creates a new list when both sides are arrays.
376
+ # NOTE: the fallback uses v'a + b' (verbatim JS) to avoid recursive self-compilation.
377
+ def ρσ_list_add(a, b):
378
+ if Array.isArray(a) and Array.isArray(b):
379
+ return ρσ_list_constructor(a.concat(b))
380
+ return v'a + b'
381
+
382
+ # ρσ_list_iadd: used for +=; extends a in-place when both sides are arrays (Python semantics).
383
+ def ρσ_list_iadd(a, b):
384
+ if Array.isArray(a) and Array.isArray(b):
385
+ v'Array.prototype.push.apply(a, b)'
386
+ return a
387
+ return v'a + b'
388
+
342
389
  # Unary operator overloading helpers
343
390
  def ρσ_op_neg(a):
344
391
  if a is not None and jstype(a.__neg__) is 'function': return a.__neg__()
@@ -429,3 +476,75 @@ def ρσ_instanceof():
429
476
  break
430
477
  cls = p.constructor
431
478
  return False
479
+
480
+ # ── Attribute-dunder support (__getattr__ / __setattr__ / __delattr__ / __getattribute__) ──
481
+ # We use a JavaScript Proxy to intercept attribute access/assignment/deletion on class instances
482
+ # that define any of the four attribute dunders.
483
+
484
+ # Cache the JS Proxy constructor with a ρσ_ name to avoid collisions with user-defined 'Proxy' classes.
485
+ ρσ_JS_Proxy = v'typeof Proxy === "function" ? Proxy : null'
486
+
487
+ # Symbol (or fallback string key) used to retrieve the raw underlying target from a wrapped proxy.
488
+ ρσ_proxy_target_symbol = v'typeof Symbol === "function" ? Symbol("ρσ_proxy_target") : "__ρσ_proxy_target__"'
489
+
490
+ ρσ_attr_proxy_handler = {
491
+ 'get': def(target, prop, receiver):
492
+ # Always expose the raw target via the sentinel key (used by ρσ_object_* helpers).
493
+ if prop is ρσ_proxy_target_symbol:
494
+ return target
495
+ # Pass through JS symbols (Symbol.iterator, Symbol.toPrimitive, etc.) unchanged.
496
+ if jstype(prop) is 'symbol':
497
+ return v'Reflect.get(target, prop, receiver)'
498
+ # __getattribute__ overrides every attribute lookup (except itself, to avoid infinite recursion).
499
+ if jstype(target.__getattribute__) is 'function' and prop is not '__getattribute__':
500
+ try:
501
+ return target.__getattribute__.call(receiver, prop)
502
+ except AttributeError:
503
+ # AttributeError from __getattribute__ → try __getattr__ fallback.
504
+ if jstype(target.__getattr__) is 'function':
505
+ return target.__getattr__.call(receiver, prop)
506
+ raise
507
+ # Normal property lookup via prototype chain.
508
+ val = v'Reflect.get(target, prop, receiver)'
509
+ # __getattr__ is only called when the attribute is genuinely missing.
510
+ if val is undefined and jstype(target.__getattr__) is 'function' and not v'(prop in target)':
511
+ return target.__getattr__.call(receiver, prop)
512
+ return val
513
+ ,
514
+ 'set': def(target, prop, value, receiver):
515
+ if jstype(target.__setattr__) is 'function':
516
+ target.__setattr__.call(receiver, prop, value)
517
+ return True
518
+ # Pass 'target' as receiver (not proxy) to avoid infinite recursion through the Proxy set trap.
519
+ return v'Reflect.set(target, prop, value, target)'
520
+ ,
521
+ 'deleteProperty': def(target, prop):
522
+ if jstype(target.__delattr__) is 'function':
523
+ # deleteProperty has no receiver; pass target as 'this'.
524
+ # Inside __delattr__, use ρσ_object_delattr(self, name) for a direct delete.
525
+ target.__delattr__.call(target, prop)
526
+ return True
527
+ return v'Reflect.deleteProperty(target, prop)'
528
+ }
529
+
530
+ def ρσ_object_setattr(obj, name, value):
531
+ # Bypass __setattr__ and set directly on the underlying object.
532
+ # Use this inside __setattr__ to avoid infinite recursion (like object.__setattr__ in Python).
533
+ target = obj[ρσ_proxy_target_symbol]
534
+ if target is undefined:
535
+ target = obj
536
+ v'target[name] = value'
537
+
538
+ def ρσ_object_getattr(obj, name):
539
+ # Bypass __getattribute__ and read directly from the underlying object.
540
+ target = obj[ρσ_proxy_target_symbol]
541
+ if target is undefined:
542
+ target = obj
543
+ return target[name]
544
+
545
+ def ρσ_object_delattr(obj, name):
546
+ # Bypass __delattr__ and delete directly from the underlying object.
547
+ target = obj[ρσ_proxy_target_symbol]
548
+ if target is undefined:
549
+ target = obj
550
+ v'delete target[name]'
@@ -1,97 +1,97 @@
1
- # vim:fileencoding=utf-8
2
- # License: BSD
3
- # Copyright: 2015, Kovid Goyal <kovid at kovidgoyal.net>
4
-
5
- # globals: ρσ_iterator_symbol, ρσ_bool
6
-
7
- def sum(iterable, start):
8
- if Array.isArray(iterable):
9
- return iterable.reduce(
10
- def(prev, cur): return prev+cur
11
- ,
12
- start or 0
13
- )
14
- ans = start or 0
15
- iterator = iter(iterable)
16
- r = iterator.next()
17
- while not r.done:
18
- ans += r.value
19
- r = iterator.next()
20
- return ans
21
-
22
- def map():
23
- iterators = new Array(arguments.length - 1)
24
- func = arguments[0] # noqa: unused-local
25
- args = new Array(arguments.length - 1) # noqa: unused-local
26
- for v'var i = 1; i < arguments.length; i++':
27
- iterators[i - 1] = iter(arguments[i]) # noqa:undef
28
- ans = v"{'_func':func, '_iterators':iterators, '_args':args}"
29
- ans[ρσ_iterator_symbol] = def():
30
- return this
31
- ans['next'] = def():
32
- for v'var i = 0; i < this._iterators.length; i++':
33
- r = this._iterators[i].next()
34
- if r.done:
35
- return v"{'done':true}"
36
- this._args[i] = r.value # noqa:undef
37
- return v"{'done':false, 'value':this._func.apply(undefined, this._args)}"
38
- return ans
39
-
40
- def filter(func_or_none, iterable):
41
- func = ρσ_bool if func_or_none is None else func_or_none # noqa: unused-local
42
- ans = v"{'_func':func, '_iterator':ρσ_iter(iterable)}"
43
- ans[ρσ_iterator_symbol] = def():
44
- return this
45
- ans['next'] = def():
46
- r = this._iterator.next()
47
- while not r.done:
48
- if this._func(r.value):
49
- return r
50
- r = this._iterator.next()
51
- return v"{'done':true}"
52
- return ans
53
-
54
- def zip():
55
- iterators = new Array(arguments.length)
56
- for v'var i = 0; i < arguments.length; i++':
57
- iterators[i] = iter(arguments[i]) # noqa:undef
58
- ans = v"{'_iterators':iterators}"
59
- ans[ρσ_iterator_symbol] = def():
60
- return this
61
- ans['next'] = def():
62
- args = new Array(this._iterators.length)
63
- for v'var i = 0; i < this._iterators.length; i++':
64
- r = this._iterators[i].next()
65
- if r.done:
66
- return v"{'done':true}"
67
- args[i] = r.value # noqa:undef
68
- return v"{'done':false, 'value':args}"
69
- return ans
70
-
71
- def any(iterable):
72
- if Array.isArray(iterable) or jstype(iterable) is 'string':
73
- for v'var i = 0; i < iterable.length; i++':
74
- if iterable[i]: # noqa:undef
75
- return True
76
- return False
77
- iterator = iter(iterable)
78
- r = iterator.next()
79
- while not r.done:
80
- if r.value:
81
- return True
82
- r = iterator.next()
83
- return False
84
-
85
- def all(iterable):
86
- if Array.isArray(iterable) or jstype(iterable) is 'string':
87
- for v'var i = 0; i < iterable.length; i++':
88
- if not iterable[i]: # noqa:undef
89
- return False
90
- return True
91
- iterator = iter(iterable)
92
- r = iterator.next()
93
- while not r.done:
94
- if not r.value:
95
- return False
96
- r = iterator.next()
97
- return True
1
+ # vim:fileencoding=utf-8
2
+ # License: BSD
3
+ # Copyright: 2015, Kovid Goyal <kovid at kovidgoyal.net>
4
+
5
+ # globals: ρσ_iterator_symbol, ρσ_bool
6
+
7
+ def sum(iterable, start):
8
+ if Array.isArray(iterable):
9
+ return iterable.reduce(
10
+ def(prev, cur): return prev+cur
11
+ ,
12
+ start or 0
13
+ )
14
+ ans = start or 0
15
+ iterator = iter(iterable)
16
+ r = iterator.next()
17
+ while not r.done:
18
+ ans += r.value
19
+ r = iterator.next()
20
+ return ans
21
+
22
+ def map():
23
+ iterators = new Array(arguments.length - 1)
24
+ func = arguments[0] # noqa: unused-local
25
+ args = new Array(arguments.length - 1) # noqa: unused-local
26
+ for v'var i = 1; i < arguments.length; i++':
27
+ iterators[i - 1] = iter(arguments[i]) # noqa:undef
28
+ ans = v"{'_func':func, '_iterators':iterators, '_args':args}"
29
+ ans[ρσ_iterator_symbol] = def():
30
+ return this
31
+ ans['next'] = def():
32
+ for v'var i = 0; i < this._iterators.length; i++':
33
+ r = this._iterators[i].next()
34
+ if r.done:
35
+ return v"{'done':true}"
36
+ this._args[i] = r.value # noqa:undef
37
+ return v"{'done':false, 'value':this._func.apply(undefined, this._args)}"
38
+ return ans
39
+
40
+ def filter(func_or_none, iterable):
41
+ func = ρσ_bool if func_or_none is None else func_or_none # noqa: unused-local
42
+ ans = v"{'_func':func, '_iterator':ρσ_iter(iterable)}"
43
+ ans[ρσ_iterator_symbol] = def():
44
+ return this
45
+ ans['next'] = def():
46
+ r = this._iterator.next()
47
+ while not r.done:
48
+ if this._func(r.value):
49
+ return r
50
+ r = this._iterator.next()
51
+ return v"{'done':true}"
52
+ return ans
53
+
54
+ def zip():
55
+ iterators = new Array(arguments.length)
56
+ for v'var i = 0; i < arguments.length; i++':
57
+ iterators[i] = iter(arguments[i]) # noqa:undef
58
+ ans = v"{'_iterators':iterators}"
59
+ ans[ρσ_iterator_symbol] = def():
60
+ return this
61
+ ans['next'] = def():
62
+ args = new Array(this._iterators.length)
63
+ for v'var i = 0; i < this._iterators.length; i++':
64
+ r = this._iterators[i].next()
65
+ if r.done:
66
+ return v"{'done':true}"
67
+ args[i] = r.value # noqa:undef
68
+ return v"{'done':false, 'value':args}"
69
+ return ans
70
+
71
+ def any(iterable):
72
+ if Array.isArray(iterable) or jstype(iterable) is 'string':
73
+ for v'var i = 0; i < iterable.length; i++':
74
+ if iterable[i]: # noqa:undef
75
+ return True
76
+ return False
77
+ iterator = iter(iterable)
78
+ r = iterator.next()
79
+ while not r.done:
80
+ if r.value:
81
+ return True
82
+ r = iterator.next()
83
+ return False
84
+
85
+ def all(iterable):
86
+ if Array.isArray(iterable) or jstype(iterable) is 'string':
87
+ for v'var i = 0; i < iterable.length; i++':
88
+ if not iterable[i]: # noqa:undef
89
+ return False
90
+ return True
91
+ iterator = iter(iterable)
92
+ r = iterator.next()
93
+ while not r.done:
94
+ if not r.value:
95
+ return False
96
+ r = iterator.next()
97
+ return True
@@ -774,6 +774,29 @@ define_str_func('zfill', def(width):
774
774
  return string
775
775
  )
776
776
 
777
+ define_str_func('expandtabs', def(tabsize):
778
+ if tabsize is undefined:
779
+ tabsize = 8
780
+ string = this
781
+ ans = ''
782
+ col = 0
783
+ for v'var i = 0; i < string.length; i++':
784
+ ch = string[i] # noqa:undef
785
+ if ch is '\t':
786
+ if tabsize > 0:
787
+ spaces = tabsize - (col % tabsize)
788
+ ans += v'new Array(spaces + 1).join(" ")'
789
+ col += spaces
790
+ # tabsize <= 0: tab adds no spaces, col stays
791
+ elif ch is '\n' or ch is '\r':
792
+ ans += ch
793
+ col = 0
794
+ else:
795
+ ans += ch
796
+ col += 1
797
+ return ans
798
+ )
799
+
777
800
  ρσ_str.uchrs = def(string, with_positions):
778
801
  # Return iterator over unicode chars in string. Will yield the unicode
779
802
  # replacement char U+FFFD for broken surrogate pairs
@@ -829,4 +852,12 @@ define_str_func('zfill', def(width):
829
852
  ρσ_str.whitespace = ' \t\n\r\x0b\x0c'
830
853
 
831
854
  v'define_str_func = undefined'
832
- v'var str = ρσ_str, repr = ρσ_repr'
855
+ def ρσ_format(value, spec):
856
+ if value is not None and value is not undefined and v'typeof value.__format__ === "function"':
857
+ return value.__format__(spec if spec is not undefined else '')
858
+ if spec is undefined or spec is '':
859
+ return ρσ_str(value)
860
+ return str.format('{:' + spec + '}', value)
861
+
862
+ ρσ_str.__name__ = 'str'
863
+ v'var str = ρσ_str, repr = ρσ_repr, format = ρσ_format'
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
+