jaclang 0.8.1__py3-none-any.whl → 0.8.2__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/jac.lark +12 -10
- jaclang/compiler/larkparse/jac_parser.py +2 -2
- jaclang/compiler/parser.py +18 -10
- jaclang/compiler/passes/main/__init__.py +0 -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 +243 -592
- jaclang/compiler/passes/main/sym_tab_link_pass.py +2 -5
- 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_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 +237 -105
- 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/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 +18 -3
- jaclang/compiler/passes/tool/tests/test_unparse_validate.py +2 -2
- jaclang/compiler/program.py +21 -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 +32 -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.2.dist-info}/METADATA +1 -1
- {jaclang-0.8.1.dist-info → jaclang-0.8.2.dist-info}/RECORD +72 -70
- 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.2.dist-info}/WHEEL +0 -0
- {jaclang-0.8.1.dist-info → jaclang-0.8.2.dist-info}/entry_points.txt +0 -0
jaclang/compiler/parser.py
CHANGED
|
@@ -1749,10 +1749,10 @@ class JacParser(Transform[uni.Source, uni.Module]):
|
|
|
1749
1749
|
"""
|
|
1750
1750
|
return self._binary_expr_unwind(self.cur_nodes)
|
|
1751
1751
|
|
|
1752
|
-
def
|
|
1752
|
+
def os_spawn(self, _: None) -> uni.Expr:
|
|
1753
1753
|
"""Grammar rule.
|
|
1754
1754
|
|
|
1755
|
-
|
|
1755
|
+
os_spawn: (os_spawn KW_SPAWN)? unpack
|
|
1756
1756
|
"""
|
|
1757
1757
|
return self._binary_expr_unwind(self.cur_nodes)
|
|
1758
1758
|
|
|
@@ -1862,15 +1862,16 @@ class JacParser(Transform[uni.Source, uni.Module]):
|
|
|
1862
1862
|
def atomic_call(self, _: None) -> uni.FuncCall:
|
|
1863
1863
|
"""Grammar rule.
|
|
1864
1864
|
|
|
1865
|
-
atomic_call: atomic_chain LPAREN param_list?
|
|
1865
|
+
atomic_call: atomic_chain LPAREN param_list? by_call? RPAREN by_call?
|
|
1866
1866
|
"""
|
|
1867
1867
|
genai_call: uni.FuncCall | None = None
|
|
1868
1868
|
target = self.consume(uni.Expr)
|
|
1869
1869
|
self.consume_token(Tok.LPAREN)
|
|
1870
1870
|
params_sn = self.match(list)
|
|
1871
|
-
|
|
1872
|
-
genai_call = self.consume(uni.FuncCall)
|
|
1871
|
+
genai_call = self.match(uni.FuncCall)
|
|
1873
1872
|
self.consume_token(Tok.RPAREN)
|
|
1873
|
+
body_genai_call = self.match(uni.FuncCall)
|
|
1874
|
+
|
|
1874
1875
|
return uni.FuncCall(
|
|
1875
1876
|
target=target,
|
|
1876
1877
|
params=(
|
|
@@ -1879,9 +1880,20 @@ class JacParser(Transform[uni.Source, uni.Module]):
|
|
|
1879
1880
|
else []
|
|
1880
1881
|
),
|
|
1881
1882
|
genai_call=genai_call,
|
|
1883
|
+
body_genai_call=body_genai_call,
|
|
1882
1884
|
kid=self.flat_cur_nodes,
|
|
1883
1885
|
)
|
|
1884
1886
|
|
|
1887
|
+
def by_call(self, _: None) -> uni.FuncCall:
|
|
1888
|
+
"""Grammar rule.
|
|
1889
|
+
|
|
1890
|
+
by_call: KW_BY expression
|
|
1891
|
+
"""
|
|
1892
|
+
self.consume_token(Tok.KW_BY)
|
|
1893
|
+
if call := self.match(uni.FuncCall):
|
|
1894
|
+
return call
|
|
1895
|
+
raise ValueError("Expected a function call")
|
|
1896
|
+
|
|
1885
1897
|
def index_slice(self, _: None) -> uni.IndexSlice:
|
|
1886
1898
|
"""Grammar rule.
|
|
1887
1899
|
|
|
@@ -2896,18 +2908,14 @@ class JacParser(Transform[uni.Source, uni.Module]):
|
|
|
2896
2908
|
def event_clause(self, _: None) -> uni.EventSignature:
|
|
2897
2909
|
"""Grammar rule.
|
|
2898
2910
|
|
|
2899
|
-
event_clause: KW_WITH expression? (KW_EXIT | KW_ENTRY)
|
|
2911
|
+
event_clause: KW_WITH expression? (KW_EXIT | KW_ENTRY)
|
|
2900
2912
|
"""
|
|
2901
|
-
return_spec: uni.Expr | None = None
|
|
2902
2913
|
self.consume_token(Tok.KW_WITH)
|
|
2903
2914
|
type_specs = self.match(uni.Expr)
|
|
2904
2915
|
event = self.match_token(Tok.KW_EXIT) or self.consume_token(Tok.KW_ENTRY)
|
|
2905
|
-
if self.match_token(Tok.RETURN_HINT):
|
|
2906
|
-
return_spec = self.consume(uni.Expr)
|
|
2907
2916
|
return uni.EventSignature(
|
|
2908
2917
|
event=event,
|
|
2909
2918
|
arch_tag_info=type_specs,
|
|
2910
|
-
return_type=return_spec,
|
|
2911
2919
|
kid=self.cur_nodes,
|
|
2912
2920
|
)
|
|
2913
2921
|
|
|
@@ -1,7 +1,5 @@
|
|
|
1
1
|
"""Collection of passes for Jac IR."""
|
|
2
2
|
|
|
3
|
-
from enum import Enum
|
|
4
|
-
|
|
5
3
|
from ..transform import Alert, Transform # noqa: I100
|
|
6
4
|
from .annex_pass import JacAnnexPass # noqa: I100
|
|
7
5
|
from .sym_tab_build_pass import SymTabBuildPass, UniPass # noqa: I100
|
|
@@ -17,17 +15,6 @@ from .pyjac_ast_link_pass import PyJacAstLinkPass # noqa: I100
|
|
|
17
15
|
from .inheritance_pass import InheritancePass # noqa: I100
|
|
18
16
|
|
|
19
17
|
|
|
20
|
-
class CompilerMode(Enum):
|
|
21
|
-
"""Compiler modes."""
|
|
22
|
-
|
|
23
|
-
PARSE = "PARSE"
|
|
24
|
-
NO_CGEN = "NO_CGEN"
|
|
25
|
-
NO_CGEN_SINGLE = "NO_CGEN_SINGLE"
|
|
26
|
-
COMPILE = "COMPILE"
|
|
27
|
-
COMPILE_SINGLE = "COMPILE_SINGLE"
|
|
28
|
-
TYPECHECK = "TYPECHECK"
|
|
29
|
-
|
|
30
|
-
|
|
31
18
|
__all__ = [
|
|
32
19
|
"Alert",
|
|
33
20
|
"Transform",
|
|
@@ -42,7 +29,6 @@ __all__ = [
|
|
|
42
29
|
"PyastBuildPass",
|
|
43
30
|
"PyastGenPass",
|
|
44
31
|
"PyBytecodeGenPass",
|
|
45
|
-
"CompilerMode",
|
|
46
32
|
"CFGBuildPass",
|
|
47
33
|
"PyJacAstLinkPass",
|
|
48
34
|
"InheritancePass",
|
|
@@ -48,8 +48,6 @@ class JacAnnexPass(Transform[uni.Module, uni.Module]):
|
|
|
48
48
|
|
|
49
49
|
def load_annexes(self, jac_program: JacProgram, node: uni.Module) -> None:
|
|
50
50
|
"""Parse and attach annex modules to the node."""
|
|
51
|
-
from jaclang.compiler.program import CompilerMode
|
|
52
|
-
|
|
53
51
|
if node.stub_only or not self.mod_path.endswith(".jac"):
|
|
54
52
|
return
|
|
55
53
|
if not self.mod_path:
|
|
@@ -64,9 +62,7 @@ class JacAnnexPass(Transform[uni.Module, uni.Module]):
|
|
|
64
62
|
path.startswith(f"{self.base_path}.")
|
|
65
63
|
or os.path.dirname(path) == self.impl_folder
|
|
66
64
|
):
|
|
67
|
-
mod = jac_program.compile(
|
|
68
|
-
file_path=path, mode=CompilerMode.NO_CGEN_SINGLE
|
|
69
|
-
)
|
|
65
|
+
mod = jac_program.compile(file_path=path, no_cgen=True)
|
|
70
66
|
if mod:
|
|
71
67
|
node.impl_mod.append(mod)
|
|
72
68
|
|
|
@@ -78,8 +74,6 @@ class JacAnnexPass(Transform[uni.Module, uni.Module]):
|
|
|
78
74
|
or os.path.dirname(path) == self.test_folder
|
|
79
75
|
)
|
|
80
76
|
):
|
|
81
|
-
mod = jac_program.compile(
|
|
82
|
-
file_path=path, mode=CompilerMode.NO_CGEN_SINGLE
|
|
83
|
-
)
|
|
77
|
+
mod = jac_program.compile(file_path=path, no_cgen=True)
|
|
84
78
|
if mod:
|
|
85
79
|
node.test_mod.append(mod)
|
|
@@ -10,6 +10,8 @@ The CFG provides a foundation for data flow analysis, optimization, and understa
|
|
|
10
10
|
The pass also includes functionality to coalesce basic blocks and generate visual representations of the CFG.
|
|
11
11
|
"""
|
|
12
12
|
|
|
13
|
+
from typing import Sequence
|
|
14
|
+
|
|
13
15
|
import jaclang.compiler.unitree as uni
|
|
14
16
|
from jaclang.compiler.passes import UniPass
|
|
15
17
|
|
|
@@ -65,26 +67,48 @@ class CFGBuildPass(UniPass):
|
|
|
65
67
|
else:
|
|
66
68
|
target.bb_in = [source]
|
|
67
69
|
|
|
70
|
+
def get_code_block_sequence(
|
|
71
|
+
self, node: uni.CodeBlockStmt
|
|
72
|
+
) -> list[uni.UniCFGNode] | None:
|
|
73
|
+
"""Get code block sequence."""
|
|
74
|
+
sequence: list[uni.UniCFGNode] = []
|
|
75
|
+
if hasattr(node, "body") and isinstance(node.body, Sequence):
|
|
76
|
+
for bbs in node.body:
|
|
77
|
+
if isinstance(bbs, uni.UniCFGNode):
|
|
78
|
+
sequence.append(bbs)
|
|
79
|
+
if sequence:
|
|
80
|
+
return sequence
|
|
81
|
+
else:
|
|
82
|
+
return None
|
|
83
|
+
else:
|
|
84
|
+
return None
|
|
85
|
+
|
|
68
86
|
def enter_node(self, node: uni.UniNode) -> None:
|
|
69
87
|
"""Enter BasicBlockStmt nodes."""
|
|
70
88
|
if isinstance(node, uni.UniCFGNode) and not isinstance(node, uni.Semi):
|
|
71
|
-
if
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
89
|
+
# check if the current node is a CodeBlockStmt in a sequence of statements
|
|
90
|
+
bb_stmts = self.get_code_block_sequence(node.parent)
|
|
91
|
+
if (
|
|
92
|
+
isinstance(node, uni.CodeBlockStmt)
|
|
93
|
+
and node.parent
|
|
94
|
+
and (not (isinstance(node, (uni.ElseIf, uni.ElseStmt))))
|
|
95
|
+
and bb_stmts
|
|
96
|
+
and self.first_exit
|
|
97
|
+
):
|
|
98
|
+
# bb_stmts = self.get_code_block_sequence(node.parent)
|
|
99
|
+
# bb_stmts = [
|
|
100
|
+
# bbs for bbs in node.parent.body if isinstance(bbs, uni.UniCFGNode)
|
|
101
|
+
# ]
|
|
75
102
|
if (
|
|
76
|
-
node.parent
|
|
77
|
-
and isinstance(node.parent
|
|
103
|
+
node.parent
|
|
104
|
+
and isinstance(node.parent, uni.Archetype)
|
|
78
105
|
# and isinstance(node.parent.parent, uni.BasicBlockStmt)
|
|
79
106
|
):
|
|
80
|
-
parent_obj = node.parent
|
|
107
|
+
parent_obj = node.parent
|
|
81
108
|
if parent_obj:
|
|
82
109
|
self.link_bbs(parent_obj, node)
|
|
83
110
|
elif bb_stmts[0] == node:
|
|
84
|
-
if (
|
|
85
|
-
isinstance(node.parent.parent, uni.ModuleCode)
|
|
86
|
-
and self.to_connect
|
|
87
|
-
):
|
|
111
|
+
if isinstance(node.parent, uni.ModuleCode) and self.to_connect:
|
|
88
112
|
for bb in self.to_connect:
|
|
89
113
|
self.link_bbs(bb, node)
|
|
90
114
|
self.to_connect.remove(bb) # if self.to_connect:
|
|
@@ -92,7 +116,9 @@ class CFGBuildPass(UniPass):
|
|
|
92
116
|
parent_bb = self.get_parent_bb_stmt(node)
|
|
93
117
|
if parent_bb:
|
|
94
118
|
self.link_bbs(parent_bb, node)
|
|
95
|
-
elif self.to_connect
|
|
119
|
+
elif self.to_connect and not isinstance(
|
|
120
|
+
node, (uni.ElseIf, uni.ElseStmt)
|
|
121
|
+
):
|
|
96
122
|
to_remove = []
|
|
97
123
|
for parent in self.to_connect:
|
|
98
124
|
if isinstance(parent, uni.UniCFGNode):
|
|
@@ -63,8 +63,6 @@ class JacImportDepsPass(Transform[uni.Module, uni.Module]):
|
|
|
63
63
|
|
|
64
64
|
def import_jac_module(self, node: uni.ModulePath) -> None:
|
|
65
65
|
"""Import a module."""
|
|
66
|
-
from jaclang.compiler.passes.main import CompilerMode as CMode
|
|
67
|
-
|
|
68
66
|
target = node.resolve_relative_path()
|
|
69
67
|
# If the module is a package (dir)
|
|
70
68
|
if os.path.isdir(target):
|
|
@@ -83,15 +81,11 @@ class JacImportDepsPass(Transform[uni.Module, uni.Module]):
|
|
|
83
81
|
else:
|
|
84
82
|
if from_mod_target in self.prog.mod.hub:
|
|
85
83
|
return
|
|
86
|
-
self.load_mod(
|
|
87
|
-
self.prog.compile(
|
|
88
|
-
file_path=from_mod_target, mode=CMode.PARSE
|
|
89
|
-
)
|
|
90
|
-
)
|
|
84
|
+
self.load_mod(self.prog.compile(file_path=from_mod_target))
|
|
91
85
|
else:
|
|
92
86
|
if target in self.prog.mod.hub:
|
|
93
87
|
return
|
|
94
|
-
self.load_mod(self.prog.compile(file_path=target
|
|
88
|
+
self.load_mod(self.prog.compile(file_path=target))
|
|
95
89
|
|
|
96
90
|
def load_mod(self, mod: uni.Module) -> None:
|
|
97
91
|
"""Attach a module to a node."""
|
|
@@ -102,13 +96,11 @@ class JacImportDepsPass(Transform[uni.Module, uni.Module]):
|
|
|
102
96
|
|
|
103
97
|
def import_jac_mod_from_dir(self, target: str) -> uni.Module:
|
|
104
98
|
"""Import a module from a directory."""
|
|
105
|
-
from jaclang.compiler.passes.main import CompilerMode as CMode
|
|
106
|
-
|
|
107
99
|
jac_init_path = os.path.join(target, "__init__.jac")
|
|
108
100
|
if os.path.exists(jac_init_path):
|
|
109
101
|
if jac_init_path in self.prog.mod.hub:
|
|
110
102
|
return self.prog.mod.hub[jac_init_path]
|
|
111
|
-
return self.prog.compile(file_path=jac_init_path
|
|
103
|
+
return self.prog.compile(file_path=jac_init_path)
|
|
112
104
|
elif os.path.exists(py_init_path := os.path.join(target, "__init__.py")):
|
|
113
105
|
with open(py_init_path, "r") as f:
|
|
114
106
|
file_source = f.read()
|