jaclang 0.8.1__py3-none-any.whl → 0.8.3__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 +6 -0
- jaclang/cli/cli.py +21 -50
- jaclang/compiler/codeinfo.py +0 -1
- jaclang/compiler/constant.py +2 -0
- jaclang/compiler/jac.lark +17 -10
- jaclang/compiler/larkparse/jac_parser.py +2 -2
- jaclang/compiler/parser.py +34 -10
- jaclang/compiler/passes/main/__init__.py +2 -14
- jaclang/compiler/passes/main/annex_pass.py +2 -8
- jaclang/compiler/passes/main/cfg_build_pass.py +38 -12
- jaclang/compiler/passes/main/import_pass.py +3 -11
- jaclang/compiler/passes/main/pyast_gen_pass.py +246 -592
- jaclang/compiler/passes/main/sem_def_match_pass.py +67 -0
- jaclang/compiler/passes/main/sym_tab_build_pass.py +8 -0
- jaclang/compiler/passes/main/sym_tab_link_pass.py +2 -5
- jaclang/compiler/passes/main/tests/fixtures/sem_def_match.impl.jac +12 -0
- jaclang/compiler/passes/main/tests/fixtures/sem_def_match.jac +31 -0
- jaclang/compiler/passes/main/tests/test_cfg_build_pass.py +2 -8
- jaclang/compiler/passes/main/tests/test_decl_impl_match_pass.py +7 -8
- jaclang/compiler/passes/main/tests/test_import_pass.py +5 -18
- jaclang/compiler/passes/main/tests/test_pyast_gen_pass.py +2 -6
- jaclang/compiler/passes/main/tests/test_sem_def_match_pass.py +38 -0
- jaclang/compiler/passes/main/tests/test_sub_node_pass.py +1 -3
- jaclang/compiler/passes/main/tests/test_sym_tab_link_pass.py +20 -17
- jaclang/compiler/passes/tool/doc_ir_gen_pass.py +259 -106
- jaclang/compiler/passes/tool/jac_formatter_pass.py +2 -0
- jaclang/compiler/passes/tool/tests/fixtures/archetype_frmt.jac +14 -0
- jaclang/compiler/passes/tool/tests/fixtures/general_format_checks/triple_quoted_string.jac +5 -4
- jaclang/compiler/passes/tool/tests/fixtures/has_frmt.jac +13 -0
- jaclang/compiler/passes/tool/tests/fixtures/import_fmt.jac +6 -0
- jaclang/compiler/passes/tool/tests/fixtures/simple_walk_fmt.jac +3 -3
- jaclang/compiler/passes/tool/tests/fixtures/tagbreak.jac +9 -0
- jaclang/compiler/passes/tool/tests/test_jac_format_pass.py +25 -3
- jaclang/compiler/passes/tool/tests/test_unparse_validate.py +2 -2
- jaclang/compiler/program.py +23 -60
- jaclang/compiler/tests/fixtures/pkg_import_lib_py/__init__.py +2 -8
- jaclang/compiler/tests/fixtures/pkg_import_lib_py/sub/__init__.py +1 -5
- jaclang/compiler/tests/test_importer.py +10 -13
- jaclang/compiler/unitree.py +88 -16
- jaclang/langserve/__init__.jac +1 -1
- jaclang/langserve/engine.jac +113 -108
- jaclang/langserve/server.jac +17 -2
- jaclang/langserve/tests/server_test/test_lang_serve.py +138 -46
- jaclang/langserve/tests/server_test/utils.py +35 -9
- jaclang/langserve/tests/test_sem_tokens.py +1 -1
- jaclang/langserve/tests/test_server.py +3 -7
- jaclang/runtimelib/archetype.py +127 -5
- jaclang/runtimelib/importer.py +51 -94
- jaclang/runtimelib/machine.py +391 -268
- jaclang/runtimelib/meta_importer.py +86 -0
- jaclang/runtimelib/tests/fixtures/graph_purger.jac +24 -26
- jaclang/runtimelib/tests/fixtures/other_root_access.jac +25 -16
- jaclang/runtimelib/tests/test_jaseci.py +3 -1
- jaclang/tests/fixtures/arch_rel_import_creation.jac +23 -23
- jaclang/tests/fixtures/async_ability.jac +43 -10
- jaclang/tests/fixtures/async_function.jac +18 -0
- jaclang/tests/fixtures/async_walker.jac +17 -12
- jaclang/tests/fixtures/create_dynamic_archetype.jac +25 -28
- jaclang/tests/fixtures/deep/deeper/deep_outer_import.jac +7 -4
- jaclang/tests/fixtures/deep/deeper/snd_lev.jac +2 -2
- jaclang/tests/fixtures/deep/deeper/snd_lev_dup.jac +6 -0
- jaclang/tests/fixtures/deep/one_lev.jac +2 -2
- jaclang/tests/fixtures/deep/one_lev_dup.jac +4 -3
- jaclang/tests/fixtures/dynamic_archetype.jac +19 -12
- jaclang/tests/fixtures/foo.jac +14 -22
- jaclang/tests/fixtures/jac_from_py.py +1 -1
- jaclang/tests/fixtures/jp_importer.jac +6 -6
- jaclang/tests/fixtures/jp_importer_auto.jac +5 -3
- jaclang/tests/fixtures/unicode_strings.jac +24 -0
- jaclang/tests/fixtures/walker_update.jac +5 -7
- jaclang/tests/test_language.py +138 -140
- jaclang/tests/test_reference.py +9 -4
- jaclang/tests/test_typecheck.py +13 -26
- jaclang/utils/lang_tools.py +7 -5
- jaclang/utils/module_resolver.py +23 -0
- {jaclang-0.8.1.dist-info → jaclang-0.8.3.dist-info}/METADATA +1 -1
- {jaclang-0.8.1.dist-info → jaclang-0.8.3.dist-info}/RECORD +79 -72
- jaclang/compiler/passes/main/tests/fixtures/main_err.jac +0 -6
- jaclang/compiler/passes/main/tests/fixtures/second_err.jac +0 -4
- jaclang/compiler/passes/tool/tests/fixtures/corelib.jac +0 -644
- jaclang/compiler/passes/tool/tests/test_doc_ir_gen_pass.py +0 -29
- jaclang/tests/fixtures/deep/deeper/__init__.jac +0 -1
- {jaclang-0.8.1.dist-info → jaclang-0.8.3.dist-info}/WHEEL +0 -0
- {jaclang-0.8.1.dist-info → jaclang-0.8.3.dist-info}/entry_points.txt +0 -0
|
@@ -94,6 +94,8 @@ class JacFormatPass(Transform[uni.Module, uni.Module]):
|
|
|
94
94
|
part_str = self.format_doc_ir(
|
|
95
95
|
part, indent_level, current_line_budget, is_broken
|
|
96
96
|
)
|
|
97
|
+
if part_str.startswith("\n"):
|
|
98
|
+
result = result.rstrip(" ")
|
|
97
99
|
result += part_str
|
|
98
100
|
|
|
99
101
|
if "\n" in part_str:
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
obj Anchor(ArchetypeProtocol) {
|
|
2
|
+
static def on_entry(cls: type, triggers: list[type]);
|
|
3
|
+
static def on_exit(cls: type, triggers: list[type]);
|
|
4
|
+
def make_public_ro;
|
|
5
|
+
def make_public_rw;
|
|
6
|
+
def make_private;
|
|
7
|
+
def is_public_ro -> bool;
|
|
8
|
+
def is_public_rw -> bool;
|
|
9
|
+
def is_private -> bool;
|
|
10
|
+
def is_readable(caller_id: UUID) -> bool;
|
|
11
|
+
def is_writable(caller_id: UUID) -> bool;
|
|
12
|
+
def give_access(caller_id: UUID, read_write: bool = False);
|
|
13
|
+
def revoke_access(caller_id: UUID);
|
|
14
|
+
}
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
with entry {
|
|
2
|
-
triple_quoted_string =
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
2
|
+
triple_quoted_string =
|
|
3
|
+
"""This is a triple quoted string.
|
|
4
|
+
It can span multiple lines.
|
|
5
|
+
It can contain any number of quotes or apostrophes.
|
|
6
|
+
""";
|
|
6
7
|
}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
obj Anchor(ArchetypeProtocol) {
|
|
2
|
+
has ob: object,
|
|
3
|
+
ds_entry_funcs: list[DSFunc],
|
|
4
|
+
ds_exit_funcs: list[DSFunc],
|
|
5
|
+
jid: UUID = :> uuid4(),
|
|
6
|
+
timestamp: datetime = :> datetime.now,
|
|
7
|
+
persist: bool = False,
|
|
8
|
+
access_mode: AccessMode = AccessMode.PRIVATE,
|
|
9
|
+
rw_access: set = :> set(),
|
|
10
|
+
ro_access: set = :> set(),
|
|
11
|
+
owner_id: UUID = exec_ctx.master,
|
|
12
|
+
mem: Memory = exec_ctx.memory;
|
|
13
|
+
}
|
|
@@ -10,7 +10,7 @@ edge Checking {}
|
|
|
10
10
|
|
|
11
11
|
walker Creator {
|
|
12
12
|
has count: int = 0;
|
|
13
|
-
|
|
13
|
+
|
|
14
14
|
can create with `root | Item entry {
|
|
15
15
|
here ++> Item();
|
|
16
16
|
self.count += 1;
|
|
@@ -24,11 +24,11 @@ walker Creator {
|
|
|
24
24
|
walker Walk {
|
|
25
25
|
has count: int = 0;
|
|
26
26
|
has value: int = 0;
|
|
27
|
-
|
|
27
|
+
|
|
28
28
|
can skip_root with `root entry {
|
|
29
29
|
visit [-->];
|
|
30
30
|
}
|
|
31
|
-
|
|
31
|
+
|
|
32
32
|
can step with Item entry {
|
|
33
33
|
here.value = self.count;
|
|
34
34
|
self.count += 1;
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
class SemTokManager {
|
|
2
|
+
"""Initialize semantic token manager."""
|
|
3
|
+
def init(self: SemTokManager, ir: uni.Module) -> None {
|
|
4
|
+
self.sem_tokens: List[int] = self.gen_sem_tokens(ir);
|
|
5
|
+
self.aaaaastatic_sem_tokens:
|
|
6
|
+
List[Tuple[lspt.Position, int, int, uni.AstSymbolNode]] =
|
|
7
|
+
self.gen_sem_tok_node(ir);
|
|
8
|
+
}
|
|
9
|
+
}
|
|
@@ -51,6 +51,30 @@ class JacFormatPassTests(TestCaseMicroSuite):
|
|
|
51
51
|
os.path.join(self.fixture_abs_path(""), "simple_walk_fmt.jac"),
|
|
52
52
|
)
|
|
53
53
|
|
|
54
|
+
def test_tagbreak(self) -> None:
|
|
55
|
+
"""Tests if the file matches a particular format."""
|
|
56
|
+
self.compare_files(
|
|
57
|
+
os.path.join(self.fixture_abs_path(""), "tagbreak.jac"),
|
|
58
|
+
)
|
|
59
|
+
|
|
60
|
+
def test_has_fmt(self) -> None:
|
|
61
|
+
"""Tests if the file matches a particular format."""
|
|
62
|
+
self.compare_files(
|
|
63
|
+
os.path.join(self.fixture_abs_path(""), "has_frmt.jac"),
|
|
64
|
+
)
|
|
65
|
+
|
|
66
|
+
def test_import_fmt(self) -> None:
|
|
67
|
+
"""Tests if the file matches a particular format."""
|
|
68
|
+
self.compare_files(
|
|
69
|
+
os.path.join(self.fixture_abs_path(""), "import_fmt.jac"),
|
|
70
|
+
)
|
|
71
|
+
|
|
72
|
+
def test_archetype(self) -> None:
|
|
73
|
+
"""Tests if the file matches a particular format."""
|
|
74
|
+
self.compare_files(
|
|
75
|
+
os.path.join(self.fixture_abs_path(""), "archetype_frmt.jac"),
|
|
76
|
+
)
|
|
77
|
+
|
|
54
78
|
# def test_corelib_fmt(self) -> None:
|
|
55
79
|
# """Tests if the file matches a particular format."""
|
|
56
80
|
# self.compare_files(
|
|
@@ -99,9 +123,7 @@ class JacFormatPassTests(TestCaseMicroSuite):
|
|
|
99
123
|
"""
|
|
100
124
|
code_gen_pure = JacProgram().compile(self.fixture_abs_path(filename))
|
|
101
125
|
code_gen_format = JacProgram.jac_file_formatter(self.fixture_abs_path(filename))
|
|
102
|
-
code_gen_jac = JacProgram().
|
|
103
|
-
source_str=code_gen_format, file_path=filename
|
|
104
|
-
)
|
|
126
|
+
code_gen_jac = JacProgram().compile(use_str=code_gen_format, file_path=filename)
|
|
105
127
|
if "circle_clean_tests.jac" in filename:
|
|
106
128
|
tokens = code_gen_format.split()
|
|
107
129
|
num_test = 0
|
|
@@ -34,8 +34,8 @@ class JacUnparseTests(TestCaseMicroSuite):
|
|
|
34
34
|
)
|
|
35
35
|
before = ast3.dump(code_gen_pure.gen.py_ast[0], indent=2)
|
|
36
36
|
x = code_gen_pure.unparse()
|
|
37
|
-
code_gen_jac = JacProgram().
|
|
38
|
-
|
|
37
|
+
code_gen_jac = JacProgram().compile(
|
|
38
|
+
use_str=x,
|
|
39
39
|
file_path=filename,
|
|
40
40
|
)
|
|
41
41
|
after = ast3.dump(code_gen_jac.gen.py_ast[0], indent=2)
|
jaclang/compiler/program.py
CHANGED
|
@@ -12,17 +12,16 @@ from jaclang.compiler.parser import JacParser
|
|
|
12
12
|
from jaclang.compiler.passes.main import (
|
|
13
13
|
Alert,
|
|
14
14
|
CFGBuildPass,
|
|
15
|
-
CompilerMode,
|
|
16
15
|
DeclImplMatchPass,
|
|
17
16
|
DefUsePass,
|
|
18
17
|
InheritancePass,
|
|
19
18
|
JacAnnexPass,
|
|
20
19
|
JacImportDepsPass,
|
|
21
20
|
PyBytecodeGenPass,
|
|
22
|
-
PyImportDepsPass,
|
|
23
21
|
PyJacAstLinkPass,
|
|
24
22
|
PyastBuildPass,
|
|
25
23
|
PyastGenPass,
|
|
24
|
+
SemDefMatchPass,
|
|
26
25
|
SymTabBuildPass,
|
|
27
26
|
SymTabLinkPass,
|
|
28
27
|
Transform,
|
|
@@ -38,8 +37,10 @@ from jaclang.utils.log import logging
|
|
|
38
37
|
logger = logging.getLogger(__name__)
|
|
39
38
|
|
|
40
39
|
ir_gen_sched = [
|
|
40
|
+
SymTabBuildPass,
|
|
41
41
|
DeclImplMatchPass,
|
|
42
42
|
DefUsePass,
|
|
43
|
+
SemDefMatchPass,
|
|
43
44
|
CFGBuildPass,
|
|
44
45
|
InheritancePass,
|
|
45
46
|
]
|
|
@@ -63,29 +64,13 @@ class JacProgram:
|
|
|
63
64
|
|
|
64
65
|
def get_bytecode(self, full_target: str) -> Optional[types.CodeType]:
|
|
65
66
|
"""Get the bytecode for a specific module."""
|
|
66
|
-
if full_target in self.mod.hub:
|
|
67
|
+
if full_target in self.mod.hub and self.mod.hub[full_target].gen.py_bytecode:
|
|
67
68
|
codeobj = self.mod.hub[full_target].gen.py_bytecode
|
|
68
69
|
return marshal.loads(codeobj) if isinstance(codeobj, bytes) else None
|
|
69
|
-
result = self.compile(file_path=full_target
|
|
70
|
+
result = self.compile(file_path=full_target)
|
|
70
71
|
return marshal.loads(result.gen.py_bytecode) if result.gen.py_bytecode else None
|
|
71
72
|
|
|
72
|
-
def
|
|
73
|
-
self,
|
|
74
|
-
file_path: str,
|
|
75
|
-
mode: CompilerMode = CompilerMode.COMPILE,
|
|
76
|
-
) -> uni.Module:
|
|
77
|
-
"""Convert a Jac file to an AST."""
|
|
78
|
-
with open(file_path, "r", encoding="utf-8") as file:
|
|
79
|
-
return self.compile_from_str(
|
|
80
|
-
source_str=file.read(), file_path=file_path, mode=mode
|
|
81
|
-
)
|
|
82
|
-
|
|
83
|
-
def compile_from_str(
|
|
84
|
-
self,
|
|
85
|
-
source_str: str,
|
|
86
|
-
file_path: str,
|
|
87
|
-
mode: CompilerMode = CompilerMode.COMPILE,
|
|
88
|
-
) -> uni.Module:
|
|
73
|
+
def parse_str(self, source_str: str, file_path: str) -> uni.Module:
|
|
89
74
|
"""Convert a Jac file to an AST."""
|
|
90
75
|
had_error = False
|
|
91
76
|
if file_path.endswith(".py"):
|
|
@@ -111,54 +96,32 @@ class JacProgram:
|
|
|
111
96
|
if self.mod.main.stub_only:
|
|
112
97
|
self.mod = uni.ProgramModule(mod)
|
|
113
98
|
self.mod.hub[mod.loc.mod_path] = mod
|
|
114
|
-
|
|
99
|
+
JacAnnexPass(ir_in=mod, prog=self)
|
|
100
|
+
return mod
|
|
115
101
|
|
|
116
|
-
def
|
|
117
|
-
self,
|
|
118
|
-
mod_targ: uni.Module,
|
|
119
|
-
mode: CompilerMode = CompilerMode.COMPILE,
|
|
102
|
+
def compile(
|
|
103
|
+
self, file_path: str, use_str: str | None = None, no_cgen: bool = False
|
|
120
104
|
) -> uni.Module:
|
|
121
105
|
"""Convert a Jac file to an AST."""
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
106
|
+
if not use_str:
|
|
107
|
+
with open(file_path, "r", encoding="utf-8") as file:
|
|
108
|
+
use_str = file.read()
|
|
109
|
+
mod_targ = self.parse_str(use_str, file_path)
|
|
110
|
+
self.run_schedule(mod=mod_targ, passes=ir_gen_sched)
|
|
111
|
+
if not no_cgen:
|
|
112
|
+
self.run_schedule(mod=mod_targ, passes=py_code_gen)
|
|
113
|
+
return mod_targ
|
|
114
|
+
|
|
115
|
+
def build(self, file_path: str, use_str: str | None = None) -> uni.Module:
|
|
116
|
+
"""Convert a Jac file to an AST."""
|
|
117
|
+
mod_targ = self.compile(file_path, use_str)
|
|
129
118
|
JacImportDepsPass(ir_in=mod_targ, prog=self)
|
|
130
|
-
if len(self.errors_had):
|
|
131
|
-
return mod_targ
|
|
132
|
-
SymTabLinkPass(ir_in=mod_targ, prog=self)
|
|
133
119
|
for mod in self.mod.hub.values():
|
|
134
|
-
|
|
135
|
-
if mode == CompilerMode.COMPILE:
|
|
136
|
-
return mod_targ
|
|
137
|
-
PyImportDepsPass(mod_targ, prog=self)
|
|
138
|
-
SymTabLinkPass(ir_in=mod_targ, prog=self)
|
|
120
|
+
SymTabLinkPass(ir_in=mod, prog=self)
|
|
139
121
|
for mod in self.mod.hub.values():
|
|
140
122
|
DefUsePass(mod, prog=self)
|
|
141
|
-
for mod in self.mod.hub.values():
|
|
142
|
-
self.schedule_runner(mod, mode=CompilerMode.TYPECHECK)
|
|
143
123
|
return mod_targ
|
|
144
124
|
|
|
145
|
-
def schedule_runner(
|
|
146
|
-
self,
|
|
147
|
-
mod: uni.Module,
|
|
148
|
-
mode: CompilerMode = CompilerMode.COMPILE,
|
|
149
|
-
) -> None:
|
|
150
|
-
"""Run premade passes on the module."""
|
|
151
|
-
match mode:
|
|
152
|
-
case CompilerMode.NO_CGEN | CompilerMode.NO_CGEN_SINGLE:
|
|
153
|
-
passes = ir_gen_sched
|
|
154
|
-
case CompilerMode.COMPILE | CompilerMode.COMPILE_SINGLE:
|
|
155
|
-
passes = [*ir_gen_sched, *py_code_gen]
|
|
156
|
-
case CompilerMode.TYPECHECK:
|
|
157
|
-
passes = []
|
|
158
|
-
case _:
|
|
159
|
-
raise ValueError(f"Invalid mode: {mode}")
|
|
160
|
-
self.run_schedule(mod, passes)
|
|
161
|
-
|
|
162
125
|
def run_schedule(
|
|
163
126
|
self,
|
|
164
127
|
mod: uni.Module,
|
|
@@ -1,11 +1,5 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
1
|
from jaclang import JacMachineInterface as _
|
|
4
2
|
|
|
5
|
-
|
|
6
|
-
target="tools",
|
|
7
|
-
base_path=__file__,
|
|
8
|
-
items={"tool_func": None},
|
|
9
|
-
)
|
|
3
|
+
from .tools import tool_func
|
|
10
4
|
|
|
11
|
-
glob_var_lib =
|
|
5
|
+
glob_var_lib = "pkg_import_lib_py.glob_var_lib"
|
|
@@ -3,10 +3,10 @@
|
|
|
3
3
|
import io
|
|
4
4
|
import sys
|
|
5
5
|
|
|
6
|
-
from jaclang import
|
|
6
|
+
from jaclang import JacMachine as Jac
|
|
7
7
|
from jaclang.cli import cli
|
|
8
8
|
from jaclang.compiler.program import JacProgram
|
|
9
|
-
from jaclang.runtimelib.machine import JacMachineInterface
|
|
9
|
+
from jaclang.runtimelib.machine import JacMachineInterface
|
|
10
10
|
from jaclang.utils.test import TestCase
|
|
11
11
|
|
|
12
12
|
|
|
@@ -15,29 +15,27 @@ class TestLoader(TestCase):
|
|
|
15
15
|
|
|
16
16
|
def test_import_basic_python(self) -> None:
|
|
17
17
|
"""Test basic self loading."""
|
|
18
|
-
|
|
18
|
+
Jac.set_base_path(self.fixture_abs_path(__file__))
|
|
19
19
|
JacMachineInterface.attach_program(
|
|
20
|
-
mach,
|
|
21
20
|
JacProgram(),
|
|
22
21
|
)
|
|
23
|
-
(h,) = Jac.jac_import(
|
|
22
|
+
(h,) = Jac.jac_import("fixtures.hello_world", base_path=__file__)
|
|
24
23
|
self.assertEqual(h.hello(), "Hello World!") # type: ignore
|
|
25
24
|
|
|
26
25
|
def test_modules_correct(self) -> None:
|
|
27
26
|
"""Test basic self loading."""
|
|
28
|
-
|
|
27
|
+
Jac.set_base_path(self.fixture_abs_path(__file__))
|
|
29
28
|
JacMachineInterface.attach_program(
|
|
30
|
-
mach,
|
|
31
29
|
JacProgram(),
|
|
32
30
|
)
|
|
33
|
-
Jac.jac_import(
|
|
31
|
+
Jac.jac_import("fixtures.hello_world", base_path=__file__)
|
|
34
32
|
self.assertIn(
|
|
35
33
|
"module 'fixtures.hello_world'",
|
|
36
|
-
str(
|
|
34
|
+
str(Jac.loaded_modules),
|
|
37
35
|
)
|
|
38
36
|
self.assertIn(
|
|
39
37
|
"/tests/fixtures/hello_world.jac",
|
|
40
|
-
str(
|
|
38
|
+
str(Jac.loaded_modules).replace("\\\\", "/"),
|
|
41
39
|
)
|
|
42
40
|
|
|
43
41
|
def test_jac_py_import(self) -> None:
|
|
@@ -92,12 +90,11 @@ class TestLoader(TestCase):
|
|
|
92
90
|
sys.stdout = captured_output
|
|
93
91
|
|
|
94
92
|
try:
|
|
95
|
-
|
|
93
|
+
Jac.set_base_path(self.fixture_abs_path(__file__))
|
|
96
94
|
JacMachineInterface.attach_program(
|
|
97
|
-
mach,
|
|
98
95
|
JacProgram(),
|
|
99
96
|
)
|
|
100
|
-
Jac.jac_import(
|
|
97
|
+
Jac.jac_import(module_name, base_path=__file__)
|
|
101
98
|
cli.run(jac_file_path)
|
|
102
99
|
|
|
103
100
|
# Reset stdout and get the output
|
jaclang/compiler/unitree.py
CHANGED
|
@@ -548,6 +548,7 @@ class AstSymbolNode(UniNode):
|
|
|
548
548
|
self.name_spec.name_of = self
|
|
549
549
|
self.name_spec._sym_name = sym_name
|
|
550
550
|
self.name_spec._sym_category = sym_category
|
|
551
|
+
self.semstr = ""
|
|
551
552
|
|
|
552
553
|
@property
|
|
553
554
|
def sym(self) -> Optional[Symbol]:
|
|
@@ -849,15 +850,15 @@ class NameAtom(AtomExpr, EnumBlockStmt):
|
|
|
849
850
|
return None
|
|
850
851
|
|
|
851
852
|
|
|
852
|
-
class ArchSpec(ElementStmt, CodeBlockStmt, AstSymbolNode, AstDocNode):
|
|
853
|
+
class ArchSpec(ElementStmt, CodeBlockStmt, AstSymbolNode, AstAsyncNode, AstDocNode):
|
|
853
854
|
"""ArchSpec node type for Jac Ast."""
|
|
854
855
|
|
|
855
856
|
def __init__(
|
|
856
857
|
self, decorators: Sequence[Expr] | None, is_async: bool = False
|
|
857
858
|
) -> None:
|
|
858
859
|
self.decorators = decorators
|
|
859
|
-
self.is_async = is_async
|
|
860
860
|
CodeBlockStmt.__init__(self)
|
|
861
|
+
AstAsyncNode.__init__(self, is_async=is_async)
|
|
861
862
|
|
|
862
863
|
|
|
863
864
|
class MatchPattern(UniNode):
|
|
@@ -1621,6 +1622,61 @@ class ImplDef(CodeBlockStmt, ElementStmt, ArchBlockStmt, AstSymbolNode, UniScope
|
|
|
1621
1622
|
return res
|
|
1622
1623
|
|
|
1623
1624
|
|
|
1625
|
+
class SemDef(ElementStmt, AstSymbolNode, UniScopeNode):
|
|
1626
|
+
"""SemDef node type for Jac Ast."""
|
|
1627
|
+
|
|
1628
|
+
def __init__(
|
|
1629
|
+
self,
|
|
1630
|
+
target: Sequence[NameAtom],
|
|
1631
|
+
value: String,
|
|
1632
|
+
kid: Sequence[UniNode],
|
|
1633
|
+
) -> None:
|
|
1634
|
+
self.target = target
|
|
1635
|
+
self.value = value
|
|
1636
|
+
UniNode.__init__(self, kid=kid)
|
|
1637
|
+
AstSymbolNode.__init__(
|
|
1638
|
+
self,
|
|
1639
|
+
sym_name="sem." + ".".join([x.sym_name for x in self.target]),
|
|
1640
|
+
name_spec=self.create_sem_name_node(),
|
|
1641
|
+
sym_category=SymbolType.SEM,
|
|
1642
|
+
)
|
|
1643
|
+
UniScopeNode.__init__(self, name=self.sym_name)
|
|
1644
|
+
|
|
1645
|
+
def create_sem_name_node(self) -> Name:
|
|
1646
|
+
ret = Name(
|
|
1647
|
+
orig_src=self.target[-1].loc.orig_src,
|
|
1648
|
+
name=Tok.NAME.value,
|
|
1649
|
+
value="sem." + ".".join([x.sym_name for x in self.target]),
|
|
1650
|
+
col_start=self.target[0].loc.col_start,
|
|
1651
|
+
col_end=self.target[-1].loc.col_end,
|
|
1652
|
+
line=self.target[0].loc.first_line,
|
|
1653
|
+
end_line=self.target[-1].loc.last_line,
|
|
1654
|
+
pos_start=self.target[0].loc.pos_start,
|
|
1655
|
+
pos_end=self.target[-1].loc.pos_end,
|
|
1656
|
+
)
|
|
1657
|
+
ret.parent = self
|
|
1658
|
+
return ret
|
|
1659
|
+
|
|
1660
|
+
def normalize(self, deep: bool = False) -> bool:
|
|
1661
|
+
res = True
|
|
1662
|
+
if deep:
|
|
1663
|
+
for item in self.target:
|
|
1664
|
+
res = res and item.normalize(deep)
|
|
1665
|
+
res = res and self.value.normalize(deep)
|
|
1666
|
+
new_kid: list[UniNode] = [
|
|
1667
|
+
self.gen_token(Tok.KW_SEM),
|
|
1668
|
+
]
|
|
1669
|
+
for idx, item in enumerate(self.target):
|
|
1670
|
+
new_kid.append(item)
|
|
1671
|
+
if idx < len(self.target) - 1:
|
|
1672
|
+
new_kid.append(self.gen_token(Tok.DOT))
|
|
1673
|
+
new_kid.append(self.gen_token(Tok.EQ))
|
|
1674
|
+
new_kid.append(self.value)
|
|
1675
|
+
new_kid.append(self.gen_token(Tok.SEMI))
|
|
1676
|
+
self.set_kids(nodes=new_kid)
|
|
1677
|
+
return res
|
|
1678
|
+
|
|
1679
|
+
|
|
1624
1680
|
class Enum(ArchSpec, AstAccessNode, AstImplNeedingNode, ArchBlockStmt, UniScopeNode):
|
|
1625
1681
|
"""Enum node type for Jac Ast."""
|
|
1626
1682
|
|
|
@@ -1777,6 +1833,22 @@ class Ability(
|
|
|
1777
1833
|
def is_genai_ability(self) -> bool:
|
|
1778
1834
|
return isinstance(self.body, FuncCall)
|
|
1779
1835
|
|
|
1836
|
+
def get_pos_argc_range(self) -> tuple[int, int]:
|
|
1837
|
+
"""Get the range of positional arguments for this ability.
|
|
1838
|
+
|
|
1839
|
+
Returns -1 for maximum number of arguments if there is an unpacked parameter (e.g., *args).
|
|
1840
|
+
"""
|
|
1841
|
+
mn, mx = 0, 0
|
|
1842
|
+
if isinstance(self.signature, FuncSignature):
|
|
1843
|
+
for param in self.signature.params:
|
|
1844
|
+
if param.unpack:
|
|
1845
|
+
if param.unpack == Tok.STAR_MUL:
|
|
1846
|
+
mx = -1
|
|
1847
|
+
break
|
|
1848
|
+
mn += 1
|
|
1849
|
+
mx += 1
|
|
1850
|
+
return mn, mx
|
|
1851
|
+
|
|
1780
1852
|
def py_resolve_name(self) -> str:
|
|
1781
1853
|
if isinstance(self.name_ref, Name):
|
|
1782
1854
|
return self.name_ref.value
|
|
@@ -1914,12 +1986,10 @@ class EventSignature(WalkerStmtOnlyNode):
|
|
|
1914
1986
|
self,
|
|
1915
1987
|
event: Token,
|
|
1916
1988
|
arch_tag_info: Optional[Expr],
|
|
1917
|
-
return_type: Optional[Expr],
|
|
1918
1989
|
kid: Sequence[UniNode],
|
|
1919
1990
|
) -> None:
|
|
1920
1991
|
self.event = event
|
|
1921
1992
|
self.arch_tag_info = arch_tag_info
|
|
1922
|
-
self.return_type = return_type
|
|
1923
1993
|
UniNode.__init__(self, kid=kid)
|
|
1924
1994
|
WalkerStmtOnlyNode.__init__(self)
|
|
1925
1995
|
|
|
@@ -1932,14 +2002,10 @@ class EventSignature(WalkerStmtOnlyNode):
|
|
|
1932
2002
|
if self.arch_tag_info
|
|
1933
2003
|
else res
|
|
1934
2004
|
)
|
|
1935
|
-
res = res and self.return_type.normalize(deep) if self.return_type else res
|
|
1936
2005
|
new_kid: list[UniNode] = [self.gen_token(Tok.KW_WITH)]
|
|
1937
2006
|
if self.arch_tag_info:
|
|
1938
2007
|
new_kid.append(self.arch_tag_info)
|
|
1939
2008
|
new_kid.append(self.event)
|
|
1940
|
-
if self.return_type:
|
|
1941
|
-
new_kid.append(self.gen_token(Tok.RETURN_HINT))
|
|
1942
|
-
new_kid.append(self.return_type)
|
|
1943
2009
|
self.set_kids(nodes=new_kid)
|
|
1944
2010
|
return res
|
|
1945
2011
|
|
|
@@ -3659,10 +3725,12 @@ class FuncCall(Expr):
|
|
|
3659
3725
|
params: Sequence[Expr | KWPair] | None,
|
|
3660
3726
|
genai_call: Optional[FuncCall],
|
|
3661
3727
|
kid: Sequence[UniNode],
|
|
3728
|
+
body_genai_call: Optional[FuncCall] = None,
|
|
3662
3729
|
) -> None:
|
|
3663
3730
|
self.target = target
|
|
3664
3731
|
self.params = list(params) if params else []
|
|
3665
3732
|
self.genai_call = genai_call
|
|
3733
|
+
self.body_genai_call = body_genai_call
|
|
3666
3734
|
UniNode.__init__(self, kid=kid)
|
|
3667
3735
|
Expr.__init__(self)
|
|
3668
3736
|
|
|
@@ -4578,17 +4646,21 @@ class String(Literal):
|
|
|
4578
4646
|
return eval(self.value)
|
|
4579
4647
|
|
|
4580
4648
|
elif self.value.startswith(("'", '"')):
|
|
4581
|
-
repr_str = self.value.encode().decode("unicode_escape")
|
|
4582
|
-
if (
|
|
4583
|
-
(self.value.startswith('"""') and self.value.endswith('"""'))
|
|
4584
|
-
or (self.value.startswith("'''") and self.value.endswith("'''"))
|
|
4585
|
-
) and not self.find_parent_of_type(FString):
|
|
4586
|
-
return repr_str[3:-3]
|
|
4587
4649
|
if (not self.find_parent_of_type(FString)) or (
|
|
4588
4650
|
not (self.parent and isinstance(self.parent, FString))
|
|
4589
4651
|
):
|
|
4590
|
-
|
|
4591
|
-
|
|
4652
|
+
try:
|
|
4653
|
+
return ast3.literal_eval(self.value)
|
|
4654
|
+
except (ValueError, SyntaxError):
|
|
4655
|
+
if (
|
|
4656
|
+
self.value.startswith('"""') and self.value.endswith('"""')
|
|
4657
|
+
) or (self.value.startswith("'''") and self.value.endswith("'''")):
|
|
4658
|
+
return self.value[3:-3]
|
|
4659
|
+
return self.value[1:-1]
|
|
4660
|
+
try:
|
|
4661
|
+
return ast3.literal_eval(self.value)
|
|
4662
|
+
except (ValueError, SyntaxError):
|
|
4663
|
+
return self.value
|
|
4592
4664
|
else:
|
|
4593
4665
|
return self.value
|
|
4594
4666
|
|
jaclang/langserve/__init__.jac
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
"""
|
|
1
|
+
"""Jaclang langserve package."""
|