pyscript-programming-language 1.10.0__tar.gz → 1.10.1__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.
Files changed (72) hide show
  1. {pyscript_programming_language-1.10.0/pyscript_programming_language.egg-info → pyscript_programming_language-1.10.1}/PKG-INFO +4 -4
  2. {pyscript_programming_language-1.10.0 → pyscript_programming_language-1.10.1}/pyscript/__main__.py +18 -2
  3. {pyscript_programming_language-1.10.0 → pyscript_programming_language-1.10.1}/pyscript/core/analyzer.py +5 -6
  4. {pyscript_programming_language-1.10.0 → pyscript_programming_language-1.10.1}/pyscript/core/cache.py +11 -0
  5. {pyscript_programming_language-1.10.0 → pyscript_programming_language-1.10.1}/pyscript/core/checks.py +1 -5
  6. {pyscript_programming_language-1.10.0 → pyscript_programming_language-1.10.1}/pyscript/core/constants.py +5 -3
  7. {pyscript_programming_language-1.10.0 → pyscript_programming_language-1.10.1}/pyscript/core/highlight.py +17 -14
  8. {pyscript_programming_language-1.10.0 → pyscript_programming_language-1.10.1}/pyscript/core/interpreter.py +55 -24
  9. {pyscript_programming_language-1.10.0 → pyscript_programming_language-1.10.1}/pyscript/core/mapping.py +4 -15
  10. {pyscript_programming_language-1.10.0 → pyscript_programming_language-1.10.1}/pyscript/core/nodes.py +20 -7
  11. {pyscript_programming_language-1.10.0 → pyscript_programming_language-1.10.1}/pyscript/core/objects.py +24 -4
  12. {pyscript_programming_language-1.10.0 → pyscript_programming_language-1.10.1}/pyscript/core/parser.py +164 -154
  13. {pyscript_programming_language-1.10.0 → pyscript_programming_language-1.10.1}/pyscript/core/pysbuiltins.py +13 -9
  14. {pyscript_programming_language-1.10.0 → pyscript_programming_language-1.10.1}/pyscript/core/runner.py +1 -1
  15. {pyscript_programming_language-1.10.0 → pyscript_programming_language-1.10.1}/pyscript/core/utils/generic.py +0 -1
  16. {pyscript_programming_language-1.10.0 → pyscript_programming_language-1.10.1}/pyscript/core/utils/jsdict.py +7 -2
  17. {pyscript_programming_language-1.10.0 → pyscript_programming_language-1.10.1}/pyscript/core/utils/string.py +5 -3
  18. {pyscript_programming_language-1.10.0 → pyscript_programming_language-1.10.1}/pyscript/core/version.py +2 -2
  19. {pyscript_programming_language-1.10.0 → pyscript_programming_language-1.10.1}/pyscript/lib/ast/ast_dump.py +10 -1
  20. {pyscript_programming_language-1.10.0 → pyscript_programming_language-1.10.1}/pyscript/lib/ast/ast_literal_eval.py +3 -1
  21. {pyscript_programming_language-1.10.0 → pyscript_programming_language-1.10.1}/pyscript/lib/ast/ast_unparse.py +6 -6
  22. {pyscript_programming_language-1.10.0 → pyscript_programming_language-1.10.1}/pyscript/lib/ast/ast_walk.py +4 -0
  23. {pyscript_programming_language-1.10.0 → pyscript_programming_language-1.10.1}/pyscript/lib/parser.pys +1 -1
  24. {pyscript_programming_language-1.10.0 → pyscript_programming_language-1.10.1}/pyscript/lib/sys.pys +3 -0
  25. {pyscript_programming_language-1.10.0 → pyscript_programming_language-1.10.1/pyscript_programming_language.egg-info}/PKG-INFO +4 -4
  26. {pyscript_programming_language-1.10.0 → pyscript_programming_language-1.10.1}/pyscript_programming_language.egg-info/requires.txt +1 -1
  27. {pyscript_programming_language-1.10.0 → pyscript_programming_language-1.10.1}/setup.py +2 -2
  28. {pyscript_programming_language-1.10.0 → pyscript_programming_language-1.10.1}/MANIFEST.in +0 -0
  29. {pyscript_programming_language-1.10.0 → pyscript_programming_language-1.10.1}/README.md +0 -0
  30. {pyscript_programming_language-1.10.0 → pyscript_programming_language-1.10.1}/pyscript/__init__.py +0 -0
  31. {pyscript_programming_language-1.10.0 → pyscript_programming_language-1.10.1}/pyscript/__init__.pyi +0 -0
  32. {pyscript_programming_language-1.10.0 → pyscript_programming_language-1.10.1}/pyscript/core/__init__.py +0 -0
  33. {pyscript_programming_language-1.10.0 → pyscript_programming_language-1.10.1}/pyscript/core/bases.py +0 -0
  34. {pyscript_programming_language-1.10.0 → pyscript_programming_language-1.10.1}/pyscript/core/buffer.py +0 -0
  35. {pyscript_programming_language-1.10.0 → pyscript_programming_language-1.10.1}/pyscript/core/context.py +0 -0
  36. {pyscript_programming_language-1.10.0 → pyscript_programming_language-1.10.1}/pyscript/core/exceptions.py +0 -0
  37. {pyscript_programming_language-1.10.0 → pyscript_programming_language-1.10.1}/pyscript/core/handlers.py +0 -0
  38. {pyscript_programming_language-1.10.0 → pyscript_programming_language-1.10.1}/pyscript/core/lexer.py +0 -0
  39. {pyscript_programming_language-1.10.0 → pyscript_programming_language-1.10.1}/pyscript/core/position.py +0 -0
  40. {pyscript_programming_language-1.10.0 → pyscript_programming_language-1.10.1}/pyscript/core/results.py +0 -0
  41. {pyscript_programming_language-1.10.0 → pyscript_programming_language-1.10.1}/pyscript/core/symtab.py +0 -0
  42. {pyscript_programming_language-1.10.0 → pyscript_programming_language-1.10.1}/pyscript/core/token.py +0 -0
  43. {pyscript_programming_language-1.10.0 → pyscript_programming_language-1.10.1}/pyscript/core/utils/__init__.py +0 -0
  44. {pyscript_programming_language-1.10.0 → pyscript_programming_language-1.10.1}/pyscript/core/utils/ansi.py +0 -0
  45. {pyscript_programming_language-1.10.0 → pyscript_programming_language-1.10.1}/pyscript/core/utils/debug.py +0 -0
  46. {pyscript_programming_language-1.10.0 → pyscript_programming_language-1.10.1}/pyscript/core/utils/decorators.py +0 -0
  47. {pyscript_programming_language-1.10.0 → pyscript_programming_language-1.10.1}/pyscript/core/utils/module.py +0 -0
  48. {pyscript_programming_language-1.10.0 → pyscript_programming_language-1.10.1}/pyscript/core/utils/path.py +0 -0
  49. {pyscript_programming_language-1.10.0 → pyscript_programming_language-1.10.1}/pyscript/core/utils/shell.py +0 -0
  50. {pyscript_programming_language-1.10.0 → pyscript_programming_language-1.10.1}/pyscript/core/utils/similarity.py +0 -0
  51. {pyscript_programming_language-1.10.0 → pyscript_programming_language-1.10.1}/pyscript/lib/__hello__.pys +0 -0
  52. {pyscript_programming_language-1.10.0 → pyscript_programming_language-1.10.1}/pyscript/lib/ansi.pys +0 -0
  53. {pyscript_programming_language-1.10.0 → pyscript_programming_language-1.10.1}/pyscript/lib/ast/__init__.pys +0 -0
  54. {pyscript_programming_language-1.10.0 → pyscript_programming_language-1.10.1}/pyscript/lib/brainfuck.pys +0 -0
  55. {pyscript_programming_language-1.10.0 → pyscript_programming_language-1.10.1}/pyscript/lib/dis.pys +0 -0
  56. {pyscript_programming_language-1.10.0 → pyscript_programming_language-1.10.1}/pyscript/lib/explorer.pys +0 -0
  57. {pyscript_programming_language-1.10.0 → pyscript_programming_language-1.10.1}/pyscript/lib/fpstimer.pys +0 -0
  58. {pyscript_programming_language-1.10.0 → pyscript_programming_language-1.10.1}/pyscript/lib/getch.pys +0 -0
  59. {pyscript_programming_language-1.10.0 → pyscript_programming_language-1.10.1}/pyscript/lib/inspect.pys +0 -0
  60. {pyscript_programming_language-1.10.0 → pyscript_programming_language-1.10.1}/pyscript/lib/jsdict.pys +0 -0
  61. {pyscript_programming_language-1.10.0 → pyscript_programming_language-1.10.1}/pyscript/lib/keyword.pys +0 -0
  62. {pyscript_programming_language-1.10.0 → pyscript_programming_language-1.10.1}/pyscript/lib/site.pys +0 -0
  63. {pyscript_programming_language-1.10.0 → pyscript_programming_language-1.10.1}/pyscript/lib/symtable.pys +0 -0
  64. {pyscript_programming_language-1.10.0 → pyscript_programming_language-1.10.1}/pyscript/lib/token.pys +0 -0
  65. {pyscript_programming_language-1.10.0 → pyscript_programming_language-1.10.1}/pyscript/lib/tokenize/__init__.pys +0 -0
  66. {pyscript_programming_language-1.10.0 → pyscript_programming_language-1.10.1}/pyscript/lib/tokenize/tok_untokenize.py +0 -0
  67. {pyscript_programming_language-1.10.0 → pyscript_programming_language-1.10.1}/pyscript/site-packages/this.pys +0 -0
  68. {pyscript_programming_language-1.10.0 → pyscript_programming_language-1.10.1}/pyscript/this.py +0 -0
  69. {pyscript_programming_language-1.10.0 → pyscript_programming_language-1.10.1}/pyscript_programming_language.egg-info/SOURCES.txt +0 -0
  70. {pyscript_programming_language-1.10.0 → pyscript_programming_language-1.10.1}/pyscript_programming_language.egg-info/dependency_links.txt +0 -0
  71. {pyscript_programming_language-1.10.0 → pyscript_programming_language-1.10.1}/pyscript_programming_language.egg-info/top_level.txt +0 -0
  72. {pyscript_programming_language-1.10.0 → pyscript_programming_language-1.10.1}/setup.cfg +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: pyscript-programming-language
3
- Version: 1.10.0
3
+ Version: 1.10.1
4
4
  Summary: PyScript Programming Language
5
5
  Home-page: https://azzammuhyala.github.io/pyscript
6
6
  Author: azzammuhyala
@@ -17,9 +17,9 @@ Classifier: Topic :: Software Development :: Interpreters
17
17
  Classifier: Topic :: Software Development :: Compilers
18
18
  Requires-Python: >=3.10
19
19
  Description-Content-Type: text/markdown
20
- Provides-Extra: extras
21
- Requires-Dist: beartype; extra == "extras"
22
- Requires-Dist: pygments; extra == "extras"
20
+ Provides-Extra: other
21
+ Requires-Dist: beartype; extra == "other"
22
+ Requires-Dist: pygments; extra == "other"
23
23
  Dynamic: author
24
24
  Dynamic: author-email
25
25
  Dynamic: classifier
@@ -1,5 +1,5 @@
1
1
  from .core.buffer import PysFileBuffer
2
- from .core.cache import path, undefined
2
+ from .core.cache import path, undefined, hook
3
3
  from .core.constants import DEFAULT, DEBUG, DONT_SHOW_BANNER_ON_SHELL, NO_COLOR
4
4
  from .core.highlight import (
5
5
  HLFMT_HTML, HLFMT_ANSI, HLFMT_BBCODE, pys_highlight, PygmentsPyScriptStyle, PygmentsPyScriptLexer
@@ -28,6 +28,22 @@ from os import environ
28
28
 
29
29
  import sys
30
30
 
31
+ def split_argv():
32
+ need_value_arguments = {'-c', '--command', '-l', '--highlight', '-r', '--py-recursion'}
33
+ argv = sys.argv
34
+ i = 1
35
+
36
+ while i < len(argv):
37
+ argument = argv[i]
38
+ if argument in need_value_arguments:
39
+ i += 1
40
+ elif not argument.startswith('-'):
41
+ break
42
+ i += 1
43
+
44
+ hook.argv = argv[i:]
45
+ return argv[1:i + 1]
46
+
31
47
  FORMAT_HIGHLIGHT_MAP = {
32
48
  'html': HLFMT_HTML,
33
49
  'ansi': HLFMT_ANSI,
@@ -102,7 +118,7 @@ def argument_error(argument, message):
102
118
  parser.print_usage(sys.stderr)
103
119
  parser.exit(2, f"{parser.prog}: error: argument {argument}: {message}\n")
104
120
 
105
- args = parser.parse_args()
121
+ args = parser.parse_args(split_argv())
106
122
 
107
123
  if args.highlight and args.file is None:
108
124
  argument_error("-l/--highlight", "argument 'file' required")
@@ -1,5 +1,5 @@
1
1
  from .bases import Pys
2
- from .checks import is_unpack_assignment, is_incremental
2
+ from .checks import is_unpack_assignment
3
3
  from .constants import TOKENS, KEYWORDS, DEFAULT
4
4
  from .context import PysContext
5
5
  from .exceptions import PysTraceback
@@ -155,13 +155,12 @@ class PysAnalyzer(Pys):
155
155
  self.visit(node.right)
156
156
 
157
157
  def visit_UnaryOperatorNode(self, node):
158
- if is_incremental(node.operand.type):
159
- operator = 'increase' if node.operand.type == TOKENS['DOUBLE-PLUS'] else 'decrease'
160
- self.visit_declaration_AssignNode(node.value, f"cannot {operator} literal", operator)
161
- return
162
-
163
158
  self.visit(node.value)
164
159
 
160
+ def visit_IncrementalNode(self, node):
161
+ operator = 'increase' if node.operand.type == TOKENS['DOUBLE-PLUS'] else 'decrease'
162
+ self.visit_declaration_AssignNode(node.target, f"cannot {operator} literal", operator)
163
+
165
164
  def visit_StatementsNode(self, node):
166
165
  for element in node.body:
167
166
  self.visit(element)
@@ -37,6 +37,7 @@ class PysHook(Pys):
37
37
  def __new_singleton__(cls) -> 'PysHook':
38
38
  global hook
39
39
  hook = super(cls, cls).__new__(cls)
40
+ hook.argv = []
40
41
  hook.running_shell = False
41
42
  hook.running_breakpoint = False
42
43
  hook.display = print_display
@@ -48,6 +49,16 @@ class PysHook(Pys):
48
49
  def __repr__(self) -> str:
49
50
  return f'<hook object at {id(self):016X}>'
50
51
 
52
+ @property
53
+ def argv(self) -> list[str]:
54
+ return singletons['hook.argv']
55
+
56
+ @argv.setter
57
+ def argv(self, value: list[str]) -> None:
58
+ if not isinstance(value, list) or not all(isinstance(arg, str) for arg in value):
59
+ raise TypeError("hook.argv: argv must be list of strings")
60
+ singletons['hook.argv'] = value
61
+
51
62
  @property
52
63
  def running_shell(self) -> bool:
53
64
  return singletons['hook.running_shell']
@@ -5,7 +5,7 @@ from .nodes import *
5
5
  is_expression = frozenset([
6
6
  PysNumberNode, PysStringNode, PysKeywordNode, PysIdentifierNode, PysDictionaryNode, PysSetNode, PysListNode,
7
7
  PysTupleNode, PysAttributeNode, PysSubscriptNode, PysCallNode, PysChainOperatorNode, PysTernaryOperatorNode,
8
- PysBinaryOperatorNode, PysUnaryOperatorNode, PysMatchNode, PysFunctionNode, PysEllipsisNode
8
+ PysBinaryOperatorNode, PysUnaryOperatorNode, PysIncrementalNode, PysMatchNode, PysFunctionNode, PysEllipsisNode
9
9
  ]).__contains__
10
10
 
11
11
  is_statement = frozenset([
@@ -28,10 +28,6 @@ is_equals = frozenset([
28
28
  TOKENS['EQUAL'], TOKENS['EQUAL-COLON']
29
29
  ]).__contains__
30
30
 
31
- is_incremental = frozenset([
32
- TOKENS['DOUBLE-PLUS'], TOKENS['DOUBLE-MINUS']
33
- ]).__contains__
34
-
35
31
  is_blacklist_python_builtins = frozenset([
36
32
  'IndentationError', 'TabError', 'breakpoint', 'compile', 'copyright', 'credits', 'dir', 'eval', 'exec', 'help',
37
33
  'globals', 'license', 'locals', 'vars'
@@ -106,7 +106,9 @@ KEYWORDS = MappingProxyType({
106
106
  'class': 'class',
107
107
  'constructor': 'constructor',
108
108
  'continue': 'continue',
109
+ 'def': 'def',
109
110
  'default': 'default',
111
+ 'define': 'define',
110
112
  'del': 'del',
111
113
  'delete': 'delete',
112
114
  'do': 'do',
@@ -146,9 +148,9 @@ KEYWORDS = MappingProxyType({
146
148
 
147
149
  CONSTANT_KEYWORDS = (
148
150
  KEYWORDS['__debug__'], KEYWORDS['False'], KEYWORDS['None'], KEYWORDS['True'], KEYWORDS['and'], KEYWORDS['class'],
149
- KEYWORDS['constructor'], KEYWORDS['extends'], KEYWORDS['func'], KEYWORDS['function'], KEYWORDS['false'],
150
- KEYWORDS['global'], KEYWORDS['in'], KEYWORDS['is'], KEYWORDS['not'], KEYWORDS['nil'], KEYWORDS['none'],
151
- KEYWORDS['null'], KEYWORDS['of'], KEYWORDS['or'], KEYWORDS['true']
151
+ KEYWORDS['constructor'], KEYWORDS['def'], KEYWORDS['define'], KEYWORDS['extends'], KEYWORDS['func'],
152
+ KEYWORDS['function'], KEYWORDS['false'], KEYWORDS['global'], KEYWORDS['in'], KEYWORDS['is'], KEYWORDS['not'],
153
+ KEYWORDS['nil'], KEYWORDS['none'], KEYWORDS['null'], KEYWORDS['of'], KEYWORDS['or'], KEYWORDS['true']
152
154
  )
153
155
 
154
156
  # flags
@@ -51,7 +51,10 @@ try:
51
51
 
52
52
  _set_keywords = frozenset(KEYWORDS.values())
53
53
  _set_constant_keywords = frozenset(CONSTANT_KEYWORDS)
54
- _set_keyword_definitions = frozenset([KEYWORDS['class'], KEYWORDS['func'], KEYWORDS['function']])
54
+ _set_keyword_definitions = frozenset([
55
+ KEYWORDS['class'],
56
+ KEYWORDS['def'], KEYWORDS['define'], KEYWORDS['func'], KEYWORDS['function']
57
+ ])
55
58
 
56
59
  _keywords = '|'.join(_set_keywords)
57
60
  _unicode_name = f'[{xid_start}][{xid_continue}]'
@@ -107,17 +110,6 @@ try:
107
110
  tokens = {
108
111
 
109
112
  'root': [
110
- # Whitespaces
111
- (r'\s+', Whitespace),
112
-
113
- # Punctuation and operators
114
- (rf'[\(\),;\[\]{{}}]|\\(?:{_newlines})', Punctuation),
115
- (r'\.\.\.', Keyword.Constant),
116
- (
117
- r'[!%&\*\+\-\./:<=>\?@^\|~]|&&|\*\*|\+\+|--|//|<<|==|>>|\?\?|\|\||!=|%=|&=|\*=|\+=|-=|/=|:=|<=|>=|'
118
- r'@=|^=|\|=|~=|\*\*=|//=|<<=|>>=|->|=>|!>|~!', Operator
119
- ),
120
-
121
113
  # Keywords
122
114
  (rf'\b({"|".join(_set_keywords ^ _set_constant_keywords)})\b', Keyword),
123
115
  (rf'\b({"|".join(_set_constant_keywords ^ _set_keyword_definitions)})\b', Keyword.Constant),
@@ -198,7 +190,7 @@ try:
198
190
 
199
191
  # Function definition
200
192
  (
201
- rf'\b({KEYWORDS["func"]}|{KEYWORDS["function"]})\b(\s*)'
193
+ rf'\b({KEYWORDS["def"]}|{KEYWORDS["define"]}|{KEYWORDS["func"]}|{KEYWORDS["function"]})\b(\s*)'
202
194
  rf'(?!{_keywords})({_dollar_prefix}\b{_unicode_name}*)\b',
203
195
  bygroups(Keyword.Constant, Whitespace, Name.Function)
204
196
  ),
@@ -224,9 +216,20 @@ try:
224
216
  # Variables
225
217
  (rf'{_dollar_prefix}\b{_unicode_name}*\b', Name.Variable),
226
218
 
219
+ # Whitespaces
220
+ (r'\s+', Whitespace),
221
+
222
+ # Punctuation and operators
223
+ (rf'[\(\),;\[\]{{}}]|\\(?:{_newlines})', Punctuation),
224
+ (r'\.\.\.', Keyword.Constant),
225
+ (
226
+ r'[!%&\*\+\-\./:<=>\?@^\|~]|&&|\*\*|\+\+|--|//|<<|==|>>|\?\?|\|\||!=|%=|&=|\*=|\+=|-=|/=|:=|<=|>=|'
227
+ r'@=|^=|\|=|~=|\*\*=|//=|<<=|>>=|->|=>|!>|~!', Operator
228
+ ),
229
+
227
230
  # Invalid tokens
228
231
  (r'\\.', Error),
229
- (rf'{_dollar_prefix}.', Error)
232
+ (rf'{_dollar_prefix[:-1]}.', Error)
230
233
  ],
231
234
 
232
235
  'code-tags': [
@@ -1,10 +1,10 @@
1
1
  from .constants import TOKENS, KEYWORDS, DEBUG
2
2
  from .cache import undefined
3
- from .checks import is_unpack_assignment, is_equals, is_incremental, is_public_attribute
3
+ from .checks import is_unpack_assignment, is_equals, is_public_attribute
4
4
  from .context import PysClassContext
5
5
  from .exceptions import PysTraceback
6
6
  from .handlers import handle_call
7
- from .mapping import UNARY_FUNCTIONS_MAP, KEYWORDS_TO_VALUES_MAP
7
+ from .mapping import UNARY_FUNCTIONS_MAP
8
8
  from .nodes import PysNode, PysIdentifierNode, PysAttributeNode, PysSubscriptNode
9
9
  from .objects import PysFunction
10
10
  from .pysbuiltins import ce, nce, increment, decrement
@@ -24,7 +24,6 @@ KW_OR = KEYWORDS['or']
24
24
 
25
25
  T_KEYWORD = TOKENS['KEYWORD']
26
26
  T_STRING = TOKENS['STRING']
27
- T_INCREMENT = TOKENS['DOUBLE-PLUS']
28
27
  T_AND = TOKENS['DOUBLE-AMPERSAND']
29
28
  T_OR = TOKENS['DOUBLE-PIPE']
30
29
  T_NOT = TOKENS['EXCLAMATION']
@@ -33,7 +32,20 @@ T_NCE = TOKENS['EXCLAMATION-TILDE']
33
32
  T_NULLISH = TOKENS['DOUBLE-QUESTION']
34
33
 
35
34
  get_unary_function = UNARY_FUNCTIONS_MAP.__getitem__
36
- get_value_from_keyword = KEYWORDS_TO_VALUES_MAP.__getitem__
35
+ get_incremental_function = {
36
+ TOKENS['DOUBLE-PLUS']: increment,
37
+ TOKENS['DOUBLE-MINUS']: decrement
38
+ }.__getitem__
39
+ get_value_from_keyword = {
40
+ KEYWORDS['True']: True,
41
+ KEYWORDS['False']: False,
42
+ KEYWORDS['None']: None,
43
+ KEYWORDS['true']: True,
44
+ KEYWORDS['false']: False,
45
+ KEYWORDS['nil']: None,
46
+ KEYWORDS['none']: None,
47
+ KEYWORDS['null']: None
48
+ }.__getitem__
37
49
 
38
50
  def visit(node, context):
39
51
  return get_visitors(node.__class__)(node, context)
@@ -216,7 +228,7 @@ def visit_CallNode(node, context):
216
228
 
217
229
  for nargument in node.arguments:
218
230
 
219
- if isinstance(nargument, tuple):
231
+ if nargument.__class__ is tuple:
220
232
  keyword, nvalue = nargument
221
233
  setitem(keyword.value, register(visit(nvalue, context)))
222
234
  if should_return():
@@ -344,34 +356,47 @@ def visit_UnaryOperatorNode(node, context):
344
356
 
345
357
  register = result.register
346
358
  should_return = result.should_return
347
- nposition = node.position
348
359
  otype = node.operand.type
349
- nvalue = node.value
350
360
 
351
- value = register(visit(nvalue, context))
361
+ value = register(visit(node.value, context))
352
362
  if should_return():
353
363
  return result
354
364
 
355
- with result(context, nposition):
365
+ with result(context, node.position):
366
+ return result.success(
367
+ (not value)
368
+ if node.operand.match(T_KEYWORD, KW_NOT) or otype == T_NOT else
369
+ get_unary_function(otype)(value)
370
+ )
356
371
 
357
- if node.operand.match(T_KEYWORD, KW_NOT) or otype == T_NOT:
358
- return result.success(not value)
372
+ if should_return():
373
+ return result
359
374
 
360
- elif is_incremental(otype):
361
- func = increment if otype == T_INCREMENT else decrement
375
+ def visit_IncrementalNode(node, context):
376
+ result = PysRunTimeResult()
362
377
 
363
- handle_call(func, context, nposition)
364
- increast_value = func(value)
365
- if node.operand_position == 'left':
366
- value = increast_value
378
+ register = result.register
379
+ should_return = result.should_return
380
+ nposition = node.position
381
+ ntarget = node.target
367
382
 
368
- register(visit_declaration_AssignNode(nvalue, context, increast_value))
369
- if should_return():
370
- return result
383
+ value = register(visit(ntarget, context))
384
+ if should_return():
385
+ return result
371
386
 
372
- return result.success(value)
387
+ with result(context, nposition):
388
+ func = get_incremental_function(node.operand.type)
389
+
390
+ handle_call(func, context, nposition)
391
+ increast_value = func(value)
392
+ if node.operand_position == 'left':
393
+ value = increast_value
373
394
 
374
- return result.success(get_unary_function(otype)(value))
395
+ register(visit_declaration_AssignNode(ntarget, context, increast_value))
396
+ if should_return():
397
+ return result
398
+
399
+ return result.success(value)
375
400
 
376
401
  if should_return():
377
402
  return result
@@ -685,7 +710,7 @@ def visit_TryNode(node, context):
685
710
 
686
711
  if tparameter:
687
712
  with result(context, tparameter.position):
688
- context.symbol_table.set(tparameter.value, error.exception)
713
+ context.symbol_table.set(parameter := tparameter.value, error.exception)
689
714
  if should_return():
690
715
  return
691
716
 
@@ -693,6 +718,12 @@ def visit_TryNode(node, context):
693
718
  if result.error:
694
719
  setimuattr(result.error, 'cause', error)
695
720
 
721
+ if tparameter:
722
+ with result(context, tparameter.position):
723
+ context.symbol_table.remove(parameter)
724
+ if should_return():
725
+ return
726
+
696
727
  break
697
728
 
698
729
  else:
@@ -1084,7 +1115,7 @@ def visit_FunctionNode(node, context):
1084
1115
 
1085
1116
  for nparameter in node.parameters:
1086
1117
 
1087
- if isinstance(nparameter, tuple):
1118
+ if nparameter.__class__ is tuple:
1088
1119
  keyword, nvalue = nparameter
1089
1120
 
1090
1121
  value = register(visit(nvalue, context))
@@ -10,7 +10,7 @@ from types import MappingProxyType
10
10
  contains = lambda a, b: a in b
11
11
  not_in = lambda a, b : a not in b
12
12
 
13
- BINARY_FUNCTIONS_MAP = MappingProxyType({
13
+ BINARY_FUNCTIONS_MAP = {
14
14
  TOKENS['NOT-IN']: not_in,
15
15
  TOKENS['IS-NOT']: is_not,
16
16
  TOKENS['PLUS']: add,
@@ -47,24 +47,13 @@ BINARY_FUNCTIONS_MAP = MappingProxyType({
47
47
  TOKENS['EQUAL-DOUBLE-GREATER-THAN']: irshift,
48
48
  TOKENS['MINUS-GREATER-THAN']: contains,
49
49
  TOKENS['EXCLAMATION-GREATER-THAN']: not_in
50
- })
50
+ }
51
51
 
52
- UNARY_FUNCTIONS_MAP = MappingProxyType({
52
+ UNARY_FUNCTIONS_MAP = {
53
53
  TOKENS['PLUS']: pos,
54
54
  TOKENS['MINUS']: neg,
55
55
  TOKENS['TILDE']: inv
56
- })
57
-
58
- KEYWORDS_TO_VALUES_MAP = MappingProxyType({
59
- KEYWORDS['True']: True,
60
- KEYWORDS['False']: False,
61
- KEYWORDS['None']: None,
62
- KEYWORDS['true']: True,
63
- KEYWORDS['false']: False,
64
- KEYWORDS['nil']: None,
65
- KEYWORDS['none']: None,
66
- KEYWORDS['null']: None
67
- })
56
+ }
68
57
 
69
58
  BRACKETS_MAP = MappingProxyType({
70
59
  TOKENS['LEFT-PARENTHESIS']: TOKENS['RIGHT-PARENTHESIS'],
@@ -246,25 +246,38 @@ class PysBinaryOperatorNode(PysNode):
246
246
 
247
247
  class PysUnaryOperatorNode(PysNode):
248
248
 
249
- __slots__ = ('operand', 'value', 'operand_position')
249
+ __slots__ = ('operand', 'value')
250
250
 
251
251
  @typechecked
252
- def __init__(self, operand: PysToken, value: PysNode, operand_position: Literal['left', 'right']) -> None:
252
+ def __init__(self, operand: PysToken, value: PysNode) -> None:
253
+ super().__init__(PysPosition(operand.position.file, operand.position.start, value.position.end))
254
+ setimuattr(self, 'operand', operand)
255
+ setimuattr(self, 'value', value)
256
+
257
+ def __repr__(self) -> str:
258
+ return f'UnaryOperator(operand={self.operand!r}, value={self.value!r})'
259
+
260
+ class PysIncrementalNode(PysNode):
261
+
262
+ __slots__ = ('operand', 'target', 'operand_position')
263
+
264
+ @typechecked
265
+ def __init__(self, operand: PysToken, target: PysNode, operand_position: Literal['left', 'right']) -> None:
253
266
  super().__init__(
254
- PysPosition(operand.position.file, operand.position.start, value.position.end)
267
+ PysPosition(operand.position.file, operand.position.start, target.position.end)
255
268
  if operand_position == 'left' else
256
- PysPosition(operand.position.file, value.position.start, operand.position.end)
269
+ PysPosition(operand.position.file, target.position.start, operand.position.end)
257
270
  )
258
271
 
259
272
  setimuattr(self, 'operand', operand)
260
- setimuattr(self, 'value', value)
273
+ setimuattr(self, 'target', target)
261
274
  setimuattr(self, 'operand_position', operand_position)
262
275
 
263
276
  def __repr__(self) -> str:
264
277
  return (
265
- 'UnaryOperator('
278
+ 'Incremental('
266
279
  f'operand={self.operand!r}, '
267
- f'value={self.value!r}, '
280
+ f'target={self.target!r}, '
268
281
  f'operand_position={self.operand_position!r}'
269
282
  ')'
270
283
  )
@@ -24,6 +24,26 @@ class PysFunction(PysObject):
24
24
 
25
25
  context = context.parent if isinstance(context, PysClassContext) else context
26
26
 
27
+ argument_names = []
28
+ keyword_argument_names = []
29
+ parameter_names = []
30
+ keyword_arguments = {}
31
+
32
+ append_argnames = argument_names.append
33
+ append_keynames = keyword_argument_names.append
34
+ append_paramnames = parameter_names.append
35
+ set_keywordarg = keyword_arguments.__setitem__
36
+
37
+ for parameter in parameters:
38
+ if parameter.__class__ is tuple:
39
+ arg, value = parameter
40
+ append_paramnames(arg)
41
+ append_keynames(arg)
42
+ set_keywordarg(arg, value)
43
+ else:
44
+ append_paramnames(parameter)
45
+ append_argnames(parameter)
46
+
27
47
  self.__name__ = '<function>' if name is None else name
28
48
  self.__qualname__ = ('' if qualname is None else qualname + '.') + self.__name__
29
49
  self.__code__ = PysCode(
@@ -35,10 +55,10 @@ class PysFunction(PysObject):
35
55
  closure_symbol_table=context.symbol_table,
36
56
  visit=visit,
37
57
  parameters_length=len(parameters),
38
- argument_names=tuple(item for item in parameters if not isinstance(item, tuple)),
39
- keyword_argument_names=tuple(item[0] for item in parameters if isinstance(item, tuple)),
40
- parameter_names=tuple(item[0] if isinstance(item, tuple) else item for item in parameters),
41
- keyword_arguments={item[0]: item[1] for item in parameters if isinstance(item, tuple)}
58
+ argument_names=tuple(argument_names),
59
+ keyword_argument_names=tuple(keyword_argument_names),
60
+ parameter_names=tuple(parameter_names),
61
+ keyword_arguments=keyword_arguments
42
62
  )
43
63
 
44
64
  def __repr__(self):