pyscript-programming-language 1.7.1__tar.gz → 1.7.3__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 (78) hide show
  1. {pyscript_programming_language-1.7.1 → pyscript_programming_language-1.7.3}/PKG-INFO +2 -2
  2. {pyscript_programming_language-1.7.1 → pyscript_programming_language-1.7.3}/pyscript/__init__.pyi +3 -9
  3. {pyscript_programming_language-1.7.1 → pyscript_programming_language-1.7.3}/pyscript/__main__.py +16 -15
  4. {pyscript_programming_language-1.7.1 → pyscript_programming_language-1.7.3}/pyscript/core/analyzer.py +9 -7
  5. {pyscript_programming_language-1.7.1 → pyscript_programming_language-1.7.3}/pyscript/core/cache.py +4 -4
  6. {pyscript_programming_language-1.7.1 → pyscript_programming_language-1.7.3}/pyscript/core/exceptions.py +4 -2
  7. {pyscript_programming_language-1.7.1 → pyscript_programming_language-1.7.3}/pyscript/core/highlight.py +20 -2
  8. {pyscript_programming_language-1.7.1 → pyscript_programming_language-1.7.3}/pyscript/core/lexer.py +19 -20
  9. pyscript_programming_language-1.7.3/pyscript/core/mapping.py +131 -0
  10. {pyscript_programming_language-1.7.1 → pyscript_programming_language-1.7.3}/pyscript/core/objects.py +5 -4
  11. {pyscript_programming_language-1.7.1 → pyscript_programming_language-1.7.3}/pyscript/core/parser.py +16 -1
  12. pyscript_programming_language-1.7.3/pyscript/core/position.py +99 -0
  13. {pyscript_programming_language-1.7.1 → pyscript_programming_language-1.7.3}/pyscript/core/pysbuiltins.py +166 -24
  14. {pyscript_programming_language-1.7.1 → pyscript_programming_language-1.7.3}/pyscript/core/results.py +1 -1
  15. {pyscript_programming_language-1.7.1 → pyscript_programming_language-1.7.3}/pyscript/core/runner.py +9 -5
  16. {pyscript_programming_language-1.7.1 → pyscript_programming_language-1.7.3}/pyscript/core/symtab.py +1 -3
  17. pyscript_programming_language-1.7.3/pyscript/core/utils/ansi.py +64 -0
  18. {pyscript_programming_language-1.7.1 → pyscript_programming_language-1.7.3}/pyscript/core/utils/debug.py +7 -6
  19. {pyscript_programming_language-1.7.1 → pyscript_programming_language-1.7.3}/pyscript/core/utils/decorators.py +2 -2
  20. {pyscript_programming_language-1.7.1 → pyscript_programming_language-1.7.3}/pyscript/core/utils/generic.py +30 -12
  21. {pyscript_programming_language-1.7.1 → pyscript_programming_language-1.7.3}/pyscript/core/utils/module.py +10 -5
  22. {pyscript_programming_language-1.7.1 → pyscript_programming_language-1.7.3}/pyscript/core/utils/shell.py +4 -0
  23. {pyscript_programming_language-1.7.1 → pyscript_programming_language-1.7.3}/pyscript/core/utils/string.py +7 -1
  24. {pyscript_programming_language-1.7.1 → pyscript_programming_language-1.7.3}/pyscript/core/version.py +23 -5
  25. {pyscript_programming_language-1.7.1 → pyscript_programming_language-1.7.3}/pyscript/lib/ast/__init__.pys +6 -0
  26. pyscript_programming_language-1.7.3/pyscript/lib/ast/ast_literal_eval.py +51 -0
  27. {pyscript_programming_language-1.7.1 → pyscript_programming_language-1.7.3}/pyscript/lib/ast/ast_unparse.py +6 -69
  28. {pyscript_programming_language-1.7.1 → pyscript_programming_language-1.7.3}/pyscript/lib/brainfuck.pys +3 -3
  29. pyscript_programming_language-1.7.3/pyscript/lib/dis.pys +7 -0
  30. pyscript_programming_language-1.7.3/pyscript/lib/token.pys +12 -0
  31. {pyscript_programming_language-1.7.1 → pyscript_programming_language-1.7.3}/pyscript/lib/tokenize/__init__.pys +3 -1
  32. pyscript_programming_language-1.7.3/pyscript/lib/tokenize/tok_untokenize.py +27 -0
  33. {pyscript_programming_language-1.7.1 → pyscript_programming_language-1.7.3}/pyscript_programming_language.egg-info/PKG-INFO +2 -2
  34. {pyscript_programming_language-1.7.1 → pyscript_programming_language-1.7.3}/pyscript_programming_language.egg-info/SOURCES.txt +1 -0
  35. {pyscript_programming_language-1.7.1 → pyscript_programming_language-1.7.3}/setup.py +2 -2
  36. pyscript_programming_language-1.7.1/pyscript/core/mapping.py +0 -128
  37. pyscript_programming_language-1.7.1/pyscript/core/position.py +0 -99
  38. pyscript_programming_language-1.7.1/pyscript/core/utils/ansi.py +0 -37
  39. pyscript_programming_language-1.7.1/pyscript/lib/dis.pys +0 -7
  40. pyscript_programming_language-1.7.1/pyscript/lib/token.pys +0 -1
  41. pyscript_programming_language-1.7.1/pyscript/lib/tokenize/tok_untokenize.py +0 -89
  42. {pyscript_programming_language-1.7.1 → pyscript_programming_language-1.7.3}/MANIFEST.in +0 -0
  43. {pyscript_programming_language-1.7.1 → pyscript_programming_language-1.7.3}/README.md +0 -0
  44. {pyscript_programming_language-1.7.1 → pyscript_programming_language-1.7.3}/pyscript/__init__.py +0 -0
  45. {pyscript_programming_language-1.7.1 → pyscript_programming_language-1.7.3}/pyscript/core/__init__.py +0 -0
  46. {pyscript_programming_language-1.7.1 → pyscript_programming_language-1.7.3}/pyscript/core/bases.py +0 -0
  47. {pyscript_programming_language-1.7.1 → pyscript_programming_language-1.7.3}/pyscript/core/buffer.py +0 -0
  48. {pyscript_programming_language-1.7.1 → pyscript_programming_language-1.7.3}/pyscript/core/checks.py +0 -0
  49. {pyscript_programming_language-1.7.1 → pyscript_programming_language-1.7.3}/pyscript/core/constants.py +0 -0
  50. {pyscript_programming_language-1.7.1 → pyscript_programming_language-1.7.3}/pyscript/core/context.py +0 -0
  51. {pyscript_programming_language-1.7.1 → pyscript_programming_language-1.7.3}/pyscript/core/handlers.py +0 -0
  52. {pyscript_programming_language-1.7.1 → pyscript_programming_language-1.7.3}/pyscript/core/interpreter.py +0 -0
  53. {pyscript_programming_language-1.7.1 → pyscript_programming_language-1.7.3}/pyscript/core/nodes.py +0 -0
  54. {pyscript_programming_language-1.7.1 → pyscript_programming_language-1.7.3}/pyscript/core/token.py +0 -0
  55. {pyscript_programming_language-1.7.1 → pyscript_programming_language-1.7.3}/pyscript/core/utils/__init__.py +0 -0
  56. {pyscript_programming_language-1.7.1 → pyscript_programming_language-1.7.3}/pyscript/core/utils/path.py +0 -0
  57. {pyscript_programming_language-1.7.1 → pyscript_programming_language-1.7.3}/pyscript/core/utils/similarity.py +0 -0
  58. {pyscript_programming_language-1.7.1 → pyscript_programming_language-1.7.3}/pyscript/lib/__hello__.pys +0 -0
  59. {pyscript_programming_language-1.7.1 → pyscript_programming_language-1.7.3}/pyscript/lib/ansi.pys +0 -0
  60. {pyscript_programming_language-1.7.1 → pyscript_programming_language-1.7.3}/pyscript/lib/ast/ast_dump.py +0 -0
  61. {pyscript_programming_language-1.7.1 → pyscript_programming_language-1.7.3}/pyscript/lib/ast/ast_walk.py +0 -0
  62. {pyscript_programming_language-1.7.1 → pyscript_programming_language-1.7.3}/pyscript/lib/explorer.pys +0 -0
  63. {pyscript_programming_language-1.7.1 → pyscript_programming_language-1.7.3}/pyscript/lib/fpstimer.pys +0 -0
  64. {pyscript_programming_language-1.7.1 → pyscript_programming_language-1.7.3}/pyscript/lib/getch.pys +0 -0
  65. {pyscript_programming_language-1.7.1 → pyscript_programming_language-1.7.3}/pyscript/lib/inspect.pys +0 -0
  66. {pyscript_programming_language-1.7.1 → pyscript_programming_language-1.7.3}/pyscript/lib/jsdict.pys +0 -0
  67. {pyscript_programming_language-1.7.1 → pyscript_programming_language-1.7.3}/pyscript/lib/keyword.pys +0 -0
  68. {pyscript_programming_language-1.7.1 → pyscript_programming_language-1.7.3}/pyscript/lib/parser.pys +0 -0
  69. {pyscript_programming_language-1.7.1 → pyscript_programming_language-1.7.3}/pyscript/lib/site.pys +0 -0
  70. {pyscript_programming_language-1.7.1 → pyscript_programming_language-1.7.3}/pyscript/lib/symtable.pys +0 -0
  71. {pyscript_programming_language-1.7.1 → pyscript_programming_language-1.7.3}/pyscript/lib/sys.pys +0 -0
  72. {pyscript_programming_language-1.7.1 → pyscript_programming_language-1.7.3}/pyscript/lib/this.pys +0 -0
  73. {pyscript_programming_language-1.7.1 → pyscript_programming_language-1.7.3}/pyscript/site-packages/67.pys +0 -0
  74. {pyscript_programming_language-1.7.1 → pyscript_programming_language-1.7.3}/pyscript/this.py +0 -0
  75. {pyscript_programming_language-1.7.1 → pyscript_programming_language-1.7.3}/pyscript_programming_language.egg-info/dependency_links.txt +0 -0
  76. {pyscript_programming_language-1.7.1 → pyscript_programming_language-1.7.3}/pyscript_programming_language.egg-info/requires.txt +0 -0
  77. {pyscript_programming_language-1.7.1 → pyscript_programming_language-1.7.3}/pyscript_programming_language.egg-info/top_level.txt +0 -0
  78. {pyscript_programming_language-1.7.1 → pyscript_programming_language-1.7.3}/setup.cfg +0 -0
@@ -1,8 +1,8 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: pyscript-programming-language
3
- Version: 1.7.1
3
+ Version: 1.7.3
4
4
  Summary: PyScript Programming Language
5
- Home-page: https://github.com/azzammuhyala/pyscript
5
+ Home-page: https://azzammuhyala.github.io/pyscript
6
6
  Author: azzammuhyala
7
7
  Author-email: azzammuhyala@gmail.com
8
8
  License: MIT
@@ -1,5 +1,3 @@
1
- from .core.highlight import PygmentsPyScriptLexer as PygmentsPyScriptLexer
2
-
3
1
  from typing import TYPE_CHECKING, Any, Callable, Iterator, Literal, Optional
4
2
 
5
3
  if TYPE_CHECKING:
@@ -15,6 +13,7 @@ if TYPE_CHECKING:
15
13
  from types import ModuleType
16
14
 
17
15
  from . import core as core
16
+ from .core.highlight import PygmentsPyScriptLexer as PygmentsPyScriptLexer
18
17
 
19
18
  DEFAULT: int
20
19
  DEBUG: int
@@ -37,13 +36,8 @@ def pys_highlight(
37
36
  Callable[
38
37
  [
39
38
  str | Literal[
40
- 'start',
41
- 'invalid',
42
- 'identifier', 'identifier-constant', 'identifier-function', 'identifier-type',
43
- 'keyword', 'keyword-constant',
44
- 'number', 'string', 'comment', 'newline',
45
- 'default',
46
- 'end'
39
+ 'start', 'invalid', 'identifier', 'identifier-constant', 'identifier-function', 'identifier-type',
40
+ 'keyword', 'keyword-constant', 'number', 'string', 'comment', 'newline', 'default', 'end'
47
41
  ],
48
42
  PysPosition,
49
43
  str
@@ -9,7 +9,8 @@ from .core.version import __version__
9
9
 
10
10
  from argparse import ArgumentParser
11
11
  from os import environ
12
- from sys import executable, stderr, version_info, exit, setrecursionlimit
12
+
13
+ import sys
13
14
 
14
15
  FORMAT_HIGHLIGHT_MAP = {
15
16
  'html': HLFMT_HTML,
@@ -18,8 +19,8 @@ FORMAT_HIGHLIGHT_MAP = {
18
19
  }
19
20
 
20
21
  parser = ArgumentParser(
21
- prog=f'{get_module_name_from_path(executable)} -m pyscript',
22
- description=f'PyScript Launcher for Python Version {".".join(map(str, version_info))}'
22
+ prog=f'{get_module_name_from_path(sys.executable)} -m pyscript',
23
+ description=f'PyScript Launcher for Python Version {".".join(map(str, sys.version_info))}'
23
24
  )
24
25
 
25
26
  parser.add_argument(
@@ -27,7 +28,7 @@ parser.add_argument(
27
28
  type=str,
28
29
  nargs='?',
29
30
  default=None,
30
- help="file path"
31
+ help="File path to be executed"
31
32
  )
32
33
 
33
34
  parser.add_argument(
@@ -40,53 +41,53 @@ parser.add_argument(
40
41
  '-c', '--command',
41
42
  type=str,
42
43
  default=None,
43
- help="execute PyScript from argument",
44
+ help="Execute program from a string argument",
44
45
  )
45
46
 
46
47
  parser.add_argument(
47
48
  '-d', '--debug',
48
49
  action='store_true',
49
- help="set a debug flag, this will remove the assert statement"
50
+ help="Set a debug flag, this will remove the assert statement"
50
51
  )
51
52
 
52
53
  parser.add_argument(
53
54
  '-i', '--inspect',
54
55
  action='store_true',
55
- help="inspect interactively after running a file",
56
+ help="Inspect interactively after running a 'file'",
56
57
  )
57
58
 
58
59
  parser.add_argument(
59
60
  '-l', '--highlight',
60
61
  choices=tuple(FORMAT_HIGHLIGHT_MAP.keys()),
61
62
  default=None,
62
- help='generate PyScript highlight code from a file'
63
+ help="Generate highlight code from a 'file'"
63
64
  )
64
65
 
65
66
  parser.add_argument(
66
67
  '-n', '--no-color',
67
68
  action='store_true',
68
- help="no colorful traceback"
69
+ help="Suppress colored output"
69
70
  )
70
71
 
71
72
  parser.add_argument(
72
73
  '-r', '--py-recursion',
73
74
  type=int,
74
75
  default=None,
75
- help="set a python recursion limit"
76
+ help="Set a Python recursion limit"
76
77
  )
77
78
 
78
79
  def argument_error(argument, message):
79
- parser.print_usage(stderr)
80
+ parser.print_usage(sys.stderr)
80
81
  parser.exit(2, f"{parser.prog}: error: argument {argument}: {message}\n")
81
82
 
82
83
  args = parser.parse_args()
83
84
 
84
85
  if args.highlight and args.file is None:
85
- argument_error("-l/--highlight", "file path require")
86
+ argument_error("-l/--highlight", "argument 'file' required")
86
87
 
87
88
  if args.py_recursion is not None:
88
89
  try:
89
- setrecursionlimit(args.py_recursion)
90
+ sys.setrecursionlimit(args.py_recursion)
90
91
  except BaseException as e:
91
92
  argument_error("-r/--py-recursion", e)
92
93
 
@@ -121,7 +122,7 @@ if args.file is not None:
121
122
 
122
123
  if args.highlight:
123
124
  try:
124
- print(pys_highlight(file, FORMAT_HIGHLIGHT_MAP.get(args.highlight, None)))
125
+ print(pys_highlight(file, FORMAT_HIGHLIGHT_MAP.get(args.highlight)))
125
126
  except BaseException as e:
126
127
  parser.error(f"file {path!r}: Highlight error: {e}")
127
128
 
@@ -150,4 +151,4 @@ elif args.command is not None:
150
151
  else:
151
152
  code = pys_shell(undefined, flags)
152
153
 
153
- exit(code)
154
+ sys.exit(code)
@@ -157,23 +157,25 @@ class PysAnalyzer(Pys):
157
157
  self.visit(node.right)
158
158
 
159
159
  def visit_UnaryOperatorNode(self, node):
160
+ value = node.value
161
+
160
162
  if is_incremental(node.operand.type):
161
- type = node.value.__class__
163
+ type = value.__class__
162
164
  operator = 'increase' if node.operand.type == TOKENS['DOUBLE-PLUS'] else 'decrease'
163
165
 
164
166
  if type is PysKeywordNode:
165
- self.throw(f"cannot {operator} {node.value.token.value}", node.value.position)
167
+ self.throw(f"cannot {operator} {value.name.value}", value.position)
166
168
  return
167
169
 
168
- elif isinstance(node.value, PysNode):
170
+ elif isinstance(value, PysNode):
169
171
  if type not in (PysIdentifierNode, PysAttributeNode, PysSubscriptNode):
170
- self.throw(f"cannot {operator} literal", node.value.position)
172
+ self.throw(f"cannot {operator} literal", value.position)
171
173
  return
172
174
 
173
175
  else:
174
176
  raise TypeError("UnaryOperator: node.value is not PysNode")
175
177
 
176
- self.visit(node.value)
178
+ self.visit(value)
177
179
 
178
180
  def visit_StatementsNode(self, node):
179
181
  for element in node.body:
@@ -435,7 +437,7 @@ class PysAnalyzer(Pys):
435
437
  return
436
438
 
437
439
  elif type is PysKeywordNode:
438
- self.throw(f"cannot delete {target.token.value}", target.position)
440
+ self.throw(f"cannot delete {target.name.value}", target.position)
439
441
  return
440
442
 
441
443
  elif isinstance(target, PysNode):
@@ -502,7 +504,7 @@ class PysAnalyzer(Pys):
502
504
  return
503
505
 
504
506
  elif type is PysKeywordNode:
505
- self.throw(f"cannot assign to {node.token.value}", node.position)
507
+ self.throw(f"cannot assign to {node.name.value}", node.position)
506
508
 
507
509
  elif isinstance(node, PysNode):
508
510
  if type is not PysIdentifierNode:
@@ -71,7 +71,7 @@ class PysHook(Pys):
71
71
  @display.setter
72
72
  def display(self, value):
73
73
  if value is not None and not callable(value):
74
- raise TypeError("sys.hook.display: must be callable")
74
+ raise TypeError("hook.display: must be callable")
75
75
  singletons['hook.display'] = value
76
76
 
77
77
  @property
@@ -81,7 +81,7 @@ class PysHook(Pys):
81
81
  @exception.setter
82
82
  def exception(self, value):
83
83
  if value is not None and not callable(value):
84
- raise TypeError("sys.hook.exception: must be callable")
84
+ raise TypeError("hook.exception: must be callable")
85
85
  singletons['hook.exception'] = value
86
86
 
87
87
  @property
@@ -91,7 +91,7 @@ class PysHook(Pys):
91
91
  @ps1.setter
92
92
  def ps1(self, value):
93
93
  if not isinstance(value, str):
94
- raise TypeError("sys.hook.ps1: must be a string")
94
+ raise TypeError("hook.ps1: must be a string")
95
95
  singletons['hook.ps1'] = value
96
96
 
97
97
  @property
@@ -101,7 +101,7 @@ class PysHook(Pys):
101
101
  @ps2.setter
102
102
  def ps2(self, value):
103
103
  if not isinstance(value, str):
104
- raise TypeError("sys.hook.ps2: must be a string")
104
+ raise TypeError("hook.ps2: must be a string")
105
105
  singletons['hook.ps2'] = value
106
106
 
107
107
  PysUndefined()
@@ -21,13 +21,15 @@ class PysTraceback(Pys):
21
21
  return f'<traceback of exception {self.exception!r}>'
22
22
 
23
23
  def string_traceback(self):
24
+ from .position import format_arrow # circular import problem solved
25
+
24
26
  context = self.context
25
27
  position = self.position
26
28
 
27
29
  if colored := not (context.flags & NO_COLOR):
28
30
  reset = acolor('reset')
29
31
  magenta = acolor('magenta')
30
- bmagenta = acolor('magenta', BOLD)
32
+ bmagenta = acolor('magenta', style=BOLD)
31
33
  else:
32
34
  reset = ''
33
35
  magenta = ''
@@ -44,7 +46,7 @@ class PysTraceback(Pys):
44
46
  '{}{}{}'.format(
45
47
  '' if is_positionless else f', line {magenta}{position.start_line}{reset}',
46
48
  '' if context_name is None else f', in {magenta}{context_name}{reset}',
47
- '' if is_positionless else f'\n{indent(position.format_arrow(colored), 4)}'
49
+ '' if is_positionless else f'\n{indent(format_arrow(position, colored), 4)}'
48
50
  )
49
51
  )
50
52
 
@@ -3,15 +3,33 @@ from .buffer import PysFileBuffer
3
3
  from .checks import is_left_bracket, is_right_bracket, is_bracket, is_constant_keywords, is_public_attribute
4
4
  from .constants import TOKENS, KEYWORDS, CONSTANT_KEYWORDS, HIGHLIGHT
5
5
  from .lexer import PysLexer
6
- from .mapping import BRACKETS_MAP, HIGHLIGHT_MAP
6
+ from .mapping import BRACKETS_MAP
7
7
  from .position import PysPosition
8
8
  from .pysbuiltins import pys_builtins
9
9
  from .utils.ansi import acolor
10
10
  from .utils.decorators import typechecked
11
11
 
12
12
  from html import escape as html_escape
13
+ from types import MappingProxyType
13
14
  from typing import Callable, Optional
14
15
 
16
+ HIGHLIGHT_MAP = MappingProxyType({
17
+ 'default': '#D4D4D4',
18
+ 'keyword': '#C586C0',
19
+ 'keyword-constant': '#307CD6',
20
+ 'identifier': '#8CDCFE',
21
+ 'identifier-constant': '#2EA3FF',
22
+ 'identifier-function': '#DCDCAA',
23
+ 'identifier-type': '#4EC9B0',
24
+ 'number': '#B5CEA8',
25
+ 'string': '#CE9178',
26
+ 'brackets-0': '#FFD705',
27
+ 'brackets-1': '#D45DBA',
28
+ 'brackets-2': '#1A9FFF',
29
+ 'comment': '#549952',
30
+ 'invalid': '#B51819'
31
+ })
32
+
15
33
  _builtin_types = tuple(
16
34
  name
17
35
  for name, object in pys_builtins.__dict__.items()
@@ -221,7 +239,7 @@ except ImportError:
221
239
  class PygmentsPyScriptLexer(Pys):
222
240
 
223
241
  def __new__(cls, *args, **kwargs):
224
- raise ModuleNotFoundError("pygments is not found")
242
+ raise ModuleNotFoundError("module pygments is not found")
225
243
 
226
244
  @typechecked
227
245
  class _PysHighlightFormatter(Pys):
@@ -9,8 +9,23 @@ from .token import PysToken
9
9
  from .utils.decorators import typechecked
10
10
 
11
11
  from unicodedata import lookup as unicode_lookup
12
+ from types import MappingProxyType
12
13
  from typing import Optional
13
- from sys import stderr
14
+
15
+ import sys
16
+
17
+ ESCAPE_CHARACTERS_MAP = MappingProxyType({
18
+ '\\': '\\',
19
+ "'": "'",
20
+ '"': '"',
21
+ 'n': '\n',
22
+ 'r': '\r',
23
+ 't': '\t',
24
+ 'b': '\b',
25
+ 'f': '\f',
26
+ 'a': '\a',
27
+ 'v': '\v'
28
+ })
14
29
 
15
30
  class PysLexer(Pys):
16
31
 
@@ -415,24 +430,8 @@ class PysLexer(Pys):
415
430
  self.advance()
416
431
 
417
432
  elif self.character_in('\\\'"nrtbfav\n'):
418
-
419
- if self.character_in('\\\'"'):
420
- string += self.current_character
421
- elif self.current_character == 'n':
422
- string += '\n'
423
- elif self.current_character == 'r':
424
- string += '\r'
425
- elif self.current_character == 't':
426
- string += '\t'
427
- elif self.current_character == 'b':
428
- string += '\b'
429
- elif self.current_character == 'f':
430
- string += '\f'
431
- elif self.current_character == 'a':
432
- string += '\a'
433
- elif self.current_character == 'v':
434
- string += '\v'
435
-
433
+ if escape_character := ESCAPE_CHARACTERS_MAP.get(self.current_character):
434
+ string += escape_character
436
435
  self.advance()
437
436
 
438
437
  elif decoded_error_message is None:
@@ -521,7 +520,7 @@ class PysLexer(Pys):
521
520
  warning_displayed = True
522
521
  print(
523
522
  f"SyntaxWarning: invalid escape sequence '\\{self.current_character}'",
524
- file=stderr
523
+ file=sys.stderr
525
524
  )
526
525
 
527
526
  string += '\\' + self.current_character
@@ -0,0 +1,131 @@
1
+ from .constants import TOKENS, KEYWORDS
2
+
3
+ from operator import (
4
+ is_not, eq, ne, lt, gt, le, ge, add, sub, mul, truediv, floordiv, pow, matmul, mod, and_, or_, xor, lshift, rshift,
5
+ iadd, isub, imul, itruediv, ifloordiv, ipow, imatmul, imod, iand, ior, ixor, ilshift, irshift, pos, neg, inv
6
+ )
7
+ from types import MappingProxyType
8
+
9
+ BINARY_FUNCTIONS_MAP = MappingProxyType({
10
+ TOKENS['NOT-IN']: lambda a, b : a not in b,
11
+ TOKENS['IS-NOT']: is_not,
12
+ TOKENS['PLUS']: add,
13
+ TOKENS['MINUS']: sub,
14
+ TOKENS['STAR']: mul,
15
+ TOKENS['SLASH']: truediv,
16
+ TOKENS['DOUBLE-SLASH']: floordiv,
17
+ TOKENS['DOUBLE-STAR']: pow,
18
+ TOKENS['AT']: matmul,
19
+ TOKENS['PERCENT']: mod,
20
+ TOKENS['AMPERSAND']: and_,
21
+ TOKENS['PIPE']: or_,
22
+ TOKENS['CIRCUMFLEX']: xor,
23
+ TOKENS['DOUBLE-LESS-THAN']: lshift,
24
+ TOKENS['DOUBLE-GREATER-THAN']: rshift,
25
+ TOKENS['DOUBLE-EQUAL']: eq,
26
+ TOKENS['EQUAL-EXCLAMATION']: ne,
27
+ TOKENS['LESS-THAN']: lt,
28
+ TOKENS['GREATER-THAN']: gt,
29
+ TOKENS['EQUAL-LESS-THAN']: le,
30
+ TOKENS['EQUAL-GREATER-THAN']: ge,
31
+ TOKENS['EQUAL-PLUS']: iadd,
32
+ TOKENS['EQUAL-MINUS']: isub,
33
+ TOKENS['EQUAL-STAR']: imul,
34
+ TOKENS['EQUAL-SLASH']: itruediv,
35
+ TOKENS['EQUAL-DOUBLE-SLASH']: ifloordiv,
36
+ TOKENS['EQUAL-DOUBLE-STAR']: ipow,
37
+ TOKENS['EQUAL-AT']: imatmul,
38
+ TOKENS['EQUAL-PERCENT']: imod,
39
+ TOKENS['EQUAL-AMPERSAND']: iand,
40
+ TOKENS['EQUAL-PIPE']: ior,
41
+ TOKENS['EQUAL-CIRCUMFLEX']: ixor,
42
+ TOKENS['EQUAL-DOUBLE-LESS-THAN']: ilshift,
43
+ TOKENS['EQUAL-DOUBLE-GREATER-THAN']: irshift,
44
+ })
45
+
46
+ UNARY_FUNCTIONS_MAP = MappingProxyType({
47
+ TOKENS['PLUS']: pos,
48
+ TOKENS['MINUS']: neg,
49
+ TOKENS['TILDE']: inv
50
+ })
51
+
52
+ KEYWORDS_TO_VALUES_MAP = MappingProxyType({
53
+ KEYWORDS['True']: True,
54
+ KEYWORDS['False']: False,
55
+ KEYWORDS['None']: None,
56
+ KEYWORDS['true']: True,
57
+ KEYWORDS['false']: False,
58
+ KEYWORDS['none']: None
59
+ })
60
+
61
+ BRACKETS_MAP = MappingProxyType({
62
+ TOKENS['LEFT-PARENTHESIS']: TOKENS['RIGHT-PARENTHESIS'],
63
+ TOKENS['LEFT-SQUARE']: TOKENS['RIGHT-SQUARE'],
64
+ TOKENS['LEFT-CURLY']: TOKENS['RIGHT-CURLY']
65
+ })
66
+
67
+ SYMBOLS_TOKEN_MAP = MappingProxyType({
68
+ TOKENS['NOT-IN']: KEYWORDS['not'] + ' ' + KEYWORDS['in'],
69
+ TOKENS['IS-NOT']: KEYWORDS['is'] + ' ' + KEYWORDS['not'],
70
+ TOKENS['NULL']: '\0',
71
+ TOKENS['NEWLINE']: '\n',
72
+ TOKENS['EXCLAMATION']: '!',
73
+ TOKENS['COMMENT']: '#',
74
+ TOKENS['PERCENT']: '%',
75
+ TOKENS['AMPERSAND']: '&',
76
+ TOKENS['RIGHT-PARENTHESIS']: ')',
77
+ TOKENS['LEFT-PARENTHESIS']: '(',
78
+ TOKENS['STAR']: '*',
79
+ TOKENS['PLUS']: '+',
80
+ TOKENS['COMMA']: ',',
81
+ TOKENS['MINUS']: '-',
82
+ TOKENS['DOT']: '.',
83
+ TOKENS['SLASH']: '/',
84
+ TOKENS['COLON']: ':',
85
+ TOKENS['SEMICOLON']: ';',
86
+ TOKENS['LESS-THAN']: '<',
87
+ TOKENS['EQUAL']: '=',
88
+ TOKENS['GREATER-THAN']: '>',
89
+ TOKENS['QUESTION']: '?',
90
+ TOKENS['AT']: '@',
91
+ TOKENS['LEFT-SQUARE']: '[',
92
+ TOKENS['RIGHT-SQUARE']: ']',
93
+ TOKENS['CIRCUMFLEX']: '^',
94
+ TOKENS['LEFT-CURLY']: '{',
95
+ TOKENS['PIPE']: '|',
96
+ TOKENS['RIGHT-CURLY']: '}',
97
+ TOKENS['TILDE']: '~',
98
+ TOKENS['DOUBLE-AMPERSAND']: '&&',
99
+ TOKENS['DOUBLE-STAR']: '**',
100
+ TOKENS['DOUBLE-PLUS']: '++',
101
+ TOKENS['DOUBLE-MINUS']: '--',
102
+ TOKENS['DOUBLE-SLASH']: '//',
103
+ TOKENS['DOUBLE-LESS-THAN']: '<<',
104
+ TOKENS['DOUBLE-EQUAL']: '==',
105
+ TOKENS['DOUBLE-GREATER-THAN']: '>>',
106
+ TOKENS['DOUBLE-QUESTION']: '??',
107
+ TOKENS['DOUBLE-PIPE']: '||',
108
+ TOKENS['TRIPLE-DOT']: '...',
109
+ TOKENS['EQUAL-EXCLAMATION']: '!=',
110
+ TOKENS['EQUAL-PERCENT']: '%=',
111
+ TOKENS['EQUAL-AMPERSAND']: '&=',
112
+ TOKENS['EQUAL-STAR']: '*=',
113
+ TOKENS['EQUAL-PLUS']: '+=',
114
+ TOKENS['EQUAL-MINUS']: '-=',
115
+ TOKENS['EQUAL-SLASH']: '/=',
116
+ TOKENS['EQUAL-COLON']: ':=',
117
+ TOKENS['EQUAL-LESS-THAN']: '<=',
118
+ TOKENS['EQUAL-GREATER-THAN']: '>=',
119
+ TOKENS['EQUAL-AT']: '@=',
120
+ TOKENS['EQUAL-CIRCUMFLEX']: '^=',
121
+ TOKENS['EQUAL-PIPE']: '|=',
122
+ TOKENS['EQUAL-TILDE']: '~=',
123
+ TOKENS['EQUAL-DOUBLE-STAR']: '**=',
124
+ TOKENS['EQUAL-DOUBLE-SLASH']: '//=',
125
+ TOKENS['EQUAL-DOUBLE-LESS-THAN']: '<<=',
126
+ TOKENS['EQUAL-DOUBLE-GREATER-THAN']: '>>=',
127
+ TOKENS['EQUAL-ARROW']: '=>',
128
+ TOKENS['EXCLAMATION-TILDE']: '~!'
129
+ })
130
+
131
+ EMPTY_MAP = MappingProxyType({})
@@ -19,10 +19,11 @@ class PysCode(PysObject):
19
19
  class PysPythonFunction(PysObject):
20
20
 
21
21
  def __init__(self, func):
22
- from .handlers import handle_call
22
+ from .handlers import handle_call # circular import problem solved
23
23
 
24
- self.__name__ = func.__name__
25
- self.__qualname__ = func.__qualname__
24
+ self.__name__ = getattr(func, '__name__', '<function>')
25
+ self.__qualname__ = getattr(func, '__qualname__', '<function>')
26
+ self.__doc__ = getattr(func, '__doc__', None)
26
27
  self.__func__ = func
27
28
  self.__code__ = PysCode(
28
29
  position=None,
@@ -46,7 +47,7 @@ class PysPythonFunction(PysObject):
46
47
  class PysFunction(PysObject):
47
48
 
48
49
  def __init__(self, name, qualname, parameters, body, position, context):
49
- from .interpreter import visit
50
+ from .interpreter import visit # circular import problem solved
50
51
 
51
52
  context = context.parent if isinstance(context, PysClassContext) else context
52
53
 
@@ -3,7 +3,7 @@ from .checks import is_right_bracket
3
3
  from .constants import TOKENS, KEYWORDS, DEFAULT, REVERSE_POW_XOR
4
4
  from .context import PysContext
5
5
  from .exceptions import PysTraceback
6
- from .mapping import BRACKETS_ITERABLE_MAP, NODE_ITERABLE_MAP, BRACKETS_MAP
6
+ from .mapping import BRACKETS_MAP
7
7
  from .nodes import *
8
8
  from .position import PysPosition
9
9
  from .results import PysParserResult
@@ -11,8 +11,23 @@ from .token import PysToken
11
11
  from .utils.decorators import typechecked
12
12
  from .utils.generic import setimuattr
13
13
 
14
+ from types import MappingProxyType
14
15
  from typing import Optional, Callable
15
16
 
17
+ BRACKETS_ITERABLE_MAP = MappingProxyType({
18
+ 'dict': TOKENS['LEFT-CURLY'],
19
+ 'set': TOKENS['LEFT-CURLY'],
20
+ 'list': TOKENS['LEFT-SQUARE'],
21
+ 'tuple': TOKENS['LEFT-PARENTHESIS']
22
+ })
23
+
24
+ NODE_ITERABLE_MAP = MappingProxyType({
25
+ 'dict': PysDictionaryNode,
26
+ 'set': PysSetNode,
27
+ 'list': PysListNode,
28
+ 'tuple': PysTupleNode
29
+ })
30
+
16
31
  class PysParser(Pys):
17
32
 
18
33
  @typechecked
@@ -0,0 +1,99 @@
1
+ from .bases import Pys
2
+ from .buffer import PysFileBuffer
3
+ from .utils.ansi import BOLD, acolor
4
+ from .utils.decorators import typechecked, immutable
5
+ from .utils.generic import setimuattr
6
+
7
+ @immutable
8
+ class PysPosition(Pys):
9
+
10
+ __slots__ = ('file', 'start', 'end', 'start_line', 'start_column', 'end_line', 'end_column', 'is_positionless')
11
+
12
+ @typechecked
13
+ def __init__(self, file: PysFileBuffer, start: int, end: int) -> None:
14
+ is_positionless = start < 0 or end < 0 or start > end or end > len(file.text) + 1
15
+
16
+ setimuattr(self, 'file', file)
17
+ setimuattr(self, 'start', -1 if is_positionless else start)
18
+ setimuattr(self, 'end', -1 if is_positionless else end)
19
+ setimuattr(self, 'start_line', -1 if is_positionless else file.text.count('\n', 0, start) + 1)
20
+ setimuattr(self, 'start_column', -1 if is_positionless else start - file.text.rfind('\n', 0, start))
21
+ setimuattr(self, 'end_line', -1 if is_positionless else file.text.count('\n', 0, end) + 1)
22
+ setimuattr(self, 'end_column', -1 if is_positionless else end - file.text.rfind('\n', 0, end))
23
+ setimuattr(self, 'is_positionless', is_positionless)
24
+
25
+ def __repr__(self):
26
+ return f'<Position({self.start!r}, {self.end!r}) from {self.file.name!r}>'
27
+
28
+ def format_arrow(position, colored=True):
29
+ if position.is_positionless:
30
+ return ''
31
+
32
+ if colored:
33
+ reset = acolor('reset')
34
+ bred = acolor('red', style=BOLD)
35
+ else:
36
+ reset = ''
37
+ bred = ''
38
+
39
+ line_start = position.start_line
40
+ line_end = position.end_line
41
+ column_start = position.start_column
42
+ column_end = position.end_column
43
+
44
+ text = position.file.text
45
+
46
+ start = text.rfind('\n', 0, position.start) + 1
47
+ end = text.find('\n', start + 1)
48
+ if end == -1:
49
+ end = len(text)
50
+
51
+ if text[position.start:position.end] in ('', '\n'):
52
+ if position.start > start:
53
+ line = text[start:end].lstrip().replace('\t', ' ')
54
+ return f'{line}\n{bred}{" " * len(line)}^{reset}'
55
+ return f'\n{bred}^{reset}'
56
+
57
+ result = []
58
+ lines = []
59
+ count = line_end - line_start + 1
60
+
61
+ for i in range(count):
62
+ line = text[start:end].lstrip('\n')
63
+
64
+ lines.append(
65
+ (
66
+ line,
67
+ len(line.lstrip()),
68
+ column_start - 1 if i == 0 else 0,
69
+ column_end - 1 if i == count - 1 else len(line)
70
+ )
71
+ )
72
+
73
+ start = end
74
+ end = text.find('\n', start + 1)
75
+ if end == -1:
76
+ end = len(text)
77
+
78
+ minimum_indent = min(len(line) - line_code_length for line, line_code_length, _, _ in lines)
79
+
80
+ for i, (line, line_code_length, start, end) in enumerate(lines):
81
+ line = line[minimum_indent:]
82
+ er = end - minimum_indent
83
+
84
+ if i == 0:
85
+ sr = start - minimum_indent
86
+
87
+ arrow = '^' * (end - start)
88
+ line = f'{line[:sr]}{bred}{line[sr:er]}{reset}{line[er:]}\n{" " * sr}{bred}{arrow}{reset}'
89
+
90
+ else:
91
+ indent = len(line) - line_code_length
92
+
93
+ arrow = '^' * (end - start - (minimum_indent + indent))
94
+ line = f'{line[:indent]}{bred}{line[indent:er]}{reset}{line[er:]}\n{" " * indent}{bred}{arrow}{reset}'
95
+
96
+ if arrow:
97
+ result.append(line)
98
+
99
+ return '\n'.join(result).replace('\t', ' ')