pyscript-programming-language 1.12.0__py3-none-any.whl
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.
- pyscript/__init__.py +49 -0
- pyscript/__init__.pyi +96 -0
- pyscript/__main__.py +303 -0
- pyscript/core/__init__.py +61 -0
- pyscript/core/analyzer.py +531 -0
- pyscript/core/bases.py +2 -0
- pyscript/core/buffer.py +43 -0
- pyscript/core/cache.py +70 -0
- pyscript/core/checks.py +42 -0
- pyscript/core/constants.py +123 -0
- pyscript/core/context.py +63 -0
- pyscript/core/editor/__init__.py +15 -0
- pyscript/core/editor/bases.py +35 -0
- pyscript/core/editor/gui.py +144 -0
- pyscript/core/editor/terminal.py +175 -0
- pyscript/core/exceptions.py +123 -0
- pyscript/core/handlers.py +57 -0
- pyscript/core/highlight.py +552 -0
- pyscript/core/interpreter.py +1546 -0
- pyscript/core/lexer.py +863 -0
- pyscript/core/mapping.py +139 -0
- pyscript/core/nodes.py +663 -0
- pyscript/core/objects.py +213 -0
- pyscript/core/parser.py +2456 -0
- pyscript/core/position.py +114 -0
- pyscript/core/pysbuiltins.py +703 -0
- pyscript/core/results.py +186 -0
- pyscript/core/runner.py +363 -0
- pyscript/core/shell.py +287 -0
- pyscript/core/symtab.py +103 -0
- pyscript/core/token.py +25 -0
- pyscript/core/utils/__init__.py +27 -0
- pyscript/core/utils/ansi.py +127 -0
- pyscript/core/utils/debug.py +60 -0
- pyscript/core/utils/decorators.py +53 -0
- pyscript/core/utils/generic.py +46 -0
- pyscript/core/utils/jsdict.py +32 -0
- pyscript/core/utils/module.py +28 -0
- pyscript/core/utils/path.py +29 -0
- pyscript/core/utils/similarity.py +22 -0
- pyscript/core/utils/string.py +49 -0
- pyscript/core/version.py +120 -0
- pyscript/lib/__hello__.pys +7 -0
- pyscript/lib/ansi.pys +14 -0
- pyscript/lib/ast/__init__.pys +36 -0
- pyscript/lib/ast/ast_dump.py +433 -0
- pyscript/lib/ast/ast_literal_eval.py +80 -0
- pyscript/lib/ast/ast_unparse.py +540 -0
- pyscript/lib/ast/ast_walk.py +256 -0
- pyscript/lib/brainfuck.pys +190 -0
- pyscript/lib/dis.pys +7 -0
- pyscript/lib/explorer.pys +218 -0
- pyscript/lib/fpstimer/__init__.pys +6 -0
- pyscript/lib/fpstimer/py_fpstimer.py +54 -0
- pyscript/lib/getch.pys +28 -0
- pyscript/lib/inspect.pys +25 -0
- pyscript/lib/jsdict.pys +5 -0
- pyscript/lib/keyword.pys +2 -0
- pyscript/lib/opcode.pys +1 -0
- pyscript/lib/parser.pys +165 -0
- pyscript/lib/site.pys +55 -0
- pyscript/lib/symtable.pys +5 -0
- pyscript/lib/token.pys +12 -0
- pyscript/lib/tokenize/__init__.pys +14 -0
- pyscript/lib/tokenize/tok_untokenize.py +64 -0
- pyscript/other/.nomedia +0 -0
- pyscript/other/PyScript.ico +0 -0
- pyscript/other/copyright +2 -0
- pyscript/other/credits +2 -0
- pyscript/other/license +21 -0
- pyscript/site-packages/this.pys +19 -0
- pyscript/this.py +8 -0
- pyscript_programming_language-1.12.0.dist-info/METADATA +133 -0
- pyscript_programming_language-1.12.0.dist-info/RECORD +76 -0
- pyscript_programming_language-1.12.0.dist-info/WHEEL +5 -0
- pyscript_programming_language-1.12.0.dist-info/top_level.txt +1 -0
|
@@ -0,0 +1,1546 @@
|
|
|
1
|
+
from .constants import TOKENS, DEBUG
|
|
2
|
+
from .cache import undefined
|
|
3
|
+
from .checks import is_list, is_equals, is_public_attribute
|
|
4
|
+
from .context import PysClassContext
|
|
5
|
+
from .exceptions import PysTraceback
|
|
6
|
+
from .handlers import handle_call
|
|
7
|
+
from .mapping import BINARY_FUNCTIONS_MAP, UNARY_FUNCTIONS_MAP
|
|
8
|
+
from .nodes import PysNode, PysIdentifierNode, PysAttributeNode, PysSubscriptNode
|
|
9
|
+
from .objects import PysFunction
|
|
10
|
+
from .pysbuiltins import ce, nce, increment, decrement
|
|
11
|
+
from .results import PysRunTimeResult
|
|
12
|
+
from .symtab import PysClassSymbolTable, find_closest
|
|
13
|
+
from .utils.debug import get_error_args
|
|
14
|
+
from .utils.generic import getattribute, setimuattr, dkeys, is_object_of
|
|
15
|
+
from .utils.similarity import get_closest
|
|
16
|
+
|
|
17
|
+
from collections.abc import Iterable
|
|
18
|
+
|
|
19
|
+
T_KEYWORD = TOKENS['KEYWORD']
|
|
20
|
+
T_STRING = TOKENS['STRING']
|
|
21
|
+
T_AND = TOKENS['DOUBLE-AMPERSAND']
|
|
22
|
+
T_OR = TOKENS['DOUBLE-PIPE']
|
|
23
|
+
T_NOT = TOKENS['EXCLAMATION']
|
|
24
|
+
T_CE = TOKENS['EQUAL-TILDE']
|
|
25
|
+
T_NCE = TOKENS['EXCLAMATION-TILDE']
|
|
26
|
+
T_NULLISH = TOKENS['DOUBLE-QUESTION']
|
|
27
|
+
|
|
28
|
+
get_incremental_function = {
|
|
29
|
+
TOKENS['DOUBLE-PLUS']: increment,
|
|
30
|
+
TOKENS['DOUBLE-MINUS']: decrement
|
|
31
|
+
}.__getitem__
|
|
32
|
+
|
|
33
|
+
get_value_from_keyword = {
|
|
34
|
+
'True': True,
|
|
35
|
+
'False': False,
|
|
36
|
+
'None': None,
|
|
37
|
+
'true': True,
|
|
38
|
+
'false': False,
|
|
39
|
+
'nil': None,
|
|
40
|
+
'none': None,
|
|
41
|
+
'null': None
|
|
42
|
+
}.__getitem__
|
|
43
|
+
|
|
44
|
+
def visit_NumberNode(node, context):
|
|
45
|
+
return PysRunTimeResult().success(node.value.value)
|
|
46
|
+
|
|
47
|
+
def visit_StringNode(node, context):
|
|
48
|
+
return PysRunTimeResult().success(node.value.value)
|
|
49
|
+
|
|
50
|
+
def visit_KeywordNode(node, context):
|
|
51
|
+
name = node.name.value
|
|
52
|
+
return PysRunTimeResult().success(
|
|
53
|
+
(True if context.flags & DEBUG else False)
|
|
54
|
+
if name == '__debug__' else
|
|
55
|
+
get_value_from_keyword(name)
|
|
56
|
+
)
|
|
57
|
+
|
|
58
|
+
def visit_IdentifierNode(node, context):
|
|
59
|
+
result = PysRunTimeResult()
|
|
60
|
+
|
|
61
|
+
position = node.position
|
|
62
|
+
name = node.name.value
|
|
63
|
+
symbol_table = context.symbol_table
|
|
64
|
+
|
|
65
|
+
with result(context, position):
|
|
66
|
+
value = symbol_table.get(name)
|
|
67
|
+
|
|
68
|
+
if value is undefined:
|
|
69
|
+
closest_symbol = find_closest(symbol_table, name)
|
|
70
|
+
|
|
71
|
+
return result.failure(
|
|
72
|
+
PysTraceback(
|
|
73
|
+
NameError(
|
|
74
|
+
f"name {name!r} is not defined" +
|
|
75
|
+
(
|
|
76
|
+
''
|
|
77
|
+
if closest_symbol is None else
|
|
78
|
+
f". Did you mean {closest_symbol!r}?"
|
|
79
|
+
)
|
|
80
|
+
),
|
|
81
|
+
context,
|
|
82
|
+
position
|
|
83
|
+
)
|
|
84
|
+
)
|
|
85
|
+
|
|
86
|
+
if result.should_return():
|
|
87
|
+
return result
|
|
88
|
+
|
|
89
|
+
return result.success(value)
|
|
90
|
+
|
|
91
|
+
def visit_DictionaryNode(node, context):
|
|
92
|
+
result = PysRunTimeResult()
|
|
93
|
+
|
|
94
|
+
elements = node.class_type()
|
|
95
|
+
|
|
96
|
+
register = result.register
|
|
97
|
+
should_return = result.should_return
|
|
98
|
+
setitem = getattribute(elements, '__setitem__')
|
|
99
|
+
|
|
100
|
+
for nkey, nvalue in node.pairs:
|
|
101
|
+
key = register(get_visitor(nkey.__class__)(nkey, context))
|
|
102
|
+
if should_return():
|
|
103
|
+
return result
|
|
104
|
+
|
|
105
|
+
value = register(get_visitor(nvalue.__class__)(nvalue, context))
|
|
106
|
+
if should_return():
|
|
107
|
+
return result
|
|
108
|
+
|
|
109
|
+
with result(context, nkey.position):
|
|
110
|
+
setitem(key, value)
|
|
111
|
+
|
|
112
|
+
if should_return():
|
|
113
|
+
return result
|
|
114
|
+
|
|
115
|
+
return result.success(elements)
|
|
116
|
+
|
|
117
|
+
def visit_SetNode(node, context):
|
|
118
|
+
result = PysRunTimeResult()
|
|
119
|
+
|
|
120
|
+
elements = set()
|
|
121
|
+
|
|
122
|
+
register = result.register
|
|
123
|
+
should_return = result.should_return
|
|
124
|
+
add = elements.add
|
|
125
|
+
|
|
126
|
+
for nelement in node.elements:
|
|
127
|
+
|
|
128
|
+
with result(context, nelement.position):
|
|
129
|
+
add(register(get_visitor(nelement.__class__)(nelement, context)))
|
|
130
|
+
|
|
131
|
+
if should_return():
|
|
132
|
+
return result
|
|
133
|
+
|
|
134
|
+
return result.success(elements)
|
|
135
|
+
|
|
136
|
+
def visit_ListNode(node, context):
|
|
137
|
+
result = PysRunTimeResult()
|
|
138
|
+
|
|
139
|
+
elements = []
|
|
140
|
+
|
|
141
|
+
register = result.register
|
|
142
|
+
should_return = result.should_return
|
|
143
|
+
append = elements.append
|
|
144
|
+
|
|
145
|
+
for nelement in node.elements:
|
|
146
|
+
append(register(get_visitor(nelement.__class__)(nelement, context)))
|
|
147
|
+
if should_return():
|
|
148
|
+
return result
|
|
149
|
+
|
|
150
|
+
return result.success(elements)
|
|
151
|
+
|
|
152
|
+
def visit_TupleNode(node, context):
|
|
153
|
+
result = PysRunTimeResult()
|
|
154
|
+
|
|
155
|
+
elements = []
|
|
156
|
+
|
|
157
|
+
register = result.register
|
|
158
|
+
should_return = result.should_return
|
|
159
|
+
append = elements.append
|
|
160
|
+
|
|
161
|
+
for nelement in node.elements:
|
|
162
|
+
append(register(get_visitor(nelement.__class__)(nelement, context)))
|
|
163
|
+
if should_return():
|
|
164
|
+
return result
|
|
165
|
+
|
|
166
|
+
return result.success(tuple(elements))
|
|
167
|
+
|
|
168
|
+
def visit_AttributeNode(node, context):
|
|
169
|
+
result = PysRunTimeResult()
|
|
170
|
+
|
|
171
|
+
should_return = result.should_return
|
|
172
|
+
nattribute = node.attribute
|
|
173
|
+
ntarget = node.target
|
|
174
|
+
|
|
175
|
+
target = result.register(get_visitor(ntarget.__class__)(ntarget, context))
|
|
176
|
+
if should_return():
|
|
177
|
+
return result
|
|
178
|
+
|
|
179
|
+
with result(context, nattribute.position):
|
|
180
|
+
return result.success(getattr(target, nattribute.value))
|
|
181
|
+
|
|
182
|
+
if should_return():
|
|
183
|
+
return result
|
|
184
|
+
|
|
185
|
+
def visit_SubscriptNode(node, context):
|
|
186
|
+
result = PysRunTimeResult()
|
|
187
|
+
|
|
188
|
+
register = result.register
|
|
189
|
+
should_return = result.should_return
|
|
190
|
+
ntarget = node.target
|
|
191
|
+
|
|
192
|
+
target = register(get_visitor(ntarget.__class__)(ntarget, context))
|
|
193
|
+
if should_return():
|
|
194
|
+
return result
|
|
195
|
+
|
|
196
|
+
slice = register(visit_slice_SubscriptNode(node.slice, context))
|
|
197
|
+
if should_return():
|
|
198
|
+
return result
|
|
199
|
+
|
|
200
|
+
with result(context, node.position):
|
|
201
|
+
return result.success(target[slice])
|
|
202
|
+
|
|
203
|
+
if should_return():
|
|
204
|
+
return result
|
|
205
|
+
|
|
206
|
+
def visit_CallNode(node, context):
|
|
207
|
+
result = PysRunTimeResult()
|
|
208
|
+
|
|
209
|
+
args = []
|
|
210
|
+
kwargs = {}
|
|
211
|
+
|
|
212
|
+
register = result.register
|
|
213
|
+
should_return = result.should_return
|
|
214
|
+
append = args.append
|
|
215
|
+
setitem = kwargs.__setitem__
|
|
216
|
+
nposition = node.position
|
|
217
|
+
ntarget = node.target
|
|
218
|
+
|
|
219
|
+
target = register(get_visitor(ntarget.__class__)(ntarget, context))
|
|
220
|
+
if should_return():
|
|
221
|
+
return result
|
|
222
|
+
|
|
223
|
+
for nargument in node.arguments:
|
|
224
|
+
|
|
225
|
+
if nargument.__class__ is tuple:
|
|
226
|
+
keyword, nvalue = nargument
|
|
227
|
+
setitem(keyword.value, register(get_visitor(nvalue.__class__)(nvalue, context)))
|
|
228
|
+
if should_return():
|
|
229
|
+
return result
|
|
230
|
+
|
|
231
|
+
else:
|
|
232
|
+
append(register(get_visitor(nargument.__class__)(nargument, context)))
|
|
233
|
+
if should_return():
|
|
234
|
+
return result
|
|
235
|
+
|
|
236
|
+
with result(context, nposition):
|
|
237
|
+
handle_call(target, context, nposition)
|
|
238
|
+
return result.success(target(*args, **kwargs))
|
|
239
|
+
|
|
240
|
+
if should_return():
|
|
241
|
+
return result
|
|
242
|
+
|
|
243
|
+
def visit_ChainOperatorNode(node, context):
|
|
244
|
+
result = PysRunTimeResult()
|
|
245
|
+
|
|
246
|
+
register = result.register
|
|
247
|
+
should_return = result.should_return
|
|
248
|
+
nposition = node.position
|
|
249
|
+
get_expression = node.expressions.__getitem__
|
|
250
|
+
first = get_expression(0)
|
|
251
|
+
|
|
252
|
+
left = register(get_visitor(first.__class__)(first, context))
|
|
253
|
+
if should_return():
|
|
254
|
+
return result
|
|
255
|
+
|
|
256
|
+
with result(context, nposition):
|
|
257
|
+
|
|
258
|
+
for i, toperand in enumerate(node.operations, start=1):
|
|
259
|
+
otype = toperand.type
|
|
260
|
+
ovalue = toperand.value
|
|
261
|
+
nexpression = get_expression(i)
|
|
262
|
+
|
|
263
|
+
right = register(get_visitor(nexpression.__class__)(nexpression, context))
|
|
264
|
+
if should_return():
|
|
265
|
+
return result
|
|
266
|
+
|
|
267
|
+
if otype == T_KEYWORD and ovalue == 'in':
|
|
268
|
+
value = left in right
|
|
269
|
+
elif otype == T_KEYWORD and ovalue == 'is':
|
|
270
|
+
value = left is right
|
|
271
|
+
elif otype == T_CE:
|
|
272
|
+
handle_call(ce, context, nposition)
|
|
273
|
+
value = ce(left, right)
|
|
274
|
+
elif otype == T_NCE:
|
|
275
|
+
handle_call(nce, context, nposition)
|
|
276
|
+
value = nce(left, right)
|
|
277
|
+
else:
|
|
278
|
+
value = BINARY_FUNCTIONS_MAP(otype)(left, right)
|
|
279
|
+
|
|
280
|
+
if not value:
|
|
281
|
+
break
|
|
282
|
+
|
|
283
|
+
left = right
|
|
284
|
+
|
|
285
|
+
if should_return():
|
|
286
|
+
return result
|
|
287
|
+
|
|
288
|
+
return result.success(value)
|
|
289
|
+
|
|
290
|
+
def visit_TernaryOperatorNode(node, context):
|
|
291
|
+
result = PysRunTimeResult()
|
|
292
|
+
|
|
293
|
+
register = result.register
|
|
294
|
+
should_return = result.should_return
|
|
295
|
+
ncondition = node.condition
|
|
296
|
+
|
|
297
|
+
condition = register(get_visitor(ncondition.__class__)(ncondition, context))
|
|
298
|
+
if should_return():
|
|
299
|
+
return result
|
|
300
|
+
|
|
301
|
+
with result(context, node.position):
|
|
302
|
+
nvalue = node.valid if condition else node.invalid
|
|
303
|
+
value = register(get_visitor(nvalue.__class__)(nvalue, context))
|
|
304
|
+
if should_return():
|
|
305
|
+
return result
|
|
306
|
+
|
|
307
|
+
return result.success(value)
|
|
308
|
+
|
|
309
|
+
if should_return():
|
|
310
|
+
return result
|
|
311
|
+
|
|
312
|
+
def visit_BinaryOperatorNode(node, context):
|
|
313
|
+
result = PysRunTimeResult()
|
|
314
|
+
|
|
315
|
+
register = result.register
|
|
316
|
+
should_return = result.should_return
|
|
317
|
+
otype = node.operand.type
|
|
318
|
+
ovalue = node.operand.value
|
|
319
|
+
nleft = node.left
|
|
320
|
+
nright = node.right
|
|
321
|
+
|
|
322
|
+
left = register(get_visitor(nleft.__class__)(nleft, context))
|
|
323
|
+
if should_return():
|
|
324
|
+
return result
|
|
325
|
+
|
|
326
|
+
with result(context, node.position):
|
|
327
|
+
should_return_right = True
|
|
328
|
+
|
|
329
|
+
if (otype == T_KEYWORD and ovalue == 'and') or otype == T_AND:
|
|
330
|
+
if not left:
|
|
331
|
+
return result.success(left)
|
|
332
|
+
elif (otype == T_KEYWORD and ovalue == 'or') or otype == T_OR:
|
|
333
|
+
if left:
|
|
334
|
+
return result.success(left)
|
|
335
|
+
elif otype == T_NULLISH:
|
|
336
|
+
if left is not None:
|
|
337
|
+
return result.success(left)
|
|
338
|
+
else:
|
|
339
|
+
should_return_right = False
|
|
340
|
+
|
|
341
|
+
right = register(get_visitor(nright.__class__)(nright, context))
|
|
342
|
+
if should_return():
|
|
343
|
+
return result
|
|
344
|
+
|
|
345
|
+
return result.success(
|
|
346
|
+
right
|
|
347
|
+
if should_return_right else
|
|
348
|
+
BINARY_FUNCTIONS_MAP(otype)(left, right)
|
|
349
|
+
)
|
|
350
|
+
|
|
351
|
+
if should_return():
|
|
352
|
+
return result
|
|
353
|
+
|
|
354
|
+
def visit_UnaryOperatorNode(node, context):
|
|
355
|
+
result = PysRunTimeResult()
|
|
356
|
+
|
|
357
|
+
register = result.register
|
|
358
|
+
should_return = result.should_return
|
|
359
|
+
otype = node.operand.type
|
|
360
|
+
ovalue = node.operand.value
|
|
361
|
+
nvalue = node.value
|
|
362
|
+
|
|
363
|
+
value = register(get_visitor(nvalue.__class__)(nvalue, context))
|
|
364
|
+
if should_return():
|
|
365
|
+
return result
|
|
366
|
+
|
|
367
|
+
with result(context, node.position):
|
|
368
|
+
if (otype == T_KEYWORD and ovalue == 'not') or otype == T_NOT:
|
|
369
|
+
return result.success(not value)
|
|
370
|
+
elif (otype == T_KEYWORD and ovalue == 'typeof'):
|
|
371
|
+
return result.success(type(value).__name__)
|
|
372
|
+
return result.success(UNARY_FUNCTIONS_MAP(otype)(value))
|
|
373
|
+
|
|
374
|
+
if should_return():
|
|
375
|
+
return result
|
|
376
|
+
|
|
377
|
+
def visit_IncrementalNode(node, context):
|
|
378
|
+
result = PysRunTimeResult()
|
|
379
|
+
|
|
380
|
+
register = result.register
|
|
381
|
+
should_return = result.should_return
|
|
382
|
+
nposition = node.position
|
|
383
|
+
ntarget = node.target
|
|
384
|
+
|
|
385
|
+
value = register(get_visitor(ntarget.__class__)(ntarget, context))
|
|
386
|
+
if should_return():
|
|
387
|
+
return result
|
|
388
|
+
|
|
389
|
+
with result(context, nposition):
|
|
390
|
+
handle_call(function := get_incremental_function(node.operand.type), context, nposition)
|
|
391
|
+
increast_value = function(value)
|
|
392
|
+
|
|
393
|
+
if node.operand_position == 'left':
|
|
394
|
+
value = increast_value
|
|
395
|
+
|
|
396
|
+
register(visit_declaration_AssignmentNode(ntarget, context, increast_value))
|
|
397
|
+
if should_return():
|
|
398
|
+
return result
|
|
399
|
+
|
|
400
|
+
return result.success(value)
|
|
401
|
+
|
|
402
|
+
if should_return():
|
|
403
|
+
return result
|
|
404
|
+
|
|
405
|
+
def visit_StatementsNode(node, context):
|
|
406
|
+
result = PysRunTimeResult()
|
|
407
|
+
|
|
408
|
+
register = result.register
|
|
409
|
+
should_return = result.should_return
|
|
410
|
+
body = node.body
|
|
411
|
+
|
|
412
|
+
if len(body) == 1:
|
|
413
|
+
nvalue = body[0]
|
|
414
|
+
value = register(get_visitor(nvalue.__class__)(nvalue, context))
|
|
415
|
+
if should_return():
|
|
416
|
+
return result
|
|
417
|
+
|
|
418
|
+
return result.success(value)
|
|
419
|
+
|
|
420
|
+
for nelement in body:
|
|
421
|
+
register(get_visitor(nelement.__class__)(nelement, context))
|
|
422
|
+
if should_return():
|
|
423
|
+
return result
|
|
424
|
+
|
|
425
|
+
return result.success(None)
|
|
426
|
+
|
|
427
|
+
def visit_AssignmentNode(node, context):
|
|
428
|
+
result = PysRunTimeResult()
|
|
429
|
+
|
|
430
|
+
register = result.register
|
|
431
|
+
should_return = result.should_return
|
|
432
|
+
nvalue = node.value
|
|
433
|
+
|
|
434
|
+
value = register(get_visitor(nvalue.__class__)(nvalue, context))
|
|
435
|
+
if should_return():
|
|
436
|
+
return result
|
|
437
|
+
|
|
438
|
+
register(visit_declaration_AssignmentNode(node.target, context, value, node.operand.type))
|
|
439
|
+
if should_return():
|
|
440
|
+
return result
|
|
441
|
+
|
|
442
|
+
return result.success(value)
|
|
443
|
+
|
|
444
|
+
def visit_ImportNode(node, context):
|
|
445
|
+
result = PysRunTimeResult()
|
|
446
|
+
|
|
447
|
+
should_return = result.should_return
|
|
448
|
+
get_symbol = context.symbol_table.get
|
|
449
|
+
set_symbol = context.symbol_table.set
|
|
450
|
+
npackages = node.packages
|
|
451
|
+
tname, tas_name = node.name
|
|
452
|
+
name_position = tname.position
|
|
453
|
+
|
|
454
|
+
with result(context, name_position):
|
|
455
|
+
name_module = tname.value
|
|
456
|
+
use_python_package = False
|
|
457
|
+
|
|
458
|
+
require = get_symbol('require')
|
|
459
|
+
|
|
460
|
+
if require is undefined:
|
|
461
|
+
use_python_package = True
|
|
462
|
+
else:
|
|
463
|
+
handle_call(require, context, name_position)
|
|
464
|
+
try:
|
|
465
|
+
module = require(name_module)
|
|
466
|
+
except ModuleNotFoundError:
|
|
467
|
+
use_python_package = True
|
|
468
|
+
|
|
469
|
+
if use_python_package:
|
|
470
|
+
pyimport = get_symbol('pyimport')
|
|
471
|
+
|
|
472
|
+
if pyimport is undefined:
|
|
473
|
+
pyimport = get_symbol('__import__')
|
|
474
|
+
|
|
475
|
+
if pyimport is undefined:
|
|
476
|
+
return result.failure(
|
|
477
|
+
PysTraceback(
|
|
478
|
+
NameError("names 'require', 'pyimport', and '__import__' is not defined"),
|
|
479
|
+
context,
|
|
480
|
+
node.position
|
|
481
|
+
)
|
|
482
|
+
)
|
|
483
|
+
|
|
484
|
+
handle_call(pyimport, context, name_position)
|
|
485
|
+
module = pyimport(name_module)
|
|
486
|
+
|
|
487
|
+
if should_return():
|
|
488
|
+
return result
|
|
489
|
+
|
|
490
|
+
if npackages == 'all':
|
|
491
|
+
|
|
492
|
+
with result(context, name_position):
|
|
493
|
+
exported_from = '__all__'
|
|
494
|
+
exported_packages = getattr(module, exported_from, undefined)
|
|
495
|
+
if exported_packages is undefined:
|
|
496
|
+
exported_from = '__dir__()'
|
|
497
|
+
exported_packages = filter(is_public_attribute, dir(module))
|
|
498
|
+
|
|
499
|
+
for package in exported_packages:
|
|
500
|
+
|
|
501
|
+
if not isinstance(package, str):
|
|
502
|
+
return result.failure(
|
|
503
|
+
PysTraceback(
|
|
504
|
+
TypeError(
|
|
505
|
+
f"Item in {module.__name__}.{exported_from} must be str, not {type(package).__name__}"
|
|
506
|
+
),
|
|
507
|
+
context,
|
|
508
|
+
name_position
|
|
509
|
+
)
|
|
510
|
+
)
|
|
511
|
+
|
|
512
|
+
set_symbol(package, getattr(module, package))
|
|
513
|
+
|
|
514
|
+
if should_return():
|
|
515
|
+
return result
|
|
516
|
+
|
|
517
|
+
elif npackages:
|
|
518
|
+
|
|
519
|
+
for tpackage, tas_package in npackages:
|
|
520
|
+
|
|
521
|
+
with result(context, tpackage.position):
|
|
522
|
+
set_symbol(
|
|
523
|
+
(tpackage if tas_package is None else tas_package).value,
|
|
524
|
+
getattr(module, tpackage.value)
|
|
525
|
+
)
|
|
526
|
+
|
|
527
|
+
if should_return():
|
|
528
|
+
return result
|
|
529
|
+
|
|
530
|
+
elif not (tname.type == T_STRING and tas_name is None):
|
|
531
|
+
|
|
532
|
+
with result(context, node.position):
|
|
533
|
+
set_symbol((tname if tas_name is None else tas_name).value, module)
|
|
534
|
+
|
|
535
|
+
if should_return():
|
|
536
|
+
return result
|
|
537
|
+
|
|
538
|
+
return result.success(None)
|
|
539
|
+
|
|
540
|
+
def visit_IfNode(node, context):
|
|
541
|
+
result = PysRunTimeResult()
|
|
542
|
+
|
|
543
|
+
register = result.register
|
|
544
|
+
should_return = result.should_return
|
|
545
|
+
else_body = node.else_body
|
|
546
|
+
|
|
547
|
+
for ncondition, body in node.cases_body:
|
|
548
|
+
condition = register(get_visitor(ncondition.__class__)(ncondition, context))
|
|
549
|
+
if should_return():
|
|
550
|
+
return result
|
|
551
|
+
|
|
552
|
+
with result(context, ncondition.position):
|
|
553
|
+
condition = True if condition else False
|
|
554
|
+
|
|
555
|
+
if should_return():
|
|
556
|
+
return result
|
|
557
|
+
|
|
558
|
+
if condition:
|
|
559
|
+
register(get_visitor(body.__class__)(body, context))
|
|
560
|
+
if should_return():
|
|
561
|
+
return result
|
|
562
|
+
|
|
563
|
+
return result.success(None)
|
|
564
|
+
|
|
565
|
+
if else_body:
|
|
566
|
+
register(get_visitor(else_body.__class__)(else_body, context))
|
|
567
|
+
if should_return():
|
|
568
|
+
return result
|
|
569
|
+
|
|
570
|
+
return result.success(None)
|
|
571
|
+
|
|
572
|
+
def visit_SwitchNode(node, context):
|
|
573
|
+
result = PysRunTimeResult()
|
|
574
|
+
|
|
575
|
+
register = result.register
|
|
576
|
+
should_return = result.should_return
|
|
577
|
+
default_body = node.default_body
|
|
578
|
+
ntarget = node.target
|
|
579
|
+
|
|
580
|
+
fall_through = False
|
|
581
|
+
no_match_found = True
|
|
582
|
+
|
|
583
|
+
target = register(get_visitor(ntarget.__class__)(ntarget, context))
|
|
584
|
+
if should_return():
|
|
585
|
+
return result
|
|
586
|
+
|
|
587
|
+
for ncondition, body in node.case_cases:
|
|
588
|
+
case = register(get_visitor(ncondition.__class__)(ncondition, context))
|
|
589
|
+
if should_return():
|
|
590
|
+
return result
|
|
591
|
+
|
|
592
|
+
with result(context, ncondition.position):
|
|
593
|
+
equal = True if target == case else False
|
|
594
|
+
|
|
595
|
+
if should_return():
|
|
596
|
+
return result
|
|
597
|
+
|
|
598
|
+
if fall_through or equal:
|
|
599
|
+
no_match_found = False
|
|
600
|
+
|
|
601
|
+
register(get_visitor(body.__class__)(body, context))
|
|
602
|
+
if should_return() and not result.should_break:
|
|
603
|
+
return result
|
|
604
|
+
|
|
605
|
+
if result.should_break:
|
|
606
|
+
result.should_break = False
|
|
607
|
+
fall_through = False
|
|
608
|
+
else:
|
|
609
|
+
fall_through = True
|
|
610
|
+
|
|
611
|
+
if (fall_through or no_match_found) and default_body:
|
|
612
|
+
register(get_visitor(default_body.__class__)(default_body, context))
|
|
613
|
+
if should_return() and not result.should_break:
|
|
614
|
+
return result
|
|
615
|
+
|
|
616
|
+
result.should_break = False
|
|
617
|
+
|
|
618
|
+
return result.success(None)
|
|
619
|
+
|
|
620
|
+
def visit_MatchNode(node, context):
|
|
621
|
+
result = PysRunTimeResult()
|
|
622
|
+
|
|
623
|
+
register = result.register
|
|
624
|
+
should_return = result.should_return
|
|
625
|
+
ntarget = node.target
|
|
626
|
+
|
|
627
|
+
compare = False
|
|
628
|
+
|
|
629
|
+
if ntarget:
|
|
630
|
+
target = register(get_visitor(ntarget.__class__)(ntarget, context))
|
|
631
|
+
if should_return():
|
|
632
|
+
return result
|
|
633
|
+
|
|
634
|
+
compare = True
|
|
635
|
+
|
|
636
|
+
for ncondition, nvalue in node.cases:
|
|
637
|
+
condition = register(get_visitor(ncondition.__class__)(ncondition, context))
|
|
638
|
+
if should_return():
|
|
639
|
+
return result
|
|
640
|
+
|
|
641
|
+
with result(context, ncondition.position):
|
|
642
|
+
valid = target == condition if compare else (True if condition else False)
|
|
643
|
+
|
|
644
|
+
if should_return():
|
|
645
|
+
return result
|
|
646
|
+
|
|
647
|
+
if valid:
|
|
648
|
+
value = register(get_visitor(nvalue.__class__)(nvalue, context))
|
|
649
|
+
if should_return():
|
|
650
|
+
return result
|
|
651
|
+
|
|
652
|
+
return result.success(value)
|
|
653
|
+
|
|
654
|
+
ndefault = node.default
|
|
655
|
+
|
|
656
|
+
if ndefault:
|
|
657
|
+
default = register(get_visitor(ndefault.__class__)(ndefault, context))
|
|
658
|
+
if should_return():
|
|
659
|
+
return result
|
|
660
|
+
|
|
661
|
+
return result.success(default)
|
|
662
|
+
|
|
663
|
+
return result.success(None)
|
|
664
|
+
|
|
665
|
+
def visit_TryNode(node, context):
|
|
666
|
+
result = PysRunTimeResult()
|
|
667
|
+
|
|
668
|
+
register = result.register
|
|
669
|
+
failure = result.failure
|
|
670
|
+
should_return = result.should_return
|
|
671
|
+
body = node.body
|
|
672
|
+
else_body = node.else_body
|
|
673
|
+
finally_body = node.finally_body
|
|
674
|
+
|
|
675
|
+
register(get_visitor(body.__class__)(body, context))
|
|
676
|
+
error = result.error
|
|
677
|
+
|
|
678
|
+
if error:
|
|
679
|
+
exception = error.exception
|
|
680
|
+
failure(None)
|
|
681
|
+
|
|
682
|
+
for (targets, tparameter), body in node.catch_cases:
|
|
683
|
+
handle_exception = True
|
|
684
|
+
stop = False
|
|
685
|
+
|
|
686
|
+
if targets:
|
|
687
|
+
handle_exception = False
|
|
688
|
+
|
|
689
|
+
for nerror_class in targets:
|
|
690
|
+
error_class = register(visit_IdentifierNode(nerror_class, context))
|
|
691
|
+
if result.error:
|
|
692
|
+
setimuattr(result.error, 'cause', error)
|
|
693
|
+
stop = True
|
|
694
|
+
break
|
|
695
|
+
|
|
696
|
+
if not (isinstance(error_class, type) and issubclass(error_class, BaseException)):
|
|
697
|
+
failure(
|
|
698
|
+
PysTraceback(
|
|
699
|
+
TypeError("catching classes that do not inherit from BaseException is not allowed"),
|
|
700
|
+
context,
|
|
701
|
+
nerror_class.position,
|
|
702
|
+
error
|
|
703
|
+
)
|
|
704
|
+
)
|
|
705
|
+
stop = True
|
|
706
|
+
break
|
|
707
|
+
|
|
708
|
+
if is_object_of(exception, error_class):
|
|
709
|
+
handle_exception = True
|
|
710
|
+
break
|
|
711
|
+
|
|
712
|
+
if stop:
|
|
713
|
+
break
|
|
714
|
+
|
|
715
|
+
elif handle_exception:
|
|
716
|
+
|
|
717
|
+
if tparameter:
|
|
718
|
+
with result(context, position := tparameter.position):
|
|
719
|
+
(symbol_table := context.symbol_table).set(parameter := tparameter.value, error.exception)
|
|
720
|
+
if should_return():
|
|
721
|
+
break
|
|
722
|
+
|
|
723
|
+
register(get_visitor(body.__class__)(body, context))
|
|
724
|
+
if result.error:
|
|
725
|
+
setimuattr(result.error, 'cause', error)
|
|
726
|
+
|
|
727
|
+
if tparameter:
|
|
728
|
+
with result(context, position):
|
|
729
|
+
symbol_table.remove(parameter)
|
|
730
|
+
if should_return():
|
|
731
|
+
break
|
|
732
|
+
|
|
733
|
+
break
|
|
734
|
+
|
|
735
|
+
else:
|
|
736
|
+
failure(error)
|
|
737
|
+
|
|
738
|
+
elif else_body:
|
|
739
|
+
register(get_visitor(else_body.__class__)(else_body, context))
|
|
740
|
+
|
|
741
|
+
if finally_body:
|
|
742
|
+
finally_result = PysRunTimeResult()
|
|
743
|
+
finally_result.register(get_visitor(finally_body.__class__)(finally_body, context))
|
|
744
|
+
if finally_result.should_return():
|
|
745
|
+
if finally_result.error:
|
|
746
|
+
setimuattr(finally_result.error, 'cause', result.error)
|
|
747
|
+
return finally_result
|
|
748
|
+
|
|
749
|
+
if should_return():
|
|
750
|
+
return result
|
|
751
|
+
|
|
752
|
+
return result.success(None)
|
|
753
|
+
|
|
754
|
+
def visit_WithNode(node, context):
|
|
755
|
+
result = PysRunTimeResult()
|
|
756
|
+
|
|
757
|
+
exits = []
|
|
758
|
+
|
|
759
|
+
register = result.register
|
|
760
|
+
failure = result.failure
|
|
761
|
+
should_return = result.should_return
|
|
762
|
+
append = exits.append
|
|
763
|
+
set_symbol = context.symbol_table.set
|
|
764
|
+
|
|
765
|
+
for ncontext, nalias in node.contexts:
|
|
766
|
+
context_value = register(get_visitor(ncontext.__class__)(ncontext, context))
|
|
767
|
+
if should_return():
|
|
768
|
+
break
|
|
769
|
+
|
|
770
|
+
ncontext_position = ncontext.position
|
|
771
|
+
|
|
772
|
+
with result(context, ncontext_position):
|
|
773
|
+
enter = getattr(context_value, '__enter__', undefined)
|
|
774
|
+
exit = getattr(context_value, '__exit__', undefined)
|
|
775
|
+
|
|
776
|
+
missed_enter = enter is undefined
|
|
777
|
+
missed_exit = exit is undefined
|
|
778
|
+
|
|
779
|
+
if missed_enter or missed_exit:
|
|
780
|
+
message = f"{type(context_value).__name__!r} object does not support the context manager protocol"
|
|
781
|
+
|
|
782
|
+
if missed_enter and missed_exit:
|
|
783
|
+
pass
|
|
784
|
+
elif missed_enter:
|
|
785
|
+
message += " (missed __enter__ method)"
|
|
786
|
+
elif missed_exit:
|
|
787
|
+
message += " (missed __exit__ method)"
|
|
788
|
+
|
|
789
|
+
result.failure(
|
|
790
|
+
PysTraceback(
|
|
791
|
+
TypeError(message),
|
|
792
|
+
context,
|
|
793
|
+
ncontext_position
|
|
794
|
+
)
|
|
795
|
+
)
|
|
796
|
+
break
|
|
797
|
+
|
|
798
|
+
handle_call(enter, context, ncontext_position)
|
|
799
|
+
enter_value = enter()
|
|
800
|
+
append((exit, ncontext_position))
|
|
801
|
+
|
|
802
|
+
if should_return():
|
|
803
|
+
break
|
|
804
|
+
|
|
805
|
+
if nalias:
|
|
806
|
+
with result(context, nalias.position):
|
|
807
|
+
set_symbol(nalias.value, enter_value)
|
|
808
|
+
if should_return():
|
|
809
|
+
break
|
|
810
|
+
|
|
811
|
+
if not should_return():
|
|
812
|
+
body = node.body
|
|
813
|
+
register(get_visitor(body.__class__)(body, context))
|
|
814
|
+
|
|
815
|
+
error = result.error
|
|
816
|
+
|
|
817
|
+
for exit, ncontext_position in reversed(exits):
|
|
818
|
+
with result(context, ncontext_position):
|
|
819
|
+
handle_call(exit, context, ncontext_position)
|
|
820
|
+
if exit(*get_error_args(error)):
|
|
821
|
+
failure(None)
|
|
822
|
+
error = None
|
|
823
|
+
|
|
824
|
+
if should_return():
|
|
825
|
+
if result.error and result.error is not error:
|
|
826
|
+
setimuattr(result.error, 'cause', error)
|
|
827
|
+
return result
|
|
828
|
+
|
|
829
|
+
return result.success(None)
|
|
830
|
+
|
|
831
|
+
def visit_ForNode(node, context):
|
|
832
|
+
result = PysRunTimeResult()
|
|
833
|
+
|
|
834
|
+
register = result.register
|
|
835
|
+
should_return = result.should_return
|
|
836
|
+
nheader = node.header
|
|
837
|
+
nheader_length = len(nheader)
|
|
838
|
+
body = node.body
|
|
839
|
+
body_class = body.__class__
|
|
840
|
+
else_body = node.else_body
|
|
841
|
+
|
|
842
|
+
if nheader_length == 2:
|
|
843
|
+
ndeclaration, niteration = nheader
|
|
844
|
+
niteration_position = niteration.position
|
|
845
|
+
|
|
846
|
+
iteration = register(get_visitor(niteration.__class__)(niteration, context))
|
|
847
|
+
if should_return():
|
|
848
|
+
return result
|
|
849
|
+
|
|
850
|
+
with result(context, niteration_position):
|
|
851
|
+
handle_call(getattr(iteration, '__iter__', None), context, niteration_position)
|
|
852
|
+
next = iter(iteration).__next__
|
|
853
|
+
|
|
854
|
+
if should_return():
|
|
855
|
+
return result
|
|
856
|
+
|
|
857
|
+
def condition():
|
|
858
|
+
with result(context, niteration_position):
|
|
859
|
+
handle_call(next, context, niteration_position)
|
|
860
|
+
register(visit_declaration_AssignmentNode(ndeclaration, context, next()))
|
|
861
|
+
|
|
862
|
+
if should_return():
|
|
863
|
+
if result.error and is_object_of(result.error.exception, StopIteration):
|
|
864
|
+
result.failure(None)
|
|
865
|
+
return False
|
|
866
|
+
|
|
867
|
+
return True
|
|
868
|
+
|
|
869
|
+
def update():
|
|
870
|
+
pass
|
|
871
|
+
|
|
872
|
+
elif nheader_length == 3:
|
|
873
|
+
ndeclaration, ncondition, nupdate = nheader
|
|
874
|
+
|
|
875
|
+
if ndeclaration:
|
|
876
|
+
register(get_visitor(ndeclaration.__class__)(ndeclaration, context))
|
|
877
|
+
if should_return():
|
|
878
|
+
return result
|
|
879
|
+
|
|
880
|
+
if ncondition:
|
|
881
|
+
ncondition_class = ncondition.__class__
|
|
882
|
+
ncondition_position = ncondition.position
|
|
883
|
+
def condition():
|
|
884
|
+
value = register(get_visitor(ncondition_class)(ncondition, context))
|
|
885
|
+
if should_return():
|
|
886
|
+
return False
|
|
887
|
+
with result(context, ncondition_position):
|
|
888
|
+
return True if value else False
|
|
889
|
+
|
|
890
|
+
else:
|
|
891
|
+
def condition():
|
|
892
|
+
return True
|
|
893
|
+
|
|
894
|
+
if nupdate:
|
|
895
|
+
nupdate_class = nupdate.__class__
|
|
896
|
+
def update():
|
|
897
|
+
register(get_visitor(nupdate_class)(nupdate, context))
|
|
898
|
+
|
|
899
|
+
else:
|
|
900
|
+
def update():
|
|
901
|
+
pass
|
|
902
|
+
|
|
903
|
+
while True:
|
|
904
|
+
done = condition()
|
|
905
|
+
if should_return():
|
|
906
|
+
return result
|
|
907
|
+
|
|
908
|
+
if not done:
|
|
909
|
+
break
|
|
910
|
+
|
|
911
|
+
register(get_visitor(body_class)(body, context))
|
|
912
|
+
if should_return():
|
|
913
|
+
if result.should_continue:
|
|
914
|
+
result.should_continue = False
|
|
915
|
+
elif result.should_break:
|
|
916
|
+
break
|
|
917
|
+
else:
|
|
918
|
+
return result
|
|
919
|
+
|
|
920
|
+
update()
|
|
921
|
+
if should_return():
|
|
922
|
+
return result
|
|
923
|
+
|
|
924
|
+
if result.should_break:
|
|
925
|
+
result.should_break = False
|
|
926
|
+
|
|
927
|
+
elif else_body:
|
|
928
|
+
register(get_visitor(else_body.__class__)(else_body, context))
|
|
929
|
+
if should_return():
|
|
930
|
+
return result
|
|
931
|
+
|
|
932
|
+
return result.success(None)
|
|
933
|
+
|
|
934
|
+
def visit_WhileNode(node, context):
|
|
935
|
+
result = PysRunTimeResult()
|
|
936
|
+
|
|
937
|
+
register = result.register
|
|
938
|
+
should_return = result.should_return
|
|
939
|
+
ncondition = node.condition
|
|
940
|
+
ncondition_class = ncondition.__class__
|
|
941
|
+
ncondition_position = ncondition.position
|
|
942
|
+
body = node.body
|
|
943
|
+
body_class = body.__class__
|
|
944
|
+
else_body = node.else_body
|
|
945
|
+
|
|
946
|
+
while True:
|
|
947
|
+
condition = register(get_visitor(ncondition_class)(ncondition, context))
|
|
948
|
+
if should_return():
|
|
949
|
+
return result
|
|
950
|
+
|
|
951
|
+
with result(context, ncondition_position):
|
|
952
|
+
if not condition:
|
|
953
|
+
break
|
|
954
|
+
|
|
955
|
+
if should_return():
|
|
956
|
+
return result
|
|
957
|
+
|
|
958
|
+
register(get_visitor(body_class)(body, context))
|
|
959
|
+
if should_return():
|
|
960
|
+
if result.should_continue:
|
|
961
|
+
result.should_continue = False
|
|
962
|
+
elif result.should_break:
|
|
963
|
+
break
|
|
964
|
+
else:
|
|
965
|
+
return result
|
|
966
|
+
|
|
967
|
+
if result.should_break:
|
|
968
|
+
result.should_break = False
|
|
969
|
+
|
|
970
|
+
elif else_body:
|
|
971
|
+
register(get_visitor(else_body.__class__)(else_body, context))
|
|
972
|
+
if should_return():
|
|
973
|
+
return result
|
|
974
|
+
|
|
975
|
+
return result.success(None)
|
|
976
|
+
|
|
977
|
+
def visit_DoWhileNode(node, context):
|
|
978
|
+
result = PysRunTimeResult()
|
|
979
|
+
|
|
980
|
+
register = result.register
|
|
981
|
+
should_return = result.should_return
|
|
982
|
+
ncondition = node.condition
|
|
983
|
+
ncondition_class = ncondition.__class__
|
|
984
|
+
ncondition_position = ncondition.position
|
|
985
|
+
body = node.body
|
|
986
|
+
body_class = body.__class__
|
|
987
|
+
else_body = node.else_body
|
|
988
|
+
|
|
989
|
+
while True:
|
|
990
|
+
register(get_visitor(body_class)(body, context))
|
|
991
|
+
if should_return():
|
|
992
|
+
if result.should_continue:
|
|
993
|
+
result.should_continue = False
|
|
994
|
+
elif result.should_break:
|
|
995
|
+
break
|
|
996
|
+
else:
|
|
997
|
+
return result
|
|
998
|
+
|
|
999
|
+
condition = register(get_visitor(ncondition_class)(ncondition, context))
|
|
1000
|
+
if should_return():
|
|
1001
|
+
return result
|
|
1002
|
+
|
|
1003
|
+
with result(context, ncondition_position):
|
|
1004
|
+
if not condition:
|
|
1005
|
+
break
|
|
1006
|
+
|
|
1007
|
+
if should_return():
|
|
1008
|
+
return result
|
|
1009
|
+
|
|
1010
|
+
if result.should_break:
|
|
1011
|
+
result.should_break = False
|
|
1012
|
+
|
|
1013
|
+
elif else_body:
|
|
1014
|
+
register(get_visitor(else_body.__class__)(else_body, context))
|
|
1015
|
+
if should_return():
|
|
1016
|
+
return result
|
|
1017
|
+
|
|
1018
|
+
return result.success(None)
|
|
1019
|
+
|
|
1020
|
+
def visit_RepeatNode(node, context):
|
|
1021
|
+
result = PysRunTimeResult()
|
|
1022
|
+
|
|
1023
|
+
register = result.register
|
|
1024
|
+
should_return = result.should_return
|
|
1025
|
+
ncondition = node.condition
|
|
1026
|
+
ncondition_class = ncondition.__class__
|
|
1027
|
+
ncondition_position = ncondition.position
|
|
1028
|
+
body = node.body
|
|
1029
|
+
body_class = body.__class__
|
|
1030
|
+
else_body = node.else_body
|
|
1031
|
+
|
|
1032
|
+
while True:
|
|
1033
|
+
register(get_visitor(body_class)(body, context))
|
|
1034
|
+
if should_return():
|
|
1035
|
+
if result.should_continue:
|
|
1036
|
+
result.should_continue = False
|
|
1037
|
+
elif result.should_break:
|
|
1038
|
+
break
|
|
1039
|
+
else:
|
|
1040
|
+
return result
|
|
1041
|
+
|
|
1042
|
+
condition = register(get_visitor(ncondition_class)(ncondition, context))
|
|
1043
|
+
if should_return():
|
|
1044
|
+
return result
|
|
1045
|
+
|
|
1046
|
+
with result(context, ncondition_position):
|
|
1047
|
+
if condition:
|
|
1048
|
+
break
|
|
1049
|
+
|
|
1050
|
+
if should_return():
|
|
1051
|
+
return result
|
|
1052
|
+
|
|
1053
|
+
if result.should_break:
|
|
1054
|
+
result.should_break = False
|
|
1055
|
+
|
|
1056
|
+
elif else_body:
|
|
1057
|
+
register(get_visitor(else_body.__class__)(else_body, context))
|
|
1058
|
+
if should_return():
|
|
1059
|
+
return result
|
|
1060
|
+
|
|
1061
|
+
return result.success(None)
|
|
1062
|
+
|
|
1063
|
+
def visit_ClassNode(node, context):
|
|
1064
|
+
result = PysRunTimeResult()
|
|
1065
|
+
|
|
1066
|
+
bases = []
|
|
1067
|
+
|
|
1068
|
+
register = result.register
|
|
1069
|
+
should_return = result.should_return
|
|
1070
|
+
append = bases.append
|
|
1071
|
+
nposition = node.position
|
|
1072
|
+
name = node.name.value
|
|
1073
|
+
body = node.body
|
|
1074
|
+
symbol_table = context.symbol_table
|
|
1075
|
+
|
|
1076
|
+
for nbase in node.bases:
|
|
1077
|
+
append(register(get_visitor(nbase.__class__)(nbase, context)))
|
|
1078
|
+
if should_return():
|
|
1079
|
+
return result
|
|
1080
|
+
|
|
1081
|
+
class_context = PysClassContext(
|
|
1082
|
+
name=name,
|
|
1083
|
+
symbol_table=PysClassSymbolTable(symbol_table),
|
|
1084
|
+
parent=context,
|
|
1085
|
+
parent_entry_position=nposition
|
|
1086
|
+
)
|
|
1087
|
+
|
|
1088
|
+
register(get_visitor(body.__class__)(body, class_context))
|
|
1089
|
+
if should_return():
|
|
1090
|
+
return result
|
|
1091
|
+
|
|
1092
|
+
with result(context, nposition):
|
|
1093
|
+
cls = type(name, tuple(bases), class_context.symbol_table.symbols)
|
|
1094
|
+
cls.__qualname__ = class_context.qualname
|
|
1095
|
+
|
|
1096
|
+
if should_return():
|
|
1097
|
+
return result
|
|
1098
|
+
|
|
1099
|
+
for ndecorator in reversed(node.decorators):
|
|
1100
|
+
decorator = register(get_visitor(ndecorator.__class__)(ndecorator, context))
|
|
1101
|
+
if should_return():
|
|
1102
|
+
return result
|
|
1103
|
+
|
|
1104
|
+
dposition = ndecorator.position
|
|
1105
|
+
|
|
1106
|
+
with result(context, dposition):
|
|
1107
|
+
handle_call(decorator, context, dposition)
|
|
1108
|
+
cls = decorator(cls)
|
|
1109
|
+
|
|
1110
|
+
if should_return():
|
|
1111
|
+
return result
|
|
1112
|
+
|
|
1113
|
+
with result(context, nposition):
|
|
1114
|
+
symbol_table.set(name, cls)
|
|
1115
|
+
|
|
1116
|
+
if should_return():
|
|
1117
|
+
return result
|
|
1118
|
+
|
|
1119
|
+
return result.success(None)
|
|
1120
|
+
|
|
1121
|
+
def visit_FunctionNode(node, context):
|
|
1122
|
+
result = PysRunTimeResult()
|
|
1123
|
+
|
|
1124
|
+
parameters = []
|
|
1125
|
+
|
|
1126
|
+
register = result.register
|
|
1127
|
+
should_return = result.should_return
|
|
1128
|
+
append = parameters.append
|
|
1129
|
+
nposition = node.position
|
|
1130
|
+
name = None if node.name is None else node.name.value
|
|
1131
|
+
|
|
1132
|
+
for nparameter in node.parameters:
|
|
1133
|
+
|
|
1134
|
+
if nparameter.__class__ is tuple:
|
|
1135
|
+
keyword, nvalue = nparameter
|
|
1136
|
+
|
|
1137
|
+
value = register(get_visitor(nvalue.__class__)(nvalue, context))
|
|
1138
|
+
if should_return():
|
|
1139
|
+
return result
|
|
1140
|
+
|
|
1141
|
+
append((keyword.value, value))
|
|
1142
|
+
|
|
1143
|
+
else:
|
|
1144
|
+
append(nparameter.value)
|
|
1145
|
+
|
|
1146
|
+
function = PysFunction(
|
|
1147
|
+
name=name,
|
|
1148
|
+
qualname=context.qualname,
|
|
1149
|
+
parameters=parameters,
|
|
1150
|
+
body=node.body,
|
|
1151
|
+
context=context,
|
|
1152
|
+
position=nposition
|
|
1153
|
+
)
|
|
1154
|
+
|
|
1155
|
+
for ndecorator in reversed(node.decorators):
|
|
1156
|
+
decorator = register(get_visitor(ndecorator.__class__)(ndecorator, context))
|
|
1157
|
+
if should_return():
|
|
1158
|
+
return result
|
|
1159
|
+
|
|
1160
|
+
dposition = ndecorator.position
|
|
1161
|
+
|
|
1162
|
+
with result(context, dposition):
|
|
1163
|
+
handle_call(decorator, context, dposition)
|
|
1164
|
+
function = decorator(function)
|
|
1165
|
+
|
|
1166
|
+
if should_return():
|
|
1167
|
+
return result
|
|
1168
|
+
|
|
1169
|
+
if name:
|
|
1170
|
+
with result(context, nposition):
|
|
1171
|
+
context.symbol_table.set(name, function)
|
|
1172
|
+
if should_return():
|
|
1173
|
+
return result
|
|
1174
|
+
|
|
1175
|
+
return result.success(function)
|
|
1176
|
+
|
|
1177
|
+
def visit_GlobalNode(node, context):
|
|
1178
|
+
context.symbol_table.globals.update(name.value for name in node.identifiers)
|
|
1179
|
+
return PysRunTimeResult().success(None)
|
|
1180
|
+
|
|
1181
|
+
def visit_ReturnNode(node, context):
|
|
1182
|
+
result = PysRunTimeResult()
|
|
1183
|
+
|
|
1184
|
+
nvalue = node.value
|
|
1185
|
+
|
|
1186
|
+
if nvalue:
|
|
1187
|
+
value = result.register(get_visitor(nvalue.__class__)(nvalue, context))
|
|
1188
|
+
if result.should_return():
|
|
1189
|
+
return result
|
|
1190
|
+
return result.success_return(value)
|
|
1191
|
+
|
|
1192
|
+
return result.success_return(None)
|
|
1193
|
+
|
|
1194
|
+
def visit_ThrowNode(node, context):
|
|
1195
|
+
result = PysRunTimeResult()
|
|
1196
|
+
|
|
1197
|
+
register = result.register
|
|
1198
|
+
should_return = result.should_return
|
|
1199
|
+
ntarget = node.target
|
|
1200
|
+
ncause = node.cause
|
|
1201
|
+
|
|
1202
|
+
target = register(get_visitor(ntarget.__class__)(ntarget, context))
|
|
1203
|
+
if should_return():
|
|
1204
|
+
return result
|
|
1205
|
+
|
|
1206
|
+
if not is_object_of(target, BaseException):
|
|
1207
|
+
return result.failure(
|
|
1208
|
+
PysTraceback(
|
|
1209
|
+
TypeError("exceptions must derive from BaseException"),
|
|
1210
|
+
context,
|
|
1211
|
+
ntarget.position
|
|
1212
|
+
)
|
|
1213
|
+
)
|
|
1214
|
+
|
|
1215
|
+
if ncause:
|
|
1216
|
+
cause = register(get_visitor(ncause.__class__)(ncause, context))
|
|
1217
|
+
if should_return():
|
|
1218
|
+
return result
|
|
1219
|
+
|
|
1220
|
+
if not is_object_of(cause, BaseException):
|
|
1221
|
+
return result.failure(
|
|
1222
|
+
PysTraceback(
|
|
1223
|
+
TypeError("exceptions must derive from BaseException"),
|
|
1224
|
+
context,
|
|
1225
|
+
ncause.position
|
|
1226
|
+
)
|
|
1227
|
+
)
|
|
1228
|
+
|
|
1229
|
+
cause = PysTraceback(
|
|
1230
|
+
cause,
|
|
1231
|
+
context,
|
|
1232
|
+
ncause.position
|
|
1233
|
+
)
|
|
1234
|
+
|
|
1235
|
+
else:
|
|
1236
|
+
cause = None
|
|
1237
|
+
|
|
1238
|
+
return result.failure(
|
|
1239
|
+
PysTraceback(
|
|
1240
|
+
target,
|
|
1241
|
+
context,
|
|
1242
|
+
node.position,
|
|
1243
|
+
cause,
|
|
1244
|
+
True if ncause else False
|
|
1245
|
+
)
|
|
1246
|
+
)
|
|
1247
|
+
|
|
1248
|
+
def visit_AssertNode(node, context):
|
|
1249
|
+
result = PysRunTimeResult()
|
|
1250
|
+
|
|
1251
|
+
if not (context.flags & DEBUG):
|
|
1252
|
+
register = result.register
|
|
1253
|
+
should_return = result.should_return
|
|
1254
|
+
ncondition = node.condition
|
|
1255
|
+
|
|
1256
|
+
condition = register(get_visitor(ncondition.__class__)(ncondition, context))
|
|
1257
|
+
if should_return():
|
|
1258
|
+
return result
|
|
1259
|
+
|
|
1260
|
+
with result(context, ncondition.position):
|
|
1261
|
+
|
|
1262
|
+
if not condition:
|
|
1263
|
+
nmessage = node.message
|
|
1264
|
+
|
|
1265
|
+
if nmessage:
|
|
1266
|
+
message = register(get_visitor(nmessage.__class__)(nmessage, context))
|
|
1267
|
+
if should_return():
|
|
1268
|
+
return result
|
|
1269
|
+
|
|
1270
|
+
return result.failure(
|
|
1271
|
+
PysTraceback(
|
|
1272
|
+
AssertionError(message),
|
|
1273
|
+
context,
|
|
1274
|
+
node.position
|
|
1275
|
+
)
|
|
1276
|
+
)
|
|
1277
|
+
|
|
1278
|
+
return result.failure(
|
|
1279
|
+
PysTraceback(
|
|
1280
|
+
AssertionError,
|
|
1281
|
+
context,
|
|
1282
|
+
node.position
|
|
1283
|
+
)
|
|
1284
|
+
)
|
|
1285
|
+
|
|
1286
|
+
if should_return():
|
|
1287
|
+
return result
|
|
1288
|
+
|
|
1289
|
+
return result.success(None)
|
|
1290
|
+
|
|
1291
|
+
def visit_DeleteNode(node, context):
|
|
1292
|
+
result = PysRunTimeResult()
|
|
1293
|
+
|
|
1294
|
+
register = result.register
|
|
1295
|
+
should_return = result.should_return
|
|
1296
|
+
symbol_table = context.symbol_table
|
|
1297
|
+
|
|
1298
|
+
for ntarget in node.targets:
|
|
1299
|
+
target_position = ntarget.position
|
|
1300
|
+
ntarget_type = ntarget.__class__
|
|
1301
|
+
|
|
1302
|
+
if ntarget_type is PysIdentifierNode:
|
|
1303
|
+
name = ntarget.name.value
|
|
1304
|
+
|
|
1305
|
+
with result(context, target_position):
|
|
1306
|
+
|
|
1307
|
+
if not symbol_table.remove(name):
|
|
1308
|
+
closest_symbol = get_closest(dkeys(symbol_table.symbols), name)
|
|
1309
|
+
|
|
1310
|
+
return result.failure(
|
|
1311
|
+
PysTraceback(
|
|
1312
|
+
NameError(
|
|
1313
|
+
(
|
|
1314
|
+
f"name {name!r} is not defined"
|
|
1315
|
+
if symbol_table.get(name) is undefined else
|
|
1316
|
+
f"name {name!r} is not defined on local"
|
|
1317
|
+
)
|
|
1318
|
+
+
|
|
1319
|
+
(
|
|
1320
|
+
''
|
|
1321
|
+
if closest_symbol is None else
|
|
1322
|
+
f". Did you mean {closest_symbol!r}?"
|
|
1323
|
+
)
|
|
1324
|
+
),
|
|
1325
|
+
context,
|
|
1326
|
+
target_position
|
|
1327
|
+
)
|
|
1328
|
+
)
|
|
1329
|
+
|
|
1330
|
+
if should_return():
|
|
1331
|
+
return result
|
|
1332
|
+
|
|
1333
|
+
elif ntarget_type is PysAttributeNode:
|
|
1334
|
+
tntarget = ntarget.target
|
|
1335
|
+
target = register(get_visitor(tntarget.__class__)(tntarget, context))
|
|
1336
|
+
if should_return():
|
|
1337
|
+
return result
|
|
1338
|
+
|
|
1339
|
+
with result(context, target_position):
|
|
1340
|
+
delattr(target, ntarget.attribute.value)
|
|
1341
|
+
|
|
1342
|
+
if should_return():
|
|
1343
|
+
return result
|
|
1344
|
+
|
|
1345
|
+
elif ntarget_type is PysSubscriptNode:
|
|
1346
|
+
tntarget = ntarget.target
|
|
1347
|
+
target = register(get_visitor(tntarget.__class__)(tntarget, context))
|
|
1348
|
+
if should_return():
|
|
1349
|
+
return result
|
|
1350
|
+
|
|
1351
|
+
slice = register(visit_slice_SubscriptNode(ntarget.slice, context))
|
|
1352
|
+
if should_return():
|
|
1353
|
+
return result
|
|
1354
|
+
|
|
1355
|
+
with result(context, target_position):
|
|
1356
|
+
del target[slice]
|
|
1357
|
+
|
|
1358
|
+
if should_return():
|
|
1359
|
+
return result
|
|
1360
|
+
|
|
1361
|
+
return result.success(None)
|
|
1362
|
+
|
|
1363
|
+
def visit_EllipsisNode(node, context):
|
|
1364
|
+
return PysRunTimeResult().success(...)
|
|
1365
|
+
|
|
1366
|
+
def visit_ContinueNode(node, context):
|
|
1367
|
+
return PysRunTimeResult().success_continue()
|
|
1368
|
+
|
|
1369
|
+
def visit_BreakNode(node, context):
|
|
1370
|
+
return PysRunTimeResult().success_break()
|
|
1371
|
+
|
|
1372
|
+
def visit_slice_SubscriptNode(node, context):
|
|
1373
|
+
result = PysRunTimeResult()
|
|
1374
|
+
|
|
1375
|
+
register = result.register
|
|
1376
|
+
should_return = result.should_return
|
|
1377
|
+
ntype = node.__class__
|
|
1378
|
+
|
|
1379
|
+
if ntype is slice:
|
|
1380
|
+
start = node.start
|
|
1381
|
+
stop = node.stop
|
|
1382
|
+
step = node.step
|
|
1383
|
+
|
|
1384
|
+
if start is not None:
|
|
1385
|
+
start = register(get_visitor(start.__class__)(start, context))
|
|
1386
|
+
if should_return():
|
|
1387
|
+
return result
|
|
1388
|
+
|
|
1389
|
+
if stop is not None:
|
|
1390
|
+
stop = register(get_visitor(stop.__class__)(stop, context))
|
|
1391
|
+
if should_return():
|
|
1392
|
+
return result
|
|
1393
|
+
|
|
1394
|
+
if step is not None:
|
|
1395
|
+
step = register(get_visitor(step.__class__)(step, context))
|
|
1396
|
+
if should_return():
|
|
1397
|
+
return result
|
|
1398
|
+
|
|
1399
|
+
return result.success(slice(start, stop, step))
|
|
1400
|
+
|
|
1401
|
+
elif ntype is tuple:
|
|
1402
|
+
slices = []
|
|
1403
|
+
append = slices.append
|
|
1404
|
+
|
|
1405
|
+
for element in node:
|
|
1406
|
+
append(register(visit_slice_SubscriptNode(element, context)))
|
|
1407
|
+
if should_return():
|
|
1408
|
+
return result
|
|
1409
|
+
|
|
1410
|
+
return result.success(tuple(slices))
|
|
1411
|
+
|
|
1412
|
+
else:
|
|
1413
|
+
value = register(get_visitor(node.__class__)(node, context))
|
|
1414
|
+
if should_return():
|
|
1415
|
+
return result
|
|
1416
|
+
|
|
1417
|
+
return result.success(value)
|
|
1418
|
+
|
|
1419
|
+
def visit_declaration_AssignmentNode(node, context, value, operand=TOKENS['EQUAL']):
|
|
1420
|
+
result = PysRunTimeResult()
|
|
1421
|
+
|
|
1422
|
+
register = result.register
|
|
1423
|
+
should_return = result.should_return
|
|
1424
|
+
ntype = node.__class__
|
|
1425
|
+
|
|
1426
|
+
if ntype is PysIdentifierNode:
|
|
1427
|
+
symbol_table = context.symbol_table
|
|
1428
|
+
name = node.name.value
|
|
1429
|
+
|
|
1430
|
+
with result(context, node.position):
|
|
1431
|
+
|
|
1432
|
+
if not symbol_table.set(name, value, operand=operand):
|
|
1433
|
+
closest_symbol = get_closest(dkeys(symbol_table.symbols), name)
|
|
1434
|
+
|
|
1435
|
+
result.failure(
|
|
1436
|
+
PysTraceback(
|
|
1437
|
+
NameError(
|
|
1438
|
+
(
|
|
1439
|
+
f"name {name!r} is not defined"
|
|
1440
|
+
if symbol_table.get(name) is undefined else
|
|
1441
|
+
f"name {name!r} is not defined on local"
|
|
1442
|
+
)
|
|
1443
|
+
+
|
|
1444
|
+
(
|
|
1445
|
+
''
|
|
1446
|
+
if closest_symbol is None else
|
|
1447
|
+
f". Did you mean {closest_symbol!r}?"
|
|
1448
|
+
)
|
|
1449
|
+
),
|
|
1450
|
+
context,
|
|
1451
|
+
node.position
|
|
1452
|
+
)
|
|
1453
|
+
)
|
|
1454
|
+
|
|
1455
|
+
if should_return():
|
|
1456
|
+
return result
|
|
1457
|
+
|
|
1458
|
+
elif ntype is PysAttributeNode:
|
|
1459
|
+
ntarget = node.target
|
|
1460
|
+
target = register(get_visitor(ntarget.__class__)(ntarget, context))
|
|
1461
|
+
if should_return():
|
|
1462
|
+
return result
|
|
1463
|
+
|
|
1464
|
+
attribute = node.attribute.value
|
|
1465
|
+
|
|
1466
|
+
with result(context, node.position):
|
|
1467
|
+
setattr(
|
|
1468
|
+
target,
|
|
1469
|
+
attribute,
|
|
1470
|
+
value
|
|
1471
|
+
if is_equals(operand) else
|
|
1472
|
+
BINARY_FUNCTIONS_MAP(operand)(getattr(target, attribute), value)
|
|
1473
|
+
)
|
|
1474
|
+
|
|
1475
|
+
if should_return():
|
|
1476
|
+
return result
|
|
1477
|
+
|
|
1478
|
+
elif ntype is PysSubscriptNode:
|
|
1479
|
+
ntarget = node.target
|
|
1480
|
+
target = register(get_visitor(ntarget.__class__)(ntarget, context))
|
|
1481
|
+
if should_return():
|
|
1482
|
+
return result
|
|
1483
|
+
|
|
1484
|
+
slice = register(visit_slice_SubscriptNode(node.slice, context))
|
|
1485
|
+
if should_return():
|
|
1486
|
+
return result
|
|
1487
|
+
|
|
1488
|
+
with result(context, node.position):
|
|
1489
|
+
target[slice] = value if is_equals(operand) else BINARY_FUNCTIONS_MAP(operand)(target[slice], value)
|
|
1490
|
+
|
|
1491
|
+
if should_return():
|
|
1492
|
+
return result
|
|
1493
|
+
|
|
1494
|
+
elif is_list(ntype):
|
|
1495
|
+
position = node.position
|
|
1496
|
+
|
|
1497
|
+
if not isinstance(value, Iterable):
|
|
1498
|
+
return result.failure(
|
|
1499
|
+
PysTraceback(
|
|
1500
|
+
TypeError(f"cannot unpack non-iterable {type(value).__name__} object"),
|
|
1501
|
+
context,
|
|
1502
|
+
position
|
|
1503
|
+
)
|
|
1504
|
+
)
|
|
1505
|
+
|
|
1506
|
+
elements = node.elements
|
|
1507
|
+
count = 0
|
|
1508
|
+
|
|
1509
|
+
with result(context, position):
|
|
1510
|
+
|
|
1511
|
+
for element, element_value in zip(elements, value):
|
|
1512
|
+
register(visit_declaration_AssignmentNode(element, context, element_value, operand))
|
|
1513
|
+
if should_return():
|
|
1514
|
+
return result
|
|
1515
|
+
|
|
1516
|
+
count += 1
|
|
1517
|
+
|
|
1518
|
+
if should_return():
|
|
1519
|
+
return result
|
|
1520
|
+
|
|
1521
|
+
length = len(elements)
|
|
1522
|
+
|
|
1523
|
+
if count < length:
|
|
1524
|
+
return result.failure(
|
|
1525
|
+
PysTraceback(
|
|
1526
|
+
ValueError(f"not enough values to unpack (expected {length}, got {count})"),
|
|
1527
|
+
context,
|
|
1528
|
+
node.position
|
|
1529
|
+
)
|
|
1530
|
+
)
|
|
1531
|
+
|
|
1532
|
+
elif count > length:
|
|
1533
|
+
return result.failure(
|
|
1534
|
+
PysTraceback(
|
|
1535
|
+
ValueError(f"to many values to unpack (expected {length})"),
|
|
1536
|
+
context,
|
|
1537
|
+
node.position
|
|
1538
|
+
)
|
|
1539
|
+
)
|
|
1540
|
+
|
|
1541
|
+
return result.success(None)
|
|
1542
|
+
|
|
1543
|
+
get_visitor = {
|
|
1544
|
+
class_node: globals()['visit_' + class_node.__name__.removeprefix('Pys')]
|
|
1545
|
+
for class_node in PysNode.__subclasses__()
|
|
1546
|
+
}.__getitem__
|