pyscript-programming-language 1.10.3__tar.gz → 1.10.4__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 (73) hide show
  1. {pyscript_programming_language-1.10.3/pyscript_programming_language.egg-info → pyscript_programming_language-1.10.4}/PKG-INFO +4 -3
  2. {pyscript_programming_language-1.10.3 → pyscript_programming_language-1.10.4}/README.md +3 -2
  3. {pyscript_programming_language-1.10.3 → pyscript_programming_language-1.10.4}/pyscript/__init__.py +2 -1
  4. {pyscript_programming_language-1.10.3 → pyscript_programming_language-1.10.4}/pyscript/__init__.pyi +11 -0
  5. {pyscript_programming_language-1.10.3 → pyscript_programming_language-1.10.4}/pyscript/core/analyzer.py +8 -8
  6. {pyscript_programming_language-1.10.3 → pyscript_programming_language-1.10.4}/pyscript/core/checks.py +1 -1
  7. {pyscript_programming_language-1.10.3 → pyscript_programming_language-1.10.4}/pyscript/core/constants.py +8 -57
  8. {pyscript_programming_language-1.10.3 → pyscript_programming_language-1.10.4}/pyscript/core/context.py +1 -1
  9. {pyscript_programming_language-1.10.3 → pyscript_programming_language-1.10.4}/pyscript/core/exceptions.py +4 -6
  10. {pyscript_programming_language-1.10.3 → pyscript_programming_language-1.10.4}/pyscript/core/highlight.py +9 -16
  11. {pyscript_programming_language-1.10.3 → pyscript_programming_language-1.10.4}/pyscript/core/interpreter.py +28 -34
  12. {pyscript_programming_language-1.10.3 → pyscript_programming_language-1.10.4}/pyscript/core/mapping.py +17 -17
  13. {pyscript_programming_language-1.10.3 → pyscript_programming_language-1.10.4}/pyscript/core/objects.py +2 -2
  14. {pyscript_programming_language-1.10.3 → pyscript_programming_language-1.10.4}/pyscript/core/parser.py +127 -127
  15. {pyscript_programming_language-1.10.3 → pyscript_programming_language-1.10.4}/pyscript/core/pysbuiltins.py +5 -3
  16. {pyscript_programming_language-1.10.3 → pyscript_programming_language-1.10.4}/pyscript/core/results.py +4 -0
  17. {pyscript_programming_language-1.10.3 → pyscript_programming_language-1.10.4}/pyscript/core/runner.py +46 -19
  18. {pyscript_programming_language-1.10.3 → pyscript_programming_language-1.10.4}/pyscript/core/symtab.py +2 -4
  19. {pyscript_programming_language-1.10.3 → pyscript_programming_language-1.10.4}/pyscript/core/version.py +2 -2
  20. {pyscript_programming_language-1.10.3 → pyscript_programming_language-1.10.4}/pyscript/lib/ast/ast_literal_eval.py +6 -6
  21. {pyscript_programming_language-1.10.3 → pyscript_programming_language-1.10.4}/pyscript/lib/ast/ast_unparse.py +59 -63
  22. pyscript_programming_language-1.10.4/pyscript/lib/keyword.pys +2 -0
  23. {pyscript_programming_language-1.10.3 → pyscript_programming_language-1.10.4/pyscript_programming_language.egg-info}/PKG-INFO +4 -3
  24. {pyscript_programming_language-1.10.3 → pyscript_programming_language-1.10.4}/setup.py +2 -2
  25. pyscript_programming_language-1.10.3/pyscript/lib/keyword.pys +0 -2
  26. {pyscript_programming_language-1.10.3 → pyscript_programming_language-1.10.4}/MANIFEST.in +0 -0
  27. {pyscript_programming_language-1.10.3 → pyscript_programming_language-1.10.4}/pyscript/__main__.py +0 -0
  28. {pyscript_programming_language-1.10.3 → pyscript_programming_language-1.10.4}/pyscript/core/__init__.py +0 -0
  29. {pyscript_programming_language-1.10.3 → pyscript_programming_language-1.10.4}/pyscript/core/bases.py +0 -0
  30. {pyscript_programming_language-1.10.3 → pyscript_programming_language-1.10.4}/pyscript/core/buffer.py +0 -0
  31. {pyscript_programming_language-1.10.3 → pyscript_programming_language-1.10.4}/pyscript/core/cache.py +0 -0
  32. {pyscript_programming_language-1.10.3 → pyscript_programming_language-1.10.4}/pyscript/core/handlers.py +0 -0
  33. {pyscript_programming_language-1.10.3 → pyscript_programming_language-1.10.4}/pyscript/core/lexer.py +0 -0
  34. {pyscript_programming_language-1.10.3 → pyscript_programming_language-1.10.4}/pyscript/core/nodes.py +0 -0
  35. {pyscript_programming_language-1.10.3 → pyscript_programming_language-1.10.4}/pyscript/core/position.py +0 -0
  36. {pyscript_programming_language-1.10.3 → pyscript_programming_language-1.10.4}/pyscript/core/token.py +0 -0
  37. {pyscript_programming_language-1.10.3 → pyscript_programming_language-1.10.4}/pyscript/core/utils/__init__.py +0 -0
  38. {pyscript_programming_language-1.10.3 → pyscript_programming_language-1.10.4}/pyscript/core/utils/ansi.py +0 -0
  39. {pyscript_programming_language-1.10.3 → pyscript_programming_language-1.10.4}/pyscript/core/utils/debug.py +0 -0
  40. {pyscript_programming_language-1.10.3 → pyscript_programming_language-1.10.4}/pyscript/core/utils/decorators.py +0 -0
  41. {pyscript_programming_language-1.10.3 → pyscript_programming_language-1.10.4}/pyscript/core/utils/generic.py +0 -0
  42. {pyscript_programming_language-1.10.3 → pyscript_programming_language-1.10.4}/pyscript/core/utils/jsdict.py +0 -0
  43. {pyscript_programming_language-1.10.3 → pyscript_programming_language-1.10.4}/pyscript/core/utils/module.py +0 -0
  44. {pyscript_programming_language-1.10.3 → pyscript_programming_language-1.10.4}/pyscript/core/utils/path.py +0 -0
  45. {pyscript_programming_language-1.10.3 → pyscript_programming_language-1.10.4}/pyscript/core/utils/shell.py +0 -0
  46. {pyscript_programming_language-1.10.3 → pyscript_programming_language-1.10.4}/pyscript/core/utils/similarity.py +0 -0
  47. {pyscript_programming_language-1.10.3 → pyscript_programming_language-1.10.4}/pyscript/core/utils/string.py +0 -0
  48. {pyscript_programming_language-1.10.3 → pyscript_programming_language-1.10.4}/pyscript/lib/__hello__.pys +0 -0
  49. {pyscript_programming_language-1.10.3 → pyscript_programming_language-1.10.4}/pyscript/lib/ansi.pys +0 -0
  50. {pyscript_programming_language-1.10.3 → pyscript_programming_language-1.10.4}/pyscript/lib/ast/__init__.pys +0 -0
  51. {pyscript_programming_language-1.10.3 → pyscript_programming_language-1.10.4}/pyscript/lib/ast/ast_dump.py +0 -0
  52. {pyscript_programming_language-1.10.3 → pyscript_programming_language-1.10.4}/pyscript/lib/ast/ast_walk.py +0 -0
  53. {pyscript_programming_language-1.10.3 → pyscript_programming_language-1.10.4}/pyscript/lib/brainfuck.pys +0 -0
  54. {pyscript_programming_language-1.10.3 → pyscript_programming_language-1.10.4}/pyscript/lib/dis.pys +0 -0
  55. {pyscript_programming_language-1.10.3 → pyscript_programming_language-1.10.4}/pyscript/lib/explorer.pys +0 -0
  56. {pyscript_programming_language-1.10.3 → pyscript_programming_language-1.10.4}/pyscript/lib/fpstimer.pys +0 -0
  57. {pyscript_programming_language-1.10.3 → pyscript_programming_language-1.10.4}/pyscript/lib/getch.pys +0 -0
  58. {pyscript_programming_language-1.10.3 → pyscript_programming_language-1.10.4}/pyscript/lib/inspect.pys +0 -0
  59. {pyscript_programming_language-1.10.3 → pyscript_programming_language-1.10.4}/pyscript/lib/jsdict.pys +0 -0
  60. {pyscript_programming_language-1.10.3 → pyscript_programming_language-1.10.4}/pyscript/lib/parser.pys +0 -0
  61. {pyscript_programming_language-1.10.3 → pyscript_programming_language-1.10.4}/pyscript/lib/site.pys +0 -0
  62. {pyscript_programming_language-1.10.3 → pyscript_programming_language-1.10.4}/pyscript/lib/symtable.pys +0 -0
  63. {pyscript_programming_language-1.10.3 → pyscript_programming_language-1.10.4}/pyscript/lib/sys.pys +0 -0
  64. {pyscript_programming_language-1.10.3 → pyscript_programming_language-1.10.4}/pyscript/lib/token.pys +0 -0
  65. {pyscript_programming_language-1.10.3 → pyscript_programming_language-1.10.4}/pyscript/lib/tokenize/__init__.pys +0 -0
  66. {pyscript_programming_language-1.10.3 → pyscript_programming_language-1.10.4}/pyscript/lib/tokenize/tok_untokenize.py +0 -0
  67. {pyscript_programming_language-1.10.3 → pyscript_programming_language-1.10.4}/pyscript/site-packages/this.pys +0 -0
  68. {pyscript_programming_language-1.10.3 → pyscript_programming_language-1.10.4}/pyscript/this.py +0 -0
  69. {pyscript_programming_language-1.10.3 → pyscript_programming_language-1.10.4}/pyscript_programming_language.egg-info/SOURCES.txt +0 -0
  70. {pyscript_programming_language-1.10.3 → pyscript_programming_language-1.10.4}/pyscript_programming_language.egg-info/dependency_links.txt +0 -0
  71. {pyscript_programming_language-1.10.3 → pyscript_programming_language-1.10.4}/pyscript_programming_language.egg-info/requires.txt +0 -0
  72. {pyscript_programming_language-1.10.3 → pyscript_programming_language-1.10.4}/pyscript_programming_language.egg-info/top_level.txt +0 -0
  73. {pyscript_programming_language-1.10.3 → pyscript_programming_language-1.10.4}/setup.cfg +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: pyscript-programming-language
3
- Version: 1.10.3
3
+ Version: 1.10.4
4
4
  Summary: PyScript Programming Language
5
5
  Home-page: https://azzammuhyala.github.io/pyscript
6
6
  Author: azzammuhyala
@@ -83,5 +83,6 @@ Familiar? There it is!
83
83
 
84
84
  ## Behind it
85
85
  This language created from based up on a
86
- [YouTube tutorial](https://www.youtube.com/playlist?list=PLZQftyCk7_SdoVexSmwy_tBgs7P0b97yD) (check more on GitHub [here](https://github.com/davidcallanan/py-myopl-code)). At least, it takes
87
- about 6 months to learn it, and also need to learn general things that exist in other programming languages.
86
+ [YouTube tutorial](https://www.youtube.com/playlist?list=PLZQftyCk7_SdoVexSmwy_tBgs7P0b97yD) (check more on GitHub
87
+ [here](https://github.com/davidcallanan/py-myopl-code)). At least, it takes about 6 months to learn it, and also need to
88
+ learn general things that exist in other programming languages.
@@ -48,5 +48,6 @@ Familiar? There it is!
48
48
 
49
49
  ## Behind it
50
50
  This language created from based up on a
51
- [YouTube tutorial](https://www.youtube.com/playlist?list=PLZQftyCk7_SdoVexSmwy_tBgs7P0b97yD) (check more on GitHub [here](https://github.com/davidcallanan/py-myopl-code)). At least, it takes
52
- about 6 months to learn it, and also need to learn general things that exist in other programming languages.
51
+ [YouTube tutorial](https://www.youtube.com/playlist?list=PLZQftyCk7_SdoVexSmwy_tBgs7P0b97yD) (check more on GitHub
52
+ [here](https://github.com/davidcallanan/py-myopl-code)). At least, it takes about 6 months to learn it, and also need to
53
+ learn general things that exist in other programming languages.
@@ -15,7 +15,7 @@ from .core.cache import undefined, hook
15
15
  from .core.highlight import (
16
16
  HLFMT_HTML, HLFMT_ANSI, HLFMT_BBCODE, pys_highlight, PygmentsPyScriptStyle, PygmentsPyScriptLexer
17
17
  )
18
- from .core.runner import pys_exec, pys_eval, pys_require, pys_shell
18
+ from .core.runner import pys_runner, pys_exec, pys_eval, pys_require, pys_shell
19
19
  from .core.version import version, version_info, __version__, __date__
20
20
 
21
21
  __all__ = (
@@ -36,6 +36,7 @@ __all__ = (
36
36
  'version',
37
37
  'version_info',
38
38
  'pys_highlight',
39
+ 'pys_runner',
39
40
  'pys_exec',
40
41
  'pys_eval',
41
42
  'pys_require',
@@ -3,6 +3,7 @@ from typing import TYPE_CHECKING, Any, Callable, Iterable, Literal, Optional
3
3
  if TYPE_CHECKING:
4
4
  from .core.buffer import PysFileBuffer
5
5
  from .core.cache import PysUndefined, PysHook
6
+ from .core.context import PysContext
6
7
  from .core.highlight import _PysHighlightFormatter
7
8
  from .core.position import PysPosition
8
9
  from .core.results import PysExecuteResult
@@ -54,6 +55,16 @@ def pys_highlight(
54
55
  max_bracket_level: int = 3
55
56
  ) -> str: ...
56
57
 
58
+ def pys_runner(
59
+ file: PysFileBuffer,
60
+ mode: Literal['exec', 'eval', 'single'],
61
+ symbol_table: PysSymbolTable,
62
+ flags: Optional[int] = None,
63
+ parser_flags: int = DEFAULT,
64
+ context_parent: Optional[PysContext] = None,
65
+ context_parent_entry_position: Optional[PysPosition] = None
66
+ ) -> PysExecuteResult: ...
67
+
57
68
  def pys_exec(
58
69
  source: str | bytes | bytearray | Iterable | BuiltinMethodType | IOBase | PysFileBuffer,
59
70
  globals: Optional[dict[str, Any] | PysSymbolTable | PysUndefined] = None,
@@ -1,6 +1,6 @@
1
1
  from .bases import Pys
2
2
  from .checks import is_unpack_assignment
3
- from .constants import TOKENS, KEYWORDS, DEFAULT
3
+ from .constants import TOKENS, DEFAULT
4
4
  from .context import PysContext
5
5
  from .exceptions import PysTraceback
6
6
  from .nodes import PysNode, PysKeywordNode, PysIdentifierNode, PysAttributeNode, PysSubscriptNode
@@ -363,7 +363,7 @@ class PysAnalyzer(Pys):
363
363
 
364
364
  def visit_FunctionNode(self, node):
365
365
  if node.constructor and self.in_class == 0:
366
- self.throw(f"{KEYWORDS['constructor']} function outside of class", node.name.position)
366
+ self.throw("constructor function outside of class", node.name.position)
367
367
  return
368
368
 
369
369
  for decorator in node.decorators:
@@ -410,7 +410,7 @@ class PysAnalyzer(Pys):
410
410
 
411
411
  def visit_GlobalNode(self, node):
412
412
  if self.in_function == 0:
413
- self.throw(f"{KEYWORDS['global']} outside of function", node.position)
413
+ self.throw("global outside of function", node.position)
414
414
 
415
415
  for identifier in node.identifiers:
416
416
  if identifier.value in self.parameters:
@@ -419,7 +419,7 @@ class PysAnalyzer(Pys):
419
419
 
420
420
  def visit_ReturnNode(self, node):
421
421
  if self.in_function == 0:
422
- self.throw(f"{KEYWORDS['return']} outside of function", node.position)
422
+ self.throw("return outside of function", node.position)
423
423
  return
424
424
 
425
425
  if node.value:
@@ -460,20 +460,20 @@ class PysAnalyzer(Pys):
460
460
  return
461
461
 
462
462
  elif type is PysKeywordNode:
463
- self.throw(f"cannot {KEYWORDS['delete']} {target.name.value}", target.position)
463
+ self.throw(f"cannot delete {target.name.value}", target.position)
464
464
  return
465
465
 
466
466
  elif type is not PysIdentifierNode:
467
- self.throw(f"cannot {KEYWORDS['delete']} literal", target.position)
467
+ self.throw("cannot delete literal", target.position)
468
468
  return
469
469
 
470
470
  def visit_ContinueNode(self, node):
471
471
  if self.in_loop == 0:
472
- self.throw(f"{KEYWORDS['continue']} outside of loop", node.position)
472
+ self.throw("continue outside of loop", node.position)
473
473
 
474
474
  def visit_BreakNode(self, node):
475
475
  if self.in_loop == 0 and self.in_switch == 0:
476
- self.throw(f"{KEYWORDS['break']} outside of loop or switch case", node.position)
476
+ self.throw("break outside of loop or switch case", node.position)
477
477
 
478
478
  def visit_slice_SubscriptNode(self, nslice):
479
479
  type = nslice.__class__
@@ -18,7 +18,7 @@ is_unpack_assignment = frozenset([
18
18
  PysSetNode, PysListNode, PysTupleNode
19
19
  ]).__contains__
20
20
 
21
- is_keyword = frozenset(KEYWORDS.values()).__contains__
21
+ is_keyword = frozenset(KEYWORDS).__contains__
22
22
 
23
23
  is_python_extensions = frozenset([
24
24
  '.py', '.ipy', '.pyc', '.pyd', '.pyi', '.pyo', '.pyp', '.pyw', '.pyz', '.rpy', '.xpy', '.pyproj'
@@ -92,65 +92,16 @@ TOKENS = MappingProxyType({
92
92
  })
93
93
 
94
94
  # keywords
95
- KEYWORDS = MappingProxyType({
96
- '__debug__': '__debug__',
97
- 'False': 'False',
98
- 'None': 'None',
99
- 'True': 'True',
100
- 'and': 'and',
101
- 'as': 'as',
102
- 'assert': 'assert',
103
- 'break': 'break',
104
- 'case': 'case',
105
- 'catch': 'catch',
106
- 'class': 'class',
107
- 'constructor': 'constructor',
108
- 'continue': 'continue',
109
- 'def': 'def',
110
- 'default': 'default',
111
- 'define': 'define',
112
- 'del': 'del',
113
- 'delete': 'delete',
114
- 'do': 'do',
115
- 'elif': 'elif',
116
- 'else': 'else',
117
- 'except': 'except',
118
- 'extends': 'extends',
119
- 'false': 'false',
120
- 'finally': 'finally',
121
- 'for': 'for',
122
- 'from': 'from',
123
- 'func': 'func',
124
- 'function': 'function',
125
- 'global': 'global',
126
- 'if': 'if',
127
- 'import': 'import',
128
- 'in': 'in',
129
- 'is': 'is',
130
- 'match': 'match',
131
- 'nil': 'nil',
132
- 'none': 'none',
133
- 'null': 'null',
134
- 'not': 'not',
135
- 'true': 'true',
136
- 'of': 'of',
137
- 'or': 'or',
138
- 'raise': 'raise',
139
- 'repeat': 'repeat',
140
- 'return': 'return',
141
- 'switch': 'switch',
142
- 'throw': 'throw',
143
- 'try': 'try',
144
- 'until': 'until',
145
- 'while': 'while',
146
- 'with': 'with'
147
- })
95
+ KEYWORDS = (
96
+ '__debug__', 'False', 'None', 'True', 'and', 'as', 'assert', 'break', 'case', 'catch', 'class', 'constructor',
97
+ 'continue', 'def', 'default', 'define', 'del', 'delete', 'do', 'elif', 'else', 'except', 'extends', 'false',
98
+ 'finally', 'for', 'from', 'func', 'function', 'global', 'if', 'import', 'in', 'is', 'match', 'nil', 'none', 'null',
99
+ 'not', 'true', 'typeof', 'of', 'or', 'raise', 'repeat', 'return', 'switch', 'throw', 'try', 'until', 'while', 'with'
100
+ )
148
101
 
149
102
  CONSTANT_KEYWORDS = (
150
- KEYWORDS['__debug__'], KEYWORDS['False'], KEYWORDS['None'], KEYWORDS['True'], KEYWORDS['and'], KEYWORDS['class'],
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']
103
+ '__debug__', 'False', 'None', 'True', 'and', 'class', 'constructor', 'def', 'define', 'extends', 'func', 'function',
104
+ 'false', 'global', 'in', 'is', 'not', 'nil', 'none', 'null', 'of', 'or', 'true', 'typeof'
154
105
  )
155
106
 
156
107
  # flags
@@ -56,7 +56,7 @@ class PysClassContext(PysContext):
56
56
  super().__init__(
57
57
  file=parent.file,
58
58
  name=name,
59
- qualname=('' if qualname is None else qualname + '.') + name,
59
+ qualname=name if qualname is None else f'{qualname}.{name}',
60
60
  symbol_table=symbol_table,
61
61
  parent=parent,
62
62
  parent_entry_position=parent_entry_position
@@ -58,12 +58,10 @@ class PysTraceback(Pys):
58
58
  context_name = context.name
59
59
 
60
60
  frames.append(
61
- f' File {magenta}"{position.file.name}"{reset}'
62
- '{}{}{}'.format(
63
- '' if is_positionless else f', line {magenta}{position.start_line}{reset}',
64
- '' if context_name is None else f', in {magenta}{context_name}{reset}',
65
- '' if is_positionless else f'\n{indent(format_arrow(position, colored), 4)}'
66
- )
61
+ f' File {magenta}"{position.file.name}"{reset}' +
62
+ ('' if is_positionless else f', line {magenta}{position.start_line}{reset}') +
63
+ ('' if context_name is None else f', in {magenta}{context_name}{reset}') +
64
+ ('' if is_positionless else f'\n{indent(format_arrow(position, colored), 4)}')
67
65
  )
68
66
 
69
67
  position = context.parent_entry_position
@@ -49,12 +49,9 @@ try:
49
49
  from pygments.token import Comment, Error, Escape, Keyword, Name, Number, Operator, Punctuation, String, Whitespace
50
50
  from pygments.unistring import xid_start, xid_continue
51
51
 
52
- _set_keywords = frozenset(KEYWORDS.values())
52
+ _set_keywords = frozenset(KEYWORDS)
53
53
  _set_constant_keywords = frozenset(CONSTANT_KEYWORDS)
54
- _set_keyword_definitions = frozenset([
55
- KEYWORDS['class'],
56
- KEYWORDS['def'], KEYWORDS['define'], KEYWORDS['func'], KEYWORDS['function']
57
- ])
54
+ _set_keyword_definitions = frozenset(['class', 'def', 'define', 'func', 'function'])
58
55
 
59
56
  _keywords = '|'.join(_set_keywords)
60
57
  _unicode_name = f'[{xid_start}][{xid_continue}]*'
@@ -184,14 +181,13 @@ try:
184
181
 
185
182
  # Class definition
186
183
  (
187
- rf'\b({KEYWORDS["class"]})\b(\s+)\b(?!{_keywords})({_dollar_prefix}{_unicode_name})\b',
184
+ rf'\b(class)\b(\s+)(?!{_keywords})({_dollar_prefix}{_unicode_name})\b',
188
185
  bygroups(Keyword.Constant, Whitespace, Name.Class)
189
186
  ),
190
187
 
191
188
  # Function definition
192
189
  (
193
- rf'\b({KEYWORDS["def"]}|{KEYWORDS["define"]}|{KEYWORDS["func"]}|{KEYWORDS["function"]})\b(\s+)\b'
194
- rf'(?!{_keywords})({_dollar_prefix}{_unicode_name})\b',
190
+ rf'\b(def|define|func|function)\b(\s+)(?!{_keywords})({_dollar_prefix}{_unicode_name})\b',
195
191
  bygroups(Keyword.Constant, Whitespace, Name.Function)
196
192
  ),
197
193
 
@@ -405,11 +401,11 @@ def pys_highlight(
405
401
 
406
402
  Parameters
407
403
  ----------
408
- source: A PyScript source code (tolerant of syntax errors).
404
+ - source : A PyScript source code (tolerant of syntax errors).
409
405
 
410
- format: A function to format the code form.
406
+ - format : A function to format the code form.
411
407
 
412
- max_bracket_level: Maximum difference level of parentheses (with circular indexing).
408
+ - max_bracket_level : Maximum difference level of parentheses (with circular indexing).
413
409
  """
414
410
 
415
411
  file = PysFileBuffer(source)
@@ -461,12 +457,9 @@ def pys_highlight(
461
457
  while j > 0 and tokens[j].type in (TOKENS['NEWLINE'], TOKENS['COMMENT']):
462
458
  j -= 1
463
459
  previous_token = tokens[j]
464
- if previous_token.match(TOKENS['KEYWORD'], KEYWORDS['class']):
460
+ if previous_token.match(TOKENS['KEYWORD'], 'class'):
465
461
  type_fmt = 'identifier-type'
466
- elif previous_token.match(
467
- TOKENS['KEYWORD'],
468
- KEYWORDS['def'], KEYWORDS['define'], KEYWORDS['func'], KEYWORDS['function']
469
- ):
462
+ elif previous_token.match(TOKENS['KEYWORD'], 'def', 'define', 'func', 'function'):
470
463
  type_fmt = 'identifier-function'
471
464
  else:
472
465
  j = i + 1
@@ -1,27 +1,20 @@
1
- from .constants import TOKENS, KEYWORDS, DEBUG
1
+ from .constants import TOKENS, DEBUG
2
2
  from .cache import undefined
3
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
7
+ from .mapping import BINARY_FUNCTIONS_MAP, 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
11
11
  from .results import PysRunTimeResult
12
- from .symtab import get_binary_function, PysClassSymbolTable, find_closest
12
+ from .symtab import PysClassSymbolTable, find_closest
13
13
  from .utils.generic import getattribute, setimuattr, is_object_of, get_error_args
14
14
  from .utils.similarity import get_closest
15
15
 
16
16
  from collections.abc import Iterable
17
17
 
18
- KW__DEBUG__ = KEYWORDS['__debug__']
19
- KW_AND = KEYWORDS['and']
20
- KW_IN = KEYWORDS['in']
21
- KW_IS = KEYWORDS['is']
22
- KW_NOT = KEYWORDS['not']
23
- KW_OR = KEYWORDS['or']
24
-
25
18
  T_KEYWORD = TOKENS['KEYWORD']
26
19
  T_STRING = TOKENS['STRING']
27
20
  T_AND = TOKENS['DOUBLE-AMPERSAND']
@@ -31,20 +24,20 @@ T_CE = TOKENS['EQUAL-TILDE']
31
24
  T_NCE = TOKENS['EXCLAMATION-TILDE']
32
25
  T_NULLISH = TOKENS['DOUBLE-QUESTION']
33
26
 
34
- get_unary_function = UNARY_FUNCTIONS_MAP.__getitem__
35
27
  get_incremental_function = {
36
28
  TOKENS['DOUBLE-PLUS']: increment,
37
29
  TOKENS['DOUBLE-MINUS']: decrement
38
30
  }.__getitem__
31
+
39
32
  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
33
+ 'True': True,
34
+ 'False': False,
35
+ 'None': None,
36
+ 'true': True,
37
+ 'false': False,
38
+ 'nil': None,
39
+ 'none': None,
40
+ 'null': None
48
41
  }.__getitem__
49
42
 
50
43
  def visit_NumberNode(node, context):
@@ -57,7 +50,7 @@ def visit_KeywordNode(node, context):
57
50
  name = node.name.value
58
51
  return PysRunTimeResult().success(
59
52
  (True if context.flags & DEBUG else False)
60
- if name == KW__DEBUG__ else
53
+ if name == '__debug__' else
61
54
  get_value_from_keyword(name)
62
55
  )
63
56
 
@@ -270,9 +263,9 @@ def visit_ChainOperatorNode(node, context):
270
263
  if should_return():
271
264
  return result
272
265
 
273
- if omatch(T_KEYWORD, KW_IN):
266
+ if omatch(T_KEYWORD, 'in'):
274
267
  value = left in right
275
- elif omatch(T_KEYWORD, KW_IS):
268
+ elif omatch(T_KEYWORD, 'is'):
276
269
  value = left is right
277
270
  elif otype == T_CE:
278
271
  handle_call(ce, context, nposition)
@@ -281,7 +274,7 @@ def visit_ChainOperatorNode(node, context):
281
274
  handle_call(nce, context, nposition)
282
275
  value = nce(left, right)
283
276
  else:
284
- value = get_binary_function(otype)(left, right)
277
+ value = BINARY_FUNCTIONS_MAP(otype)(left, right)
285
278
 
286
279
  if not value:
287
280
  break
@@ -332,10 +325,10 @@ def visit_BinaryOperatorNode(node, context):
332
325
  with result(context, node.position):
333
326
  should_return_right = True
334
327
 
335
- if omatch(T_KEYWORD, KW_AND) or otype == T_AND:
328
+ if omatch(T_KEYWORD, 'and') or otype == T_AND:
336
329
  if not left:
337
330
  return result.success(left)
338
- elif omatch(T_KEYWORD, KW_OR) or otype == T_OR:
331
+ elif omatch(T_KEYWORD, 'or') or otype == T_OR:
339
332
  if left:
340
333
  return result.success(left)
341
334
  elif otype == T_NULLISH:
@@ -351,7 +344,7 @@ def visit_BinaryOperatorNode(node, context):
351
344
  return result.success(
352
345
  right
353
346
  if should_return_right else
354
- get_binary_function(otype)(left, right)
347
+ BINARY_FUNCTIONS_MAP(otype)(left, right)
355
348
  )
356
349
 
357
350
  if should_return():
@@ -362,6 +355,7 @@ def visit_UnaryOperatorNode(node, context):
362
355
 
363
356
  register = result.register
364
357
  should_return = result.should_return
358
+ omatch = node.operand.match
365
359
  otype = node.operand.type
366
360
  nvalue = node.value
367
361
 
@@ -370,11 +364,11 @@ def visit_UnaryOperatorNode(node, context):
370
364
  return result
371
365
 
372
366
  with result(context, node.position):
373
- return result.success(
374
- (not value)
375
- if node.operand.match(T_KEYWORD, KW_NOT) or otype == T_NOT else
376
- get_unary_function(otype)(value)
377
- )
367
+ if omatch(T_KEYWORD, 'not') or otype == T_NOT:
368
+ return result.success(not value)
369
+ elif omatch(T_KEYWORD, 'typeof'):
370
+ return result.success(type(value).__name__)
371
+ return result.success(UNARY_FUNCTIONS_MAP(otype)(value))
378
372
 
379
373
  if should_return():
380
374
  return result
@@ -1475,8 +1469,8 @@ def visit_declaration_AssignNode(node, context, value, operand=TOKENS['EQUAL']):
1475
1469
  target,
1476
1470
  attribute,
1477
1471
  value
1478
- if is_equals(operand) else
1479
- get_binary_function(operand)(getattr(target, attribute), value)
1472
+ if is_equals(operand) else
1473
+ BINARY_FUNCTIONS_MAP(operand)(getattr(target, attribute), value)
1480
1474
  )
1481
1475
 
1482
1476
  if should_return():
@@ -1493,7 +1487,7 @@ def visit_declaration_AssignNode(node, context, value, operand=TOKENS['EQUAL']):
1493
1487
  return result
1494
1488
 
1495
1489
  with result(context, node.position):
1496
- target[slice] = value if is_equals(operand) else get_binary_function(operand)(target[slice], value)
1490
+ target[slice] = value if is_equals(operand) else BINARY_FUNCTIONS_MAP(operand)(target[slice], value)
1497
1491
 
1498
1492
  if should_return():
1499
1493
  return result
@@ -1,4 +1,4 @@
1
- from .constants import TOKENS, KEYWORDS
1
+ from .constants import TOKENS
2
2
  from .utils.ansi import BOLD, acolor
3
3
 
4
4
  from operator import (
@@ -10,6 +10,8 @@ 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
+ EMPTY_MAP = {}
14
+
13
15
  BINARY_FUNCTIONS_MAP = {
14
16
  TOKENS['NOT-IN']: not_in,
15
17
  TOKENS['IS-NOT']: is_not,
@@ -47,13 +49,22 @@ BINARY_FUNCTIONS_MAP = {
47
49
  TOKENS['EQUAL-DOUBLE-GREATER-THAN']: irshift,
48
50
  TOKENS['MINUS-GREATER-THAN']: contains,
49
51
  TOKENS['EXCLAMATION-GREATER-THAN']: not_in
50
- }
52
+ }.__getitem__
51
53
 
52
54
  UNARY_FUNCTIONS_MAP = {
53
55
  TOKENS['PLUS']: pos,
54
56
  TOKENS['MINUS']: neg,
55
57
  TOKENS['TILDE']: inv
56
- }
58
+ }.__getitem__
59
+
60
+ ACOLORS = {
61
+ 'reset': acolor('reset'),
62
+ 'magenta': acolor('magenta'),
63
+ 'bold-magenta': acolor('magenta', style=BOLD),
64
+ 'bold-red': acolor('red', style=BOLD)
65
+ }.__getitem__
66
+
67
+ REVERSE_TOKENS = MappingProxyType({type: name for name, type in TOKENS.items()})
57
68
 
58
69
  BRACKETS_MAP = MappingProxyType({
59
70
  TOKENS['LEFT-PARENTHESIS']: TOKENS['RIGHT-PARENTHESIS'],
@@ -62,8 +73,8 @@ BRACKETS_MAP = MappingProxyType({
62
73
  })
63
74
 
64
75
  SYMBOLS_TOKEN_MAP = MappingProxyType({
65
- TOKENS['NOT-IN']: KEYWORDS['not'] + ' ' + KEYWORDS['in'],
66
- TOKENS['IS-NOT']: KEYWORDS['is'] + ' ' + KEYWORDS['not'],
76
+ TOKENS['NOT-IN']: 'not in',
77
+ TOKENS['IS-NOT']: 'is not',
67
78
  TOKENS['NULL']: '\0',
68
79
  TOKENS['NEWLINE']: '\n',
69
80
  TOKENS['EXCLAMATION']: '!',
@@ -125,15 +136,4 @@ SYMBOLS_TOKEN_MAP = MappingProxyType({
125
136
  TOKENS['EQUAL-ARROW']: '=>',
126
137
  TOKENS['EXCLAMATION-GREATER-THAN']: '!>',
127
138
  TOKENS['EXCLAMATION-TILDE']: '~!'
128
- })
129
-
130
- ACOLORS = {
131
- 'reset': acolor('reset'),
132
- 'magenta': acolor('magenta'),
133
- 'bold-magenta': acolor('magenta', style=BOLD),
134
- 'bold-red': acolor('red', style=BOLD)
135
- }.__getitem__
136
-
137
- EMPTY_MAP = {}
138
-
139
- REVERSE_TOKENS = MappingProxyType({type: name for name, type in TOKENS.items()})
139
+ })
@@ -44,8 +44,8 @@ class PysFunction(PysObject):
44
44
  append_paramnames(parameter)
45
45
  append_argnames(parameter)
46
46
 
47
- self.__name__ = '<function>' if name is None else name
48
- self.__qualname__ = ('' if qualname is None else qualname + '.') + self.__name__
47
+ self.__name__ = name = '<function>' if name is None else name
48
+ self.__qualname__ = name if qualname is None else f'{qualname}.{name}'
49
49
  self.__code__ = PysCode(
50
50
  parameters=parameters,
51
51
  body=body,