rapydscript-ns 0.8.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.
- package/.agignore +1 -0
- package/.gitattributes +4 -0
- package/.github/workflows/ci.yml +38 -0
- package/.github/workflows/web-repl-page-deploy.yml +42 -0
- package/=template.pyj +5 -0
- package/CHANGELOG.md +456 -0
- package/CONTRIBUTORS +13 -0
- package/HACKING.md +103 -0
- package/LICENSE +24 -0
- package/README.md +2512 -0
- package/TODO.md +327 -0
- package/add-toc-to-readme +2 -0
- package/bin/export +75 -0
- package/bin/rapydscript +70 -0
- package/bin/web-repl-export +102 -0
- package/build +3 -0
- package/package.json +46 -0
- package/publish.py +37 -0
- package/release/baselib-plain-pretty.js +4370 -0
- package/release/baselib-plain-ugly.js +3 -0
- package/release/compiler.js +18394 -0
- package/release/signatures.json +31 -0
- package/session.vim +4 -0
- package/setup.cfg +2 -0
- package/src/ast.pyj +1356 -0
- package/src/baselib-builtins.pyj +279 -0
- package/src/baselib-containers.pyj +723 -0
- package/src/baselib-errors.pyj +37 -0
- package/src/baselib-internal.pyj +421 -0
- package/src/baselib-itertools.pyj +97 -0
- package/src/baselib-str.pyj +798 -0
- package/src/compiler.pyj +36 -0
- package/src/errors.pyj +30 -0
- package/src/lib/aes.pyj +646 -0
- package/src/lib/collections.pyj +695 -0
- package/src/lib/elementmaker.pyj +83 -0
- package/src/lib/encodings.pyj +126 -0
- package/src/lib/functools.pyj +148 -0
- package/src/lib/gettext.pyj +569 -0
- package/src/lib/itertools.pyj +580 -0
- package/src/lib/math.pyj +193 -0
- package/src/lib/numpy.pyj +2101 -0
- package/src/lib/operator.pyj +11 -0
- package/src/lib/pythonize.pyj +20 -0
- package/src/lib/random.pyj +118 -0
- package/src/lib/re.pyj +470 -0
- package/src/lib/traceback.pyj +63 -0
- package/src/lib/uuid.pyj +77 -0
- package/src/monaco-language-service/analyzer.js +526 -0
- package/src/monaco-language-service/builtins.js +543 -0
- package/src/monaco-language-service/completions.js +498 -0
- package/src/monaco-language-service/diagnostics.js +643 -0
- package/src/monaco-language-service/dts.js +550 -0
- package/src/monaco-language-service/hover.js +121 -0
- package/src/monaco-language-service/index.js +386 -0
- package/src/monaco-language-service/scope.js +162 -0
- package/src/monaco-language-service/signature.js +144 -0
- package/src/output/__init__.pyj +0 -0
- package/src/output/classes.pyj +296 -0
- package/src/output/codegen.pyj +492 -0
- package/src/output/comments.pyj +45 -0
- package/src/output/exceptions.pyj +105 -0
- package/src/output/functions.pyj +491 -0
- package/src/output/literals.pyj +109 -0
- package/src/output/loops.pyj +444 -0
- package/src/output/modules.pyj +329 -0
- package/src/output/operators.pyj +429 -0
- package/src/output/statements.pyj +463 -0
- package/src/output/stream.pyj +309 -0
- package/src/output/treeshake.pyj +182 -0
- package/src/output/utils.pyj +72 -0
- package/src/parse.pyj +3106 -0
- package/src/string_interpolation.pyj +72 -0
- package/src/tokenizer.pyj +702 -0
- package/src/unicode_aliases.pyj +576 -0
- package/src/utils.pyj +192 -0
- package/test/_import_one.pyj +37 -0
- package/test/_import_two/__init__.pyj +11 -0
- package/test/_import_two/level2/__init__.pyj +0 -0
- package/test/_import_two/level2/deep.pyj +4 -0
- package/test/_import_two/other.pyj +6 -0
- package/test/_import_two/sub.pyj +13 -0
- package/test/aes_vectors.pyj +421 -0
- package/test/annotations.pyj +80 -0
- package/test/baselib.pyj +319 -0
- package/test/classes.pyj +452 -0
- package/test/collections.pyj +152 -0
- package/test/decorators.pyj +77 -0
- package/test/dict_spread.pyj +76 -0
- package/test/docstrings.pyj +39 -0
- package/test/elementmaker_test.pyj +45 -0
- package/test/ellipsis.pyj +49 -0
- package/test/functions.pyj +151 -0
- package/test/generators.pyj +41 -0
- package/test/generic.pyj +370 -0
- package/test/imports.pyj +72 -0
- package/test/internationalization.pyj +73 -0
- package/test/lint.pyj +164 -0
- package/test/loops.pyj +85 -0
- package/test/numpy.pyj +734 -0
- package/test/omit_function_metadata.pyj +20 -0
- package/test/regexp.pyj +55 -0
- package/test/repl.pyj +121 -0
- package/test/scoped_flags.pyj +76 -0
- package/test/starargs.pyj +506 -0
- package/test/starred_assign.pyj +104 -0
- package/test/str.pyj +198 -0
- package/test/subscript_tuple.pyj +53 -0
- package/test/unit/fixtures/fibonacci_expected.js +46 -0
- package/test/unit/index.js +2989 -0
- package/test/unit/language-service-builtins.js +815 -0
- package/test/unit/language-service-completions.js +1067 -0
- package/test/unit/language-service-dts.js +543 -0
- package/test/unit/language-service-hover.js +455 -0
- package/test/unit/language-service-scope.js +833 -0
- package/test/unit/language-service-signature.js +458 -0
- package/test/unit/language-service.js +705 -0
- package/test/unit/run-language-service.js +41 -0
- package/test/unit/web-repl.js +484 -0
- package/tools/build-language-service.js +190 -0
- package/tools/cli.js +547 -0
- package/tools/compile.js +219 -0
- package/tools/compiler.js +108 -0
- package/tools/completer.js +131 -0
- package/tools/embedded_compiler.js +251 -0
- package/tools/export.js +316 -0
- package/tools/gettext.js +185 -0
- package/tools/ini.js +65 -0
- package/tools/lint.js +705 -0
- package/tools/msgfmt.js +187 -0
- package/tools/repl.js +223 -0
- package/tools/self.js +162 -0
- package/tools/test.js +118 -0
- package/tools/utils.js +128 -0
- package/tools/web_repl.js +95 -0
- package/try +41 -0
- package/web-repl/env.js +74 -0
- package/web-repl/index.html +163 -0
- package/web-repl/language-service.js +4084 -0
- package/web-repl/main.js +254 -0
- package/web-repl/prism.css +139 -0
- package/web-repl/prism.js +113 -0
- package/web-repl/rapydscript.js +435 -0
- package/web-repl/sha1.js +25 -0
|
@@ -0,0 +1,429 @@
|
|
|
1
|
+
# vim:fileencoding=utf-8
|
|
2
|
+
# License: BSD Copyright: 2016, Kovid Goyal <kovid at kovidgoyal.net>
|
|
3
|
+
from __python__ import hash_literals
|
|
4
|
+
from ast import (
|
|
5
|
+
AST_Array, AST_Assign, AST_BaseCall, AST_Binary, AST_Conditional,
|
|
6
|
+
AST_ItemAccess, AST_NamedExpr, AST_Number, AST_Object, AST_Return, AST_Seq, AST_Set,
|
|
7
|
+
AST_SimpleStatement, AST_Statement, AST_String, AST_Sub, AST_Symbol,
|
|
8
|
+
AST_SymbolRef, AST_Starred, AST_Unary, is_node_type
|
|
9
|
+
)
|
|
10
|
+
from output.loops import unpack_tuple
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
def print_getattr(self, output, skip_expression): # AST_Dot
|
|
14
|
+
if not skip_expression:
|
|
15
|
+
expr = self.expression
|
|
16
|
+
expr.print(output)
|
|
17
|
+
if is_node_type(expr, AST_Number) and expr.value >= 0:
|
|
18
|
+
if not /[xa-f.]/i.test(output.last()):
|
|
19
|
+
output.print(".")
|
|
20
|
+
output.print(".")
|
|
21
|
+
# the name after dot would be mapped about here.
|
|
22
|
+
output.print_name(self.property)
|
|
23
|
+
|
|
24
|
+
def print_getitem(self, output): # AST_Sub
|
|
25
|
+
expr = self.expression
|
|
26
|
+
prop = self.property
|
|
27
|
+
# Tuple-style subscript: a[1, 2] → a[[1, 2]]
|
|
28
|
+
if is_node_type(prop, AST_Array) and prop.is_subscript_tuple:
|
|
29
|
+
expr.print(output)
|
|
30
|
+
output.print('[[')
|
|
31
|
+
for i, elem in enumerate(prop.elements):
|
|
32
|
+
if i:
|
|
33
|
+
output.comma()
|
|
34
|
+
elem.print(output)
|
|
35
|
+
output.print(']]')
|
|
36
|
+
return
|
|
37
|
+
if (is_node_type(prop, AST_Number) or is_node_type(prop, AST_String)) or (is_node_type(prop, AST_SymbolRef) and prop.name and prop.name.startsWith('ρσ_')):
|
|
38
|
+
expr.print(output)
|
|
39
|
+
output.print('['), prop.print(output), output.print(']')
|
|
40
|
+
return
|
|
41
|
+
is_negative_number = is_node_type(prop, AST_Unary) and prop.operator is "-" and is_node_type(prop.expression, AST_Number)
|
|
42
|
+
is_repeatable = is_node_type(expr, AST_SymbolRef)
|
|
43
|
+
if is_repeatable:
|
|
44
|
+
expr.print(output)
|
|
45
|
+
else:
|
|
46
|
+
output.spaced('(ρσ_expr_temp', '=', expr), output.print(')')
|
|
47
|
+
expr = {'print': def(): output.print('ρσ_expr_temp');}
|
|
48
|
+
|
|
49
|
+
if is_negative_number:
|
|
50
|
+
output.print('['), expr.print(output), output.print('.length'), prop.print(output), output.print(']')
|
|
51
|
+
return
|
|
52
|
+
is_repeatable = is_node_type(prop, AST_SymbolRef)
|
|
53
|
+
# We have to check the type of the property because if it is a Symbol, it
|
|
54
|
+
# will raise a TypeError with the < operator.
|
|
55
|
+
if is_repeatable:
|
|
56
|
+
output.spaced('[(typeof', prop, '===', '"number"', '&&', prop)
|
|
57
|
+
output.spaced('', '<', '0)', '?', expr), output.spaced('.length', '+', prop, ':', prop)
|
|
58
|
+
output.print("]")
|
|
59
|
+
else:
|
|
60
|
+
output.print('[ρσ_bound_index('), prop.print(output), output.comma(), expr.print(output), output.print(')]')
|
|
61
|
+
|
|
62
|
+
|
|
63
|
+
def print_rich_getitem(self, output): # AST_ItemAccess
|
|
64
|
+
func = 'ρσ_' + ('setitem' if self.assignment else 'getitem')
|
|
65
|
+
output.print(func + '(')
|
|
66
|
+
self.expression.print(output), output.comma(), self.property.print(output)
|
|
67
|
+
if self.assignment:
|
|
68
|
+
output.comma()
|
|
69
|
+
asg = self.assignment
|
|
70
|
+
as_op = self.assign_operator
|
|
71
|
+
if as_op.length > 0:
|
|
72
|
+
self.assignment = None
|
|
73
|
+
print_rich_getitem(self, output)
|
|
74
|
+
self.assignment = asg
|
|
75
|
+
output.space()
|
|
76
|
+
output.print(as_op)
|
|
77
|
+
output.space()
|
|
78
|
+
self.assignment.print(output)
|
|
79
|
+
output.print(')')
|
|
80
|
+
|
|
81
|
+
def print_splice_assignment(self, output): # AST_Splice
|
|
82
|
+
# splice assignment via pythonic array[start:end]
|
|
83
|
+
output.print('ρσ_splice(')
|
|
84
|
+
self.expression.print(output), output.comma(), self.assignment.print(output), output.comma()
|
|
85
|
+
self.property.print(output) if self.property else output.print('0')
|
|
86
|
+
if self.property2:
|
|
87
|
+
output.comma()
|
|
88
|
+
self.property2.print(output)
|
|
89
|
+
output.print(')')
|
|
90
|
+
|
|
91
|
+
def print_delete(self, output):
|
|
92
|
+
if is_node_type(self, AST_Symbol):
|
|
93
|
+
output.assign(self), output.print('undefined')
|
|
94
|
+
elif is_node_type(self, AST_Sub) or is_node_type(self, AST_ItemAccess):
|
|
95
|
+
output.print('ρσ_delitem('), self.expression.print(output), output.comma(), self.property.print(output), output.print(')')
|
|
96
|
+
else:
|
|
97
|
+
output.spaced('delete', self)
|
|
98
|
+
|
|
99
|
+
def print_unary_prefix(self, output):
|
|
100
|
+
op = self.operator
|
|
101
|
+
if op is 'delete':
|
|
102
|
+
return print_delete(self.expression, output)
|
|
103
|
+
if self.overloaded:
|
|
104
|
+
if op is '-':
|
|
105
|
+
output.print('ρσ_op_neg('), self.expression.print(output), output.print(')')
|
|
106
|
+
return
|
|
107
|
+
if op is '+':
|
|
108
|
+
output.print('ρσ_op_pos('), self.expression.print(output), output.print(')')
|
|
109
|
+
return
|
|
110
|
+
if op is '~':
|
|
111
|
+
output.print('ρσ_op_invert('), self.expression.print(output), output.print(')')
|
|
112
|
+
return
|
|
113
|
+
output.print(op)
|
|
114
|
+
if /^[a-z]/i.test(op):
|
|
115
|
+
output.space()
|
|
116
|
+
if self.parenthesized:
|
|
117
|
+
output.with_parens(def():
|
|
118
|
+
self.expression.print(output)
|
|
119
|
+
)
|
|
120
|
+
else:
|
|
121
|
+
self.expression.print(output)
|
|
122
|
+
|
|
123
|
+
def write_instanceof(left, right, output):
|
|
124
|
+
|
|
125
|
+
def do_many(vals):
|
|
126
|
+
output.print('ρσ_instanceof.apply(null,'), output.space()
|
|
127
|
+
output.print('['), left.print(output), output.comma()
|
|
128
|
+
for v'var i = 0; i < vals.length; i++':
|
|
129
|
+
vals[i].print(output)
|
|
130
|
+
if i is not vals.length - 1:
|
|
131
|
+
output.comma()
|
|
132
|
+
output.print('])')
|
|
133
|
+
|
|
134
|
+
if is_node_type(right, AST_Seq):
|
|
135
|
+
do_many(right.to_array())
|
|
136
|
+
elif is_node_type(right, AST_Array):
|
|
137
|
+
do_many(right.elements)
|
|
138
|
+
else:
|
|
139
|
+
output.print('ρσ_instanceof(')
|
|
140
|
+
left.print(output), output.comma(), right.print(output), output.print(')')
|
|
141
|
+
|
|
142
|
+
def write_smart_equality(self, output):
|
|
143
|
+
def is_ok(x):
|
|
144
|
+
return not (
|
|
145
|
+
is_node_type(x, AST_Array) or is_node_type(x, AST_Set) or is_node_type(x, AST_Object) or
|
|
146
|
+
is_node_type(x, AST_Statement) or is_node_type(x, AST_Binary) or is_node_type(x, AST_Conditional)
|
|
147
|
+
or is_node_type(x, AST_BaseCall)
|
|
148
|
+
)
|
|
149
|
+
if is_ok(self.left) and is_ok(self.right):
|
|
150
|
+
if self.operator is '==':
|
|
151
|
+
output.print('(')
|
|
152
|
+
output.spaced(self.left, '===', self.right, '||', 'typeof', self.left, '===', '"object"', '&&', 'ρσ_equals(')
|
|
153
|
+
self.left.print(output), output.print(','), output.space(), self.right.print(output), output.print('))')
|
|
154
|
+
else:
|
|
155
|
+
output.print('(')
|
|
156
|
+
output.spaced(self.left, '!==', self.right, '&&', '(typeof', self.left, '!==', '"object"', '||', 'ρσ_not_equals(')
|
|
157
|
+
self.left.print(output), output.print(','), output.space(), self.right.print(output), output.print(')))')
|
|
158
|
+
else:
|
|
159
|
+
output.print('ρσ_' + ('equals(' if self.operator is '==' else 'not_equals('))
|
|
160
|
+
self.left.print(output), output.print(','), output.space(), self.right.print(output), output.print(')')
|
|
161
|
+
|
|
162
|
+
|
|
163
|
+
comparators = {
|
|
164
|
+
"<": True,
|
|
165
|
+
">": True,
|
|
166
|
+
"<=": True,
|
|
167
|
+
">=": True,
|
|
168
|
+
}
|
|
169
|
+
|
|
170
|
+
function_ops = {
|
|
171
|
+
"in": "ρσ_in",
|
|
172
|
+
'nin': '!ρσ_in',
|
|
173
|
+
}
|
|
174
|
+
|
|
175
|
+
# Maps binary operators to their overloading helper function names.
|
|
176
|
+
overloaded_binary_ops = {
|
|
177
|
+
'+': 'ρσ_op_add',
|
|
178
|
+
'-': 'ρσ_op_sub',
|
|
179
|
+
'*': 'ρσ_op_mul',
|
|
180
|
+
'/': 'ρσ_op_truediv',
|
|
181
|
+
'//': 'ρσ_op_floordiv',
|
|
182
|
+
'%': 'ρσ_op_mod',
|
|
183
|
+
'**': 'ρσ_op_pow',
|
|
184
|
+
'&': 'ρσ_op_and',
|
|
185
|
+
'|': 'ρσ_op_or',
|
|
186
|
+
'^': 'ρσ_op_xor',
|
|
187
|
+
'<<': 'ρσ_op_lshift',
|
|
188
|
+
'>>': 'ρσ_op_rshift',
|
|
189
|
+
}
|
|
190
|
+
|
|
191
|
+
# Maps augmented-assignment operators to their overloading helper names.
|
|
192
|
+
overloaded_augmented_ops = {
|
|
193
|
+
'+=': 'ρσ_op_iadd',
|
|
194
|
+
'-=': 'ρσ_op_isub',
|
|
195
|
+
'*=': 'ρσ_op_imul',
|
|
196
|
+
'/=': 'ρσ_op_itruediv',
|
|
197
|
+
'//=': 'ρσ_op_ifloordiv',
|
|
198
|
+
'%=': 'ρσ_op_imod',
|
|
199
|
+
'**=': 'ρσ_op_ipow',
|
|
200
|
+
'&=': 'ρσ_op_iand',
|
|
201
|
+
'|=': 'ρσ_op_ior',
|
|
202
|
+
'^=': 'ρσ_op_ixor',
|
|
203
|
+
'<<=': 'ρσ_op_ilshift',
|
|
204
|
+
'>>=': 'ρσ_op_irshift',
|
|
205
|
+
}
|
|
206
|
+
|
|
207
|
+
|
|
208
|
+
def print_binary_op(self, output):
|
|
209
|
+
if self.overloaded and overloaded_binary_ops[self.operator]:
|
|
210
|
+
output.print(overloaded_binary_ops[self.operator] + '(')
|
|
211
|
+
self.left.print(output)
|
|
212
|
+
output.comma()
|
|
213
|
+
self.right.print(output)
|
|
214
|
+
output.print(')')
|
|
215
|
+
return
|
|
216
|
+
if function_ops[self.operator]:
|
|
217
|
+
output.print(function_ops[self.operator])
|
|
218
|
+
output.with_parens(def():
|
|
219
|
+
self.left.print(output)
|
|
220
|
+
output.comma()
|
|
221
|
+
self.right.print(output)
|
|
222
|
+
)
|
|
223
|
+
elif comparators[self.operator] and is_node_type(self.left, AST_Binary) and comparators[self.left.operator]:
|
|
224
|
+
# A chained comparison such as a < b < c
|
|
225
|
+
if is_node_type(self.left.right, AST_Symbol):
|
|
226
|
+
# left side compares against a regular variable,
|
|
227
|
+
# no caching needed
|
|
228
|
+
self.left.print(output)
|
|
229
|
+
leftvar = self.left.right.name
|
|
230
|
+
else:
|
|
231
|
+
# some logic is being performed, let's cache it
|
|
232
|
+
self.left.left.print(output)
|
|
233
|
+
output.space()
|
|
234
|
+
output.print(self.left.operator)
|
|
235
|
+
output.space()
|
|
236
|
+
output.with_parens(def():
|
|
237
|
+
nonlocal leftvar
|
|
238
|
+
output.assign("ρσ_cond_temp")
|
|
239
|
+
self.left.right.print(output)
|
|
240
|
+
leftvar = "ρσ_cond_temp"
|
|
241
|
+
)
|
|
242
|
+
|
|
243
|
+
output.space()
|
|
244
|
+
output.print("&&")
|
|
245
|
+
output.space()
|
|
246
|
+
output.print(leftvar)
|
|
247
|
+
output.space()
|
|
248
|
+
output.print(self.operator)
|
|
249
|
+
output.space()
|
|
250
|
+
self.right.print(output)
|
|
251
|
+
elif self.operator is '//':
|
|
252
|
+
output.print('Math.floor')
|
|
253
|
+
output.with_parens(def():
|
|
254
|
+
self.left.print(output)
|
|
255
|
+
output.space()
|
|
256
|
+
output.print('/')
|
|
257
|
+
output.space()
|
|
258
|
+
self.right.print(output)
|
|
259
|
+
)
|
|
260
|
+
elif self.operator is '**':
|
|
261
|
+
left = self.left
|
|
262
|
+
if is_node_type(self.left, AST_Unary) and not self.left.parenthesized:
|
|
263
|
+
left = self.left.expression
|
|
264
|
+
output.print(self.left.operator)
|
|
265
|
+
if output.options.js_version > 6:
|
|
266
|
+
output.print('(('), left.print(output), output.spaced(')', '**', '('), self.right.print(output), output.print('))')
|
|
267
|
+
else:
|
|
268
|
+
output.print('Math.pow('), left.print(output), output.comma(), self.right.print(output), output.print(')')
|
|
269
|
+
elif self.operator is '==' or self.operator is '!=':
|
|
270
|
+
write_smart_equality(self, output)
|
|
271
|
+
elif self.operator is 'instanceof':
|
|
272
|
+
write_instanceof(self.left, self.right, output)
|
|
273
|
+
elif self.operator is '*' and is_node_type(self.left, AST_String):
|
|
274
|
+
self.left.print(output), output.print('.repeat('), self.right.print(output), output.print(')')
|
|
275
|
+
elif self.operator is '===' or self.operator is '!==':
|
|
276
|
+
nan_check = None
|
|
277
|
+
if is_node_type(self.right, AST_Symbol) and self.right.name is 'NaN':
|
|
278
|
+
nan_check = self.left
|
|
279
|
+
if is_node_type(self.left, AST_Symbol) and self.left.name is 'NaN':
|
|
280
|
+
nan_check = self.right
|
|
281
|
+
if nan_check is not None:
|
|
282
|
+
# We use the fact that NaN is the only object that is not equal to
|
|
283
|
+
# itself
|
|
284
|
+
output.spaced(nan_check, '!==' if self.operator is '===' else '===', nan_check)
|
|
285
|
+
else:
|
|
286
|
+
output.spaced(self.left, self.operator, self.right)
|
|
287
|
+
else:
|
|
288
|
+
output.spaced(self.left, self.operator, self.right)
|
|
289
|
+
|
|
290
|
+
after_map = {'.':'d', '(':'c', '[':'d', 'g':'g', 'null':'n'}
|
|
291
|
+
|
|
292
|
+
def print_existential(self, output):
|
|
293
|
+
key = after_map[self.after] if self.after is None or jstype(self.after) is 'string' else 'e'
|
|
294
|
+
if is_node_type(self.expression, AST_SymbolRef):
|
|
295
|
+
if key is 'n':
|
|
296
|
+
output.spaced('(typeof', self.expression, '!==', '"undefined"', '&&', self.expression, '!==', 'null)')
|
|
297
|
+
return
|
|
298
|
+
if key is 'c':
|
|
299
|
+
output.spaced('(typeof', self.expression, '===', '"function"', '?', self.expression, ':', '(function(){return undefined;}))')
|
|
300
|
+
return
|
|
301
|
+
after = self.after
|
|
302
|
+
if key is 'd':
|
|
303
|
+
after = 'Object.create(null)'
|
|
304
|
+
elif key is 'g':
|
|
305
|
+
after = '{__getitem__:function(){return undefined;}}'
|
|
306
|
+
output.spaced('(typeof', self.expression, '!==', '"undefined"', '&&', self.expression, '!==', 'null', '?', self.expression, ':', after)
|
|
307
|
+
output.print(')')
|
|
308
|
+
return
|
|
309
|
+
output.print('ρσ_exists.' + key + '(')
|
|
310
|
+
self.expression.print(output)
|
|
311
|
+
if key is 'e':
|
|
312
|
+
output.comma(), self.after.print(output)
|
|
313
|
+
output.print(')')
|
|
314
|
+
|
|
315
|
+
def print_assignment(self, output):
|
|
316
|
+
flattened = False
|
|
317
|
+
left = self.left
|
|
318
|
+
if is_node_type(left, AST_Seq):
|
|
319
|
+
left = new AST_Array({'elements':v'[left.car, left.cdr]'})
|
|
320
|
+
if is_node_type(left, AST_Array):
|
|
321
|
+
flat = left.flatten()
|
|
322
|
+
flattened = flat.length > left.elements.length
|
|
323
|
+
has_starred = False
|
|
324
|
+
for elem in flat:
|
|
325
|
+
if is_node_type(elem, AST_Starred):
|
|
326
|
+
has_starred = True
|
|
327
|
+
break
|
|
328
|
+
output.print("ρσ_unpack")
|
|
329
|
+
else:
|
|
330
|
+
left.print(output)
|
|
331
|
+
output.space()
|
|
332
|
+
output.print(self.operator)
|
|
333
|
+
output.space()
|
|
334
|
+
if flattened:
|
|
335
|
+
output.print('ρσ_flatten')
|
|
336
|
+
output.with_parens(def():self.right.print(output);)
|
|
337
|
+
else:
|
|
338
|
+
self.right.print(output)
|
|
339
|
+
if is_node_type(left, AST_Array):
|
|
340
|
+
output.end_statement()
|
|
341
|
+
if not is_node_type(self.right, AST_Seq) and not is_node_type(self.right, AST_Array):
|
|
342
|
+
output.assign('ρσ_unpack')
|
|
343
|
+
if has_starred:
|
|
344
|
+
output.print('ρσ_unpack_starred_asarray('), output.print('ρσ_unpack)')
|
|
345
|
+
else:
|
|
346
|
+
output.print('ρσ_unpack_asarray(' + flat.length), output.comma(), output.print('ρσ_unpack)')
|
|
347
|
+
output.end_statement()
|
|
348
|
+
unpack_tuple(flat, output, True)
|
|
349
|
+
|
|
350
|
+
def print_assign(self, output):
|
|
351
|
+
if self.overloaded and overloaded_augmented_ops[self.operator]:
|
|
352
|
+
helper = overloaded_augmented_ops[self.operator]
|
|
353
|
+
output.assign(self.left)
|
|
354
|
+
output.print(helper + '(')
|
|
355
|
+
self.left.print(output)
|
|
356
|
+
output.comma()
|
|
357
|
+
self.right.print(output)
|
|
358
|
+
output.print(')')
|
|
359
|
+
return
|
|
360
|
+
if self.operator is '//=':
|
|
361
|
+
output.assign(self.left)
|
|
362
|
+
output.print('Math.floor')
|
|
363
|
+
output.with_parens(def():
|
|
364
|
+
self.left.print(output)
|
|
365
|
+
output.space()
|
|
366
|
+
output.print('/')
|
|
367
|
+
output.space()
|
|
368
|
+
self.right.print(output)
|
|
369
|
+
)
|
|
370
|
+
return
|
|
371
|
+
if self.operator is '=' and self.is_chained():
|
|
372
|
+
left_hand_sides, rhs = self.traverse_chain()
|
|
373
|
+
is_compound_assign = False
|
|
374
|
+
for lhs in left_hand_sides:
|
|
375
|
+
if is_node_type(lhs, AST_Seq) or is_node_type(lhs, AST_Array) or is_node_type(lhs, AST_ItemAccess):
|
|
376
|
+
is_compound_assign = True
|
|
377
|
+
break
|
|
378
|
+
if is_compound_assign:
|
|
379
|
+
temp_rhs = new AST_SymbolRef({'name':'ρσ_chain_assign_temp'})
|
|
380
|
+
print_assignment(new AST_Assign({'left':temp_rhs, 'operator':'=', 'right':rhs}), output)
|
|
381
|
+
for lhs in left_hand_sides:
|
|
382
|
+
output.end_statement(), output.indent()
|
|
383
|
+
print_assignment(new AST_Assign({'left':lhs, 'right':temp_rhs, 'operator':self.operator}), output)
|
|
384
|
+
else:
|
|
385
|
+
for lhs in left_hand_sides:
|
|
386
|
+
output.spaced(lhs, '=', '')
|
|
387
|
+
rhs.print(output)
|
|
388
|
+
else:
|
|
389
|
+
print_assignment(self, output)
|
|
390
|
+
|
|
391
|
+
def print_conditional(self, output, condition, consequent, alternative):
|
|
392
|
+
condition, consequent, alternative = self.condition, self.consequent, self.alternative
|
|
393
|
+
output.with_parens(def():condition.print(output);)
|
|
394
|
+
output.space()
|
|
395
|
+
output.print("?")
|
|
396
|
+
output.space()
|
|
397
|
+
consequent.print(output)
|
|
398
|
+
output.space()
|
|
399
|
+
output.colon()
|
|
400
|
+
alternative.print(output)
|
|
401
|
+
|
|
402
|
+
def print_seq(output):
|
|
403
|
+
self = this
|
|
404
|
+
p = output.parent()
|
|
405
|
+
print_seq = def():
|
|
406
|
+
self.car.print(output)
|
|
407
|
+
if self.cdr:
|
|
408
|
+
output.comma()
|
|
409
|
+
if output.should_break():
|
|
410
|
+
output.newline()
|
|
411
|
+
output.indent()
|
|
412
|
+
self.cdr.print(output)
|
|
413
|
+
|
|
414
|
+
# this will effectively convert tuples to arrays
|
|
415
|
+
if is_node_type(p, AST_Binary)
|
|
416
|
+
or is_node_type(p, AST_Return)
|
|
417
|
+
or is_node_type(p, AST_Array)
|
|
418
|
+
or is_node_type(p, AST_BaseCall)
|
|
419
|
+
or is_node_type(p, AST_SimpleStatement):
|
|
420
|
+
output.with_square(print_seq)
|
|
421
|
+
else:
|
|
422
|
+
print_seq()
|
|
423
|
+
|
|
424
|
+
def print_named_expr(self, output):
|
|
425
|
+
# Walrus operator: name := value → (name = value)
|
|
426
|
+
output.with_parens(def():
|
|
427
|
+
output.assign(self.name)
|
|
428
|
+
self.value.print(output)
|
|
429
|
+
)
|