rapydscript-ng 0.7.24 → 0.8.1

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 (132) hide show
  1. package/CHANGELOG.md +28 -0
  2. package/README.md +80 -26
  3. package/bin/build.ts +117 -0
  4. package/bin/package.json +1 -0
  5. package/bin/rapydscript +65 -62
  6. package/build_wheels.py +133 -0
  7. package/editor-plugins/README.md +80 -0
  8. package/editor-plugins/nvim.lua +321 -0
  9. package/local-agent.md +28 -0
  10. package/package.json +4 -5
  11. package/publish.py +27 -17
  12. package/release/baselib-plain-pretty.js +448 -326
  13. package/release/baselib-plain-ugly.js +3 -3
  14. package/release/compiler.js +9027 -8139
  15. package/release/signatures.json +27 -27
  16. package/release/stdlib_modules.json +1 -0
  17. package/src/ast.pyj +428 -280
  18. package/src/baselib-builtins.pyj +49 -28
  19. package/src/baselib-containers.pyj +241 -226
  20. package/src/baselib-errors.pyj +8 -1
  21. package/src/baselib-internal.pyj +38 -23
  22. package/src/baselib-itertools.pyj +13 -7
  23. package/src/baselib-str.pyj +59 -84
  24. package/src/compiler.pyj +4 -4
  25. package/src/errors.pyj +3 -4
  26. package/src/lib/aes.pyj +46 -32
  27. package/src/lib/elementmaker.pyj +11 -9
  28. package/src/lib/encodings.pyj +15 -5
  29. package/src/lib/gettext.pyj +9 -4
  30. package/src/lib/math.pyj +106 -45
  31. package/src/lib/operator.pyj +10 -10
  32. package/src/lib/pythonize.pyj +2 -1
  33. package/src/lib/random.pyj +28 -21
  34. package/src/lib/re.pyj +492 -19
  35. package/src/lib/traceback.pyj +171 -29
  36. package/src/lib/uuid.pyj +2 -2
  37. package/src/output/classes.pyj +28 -27
  38. package/src/output/codegen.pyj +87 -83
  39. package/src/output/comments.pyj +8 -8
  40. package/src/output/exceptions.pyj +20 -21
  41. package/src/output/functions.pyj +66 -64
  42. package/src/output/literals.pyj +24 -23
  43. package/src/output/loops.pyj +84 -142
  44. package/src/output/modules.pyj +55 -68
  45. package/src/output/operators.pyj +40 -29
  46. package/src/output/statements.pyj +21 -15
  47. package/src/output/stream.pyj +82 -56
  48. package/src/output/utils.pyj +12 -8
  49. package/src/parse.pyj +971 -620
  50. package/src/string_interpolation.pyj +5 -3
  51. package/src/tokenizer.pyj +188 -148
  52. package/src/utils.pyj +32 -15
  53. package/test/_treeshake_mod.pyj +30 -0
  54. package/test/_treeshake_side_effect.pyj +9 -0
  55. package/test/ast_serialization.pyj +392 -0
  56. package/test/async.pyj +95 -0
  57. package/test/baselib.pyj +1 -2
  58. package/test/embedded_compiler.pyj +57 -0
  59. package/test/fmt.pyj +291 -0
  60. package/test/generic.pyj +16 -3
  61. package/test/imports.pyj +8 -6
  62. package/test/internationalization.pyj +38 -37
  63. package/test/lint.pyj +120 -117
  64. package/test/lsp.pyj +257 -0
  65. package/test/repl.pyj +70 -65
  66. package/test/sourcemaps.pyj +315 -0
  67. package/test/starargs.pyj +46 -39
  68. package/test/str.pyj +8 -0
  69. package/test/traceback.pyj +263 -0
  70. package/test/treeshaking.pyj +181 -0
  71. package/test/web_repl_export.pyj +88 -0
  72. package/tools/ast_serialize.mjs +557 -0
  73. package/tools/cli.mjs +531 -0
  74. package/tools/compile.mjs +205 -0
  75. package/tools/compiler.mjs +159 -0
  76. package/tools/{completer.js → completer.mjs} +6 -6
  77. package/tools/{embedded_compiler.js → embedded_compiler.mjs} +17 -13
  78. package/tools/export.js +109 -56
  79. package/tools/fmt.mjs +975 -0
  80. package/tools/{gettext.js → gettext.mjs} +46 -53
  81. package/tools/ini.mjs +175 -0
  82. package/tools/{lint.js → lint.mjs} +78 -55
  83. package/tools/lsp.mjs +964 -0
  84. package/tools/lsp_protocol.mjs +259 -0
  85. package/tools/lsp_symbols.mjs +418 -0
  86. package/tools/{msgfmt.js → msgfmt.mjs} +18 -18
  87. package/tools/{repl.js → repl.mjs} +56 -42
  88. package/tools/{self.js → self.mjs} +71 -46
  89. package/tools/sourcemap.mjs +123 -0
  90. package/tools/test.mjs +252 -0
  91. package/tools/treeshake.mjs +400 -0
  92. package/tools/{utils.js → utils.mjs} +26 -23
  93. package/tools/{web_repl.js → web_repl.mjs} +15 -13
  94. package/tools/web_repl_export.mjs +97 -0
  95. package/tree-sitter/README.md +101 -0
  96. package/tree-sitter/grammar.js +992 -0
  97. package/tree-sitter/package.json +43 -0
  98. package/tree-sitter/queries/highlights.scm +232 -0
  99. package/tree-sitter/queries/indents.scm +64 -0
  100. package/tree-sitter/queries/injections.scm +14 -0
  101. package/tree-sitter/queries/locals.scm +108 -0
  102. package/tree-sitter/src/grammar.json +4976 -0
  103. package/tree-sitter/src/node-types.json +2901 -0
  104. package/tree-sitter/src/parser.c +196465 -0
  105. package/tree-sitter/src/scanner.c +294 -0
  106. package/tree-sitter/src/tree_sitter/alloc.h +54 -0
  107. package/tree-sitter/src/tree_sitter/array.h +330 -0
  108. package/tree-sitter/src/tree_sitter/parser.h +286 -0
  109. package/tree-sitter/test/corpus/chaining.txt +99 -0
  110. package/tree-sitter/test/corpus/classes.txt +147 -0
  111. package/tree-sitter/test/corpus/comprehensions.txt +155 -0
  112. package/tree-sitter/test/corpus/containers.txt +242 -0
  113. package/tree-sitter/test/corpus/control_flow.txt +361 -0
  114. package/tree-sitter/test/corpus/decorators.txt +64 -0
  115. package/tree-sitter/test/corpus/existential.txt +102 -0
  116. package/tree-sitter/test/corpus/functions.txt +293 -0
  117. package/tree-sitter/test/corpus/imports.txt +117 -0
  118. package/tree-sitter/test/corpus/literals.txt +135 -0
  119. package/tree-sitter/test/corpus/operators.txt +296 -0
  120. package/tree-sitter/test/corpus/statements.txt +189 -0
  121. package/tree-sitter/test/corpus/strings.txt +90 -0
  122. package/tree-sitter/test/corpus/subscripts.txt +227 -0
  123. package/tree-sitter/tree-sitter.json +36 -0
  124. package/web-repl/env.js +35 -23
  125. package/web-repl/main.js +8 -8
  126. package/bin/export +0 -75
  127. package/bin/web-repl-export +0 -102
  128. package/tools/cli.js +0 -523
  129. package/tools/compile.js +0 -184
  130. package/tools/compiler.js +0 -84
  131. package/tools/ini.js +0 -65
  132. package/tools/test.js +0 -110
@@ -1,13 +1,23 @@
1
1
  # vim:fileencoding=utf-8
2
2
  # License: BSD Copyright: 2016, Kovid Goyal <kovid at kovidgoyal.net>
3
- # globals:regenerate
4
3
  from __python__ import hash_literals
5
4
 
6
- from utils import make_predicate, defaults, repeat_string
7
5
  from tokenizer import is_identifier_char
6
+ from utils import make_predicate, defaults, repeat_string
8
7
 
9
8
  DANGEROUS = /[\u0000\u00ad\u0600-\u0604\u070f\u17b4\u17b5\u200c-\u200f\u2028-\u202f\u2060-\u206f\ufeff\ufff0-\uffff]/g
10
9
 
10
+ # Pre-computed ASCII lookup for identifier characters used in the space-emission
11
+ # hot path. Avoids the full unicode-aware is_identifier_char() for the common case.
12
+ _IDENT_CHARS = v'(function(){var t=new Uint8Array(128),s="abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789_$";for(var i=0;i<s.length;i++)t[s.charCodeAt(i)]=1;return t;})()'
13
+
14
+
15
+ def _is_ident_char(ch):
16
+ code = ch.charCodeAt(0)
17
+ if code < 128:
18
+ return v'_IDENT_CHARS[code]'
19
+ return is_identifier_char(ch)
20
+
11
21
 
12
22
  def as_hex(code, sz):
13
23
  val = code.toString(16)
@@ -17,20 +27,20 @@ def as_hex(code, sz):
17
27
 
18
28
 
19
29
  def to_ascii(str_, identifier):
20
- return str_.replace(/[\u0080-\uffff]/g, def(ch):
30
+ return str_.replace(/[\u0080-\uffff]/g, def (ch):
21
31
  code = ch.charCodeAt(0).toString(16)
22
32
  if code.length <= 2 and not identifier:
23
- return "\\x" + as_hex(code, 2)
33
+ return '\\x' + as_hex(code, 2)
24
34
  else:
25
35
  return '\\u' + as_hex(code, 4)
26
-
27
36
  )
28
37
 
38
+
29
39
  def encode_string(str_):
30
- return JSON.stringify(str_).replace(DANGEROUS, def(a):
40
+ return JSON.stringify(str_).replace(DANGEROUS, def (a):
31
41
  return '\\u' + as_hex(a.charCodeAt(0), 4)
32
42
  )
33
- require_semi_colon_chars = make_predicate("( [ + * / - , .")
43
+ require_semi_colon_chars = make_predicate('( [ + * / - , .')
34
44
 
35
45
  output_stream_defaults = {
36
46
  'indent_start': 0,
@@ -43,6 +53,7 @@ output_stream_defaults = {
43
53
  'ie_proof': True,
44
54
  'beautify': False,
45
55
  'source_map': None,
56
+ 'source_map_line_offset': 0,
46
57
  'bracketize': False,
47
58
  'semicolons': True,
48
59
  'comments': False,
@@ -53,26 +64,34 @@ output_stream_defaults = {
53
64
  'keep_docstrings': False,
54
65
  'discard_asserts': False,
55
66
  'module_cache_dir': '',
56
- 'js_version':5,
67
+ 'js_version': 6,
57
68
  'write_name': True,
58
69
  }
59
70
 
60
- class OutputStream:
61
71
 
72
+ class OutputStream:
62
73
  def __init__(self, options):
63
74
  self.options = defaults(options, output_stream_defaults, True)
64
75
  self._indentation = 0
65
76
  self.current_col = 0
66
77
  self.current_line = 1
67
78
  self.current_pos = 0
68
- self.OUTPUT = ""
79
+ self._fragments = v'[]'
69
80
  self.might_need_space = False
70
81
  self.might_need_semicolon = False
71
82
  self._last = None
72
- self._stack = []
83
+ self._stack = v'[]'
73
84
  self.index_counter = 0
74
85
  self.with_counter = 0
75
86
  self.try_else_counter = 0
87
+ self._source_map_segments = v'[]' if self.options.source_map else None
88
+ # Indentation string cache: avoids repeat_string() on every indent() call
89
+ self._indent_cache_val = -1
90
+ self._indent_cache_str = ''
91
+ # Install no-op add_mapping on the instance when source maps are disabled,
92
+ # avoiding a null check and array push per node in the hot output walk.
93
+ if not self.options.source_map:
94
+ self.add_mapping = def (node): pass
76
95
 
77
96
  def new_try_else_counter(self):
78
97
  self.try_else_counter += 1
@@ -89,7 +108,13 @@ class OutputStream:
89
108
  self.print(self.make_name(name))
90
109
 
91
110
  def make_indent(self, back):
92
- return repeat_string(" ", self.options.indent_start + self._indentation - back * self.options.indent_level)
111
+ target = self.options.indent_start + self._indentation - (back or 0) * self.options.indent_level
112
+ if target == self._indent_cache_val:
113
+ return self._indent_cache_str
114
+ s = repeat_string(' ', target)
115
+ self._indent_cache_val = target
116
+ self._indent_cache_str = s
117
+ return s
93
118
 
94
119
  # -----[ beautification/minification ]-----
95
120
  def last_char(self):
@@ -97,19 +122,19 @@ class OutputStream:
97
122
 
98
123
  def maybe_newline(self):
99
124
  if self.options.max_line_len and self.current_col > self.options.max_line_len:
100
- self.print("\n")
125
+ self.print('\n')
101
126
 
102
127
  def print(self, str_):
103
128
  str_ = v"String(str_)"
104
129
  ch = str_.charAt(0)
105
130
  if self.might_need_semicolon:
106
- if (not ch or ";}".indexOf(ch) < 0) and not /[;]$/.test(self._last):
131
+ if (not ch or ';}'.indexOf(ch) < 0) and not /[;]$/.test(self._last):
107
132
  if self.options.semicolons or require_semi_colon_chars[ch]:
108
- self.OUTPUT += ";"
133
+ self._fragments.push(';')
109
134
  self.current_col += 1
110
135
  self.current_pos += 1
111
136
  else:
112
- self.OUTPUT += "\n"
137
+ self._fragments.push('\n')
113
138
  self.current_pos += 1
114
139
  self.current_line += 1
115
140
  self.current_col = 0
@@ -117,41 +142,41 @@ class OutputStream:
117
142
  if not self.options.beautify:
118
143
  self.might_need_space = False
119
144
 
120
-
121
145
  self.might_need_semicolon = False
122
146
  self.maybe_newline()
123
147
 
124
148
  if not self.options.beautify and self.options.preserve_line and self._stack[self._stack.length - 1]:
125
149
  target_line = self._stack[self._stack.length - 1].start.line
126
150
  while self.current_line < target_line:
127
- self.OUTPUT += "\n"
151
+ self._fragments.push('\n')
128
152
  self.current_pos += 1
129
153
  self.current_line += 1
130
154
  self.current_col = 0
131
155
  self.might_need_space = False
132
156
 
133
-
134
157
  if self.might_need_space:
135
158
  prev = self.last_char()
136
- if is_identifier_char(prev) and (is_identifier_char(ch) or ch is "\\")
159
+ if _is_ident_char(prev) and (_is_ident_char(ch) or ch is '\\')
137
160
  or /^[\+\-\/]$/.test(ch) and ch is prev:
138
- self.OUTPUT += " "
161
+ self._fragments.push(' ')
139
162
  self.current_col += 1
140
163
  self.current_pos += 1
141
164
 
142
165
  self.might_need_space = False
143
166
 
144
- a = str_.split(/\r?\n/)
145
- n = a.length - 1
146
- self.current_line += n
147
- if n is 0:
148
- self.current_col += a[n].length
167
+ # Fast path: no newlines (the vast majority of tokens).
168
+ # Avoids regex allocation and array creation for single-line fragments.
169
+ self.current_pos += str_.length
170
+ if str_.indexOf('\n') < 0:
171
+ self.current_col += str_.length
149
172
  else:
150
- self.current_col = a[n].length
173
+ a = str_.split('\n')
174
+ n = a.length - 1
175
+ self.current_line += n
176
+ self.current_col = v'a[n].length'
151
177
 
152
- self.current_pos += str_.length
153
178
  self._last = str_
154
- self.OUTPUT += str_
179
+ self._fragments.push(str_)
155
180
 
156
181
  def space(self):
157
182
  if self.options.beautify:
@@ -185,17 +210,17 @@ class OutputStream:
185
210
 
186
211
  def newline(self):
187
212
  if self.options.beautify:
188
- self.print("\n")
213
+ self.print('\n')
189
214
 
190
215
  def semicolon(self):
191
216
  if self.options.beautify:
192
- self.print(";")
217
+ self.print(';')
193
218
  else:
194
219
  self.might_need_semicolon = True
195
220
 
196
221
  def force_semicolon(self):
197
222
  self.might_need_semicolon = False
198
- self.print(";")
223
+ self.print(';')
199
224
 
200
225
  def next_indent(self):
201
226
  return self._indentation + self.options.indent_level
@@ -215,61 +240,49 @@ class OutputStream:
215
240
 
216
241
  def with_block(self, cont):
217
242
  ret = None
218
- self.print("{")
243
+ self.print('{')
219
244
  self.newline()
220
- self.with_indent(self.next_indent(), def():
245
+ self.with_indent(self.next_indent(), def ():
221
246
  nonlocal ret
222
247
  ret = cont()
223
248
  )
224
249
  self.indent()
225
- self.print("}")
250
+ self.print('}')
226
251
  return ret
227
252
 
228
253
  def with_parens(self, cont):
229
- self.print("(")
254
+ self.print('(')
230
255
  ret = cont()
231
- self.print(")")
256
+ self.print(')')
232
257
  return ret
233
258
 
234
259
  def with_square(self, cont):
235
- self.print("[")
260
+ self.print('[')
236
261
  ret = cont()
237
- self.print("]")
262
+ self.print(']')
238
263
  return ret
239
264
 
240
265
  def comma(self):
241
- self.print(",")
266
+ self.print(',')
242
267
  self.space()
243
268
 
244
269
  def colon(self):
245
- self.print(":")
270
+ self.print(':')
246
271
  if self.options.space_colon:
247
272
  self.space()
248
273
 
249
- def dump_yield(self):
250
- self.indent()
251
- self.spaced('var', 'ρσ_regenerator', '=', '{}')
252
- self.end_statement()
253
- code = 'ρσ_regenerator.regeneratorRuntime = ' + regenerate(False, self.options.beautify)
254
- if self.options.beautify:
255
- code = code.replace(/\/\/.*$/mg, '\n').replace(/^\s*$/gm, '') # strip comments
256
- ci = self.make_indent(0)
257
- code = [ci + x for x in code.split('\n')].join('\n')
258
- self.print(code + '})(ρσ_regenerator)')
259
- self.end_statement()
260
-
261
274
  def get(self):
262
- return self.OUTPUT
275
+ return self._fragments.join('')
263
276
  toString = get
264
277
 
265
278
  def assign(self, name):
266
279
  # generates: '[name] = '
267
- if jstype(name) is "string":
280
+ if jstype(name) is 'string':
268
281
  self.print(name)
269
282
  else:
270
283
  name.print(self)
271
284
  self.space()
272
- self.print("=")
285
+ self.print('=')
273
286
  self.space()
274
287
 
275
288
  def current_width(self):
@@ -304,3 +317,16 @@ class OutputStream:
304
317
 
305
318
  def parent(self, n):
306
319
  return self._stack[self._stack.length - 2 - (n or 0)]
320
+
321
+ def add_mapping(self, node):
322
+ if self._source_map_segments is not None and node.start and node.start.file:
323
+ self._source_map_segments.push(v'[self.current_line - 1 + self.options.source_map_line_offset, self.current_col, node.start.file, node.start.line - 1, node.start.col]')
324
+
325
+ def add_cached_mappings(self, segments, line_offset):
326
+ if self._source_map_segments is None:
327
+ return
328
+ for seg in segments:
329
+ self._source_map_segments.push(v'[seg[0] + line_offset, seg[1], seg[2], seg[3], seg[4]]')
330
+
331
+ def get_source_map_segments(self):
332
+ return self._source_map_segments
@@ -4,6 +4,7 @@ from __python__ import hash_literals
4
4
 
5
5
  from ast import AST_BlockStatement, is_node_type
6
6
 
7
+
7
8
  def best_of(a):
8
9
  best = a[0]
9
10
  len_ = best.length
@@ -13,38 +14,41 @@ def best_of(a):
13
14
  len_ = best.length
14
15
  return best
15
16
 
17
+
16
18
  def make_num(num):
17
19
  str_ = num.toString(10)
18
- a = [ str_.replace(/^0\./, ".").replace("e+", "e") ]
20
+ a = [str_.replace(/^0\./, '.').replace('e+', 'e')]
19
21
  m = None
20
22
 
21
23
  if Math.floor(num) is num:
22
24
  if num >= 0:
23
- a.push("0x" + num.toString(16).toLowerCase(), # probably pointless
24
- "0" + num.toString(8))
25
+ a.push('0x' + num.toString(16).toLowerCase(), # probably pointless
26
+ '0' + num.toString(8))
25
27
  else:
26
- a.push("-0x" + (-num).toString(16).toLowerCase(), # probably pointless
27
- "-0" + (-num).toString(8))
28
+ a.push('-0x' + (-num).toString(16).toLowerCase(), # probably pointless
29
+ '-0' + (-num).toString(8))
28
30
 
29
31
  if m = /^(.*?)(0+)$/.exec(num):
30
- a.push(m[1] + "e" + m[2].length)
32
+ a.push(m[1] + 'e' + m[2].length)
31
33
 
32
34
  elif m = /^0?\.(0+)(.*)$/.exec(num):
33
- a.push(m[2] + "e-" + (m[1].length + m[2].length), str_.substr(str_.indexOf(".")))
35
+ a.push(m[2] + 'e-' + (m[1].length + m[2].length), str_.substr(str_.indexOf('.')))
34
36
 
35
37
  return best_of(a)
36
38
 
39
+
37
40
  def make_block(stmt, output):
38
41
  if is_node_type(stmt, AST_BlockStatement):
39
42
  stmt.print(output)
40
43
  return
41
44
 
42
- output.with_block(def():
45
+ output.with_block(def ():
43
46
  output.indent()
44
47
  stmt.print(output)
45
48
  output.newline()
46
49
  )
47
50
 
51
+
48
52
  def create_doctring(docstrings):
49
53
  ans = v'[]'
50
54
  for ds in docstrings: