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.

Files changed (50) hide show
  1. {pyscript_programming_language-1.3.0 → pyscript_programming_language-1.4.0}/PKG-INFO +7 -3
  2. {pyscript_programming_language-1.3.0 → pyscript_programming_language-1.4.0}/README.md +7 -3
  3. {pyscript_programming_language-1.3.0 → pyscript_programming_language-1.4.0}/pyscript/core/analyzer.py +104 -76
  4. pyscript_programming_language-1.4.0/pyscript/core/bases.py +2 -0
  5. {pyscript_programming_language-1.3.0 → pyscript_programming_language-1.4.0}/pyscript/core/cache.py +2 -1
  6. {pyscript_programming_language-1.3.0 → pyscript_programming_language-1.4.0}/pyscript/core/constants.py +9 -6
  7. pyscript_programming_language-1.4.0/pyscript/core/context.py +50 -0
  8. {pyscript_programming_language-1.3.0 → pyscript_programming_language-1.4.0}/pyscript/core/exceptions.py +15 -5
  9. {pyscript_programming_language-1.3.0 → pyscript_programming_language-1.4.0}/pyscript/core/handlers.py +26 -14
  10. {pyscript_programming_language-1.3.0 → pyscript_programming_language-1.4.0}/pyscript/core/highlight.py +13 -11
  11. pyscript_programming_language-1.4.0/pyscript/core/interpreter.py +1288 -0
  12. {pyscript_programming_language-1.3.0 → pyscript_programming_language-1.4.0}/pyscript/core/lexer.py +13 -15
  13. {pyscript_programming_language-1.3.0 → pyscript_programming_language-1.4.0}/pyscript/core/nodes.py +57 -59
  14. {pyscript_programming_language-1.3.0 → pyscript_programming_language-1.4.0}/pyscript/core/objects.py +26 -16
  15. {pyscript_programming_language-1.3.0 → pyscript_programming_language-1.4.0}/pyscript/core/parser.py +340 -212
  16. {pyscript_programming_language-1.3.0 → pyscript_programming_language-1.4.0}/pyscript/core/pysbuiltins.py +42 -37
  17. {pyscript_programming_language-1.3.0 → pyscript_programming_language-1.4.0}/pyscript/core/results.py +4 -4
  18. {pyscript_programming_language-1.3.0 → pyscript_programming_language-1.4.0}/pyscript/core/runner.py +19 -16
  19. {pyscript_programming_language-1.3.0 → pyscript_programming_language-1.4.0}/pyscript/core/singletons.py +24 -19
  20. {pyscript_programming_language-1.3.0 → pyscript_programming_language-1.4.0}/pyscript/core/symtab.py +4 -4
  21. {pyscript_programming_language-1.3.0 → pyscript_programming_language-1.4.0}/pyscript/core/utils.py +8 -2
  22. pyscript_programming_language-1.4.0/pyscript/core/version.py +5 -0
  23. pyscript_programming_language-1.4.0/pyscript/lib/__hello__.pys +7 -0
  24. {pyscript_programming_language-1.3.0 → pyscript_programming_language-1.4.0}/pyscript/lib/brainfuck.pys +49 -38
  25. {pyscript_programming_language-1.3.0 → pyscript_programming_language-1.4.0}/pyscript/lib/parser.pys +52 -5
  26. {pyscript_programming_language-1.3.0 → pyscript_programming_language-1.4.0}/pyscript_programming_language.egg-info/PKG-INFO +7 -3
  27. {pyscript_programming_language-1.3.0 → pyscript_programming_language-1.4.0}/setup.py +1 -1
  28. pyscript_programming_language-1.3.0/pyscript/core/bases.py +0 -4
  29. pyscript_programming_language-1.3.0/pyscript/core/context.py +0 -19
  30. pyscript_programming_language-1.3.0/pyscript/core/interpreter.py +0 -1192
  31. pyscript_programming_language-1.3.0/pyscript/core/version.py +0 -5
  32. pyscript_programming_language-1.3.0/pyscript/lib/__hello__.pys +0 -5
  33. {pyscript_programming_language-1.3.0 → pyscript_programming_language-1.4.0}/MANIFEST.in +0 -0
  34. {pyscript_programming_language-1.3.0 → pyscript_programming_language-1.4.0}/pyscript/__init__.py +0 -0
  35. {pyscript_programming_language-1.3.0 → pyscript_programming_language-1.4.0}/pyscript/__init__.pyi +0 -0
  36. {pyscript_programming_language-1.3.0 → pyscript_programming_language-1.4.0}/pyscript/__main__.py +0 -0
  37. {pyscript_programming_language-1.3.0 → pyscript_programming_language-1.4.0}/pyscript/core/__init__.py +0 -0
  38. {pyscript_programming_language-1.3.0 → pyscript_programming_language-1.4.0}/pyscript/core/buffer.py +0 -0
  39. {pyscript_programming_language-1.3.0 → pyscript_programming_language-1.4.0}/pyscript/core/position.py +0 -0
  40. {pyscript_programming_language-1.3.0 → pyscript_programming_language-1.4.0}/pyscript/core/token.py +0 -0
  41. {pyscript_programming_language-1.3.0 → pyscript_programming_language-1.4.0}/pyscript/lib/clock.pys +0 -0
  42. {pyscript_programming_language-1.3.0 → pyscript_programming_language-1.4.0}/pyscript/lib/getch.pys +0 -0
  43. {pyscript_programming_language-1.3.0 → pyscript_programming_language-1.4.0}/pyscript/lib/jsdict.pys +0 -0
  44. {pyscript_programming_language-1.3.0 → pyscript_programming_language-1.4.0}/pyscript/lib/sys.pys +0 -0
  45. {pyscript_programming_language-1.3.0 → pyscript_programming_language-1.4.0}/pyscript/lib/this.pys +0 -0
  46. {pyscript_programming_language-1.3.0 → pyscript_programming_language-1.4.0}/pyscript/this.py +0 -0
  47. {pyscript_programming_language-1.3.0 → pyscript_programming_language-1.4.0}/pyscript_programming_language.egg-info/SOURCES.txt +0 -0
  48. {pyscript_programming_language-1.3.0 → pyscript_programming_language-1.4.0}/pyscript_programming_language.egg-info/dependency_links.txt +0 -0
  49. {pyscript_programming_language-1.3.0 → pyscript_programming_language-1.4.0}/pyscript_programming_language.egg-info/top_level.txt +0 -0
  50. {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.0
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's syntax and packages, you can check out the
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's syntax and packages, you can check out the
23
- [PyScript documentation here](https://azzammuhyala.github.io/pyscript) or see on
24
- [PyScript repository](https://github.com/azzammuhyala/pyscript).
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
- if node.type == 'dict':
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 visit_AssignNode(self, node):
69
- self.check_valid_AssignNode(
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.visit(node.value)
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
- self.visit(node.condition)
87
- if self.error:
88
- return
111
+ if node.style == 'general':
112
+ self.visit(node.condition)
113
+ if self.error:
114
+ return
89
115
 
90
- self.visit(node.valid)
91
- if self.error:
92
- return
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.cases_body:
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
- if node.catch_body:
159
- self.visit(node.catch_body)
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.init) == 2:
173
- self.check_valid_AssignNode(node.init[0], "cannot assign to expression")
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(node.init[1])
232
+ self.visit(iterable)
178
233
  if self.error:
179
234
  return
180
235
 
181
- elif len(node.init) == 3:
182
- for element in node.init:
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
- names = set()
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 names:
325
+ if name in parameter_names:
271
326
  return self.throw("duplicate argument {!r} in function definition".format(name), token.position)
272
327
 
273
- names.add(name)
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, in_function, in_switch = self.in_loop, self.in_function, self.in_switch
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.name)
352
+ self.visit(node.target)
296
353
  if self.error:
297
354
  return
298
355
 
299
- names = set()
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 names:
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
- names.add(name)
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
 
@@ -0,0 +1,2 @@
1
+ class Pys:
2
+ pass
@@ -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("Error: can't access directory {!r}: {}".format(LIBRARY_PATH, e), file=sys.stderr)
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
- 'PLUS': ord('+'),
23
- 'MINUS': ord('-'),
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
- 'EPLUS': ord('+') + WITH_EQ,
56
- 'EMINUS': ord('-') + WITH_EQ,
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
- def __init__(self, exception, context, position):
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
- return result + self.exception.__name__
61
-
62
- message = str(self.exception)
63
- return result + type(self.exception).__name__ + (': ' + message if message else '')
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
- @contextmanager
13
- def handle_exception(result, context, position):
14
- try:
15
- yield
16
- except PysShouldReturn as e:
17
- result.register(e.result)
18
- except BaseException as e:
19
- result.failure(PysException(e, context, position))
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
- handle_call(getattr(object, call, None), context, position)
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
- if result.mode == 'exec' and len(result.value) == 1:
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) + self.content_block(position, content)
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=COMMENT):
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
- last_index = 0
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 token.value in highlight_keyword_identifiers else 'keyword'
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 = getattr(pys_builtins, token.value, None)
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 token.value.isupper() else 'identifier'
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[last_index:token.position.start]
197
+ space = text[last_index_position:token.position.start]
196
198
  if space:
197
- result += format('default', PysPosition(file, last_index, token.position.start), space)
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
- last_index = token.position.end
210
+ last_index_position = token.position.end
209
211
 
210
212
  return result