rapydscript-ng 0.8.3 → 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.
- package/CHANGELOG.md +6 -0
- package/bin/build.ts +29 -0
- package/package.json +1 -1
- package/release/baselib-plain-pretty.js +85 -61
- package/release/baselib-plain-ugly.js +3 -3
- package/release/compiler.js +2543 -2432
- package/release/signatures.json +26 -26
- package/src/ast.pyj +170 -58
- package/src/baselib-builtins.pyj +35 -14
- package/src/baselib-containers.pyj +70 -40
- package/src/baselib-internal.pyj +20 -8
- package/src/baselib-itertools.pyj +6 -2
- package/src/baselib-str.pyj +74 -28
- package/src/errors.pyj +4 -1
- package/src/lib/aes.pyj +664 -35
- package/src/lib/elementmaker.pyj +105 -13
- package/src/lib/encodings.pyj +31 -7
- package/src/lib/gettext.pyj +6 -3
- package/src/lib/math.pyj +38 -22
- package/src/lib/pythonize.pyj +5 -3
- package/src/lib/random.pyj +13 -5
- package/src/lib/re.pyj +81 -18
- package/src/lib/traceback.pyj +42 -10
- package/src/lib/uuid.pyj +2 -1
- package/src/output/classes.pyj +70 -26
- package/src/output/codegen.pyj +92 -20
- package/src/output/comments.pyj +11 -4
- package/src/output/exceptions.pyj +17 -4
- package/src/output/functions.pyj +34 -13
- package/src/output/literals.pyj +7 -2
- package/src/output/loops.pyj +50 -16
- package/src/output/modules.pyj +41 -12
- package/src/output/operators.pyj +154 -31
- package/src/output/statements.pyj +38 -10
- package/src/output/stream.pyj +43 -12
- package/src/output/utils.pyj +10 -3
- package/src/parse.pyj +740 -259
- package/src/string_interpolation.pyj +4 -1
- package/src/tokenizer.pyj +300 -55
- package/src/unicode_aliases.pyj +4 -2
- package/src/utils.pyj +19 -5
- package/test/functions.pyj +8 -0
- package/test/generic.pyj +9 -0
- package/test/lsp.pyj +16 -0
- package/tools/compiler.mjs +0 -6
- package/tools/fmt.mjs +41 -2
- package/tools/lint-worker.mjs +7 -1
- package/tools/lint.mjs +12 -5
- package/tools/lsp.mjs +11 -1
package/src/output/loops.pyj
CHANGED
|
@@ -2,7 +2,10 @@
|
|
|
2
2
|
# License: BSD Copyright: 2016, Kovid Goyal <kovid at kovidgoyal.net>
|
|
3
3
|
from __python__ import hash_literals
|
|
4
4
|
|
|
5
|
-
from ast import
|
|
5
|
+
from ast import (
|
|
6
|
+
AST_BaseCall, AST_SymbolRef, AST_Array, AST_Unary, AST_Number,
|
|
7
|
+
has_calls, AST_Seq, AST_ListComprehension, is_node_type
|
|
8
|
+
)
|
|
6
9
|
|
|
7
10
|
|
|
8
11
|
def unpack_tuple(elems, output, in_statement):
|
|
@@ -41,21 +44,28 @@ def is_simple_for_in(self):
|
|
|
41
44
|
# return true if this loop can be simplified into a basic for (i in j) loop
|
|
42
45
|
if is_node_type(self.object, AST_BaseCall)
|
|
43
46
|
and is_node_type(self.object.expression, AST_SymbolRef)
|
|
44
|
-
and self.object.expression.name is 'dir'
|
|
47
|
+
and self.object.expression.name is 'dir'
|
|
48
|
+
and self.object.args.args.length is 1:
|
|
45
49
|
return True
|
|
46
50
|
return False
|
|
47
51
|
|
|
48
52
|
|
|
49
53
|
def is_simple_for(self):
|
|
50
|
-
# returns true if this loop can be simplified into a
|
|
54
|
+
# returns true if this loop can be simplified into a
|
|
55
|
+
# basic for(i=n;i<h;i++) loop
|
|
51
56
|
if (is_node_type(self.object, AST_BaseCall) and
|
|
52
57
|
is_node_type(self.object.expression, AST_SymbolRef) and
|
|
53
58
|
self.object.expression.name is 'range' and
|
|
54
59
|
not (is_node_type(self.init, AST_Array))):
|
|
55
60
|
a = self.object.args.args
|
|
56
61
|
l = a.length
|
|
57
|
-
if l < 3 or (
|
|
58
|
-
|
|
62
|
+
if (l < 3 or (
|
|
63
|
+
is_node_type(a[2].value, AST_Number) or (
|
|
64
|
+
is_node_type(a[2].value, AST_Unary) and
|
|
65
|
+
a[2].value.operator is '-' and
|
|
66
|
+
is_node_type(a[2].value.expression, AST_Number)))):
|
|
67
|
+
if ((l is 1 and not has_calls(a[0].value)) or
|
|
68
|
+
(l > 1 and not has_calls(a[1].value))):
|
|
59
69
|
return True
|
|
60
70
|
return False
|
|
61
71
|
|
|
@@ -150,13 +160,18 @@ def print_for_in(self, output):
|
|
|
150
160
|
output.space()
|
|
151
161
|
output.print(idx)
|
|
152
162
|
output.space()
|
|
153
|
-
|
|
163
|
+
if is_node_type(increment, AST_Unary):
|
|
164
|
+
output.print('>')
|
|
165
|
+
else:
|
|
166
|
+
output.print('<')
|
|
154
167
|
output.space()
|
|
155
168
|
end.print(output)
|
|
156
169
|
output.semicolon()
|
|
157
170
|
output.space()
|
|
158
171
|
output.print(idx)
|
|
159
|
-
if increment and (
|
|
172
|
+
if (increment and (
|
|
173
|
+
not (is_node_type(increment, AST_Unary)) or
|
|
174
|
+
increment.expression.value is not '1')):
|
|
160
175
|
if is_node_type(increment, AST_Unary):
|
|
161
176
|
output.print('-=')
|
|
162
177
|
increment.expression.print(output)
|
|
@@ -204,7 +219,9 @@ def print_list_comprehension(self, output):
|
|
|
204
219
|
tname = self.constructor.name.slice(4)
|
|
205
220
|
result_obj = {
|
|
206
221
|
'ListComprehension': '[]',
|
|
207
|
-
'DictComprehension': (
|
|
222
|
+
'DictComprehension': (
|
|
223
|
+
'Object.create(null)' if self.is_jshash else '{}'
|
|
224
|
+
),
|
|
208
225
|
'SetComprehension': 'ρσ_set()',
|
|
209
226
|
}[tname]
|
|
210
227
|
is_generator = tname is 'GeneratorComprehension'
|
|
@@ -219,7 +236,9 @@ def print_list_comprehension(self, output):
|
|
|
219
236
|
output.space(), output.print(','), output.space()
|
|
220
237
|
output.with_parens(def ():
|
|
221
238
|
if self.value_statement.constructor is AST_Seq:
|
|
222
|
-
output.with_square(def ():
|
|
239
|
+
output.with_square(def ():
|
|
240
|
+
self.value_statement.print(output)
|
|
241
|
+
)
|
|
223
242
|
else:
|
|
224
243
|
self.value_statement.print(output)
|
|
225
244
|
)
|
|
@@ -235,13 +254,18 @@ def print_list_comprehension(self, output):
|
|
|
235
254
|
output.space(), output.print('='), output.space()
|
|
236
255
|
output.with_parens(def ():
|
|
237
256
|
if self.value_statement.constructor is AST_Seq:
|
|
238
|
-
output.with_square(def ():
|
|
257
|
+
output.with_square(def ():
|
|
258
|
+
self.value_statement.print(output)
|
|
259
|
+
)
|
|
239
260
|
else:
|
|
240
261
|
self.value_statement.print(output)
|
|
241
262
|
)
|
|
242
263
|
output.end_statement()
|
|
243
264
|
else:
|
|
244
|
-
push_func = 'ρσ_Result.' + (
|
|
265
|
+
push_func = 'ρσ_Result.' + (
|
|
266
|
+
'push' if self.constructor is AST_ListComprehension
|
|
267
|
+
else 'add'
|
|
268
|
+
)
|
|
245
269
|
if is_generator:
|
|
246
270
|
push_func = 'yield '
|
|
247
271
|
add_to_result = def (output):
|
|
@@ -263,7 +287,9 @@ def print_list_comprehension(self, output):
|
|
|
263
287
|
body_out = output
|
|
264
288
|
if is_generator:
|
|
265
289
|
body_out.indent()
|
|
266
|
-
body_out.print('function* js_generator()')
|
|
290
|
+
body_out.print('function* js_generator()')
|
|
291
|
+
body_out.space()
|
|
292
|
+
body_out.print('{')
|
|
267
293
|
body_out.newline()
|
|
268
294
|
previous_indentation = output.indentation()
|
|
269
295
|
output.set_indentation(output.next_indent())
|
|
@@ -311,7 +337,9 @@ def print_list_comprehension(self, output):
|
|
|
311
337
|
body_out.indent()
|
|
312
338
|
body_out.print('if')
|
|
313
339
|
body_out.space()
|
|
314
|
-
body_out.with_parens(def ():
|
|
340
|
+
body_out.with_parens(def ():
|
|
341
|
+
self.condition.print(body_out)
|
|
342
|
+
)
|
|
315
343
|
body_out.space()
|
|
316
344
|
body_out.with_block(def ():
|
|
317
345
|
add_to_result(body_out)
|
|
@@ -323,7 +351,10 @@ def print_list_comprehension(self, output):
|
|
|
323
351
|
body_out.newline()
|
|
324
352
|
if self.constructor is AST_ListComprehension:
|
|
325
353
|
body_out.indent()
|
|
326
|
-
body_out.spaced(
|
|
354
|
+
body_out.spaced(
|
|
355
|
+
'ρσ_Result', '=',
|
|
356
|
+
'ρσ_list_constructor(ρσ_Result)'
|
|
357
|
+
)
|
|
327
358
|
body_out.end_statement()
|
|
328
359
|
if not is_generator:
|
|
329
360
|
body_out.indent()
|
|
@@ -331,11 +362,14 @@ def print_list_comprehension(self, output):
|
|
|
331
362
|
body_out.end_statement()
|
|
332
363
|
if is_generator:
|
|
333
364
|
output.set_indentation(previous_indentation)
|
|
334
|
-
body_out.newline()
|
|
365
|
+
body_out.newline()
|
|
366
|
+
body_out.indent()
|
|
367
|
+
body_out.print('}') # end js_generator
|
|
335
368
|
output.newline(), output.indent()
|
|
336
369
|
output.spaced('var', 'result', '=', 'js_generator.call(this)')
|
|
337
370
|
output.end_statement()
|
|
338
|
-
# Python's generator objects use a separate method to
|
|
371
|
+
# Python's generator objects use a separate method to
|
|
372
|
+
# send data to the generator
|
|
339
373
|
output.indent()
|
|
340
374
|
output.spaced('result.send', '=', 'result.next')
|
|
341
375
|
output.end_statement()
|
package/src/output/modules.pyj
CHANGED
|
@@ -42,7 +42,8 @@ def write_imports(module, output):
|
|
|
42
42
|
output.print('ρσ_modules.' + module_id)
|
|
43
43
|
else:
|
|
44
44
|
output.print('ρσ_modules["' + module_id + '"]')
|
|
45
|
-
output.space(), output.print('=')
|
|
45
|
+
output.space(), output.print('=')
|
|
46
|
+
output.space(), output.print('{}')
|
|
46
47
|
output.end_statement()
|
|
47
48
|
|
|
48
49
|
# Output module code
|
|
@@ -63,7 +64,8 @@ def write_main_name(output):
|
|
|
63
64
|
|
|
64
65
|
def const_decl(js_version):
|
|
65
66
|
# return 'const' if js_version > 5 else 'var'
|
|
66
|
-
# Workaround for bug in Chrome eval(). eval() barfs if it sees const
|
|
67
|
+
# Workaround for bug in Chrome eval(). eval() barfs if it sees const
|
|
68
|
+
# before a function.
|
|
67
69
|
# See https://github.com/kovidgoyal/rapydscript-ng/issues/29
|
|
68
70
|
return 'var'
|
|
69
71
|
|
|
@@ -74,7 +76,8 @@ def declare_exports(module_id, exports, output, docstrings):
|
|
|
74
76
|
exports.push({'name': '__doc__', 'refname': 'ρσ_module_doc__'})
|
|
75
77
|
output.newline(), output.indent()
|
|
76
78
|
v = const_decl(output.options.js_version)
|
|
77
|
-
output.assign(v + ' ρσ_module_doc__')
|
|
79
|
+
output.assign(v + ' ρσ_module_doc__')
|
|
80
|
+
output.print(JSON.stringify(create_doctring(docstrings)))
|
|
78
81
|
output.end_statement()
|
|
79
82
|
output.newline()
|
|
80
83
|
for symbol in exports:
|
|
@@ -84,7 +87,8 @@ def declare_exports(module_id, exports, output, docstrings):
|
|
|
84
87
|
output.print('ρσ_modules.' + module_id + '.' + symbol.name)
|
|
85
88
|
else:
|
|
86
89
|
output.print('ρσ_modules["' + module_id + '"].' + symbol.name)
|
|
87
|
-
output.space(), output.print('=')
|
|
90
|
+
output.space(), output.print('=')
|
|
91
|
+
output.space(), output.print(symbol.refname or symbol.name)
|
|
88
92
|
seen[symbol.name] = True
|
|
89
93
|
output.end_statement()
|
|
90
94
|
|
|
@@ -98,17 +102,36 @@ def prologue(module, output):
|
|
|
98
102
|
output.print(v), output.space()
|
|
99
103
|
output.spaced.apply(
|
|
100
104
|
output,
|
|
101
|
-
((
|
|
105
|
+
((
|
|
106
|
+
'ρσ_iterator_symbol = (typeof Symbol === "function"' +
|
|
107
|
+
' && typeof Symbol.iterator === "symbol") ?' +
|
|
108
|
+
' Symbol.iterator : "iterator-Symbol-' +
|
|
109
|
+
'5d0927e5554349048cf0e3762a228256"'
|
|
110
|
+
).split(' '))
|
|
102
111
|
)
|
|
103
112
|
output.end_statement()
|
|
104
113
|
output.indent(), output.print(v), output.space()
|
|
105
114
|
output.spaced.apply(
|
|
106
115
|
output,
|
|
107
|
-
((
|
|
116
|
+
((
|
|
117
|
+
'ρσ_kwargs_symbol = (typeof Symbol === "function") ?' +
|
|
118
|
+
' Symbol("kwargs-object") : "kwargs-object-Symbol-' +
|
|
119
|
+
'5d0927e5554349048cf0e3762a228256"'
|
|
120
|
+
).split(' '))
|
|
108
121
|
)
|
|
109
122
|
output.end_statement()
|
|
110
|
-
output.indent(), output.spaced(
|
|
111
|
-
|
|
123
|
+
output.indent(), output.spaced(
|
|
124
|
+
'var',
|
|
125
|
+
'ρσ_cond_temp,',
|
|
126
|
+
'ρσ_expr_temp,',
|
|
127
|
+
'ρσ_last_exception'
|
|
128
|
+
), output.end_statement()
|
|
129
|
+
output.indent(), output.spaced(
|
|
130
|
+
'var',
|
|
131
|
+
'ρσ_object_counter',
|
|
132
|
+
'=',
|
|
133
|
+
'0'
|
|
134
|
+
), output.end_statement()
|
|
112
135
|
# Needed for Chrome < 51 and Edge as of August 2016
|
|
113
136
|
output.indent(), output.spaced(
|
|
114
137
|
'if(',
|
|
@@ -132,7 +155,10 @@ def prologue(module, output):
|
|
|
132
155
|
output.end_statement()
|
|
133
156
|
# output the baselib
|
|
134
157
|
if not output.options.baselib_plain:
|
|
135
|
-
raise ValueError(
|
|
158
|
+
raise ValueError(
|
|
159
|
+
'The baselib is missing! Remember to set the' +
|
|
160
|
+
' baselib_plain field on the options for OutputStream'
|
|
161
|
+
)
|
|
136
162
|
output.print(output.options.baselib_plain)
|
|
137
163
|
output.end_statement()
|
|
138
164
|
|
|
@@ -142,17 +168,20 @@ def print_top_level(self, output):
|
|
|
142
168
|
is_main = self.module_id is '__main__'
|
|
143
169
|
|
|
144
170
|
def write_docstrings():
|
|
145
|
-
if is_main and output.options.keep_docstrings
|
|
171
|
+
if (is_main and output.options.keep_docstrings
|
|
172
|
+
and self.docstrings and self.docstrings.length):
|
|
146
173
|
output.newline(), output.indent()
|
|
147
174
|
v = const_decl(output.options.js_version)
|
|
148
|
-
output.assign(v + ' ρσ_module_doc__')
|
|
175
|
+
output.assign(v + ' ρσ_module_doc__')
|
|
176
|
+
output.print(JSON.stringify(create_doctring(self.docstrings)))
|
|
149
177
|
output.end_statement()
|
|
150
178
|
|
|
151
179
|
if output.options.private_scope and is_main:
|
|
152
180
|
output.with_parens(def ():
|
|
153
181
|
output.print('function()')
|
|
154
182
|
output.with_block(def ():
|
|
155
|
-
# strict mode is more verbose about errors, and less
|
|
183
|
+
# strict mode is more verbose about errors, and less
|
|
184
|
+
# forgiving about them
|
|
156
185
|
# kind of like Python
|
|
157
186
|
output.indent()
|
|
158
187
|
output.print('"use strict"')
|
package/src/output/operators.pyj
CHANGED
|
@@ -26,11 +26,18 @@ def print_getattr(self, output, skip_expression): # AST_Dot
|
|
|
26
26
|
def print_getitem(self, output): # AST_Sub
|
|
27
27
|
expr = self.expression
|
|
28
28
|
prop = self.property
|
|
29
|
-
if (
|
|
29
|
+
if (
|
|
30
|
+
is_node_type(prop, AST_Number) or is_node_type(prop, AST_String)
|
|
31
|
+
or (is_node_type(prop, AST_SymbolRef) and prop.name
|
|
32
|
+
and prop.name.startsWith('ρσ_'))
|
|
33
|
+
):
|
|
30
34
|
expr.print(output)
|
|
31
35
|
output.print('['), prop.print(output), output.print(']')
|
|
32
36
|
return
|
|
33
|
-
is_negative_number =
|
|
37
|
+
is_negative_number = (
|
|
38
|
+
is_node_type(prop, AST_Unary) and prop.operator is '-'
|
|
39
|
+
and is_node_type(prop.expression, AST_Number)
|
|
40
|
+
)
|
|
34
41
|
is_repeatable = is_node_type(expr, AST_SymbolRef)
|
|
35
42
|
if is_repeatable:
|
|
36
43
|
expr.print(output)
|
|
@@ -39,17 +46,27 @@ def print_getitem(self, output): # AST_Sub
|
|
|
39
46
|
expr = {'print': def (): output.print('ρσ_expr_temp');}
|
|
40
47
|
|
|
41
48
|
if is_negative_number:
|
|
42
|
-
output.print('['), expr.print(output)
|
|
49
|
+
output.print('['), expr.print(output)
|
|
50
|
+
output.print('.length'), prop.print(output)
|
|
51
|
+
output.print(']')
|
|
43
52
|
return
|
|
44
53
|
is_repeatable = is_node_type(prop, AST_SymbolRef)
|
|
45
54
|
# We have to check the type of the property because if it is a Symbol, it
|
|
46
55
|
# will raise a TypeError with the < operator.
|
|
47
56
|
if is_repeatable:
|
|
48
57
|
output.spaced('[(typeof', prop, '===', '"number"', '&&', prop)
|
|
49
|
-
output.spaced(
|
|
58
|
+
output.spaced(
|
|
59
|
+
'',
|
|
60
|
+
'<',
|
|
61
|
+
'0)',
|
|
62
|
+
'?',
|
|
63
|
+
expr
|
|
64
|
+
), output.spaced('.length', '+', prop, ':', prop)
|
|
50
65
|
output.print(']')
|
|
51
66
|
else:
|
|
52
|
-
output.print('[ρσ_bound_index(')
|
|
67
|
+
output.print('[ρσ_bound_index(')
|
|
68
|
+
prop.print(output), output.comma(), expr.print(output)
|
|
69
|
+
output.print(')]')
|
|
53
70
|
|
|
54
71
|
|
|
55
72
|
def print_rich_getitem(self, output): # AST_ItemAccess
|
|
@@ -74,7 +91,8 @@ def print_rich_getitem(self, output): # AST_ItemAccess
|
|
|
74
91
|
def print_splice_assignment(self, output): # AST_Splice
|
|
75
92
|
# splice assignment via pythonic array[start:end]
|
|
76
93
|
output.print('ρσ_splice(')
|
|
77
|
-
self.expression.print(output), output.comma()
|
|
94
|
+
self.expression.print(output), output.comma()
|
|
95
|
+
self.assignment.print(output), output.comma()
|
|
78
96
|
self.property.print(output) if self.property else output.print('0')
|
|
79
97
|
if self.property2:
|
|
80
98
|
output.comma()
|
|
@@ -86,7 +104,9 @@ def print_delete(self, output):
|
|
|
86
104
|
if is_node_type(self, AST_Symbol):
|
|
87
105
|
output.assign(self), output.print('undefined')
|
|
88
106
|
elif is_node_type(self, AST_Sub) or is_node_type(self, AST_ItemAccess):
|
|
89
|
-
output.print('ρσ_delitem(')
|
|
107
|
+
output.print('ρσ_delitem(')
|
|
108
|
+
self.expression.print(output), output.comma()
|
|
109
|
+
self.property.print(output), output.print(')')
|
|
90
110
|
else:
|
|
91
111
|
output.spaced('delete', self)
|
|
92
112
|
|
|
@@ -122,28 +142,61 @@ def write_instanceof(left, right, output):
|
|
|
122
142
|
do_many(right.elements)
|
|
123
143
|
else:
|
|
124
144
|
output.print('ρσ_instanceof(')
|
|
125
|
-
left.print(output), output.comma()
|
|
145
|
+
left.print(output), output.comma()
|
|
146
|
+
right.print(output), output.print(')')
|
|
126
147
|
|
|
127
148
|
|
|
128
149
|
def write_smart_equality(self, output):
|
|
129
150
|
def is_ok(x):
|
|
130
151
|
return not (
|
|
131
|
-
is_node_type(x, AST_Array) or is_node_type(x, AST_Set)
|
|
132
|
-
|
|
152
|
+
is_node_type(x, AST_Array) or is_node_type(x, AST_Set)
|
|
153
|
+
or is_node_type(x, AST_Object) or is_node_type(x, AST_Statement)
|
|
154
|
+
or is_node_type(x, AST_Binary)
|
|
155
|
+
or is_node_type(x, AST_Conditional)
|
|
133
156
|
or is_node_type(x, AST_BaseCall)
|
|
134
157
|
)
|
|
135
158
|
if is_ok(self.left) and is_ok(self.right):
|
|
136
159
|
if self.operator is '==':
|
|
137
160
|
output.print('(')
|
|
138
|
-
output.spaced(
|
|
139
|
-
|
|
161
|
+
output.spaced(
|
|
162
|
+
self.left,
|
|
163
|
+
'===',
|
|
164
|
+
self.right,
|
|
165
|
+
'||',
|
|
166
|
+
'typeof',
|
|
167
|
+
self.left,
|
|
168
|
+
'===',
|
|
169
|
+
'"object"',
|
|
170
|
+
'&&',
|
|
171
|
+
'ρσ_equals('
|
|
172
|
+
)
|
|
173
|
+
self.left.print(output), output.print(',')
|
|
174
|
+
output.space(), self.right.print(output)
|
|
175
|
+
output.print('))')
|
|
140
176
|
else:
|
|
141
177
|
output.print('(')
|
|
142
|
-
output.spaced(
|
|
143
|
-
|
|
178
|
+
output.spaced(
|
|
179
|
+
self.left,
|
|
180
|
+
'!==',
|
|
181
|
+
self.right,
|
|
182
|
+
'&&',
|
|
183
|
+
'(typeof',
|
|
184
|
+
self.left,
|
|
185
|
+
'!==',
|
|
186
|
+
'"object"',
|
|
187
|
+
'||',
|
|
188
|
+
'ρσ_not_equals('
|
|
189
|
+
)
|
|
190
|
+
self.left.print(output), output.print(',')
|
|
191
|
+
output.space(), self.right.print(output)
|
|
192
|
+
output.print(')))')
|
|
144
193
|
else:
|
|
145
|
-
output.print(
|
|
146
|
-
|
|
194
|
+
output.print(
|
|
195
|
+
'ρσ_' + ('equals(' if self.operator is '==' else 'not_equals(')
|
|
196
|
+
)
|
|
197
|
+
self.left.print(output), output.print(',')
|
|
198
|
+
output.space(), self.right.print(output)
|
|
199
|
+
output.print(')')
|
|
147
200
|
|
|
148
201
|
|
|
149
202
|
comparators = {
|
|
@@ -167,7 +220,10 @@ def print_binary_op(self, output):
|
|
|
167
220
|
output.comma()
|
|
168
221
|
self.right.print(output)
|
|
169
222
|
)
|
|
170
|
-
elif comparators[self.operator] and is_node_type(
|
|
223
|
+
elif comparators[self.operator] and is_node_type(
|
|
224
|
+
self.left,
|
|
225
|
+
AST_Binary
|
|
226
|
+
) and comparators[self.left.operator]:
|
|
171
227
|
# A chained comparison such as a < b < c
|
|
172
228
|
if is_node_type(self.left.right, AST_Symbol):
|
|
173
229
|
# left side compares against a regular variable,
|
|
@@ -210,15 +266,22 @@ def print_binary_op(self, output):
|
|
|
210
266
|
left = self.left.expression
|
|
211
267
|
output.print(self.left.operator)
|
|
212
268
|
if output.options.js_version > 6:
|
|
213
|
-
output.print('(('), left.print(output), output.spaced(
|
|
269
|
+
output.print('(('), left.print(output), output.spaced(
|
|
270
|
+
')',
|
|
271
|
+
'**',
|
|
272
|
+
'('
|
|
273
|
+
), self.right.print(output), output.print('))')
|
|
214
274
|
else:
|
|
215
|
-
output.print('Math.pow('), left.print(output)
|
|
275
|
+
output.print('Math.pow('), left.print(output)
|
|
276
|
+
output.comma(), self.right.print(output)
|
|
277
|
+
output.print(')')
|
|
216
278
|
elif self.operator is '==' or self.operator is '!=':
|
|
217
279
|
write_smart_equality(self, output)
|
|
218
280
|
elif self.operator is 'instanceof':
|
|
219
281
|
write_instanceof(self.left, self.right, output)
|
|
220
282
|
elif self.operator is '*' and is_node_type(self.left, AST_String):
|
|
221
|
-
self.left.print(output), output.print('.repeat(')
|
|
283
|
+
self.left.print(output), output.print('.repeat(')
|
|
284
|
+
self.right.print(output), output.print(')')
|
|
222
285
|
elif self.operator is '===' or self.operator is '!==':
|
|
223
286
|
nan_check = None
|
|
224
287
|
if is_node_type(self.right, AST_Symbol) and self.right.name is 'NaN':
|
|
@@ -228,7 +291,11 @@ def print_binary_op(self, output):
|
|
|
228
291
|
if nan_check is not None:
|
|
229
292
|
# We use the fact that NaN is the only object that is not equal to
|
|
230
293
|
# itself
|
|
231
|
-
output.spaced(
|
|
294
|
+
output.spaced(
|
|
295
|
+
nan_check,
|
|
296
|
+
'!==' if self.operator is '===' else '===',
|
|
297
|
+
nan_check
|
|
298
|
+
)
|
|
232
299
|
else:
|
|
233
300
|
output.spaced(self.left, self.operator, self.right)
|
|
234
301
|
else:
|
|
@@ -238,20 +305,54 @@ after_map = {'.': 'd', '(': 'c', '[': 'd', 'g': 'g', 'null': 'n'}
|
|
|
238
305
|
|
|
239
306
|
|
|
240
307
|
def print_existential(self, output):
|
|
241
|
-
key =
|
|
308
|
+
key = (
|
|
309
|
+
after_map[self.after]
|
|
310
|
+
if self.after is None or jstype(self.after) is 'string' else 'e'
|
|
311
|
+
)
|
|
242
312
|
if is_node_type(self.expression, AST_SymbolRef):
|
|
243
313
|
if key is 'n':
|
|
244
|
-
output.spaced(
|
|
314
|
+
output.spaced(
|
|
315
|
+
'(typeof',
|
|
316
|
+
self.expression,
|
|
317
|
+
'!==',
|
|
318
|
+
'"undefined"',
|
|
319
|
+
'&&',
|
|
320
|
+
self.expression,
|
|
321
|
+
'!==',
|
|
322
|
+
'null)'
|
|
323
|
+
)
|
|
245
324
|
return
|
|
246
325
|
if key is 'c':
|
|
247
|
-
output.spaced(
|
|
326
|
+
output.spaced(
|
|
327
|
+
'(typeof',
|
|
328
|
+
self.expression,
|
|
329
|
+
'===',
|
|
330
|
+
'"function"',
|
|
331
|
+
'?',
|
|
332
|
+
self.expression,
|
|
333
|
+
':',
|
|
334
|
+
'(function(){return undefined;}))'
|
|
335
|
+
)
|
|
248
336
|
return
|
|
249
337
|
after = self.after
|
|
250
338
|
if key is 'd':
|
|
251
339
|
after = 'Object.create(null)'
|
|
252
340
|
elif key is 'g':
|
|
253
341
|
after = '{__getitem__:function(){return undefined;}}'
|
|
254
|
-
output.spaced(
|
|
342
|
+
output.spaced(
|
|
343
|
+
'(typeof',
|
|
344
|
+
self.expression,
|
|
345
|
+
'!==',
|
|
346
|
+
'"undefined"',
|
|
347
|
+
'&&',
|
|
348
|
+
self.expression,
|
|
349
|
+
'!==',
|
|
350
|
+
'null',
|
|
351
|
+
'?',
|
|
352
|
+
self.expression,
|
|
353
|
+
':',
|
|
354
|
+
after
|
|
355
|
+
)
|
|
255
356
|
output.print(')')
|
|
256
357
|
return
|
|
257
358
|
output.print('ρσ_exists.' + key + '(')
|
|
@@ -282,9 +383,13 @@ def print_assignment(self, output):
|
|
|
282
383
|
self.right.print(output)
|
|
283
384
|
if is_node_type(left, AST_Array):
|
|
284
385
|
output.end_statement()
|
|
285
|
-
if not is_node_type(
|
|
386
|
+
if not is_node_type(
|
|
387
|
+
self.right,
|
|
388
|
+
AST_Seq
|
|
389
|
+
) and not is_node_type(self.right, AST_Array):
|
|
286
390
|
output.assign('ρσ_unpack')
|
|
287
|
-
output.print('ρσ_unpack_asarray(' + flat.length)
|
|
391
|
+
output.print('ρσ_unpack_asarray(' + flat.length)
|
|
392
|
+
output.comma(), output.print('ρσ_unpack)')
|
|
288
393
|
output.end_statement()
|
|
289
394
|
unpack_tuple(flat, output, True)
|
|
290
395
|
|
|
@@ -305,15 +410,31 @@ def print_assign(self, output):
|
|
|
305
410
|
left_hand_sides, rhs = self.traverse_chain()
|
|
306
411
|
is_compound_assign = False
|
|
307
412
|
for lhs in left_hand_sides:
|
|
308
|
-
if
|
|
413
|
+
if (
|
|
414
|
+
is_node_type(lhs, AST_Seq)
|
|
415
|
+
or is_node_type(lhs, AST_Array)
|
|
416
|
+
or is_node_type(lhs, AST_ItemAccess)
|
|
417
|
+
):
|
|
309
418
|
is_compound_assign = True
|
|
310
419
|
break
|
|
311
420
|
if is_compound_assign:
|
|
312
421
|
temp_rhs = new AST_SymbolRef({'name': 'ρσ_chain_assign_temp'})
|
|
313
|
-
print_assignment(
|
|
422
|
+
print_assignment(
|
|
423
|
+
new AST_Assign({
|
|
424
|
+
'left': temp_rhs, 'operator': '=', 'right': rhs
|
|
425
|
+
}),
|
|
426
|
+
output
|
|
427
|
+
)
|
|
314
428
|
for lhs in left_hand_sides:
|
|
315
429
|
output.end_statement(), output.indent()
|
|
316
|
-
print_assignment(
|
|
430
|
+
print_assignment(
|
|
431
|
+
new AST_Assign({
|
|
432
|
+
'left': lhs,
|
|
433
|
+
'right': temp_rhs,
|
|
434
|
+
'operator': self.operator
|
|
435
|
+
}),
|
|
436
|
+
output
|
|
437
|
+
)
|
|
317
438
|
else:
|
|
318
439
|
for lhs in left_hand_sides:
|
|
319
440
|
output.spaced(lhs, '=', '')
|
|
@@ -323,7 +444,9 @@ def print_assign(self, output):
|
|
|
323
444
|
|
|
324
445
|
|
|
325
446
|
def print_conditional(self, output, condition, consequent, alternative):
|
|
326
|
-
condition
|
|
447
|
+
condition = self.condition
|
|
448
|
+
consequent = self.consequent
|
|
449
|
+
alternative = self.alternative
|
|
327
450
|
output.with_parens(def (): condition.print(output);)
|
|
328
451
|
output.space()
|
|
329
452
|
output.print('?')
|
|
@@ -70,7 +70,8 @@ def declare_vars(vars, output):
|
|
|
70
70
|
def display_body(body, is_toplevel, output):
|
|
71
71
|
last = body.length - 1
|
|
72
72
|
for i, stmt in enumerate(body):
|
|
73
|
-
if not (is_node_type(stmt, AST_EmptyStatement))
|
|
73
|
+
if (not (is_node_type(stmt, AST_EmptyStatement))
|
|
74
|
+
and not (is_node_type(stmt, AST_Definitions))):
|
|
74
75
|
output.indent()
|
|
75
76
|
stmt.print(output)
|
|
76
77
|
if not (i is last and is_toplevel):
|
|
@@ -134,7 +135,9 @@ def print_bracketed(node, output, complex, function_preamble, before, after):
|
|
|
134
135
|
|
|
135
136
|
def print_with(self, output):
|
|
136
137
|
exits = v'[]'
|
|
137
|
-
output.assign('ρσ_with_exception')
|
|
138
|
+
output.assign('ρσ_with_exception')
|
|
139
|
+
output.print('undefined')
|
|
140
|
+
output.end_statement()
|
|
138
141
|
for clause in self.clauses:
|
|
139
142
|
output.with_counter += 1
|
|
140
143
|
clause_name = 'ρσ_with_clause_' + output.with_counter
|
|
@@ -155,29 +158,54 @@ def print_with(self, output):
|
|
|
155
158
|
)
|
|
156
159
|
output.space(), output.print('catch(e)')
|
|
157
160
|
output.with_block(def ():
|
|
158
|
-
output.indent()
|
|
161
|
+
output.indent()
|
|
162
|
+
output.assign('ρσ_with_exception')
|
|
163
|
+
output.print('e')
|
|
164
|
+
output.end_statement()
|
|
165
|
+
)
|
|
166
|
+
output.newline(), output.indent(), output.spaced(
|
|
167
|
+
'if',
|
|
168
|
+
'(ρσ_with_exception',
|
|
169
|
+
'===',
|
|
170
|
+
'undefined)'
|
|
159
171
|
)
|
|
160
|
-
output.newline(), output.indent(), output.spaced('if', '(ρσ_with_exception', '===', 'undefined)')
|
|
161
172
|
output.with_block(def ():
|
|
162
173
|
for clause in exits:
|
|
163
|
-
output.indent()
|
|
174
|
+
output.indent()
|
|
175
|
+
output.print(clause + '.__exit__()')
|
|
176
|
+
output.end_statement()
|
|
164
177
|
)
|
|
165
178
|
output.space(), output.print('else'), output.space()
|
|
166
179
|
output.with_block(def ():
|
|
167
|
-
output.indent()
|
|
180
|
+
output.indent()
|
|
181
|
+
output.assign('ρσ_with_suppress')
|
|
182
|
+
output.print('false')
|
|
183
|
+
output.end_statement()
|
|
168
184
|
for clause in exits:
|
|
169
185
|
output.indent()
|
|
170
|
-
output.spaced(
|
|
171
|
-
|
|
186
|
+
output.spaced(
|
|
187
|
+
'ρσ_with_suppress', '|=',
|
|
188
|
+
'ρσ_bool(' + clause
|
|
189
|
+
+ '.__exit__(ρσ_with_exception.constructor,',
|
|
190
|
+
'ρσ_with_exception,',
|
|
191
|
+
'ρσ_with_exception.stack))'
|
|
192
|
+
)
|
|
172
193
|
output.end_statement()
|
|
173
|
-
output.indent()
|
|
194
|
+
output.indent()
|
|
195
|
+
output.spaced('if', '(!ρσ_with_suppress)', 'throw ρσ_with_exception')
|
|
196
|
+
output.end_statement()
|
|
174
197
|
)
|
|
175
198
|
|
|
176
199
|
|
|
177
200
|
def print_assert(self, output):
|
|
178
201
|
if output.options.discard_asserts:
|
|
179
202
|
return
|
|
180
|
-
output.spaced(
|
|
203
|
+
output.spaced(
|
|
204
|
+
'if',
|
|
205
|
+
'(!('
|
|
206
|
+
), self.condition.print(output), output.spaced(
|
|
207
|
+
'))', 'throw new AssertionError'
|
|
208
|
+
)
|
|
181
209
|
if self.message:
|
|
182
210
|
output.print('(')
|
|
183
211
|
self.message.print(output)
|