jaclang 0.7.2__py3-none-any.whl → 0.7.7__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 +2 -2
- jaclang/compiler/absyntree.py +499 -294
- jaclang/compiler/codeloc.py +2 -2
- jaclang/compiler/constant.py +100 -2
- jaclang/compiler/jac.lark +27 -19
- jaclang/compiler/parser.py +119 -92
- jaclang/compiler/passes/main/access_modifier_pass.py +20 -12
- jaclang/compiler/passes/main/def_impl_match_pass.py +28 -14
- jaclang/compiler/passes/main/def_use_pass.py +59 -40
- jaclang/compiler/passes/main/fuse_typeinfo_pass.py +65 -43
- jaclang/compiler/passes/main/import_pass.py +8 -6
- jaclang/compiler/passes/main/pyast_gen_pass.py +97 -42
- jaclang/compiler/passes/main/pyast_load_pass.py +47 -12
- jaclang/compiler/passes/main/pyjac_ast_link_pass.py +19 -10
- jaclang/compiler/passes/main/registry_pass.py +6 -6
- jaclang/compiler/passes/main/sub_node_tab_pass.py +0 -5
- jaclang/compiler/passes/main/sym_tab_build_pass.py +43 -235
- jaclang/compiler/passes/main/tests/test_decl_def_match_pass.py +21 -4
- jaclang/compiler/passes/main/tests/test_def_use_pass.py +5 -10
- jaclang/compiler/passes/main/type_check_pass.py +2 -1
- jaclang/compiler/passes/tool/jac_formatter_pass.py +30 -9
- jaclang/compiler/passes/tool/tests/fixtures/corelib.jac +16 -0
- jaclang/compiler/passes/tool/tests/fixtures/corelib_fmt.jac +16 -0
- jaclang/compiler/passes/tool/tests/fixtures/genai/essay_review.jac +1 -1
- jaclang/compiler/passes/tool/tests/fixtures/genai/expert_answer.jac +1 -1
- jaclang/compiler/passes/tool/tests/fixtures/genai/joke_gen.jac +1 -1
- jaclang/compiler/passes/tool/tests/fixtures/genai/odd_word_out.jac +1 -1
- jaclang/compiler/passes/tool/tests/fixtures/genai/personality_finder.jac +1 -1
- jaclang/compiler/passes/tool/tests/fixtures/genai/text_to_type.jac +1 -1
- jaclang/compiler/passes/tool/tests/fixtures/genai/translator.jac +1 -1
- jaclang/compiler/passes/tool/tests/fixtures/genai/wikipedia.jac +1 -1
- jaclang/compiler/passes/transform.py +2 -4
- jaclang/{core/registry.py → compiler/semtable.py} +1 -3
- jaclang/compiler/symtable.py +142 -101
- jaclang/compiler/tests/test_parser.py +2 -2
- jaclang/core/aott.py +15 -11
- jaclang/core/{construct.py → architype.py} +25 -240
- jaclang/core/constructs.py +44 -0
- jaclang/core/context.py +157 -0
- jaclang/core/importer.py +18 -9
- jaclang/core/memory.py +99 -0
- jaclang/core/test.py +90 -0
- jaclang/core/utils.py +2 -2
- jaclang/langserve/engine.py +127 -50
- jaclang/langserve/server.py +34 -61
- jaclang/langserve/tests/fixtures/base_module_structure.jac +28 -0
- jaclang/langserve/tests/fixtures/circle.jac +16 -12
- jaclang/langserve/tests/fixtures/circle_err.jac +3 -3
- jaclang/langserve/tests/fixtures/circle_pure.test.jac +15 -0
- jaclang/langserve/tests/fixtures/import_include_statements.jac +6 -0
- jaclang/langserve/tests/fixtures/py_import.py +26 -0
- jaclang/langserve/tests/test_server.py +93 -18
- jaclang/langserve/utils.py +124 -10
- jaclang/plugin/builtin.py +1 -1
- jaclang/plugin/default.py +23 -9
- jaclang/plugin/feature.py +25 -7
- jaclang/plugin/spec.py +18 -20
- jaclang/settings.py +3 -0
- jaclang/tests/fixtures/abc.jac +16 -12
- jaclang/tests/fixtures/aott_raise.jac +1 -1
- jaclang/tests/fixtures/byllmissue.jac +9 -0
- jaclang/tests/fixtures/edgetypeissue.jac +10 -0
- jaclang/tests/fixtures/hello.jac +1 -1
- jaclang/tests/fixtures/impl_match_confused.impl.jac +1 -0
- jaclang/tests/fixtures/impl_match_confused.jac +5 -0
- jaclang/tests/fixtures/maxfail_run_test.jac +17 -5
- jaclang/tests/fixtures/run_test.jac +17 -5
- jaclang/tests/fixtures/with_llm_function.jac +1 -1
- jaclang/tests/fixtures/with_llm_lower.jac +1 -1
- jaclang/tests/fixtures/with_llm_method.jac +1 -1
- jaclang/tests/fixtures/with_llm_type.jac +1 -1
- jaclang/tests/fixtures/with_llm_vision.jac +1 -1
- jaclang/tests/test_bugs.py +19 -0
- jaclang/tests/test_cli.py +1 -1
- jaclang/tests/test_language.py +161 -96
- jaclang/tests/test_reference.py +1 -1
- jaclang/utils/lang_tools.py +5 -4
- jaclang/utils/test.py +2 -1
- jaclang/utils/treeprinter.py +22 -8
- {jaclang-0.7.2.dist-info → jaclang-0.7.7.dist-info}/METADATA +1 -1
- {jaclang-0.7.2.dist-info → jaclang-0.7.7.dist-info}/RECORD +83 -80
- jaclang/core/llms/__init__.py +0 -20
- jaclang/core/llms/anthropic.py +0 -90
- jaclang/core/llms/base.py +0 -206
- jaclang/core/llms/groq.py +0 -70
- jaclang/core/llms/huggingface.py +0 -76
- jaclang/core/llms/ollama.py +0 -81
- jaclang/core/llms/openai.py +0 -65
- jaclang/core/llms/togetherai.py +0 -63
- jaclang/core/llms/utils.py +0 -9
- {jaclang-0.7.2.dist-info → jaclang-0.7.7.dist-info}/WHEEL +0 -0
- {jaclang-0.7.2.dist-info → jaclang-0.7.7.dist-info}/entry_points.txt +0 -0
|
@@ -478,3 +478,19 @@ obj JacPlugin {
|
|
|
478
478
|
(walker_obj: Any, expr: Any) -> bool {
|
|
479
479
|
return walker_obj._jac_.visit_node(expr);
|
|
480
480
|
}
|
|
481
|
+
|
|
482
|
+
glob expected_area = 78.53981633974483;
|
|
483
|
+
|
|
484
|
+
test a1 {
|
|
485
|
+
check assertAlmostEqual(calculate_area(RAD), expected_area);
|
|
486
|
+
}
|
|
487
|
+
|
|
488
|
+
test a2 {
|
|
489
|
+
c = Circle(RAD);
|
|
490
|
+
check assertAlmostEqual(c.area(), expected_area);
|
|
491
|
+
}
|
|
492
|
+
|
|
493
|
+
test a3 {
|
|
494
|
+
c = Circle(RAD);
|
|
495
|
+
check assertEqual(c.shape_type, ShapeType.CIRCLE);
|
|
496
|
+
}
|
|
@@ -22,7 +22,7 @@ class Alert:
|
|
|
22
22
|
def __str__(self) -> str:
|
|
23
23
|
"""Return string representation of alert."""
|
|
24
24
|
return (
|
|
25
|
-
f"{self.loc.mod_path}, line {self.loc.first_line},"
|
|
25
|
+
f" {self.loc.mod_path}, line {self.loc.first_line},"
|
|
26
26
|
f" col {self.loc.col_start}: {self.msg}"
|
|
27
27
|
)
|
|
28
28
|
|
|
@@ -40,7 +40,7 @@ class Transform(ABC, Generic[T]):
|
|
|
40
40
|
prior: Optional[Transform] = None,
|
|
41
41
|
) -> None:
|
|
42
42
|
"""Initialize pass."""
|
|
43
|
-
self.logger = logging.getLogger(self.__class__.
|
|
43
|
+
self.logger = logging.getLogger(self.__class__.__name__)
|
|
44
44
|
self.errors_had: list[Alert] = [] if not prior else prior.errors_had
|
|
45
45
|
self.warnings_had: list[Alert] = [] if not prior else prior.warnings_had
|
|
46
46
|
self.cur_node: AstNode = input_ir # tracks current node during traversal
|
|
@@ -59,7 +59,6 @@ class Transform(ABC, Generic[T]):
|
|
|
59
59
|
self.__class__,
|
|
60
60
|
)
|
|
61
61
|
self.errors_had.append(alrt)
|
|
62
|
-
# print("Error:", str(alrt))
|
|
63
62
|
self.logger.error(str(alrt))
|
|
64
63
|
|
|
65
64
|
def log_warning(self, msg: str, node_override: Optional[AstNode] = None) -> None:
|
|
@@ -70,5 +69,4 @@ class Transform(ABC, Generic[T]):
|
|
|
70
69
|
self.__class__,
|
|
71
70
|
)
|
|
72
71
|
self.warnings_had.append(alrt)
|
|
73
|
-
# print("Warning:", str(alrt))
|
|
74
72
|
self.logger.warning(str(alrt))
|
|
@@ -12,9 +12,7 @@ from typing import Optional
|
|
|
12
12
|
class SemInfo:
|
|
13
13
|
"""Semantic information class."""
|
|
14
14
|
|
|
15
|
-
def __init__(
|
|
16
|
-
self, name: str, type: Optional[str] = None, semstr: Optional[str] = None
|
|
17
|
-
) -> None:
|
|
15
|
+
def __init__(self, name: str, type: Optional[str] = None, semstr: str = "") -> None:
|
|
18
16
|
"""Initialize the class."""
|
|
19
17
|
self.name = name
|
|
20
18
|
self.type = type
|
jaclang/compiler/symtable.py
CHANGED
|
@@ -2,77 +2,14 @@
|
|
|
2
2
|
|
|
3
3
|
from __future__ import annotations
|
|
4
4
|
|
|
5
|
-
|
|
6
|
-
from typing import Optional,
|
|
5
|
+
import ast as ast3
|
|
6
|
+
from typing import Optional, Sequence
|
|
7
7
|
|
|
8
|
+
import jaclang.compiler.absyntree as ast
|
|
9
|
+
from jaclang.compiler.constant import SymbolAccess, SymbolType
|
|
8
10
|
from jaclang.utils.treeprinter import dotgen_symtab_tree, print_symtab_tree
|
|
9
11
|
|
|
10
12
|
|
|
11
|
-
if TYPE_CHECKING:
|
|
12
|
-
import jaclang.compiler.absyntree as ast
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
class SymbolType(Enum):
|
|
16
|
-
"""Symbol types."""
|
|
17
|
-
|
|
18
|
-
MODULE = "module" # LSP: Module
|
|
19
|
-
MOD_VAR = "mod_var" # LSP: Variable
|
|
20
|
-
VAR = "variable" # LSP: Variable
|
|
21
|
-
IMM_VAR = "immutable" # LSP: Constant
|
|
22
|
-
ABILITY = "ability" # LSP: Function
|
|
23
|
-
OBJECT_ARCH = "object" # LSP: Class
|
|
24
|
-
NODE_ARCH = "node" # LSP: Class
|
|
25
|
-
EDGE_ARCH = "edge" # LSP: Class
|
|
26
|
-
WALKER_ARCH = "walker" # LSP: Class
|
|
27
|
-
ENUM_ARCH = "enum" # LSP: Enum
|
|
28
|
-
TEST = "test" # LSP: Function
|
|
29
|
-
TYPE = "type" # LSP: TypeParameter
|
|
30
|
-
IMPL = "impl" # LSP: Interface or Property
|
|
31
|
-
HAS_VAR = "field" # LSP: Field
|
|
32
|
-
METHOD = "method" # LSP: Method
|
|
33
|
-
CONSTRUCTOR = "constructor" # LSP: Constructor
|
|
34
|
-
ENUM_MEMBER = "enum_member" # LSP: EnumMember
|
|
35
|
-
NUMBER = "number" # LSP: Number
|
|
36
|
-
STRING = "string" # LSP: String
|
|
37
|
-
BOOL = "bool" # LSP: Boolean
|
|
38
|
-
SEQUENCE = "sequence" # LSP: Array
|
|
39
|
-
NULL = "null" # LSP: Null
|
|
40
|
-
|
|
41
|
-
def __str__(self) -> str:
|
|
42
|
-
"""Stringify."""
|
|
43
|
-
return self.value
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
class SymbolInfo:
|
|
47
|
-
"""Symbol Info."""
|
|
48
|
-
|
|
49
|
-
def __init__(
|
|
50
|
-
self, typ: str = "NoType", acc_tag: Optional[SymbolAccess] = None
|
|
51
|
-
) -> None: # noqa: ANN401
|
|
52
|
-
"""Initialize."""
|
|
53
|
-
self.typ = typ
|
|
54
|
-
self.acc_tag: Optional[SymbolAccess] = acc_tag
|
|
55
|
-
self.typ_sym_table: Optional[SymbolTable] = None
|
|
56
|
-
|
|
57
|
-
@property
|
|
58
|
-
def clean_type(self) -> str:
|
|
59
|
-
"""Get clean type."""
|
|
60
|
-
ret_type = self.typ.replace("builtins.", "").replace("NoType", "")
|
|
61
|
-
return ret_type
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
class SymbolAccess(Enum):
|
|
65
|
-
"""Symbol types."""
|
|
66
|
-
|
|
67
|
-
PRIVATE = "private"
|
|
68
|
-
PUBLIC = "public"
|
|
69
|
-
PROTECTED = "protected"
|
|
70
|
-
|
|
71
|
-
def __str__(self) -> str:
|
|
72
|
-
"""Stringify."""
|
|
73
|
-
return self.value
|
|
74
|
-
|
|
75
|
-
|
|
76
13
|
# Symbols can have mulitple definitions but resolves decl to be the
|
|
77
14
|
# first such definition in a given scope.
|
|
78
15
|
class Symbol:
|
|
@@ -80,20 +17,19 @@ class Symbol:
|
|
|
80
17
|
|
|
81
18
|
def __init__(
|
|
82
19
|
self,
|
|
83
|
-
defn: ast.
|
|
20
|
+
defn: ast.NameAtom,
|
|
84
21
|
access: SymbolAccess,
|
|
85
22
|
parent_tab: SymbolTable,
|
|
86
|
-
typ: Optional[type] = None,
|
|
87
23
|
) -> None:
|
|
88
24
|
"""Initialize."""
|
|
89
|
-
self.
|
|
90
|
-
self.
|
|
91
|
-
defn.
|
|
92
|
-
self.access = access
|
|
25
|
+
self.defn: list[ast.NameAtom] = [defn]
|
|
26
|
+
self.uses: list[ast.NameAtom] = []
|
|
27
|
+
defn.sym = self
|
|
28
|
+
self.access: SymbolAccess = access
|
|
93
29
|
self.parent_tab = parent_tab
|
|
94
30
|
|
|
95
31
|
@property
|
|
96
|
-
def decl(self) -> ast.
|
|
32
|
+
def decl(self) -> ast.NameAtom:
|
|
97
33
|
"""Get decl."""
|
|
98
34
|
return self.defn[0]
|
|
99
35
|
|
|
@@ -105,33 +41,32 @@ class Symbol:
|
|
|
105
41
|
@property
|
|
106
42
|
def sym_type(self) -> SymbolType:
|
|
107
43
|
"""Get sym_type."""
|
|
108
|
-
return self.decl.
|
|
44
|
+
return self.decl.sym_category
|
|
109
45
|
|
|
110
46
|
@property
|
|
111
|
-
def
|
|
47
|
+
def sym_dotted_name(self) -> str:
|
|
112
48
|
"""Return a full path of the symbol."""
|
|
113
49
|
out = [self.defn[0].sym_name]
|
|
114
|
-
current_tab = self.parent_tab
|
|
50
|
+
current_tab: SymbolTable | None = self.parent_tab
|
|
115
51
|
while current_tab is not None:
|
|
116
52
|
out.append(current_tab.name)
|
|
117
|
-
|
|
118
|
-
current_tab = current_tab.parent
|
|
119
|
-
else:
|
|
120
|
-
break
|
|
53
|
+
current_tab = current_tab.parent
|
|
121
54
|
out.reverse()
|
|
122
55
|
return ".".join(out)
|
|
123
56
|
|
|
124
|
-
def add_defn(self, node: ast.
|
|
57
|
+
def add_defn(self, node: ast.NameAtom) -> None:
|
|
125
58
|
"""Add defn."""
|
|
126
59
|
self.defn.append(node)
|
|
127
|
-
node.
|
|
60
|
+
node.sym = self
|
|
61
|
+
|
|
62
|
+
def add_use(self, node: ast.NameAtom) -> None:
|
|
63
|
+
"""Add use."""
|
|
64
|
+
self.uses.append(node)
|
|
65
|
+
node.sym = self
|
|
128
66
|
|
|
129
67
|
def __repr__(self) -> str:
|
|
130
68
|
"""Repr."""
|
|
131
|
-
return (
|
|
132
|
-
f"Symbol({self.sym_name}, {self.sym_type}, {self.access}, "
|
|
133
|
-
f"{self.typ}, {self.defn})"
|
|
134
|
-
)
|
|
69
|
+
return f"Symbol({self.sym_name}, {self.sym_type}, {self.access}, {self.defn})"
|
|
135
70
|
|
|
136
71
|
|
|
137
72
|
class SymbolTable:
|
|
@@ -143,27 +78,25 @@ class SymbolTable:
|
|
|
143
78
|
"""Initialize."""
|
|
144
79
|
self.name = name
|
|
145
80
|
self.owner = owner
|
|
146
|
-
self.parent = parent
|
|
81
|
+
self.parent = parent
|
|
147
82
|
self.kid: list[SymbolTable] = []
|
|
148
83
|
self.tab: dict[str, Symbol] = {}
|
|
149
|
-
self.
|
|
84
|
+
self.inherit: list[SymbolTable] = []
|
|
150
85
|
|
|
151
|
-
def
|
|
152
|
-
"""Check if has parent."""
|
|
153
|
-
return self.parent != self
|
|
154
|
-
|
|
155
|
-
def get_parent(self) -> SymbolTable:
|
|
86
|
+
def get_parent(self) -> Optional[SymbolTable]:
|
|
156
87
|
"""Get parent."""
|
|
157
|
-
if self.parent == self:
|
|
158
|
-
raise Exception("No parent")
|
|
159
88
|
return self.parent
|
|
160
89
|
|
|
161
90
|
def lookup(self, name: str, deep: bool = True) -> Optional[Symbol]:
|
|
162
91
|
"""Lookup a variable in the symbol table."""
|
|
163
92
|
if name in self.tab:
|
|
164
93
|
return self.tab[name]
|
|
165
|
-
|
|
166
|
-
|
|
94
|
+
for i in self.inherit:
|
|
95
|
+
found = i.lookup(name, deep=False)
|
|
96
|
+
if found:
|
|
97
|
+
return found
|
|
98
|
+
if deep and self.parent:
|
|
99
|
+
return self.parent.lookup(name, deep)
|
|
167
100
|
return None
|
|
168
101
|
|
|
169
102
|
def insert(
|
|
@@ -184,7 +117,7 @@ class SymbolTable:
|
|
|
184
117
|
)
|
|
185
118
|
if node.sym_name not in self.tab:
|
|
186
119
|
self.tab[node.sym_name] = Symbol(
|
|
187
|
-
defn=node,
|
|
120
|
+
defn=node.name_spec,
|
|
188
121
|
access=(
|
|
189
122
|
access_spec
|
|
190
123
|
if isinstance(access_spec, SymbolAccess)
|
|
@@ -193,8 +126,8 @@ class SymbolTable:
|
|
|
193
126
|
parent_tab=self,
|
|
194
127
|
)
|
|
195
128
|
else:
|
|
196
|
-
self.tab[node.sym_name].add_defn(node)
|
|
197
|
-
node.
|
|
129
|
+
self.tab[node.sym_name].add_defn(node.name_spec)
|
|
130
|
+
node.name_spec.sym = self.tab[node.sym_name]
|
|
198
131
|
return collision
|
|
199
132
|
|
|
200
133
|
def find_scope(self, name: str) -> Optional[SymbolTable]:
|
|
@@ -209,6 +142,114 @@ class SymbolTable:
|
|
|
209
142
|
self.kid.append(SymbolTable(name, key_node, self))
|
|
210
143
|
return self.kid[-1]
|
|
211
144
|
|
|
145
|
+
def inherit_sym_tab(self, target_sym_tab: SymbolTable) -> None:
|
|
146
|
+
"""Inherit symbol table."""
|
|
147
|
+
for i in target_sym_tab.tab.values():
|
|
148
|
+
self.def_insert(i.decl, access_spec=i.access)
|
|
149
|
+
|
|
150
|
+
def def_insert(
|
|
151
|
+
self,
|
|
152
|
+
node: ast.AstSymbolNode,
|
|
153
|
+
access_spec: Optional[ast.AstAccessNode] | SymbolAccess = None,
|
|
154
|
+
single_decl: Optional[str] = None,
|
|
155
|
+
) -> Optional[Symbol]:
|
|
156
|
+
"""Insert into symbol table."""
|
|
157
|
+
if node.sym and self == node.sym.parent_tab:
|
|
158
|
+
return node.sym
|
|
159
|
+
self.insert(node=node, single=single_decl is not None, access_spec=access_spec)
|
|
160
|
+
self.update_py_ctx_for_def(node)
|
|
161
|
+
return node.sym
|
|
162
|
+
|
|
163
|
+
def chain_def_insert(self, node_list: list[ast.AstSymbolNode]) -> None:
|
|
164
|
+
"""Link chain of containing names to symbol."""
|
|
165
|
+
if not node_list:
|
|
166
|
+
return
|
|
167
|
+
cur_sym_tab: SymbolTable | None = node_list[0].sym_tab
|
|
168
|
+
node_list[-1].name_spec.py_ctx_func = ast3.Store
|
|
169
|
+
if isinstance(node_list[-1].name_spec, ast.AstSymbolNode):
|
|
170
|
+
node_list[-1].name_spec.py_ctx_func = ast3.Store
|
|
171
|
+
|
|
172
|
+
node_list = node_list[:-1] # Just performs lookup mappings of pre assign chain
|
|
173
|
+
for i in node_list:
|
|
174
|
+
cur_sym_tab = (
|
|
175
|
+
lookup.decl.sym_tab
|
|
176
|
+
if (
|
|
177
|
+
lookup := self.use_lookup(
|
|
178
|
+
i,
|
|
179
|
+
sym_table=cur_sym_tab,
|
|
180
|
+
)
|
|
181
|
+
)
|
|
182
|
+
else None
|
|
183
|
+
)
|
|
184
|
+
|
|
185
|
+
def use_lookup(
|
|
186
|
+
self,
|
|
187
|
+
node: ast.AstSymbolNode,
|
|
188
|
+
sym_table: Optional[SymbolTable] = None,
|
|
189
|
+
) -> Optional[Symbol]:
|
|
190
|
+
"""Link to symbol."""
|
|
191
|
+
if node.sym:
|
|
192
|
+
return node.sym
|
|
193
|
+
if not sym_table:
|
|
194
|
+
sym_table = node.sym_tab
|
|
195
|
+
if sym_table:
|
|
196
|
+
lookup = sym_table.lookup(name=node.sym_name, deep=True)
|
|
197
|
+
lookup.add_use(node.name_spec) if lookup else None
|
|
198
|
+
return node.sym
|
|
199
|
+
|
|
200
|
+
def chain_use_lookup(self, node_list: Sequence[ast.AstSymbolNode]) -> None:
|
|
201
|
+
"""Link chain of containing names to symbol."""
|
|
202
|
+
if not node_list:
|
|
203
|
+
return
|
|
204
|
+
cur_sym_tab: SymbolTable | None = node_list[0].sym_tab
|
|
205
|
+
for i in node_list:
|
|
206
|
+
if cur_sym_tab is None:
|
|
207
|
+
break
|
|
208
|
+
cur_sym_tab = (
|
|
209
|
+
lookup.decl.sym_tab
|
|
210
|
+
if (
|
|
211
|
+
lookup := self.use_lookup(
|
|
212
|
+
i,
|
|
213
|
+
sym_table=cur_sym_tab,
|
|
214
|
+
)
|
|
215
|
+
)
|
|
216
|
+
else None
|
|
217
|
+
)
|
|
218
|
+
|
|
219
|
+
def update_py_ctx_for_def(self, node: ast.AstSymbolNode) -> None:
|
|
220
|
+
"""Update python context for definition."""
|
|
221
|
+
node.name_spec.py_ctx_func = ast3.Store
|
|
222
|
+
if isinstance(node, (ast.TupleVal, ast.ListVal)) and node.values:
|
|
223
|
+
# Handling of UnaryExpr case for item is only necessary for
|
|
224
|
+
# the generation of Starred nodes in the AST for examples
|
|
225
|
+
# like `(a, *b) = (1, 2, 3, 4)`.
|
|
226
|
+
def fix(item: ast.TupleVal | ast.ListVal | ast.UnaryExpr) -> None:
|
|
227
|
+
if isinstance(item, ast.UnaryExpr):
|
|
228
|
+
if isinstance(item.operand, ast.AstSymbolNode):
|
|
229
|
+
item.operand.name_spec.py_ctx_func = ast3.Store
|
|
230
|
+
elif isinstance(item, (ast.TupleVal, ast.ListVal)):
|
|
231
|
+
for i in item.values.items if item.values else []:
|
|
232
|
+
if isinstance(i, ast.AstSymbolNode):
|
|
233
|
+
i.name_spec.py_ctx_func = ast3.Store
|
|
234
|
+
elif isinstance(i, ast.AtomTrailer):
|
|
235
|
+
self.chain_def_insert(i.as_attr_list)
|
|
236
|
+
if isinstance(i, (ast.TupleVal, ast.ListVal, ast.UnaryExpr)):
|
|
237
|
+
fix(i)
|
|
238
|
+
|
|
239
|
+
fix(node)
|
|
240
|
+
|
|
241
|
+
def inherit_baseclasses_sym(self, node: ast.Architype | ast.Enum) -> None:
|
|
242
|
+
"""Inherit base classes symbol tables."""
|
|
243
|
+
if node.base_classes:
|
|
244
|
+
for base_cls in node.base_classes.items:
|
|
245
|
+
if (
|
|
246
|
+
isinstance(base_cls, ast.AstSymbolNode)
|
|
247
|
+
and (found := self.use_lookup(base_cls))
|
|
248
|
+
and found
|
|
249
|
+
):
|
|
250
|
+
self.inherit.append(found.decl.sym_tab)
|
|
251
|
+
base_cls.name_spec.name_of = found.decl.name_of
|
|
252
|
+
|
|
212
253
|
def pp(self, depth: Optional[int] = None) -> str:
|
|
213
254
|
"""Pretty print."""
|
|
214
255
|
return print_symtab_tree(root=self, depth=depth)
|
|
@@ -102,9 +102,9 @@ class TestLarkParser(TestCaseMicroSuite):
|
|
|
102
102
|
"JacSource",
|
|
103
103
|
"EmptyToken",
|
|
104
104
|
"AstSymbolNode",
|
|
105
|
+
"AstSymbolStubNode",
|
|
105
106
|
"AstImplNeedingNode",
|
|
106
107
|
"AstAccessNode",
|
|
107
|
-
"TokenSymbol",
|
|
108
108
|
"Literal",
|
|
109
109
|
"AstDocNode",
|
|
110
110
|
"AstSemStrNode",
|
|
@@ -119,7 +119,7 @@ class TestLarkParser(TestCaseMicroSuite):
|
|
|
119
119
|
"ArchBlockStmt",
|
|
120
120
|
"EnumBlockStmt",
|
|
121
121
|
"CodeBlockStmt",
|
|
122
|
-
"
|
|
122
|
+
"NameAtom",
|
|
123
123
|
"ArchSpec",
|
|
124
124
|
"MatchPattern",
|
|
125
125
|
]
|
jaclang/core/aott.py
CHANGED
|
@@ -17,15 +17,19 @@ try:
|
|
|
17
17
|
except ImportError:
|
|
18
18
|
Image = None
|
|
19
19
|
|
|
20
|
-
from jaclang.
|
|
21
|
-
|
|
20
|
+
from jaclang.compiler.semtable import SemInfo, SemRegistry, SemScope
|
|
21
|
+
|
|
22
|
+
try:
|
|
23
|
+
from mtllm.llms import BaseLLM
|
|
24
|
+
except ImportError:
|
|
25
|
+
BaseLLM = None
|
|
22
26
|
|
|
23
27
|
|
|
24
28
|
IMG_FORMATS = ["PngImageFile", "JpegImageFile"]
|
|
25
29
|
|
|
26
30
|
|
|
27
31
|
def aott_raise(
|
|
28
|
-
model: BaseLLM,
|
|
32
|
+
model: BaseLLM, # type: ignore
|
|
29
33
|
information: str,
|
|
30
34
|
inputs_information: str | list[dict],
|
|
31
35
|
output_information: str,
|
|
@@ -108,7 +112,7 @@ def get_info_types(
|
|
|
108
112
|
else None
|
|
109
113
|
)
|
|
110
114
|
info_str.append(
|
|
111
|
-
f"{sem_info.semstr} ({sem_info.name}) ({sem_info.type}) = {get_object_string(incl[1])}"
|
|
115
|
+
f"{sem_info.semstr} ({sem_info.name}) ({sem_info.type}) = {get_object_string(incl[1])}".strip()
|
|
112
116
|
)
|
|
113
117
|
return ("\n".join(info_str), collected_types)
|
|
114
118
|
|
|
@@ -179,7 +183,7 @@ def get_type_explanation(
|
|
|
179
183
|
if sem_info.type == "Enum" and isinstance(type_info, list):
|
|
180
184
|
for enum_item in type_info:
|
|
181
185
|
type_info_str.append(
|
|
182
|
-
f"{enum_item.semstr} ({enum_item.name}) (EnumItem)"
|
|
186
|
+
f"{enum_item.semstr} ({enum_item.name}) (EnumItem)".strip()
|
|
183
187
|
)
|
|
184
188
|
type_example[0] = type_example[0].replace("(", f".{enum_item.name}")
|
|
185
189
|
elif sem_info.type in ["obj", "class", "node", "edge"] and isinstance(
|
|
@@ -189,7 +193,7 @@ def get_type_explanation(
|
|
|
189
193
|
if arch_item.type in ["obj", "class", "node", "edge"]:
|
|
190
194
|
continue
|
|
191
195
|
type_info_str.append(
|
|
192
|
-
f"{arch_item.semstr} ({arch_item.name}) ({arch_item.type})"
|
|
196
|
+
f"{arch_item.semstr} ({arch_item.name}) ({arch_item.type})".strip()
|
|
193
197
|
)
|
|
194
198
|
type_example.append(f"{arch_item.name}={arch_item.type}, ")
|
|
195
199
|
if arch_item.type and extract_non_primary_type(arch_item.type):
|
|
@@ -199,7 +203,7 @@ def get_type_explanation(
|
|
|
199
203
|
else:
|
|
200
204
|
type_example.append(")")
|
|
201
205
|
return (
|
|
202
|
-
f"{sem_info.semstr} ({sem_info.name}) ({sem_info.type}) eg:- {''.join(type_example)} -> {', '.join(type_info_str)}", # noqa: E501
|
|
206
|
+
f"{sem_info.semstr} ({sem_info.name}) ({sem_info.type}) eg:- {''.join(type_example)} -> {', '.join(type_info_str)}".strip(), # noqa: E501
|
|
203
207
|
set(type_info_types),
|
|
204
208
|
)
|
|
205
209
|
return None, None
|
|
@@ -270,7 +274,7 @@ def get_input_information(
|
|
|
270
274
|
typ_anno = get_type_annotation(i[3])
|
|
271
275
|
type_collector.extend(extract_non_primary_type(typ_anno))
|
|
272
276
|
inputs_information_list.append(
|
|
273
|
-
f"{i[0]} ({i[2]}) ({typ_anno}) = {get_object_string(i[3])}"
|
|
277
|
+
f"{i[0] if i[0] else ''} ({i[2]}) ({typ_anno}) = {get_object_string(i[3])}".strip()
|
|
274
278
|
)
|
|
275
279
|
return "\n".join(inputs_information_list)
|
|
276
280
|
else:
|
|
@@ -281,7 +285,7 @@ def get_input_information(
|
|
|
281
285
|
image_repr: list[dict] = [
|
|
282
286
|
{
|
|
283
287
|
"type": "text",
|
|
284
|
-
"text": f"{i[0]} ({i[2]}) (Image) = ",
|
|
288
|
+
"text": f"{i[0] if i[0] else ''} ({i[2]}) (Image) = ".strip(),
|
|
285
289
|
},
|
|
286
290
|
{"type": "image_url", "image_url": {"url": img_base64}},
|
|
287
291
|
]
|
|
@@ -292,13 +296,13 @@ def get_input_information(
|
|
|
292
296
|
inputs_information_dict_list.append(
|
|
293
297
|
{
|
|
294
298
|
"type": "text",
|
|
295
|
-
"text": f"{i[0]} ({i[2]}) ({typ_anno}) = {get_object_string(i[3])}",
|
|
299
|
+
"text": f"{i[0] if i[0] else ''} ({i[2]}) ({typ_anno}) = {get_object_string(i[3])}".strip(),
|
|
296
300
|
}
|
|
297
301
|
)
|
|
298
302
|
return inputs_information_dict_list
|
|
299
303
|
|
|
300
304
|
|
|
301
|
-
def image_to_base64(image: Image) -> str:
|
|
305
|
+
def image_to_base64(image: Image) -> str: # type: ignore
|
|
302
306
|
"""Convert an image to base64 expected by OpenAI."""
|
|
303
307
|
if not Image:
|
|
304
308
|
log = logging.getLogger(__name__)
|