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
jaclang/compiler/parser.py
CHANGED
|
@@ -546,6 +546,22 @@ class JacParser(Transform[uni.Source, uni.Module]):
|
|
|
546
546
|
)
|
|
547
547
|
return impl
|
|
548
548
|
|
|
549
|
+
def sem_def(self, _: None) -> uni.SemDef:
|
|
550
|
+
"""Grammar rule.
|
|
551
|
+
|
|
552
|
+
sem_def: KW_SEM dotted_name EQ multistring SEMI
|
|
553
|
+
"""
|
|
554
|
+
self.consume_token(Tok.KW_SEM)
|
|
555
|
+
target = self.extract_from_list(self.consume(list), uni.NameAtom)
|
|
556
|
+
self.consume_token(Tok.EQ)
|
|
557
|
+
value = self.consume(uni.String)
|
|
558
|
+
self.consume_token(Tok.SEMI)
|
|
559
|
+
return uni.SemDef(
|
|
560
|
+
target=target,
|
|
561
|
+
value=value,
|
|
562
|
+
kid=self.flat_cur_nodes,
|
|
563
|
+
)
|
|
564
|
+
|
|
549
565
|
def impl_spec(
|
|
550
566
|
self, _: None
|
|
551
567
|
) -> Sequence[uni.Expr] | uni.FuncSignature | uni.EventSignature:
|
|
@@ -1749,10 +1765,10 @@ class JacParser(Transform[uni.Source, uni.Module]):
|
|
|
1749
1765
|
"""
|
|
1750
1766
|
return self._binary_expr_unwind(self.cur_nodes)
|
|
1751
1767
|
|
|
1752
|
-
def
|
|
1768
|
+
def os_spawn(self, _: None) -> uni.Expr:
|
|
1753
1769
|
"""Grammar rule.
|
|
1754
1770
|
|
|
1755
|
-
|
|
1771
|
+
os_spawn: (os_spawn KW_SPAWN)? unpack
|
|
1756
1772
|
"""
|
|
1757
1773
|
return self._binary_expr_unwind(self.cur_nodes)
|
|
1758
1774
|
|
|
@@ -1862,15 +1878,16 @@ class JacParser(Transform[uni.Source, uni.Module]):
|
|
|
1862
1878
|
def atomic_call(self, _: None) -> uni.FuncCall:
|
|
1863
1879
|
"""Grammar rule.
|
|
1864
1880
|
|
|
1865
|
-
atomic_call: atomic_chain LPAREN param_list?
|
|
1881
|
+
atomic_call: atomic_chain LPAREN param_list? by_call? RPAREN by_call?
|
|
1866
1882
|
"""
|
|
1867
1883
|
genai_call: uni.FuncCall | None = None
|
|
1868
1884
|
target = self.consume(uni.Expr)
|
|
1869
1885
|
self.consume_token(Tok.LPAREN)
|
|
1870
1886
|
params_sn = self.match(list)
|
|
1871
|
-
|
|
1872
|
-
genai_call = self.consume(uni.FuncCall)
|
|
1887
|
+
genai_call = self.match(uni.FuncCall)
|
|
1873
1888
|
self.consume_token(Tok.RPAREN)
|
|
1889
|
+
body_genai_call = self.match(uni.FuncCall)
|
|
1890
|
+
|
|
1874
1891
|
return uni.FuncCall(
|
|
1875
1892
|
target=target,
|
|
1876
1893
|
params=(
|
|
@@ -1879,9 +1896,20 @@ class JacParser(Transform[uni.Source, uni.Module]):
|
|
|
1879
1896
|
else []
|
|
1880
1897
|
),
|
|
1881
1898
|
genai_call=genai_call,
|
|
1899
|
+
body_genai_call=body_genai_call,
|
|
1882
1900
|
kid=self.flat_cur_nodes,
|
|
1883
1901
|
)
|
|
1884
1902
|
|
|
1903
|
+
def by_call(self, _: None) -> uni.FuncCall:
|
|
1904
|
+
"""Grammar rule.
|
|
1905
|
+
|
|
1906
|
+
by_call: KW_BY expression
|
|
1907
|
+
"""
|
|
1908
|
+
self.consume_token(Tok.KW_BY)
|
|
1909
|
+
if call := self.match(uni.FuncCall):
|
|
1910
|
+
return call
|
|
1911
|
+
raise ValueError("Expected a function call")
|
|
1912
|
+
|
|
1885
1913
|
def index_slice(self, _: None) -> uni.IndexSlice:
|
|
1886
1914
|
"""Grammar rule.
|
|
1887
1915
|
|
|
@@ -2896,18 +2924,14 @@ class JacParser(Transform[uni.Source, uni.Module]):
|
|
|
2896
2924
|
def event_clause(self, _: None) -> uni.EventSignature:
|
|
2897
2925
|
"""Grammar rule.
|
|
2898
2926
|
|
|
2899
|
-
event_clause: KW_WITH expression? (KW_EXIT | KW_ENTRY)
|
|
2927
|
+
event_clause: KW_WITH expression? (KW_EXIT | KW_ENTRY)
|
|
2900
2928
|
"""
|
|
2901
|
-
return_spec: uni.Expr | None = None
|
|
2902
2929
|
self.consume_token(Tok.KW_WITH)
|
|
2903
2930
|
type_specs = self.match(uni.Expr)
|
|
2904
2931
|
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
2932
|
return uni.EventSignature(
|
|
2908
2933
|
event=event,
|
|
2909
2934
|
arch_tag_info=type_specs,
|
|
2910
|
-
return_type=return_spec,
|
|
2911
2935
|
kid=self.cur_nodes,
|
|
2912
2936
|
)
|
|
2913
2937
|
|
|
@@ -1,12 +1,11 @@
|
|
|
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
|
|
8
6
|
from .sym_tab_link_pass import SymTabLinkPass # noqa: I100
|
|
9
7
|
from .def_use_pass import DefUsePass # noqa: I100
|
|
8
|
+
from .sem_def_match_pass import SemDefMatchPass # noqa: I100
|
|
10
9
|
from .import_pass import JacImportDepsPass, PyImportDepsPass # noqa: I100
|
|
11
10
|
from .def_impl_match_pass import DeclImplMatchPass # noqa: I100
|
|
12
11
|
from .pyast_load_pass import PyastBuildPass # type: ignore # noqa: I100
|
|
@@ -17,17 +16,6 @@ from .pyjac_ast_link_pass import PyJacAstLinkPass # noqa: I100
|
|
|
17
16
|
from .inheritance_pass import InheritancePass # noqa: I100
|
|
18
17
|
|
|
19
18
|
|
|
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
19
|
__all__ = [
|
|
32
20
|
"Alert",
|
|
33
21
|
"Transform",
|
|
@@ -39,10 +27,10 @@ __all__ = [
|
|
|
39
27
|
"SymTabLinkPass",
|
|
40
28
|
"DeclImplMatchPass",
|
|
41
29
|
"DefUsePass",
|
|
30
|
+
"SemDefMatchPass",
|
|
42
31
|
"PyastBuildPass",
|
|
43
32
|
"PyastGenPass",
|
|
44
33
|
"PyBytecodeGenPass",
|
|
45
|
-
"CompilerMode",
|
|
46
34
|
"CFGBuildPass",
|
|
47
35
|
"PyJacAstLinkPass",
|
|
48
36
|
"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()
|