jaclang 0.0.5__py3-none-any.whl → 0.0.8__py3-none-any.whl
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 jaclang might be problematic. Click here for more details.
- jaclang/__init__.py +2 -1
- jaclang/cli/__jac_gen__/__init__.py +0 -0
- jaclang/cli/__jac_gen__/cli.py +175 -0
- jaclang/cli/__jac_gen__/cmds.py +132 -0
- jaclang/cli/cli.jac +2 -2
- jaclang/cli/cmds.jac +8 -2
- jaclang/cli/impl/__jac_gen__/__init__.py +0 -0
- jaclang/cli/impl/__jac_gen__/cli_impl.py +16 -0
- jaclang/cli/impl/__jac_gen__/cmds_impl.py +26 -0
- jaclang/cli/impl/cli_impl.jac +25 -8
- jaclang/cli/impl/cmds_impl.jac +35 -6
- jaclang/core/__jac_gen__/__init__.py +0 -0
- jaclang/core/__jac_gen__/primitives.py +567 -0
- jaclang/core/impl/__jac_gen__/__init__.py +0 -0
- jaclang/core/impl/__jac_gen__/arch_impl.py +24 -0
- jaclang/core/impl/__jac_gen__/element_impl.py +26 -0
- jaclang/core/impl/__jac_gen__/exec_ctx_impl.py +12 -0
- jaclang/core/impl/__jac_gen__/memory_impl.py +14 -0
- jaclang/core/impl/element_impl.jac +3 -3
- jaclang/core/impl/exec_ctx_impl.jac +3 -6
- jaclang/core/primitives.jac +4 -3
- jaclang/jac/absyntree.py +555 -180
- jaclang/jac/constant.py +6 -0
- jaclang/jac/importer.py +34 -56
- jaclang/jac/langserve.py +26 -0
- jaclang/jac/lexer.py +35 -3
- jaclang/jac/parser.py +146 -115
- jaclang/jac/passes/blue/__init__.py +8 -3
- jaclang/jac/passes/blue/ast_build_pass.py +454 -305
- jaclang/jac/passes/blue/blue_pygen_pass.py +112 -74
- jaclang/jac/passes/blue/decl_def_match_pass.py +49 -277
- jaclang/jac/passes/blue/import_pass.py +1 -1
- jaclang/jac/passes/blue/pyout_pass.py +74 -0
- jaclang/jac/passes/blue/semantic_check_pass.py +37 -0
- jaclang/jac/passes/blue/sym_tab_build_pass.py +1045 -0
- jaclang/jac/passes/blue/tests/test_ast_build_pass.py +2 -2
- jaclang/jac/passes/blue/tests/test_blue_pygen_pass.py +9 -28
- jaclang/jac/passes/blue/tests/test_decl_def_match_pass.py +13 -22
- jaclang/jac/passes/blue/tests/test_sym_tab_build_pass.py +22 -0
- jaclang/jac/passes/ir_pass.py +8 -6
- jaclang/jac/passes/purple/__jac_gen__/__init__.py +0 -0
- jaclang/jac/passes/purple/__jac_gen__/analyze_pass.py +37 -0
- jaclang/jac/passes/purple/__jac_gen__/purple_pygen_pass.py +305 -0
- jaclang/jac/passes/purple/impl/__jac_gen__/__init__.py +0 -0
- jaclang/jac/passes/purple/impl/__jac_gen__/purple_pygen_pass_impl.py +23 -0
- jaclang/jac/passes/purple/impl/purple_pygen_pass_impl.jac +2 -5
- jaclang/jac/symtable.py +154 -0
- jaclang/jac/tests/fixtures/__jac_gen__/__init__.py +0 -0
- jaclang/jac/tests/fixtures/__jac_gen__/hello_world.py +16 -0
- jaclang/jac/tests/fixtures/fam.jac +7 -8
- jaclang/jac/tests/fixtures/mod_doc_test.jac +1 -0
- jaclang/jac/tests/test_parser.py +8 -0
- jaclang/jac/transform.py +41 -14
- jaclang/jac/transpiler.py +18 -9
- jaclang/utils/fstring_parser.py +2 -2
- jaclang/utils/helpers.py +41 -0
- jaclang/utils/lang_tools.py +12 -2
- jaclang/utils/test.py +41 -0
- jaclang/vendor/__init__.py +1 -0
- jaclang/vendor/pygls/__init__.py +25 -0
- jaclang/vendor/pygls/capabilities.py +502 -0
- jaclang/vendor/pygls/client.py +176 -0
- jaclang/vendor/pygls/constants.py +26 -0
- jaclang/vendor/pygls/exceptions.py +220 -0
- jaclang/vendor/pygls/feature_manager.py +241 -0
- jaclang/vendor/pygls/lsp/__init__.py +139 -0
- jaclang/vendor/pygls/lsp/client.py +2224 -0
- jaclang/vendor/pygls/lsprotocol/__init__.py +2 -0
- jaclang/vendor/pygls/lsprotocol/_hooks.py +1233 -0
- jaclang/vendor/pygls/lsprotocol/converters.py +17 -0
- jaclang/vendor/pygls/lsprotocol/types.py +12820 -0
- jaclang/vendor/pygls/lsprotocol/validators.py +47 -0
- jaclang/vendor/pygls/progress.py +79 -0
- jaclang/vendor/pygls/protocol.py +1184 -0
- jaclang/vendor/pygls/server.py +620 -0
- jaclang/vendor/pygls/uris.py +184 -0
- jaclang/vendor/pygls/workspace/__init__.py +81 -0
- jaclang/vendor/pygls/workspace/position.py +204 -0
- jaclang/vendor/pygls/workspace/text_document.py +234 -0
- jaclang/vendor/pygls/workspace/workspace.py +311 -0
- {jaclang-0.0.5.dist-info → jaclang-0.0.8.dist-info}/METADATA +1 -1
- jaclang-0.0.8.dist-info/RECORD +118 -0
- jaclang/core/jaclang.jac +0 -62
- jaclang/jac/passes/blue/tests/test_type_analyze_pass.py +0 -53
- jaclang/jac/passes/blue/type_analyze_pass.py +0 -728
- jaclang/jac/sym_table.py +0 -127
- jaclang-0.0.5.dist-info/RECORD +0 -73
- /jaclang/{utils → vendor}/sly/__init__.py +0 -0
- /jaclang/{utils → vendor}/sly/docparse.py +0 -0
- /jaclang/{utils → vendor}/sly/lex.py +0 -0
- /jaclang/{utils → vendor}/sly/yacc.py +0 -0
- {jaclang-0.0.5.dist-info → jaclang-0.0.8.dist-info}/WHEEL +0 -0
- {jaclang-0.0.5.dist-info → jaclang-0.0.8.dist-info}/entry_points.txt +0 -0
- {jaclang-0.0.5.dist-info → jaclang-0.0.8.dist-info}/top_level.txt +0 -0
jaclang/jac/constant.py
CHANGED
|
@@ -7,6 +7,7 @@ class Constants(str, Enum):
|
|
|
7
7
|
|
|
8
8
|
JAC_LANG_IMP = "jac"
|
|
9
9
|
JAC_DEBUG_SPLITTER = "JAC DEBUG INFO"
|
|
10
|
+
JAC_ERROR_PREAMBLE = "Jac error originates from..."
|
|
10
11
|
PATCH = "PATCH"
|
|
11
12
|
|
|
12
13
|
JAC_TMP = "_jac_tmp"
|
|
@@ -27,6 +28,9 @@ class Constants(str, Enum):
|
|
|
27
28
|
WITH_DIR = "_jac_apply_dir_"
|
|
28
29
|
EDGE_DIR = "_jac_Edge_Dir_"
|
|
29
30
|
|
|
31
|
+
PYNLINE = "::py::"
|
|
32
|
+
JAC_GEN_DIR = "__jac_gen__"
|
|
33
|
+
|
|
30
34
|
def __str__(self) -> str:
|
|
31
35
|
"""Return the string representation of the token."""
|
|
32
36
|
return self.value
|
|
@@ -54,6 +58,7 @@ class Tokens(str, Enum):
|
|
|
54
58
|
FLOAT = "FLOAT"
|
|
55
59
|
STRING = "STRING"
|
|
56
60
|
DOC_STRING = "DOC_STRING"
|
|
61
|
+
PYNLINE = "PYNLINE"
|
|
57
62
|
FSTRING = "FSTRING"
|
|
58
63
|
BOOL = "BOOL"
|
|
59
64
|
INT = "INT"
|
|
@@ -75,6 +80,7 @@ class Tokens(str, Enum):
|
|
|
75
80
|
TYP_ANY = "TYP_ANY"
|
|
76
81
|
TYP_TYPE = "TYP_TYPE"
|
|
77
82
|
KW_FREEZE = "KW_FREEZE"
|
|
83
|
+
KW_ABSTRACT = "KW_ABSTRACT"
|
|
78
84
|
KW_OBJECT = "KW_OBJECT"
|
|
79
85
|
KW_ENUM = "KW_ENUM"
|
|
80
86
|
KW_NODE = "KW_NODE"
|
jaclang/jac/importer.py
CHANGED
|
@@ -4,12 +4,12 @@ import marshal
|
|
|
4
4
|
import sys
|
|
5
5
|
import traceback
|
|
6
6
|
import types
|
|
7
|
-
from os import
|
|
7
|
+
from os import path
|
|
8
8
|
from typing import Callable, Optional
|
|
9
9
|
|
|
10
|
-
from jaclang.jac.constant import Constants as Con
|
|
10
|
+
from jaclang.jac.constant import Constants as Con
|
|
11
11
|
from jaclang.jac.transpiler import transpile_jac_blue, transpile_jac_purple
|
|
12
|
-
from jaclang.utils.helpers import
|
|
12
|
+
from jaclang.utils.helpers import handle_jac_error
|
|
13
13
|
|
|
14
14
|
|
|
15
15
|
def import_jac_module(
|
|
@@ -17,11 +17,10 @@ def import_jac_module(
|
|
|
17
17
|
target: str,
|
|
18
18
|
base_path: Optional[str] = None,
|
|
19
19
|
cachable: bool = True,
|
|
20
|
+
override_name: Optional[str] = None,
|
|
20
21
|
) -> Optional[types.ModuleType]:
|
|
21
22
|
"""Core Import Process."""
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
dir_path, file_name = path.split(target)
|
|
23
|
+
dir_path, file_name = path.split(path.join(*(target.split("."))) + ".jac")
|
|
25
24
|
module_name = path.splitext(file_name)[0]
|
|
26
25
|
package_path = dir_path.replace(path.sep, ".")
|
|
27
26
|
|
|
@@ -35,11 +34,13 @@ def import_jac_module(
|
|
|
35
34
|
else:
|
|
36
35
|
frame = inspect.stack()[2]
|
|
37
36
|
caller_dir = path.dirname(path.abspath(frame[0].f_code.co_filename))
|
|
38
|
-
|
|
37
|
+
caller_dir = path.join(caller_dir, dir_path)
|
|
38
|
+
|
|
39
|
+
gen_dir = path.join(caller_dir, Con.JAC_GEN_DIR)
|
|
40
|
+
full_target = path.normpath(path.join(caller_dir, file_name))
|
|
39
41
|
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
py_file_path = path.join(dev_dir, module_name + ".py")
|
|
42
|
+
py_file_path = path.join(gen_dir, module_name + ".py")
|
|
43
|
+
pyc_file_path = path.join(gen_dir, module_name + ".pyc")
|
|
43
44
|
if (
|
|
44
45
|
cachable
|
|
45
46
|
and path.exists(py_file_path)
|
|
@@ -47,28 +48,21 @@ def import_jac_module(
|
|
|
47
48
|
):
|
|
48
49
|
with open(py_file_path, "r") as f:
|
|
49
50
|
code_string = f.read()
|
|
51
|
+
with open(pyc_file_path, "rb") as f:
|
|
52
|
+
codeobj = marshal.load(f)
|
|
50
53
|
else:
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
+
if transpiler_func(file_path=full_target, base_dir=caller_dir):
|
|
55
|
+
return None
|
|
56
|
+
with open(py_file_path, "r") as f:
|
|
57
|
+
code_string = f.read()
|
|
58
|
+
with open(pyc_file_path, "rb") as f:
|
|
59
|
+
codeobj = marshal.load(f)
|
|
54
60
|
|
|
55
61
|
module = types.ModuleType(module_name)
|
|
56
62
|
module.__file__ = full_target
|
|
57
|
-
module.__name__ = module_name
|
|
63
|
+
module.__name__ = override_name if override_name else module_name
|
|
58
64
|
module.__dict__["_jac_pycodestring_"] = code_string
|
|
59
65
|
|
|
60
|
-
if (
|
|
61
|
-
cachable
|
|
62
|
-
and path.exists(py_file_path + "c")
|
|
63
|
-
and path.getmtime(py_file_path + "c") > path.getmtime(full_target)
|
|
64
|
-
):
|
|
65
|
-
with open(py_file_path + "c", "rb") as f:
|
|
66
|
-
codeobj = marshal.load(f)
|
|
67
|
-
else:
|
|
68
|
-
codeobj = compile(code_string, f"_jac_py_gen ({module.__file__})", "exec")
|
|
69
|
-
with open(py_file_path + "c", "wb") as f:
|
|
70
|
-
marshal.dump(codeobj, f)
|
|
71
|
-
|
|
72
66
|
try:
|
|
73
67
|
exec(codeobj, module.__dict__)
|
|
74
68
|
except Exception as e:
|
|
@@ -90,41 +84,25 @@ def import_jac_module(
|
|
|
90
84
|
return module
|
|
91
85
|
|
|
92
86
|
|
|
93
|
-
def handle_jac_error(code_string: str, e: Exception, tb: traceback.StackSummary) -> str:
|
|
94
|
-
"""Handle Jac Error."""
|
|
95
|
-
except_line = e.end_lineno if isinstance(e, SyntaxError) else list(tb)[-1].lineno
|
|
96
|
-
if not isinstance(except_line, int) or except_line == 0:
|
|
97
|
-
return ""
|
|
98
|
-
py_error_region = clip_code_section(
|
|
99
|
-
add_line_numbers(code_string), except_line, Val.JAC_ERROR_LINE_RANGE
|
|
100
|
-
)
|
|
101
|
-
try:
|
|
102
|
-
jac_err_line = int(code_string.splitlines()[except_line - 1].split()[-1])
|
|
103
|
-
mod_index = int(code_string.splitlines()[except_line - 1].split()[-2])
|
|
104
|
-
mod_paths = code_string.split(Con.JAC_DEBUG_SPLITTER)[1].strip().splitlines()
|
|
105
|
-
with open(mod_paths[mod_index], "r") as file:
|
|
106
|
-
jac_code_string = file.read()
|
|
107
|
-
jac_error_region = clip_code_section(
|
|
108
|
-
add_line_numbers(jac_code_string), jac_err_line, Val.JAC_ERROR_LINE_RANGE
|
|
109
|
-
)
|
|
110
|
-
except Exception as e:
|
|
111
|
-
jac_error_region = str(e)
|
|
112
|
-
snippet = (
|
|
113
|
-
f"JacCode Snippet:\n{jac_error_region}\n"
|
|
114
|
-
f"PyCode Snippet:\n{py_error_region}\n"
|
|
115
|
-
)
|
|
116
|
-
return snippet
|
|
117
|
-
|
|
118
|
-
|
|
119
87
|
def jac_blue_import(
|
|
120
|
-
target: str,
|
|
88
|
+
target: str,
|
|
89
|
+
base_path: Optional[str] = None,
|
|
90
|
+
cachable: bool = True,
|
|
91
|
+
override_name: Optional[str] = None,
|
|
121
92
|
) -> Optional[types.ModuleType]:
|
|
122
93
|
"""Jac Blue Imports."""
|
|
123
|
-
return import_jac_module(
|
|
94
|
+
return import_jac_module(
|
|
95
|
+
transpile_jac_blue, target, base_path, cachable, override_name
|
|
96
|
+
)
|
|
124
97
|
|
|
125
98
|
|
|
126
99
|
def jac_purple_import(
|
|
127
|
-
target: str,
|
|
100
|
+
target: str,
|
|
101
|
+
base_path: Optional[str] = None,
|
|
102
|
+
cachable: bool = True,
|
|
103
|
+
override_name: Optional[str] = None,
|
|
128
104
|
) -> Optional[types.ModuleType]:
|
|
129
105
|
"""Jac Purple Imports."""
|
|
130
|
-
return import_jac_module(
|
|
106
|
+
return import_jac_module(
|
|
107
|
+
transpile_jac_purple, target, base_path, cachable, override_name
|
|
108
|
+
)
|
jaclang/jac/langserve.py
ADDED
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
"""Example language server for JAC."""
|
|
2
|
+
|
|
3
|
+
from jaclang.vendor.pygls.lsprotocol.types import (
|
|
4
|
+
CompletionItem,
|
|
5
|
+
CompletionList,
|
|
6
|
+
CompletionParams,
|
|
7
|
+
TEXT_DOCUMENT_COMPLETION,
|
|
8
|
+
)
|
|
9
|
+
from jaclang.vendor.pygls.server import LanguageServer
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
server = LanguageServer("example-server", "v0.1")
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
@server.feature(TEXT_DOCUMENT_COMPLETION)
|
|
16
|
+
def completions(params: CompletionParams) -> CompletionList:
|
|
17
|
+
"""Provide completions for the current line."""
|
|
18
|
+
items = []
|
|
19
|
+
document = server.workspace.get_document(params.text_document.uri)
|
|
20
|
+
current_line = document.lines[params.position.line].strip()
|
|
21
|
+
if current_line.endswith("hello."):
|
|
22
|
+
items = [
|
|
23
|
+
CompletionItem(label="world"),
|
|
24
|
+
CompletionItem(label="friend"),
|
|
25
|
+
]
|
|
26
|
+
return CompletionList(is_incomplete=False, items=items)
|
jaclang/jac/lexer.py
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
from typing import Generator
|
|
3
3
|
|
|
4
4
|
from jaclang.jac.transform import ABCLexerMeta, Transform
|
|
5
|
-
from jaclang.
|
|
5
|
+
from jaclang.vendor.sly.lex import Lexer, Token
|
|
6
6
|
|
|
7
7
|
|
|
8
8
|
class JacLexer(Lexer, Transform, metaclass=ABCLexerMeta):
|
|
@@ -14,8 +14,10 @@ class JacLexer(Lexer, Transform, metaclass=ABCLexerMeta):
|
|
|
14
14
|
input_ir: str,
|
|
15
15
|
base_path: str = "",
|
|
16
16
|
prior: Transform | None = None,
|
|
17
|
+
fstr_override: bool = False,
|
|
17
18
|
) -> None:
|
|
18
19
|
"""Initialize lexer."""
|
|
20
|
+
self.fstr_override = fstr_override
|
|
19
21
|
Transform.__init__(self, mod_path, input_ir, base_path, prior) # type: ignore
|
|
20
22
|
self.ir: Generator = self.ir
|
|
21
23
|
|
|
@@ -23,6 +25,7 @@ class JacLexer(Lexer, Transform, metaclass=ABCLexerMeta):
|
|
|
23
25
|
"FLOAT",
|
|
24
26
|
"STRING",
|
|
25
27
|
"DOC_STRING",
|
|
28
|
+
"PYNLINE",
|
|
26
29
|
"FSTRING",
|
|
27
30
|
"BOOL",
|
|
28
31
|
"INT",
|
|
@@ -44,6 +47,7 @@ class JacLexer(Lexer, Transform, metaclass=ABCLexerMeta):
|
|
|
44
47
|
"TYP_ANY",
|
|
45
48
|
"TYP_TYPE",
|
|
46
49
|
"KW_FREEZE",
|
|
50
|
+
"KW_ABSTRACT",
|
|
47
51
|
"KW_OBJECT",
|
|
48
52
|
"KW_ENUM",
|
|
49
53
|
"KW_NODE",
|
|
@@ -186,6 +190,7 @@ class JacLexer(Lexer, Transform, metaclass=ABCLexerMeta):
|
|
|
186
190
|
# Regular expression rules for tokens
|
|
187
191
|
FLOAT = r"(\d+(\.\d*)?|\.\d+)([eE][+-]?\d+)?"
|
|
188
192
|
DOC_STRING = r'"""(.|\n|\r)*?"""|\'\'\'(.|\n|\r)*?\'\'\'' # type: ignore
|
|
193
|
+
PYNLINE = r"::py::(.|\n|\r)*?::py::" # type: ignore
|
|
189
194
|
FSTRING = r'f"[^"\r\n]*"|f\'[^\'\r\n]*\''
|
|
190
195
|
STRING = r'"[^"\r\n]*"|\'[^\'\r\n]*\''
|
|
191
196
|
BOOL = r"True|False"
|
|
@@ -211,7 +216,8 @@ class JacLexer(Lexer, Transform, metaclass=ABCLexerMeta):
|
|
|
211
216
|
NAME["bytes"] = "TYP_BYTES" # type: ignore
|
|
212
217
|
NAME["any"] = "TYP_ANY" # type: ignore
|
|
213
218
|
NAME["type"] = "TYP_TYPE" # type: ignore
|
|
214
|
-
NAME["
|
|
219
|
+
NAME["froz"] = "KW_FREEZE" # type: ignore
|
|
220
|
+
NAME["abstract"] = "KW_ABSTRACT" # type: ignore
|
|
215
221
|
NAME["object"] = "KW_OBJECT" # type: ignore
|
|
216
222
|
NAME["enum"] = "KW_ENUM" # type: ignore
|
|
217
223
|
NAME["node"] = "KW_NODE" # type: ignore
|
|
@@ -269,9 +275,9 @@ class JacLexer(Lexer, Transform, metaclass=ABCLexerMeta):
|
|
|
269
275
|
ARROW_R = r"-->"
|
|
270
276
|
ARROW_BI = r"<-->"
|
|
271
277
|
ARROW_L_p1 = r"<-\["
|
|
278
|
+
ARROW_R_p2 = r"]->"
|
|
272
279
|
ARROW_L_p2 = r"]-"
|
|
273
280
|
ARROW_R_p1 = r"-\["
|
|
274
|
-
ARROW_R_p2 = r"]->"
|
|
275
281
|
CARROW_L = r"<\+\+"
|
|
276
282
|
CARROW_R = r"\+\+>"
|
|
277
283
|
CARROW_L_p1 = r"<\+\["
|
|
@@ -368,12 +374,38 @@ class JacLexer(Lexer, Transform, metaclass=ABCLexerMeta):
|
|
|
368
374
|
self.lineno += t.value.count("\r")
|
|
369
375
|
return t
|
|
370
376
|
|
|
377
|
+
def PYNLINE(self, t: Token) -> Token: # noqa
|
|
378
|
+
"""Add docstring to lexer."""
|
|
379
|
+
self.lineno += t.value.count("\n")
|
|
380
|
+
self.lineno += t.value.count("\r")
|
|
381
|
+
return t
|
|
382
|
+
|
|
371
383
|
# Transform Implementations
|
|
372
384
|
# -------------------------
|
|
373
385
|
def transform(self, ir: str) -> Generator:
|
|
374
386
|
"""Tokenize the input."""
|
|
375
387
|
return self.tokenize(ir)
|
|
376
388
|
|
|
389
|
+
def tokenize(self, text: str) -> Generator:
|
|
390
|
+
"""Tokenize override for no module level docstring."""
|
|
391
|
+
has_doc_string_start = False
|
|
392
|
+
for tok in super().tokenize(text):
|
|
393
|
+
if (
|
|
394
|
+
tok.type != "DOC_STRING"
|
|
395
|
+
and not has_doc_string_start
|
|
396
|
+
and not self.fstr_override
|
|
397
|
+
):
|
|
398
|
+
dtok = Token()
|
|
399
|
+
dtok.type = "DOC_STRING"
|
|
400
|
+
dtok.value = '""""""'
|
|
401
|
+
dtok.lineno = 1
|
|
402
|
+
dtok.lineidx = 0
|
|
403
|
+
dtok.index = 0
|
|
404
|
+
dtok.end = 0
|
|
405
|
+
yield dtok
|
|
406
|
+
has_doc_string_start = True
|
|
407
|
+
yield tok
|
|
408
|
+
|
|
377
409
|
def error(self, t: Token) -> None:
|
|
378
410
|
"""Raise an error for illegal characters."""
|
|
379
411
|
self.cur_line = self.lineno
|