jaclang 0.7.1__py3-none-any.whl → 0.7.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/compiler/absyntree.py +51 -14
- jaclang/compiler/passes/main/def_impl_match_pass.py +9 -3
- jaclang/compiler/passes/main/fuse_typeinfo_pass.py +20 -1
- jaclang/compiler/passes/main/import_pass.py +4 -1
- jaclang/compiler/passes/main/pyast_gen_pass.py +14 -6
- jaclang/compiler/passes/main/pyast_load_pass.py +2 -1
- jaclang/compiler/passes/main/pyjac_ast_link_pass.py +6 -1
- jaclang/compiler/passes/main/pyout_pass.py +3 -1
- jaclang/compiler/passes/main/tests/test_import_pass.py +8 -0
- jaclang/compiler/passes/main/tests/test_type_check_pass.py +1 -1
- jaclang/compiler/passes/tool/jac_formatter_pass.py +14 -2
- jaclang/compiler/passes/tool/tests/fixtures/doc_string.jac +15 -0
- jaclang/compiler/passes/tool/tests/test_jac_format_pass.py +7 -5
- jaclang/compiler/passes/tool/tests/test_unparse_validate.py +1 -2
- jaclang/compiler/symtable.py +21 -1
- jaclang/core/aott.py +107 -11
- jaclang/core/construct.py +171 -5
- jaclang/core/llms/anthropic.py +31 -2
- jaclang/core/llms/base.py +3 -3
- jaclang/core/llms/groq.py +4 -1
- jaclang/core/llms/huggingface.py +4 -1
- jaclang/core/llms/ollama.py +4 -1
- jaclang/core/llms/openai.py +6 -2
- jaclang/core/llms/togetherai.py +4 -1
- jaclang/langserve/engine.py +99 -115
- jaclang/langserve/server.py +27 -5
- jaclang/langserve/tests/fixtures/circle_pure.impl.jac +8 -4
- jaclang/langserve/tests/fixtures/circle_pure.jac +2 -2
- jaclang/langserve/tests/test_server.py +123 -0
- jaclang/langserve/utils.py +100 -10
- jaclang/plugin/default.py +25 -83
- jaclang/plugin/feature.py +10 -12
- jaclang/plugin/tests/test_features.py +0 -33
- jaclang/settings.py +1 -0
- jaclang/tests/fixtures/byllmissue.jac +3 -0
- jaclang/tests/fixtures/hash_init_check.jac +17 -0
- jaclang/tests/fixtures/math_question.jpg +0 -0
- jaclang/tests/fixtures/nosigself.jac +19 -0
- jaclang/tests/fixtures/walker_override.jac +21 -0
- jaclang/tests/fixtures/with_llm_vision.jac +25 -0
- jaclang/tests/test_language.py +61 -11
- jaclang/utils/treeprinter.py +19 -2
- {jaclang-0.7.1.dist-info → jaclang-0.7.2.dist-info}/METADATA +3 -2
- {jaclang-0.7.1.dist-info → jaclang-0.7.2.dist-info}/RECORD +46 -41
- jaclang/core/memory.py +0 -48
- jaclang/core/shelve_storage.py +0 -55
- {jaclang-0.7.1.dist-info → jaclang-0.7.2.dist-info}/WHEEL +0 -0
- {jaclang-0.7.1.dist-info → jaclang-0.7.2.dist-info}/entry_points.txt +0 -0
jaclang/compiler/absyntree.py
CHANGED
|
@@ -3,6 +3,7 @@
|
|
|
3
3
|
from __future__ import annotations
|
|
4
4
|
|
|
5
5
|
import ast as ast3
|
|
6
|
+
import os
|
|
6
7
|
from hashlib import md5
|
|
7
8
|
from types import EllipsisType
|
|
8
9
|
from typing import Any, Callable, Generic, Optional, Sequence, Type, TypeVar
|
|
@@ -31,7 +32,6 @@ class AstNode:
|
|
|
31
32
|
self.kid: list[AstNode] = [x.set_parent(self) for x in kid]
|
|
32
33
|
self.sym_tab: Optional[SymbolTable] = None
|
|
33
34
|
self._sub_node_tab: dict[type, list[AstNode]] = {}
|
|
34
|
-
self._typ: type = type(None)
|
|
35
35
|
self.gen: CodeGenTarget = CodeGenTarget()
|
|
36
36
|
self.meta: dict[str, str] = {}
|
|
37
37
|
self.loc: CodeLocInfo = CodeLocInfo(*self.resolve_tok_range())
|
|
@@ -111,11 +111,15 @@ class AstNode:
|
|
|
111
111
|
|
|
112
112
|
return Pass.get_all_sub_nodes(node=self, typ=typ, brute_force=brute_force)
|
|
113
113
|
|
|
114
|
-
def
|
|
114
|
+
def find_parent_of_type(self, typ: Type[T]) -> Optional[T]:
|
|
115
115
|
"""Get parent of type."""
|
|
116
116
|
from jaclang.compiler.passes import Pass
|
|
117
117
|
|
|
118
|
-
|
|
118
|
+
return Pass.has_parent_of_type(node=self, typ=typ)
|
|
119
|
+
|
|
120
|
+
def parent_of_type(self, typ: Type[T]) -> T:
|
|
121
|
+
"""Get parent of type."""
|
|
122
|
+
ret = self.find_parent_of_type(typ)
|
|
119
123
|
if isinstance(ret, typ):
|
|
120
124
|
return ret
|
|
121
125
|
else:
|
|
@@ -178,6 +182,8 @@ class AstSymbolNode(AstNode):
|
|
|
178
182
|
self.sym_link: Optional[Symbol] = None
|
|
179
183
|
self.sym_name: str = sym_name
|
|
180
184
|
self.sym_name_node = sym_name_node
|
|
185
|
+
if isinstance(self.sym_name_node, NameSpec):
|
|
186
|
+
self.sym_name_node.name_of = self
|
|
181
187
|
self.sym_type: SymbolType = sym_type
|
|
182
188
|
self.sym_info: SymbolInfo = SymbolInfo()
|
|
183
189
|
self.py_ctx_func: Type[ast3.AST] = ast3.Load
|
|
@@ -258,8 +264,11 @@ class WalkerStmtOnlyNode(AstNode):
|
|
|
258
264
|
class AstImplOnlyNode(AstNode):
|
|
259
265
|
"""ImplOnly node type for Jac Ast."""
|
|
260
266
|
|
|
261
|
-
def __init__(
|
|
267
|
+
def __init__(
|
|
268
|
+
self, target: ArchRefChain, body: SubNodeList, decl_link: Optional[AstNode]
|
|
269
|
+
) -> None:
|
|
262
270
|
"""Initialize impl only node."""
|
|
271
|
+
self.target = target
|
|
263
272
|
self.body = body
|
|
264
273
|
self.decl_link = decl_link
|
|
265
274
|
|
|
@@ -304,6 +313,10 @@ class CodeBlockStmt(AstNode):
|
|
|
304
313
|
class NameSpec(AtomExpr, EnumBlockStmt):
|
|
305
314
|
"""NameSpec node type for Jac Ast."""
|
|
306
315
|
|
|
316
|
+
def __init__(self) -> None:
|
|
317
|
+
"""Initialize name spec node."""
|
|
318
|
+
self.name_of: AstSymbolNode = self
|
|
319
|
+
|
|
307
320
|
|
|
308
321
|
class ArchSpec(ElementStmt, CodeBlockStmt, AstSymbolNode, AstDocNode, AstSemStrNode):
|
|
309
322
|
"""ArchSpec node type for Jac Ast."""
|
|
@@ -392,7 +405,7 @@ class Module(AstDocNode):
|
|
|
392
405
|
body: Sequence[ElementStmt | String | EmptyToken],
|
|
393
406
|
is_imported: bool,
|
|
394
407
|
kid: Sequence[AstNode],
|
|
395
|
-
|
|
408
|
+
stub_only: bool = False,
|
|
396
409
|
registry: Optional[SemRegistry] = None,
|
|
397
410
|
) -> None:
|
|
398
411
|
"""Initialize whole program node."""
|
|
@@ -400,13 +413,37 @@ class Module(AstDocNode):
|
|
|
400
413
|
self.source = source
|
|
401
414
|
self.body = body
|
|
402
415
|
self.is_imported = is_imported
|
|
416
|
+
self.stub_only = stub_only
|
|
403
417
|
self.impl_mod: list[Module] = []
|
|
404
|
-
self.test_mod =
|
|
418
|
+
self.test_mod: list[Module] = []
|
|
405
419
|
self.mod_deps: dict[str, Module] = {}
|
|
406
420
|
self.registry = registry
|
|
407
421
|
AstNode.__init__(self, kid=kid)
|
|
408
422
|
AstDocNode.__init__(self, doc=doc)
|
|
409
423
|
|
|
424
|
+
@property
|
|
425
|
+
def annexable_by(self) -> Optional[str]:
|
|
426
|
+
"""Get annexable by."""
|
|
427
|
+
if not self.stub_only and self.loc.mod_path.endswith("impl.jac"):
|
|
428
|
+
head_mod_name = self.name.split(".")[0]
|
|
429
|
+
potential_path = os.path.join(
|
|
430
|
+
os.path.dirname(self.loc.mod_path),
|
|
431
|
+
f"{head_mod_name}.jac",
|
|
432
|
+
)
|
|
433
|
+
if os.path.exists(potential_path):
|
|
434
|
+
return potential_path
|
|
435
|
+
if os.path.split(os.path.dirname(self.loc.mod_path))[-1].endswith(".impl"):
|
|
436
|
+
head_mod_name = os.path.split(os.path.dirname(self.loc.mod_path))[
|
|
437
|
+
-1
|
|
438
|
+
].split(".")[0]
|
|
439
|
+
potential_path = os.path.join(
|
|
440
|
+
os.path.dirname(os.path.dirname(self.loc.mod_path)),
|
|
441
|
+
f"{head_mod_name}.jac",
|
|
442
|
+
)
|
|
443
|
+
if os.path.exists(potential_path):
|
|
444
|
+
return potential_path
|
|
445
|
+
return None
|
|
446
|
+
|
|
410
447
|
def normalize(self, deep: bool = False) -> bool:
|
|
411
448
|
"""Normalize module node."""
|
|
412
449
|
res = True
|
|
@@ -841,7 +878,6 @@ class ArchDef(ArchSpec, AstImplOnlyNode):
|
|
|
841
878
|
decl_link: Optional[Architype] = None,
|
|
842
879
|
) -> None:
|
|
843
880
|
"""Initialize arch def node."""
|
|
844
|
-
self.target = target
|
|
845
881
|
AstNode.__init__(self, kid=kid)
|
|
846
882
|
AstSymbolNode.__init__(
|
|
847
883
|
self,
|
|
@@ -851,7 +887,7 @@ class ArchDef(ArchSpec, AstImplOnlyNode):
|
|
|
851
887
|
)
|
|
852
888
|
AstDocNode.__init__(self, doc=doc)
|
|
853
889
|
ArchSpec.__init__(self, decorators=decorators)
|
|
854
|
-
AstImplOnlyNode.__init__(self, body=body, decl_link=decl_link)
|
|
890
|
+
AstImplOnlyNode.__init__(self, target=target, body=body, decl_link=decl_link)
|
|
855
891
|
|
|
856
892
|
def normalize(self, deep: bool = False) -> bool:
|
|
857
893
|
"""Normalize arch def node."""
|
|
@@ -952,7 +988,6 @@ class EnumDef(ArchSpec, AstImplOnlyNode):
|
|
|
952
988
|
decl_link: Optional[Enum] = None,
|
|
953
989
|
) -> None:
|
|
954
990
|
"""Initialize arch def node."""
|
|
955
|
-
self.target = target
|
|
956
991
|
AstNode.__init__(self, kid=kid)
|
|
957
992
|
AstSymbolNode.__init__(
|
|
958
993
|
self,
|
|
@@ -962,7 +997,7 @@ class EnumDef(ArchSpec, AstImplOnlyNode):
|
|
|
962
997
|
)
|
|
963
998
|
AstDocNode.__init__(self, doc=doc)
|
|
964
999
|
ArchSpec.__init__(self, decorators=decorators)
|
|
965
|
-
AstImplOnlyNode.__init__(self, body=body, decl_link=decl_link)
|
|
1000
|
+
AstImplOnlyNode.__init__(self, target=target, body=body, decl_link=decl_link)
|
|
966
1001
|
|
|
967
1002
|
def normalize(self, deep: bool = False) -> bool:
|
|
968
1003
|
"""Normalize enum def node."""
|
|
@@ -1002,7 +1037,7 @@ class Ability(
|
|
|
1002
1037
|
is_static: bool,
|
|
1003
1038
|
is_abstract: bool,
|
|
1004
1039
|
access: Optional[SubTag[Token]],
|
|
1005
|
-
signature:
|
|
1040
|
+
signature: FuncSignature | EventSignature,
|
|
1006
1041
|
body: Optional[SubNodeList[CodeBlockStmt] | AbilityDef | FuncCall],
|
|
1007
1042
|
kid: Sequence[AstNode],
|
|
1008
1043
|
semstr: Optional[String] = None,
|
|
@@ -1111,7 +1146,6 @@ class AbilityDef(AstSymbolNode, ElementStmt, AstImplOnlyNode, CodeBlockStmt):
|
|
|
1111
1146
|
decl_link: Optional[Ability] = None,
|
|
1112
1147
|
) -> None:
|
|
1113
1148
|
"""Initialize ability def node."""
|
|
1114
|
-
self.target = target
|
|
1115
1149
|
self.signature = signature
|
|
1116
1150
|
self.decorators = decorators
|
|
1117
1151
|
AstNode.__init__(self, kid=kid)
|
|
@@ -1122,7 +1156,7 @@ class AbilityDef(AstSymbolNode, ElementStmt, AstImplOnlyNode, CodeBlockStmt):
|
|
|
1122
1156
|
sym_type=SymbolType.IMPL,
|
|
1123
1157
|
)
|
|
1124
1158
|
AstDocNode.__init__(self, doc=doc)
|
|
1125
|
-
AstImplOnlyNode.__init__(self, body=body, decl_link=decl_link)
|
|
1159
|
+
AstImplOnlyNode.__init__(self, target=target, body=body, decl_link=decl_link)
|
|
1126
1160
|
|
|
1127
1161
|
def normalize(self, deep: bool = False) -> bool:
|
|
1128
1162
|
"""Normalize ability def node."""
|
|
@@ -1394,7 +1428,7 @@ class HasVar(AstSymbolNode, AstTypedVarNode, AstSemStrNode):
|
|
|
1394
1428
|
self,
|
|
1395
1429
|
sym_name=name.value,
|
|
1396
1430
|
sym_name_node=name,
|
|
1397
|
-
sym_type=SymbolType.
|
|
1431
|
+
sym_type=SymbolType.HAS_VAR,
|
|
1398
1432
|
)
|
|
1399
1433
|
AstTypedVarNode.__init__(self, type_tag=type_tag)
|
|
1400
1434
|
AstSemStrNode.__init__(self, semstr=semstr)
|
|
@@ -3066,6 +3100,7 @@ class ArchRef(NameSpec):
|
|
|
3066
3100
|
sym_name_node=name_ref,
|
|
3067
3101
|
sym_type=SymbolType.TYPE,
|
|
3068
3102
|
)
|
|
3103
|
+
NameSpec.__init__(self)
|
|
3069
3104
|
|
|
3070
3105
|
def normalize(self, deep: bool = False) -> bool:
|
|
3071
3106
|
"""Normalize ast node."""
|
|
@@ -3103,6 +3138,7 @@ class SpecialVarRef(NameSpec):
|
|
|
3103
3138
|
sym_name_node=var,
|
|
3104
3139
|
sym_type=SymbolType.VAR,
|
|
3105
3140
|
)
|
|
3141
|
+
NameSpec.__init__(self)
|
|
3106
3142
|
|
|
3107
3143
|
def normalize(self, deep: bool = False) -> bool:
|
|
3108
3144
|
"""Normalize ast node."""
|
|
@@ -3786,6 +3822,7 @@ class Name(Token, NameSpec):
|
|
|
3786
3822
|
sym_name_node=self,
|
|
3787
3823
|
sym_type=SymbolType.VAR,
|
|
3788
3824
|
)
|
|
3825
|
+
NameSpec.__init__(self)
|
|
3789
3826
|
|
|
3790
3827
|
def unparse(self) -> str:
|
|
3791
3828
|
"""Unparse name."""
|
|
@@ -9,7 +9,7 @@ body field.
|
|
|
9
9
|
import jaclang.compiler.absyntree as ast
|
|
10
10
|
from jaclang.compiler.passes import Pass
|
|
11
11
|
from jaclang.compiler.passes.main import SubNodeTabPass
|
|
12
|
-
from jaclang.compiler.symtable import Symbol, SymbolTable
|
|
12
|
+
from jaclang.compiler.symtable import Symbol, SymbolTable
|
|
13
13
|
|
|
14
14
|
|
|
15
15
|
class DeclImplMatchPass(Pass):
|
|
@@ -39,11 +39,12 @@ class DeclImplMatchPass(Pass):
|
|
|
39
39
|
def connect_def_impl(self, sym_tab: SymbolTable) -> None:
|
|
40
40
|
"""Connect Decls and Defs."""
|
|
41
41
|
for sym in sym_tab.tab.values():
|
|
42
|
-
if sym.
|
|
42
|
+
if isinstance(sym.decl, ast.AstImplOnlyNode):
|
|
43
43
|
# currently strips the type info from impls
|
|
44
44
|
arch_refs = [x[3:] for x in sym.sym_name.split(".")]
|
|
45
|
+
name_of_links = [] # to link archref names to decls
|
|
45
46
|
lookup = sym_tab.lookup(arch_refs[0])
|
|
46
|
-
#
|
|
47
|
+
# If below may need to be a while instead of if to skip over local
|
|
47
48
|
# import name collisions (see test: test_impl_decl_resolution_fix)
|
|
48
49
|
if lookup and not isinstance(lookup.decl, ast.AstImplNeedingNode):
|
|
49
50
|
lookup = sym_tab.parent.lookup(arch_refs[0])
|
|
@@ -52,6 +53,7 @@ class DeclImplMatchPass(Pass):
|
|
|
52
53
|
if len(arch_refs) == 1 and lookup
|
|
53
54
|
else lookup.defn[-1] if lookup else None
|
|
54
55
|
)
|
|
56
|
+
name_of_links.append(decl_node) if decl_node else None
|
|
55
57
|
for name in arch_refs[1:]:
|
|
56
58
|
if decl_node:
|
|
57
59
|
lookup = (
|
|
@@ -64,6 +66,7 @@ class DeclImplMatchPass(Pass):
|
|
|
64
66
|
if len(arch_refs) == 1 and lookup
|
|
65
67
|
else lookup.defn[-1] if lookup else None
|
|
66
68
|
)
|
|
69
|
+
name_of_links.append(decl_node) if decl_node else None
|
|
67
70
|
else:
|
|
68
71
|
break
|
|
69
72
|
if not decl_node:
|
|
@@ -76,6 +79,9 @@ class DeclImplMatchPass(Pass):
|
|
|
76
79
|
continue
|
|
77
80
|
decl_node.body = sym.decl # type: ignore
|
|
78
81
|
sym.decl.decl_link = decl_node # type: ignore
|
|
82
|
+
for idx, a in enumerate(sym.decl.target.archs):
|
|
83
|
+
if isinstance(a.name_ref.sym_name_node, ast.NameSpec):
|
|
84
|
+
a.name_ref.sym_name_node.name_of = name_of_links[idx]
|
|
79
85
|
decl_node.sym_tab.tab = sym.decl.sym_tab.tab # type: ignore
|
|
80
86
|
for i in sym_tab.kid:
|
|
81
87
|
self.connect_def_impl(i)
|
|
@@ -129,8 +129,10 @@ class FuseTypeInfoPass(Pass):
|
|
|
129
129
|
if isinstance(mypy_node, MypyNodes.MemberExpr):
|
|
130
130
|
if mypy_node in self.node_type_hash:
|
|
131
131
|
t = str(self.node_type_hash[mypy_node])
|
|
132
|
-
if "->" in t:
|
|
132
|
+
if "def" in t and "->" in t:
|
|
133
133
|
t = t.split("->")[1].strip()
|
|
134
|
+
elif "def" in t:
|
|
135
|
+
t = "None"
|
|
134
136
|
node.sym_info.typ = t
|
|
135
137
|
else:
|
|
136
138
|
self.__debug_print(f"{node.loc} MemberExpr type is not found")
|
|
@@ -181,6 +183,18 @@ class FuseTypeInfoPass(Pass):
|
|
|
181
183
|
"""Pass handler for name nodes."""
|
|
182
184
|
self.__collect_type_from_symbol(node)
|
|
183
185
|
|
|
186
|
+
# Assign correct symbols to sym_link in case of
|
|
187
|
+
# AtomTrailer Object
|
|
188
|
+
if isinstance(node.parent, ast.AtomTrailer):
|
|
189
|
+
target_node = node.parent.target
|
|
190
|
+
if isinstance(target_node, ast.AstSymbolNode):
|
|
191
|
+
parent_symbol_table = target_node.sym_info.typ_sym_table
|
|
192
|
+
if isinstance(parent_symbol_table, ast.SymbolTable):
|
|
193
|
+
owner = parent_symbol_table.owner
|
|
194
|
+
if isinstance(owner, ast.AstSymbolNode):
|
|
195
|
+
target_node.sym_link = owner.sym_link
|
|
196
|
+
node.sym_link = parent_symbol_table.lookup(node.sym_name)
|
|
197
|
+
|
|
184
198
|
@__handle_node
|
|
185
199
|
def enter_module_path(self, node: ast.ModulePath) -> None:
|
|
186
200
|
"""Pass handler for ModulePath nodes."""
|
|
@@ -263,6 +277,11 @@ class FuseTypeInfoPass(Pass):
|
|
|
263
277
|
"Getting type of 'HasVar' is only supported with AssignmentStmt"
|
|
264
278
|
)
|
|
265
279
|
|
|
280
|
+
def exit_has_var(self, node: ast.HasVar) -> None:
|
|
281
|
+
"""Pass handler for HasVar nodes."""
|
|
282
|
+
node.sym_info.typ = node.name.sym_info.typ
|
|
283
|
+
node.sym_info.typ_sym_table = node.name.sym_info.typ_sym_table
|
|
284
|
+
|
|
266
285
|
@__handle_node
|
|
267
286
|
def enter_multi_string(self, node: ast.MultiString) -> None:
|
|
268
287
|
"""Pass handler for MultiString nodes."""
|
|
@@ -63,6 +63,8 @@ class JacImportPass(Pass):
|
|
|
63
63
|
|
|
64
64
|
def __annex_impl(self, node: ast.Module) -> None:
|
|
65
65
|
"""Annex impl and test modules."""
|
|
66
|
+
if node.stub_only:
|
|
67
|
+
return
|
|
66
68
|
if not node.loc.mod_path:
|
|
67
69
|
self.error("Module has no path")
|
|
68
70
|
if not node.loc.mod_path.endswith(".jac"):
|
|
@@ -105,7 +107,7 @@ class JacImportPass(Pass):
|
|
|
105
107
|
) and cur_file.endswith(".test.jac"):
|
|
106
108
|
mod = self.import_jac_mod_from_file(cur_file)
|
|
107
109
|
if mod:
|
|
108
|
-
node.test_mod
|
|
110
|
+
node.test_mod.append(mod)
|
|
109
111
|
node.add_kids_right([mod], pos_update=False)
|
|
110
112
|
mod.parent = node
|
|
111
113
|
|
|
@@ -167,6 +169,7 @@ class JacImportPass(Pass):
|
|
|
167
169
|
doc=None,
|
|
168
170
|
body=[],
|
|
169
171
|
is_imported=False,
|
|
172
|
+
stub_only=True,
|
|
170
173
|
kid=[ast.EmptyToken()],
|
|
171
174
|
)
|
|
172
175
|
|
|
@@ -54,6 +54,13 @@ class PyastGenPass(Pass):
|
|
|
54
54
|
)
|
|
55
55
|
]
|
|
56
56
|
|
|
57
|
+
def enter_node(self, node: ast.AstNode) -> None:
|
|
58
|
+
"""Enter node."""
|
|
59
|
+
if node.gen.py_ast:
|
|
60
|
+
self.prune()
|
|
61
|
+
return
|
|
62
|
+
super().enter_node(node)
|
|
63
|
+
|
|
57
64
|
def exit_node(self, node: ast.AstNode) -> None:
|
|
58
65
|
"""Exit node."""
|
|
59
66
|
super().exit_node(node)
|
|
@@ -325,7 +332,8 @@ class PyastGenPass(Pass):
|
|
|
325
332
|
for pbody in node.impl_mod:
|
|
326
333
|
pre_body = [*pre_body, *pbody.body]
|
|
327
334
|
pre_body = [*pre_body, *clean_body]
|
|
328
|
-
|
|
335
|
+
for pbody in node.test_mod:
|
|
336
|
+
pre_body = [*pre_body, *pbody.body]
|
|
329
337
|
body = (
|
|
330
338
|
[
|
|
331
339
|
self.sync(ast3.Expr(value=node.doc.gen.py_ast[0]), jac_node=node.doc),
|
|
@@ -676,9 +684,9 @@ class PyastGenPass(Pass):
|
|
|
676
684
|
if isinstance(node.body, ast.ArchDef)
|
|
677
685
|
else node.body.items if node.body else []
|
|
678
686
|
):
|
|
679
|
-
if isinstance(i, ast.Ability)
|
|
687
|
+
if isinstance(i, ast.Ability):
|
|
680
688
|
self.method_sigs.append(i.signature)
|
|
681
|
-
if isinstance(node.body, ast.
|
|
689
|
+
if isinstance(node.body, ast.AstImplOnlyNode):
|
|
682
690
|
self.traverse(node.body)
|
|
683
691
|
|
|
684
692
|
def exit_architype(self, node: ast.Architype) -> None:
|
|
@@ -854,7 +862,7 @@ class PyastGenPass(Pass):
|
|
|
854
862
|
doc: Optional[String],
|
|
855
863
|
decorators: Optional[SubNodeList[ExprType]],
|
|
856
864
|
"""
|
|
857
|
-
if isinstance(node.body, ast.
|
|
865
|
+
if isinstance(node.body, ast.AstImplOnlyNode):
|
|
858
866
|
self.traverse(node.body)
|
|
859
867
|
|
|
860
868
|
def exit_enum(self, node: ast.Enum) -> None:
|
|
@@ -920,7 +928,7 @@ class PyastGenPass(Pass):
|
|
|
920
928
|
doc: Optional[String],
|
|
921
929
|
decorators: Optional[SubNodeList[ExprType]],
|
|
922
930
|
"""
|
|
923
|
-
if isinstance(node.body, ast.
|
|
931
|
+
if isinstance(node.body, ast.AstImplOnlyNode):
|
|
924
932
|
self.traverse(node.body)
|
|
925
933
|
|
|
926
934
|
def exit_ability(self, node: ast.Ability) -> None:
|
|
@@ -1096,7 +1104,7 @@ class PyastGenPass(Pass):
|
|
|
1096
1104
|
action = (
|
|
1097
1105
|
node.semstr.gen.py_ast[0]
|
|
1098
1106
|
if node.semstr
|
|
1099
|
-
else self.sync(ast3.Constant(value=
|
|
1107
|
+
else self.sync(ast3.Constant(value=node.name_ref.sym_name))
|
|
1100
1108
|
)
|
|
1101
1109
|
return [
|
|
1102
1110
|
self.sync(
|
|
@@ -127,7 +127,6 @@ class PyastBuildPass(Pass[ast.PythonModuleAst]):
|
|
|
127
127
|
is_imported=False,
|
|
128
128
|
kid=valid,
|
|
129
129
|
)
|
|
130
|
-
ret.gen.py_ast = [node]
|
|
131
130
|
return self.nu(ret)
|
|
132
131
|
|
|
133
132
|
def proc_function_def(
|
|
@@ -209,6 +208,8 @@ class PyastBuildPass(Pass[ast.PythonModuleAst]):
|
|
|
209
208
|
kid = ([doc] if doc else []) + (
|
|
210
209
|
[name, sig, valid_body] if sig else [name, valid_body]
|
|
211
210
|
)
|
|
211
|
+
if not sig:
|
|
212
|
+
raise self.ice("Function signature not found")
|
|
212
213
|
ret = ast.Ability(
|
|
213
214
|
name_ref=name,
|
|
214
215
|
is_async=False,
|
|
@@ -1,4 +1,9 @@
|
|
|
1
|
-
"""Jac to python ast link pass.
|
|
1
|
+
"""Jac to python ast link pass.
|
|
2
|
+
|
|
3
|
+
This pass is needed so cases where there are multiple Jac nodes relevant to a
|
|
4
|
+
single python node can be linked. For example FuncDef doesn't have a Name node
|
|
5
|
+
however Ability does.
|
|
6
|
+
"""
|
|
2
7
|
|
|
3
8
|
import ast as ast3
|
|
4
9
|
|
|
@@ -35,7 +35,9 @@ class PyOutPass(Pass):
|
|
|
35
35
|
f"Unable to find module {node.loc.mod_path} or no code present.", node
|
|
36
36
|
)
|
|
37
37
|
return
|
|
38
|
-
mods = [node] +
|
|
38
|
+
mods = [node] + [
|
|
39
|
+
i for i in self.get_all_sub_nodes(node, ast.Module) if not i.stub_only
|
|
40
|
+
]
|
|
39
41
|
for mod in mods:
|
|
40
42
|
mod_path, out_path_py, out_path_pyc = self.get_output_targets(mod)
|
|
41
43
|
if os.path.exists(out_path_pyc) and os.path.getmtime(
|
|
@@ -41,3 +41,11 @@ class ImportPassPassTests(TestCase):
|
|
|
41
41
|
self.assertIn("autoimpl", mod_names)
|
|
42
42
|
self.assertIn("autoimpl.impl", mod_names)
|
|
43
43
|
self.assertIn("autoimpl.something.else.impl", mod_names)
|
|
44
|
+
|
|
45
|
+
def test_annexalbe_by_discovery(self) -> None:
|
|
46
|
+
"""Basic test for pass."""
|
|
47
|
+
state = jac_file_to_pass(
|
|
48
|
+
self.fixture_abs_path("incautoimpl.jac"), JacImportPass
|
|
49
|
+
)
|
|
50
|
+
for i in state.ir.get_all_sub_nodes(ast.Module):
|
|
51
|
+
self.assertEqual(i.annexable_by, self.fixture_abs_path("autoimpl.jac"))
|
|
@@ -59,6 +59,6 @@ class MypyTypeCheckPassTests(TestCase):
|
|
|
59
59
|
self.assertIn("HasVar - species - Type: builtins.str", out)
|
|
60
60
|
self.assertIn("myDog - Type: type_info.Dog", out)
|
|
61
61
|
self.assertIn("Body - Type: type_info.Dog.Body", out)
|
|
62
|
-
self.assertEqual(out.count("Type: builtins.str"),
|
|
62
|
+
self.assertEqual(out.count("Type: builtins.str"), 28)
|
|
63
63
|
for i in lis:
|
|
64
64
|
self.assertNotIn(i, out)
|
|
@@ -421,7 +421,10 @@ class JacFormatPass(Pass):
|
|
|
421
421
|
self.emit_ln(node, "")
|
|
422
422
|
self.emit_ln(node, i.gen.jac)
|
|
423
423
|
if isinstance(i, ast.Token) and i.name == Tok.KW_BY:
|
|
424
|
-
|
|
424
|
+
if not node.params:
|
|
425
|
+
self.emit(node, f"{i.gen.jac} ")
|
|
426
|
+
else:
|
|
427
|
+
self.emit(node, f" {i.gen.jac} ")
|
|
425
428
|
else:
|
|
426
429
|
if (
|
|
427
430
|
line_break_needed
|
|
@@ -2402,7 +2405,16 @@ class JacFormatPass(Pass):
|
|
|
2402
2405
|
and isinstance(node.parent.parent, ast.FString)
|
|
2403
2406
|
):
|
|
2404
2407
|
self.emit(node, node.value)
|
|
2405
|
-
|
|
2408
|
+
if "\n" in node.value:
|
|
2409
|
+
string_type = node.value[0:3]
|
|
2410
|
+
pure_string = node.value[3:-3]
|
|
2411
|
+
lines = pure_string.split("\n")
|
|
2412
|
+
self.emit(node, string_type)
|
|
2413
|
+
for line in lines[:-1]:
|
|
2414
|
+
self.emit_ln(node, line)
|
|
2415
|
+
self.emit_ln(node, f"{lines[-1]}{string_type}")
|
|
2416
|
+
else:
|
|
2417
|
+
self.emit(node, node.value)
|
|
2406
2418
|
|
|
2407
2419
|
def enter_bool(self, node: ast.Bool) -> None:
|
|
2408
2420
|
"""Sub objects.
|
|
@@ -44,8 +44,8 @@ class JacFormatPassTests(TestCaseMicroSuite, AstSyncTestMixin):
|
|
|
44
44
|
|
|
45
45
|
if diff:
|
|
46
46
|
print(f"Differences found in comparison:\n{diff}")
|
|
47
|
-
|
|
48
|
-
|
|
47
|
+
raise AssertionError("Files differ after formatting.")
|
|
48
|
+
|
|
49
49
|
except FileNotFoundError:
|
|
50
50
|
print(f"File not found: {original_file} or {formatted_file}")
|
|
51
51
|
raise
|
|
@@ -76,6 +76,9 @@ class JacFormatPassTests(TestCaseMicroSuite, AstSyncTestMixin):
|
|
|
76
76
|
self.compare_files(
|
|
77
77
|
os.path.join(self.fixture_abs_path(""), "corelib_fmt.jac"),
|
|
78
78
|
)
|
|
79
|
+
self.compare_files(
|
|
80
|
+
os.path.join(self.fixture_abs_path(""), "doc_string.jac"),
|
|
81
|
+
)
|
|
79
82
|
|
|
80
83
|
def test_compare_myca_fixtures(self) -> None:
|
|
81
84
|
"""Tests if files in the myca fixtures directory do not change after being formatted."""
|
|
@@ -135,14 +138,13 @@ class JacFormatPassTests(TestCaseMicroSuite, AstSyncTestMixin):
|
|
|
135
138
|
diff = "\n".join(unified_diff(before.splitlines(), after.splitlines()))
|
|
136
139
|
self.assertFalse(diff, "AST structures differ after formatting.")
|
|
137
140
|
|
|
138
|
-
except Exception:
|
|
141
|
+
except Exception as e:
|
|
139
142
|
print(add_line_numbers(code_gen_pure.ir.source.code))
|
|
140
143
|
print("\n+++++++++++++++++++++++++++++++++++++++\n")
|
|
141
144
|
print(add_line_numbers(code_gen_format.ir.gen.jac))
|
|
142
145
|
print("\n+++++++++++++++++++++++++++++++++++++++\n")
|
|
143
146
|
print("\n".join(unified_diff(before.splitlines(), after.splitlines())))
|
|
144
|
-
|
|
145
|
-
# raise e
|
|
147
|
+
raise e
|
|
146
148
|
|
|
147
149
|
|
|
148
150
|
JacFormatPassTests.self_attach_micro_tests()
|
|
@@ -30,7 +30,7 @@ class JacUnparseTests(TestCaseMicroSuite, AstSyncTestMixin):
|
|
|
30
30
|
self.assertEqual(x, y)
|
|
31
31
|
except Exception as e:
|
|
32
32
|
print("\n".join(unified_diff(x.splitlines(), y.splitlines())))
|
|
33
|
-
|
|
33
|
+
raise e
|
|
34
34
|
|
|
35
35
|
def micro_suite_test(self, filename: str) -> None:
|
|
36
36
|
"""Parse micro jac file."""
|
|
@@ -75,7 +75,6 @@ class JacUnparseTests(TestCaseMicroSuite, AstSyncTestMixin):
|
|
|
75
75
|
|
|
76
76
|
except Exception as e:
|
|
77
77
|
raise e
|
|
78
|
-
# self.skipTest(f"Test failed, but skipping instead of failing: {e}")
|
|
79
78
|
|
|
80
79
|
|
|
81
80
|
JacUnparseTests.self_attach_micro_tests()
|
jaclang/compiler/symtable.py
CHANGED
|
@@ -17,7 +17,7 @@ class SymbolType(Enum):
|
|
|
17
17
|
|
|
18
18
|
MODULE = "module" # LSP: Module
|
|
19
19
|
MOD_VAR = "mod_var" # LSP: Variable
|
|
20
|
-
VAR = "
|
|
20
|
+
VAR = "variable" # LSP: Variable
|
|
21
21
|
IMM_VAR = "immutable" # LSP: Constant
|
|
22
22
|
ABILITY = "ability" # LSP: Function
|
|
23
23
|
OBJECT_ARCH = "object" # LSP: Class
|
|
@@ -54,6 +54,12 @@ class SymbolInfo:
|
|
|
54
54
|
self.acc_tag: Optional[SymbolAccess] = acc_tag
|
|
55
55
|
self.typ_sym_table: Optional[SymbolTable] = None
|
|
56
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
|
+
|
|
57
63
|
|
|
58
64
|
class SymbolAccess(Enum):
|
|
59
65
|
"""Symbol types."""
|
|
@@ -101,6 +107,20 @@ class Symbol:
|
|
|
101
107
|
"""Get sym_type."""
|
|
102
108
|
return self.decl.sym_type
|
|
103
109
|
|
|
110
|
+
@property
|
|
111
|
+
def sym_path_str(self) -> str:
|
|
112
|
+
"""Return a full path of the symbol."""
|
|
113
|
+
out = [self.defn[0].sym_name]
|
|
114
|
+
current_tab = self.parent_tab
|
|
115
|
+
while current_tab is not None:
|
|
116
|
+
out.append(current_tab.name)
|
|
117
|
+
if current_tab.has_parent():
|
|
118
|
+
current_tab = current_tab.parent
|
|
119
|
+
else:
|
|
120
|
+
break
|
|
121
|
+
out.reverse()
|
|
122
|
+
return ".".join(out)
|
|
123
|
+
|
|
104
124
|
def add_defn(self, node: ast.AstSymbolNode) -> None:
|
|
105
125
|
"""Add defn."""
|
|
106
126
|
self.defn.append(node)
|