jaclang 0.7.14__py3-none-any.whl → 0.7.15__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/cli/cli.py +11 -8
- jaclang/cli/cmdreg.py +9 -12
- jaclang/compiler/__init__.py +0 -2
- jaclang/compiler/absyntree.py +3 -8
- jaclang/compiler/passes/ir_pass.py +3 -12
- jaclang/compiler/passes/main/fuse_typeinfo_pass.py +4 -5
- jaclang/compiler/passes/main/import_pass.py +4 -2
- jaclang/compiler/passes/main/pyast_gen_pass.py +32 -31
- jaclang/compiler/passes/main/registry_pass.py +1 -1
- jaclang/compiler/passes/tool/jac_formatter_pass.py +3 -20
- jaclang/compiler/passes/transform.py +4 -0
- jaclang/compiler/semtable.py +5 -3
- jaclang/compiler/tests/test_importer.py +3 -0
- jaclang/langserve/engine.py +210 -69
- jaclang/langserve/server.py +6 -10
- jaclang/langserve/tests/fixtures/base_module_structure.jac +1 -1
- jaclang/langserve/tests/fixtures/import_include_statements.jac +1 -1
- jaclang/langserve/tests/test_sem_tokens.py +277 -0
- jaclang/langserve/tests/test_server.py +4 -4
- jaclang/langserve/utils.py +128 -95
- jaclang/plugin/builtin.py +1 -1
- jaclang/plugin/default.py +23 -16
- jaclang/plugin/feature.py +4 -5
- jaclang/plugin/spec.py +2 -2
- jaclang/{core → runtimelib}/architype.py +1 -1
- jaclang/{core → runtimelib}/context.py +4 -1
- jaclang/runtimelib/importer.py +414 -0
- jaclang/runtimelib/machine.py +19 -0
- jaclang/{core → runtimelib}/utils.py +1 -1
- jaclang/tests/fixtures/deep/one_lev.jac +3 -3
- jaclang/tests/fixtures/deep/one_lev_dup.jac +2 -3
- jaclang/tests/test_cli.py +1 -1
- jaclang/tests/test_language.py +7 -0
- jaclang/utils/treeprinter.py +0 -4
- {jaclang-0.7.14.dist-info → jaclang-0.7.15.dist-info}/METADATA +1 -1
- {jaclang-0.7.14.dist-info → jaclang-0.7.15.dist-info}/RECORD +42 -40
- jaclang/core/importer.py +0 -344
- /jaclang/{core → runtimelib}/__init__.py +0 -0
- /jaclang/{core → runtimelib}/constructs.py +0 -0
- /jaclang/{core → runtimelib}/memory.py +0 -0
- /jaclang/{core → runtimelib}/test.py +0 -0
- {jaclang-0.7.14.dist-info → jaclang-0.7.15.dist-info}/WHEEL +0 -0
- {jaclang-0.7.14.dist-info → jaclang-0.7.15.dist-info}/entry_points.txt +0 -0
jaclang/cli/cli.py
CHANGED
|
@@ -19,10 +19,10 @@ from jaclang.compiler.constant import Constants
|
|
|
19
19
|
from jaclang.compiler.passes.main.pyast_load_pass import PyastBuildPass
|
|
20
20
|
from jaclang.compiler.passes.main.schedules import py_code_gen_typed
|
|
21
21
|
from jaclang.compiler.passes.tool.schedules import format_pass
|
|
22
|
-
from jaclang.core.constructs import Architype
|
|
23
22
|
from jaclang.plugin.builtin import dotgen
|
|
24
23
|
from jaclang.plugin.feature import JacCmd as Cmd
|
|
25
24
|
from jaclang.plugin.feature import JacFeature as Jac
|
|
25
|
+
from jaclang.runtimelib.constructs import Architype
|
|
26
26
|
from jaclang.utils.helpers import debugger as db
|
|
27
27
|
from jaclang.utils.lang_tools import AstTool
|
|
28
28
|
|
|
@@ -86,11 +86,10 @@ def run(
|
|
|
86
86
|
else ""
|
|
87
87
|
)
|
|
88
88
|
|
|
89
|
-
Jac.context().init_memory(session)
|
|
90
|
-
|
|
91
89
|
base, mod = os.path.split(filename)
|
|
92
90
|
base = base if base else "./"
|
|
93
91
|
mod = mod[:-4]
|
|
92
|
+
Jac.context().init_memory(base_path=base, session=session)
|
|
94
93
|
if filename.endswith(".jac"):
|
|
95
94
|
ret_module = jac_import(
|
|
96
95
|
target=mod,
|
|
@@ -146,7 +145,7 @@ def get_object(id: str, session: str = "") -> dict:
|
|
|
146
145
|
if session == "":
|
|
147
146
|
session = cmd_registry.args.session if "session" in cmd_registry.args else ""
|
|
148
147
|
|
|
149
|
-
Jac.context().init_memory(session)
|
|
148
|
+
Jac.context().init_memory(session=session)
|
|
150
149
|
|
|
151
150
|
if id == "root":
|
|
152
151
|
id_uuid = UUID(int=0)
|
|
@@ -357,11 +356,10 @@ def dot(
|
|
|
357
356
|
else ""
|
|
358
357
|
)
|
|
359
358
|
|
|
360
|
-
Jac.context().init_memory(session)
|
|
361
|
-
|
|
362
359
|
base, mod = os.path.split(filename)
|
|
363
360
|
base = base if base else "./"
|
|
364
361
|
mod = mod[:-4]
|
|
362
|
+
Jac.context().init_memory(base_path=base, session=session)
|
|
365
363
|
if filename.endswith(".jac"):
|
|
366
364
|
jac_import(
|
|
367
365
|
target=mod,
|
|
@@ -437,12 +435,17 @@ def start_cli() -> None:
|
|
|
437
435
|
parser = cmd_registry.parser
|
|
438
436
|
args = parser.parse_args()
|
|
439
437
|
cmd_registry.args = args
|
|
438
|
+
|
|
439
|
+
if args.version:
|
|
440
|
+
version = importlib.metadata.version("jaclang")
|
|
441
|
+
print(f"Jac version {version}")
|
|
442
|
+
return
|
|
443
|
+
|
|
440
444
|
command = cmd_registry.get(args.command)
|
|
441
445
|
if command:
|
|
442
446
|
args_dict = vars(args)
|
|
443
447
|
args_dict.pop("command")
|
|
444
|
-
|
|
445
|
-
args_dict.pop("session")
|
|
448
|
+
args_dict.pop("version", None)
|
|
446
449
|
ret = command.call(**args_dict)
|
|
447
450
|
if ret:
|
|
448
451
|
print(ret)
|
jaclang/cli/cmdreg.py
CHANGED
|
@@ -38,7 +38,7 @@ class CommandRegistry:
|
|
|
38
38
|
self.registry = {}
|
|
39
39
|
self.parser = argparse.ArgumentParser(prog="jac")
|
|
40
40
|
self.parser.add_argument(
|
|
41
|
-
"
|
|
41
|
+
"-V", "--version", action="store_true", help="Show the Jac version"
|
|
42
42
|
)
|
|
43
43
|
self.sub_parsers = self.parser.add_subparsers(title="commands", dest="command")
|
|
44
44
|
self.args = argparse.Namespace()
|
|
@@ -172,17 +172,14 @@ class CommandShell(cmd.Cmd):
|
|
|
172
172
|
|
|
173
173
|
def default(self, line: str) -> None:
|
|
174
174
|
"""Process the command line input."""
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
self.stdout.write(f"{ret_str}\n")
|
|
184
|
-
except Exception as e:
|
|
185
|
-
print(e)
|
|
175
|
+
args = vars(self.cmd_reg.parser.parse_args(line.split()))
|
|
176
|
+
command = self.cmd_reg.get(args["command"])
|
|
177
|
+
if command:
|
|
178
|
+
args.pop("command")
|
|
179
|
+
ret = command.call(**args)
|
|
180
|
+
if ret:
|
|
181
|
+
ret_str = pprint.pformat(ret, indent=2)
|
|
182
|
+
self.stdout.write(f"{ret_str}\n")
|
|
186
183
|
|
|
187
184
|
def do_help(self, arg: str) -> None:
|
|
188
185
|
"""Jac CLI 'help' implementaion."""
|
jaclang/compiler/__init__.py
CHANGED
|
@@ -34,8 +34,6 @@ def generate_static_parser(force: bool = False) -> None:
|
|
|
34
34
|
except Exception as e:
|
|
35
35
|
logging.error(f"Error generating reference files: {e}")
|
|
36
36
|
|
|
37
|
-
|
|
38
|
-
generate_static_parser()
|
|
39
37
|
try:
|
|
40
38
|
from jaclang.compiler.generated import jac_parser as jac_lark
|
|
41
39
|
except ModuleNotFoundError:
|
jaclang/compiler/absyntree.py
CHANGED
|
@@ -55,15 +55,10 @@ class AstNode:
|
|
|
55
55
|
"""Get symbol table."""
|
|
56
56
|
# sym_tab should never be accessed without being set in codebase
|
|
57
57
|
if not self._sym_tab:
|
|
58
|
-
import traceback
|
|
59
|
-
|
|
60
|
-
if self.parent:
|
|
61
|
-
print(f"Parent: {self.parent.pp()}")
|
|
62
|
-
print("Node: ", self.pp())
|
|
63
|
-
stack_trace = traceback.format_stack()
|
|
64
|
-
print("".join(stack_trace))
|
|
65
58
|
raise ValueError(
|
|
66
|
-
f"Symbol table not set for {type(self).__name__}. Impossible
|
|
59
|
+
f"Symbol table not set for {type(self).__name__}. Impossible.\n"
|
|
60
|
+
f"Node: {self.pp()}\n"
|
|
61
|
+
f"Parent: {self.parent.pp() if self.parent else None}\n"
|
|
67
62
|
)
|
|
68
63
|
return self._sym_tab
|
|
69
64
|
|
|
@@ -115,7 +115,7 @@ class Pass(Transform[T]):
|
|
|
115
115
|
self.after_pass()
|
|
116
116
|
self.time_taken = time.time() - start_time
|
|
117
117
|
if settings.pass_timer:
|
|
118
|
-
|
|
118
|
+
self.log_info(
|
|
119
119
|
f"Time taken in {self.__class__.__name__}: {self.time_taken:.4f} seconds"
|
|
120
120
|
)
|
|
121
121
|
return self.ir
|
|
@@ -136,21 +136,12 @@ class Pass(Transform[T]):
|
|
|
136
136
|
self.exit_node(node)
|
|
137
137
|
return node
|
|
138
138
|
|
|
139
|
-
def update_code_loc(self, node: Optional[ast.AstNode] = None) -> None:
|
|
140
|
-
"""Update code location."""
|
|
141
|
-
if node is None:
|
|
142
|
-
node = self.cur_node
|
|
143
|
-
if not isinstance(node, ast.AstNode):
|
|
144
|
-
self.ice("Current node is not an AstNode.")
|
|
145
|
-
|
|
146
139
|
def error(self, msg: str, node_override: Optional[ast.AstNode] = None) -> None:
|
|
147
140
|
"""Pass Error."""
|
|
148
|
-
self.update_code_loc(node_override)
|
|
149
141
|
self.log_error(f"{msg}", node_override=node_override)
|
|
150
142
|
|
|
151
143
|
def warning(self, msg: str, node_override: Optional[ast.AstNode] = None) -> None:
|
|
152
144
|
"""Pass Error."""
|
|
153
|
-
self.update_code_loc(node_override)
|
|
154
145
|
self.log_warning(f"{msg}", node_override=node_override)
|
|
155
146
|
|
|
156
147
|
def ice(self, msg: str = "Something went horribly wrong!") -> RuntimeError:
|
|
@@ -166,10 +157,10 @@ class PrinterPass(Pass):
|
|
|
166
157
|
|
|
167
158
|
def enter_node(self, node: ast.AstNode) -> None:
|
|
168
159
|
"""Run on entering node."""
|
|
169
|
-
|
|
160
|
+
self.log_info(f"Entering: {node.__class__.__name__}: {node.loc}")
|
|
170
161
|
super().enter_node(node)
|
|
171
162
|
|
|
172
163
|
def exit_node(self, node: ast.AstNode) -> None:
|
|
173
164
|
"""Run on exiting node."""
|
|
174
165
|
super().exit_node(node)
|
|
175
|
-
|
|
166
|
+
self.log_info(f"Exiting: {node.__class__.__name__}: {node.loc}")
|
|
@@ -6,7 +6,6 @@ mypy apis into Jac and use jac py ast in it.
|
|
|
6
6
|
|
|
7
7
|
from __future__ import annotations
|
|
8
8
|
|
|
9
|
-
import traceback
|
|
10
9
|
from typing import Callable, TypeVar
|
|
11
10
|
|
|
12
11
|
import jaclang.compiler.absyntree as ast
|
|
@@ -32,7 +31,7 @@ class FuseTypeInfoPass(Pass):
|
|
|
32
31
|
|
|
33
32
|
def __debug_print(self, *argv: object) -> None:
|
|
34
33
|
if settings.fuse_type_info_debug:
|
|
35
|
-
|
|
34
|
+
self.log_info("FuseTypeInfo::", *argv)
|
|
36
35
|
|
|
37
36
|
def __call_type_handler(
|
|
38
37
|
self, node: ast.AstSymbolNode, mypy_type: MypyTypes.ProperType
|
|
@@ -72,7 +71,9 @@ class FuseTypeInfoPass(Pass):
|
|
|
72
71
|
) -> Callable[[FuseTypeInfoPass, T], None]:
|
|
73
72
|
def node_handler(self: FuseTypeInfoPass, node: T) -> None:
|
|
74
73
|
if not isinstance(node, ast.AstSymbolNode):
|
|
75
|
-
|
|
74
|
+
self.__debug_print(
|
|
75
|
+
f"Warning {node.__class__.__name__} is not an AstSymbolNode"
|
|
76
|
+
)
|
|
76
77
|
|
|
77
78
|
try:
|
|
78
79
|
jac_node_str = f'jac node "{node.loc}::{node.__class__.__name__}'
|
|
@@ -119,8 +120,6 @@ class FuseTypeInfoPass(Pass):
|
|
|
119
120
|
self.__debug_print(
|
|
120
121
|
f'Internal error happened while parsing "{e.obj.__class__.__name__}"'
|
|
121
122
|
)
|
|
122
|
-
traceback.print_exc()
|
|
123
|
-
print(e)
|
|
124
123
|
|
|
125
124
|
return node_handler
|
|
126
125
|
|
|
@@ -17,6 +17,9 @@ from jaclang.compiler.passes import Pass
|
|
|
17
17
|
from jaclang.compiler.passes.main import SubNodeTabPass
|
|
18
18
|
from jaclang.settings import settings
|
|
19
19
|
from jaclang.utils.helpers import import_target_to_relative_path, is_standard_lib_module
|
|
20
|
+
from jaclang.utils.log import logging
|
|
21
|
+
|
|
22
|
+
logger = logging.getLogger(__name__)
|
|
20
23
|
|
|
21
24
|
|
|
22
25
|
class JacImportPass(Pass):
|
|
@@ -204,7 +207,7 @@ class JacImportPass(Pass):
|
|
|
204
207
|
self.warnings_had += mod_pass.warnings_had
|
|
205
208
|
mod = mod_pass.ir
|
|
206
209
|
except Exception as e:
|
|
207
|
-
|
|
210
|
+
logger.info(e)
|
|
208
211
|
mod = None
|
|
209
212
|
if isinstance(mod, ast.Module):
|
|
210
213
|
self.import_table[target] = mod
|
|
@@ -252,7 +255,6 @@ class PyImportPass(JacImportPass):
|
|
|
252
255
|
if spec.origin in self.import_table:
|
|
253
256
|
return self.import_table[spec.origin]
|
|
254
257
|
with open(spec.origin, "r", encoding="utf-8") as f:
|
|
255
|
-
# print(f"\nImporting python module {node.path_str}")
|
|
256
258
|
mod = PyastBuildPass(
|
|
257
259
|
input_ir=ast.PythonModuleAst(
|
|
258
260
|
py_ast.parse(f.read()), mod_path=spec.origin
|
|
@@ -11,7 +11,7 @@ from typing import Optional, Sequence, TypeVar
|
|
|
11
11
|
import jaclang.compiler.absyntree as ast
|
|
12
12
|
from jaclang.compiler.constant import Constants as Con, EdgeDir, Tokens as Tok
|
|
13
13
|
from jaclang.compiler.passes import Pass
|
|
14
|
-
from jaclang.
|
|
14
|
+
from jaclang.runtimelib.utils import extract_params, extract_type, get_sem_scope
|
|
15
15
|
|
|
16
16
|
T = TypeVar("T", bound=ast3.AST)
|
|
17
17
|
|
|
@@ -19,24 +19,25 @@ T = TypeVar("T", bound=ast3.AST)
|
|
|
19
19
|
class PyastGenPass(Pass):
|
|
20
20
|
"""Jac blue transpilation to python pass."""
|
|
21
21
|
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
22
|
+
# TODO: This should live in utils and perhaps a test added using it
|
|
23
|
+
# @staticmethod
|
|
24
|
+
# def node_compilable_test(node: ast3.AST) -> None:
|
|
25
|
+
# """Convert any AST node to a compilable module node."""
|
|
26
|
+
# if isinstance(node, ast3.Module):
|
|
27
|
+
# pass
|
|
28
|
+
# elif isinstance(node, (ast3.Expr, ast3.stmt)):
|
|
29
|
+
# node = ast3.Module(body=[node], type_ignores=[])
|
|
30
|
+
# elif isinstance(node, list) and all(isinstance(n, ast3.stmt) for n in node):
|
|
31
|
+
# node = ast3.Module(body=node, type_ignores=[])
|
|
32
|
+
# else:
|
|
33
|
+
# node = ast3.Module(body=[], type_ignores=[])
|
|
34
|
+
# try:
|
|
35
|
+
# compile(node, "<ast>", "exec")
|
|
36
|
+
# except TypeError as e:
|
|
37
|
+
# print(ast3.dump(node, indent=2))
|
|
38
|
+
# raise e
|
|
39
|
+
# except Exception:
|
|
40
|
+
# pass
|
|
40
41
|
|
|
41
42
|
def before_pass(self) -> None:
|
|
42
43
|
"""Initialize pass."""
|
|
@@ -80,7 +81,7 @@ class PyastGenPass(Pass):
|
|
|
80
81
|
|
|
81
82
|
def needs_jac_import(self) -> None:
|
|
82
83
|
"""Check if import is needed."""
|
|
83
|
-
if
|
|
84
|
+
if self.needs_jac_import.__name__ in self.already_added:
|
|
84
85
|
return
|
|
85
86
|
self.preamble.append(
|
|
86
87
|
self.sync(
|
|
@@ -96,11 +97,11 @@ class PyastGenPass(Pass):
|
|
|
96
97
|
jac_node=self.ir,
|
|
97
98
|
)
|
|
98
99
|
)
|
|
99
|
-
self.already_added.append(
|
|
100
|
+
self.already_added.append(self.needs_jac_import.__name__)
|
|
100
101
|
|
|
101
102
|
def needs_typing(self) -> None:
|
|
102
103
|
"""Check if enum is needed."""
|
|
103
|
-
if
|
|
104
|
+
if self.needs_typing.__name__ in self.already_added:
|
|
104
105
|
return
|
|
105
106
|
self.preamble.append(
|
|
106
107
|
self.sync(
|
|
@@ -115,11 +116,11 @@ class PyastGenPass(Pass):
|
|
|
115
116
|
jac_node=self.ir,
|
|
116
117
|
)
|
|
117
118
|
)
|
|
118
|
-
self.already_added.append(
|
|
119
|
+
self.already_added.append(self.needs_typing.__name__)
|
|
119
120
|
|
|
120
121
|
def needs_enum(self) -> None:
|
|
121
122
|
"""Check if enum is needed."""
|
|
122
|
-
if
|
|
123
|
+
if self.needs_enum.__name__ in self.already_added:
|
|
123
124
|
return
|
|
124
125
|
self.preamble.append(
|
|
125
126
|
self.sync(
|
|
@@ -134,11 +135,11 @@ class PyastGenPass(Pass):
|
|
|
134
135
|
jac_node=self.ir,
|
|
135
136
|
)
|
|
136
137
|
)
|
|
137
|
-
self.already_added.append(
|
|
138
|
+
self.already_added.append(self.needs_enum.__name__)
|
|
138
139
|
|
|
139
140
|
def needs_jac_feature(self) -> None:
|
|
140
141
|
"""Check if enum is needed."""
|
|
141
|
-
if
|
|
142
|
+
if self.needs_jac_feature.__name__ in self.already_added:
|
|
142
143
|
return
|
|
143
144
|
self.preamble.append(
|
|
144
145
|
self.sync(
|
|
@@ -164,11 +165,11 @@ class PyastGenPass(Pass):
|
|
|
164
165
|
jac_node=self.ir,
|
|
165
166
|
)
|
|
166
167
|
)
|
|
167
|
-
self.already_added.append(
|
|
168
|
+
self.already_added.append(self.needs_jac_feature.__name__)
|
|
168
169
|
|
|
169
170
|
def needs_dataclass(self) -> None:
|
|
170
171
|
"""Check if enum is needed."""
|
|
171
|
-
if
|
|
172
|
+
if self.needs_dataclass.__name__ in self.already_added:
|
|
172
173
|
return
|
|
173
174
|
self.preamble.append(
|
|
174
175
|
self.sync(
|
|
@@ -184,11 +185,11 @@ class PyastGenPass(Pass):
|
|
|
184
185
|
jac_node=self.ir,
|
|
185
186
|
)
|
|
186
187
|
)
|
|
187
|
-
self.already_added.append(
|
|
188
|
+
self.already_added.append(self.needs_dataclass.__name__)
|
|
188
189
|
|
|
189
190
|
def needs_dataclass_field(self) -> None:
|
|
190
191
|
"""Check if enum is needed."""
|
|
191
|
-
if
|
|
192
|
+
if self.needs_dataclass_field.__name__ in self.already_added:
|
|
192
193
|
return
|
|
193
194
|
self.preamble.append(
|
|
194
195
|
self.sync(
|
|
@@ -202,7 +203,7 @@ class PyastGenPass(Pass):
|
|
|
202
203
|
jac_node=self.ir,
|
|
203
204
|
)
|
|
204
205
|
)
|
|
205
|
-
self.already_added.append(
|
|
206
|
+
self.already_added.append(self.needs_dataclass_field.__name__)
|
|
206
207
|
|
|
207
208
|
def flatten(self, body: list[T | list[T] | None]) -> list[T]:
|
|
208
209
|
"""Flatten ast list."""
|
|
@@ -13,7 +13,7 @@ import jaclang.compiler.absyntree as ast
|
|
|
13
13
|
from jaclang.compiler.constant import Constants as Con
|
|
14
14
|
from jaclang.compiler.passes import Pass
|
|
15
15
|
from jaclang.compiler.semtable import SemInfo, SemRegistry
|
|
16
|
-
from jaclang.
|
|
16
|
+
from jaclang.runtimelib.utils import get_sem_scope
|
|
17
17
|
|
|
18
18
|
|
|
19
19
|
class RegistryPass(Pass):
|
|
@@ -212,7 +212,7 @@ class JacFormatPass(Pass):
|
|
|
212
212
|
items: list[T],
|
|
213
213
|
"""
|
|
214
214
|
prev_token = None
|
|
215
|
-
for
|
|
215
|
+
for stmt in node.kid:
|
|
216
216
|
if isinstance(node.parent, (ast.EnumDef, ast.Enum)) and stmt.gen.jac == ",":
|
|
217
217
|
self.indent_level -= 1
|
|
218
218
|
self.emit_ln(node, f"{stmt.gen.jac}")
|
|
@@ -240,27 +240,10 @@ class JacFormatPass(Pass):
|
|
|
240
240
|
elif stmt.name == Tok.RBRACE:
|
|
241
241
|
if self.indent_level > 0:
|
|
242
242
|
self.indent_level -= 1
|
|
243
|
-
if
|
|
244
|
-
stmt.parent
|
|
245
|
-
and stmt.parent.parent
|
|
246
|
-
and isinstance(
|
|
247
|
-
stmt.parent.parent,
|
|
248
|
-
(ast.ElseIf, ast.IfStmt, ast.IterForStmt, ast.TryStmt),
|
|
249
|
-
)
|
|
250
|
-
):
|
|
243
|
+
if stmt.parent and stmt.parent.gen.jac.strip() == "{":
|
|
251
244
|
self.emit(node, f"{stmt.value}")
|
|
252
245
|
else:
|
|
253
|
-
|
|
254
|
-
node.kid[i + 1]
|
|
255
|
-
if i < (len(node.kid) - 1)
|
|
256
|
-
else ast.EmptyToken()
|
|
257
|
-
)
|
|
258
|
-
if (
|
|
259
|
-
isinstance(next_kid, ast.CommentToken)
|
|
260
|
-
and next_kid.is_inline
|
|
261
|
-
):
|
|
262
|
-
self.emit(node, f" {stmt.value}")
|
|
263
|
-
elif not (node.gen.jac).endswith("\n"):
|
|
246
|
+
if not (node.gen.jac).endswith("\n"):
|
|
264
247
|
self.emit_ln(node, "")
|
|
265
248
|
self.emit(node, f"{stmt.value}")
|
|
266
249
|
else:
|
jaclang/compiler/semtable.py
CHANGED
|
@@ -127,9 +127,11 @@ class SemRegistry:
|
|
|
127
127
|
break
|
|
128
128
|
return i
|
|
129
129
|
|
|
130
|
-
def pp(self) ->
|
|
130
|
+
def pp(self) -> str:
|
|
131
131
|
"""Pretty print the registry."""
|
|
132
|
+
ret_str = ""
|
|
132
133
|
for k, v in self.registry.items():
|
|
133
|
-
|
|
134
|
+
ret_str += f"{k}\n"
|
|
134
135
|
for i in v:
|
|
135
|
-
|
|
136
|
+
ret_str += f" {i.name} {i.type} {i.semstr}\n"
|
|
137
|
+
return ret_str
|
|
@@ -5,6 +5,7 @@ import sys
|
|
|
5
5
|
|
|
6
6
|
from jaclang import jac_import
|
|
7
7
|
from jaclang.cli import cli
|
|
8
|
+
from jaclang.plugin.feature import JacFeature as Jac
|
|
8
9
|
from jaclang.utils.test import TestCase
|
|
9
10
|
|
|
10
11
|
|
|
@@ -17,11 +18,13 @@ class TestLoader(TestCase):
|
|
|
17
18
|
|
|
18
19
|
def test_import_basic_python(self) -> None:
|
|
19
20
|
"""Test basic self loading."""
|
|
21
|
+
Jac.context().init_memory(base_path=self.fixture_abs_path(__file__))
|
|
20
22
|
(h,) = jac_import("fixtures.hello_world", base_path=__file__)
|
|
21
23
|
self.assertEqual(h.hello(), "Hello World!") # type: ignore
|
|
22
24
|
|
|
23
25
|
def test_modules_correct(self) -> None:
|
|
24
26
|
"""Test basic self loading."""
|
|
27
|
+
Jac.context().init_memory(base_path=self.fixture_abs_path(__file__))
|
|
25
28
|
jac_import("fixtures.hello_world", base_path=__file__)
|
|
26
29
|
self.assertIn("module 'hello_world'", str(sys.modules))
|
|
27
30
|
self.assertIn("/tests/fixtures/hello_world.jac", str(sys.modules))
|