pyscript-programming-language 1.3.0__tar.gz → 1.4.0__tar.gz
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.
Potentially problematic release.
This version of pyscript-programming-language might be problematic. Click here for more details.
- {pyscript_programming_language-1.3.0 → pyscript_programming_language-1.4.0}/PKG-INFO +7 -3
- {pyscript_programming_language-1.3.0 → pyscript_programming_language-1.4.0}/README.md +7 -3
- {pyscript_programming_language-1.3.0 → pyscript_programming_language-1.4.0}/pyscript/core/analyzer.py +104 -76
- pyscript_programming_language-1.4.0/pyscript/core/bases.py +2 -0
- {pyscript_programming_language-1.3.0 → pyscript_programming_language-1.4.0}/pyscript/core/cache.py +2 -1
- {pyscript_programming_language-1.3.0 → pyscript_programming_language-1.4.0}/pyscript/core/constants.py +9 -6
- pyscript_programming_language-1.4.0/pyscript/core/context.py +50 -0
- {pyscript_programming_language-1.3.0 → pyscript_programming_language-1.4.0}/pyscript/core/exceptions.py +15 -5
- {pyscript_programming_language-1.3.0 → pyscript_programming_language-1.4.0}/pyscript/core/handlers.py +26 -14
- {pyscript_programming_language-1.3.0 → pyscript_programming_language-1.4.0}/pyscript/core/highlight.py +13 -11
- pyscript_programming_language-1.4.0/pyscript/core/interpreter.py +1288 -0
- {pyscript_programming_language-1.3.0 → pyscript_programming_language-1.4.0}/pyscript/core/lexer.py +13 -15
- {pyscript_programming_language-1.3.0 → pyscript_programming_language-1.4.0}/pyscript/core/nodes.py +57 -59
- {pyscript_programming_language-1.3.0 → pyscript_programming_language-1.4.0}/pyscript/core/objects.py +26 -16
- {pyscript_programming_language-1.3.0 → pyscript_programming_language-1.4.0}/pyscript/core/parser.py +340 -212
- {pyscript_programming_language-1.3.0 → pyscript_programming_language-1.4.0}/pyscript/core/pysbuiltins.py +42 -37
- {pyscript_programming_language-1.3.0 → pyscript_programming_language-1.4.0}/pyscript/core/results.py +4 -4
- {pyscript_programming_language-1.3.0 → pyscript_programming_language-1.4.0}/pyscript/core/runner.py +19 -16
- {pyscript_programming_language-1.3.0 → pyscript_programming_language-1.4.0}/pyscript/core/singletons.py +24 -19
- {pyscript_programming_language-1.3.0 → pyscript_programming_language-1.4.0}/pyscript/core/symtab.py +4 -4
- {pyscript_programming_language-1.3.0 → pyscript_programming_language-1.4.0}/pyscript/core/utils.py +8 -2
- pyscript_programming_language-1.4.0/pyscript/core/version.py +5 -0
- pyscript_programming_language-1.4.0/pyscript/lib/__hello__.pys +7 -0
- {pyscript_programming_language-1.3.0 → pyscript_programming_language-1.4.0}/pyscript/lib/brainfuck.pys +49 -38
- {pyscript_programming_language-1.3.0 → pyscript_programming_language-1.4.0}/pyscript/lib/parser.pys +52 -5
- {pyscript_programming_language-1.3.0 → pyscript_programming_language-1.4.0}/pyscript_programming_language.egg-info/PKG-INFO +7 -3
- {pyscript_programming_language-1.3.0 → pyscript_programming_language-1.4.0}/setup.py +1 -1
- pyscript_programming_language-1.3.0/pyscript/core/bases.py +0 -4
- pyscript_programming_language-1.3.0/pyscript/core/context.py +0 -19
- pyscript_programming_language-1.3.0/pyscript/core/interpreter.py +0 -1192
- pyscript_programming_language-1.3.0/pyscript/core/version.py +0 -5
- pyscript_programming_language-1.3.0/pyscript/lib/__hello__.pys +0 -5
- {pyscript_programming_language-1.3.0 → pyscript_programming_language-1.4.0}/MANIFEST.in +0 -0
- {pyscript_programming_language-1.3.0 → pyscript_programming_language-1.4.0}/pyscript/__init__.py +0 -0
- {pyscript_programming_language-1.3.0 → pyscript_programming_language-1.4.0}/pyscript/__init__.pyi +0 -0
- {pyscript_programming_language-1.3.0 → pyscript_programming_language-1.4.0}/pyscript/__main__.py +0 -0
- {pyscript_programming_language-1.3.0 → pyscript_programming_language-1.4.0}/pyscript/core/__init__.py +0 -0
- {pyscript_programming_language-1.3.0 → pyscript_programming_language-1.4.0}/pyscript/core/buffer.py +0 -0
- {pyscript_programming_language-1.3.0 → pyscript_programming_language-1.4.0}/pyscript/core/position.py +0 -0
- {pyscript_programming_language-1.3.0 → pyscript_programming_language-1.4.0}/pyscript/core/token.py +0 -0
- {pyscript_programming_language-1.3.0 → pyscript_programming_language-1.4.0}/pyscript/lib/clock.pys +0 -0
- {pyscript_programming_language-1.3.0 → pyscript_programming_language-1.4.0}/pyscript/lib/getch.pys +0 -0
- {pyscript_programming_language-1.3.0 → pyscript_programming_language-1.4.0}/pyscript/lib/jsdict.pys +0 -0
- {pyscript_programming_language-1.3.0 → pyscript_programming_language-1.4.0}/pyscript/lib/sys.pys +0 -0
- {pyscript_programming_language-1.3.0 → pyscript_programming_language-1.4.0}/pyscript/lib/this.pys +0 -0
- {pyscript_programming_language-1.3.0 → pyscript_programming_language-1.4.0}/pyscript/this.py +0 -0
- {pyscript_programming_language-1.3.0 → pyscript_programming_language-1.4.0}/pyscript_programming_language.egg-info/SOURCES.txt +0 -0
- {pyscript_programming_language-1.3.0 → pyscript_programming_language-1.4.0}/pyscript_programming_language.egg-info/dependency_links.txt +0 -0
- {pyscript_programming_language-1.3.0 → pyscript_programming_language-1.4.0}/pyscript_programming_language.egg-info/top_level.txt +0 -0
- {pyscript_programming_language-1.3.0 → pyscript_programming_language-1.4.0}/setup.cfg +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: pyscript-programming-language
|
|
3
|
-
Version: 1.
|
|
3
|
+
Version: 1.4.0
|
|
4
4
|
Summary: PyScript Programming Language
|
|
5
5
|
Home-page: https://github.com/azzammuhyala/pyscript
|
|
6
6
|
Author: azzammuhyala
|
|
@@ -50,6 +50,10 @@ language was created as a relatively complex project. Using Python as the founda
|
|
|
50
50
|
understand syntax makes it easy to understand how the language is built without having to understand complex
|
|
51
51
|
instructions like those in C, C++, and other low-level languages.
|
|
52
52
|
|
|
53
|
-
To learn more about PyScript
|
|
54
|
-
[PyScript documentation here](https://azzammuhyala.github.io/pyscript) or see on
|
|
53
|
+
To learn more about PyScript, you can see on [PyScript documentation here](https://azzammuhyala.github.io/pyscript) or
|
|
55
54
|
[PyScript repository](https://github.com/azzammuhyala/pyscript).
|
|
55
|
+
|
|
56
|
+
## Behind it
|
|
57
|
+
This language created from based up on a
|
|
58
|
+
[YouTube tutorial](https://www.youtube.com/playlist?list=PLZQftyCk7_SdoVexSmwy_tBgs7P0b97yD). At least, it takes
|
|
59
|
+
about 6 months to learn it, and also need to learn general things that exist in other programming languages.
|
|
@@ -19,6 +19,10 @@ language was created as a relatively complex project. Using Python as the founda
|
|
|
19
19
|
understand syntax makes it easy to understand how the language is built without having to understand complex
|
|
20
20
|
instructions like those in C, C++, and other low-level languages.
|
|
21
21
|
|
|
22
|
-
To learn more about PyScript
|
|
23
|
-
[PyScript
|
|
24
|
-
|
|
22
|
+
To learn more about PyScript, you can see on [PyScript documentation here](https://azzammuhyala.github.io/pyscript) or
|
|
23
|
+
[PyScript repository](https://github.com/azzammuhyala/pyscript).
|
|
24
|
+
|
|
25
|
+
## Behind it
|
|
26
|
+
This language created from based up on a
|
|
27
|
+
[YouTube tutorial](https://www.youtube.com/playlist?list=PLZQftyCk7_SdoVexSmwy_tBgs7P0b97yD). At least, it takes
|
|
28
|
+
about 6 months to learn it, and also need to learn general things that exist in other programming languages.
|
|
@@ -12,12 +12,6 @@ class PysAnalyzer(Pys):
|
|
|
12
12
|
self.context = context_parent
|
|
13
13
|
self.context_parent_entry_position = context_parent_entry_position
|
|
14
14
|
|
|
15
|
-
self.in_loop = 0
|
|
16
|
-
self.in_function = 0
|
|
17
|
-
self.in_switch = 0
|
|
18
|
-
|
|
19
|
-
self.error = None
|
|
20
|
-
|
|
21
15
|
def throw(self, message, position):
|
|
22
16
|
if self.error is None:
|
|
23
17
|
self.error = PysException(
|
|
@@ -31,16 +25,58 @@ class PysAnalyzer(Pys):
|
|
|
31
25
|
position
|
|
32
26
|
)
|
|
33
27
|
|
|
28
|
+
def analyze(self, node):
|
|
29
|
+
self.in_loop = 0
|
|
30
|
+
self.in_function = 0
|
|
31
|
+
self.in_switch = 0
|
|
32
|
+
|
|
33
|
+
self.error = None
|
|
34
|
+
|
|
35
|
+
self.visit(node)
|
|
36
|
+
|
|
37
|
+
return self.error
|
|
38
|
+
|
|
34
39
|
def visit(self, node):
|
|
35
40
|
func = getattr(self, 'visit_' + type(node).__name__[3:], None)
|
|
36
41
|
if not self.error and func:
|
|
37
42
|
func(node)
|
|
38
43
|
|
|
39
|
-
return self.error
|
|
40
|
-
|
|
41
44
|
def visit_SequenceNode(self, node):
|
|
42
|
-
|
|
45
|
+
|
|
46
|
+
if node.type == 'del':
|
|
47
|
+
|
|
48
|
+
for element in node.elements:
|
|
49
|
+
|
|
50
|
+
if isinstance(element, PysSubscriptNode):
|
|
51
|
+
self.visit(element.object)
|
|
52
|
+
if self.error:
|
|
53
|
+
return
|
|
54
|
+
|
|
55
|
+
self.check_valid_slice_from_SubscriptNode(element.slice)
|
|
56
|
+
if self.error:
|
|
57
|
+
return
|
|
58
|
+
|
|
59
|
+
elif isinstance(element, PysAttributeNode):
|
|
60
|
+
self.visit(element.object)
|
|
61
|
+
if self.error:
|
|
62
|
+
return
|
|
63
|
+
|
|
64
|
+
elif isinstance(element, PysKeywordNode):
|
|
65
|
+
self.throw("cannot delete {}".format(element.token.value), element.position)
|
|
66
|
+
return
|
|
67
|
+
|
|
68
|
+
elif not isinstance(element, PysIdentifierNode):
|
|
69
|
+
self.throw("cannot delete literal", element.position)
|
|
70
|
+
return
|
|
71
|
+
|
|
72
|
+
elif node.type == 'global':
|
|
73
|
+
if self.in_function == 0:
|
|
74
|
+
self.throw("global outside of function", node.position)
|
|
75
|
+
|
|
76
|
+
elif node.type == 'dict':
|
|
77
|
+
|
|
43
78
|
for key, value in node.elements:
|
|
79
|
+
|
|
44
80
|
self.visit(key)
|
|
45
81
|
if self.error:
|
|
46
82
|
return
|
|
@@ -55,26 +91,15 @@ class PysAnalyzer(Pys):
|
|
|
55
91
|
if self.error:
|
|
56
92
|
return
|
|
57
93
|
|
|
58
|
-
def visit_SubscriptNode(self, node):
|
|
59
|
-
self.visit(node.object)
|
|
60
|
-
if self.error:
|
|
61
|
-
return
|
|
62
|
-
|
|
63
|
-
self.check_valid_slice_from_SubscriptNode(node.slice)
|
|
64
|
-
|
|
65
94
|
def visit_AttributeNode(self, node):
|
|
66
95
|
self.visit(node.object)
|
|
67
96
|
|
|
68
|
-
def
|
|
69
|
-
self.
|
|
70
|
-
node.target,
|
|
71
|
-
"cannot assign to expression here. Maybe you meant '==' instead of '='?"
|
|
72
|
-
)
|
|
73
|
-
|
|
97
|
+
def visit_SubscriptNode(self, node):
|
|
98
|
+
self.visit(node.object)
|
|
74
99
|
if self.error:
|
|
75
100
|
return
|
|
76
101
|
|
|
77
|
-
self.
|
|
102
|
+
self.check_valid_slice_from_SubscriptNode(node.slice)
|
|
78
103
|
|
|
79
104
|
def visit_ChainOperatorNode(self, node):
|
|
80
105
|
for expression in node.expressions:
|
|
@@ -83,13 +108,23 @@ class PysAnalyzer(Pys):
|
|
|
83
108
|
return
|
|
84
109
|
|
|
85
110
|
def visit_TernaryOperatorNode(self, node):
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
111
|
+
if node.style == 'general':
|
|
112
|
+
self.visit(node.condition)
|
|
113
|
+
if self.error:
|
|
114
|
+
return
|
|
89
115
|
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
116
|
+
self.visit(node.valid)
|
|
117
|
+
if self.error:
|
|
118
|
+
return
|
|
119
|
+
|
|
120
|
+
else:
|
|
121
|
+
self.visit(node.valid)
|
|
122
|
+
if self.error:
|
|
123
|
+
return
|
|
124
|
+
|
|
125
|
+
self.visit(node.condition)
|
|
126
|
+
if self.error:
|
|
127
|
+
return
|
|
93
128
|
|
|
94
129
|
self.visit(node.invalid)
|
|
95
130
|
|
|
@@ -114,6 +149,17 @@ class PysAnalyzer(Pys):
|
|
|
114
149
|
|
|
115
150
|
self.visit(node.value)
|
|
116
151
|
|
|
152
|
+
def visit_AssignNode(self, node):
|
|
153
|
+
self.check_valid_AssignNode(
|
|
154
|
+
node.target,
|
|
155
|
+
"cannot assign to expression here. Maybe you meant '==' instead of '='?"
|
|
156
|
+
)
|
|
157
|
+
|
|
158
|
+
if self.error:
|
|
159
|
+
return
|
|
160
|
+
|
|
161
|
+
self.visit(node.value)
|
|
162
|
+
|
|
117
163
|
def visit_IfNode(self, node):
|
|
118
164
|
for condition, body in node.cases_body:
|
|
119
165
|
self.visit(condition)
|
|
@@ -134,7 +180,7 @@ class PysAnalyzer(Pys):
|
|
|
134
180
|
|
|
135
181
|
self.in_switch += 1
|
|
136
182
|
|
|
137
|
-
for condition, body in node.
|
|
183
|
+
for condition, body in node.case_cases:
|
|
138
184
|
self.visit(condition)
|
|
139
185
|
if self.error:
|
|
140
186
|
return
|
|
@@ -155,8 +201,8 @@ class PysAnalyzer(Pys):
|
|
|
155
201
|
if self.error:
|
|
156
202
|
return
|
|
157
203
|
|
|
158
|
-
|
|
159
|
-
self.visit(
|
|
204
|
+
for _, body in node.catch_cases:
|
|
205
|
+
self.visit(body)
|
|
160
206
|
if self.error:
|
|
161
207
|
return
|
|
162
208
|
|
|
@@ -168,18 +214,27 @@ class PysAnalyzer(Pys):
|
|
|
168
214
|
if node.finally_body:
|
|
169
215
|
self.visit(node.finally_body)
|
|
170
216
|
|
|
217
|
+
def visit_WithNode(self, node):
|
|
218
|
+
self.visit(node.context)
|
|
219
|
+
if self.error:
|
|
220
|
+
return
|
|
221
|
+
|
|
222
|
+
self.visit(node.body)
|
|
223
|
+
|
|
171
224
|
def visit_ForNode(self, node):
|
|
172
|
-
if len(node.
|
|
173
|
-
|
|
225
|
+
if len(node.header) == 2:
|
|
226
|
+
declaration, iterable = node.header
|
|
227
|
+
|
|
228
|
+
self.check_valid_AssignNode(declaration, "cannot assign to expression")
|
|
174
229
|
if self.error:
|
|
175
230
|
return
|
|
176
231
|
|
|
177
|
-
self.visit(
|
|
232
|
+
self.visit(iterable)
|
|
178
233
|
if self.error:
|
|
179
234
|
return
|
|
180
235
|
|
|
181
|
-
elif len(node.
|
|
182
|
-
for element in node.
|
|
236
|
+
elif len(node.header) == 3:
|
|
237
|
+
for element in node.header:
|
|
183
238
|
self.visit(element)
|
|
184
239
|
if self.error:
|
|
185
240
|
return
|
|
@@ -261,42 +316,44 @@ class PysAnalyzer(Pys):
|
|
|
261
316
|
if self.error:
|
|
262
317
|
return
|
|
263
318
|
|
|
264
|
-
|
|
319
|
+
parameter_names = set()
|
|
265
320
|
|
|
266
321
|
for element in node.parameters:
|
|
267
322
|
token = (element[0] if isinstance(element, tuple) else element)
|
|
268
323
|
name = token.value
|
|
269
324
|
|
|
270
|
-
if name in
|
|
325
|
+
if name in parameter_names:
|
|
271
326
|
return self.throw("duplicate argument {!r} in function definition".format(name), token.position)
|
|
272
327
|
|
|
273
|
-
|
|
328
|
+
parameter_names.add(name)
|
|
274
329
|
|
|
275
330
|
if isinstance(element, tuple):
|
|
276
331
|
self.visit(element[1])
|
|
277
332
|
if self.error:
|
|
278
333
|
return
|
|
279
334
|
|
|
280
|
-
in_loop,
|
|
335
|
+
in_loop, in_switch = self.in_loop, self.in_switch
|
|
281
336
|
|
|
282
337
|
self.in_loop = 0
|
|
283
|
-
self.in_function = 1
|
|
284
338
|
self.in_switch = 0
|
|
285
339
|
|
|
340
|
+
self.in_function += 1
|
|
341
|
+
|
|
286
342
|
self.visit(node.body)
|
|
287
343
|
if self.error:
|
|
288
344
|
return
|
|
289
345
|
|
|
346
|
+
self.in_function -= 1
|
|
347
|
+
|
|
290
348
|
self.in_loop = in_loop
|
|
291
|
-
self.in_function = in_function
|
|
292
349
|
self.in_switch = in_switch
|
|
293
350
|
|
|
294
351
|
def visit_CallNode(self, node):
|
|
295
|
-
self.visit(node.
|
|
352
|
+
self.visit(node.target)
|
|
296
353
|
if self.error:
|
|
297
354
|
return
|
|
298
355
|
|
|
299
|
-
|
|
356
|
+
keyword_argument_names = set()
|
|
300
357
|
|
|
301
358
|
for element in node.arguments:
|
|
302
359
|
value = element
|
|
@@ -305,11 +362,11 @@ class PysAnalyzer(Pys):
|
|
|
305
362
|
token, value = element
|
|
306
363
|
name = token.value
|
|
307
364
|
|
|
308
|
-
if name in
|
|
365
|
+
if name in keyword_argument_names:
|
|
309
366
|
self.throw("duplicate argument {!r} in call definition".format(name), token.position)
|
|
310
367
|
return
|
|
311
368
|
|
|
312
|
-
|
|
369
|
+
keyword_argument_names.add(name)
|
|
313
370
|
|
|
314
371
|
self.visit(value)
|
|
315
372
|
if self.error:
|
|
@@ -323,35 +380,6 @@ class PysAnalyzer(Pys):
|
|
|
323
380
|
if node.value:
|
|
324
381
|
self.visit(node.value)
|
|
325
382
|
|
|
326
|
-
def visit_GlobalNode(self, node):
|
|
327
|
-
if self.in_function == 0:
|
|
328
|
-
self.throw("global outside of function", node.position)
|
|
329
|
-
|
|
330
|
-
def visit_DeleteNode(self, node):
|
|
331
|
-
for element in node.targets:
|
|
332
|
-
|
|
333
|
-
if isinstance(element, PysSubscriptNode):
|
|
334
|
-
self.visit(element.object)
|
|
335
|
-
if self.error:
|
|
336
|
-
return
|
|
337
|
-
|
|
338
|
-
self.check_valid_slice_from_SubscriptNode(element.slice)
|
|
339
|
-
if self.error:
|
|
340
|
-
return
|
|
341
|
-
|
|
342
|
-
elif isinstance(element, PysAttributeNode):
|
|
343
|
-
self.visit(element.object)
|
|
344
|
-
if self.error:
|
|
345
|
-
return
|
|
346
|
-
|
|
347
|
-
elif isinstance(element, PysKeywordNode):
|
|
348
|
-
self.throw("cannot delete {}".format(element.token.value), element.position)
|
|
349
|
-
return
|
|
350
|
-
|
|
351
|
-
elif not isinstance(element, PysIdentifierNode):
|
|
352
|
-
self.throw("cannot delete literal", element.position)
|
|
353
|
-
return
|
|
354
|
-
|
|
355
383
|
def visit_ThrowNode(self, node):
|
|
356
384
|
self.visit(node.target)
|
|
357
385
|
|
{pyscript_programming_language-1.3.0 → pyscript_programming_language-1.4.0}/pyscript/core/cache.py
RENAMED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
from .constants import LIBRARY_PATH
|
|
2
|
+
from .utils import get_name
|
|
2
3
|
|
|
3
4
|
import os
|
|
4
5
|
import sys
|
|
@@ -9,7 +10,7 @@ try:
|
|
|
9
10
|
library = set(os.path.splitext(lib)[0] for lib in os.listdir(LIBRARY_PATH))
|
|
10
11
|
except BaseException as e:
|
|
11
12
|
library = set()
|
|
12
|
-
print("
|
|
13
|
+
print("can't access directory {!r}: {}: {}".format(LIBRARY_PATH, get_name(e), e), file=sys.stderr)
|
|
13
14
|
|
|
14
15
|
modules = dict()
|
|
15
16
|
hook = None
|
|
@@ -19,8 +19,8 @@ TOKENS = {
|
|
|
19
19
|
'STRING': 4,
|
|
20
20
|
'NOTIN': 5,
|
|
21
21
|
'ISNOT': 6,
|
|
22
|
-
'
|
|
23
|
-
'
|
|
22
|
+
'ADD': ord('+'),
|
|
23
|
+
'SUB': ord('-'),
|
|
24
24
|
'MUL': ord('*'),
|
|
25
25
|
'DIV': ord('/'),
|
|
26
26
|
'FDIV': ord('/') + DOUBLE,
|
|
@@ -37,6 +37,7 @@ TOKENS = {
|
|
|
37
37
|
'DECREMENT': ord('-') + DOUBLE,
|
|
38
38
|
'CAND': ord('&') + DOUBLE,
|
|
39
39
|
'COR': ord('|') + DOUBLE,
|
|
40
|
+
'CNOT': ord('!'),
|
|
40
41
|
'LPAREN': ord('('),
|
|
41
42
|
'RPAREN': ord(')'),
|
|
42
43
|
'LSQUARE': ord('['),
|
|
@@ -52,8 +53,8 @@ TOKENS = {
|
|
|
52
53
|
'GT': ord('>'),
|
|
53
54
|
'LTE': ord('<') + WITH_EQ,
|
|
54
55
|
'GTE': ord('>') + WITH_EQ,
|
|
55
|
-
'
|
|
56
|
-
'
|
|
56
|
+
'EADD': ord('+') + WITH_EQ,
|
|
57
|
+
'ESUB': ord('-') + WITH_EQ,
|
|
57
58
|
'EMUL': ord('*') + WITH_EQ,
|
|
58
59
|
'EDIV': ord('/') + WITH_EQ,
|
|
59
60
|
'EFDIV': ord('/') + DOUBLE + WITH_EQ,
|
|
@@ -97,6 +98,7 @@ KEYWORDS = {
|
|
|
97
98
|
'do': 'do',
|
|
98
99
|
'elif': 'elif',
|
|
99
100
|
'else': 'else',
|
|
101
|
+
'extends': 'extends',
|
|
100
102
|
'finally': 'finally',
|
|
101
103
|
'for': 'for',
|
|
102
104
|
'from': 'from',
|
|
@@ -113,7 +115,8 @@ KEYWORDS = {
|
|
|
113
115
|
'switch': 'switch',
|
|
114
116
|
'throw': 'throw',
|
|
115
117
|
'try': 'try',
|
|
116
|
-
'while': 'while'
|
|
118
|
+
'while': 'while',
|
|
119
|
+
'with': 'with'
|
|
117
120
|
}
|
|
118
121
|
|
|
119
122
|
# default color highlight
|
|
@@ -135,7 +138,7 @@ HIGHLIGHT = {
|
|
|
135
138
|
}
|
|
136
139
|
|
|
137
140
|
# python extensions file
|
|
138
|
-
PYTHON_EXTENSIONS = {'.ipy', '.py', '.pyc', '.pyi', '.pyo', '.pyp', '.pyw', '.pyz', '.pyproj', '.rpy', '.xpy'}
|
|
141
|
+
PYTHON_EXTENSIONS = {'.ipy', '.py', '.pyc', '.pyd', '.pyi', '.pyo', '.pyp', '.pyw', '.pyz', '.pyproj', '.rpy', '.xpy'}
|
|
139
142
|
|
|
140
143
|
# flags
|
|
141
144
|
DEFAULT = 0
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
from .bases import Pys
|
|
2
|
+
from .constants import DEFAULT
|
|
3
|
+
|
|
4
|
+
class PysContext(Pys):
|
|
5
|
+
|
|
6
|
+
__slots__ = ('file', 'name', 'qualname', 'flags', 'symbol_table', 'parent', 'parent_entry_position')
|
|
7
|
+
|
|
8
|
+
def __init__(
|
|
9
|
+
self,
|
|
10
|
+
file,
|
|
11
|
+
name=None,
|
|
12
|
+
qualname=None,
|
|
13
|
+
flags=None,
|
|
14
|
+
symbol_table=None,
|
|
15
|
+
parent=None,
|
|
16
|
+
parent_entry_position=None
|
|
17
|
+
):
|
|
18
|
+
if flags is None and parent:
|
|
19
|
+
flags = parent.flags
|
|
20
|
+
|
|
21
|
+
self.file = file
|
|
22
|
+
self.name = name
|
|
23
|
+
self.qualname = qualname
|
|
24
|
+
self.flags = DEFAULT if flags is None else flags
|
|
25
|
+
self.symbol_table = symbol_table
|
|
26
|
+
self.parent = parent
|
|
27
|
+
self.parent_entry_position = parent_entry_position
|
|
28
|
+
|
|
29
|
+
def __repr__(self):
|
|
30
|
+
return '<Context {!r}>'.format(self.name)
|
|
31
|
+
|
|
32
|
+
class PysClassContext(PysContext):
|
|
33
|
+
|
|
34
|
+
__slots__ = ()
|
|
35
|
+
|
|
36
|
+
def __init__(
|
|
37
|
+
self,
|
|
38
|
+
name,
|
|
39
|
+
symbol_table,
|
|
40
|
+
parent,
|
|
41
|
+
parent_entry_position
|
|
42
|
+
):
|
|
43
|
+
super().__init__(
|
|
44
|
+
file=parent.file,
|
|
45
|
+
name=name,
|
|
46
|
+
qualname=('' if parent.qualname is None else parent.qualname + '.') + name,
|
|
47
|
+
symbol_table=symbol_table,
|
|
48
|
+
parent=parent,
|
|
49
|
+
parent_entry_position=parent_entry_position
|
|
50
|
+
)
|
|
@@ -3,10 +3,13 @@ from .utils import space_indent
|
|
|
3
3
|
|
|
4
4
|
class PysException(Pys):
|
|
5
5
|
|
|
6
|
-
|
|
6
|
+
__slots__ = ('exception', 'context', 'position', 'other_exception')
|
|
7
|
+
|
|
8
|
+
def __init__(self, exception, context, position, other_exception=None):
|
|
7
9
|
self.exception = exception
|
|
8
10
|
self.context = context
|
|
9
11
|
self.position = position
|
|
12
|
+
self.other_exception = other_exception
|
|
10
13
|
|
|
11
14
|
def __str__(self):
|
|
12
15
|
return str(self.exception)
|
|
@@ -57,10 +60,17 @@ class PysException(Pys):
|
|
|
57
60
|
result = 'Traceback (most recent call last):\n' + strings_traceback
|
|
58
61
|
|
|
59
62
|
if isinstance(self.exception, type):
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
63
|
+
result += self.exception.__name__
|
|
64
|
+
else:
|
|
65
|
+
message = str(self.exception)
|
|
66
|
+
result += type(self.exception).__name__ + (': ' + message if message else '')
|
|
67
|
+
|
|
68
|
+
return (
|
|
69
|
+
'{}\n\nDuring handling of the above exception, another exception occurred:\n\n{}'
|
|
70
|
+
.format(self.other_exception.string_traceback(), result)
|
|
71
|
+
if self.other_exception else
|
|
72
|
+
result
|
|
73
|
+
)
|
|
64
74
|
|
|
65
75
|
class PysShouldReturn(Pys, BaseException):
|
|
66
76
|
|
|
@@ -6,17 +6,30 @@ from .utils import is_object_of, print_traceback
|
|
|
6
6
|
|
|
7
7
|
from . import cache
|
|
8
8
|
|
|
9
|
-
from contextlib import contextmanager
|
|
10
9
|
from types import MethodType
|
|
11
10
|
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
11
|
+
class handle_exception:
|
|
12
|
+
|
|
13
|
+
__slots__ = ('result', 'context', 'position')
|
|
14
|
+
|
|
15
|
+
def __init__(self, result, context, position):
|
|
16
|
+
self.result = result
|
|
17
|
+
self.context = context
|
|
18
|
+
self.position = position
|
|
19
|
+
|
|
20
|
+
def __enter__(self):
|
|
21
|
+
return self
|
|
22
|
+
|
|
23
|
+
def __exit__(self, exc_type, exc_val, exc_tb):
|
|
24
|
+
if exc_type is None:
|
|
25
|
+
return False
|
|
26
|
+
|
|
27
|
+
elif exc_type is PysShouldReturn:
|
|
28
|
+
self.result.register(exc_val.result)
|
|
29
|
+
return True
|
|
30
|
+
|
|
31
|
+
self.result.failure(PysException(exc_type if exc_val is None else exc_val, self.context, self.position))
|
|
32
|
+
return True
|
|
20
33
|
|
|
21
34
|
def handle_call(object, context, position):
|
|
22
35
|
if isinstance(object, PysFunction):
|
|
@@ -31,7 +44,9 @@ def handle_call(object, context, position):
|
|
|
31
44
|
|
|
32
45
|
elif isinstance(object, type):
|
|
33
46
|
for call in ('__new__', '__init__'):
|
|
34
|
-
|
|
47
|
+
method = getattr(object, call, None)
|
|
48
|
+
if method is not None:
|
|
49
|
+
handle_call(method, context, position)
|
|
35
50
|
|
|
36
51
|
elif isinstance(object, MethodType):
|
|
37
52
|
handle_call(object.__func__, context, position)
|
|
@@ -49,10 +64,7 @@ def handle_execute(result):
|
|
|
49
64
|
return 1
|
|
50
65
|
|
|
51
66
|
elif cache.hook.display is not None:
|
|
52
|
-
|
|
53
|
-
cache.hook.display(result.value[0])
|
|
54
|
-
elif result.mode == 'eval':
|
|
55
|
-
cache.hook.display(result.value)
|
|
67
|
+
cache.hook.display(result.value)
|
|
56
68
|
|
|
57
69
|
if result_runtime.should_return():
|
|
58
70
|
if result_runtime.error:
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
from .bases import Pys
|
|
2
2
|
from .buffer import PysFileBuffer
|
|
3
|
-
from .constants import TOKENS, KEYWORDS, HIGHLIGHT, SILENT, COMMENT
|
|
3
|
+
from .constants import TOKENS, KEYWORDS, HIGHLIGHT, DEFAULT, SILENT, COMMENT
|
|
4
4
|
from .lexer import PysLexer
|
|
5
5
|
from .position import PysPosition
|
|
6
6
|
from .pysbuiltins import pys_builtins
|
|
@@ -49,7 +49,8 @@ class _HighlightFormatter(Pys):
|
|
|
49
49
|
if self._open:
|
|
50
50
|
result += self.close_block(position, self._type)
|
|
51
51
|
|
|
52
|
-
result += self.open_block(position, type) +
|
|
52
|
+
result += self.open_block(position, type) + \
|
|
53
|
+
self.content_block(position, content)
|
|
53
54
|
|
|
54
55
|
self._open = True
|
|
55
56
|
|
|
@@ -79,7 +80,7 @@ HLFMT_ANSI = _HighlightFormatter(
|
|
|
79
80
|
lambda position: '\n'
|
|
80
81
|
)
|
|
81
82
|
|
|
82
|
-
def pys_highlight(source, format=None, max_parenthesis_level=3, flags=
|
|
83
|
+
def pys_highlight(source, format=None, max_parenthesis_level=3, flags=DEFAULT):
|
|
83
84
|
"""
|
|
84
85
|
Highlight a PyScript code from source given.
|
|
85
86
|
|
|
@@ -111,7 +112,7 @@ def pys_highlight(source, format=None, max_parenthesis_level=3, flags=COMMENT):
|
|
|
111
112
|
|
|
112
113
|
lexer = PysLexer(
|
|
113
114
|
file=file,
|
|
114
|
-
flags=flags
|
|
115
|
+
flags=flags | COMMENT
|
|
115
116
|
)
|
|
116
117
|
|
|
117
118
|
tokens, error = lexer.make_tokens()
|
|
@@ -119,7 +120,7 @@ def pys_highlight(source, format=None, max_parenthesis_level=3, flags=COMMENT):
|
|
|
119
120
|
raise error.exception
|
|
120
121
|
|
|
121
122
|
result = ''
|
|
122
|
-
|
|
123
|
+
last_index_position = 0
|
|
123
124
|
parenthesis_level = 0
|
|
124
125
|
parenthesises_level = {
|
|
125
126
|
TOKENS['RPAREN']: 0,
|
|
@@ -131,6 +132,7 @@ def pys_highlight(source, format=None, max_parenthesis_level=3, flags=COMMENT):
|
|
|
131
132
|
|
|
132
133
|
for i, token in enumerate(tokens):
|
|
133
134
|
ttype = token.type
|
|
135
|
+
tvalue = token.value
|
|
134
136
|
|
|
135
137
|
if ttype in right_parenthesises:
|
|
136
138
|
parenthesises_level[ttype] -= 1
|
|
@@ -140,7 +142,7 @@ def pys_highlight(source, format=None, max_parenthesis_level=3, flags=COMMENT):
|
|
|
140
142
|
type_fmt = 'end'
|
|
141
143
|
|
|
142
144
|
elif ttype == TOKENS['KEYWORD']:
|
|
143
|
-
type_fmt = 'keyword-identifier' if
|
|
145
|
+
type_fmt = 'keyword-identifier' if tvalue in highlight_keyword_identifiers else 'keyword'
|
|
144
146
|
|
|
145
147
|
elif ttype == TOKENS['NUMBER']:
|
|
146
148
|
type_fmt = 'number'
|
|
@@ -149,7 +151,7 @@ def pys_highlight(source, format=None, max_parenthesis_level=3, flags=COMMENT):
|
|
|
149
151
|
type_fmt = 'string'
|
|
150
152
|
|
|
151
153
|
elif ttype == TOKENS['IDENTIFIER']:
|
|
152
|
-
obj =
|
|
154
|
+
obj = pys_builtins.__dict__.get(tvalue, None)
|
|
153
155
|
|
|
154
156
|
if isinstance(obj, type):
|
|
155
157
|
type_fmt = 'identifier-class'
|
|
@@ -158,7 +160,7 @@ def pys_highlight(source, format=None, max_parenthesis_level=3, flags=COMMENT):
|
|
|
158
160
|
type_fmt = 'identifier-call'
|
|
159
161
|
|
|
160
162
|
else:
|
|
161
|
-
type_fmt = 'identifier-const' if
|
|
163
|
+
type_fmt = 'identifier-const' if tvalue.isupper() else 'identifier'
|
|
162
164
|
|
|
163
165
|
j = i + 1
|
|
164
166
|
if (j < len(tokens) and tokens[j].type == TOKENS['LPAREN']):
|
|
@@ -192,9 +194,9 @@ def pys_highlight(source, format=None, max_parenthesis_level=3, flags=COMMENT):
|
|
|
192
194
|
else:
|
|
193
195
|
type_fmt = 'default'
|
|
194
196
|
|
|
195
|
-
space = text[
|
|
197
|
+
space = text[last_index_position:token.position.start]
|
|
196
198
|
if space:
|
|
197
|
-
result += format('default', PysPosition(file,
|
|
199
|
+
result += format('default', PysPosition(file, last_index_position, token.position.start), space)
|
|
198
200
|
|
|
199
201
|
result += format(type_fmt, token.position, text[token.position.start:token.position.end])
|
|
200
202
|
|
|
@@ -205,6 +207,6 @@ def pys_highlight(source, format=None, max_parenthesis_level=3, flags=COMMENT):
|
|
|
205
207
|
elif ttype == TOKENS['EOF']:
|
|
206
208
|
break
|
|
207
209
|
|
|
208
|
-
|
|
210
|
+
last_index_position = token.position.end
|
|
209
211
|
|
|
210
212
|
return result
|