jaclang 0.5.16__py3-none-any.whl → 0.5.18__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 +2 -6
- jaclang/cli/cli.py +1 -1
- jaclang/compiler/absyntree.py +24 -24
- jaclang/compiler/generated/jac_parser.py +2 -2
- jaclang/compiler/jac.lark +7 -7
- jaclang/compiler/parser.py +31 -16
- jaclang/compiler/passes/ir_pass.py +10 -8
- jaclang/compiler/passes/main/fuse_typeinfo_pass.py +3 -2
- jaclang/compiler/passes/main/import_pass.py +4 -5
- jaclang/compiler/passes/main/pyast_gen_pass.py +60 -20
- jaclang/compiler/passes/main/pyast_load_pass.py +7 -6
- jaclang/compiler/passes/main/sym_tab_build_pass.py +26 -13
- jaclang/compiler/passes/tool/jac_formatter_pass.py +146 -23
- jaclang/compiler/passes/tool/tests/test_jac_format_pass.py +66 -55
- jaclang/compiler/workspace.py +2 -6
- jaclang/core/llms.py +84 -2
- jaclang/plugin/default.py +10 -2
- jaclang/settings.py +95 -0
- jaclang/vendor/mypy/checker.py +2 -3
- {jaclang-0.5.16.dist-info → jaclang-0.5.18.dist-info}/METADATA +1 -1
- {jaclang-0.5.16.dist-info → jaclang-0.5.18.dist-info}/RECORD +24 -25
- jaclang/compiler/tests/fixtures/__jac_gen__/__init__.py +0 -0
- jaclang/compiler/tests/fixtures/__jac_gen__/hello_world.py +0 -5
- {jaclang-0.5.16.dist-info → jaclang-0.5.18.dist-info}/WHEEL +0 -0
- {jaclang-0.5.16.dist-info → jaclang-0.5.18.dist-info}/entry_points.txt +0 -0
- {jaclang-0.5.16.dist-info → jaclang-0.5.18.dist-info}/top_level.txt +0 -0
jaclang/compiler/jac.lark
CHANGED
|
@@ -317,9 +317,9 @@ cmp_op: KW_ISN
|
|
|
317
317
|
|
|
318
318
|
// Arithmetic expressions
|
|
319
319
|
arithmetic: (arithmetic (MINUS | PLUS))? term
|
|
320
|
-
term: (term (MOD | DIV | FLOOR_DIV | STAR_MUL | DECOR_OP))?
|
|
321
|
-
|
|
322
|
-
|
|
320
|
+
term: (term (MOD | DIV | FLOOR_DIV | STAR_MUL | DECOR_OP))? power
|
|
321
|
+
power: (power STAR_POW)? factor
|
|
322
|
+
factor: (BW_NOT | MINUS | PLUS) factor | connect
|
|
323
323
|
|
|
324
324
|
// Connect expressions
|
|
325
325
|
connect: (connect (connect_op | disconnect_op))? atomic_pipe
|
|
@@ -539,16 +539,16 @@ KW_POST_INIT: "postinit"
|
|
|
539
539
|
KW_SUPER: "super"
|
|
540
540
|
KW_ROOT: "root"
|
|
541
541
|
|
|
542
|
-
FLOAT: /(\d+(\.\d*)|\.\d+)([eE][+-]?\d+)
|
|
542
|
+
FLOAT: /(\d+(\.\d*)|\.\d+)([eE][+-]?\d+)?|\d+([eE][-+]?\d+)/
|
|
543
543
|
DOC_STRING.1: /"""(.|\n|\r)*?"""|'''(.|\n|\r)*?'''/
|
|
544
544
|
PYNLINE: /::py::(.|\n|\r)*?::py::/
|
|
545
545
|
STRING: /(r?b?|b?r?)"[^"\r\n]*"|(r?b?|b?r?)'[^'\r\n]*'/
|
|
546
546
|
BOOL.1: /True|False/
|
|
547
547
|
KW_NIN.1: /\bnot\s+in\b/
|
|
548
548
|
KW_ISN.1: /\bis\s+not\b/
|
|
549
|
-
HEX: /0[xX][0-9a-fA-F_]+/
|
|
550
|
-
BIN: /0[bB][01_]+/
|
|
551
|
-
OCT: /0[oO][0-7_]+/
|
|
549
|
+
HEX.1: /0[xX][0-9a-fA-F_]+/
|
|
550
|
+
BIN.1: /0[bB][01_]+/
|
|
551
|
+
OCT.1: /0[oO][0-7_]+/
|
|
552
552
|
INT: /[0-9][0-9_]*/
|
|
553
553
|
NULL.1: /None/
|
|
554
554
|
KWESC_NAME: /<>[a-zA-Z_][a-zA-Z0-9_]*/
|
jaclang/compiler/parser.py
CHANGED
|
@@ -287,17 +287,22 @@ class JacParser(Pass):
|
|
|
287
287
|
if len(kid) == 1 and isinstance(kid[0], ast.Import):
|
|
288
288
|
return self.nu(kid[0])
|
|
289
289
|
lang = kid[1]
|
|
290
|
-
|
|
290
|
+
from_path = kid[3] if isinstance(kid[3], ast.ModulePath) else None
|
|
291
|
+
if from_path:
|
|
292
|
+
items = kid[-2] if isinstance(kid[-2], ast.SubNodeList) else None
|
|
293
|
+
else:
|
|
294
|
+
paths = [i for i in kid if isinstance(i, ast.ModulePath)]
|
|
295
|
+
items = ast.SubNodeList[ast.ModulePath](
|
|
296
|
+
items=paths, delim=Tok.COMMA, kid=kid[2:-1]
|
|
297
|
+
)
|
|
298
|
+
kid = kid[:2] + [items] + kid[-1:]
|
|
291
299
|
|
|
292
|
-
items = kid[-2] if isinstance(kid[-2], ast.SubNodeList) else None
|
|
293
300
|
is_absorb = False
|
|
294
|
-
if isinstance(lang, ast.SubTag) and (
|
|
295
|
-
isinstance(items, ast.SubNodeList) or items is None
|
|
296
|
-
):
|
|
301
|
+
if isinstance(lang, ast.SubTag) and (isinstance(items, ast.SubNodeList)):
|
|
297
302
|
return self.nu(
|
|
298
303
|
ast.Import(
|
|
299
|
-
|
|
300
|
-
|
|
304
|
+
hint=lang,
|
|
305
|
+
from_loc=from_path,
|
|
301
306
|
items=items,
|
|
302
307
|
is_absorb=is_absorb,
|
|
303
308
|
kid=kid,
|
|
@@ -342,14 +347,20 @@ class JacParser(Pass):
|
|
|
342
347
|
include_stmt: KW_INCLUDE sub_name import_path SEMI
|
|
343
348
|
"""
|
|
344
349
|
lang = kid[1]
|
|
345
|
-
|
|
350
|
+
from_path = kid[2]
|
|
351
|
+
if not isinstance(from_path, ast.ModulePath):
|
|
352
|
+
raise self.ice()
|
|
353
|
+
items = ast.SubNodeList[ast.ModulePath](
|
|
354
|
+
items=[from_path], delim=Tok.COMMA, kid=[from_path]
|
|
355
|
+
)
|
|
356
|
+
kid = kid[:2] + [items] + kid[3:]
|
|
346
357
|
is_absorb = True
|
|
347
358
|
if isinstance(lang, ast.SubTag):
|
|
348
359
|
return self.nu(
|
|
349
360
|
ast.Import(
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
items=
|
|
361
|
+
hint=lang,
|
|
362
|
+
from_loc=None,
|
|
363
|
+
items=items,
|
|
353
364
|
is_absorb=is_absorb,
|
|
354
365
|
kid=kid,
|
|
355
366
|
)
|
|
@@ -1919,13 +1930,17 @@ class JacParser(Pass):
|
|
|
1919
1930
|
sig_kid.append(params)
|
|
1920
1931
|
if return_type:
|
|
1921
1932
|
sig_kid.append(return_type)
|
|
1922
|
-
signature =
|
|
1923
|
-
|
|
1924
|
-
|
|
1925
|
-
|
|
1933
|
+
signature = (
|
|
1934
|
+
ast.FuncSignature(
|
|
1935
|
+
params=params,
|
|
1936
|
+
return_type=return_type,
|
|
1937
|
+
kid=sig_kid,
|
|
1938
|
+
)
|
|
1939
|
+
if params or return_type
|
|
1940
|
+
else None
|
|
1926
1941
|
)
|
|
1927
1942
|
new_kid = [i for i in kid if i != params and i != return_type]
|
|
1928
|
-
new_kid.insert(1, signature)
|
|
1943
|
+
new_kid.insert(1, signature) if signature else None
|
|
1929
1944
|
if isinstance(chomp[0], ast.Expr):
|
|
1930
1945
|
return self.nu(
|
|
1931
1946
|
ast.LambdaExpr(
|
|
@@ -1,16 +1,18 @@
|
|
|
1
1
|
"""Abstract class for IR Passes for Jac."""
|
|
2
2
|
|
|
3
|
-
from typing import Optional, Type
|
|
3
|
+
from typing import Optional, Type, TypeVar
|
|
4
4
|
|
|
5
5
|
import jaclang.compiler.absyntree as ast
|
|
6
6
|
from jaclang.compiler.passes.transform import Transform
|
|
7
7
|
from jaclang.utils.helpers import pascal_to_snake
|
|
8
8
|
|
|
9
|
+
T = TypeVar("T", bound=ast.AstNode)
|
|
9
10
|
|
|
10
|
-
|
|
11
|
+
|
|
12
|
+
class Pass(Transform[T]):
|
|
11
13
|
"""Abstract class for IR passes."""
|
|
12
14
|
|
|
13
|
-
def __init__(self, input_ir:
|
|
15
|
+
def __init__(self, input_ir: T, prior: Optional[Transform]) -> None:
|
|
14
16
|
"""Initialize parser."""
|
|
15
17
|
self.term_signal = False
|
|
16
18
|
self.prune_signal = False
|
|
@@ -45,10 +47,10 @@ class Pass(Transform[ast.T]):
|
|
|
45
47
|
|
|
46
48
|
@staticmethod
|
|
47
49
|
def get_all_sub_nodes(
|
|
48
|
-
node: ast.AstNode, typ: Type[
|
|
49
|
-
) -> list[
|
|
50
|
+
node: ast.AstNode, typ: Type[T], brute_force: bool = False
|
|
51
|
+
) -> list[T]:
|
|
50
52
|
"""Get all sub nodes of type."""
|
|
51
|
-
result: list[
|
|
53
|
+
result: list[T] = []
|
|
52
54
|
# Assumes pass built the sub node table
|
|
53
55
|
if not node:
|
|
54
56
|
return result
|
|
@@ -69,7 +71,7 @@ class Pass(Transform[ast.T]):
|
|
|
69
71
|
return result
|
|
70
72
|
|
|
71
73
|
@staticmethod
|
|
72
|
-
def has_parent_of_type(node: ast.AstNode, typ: Type[
|
|
74
|
+
def has_parent_of_type(node: ast.AstNode, typ: Type[T]) -> Optional[T]:
|
|
73
75
|
"""Check if node has parent of type."""
|
|
74
76
|
while node.parent:
|
|
75
77
|
if isinstance(node.parent, typ):
|
|
@@ -97,7 +99,7 @@ class Pass(Transform[ast.T]):
|
|
|
97
99
|
|
|
98
100
|
# Transform Implementations
|
|
99
101
|
# -------------------------
|
|
100
|
-
def transform(self, ir:
|
|
102
|
+
def transform(self, ir: T) -> ast.AstNode:
|
|
101
103
|
"""Run pass."""
|
|
102
104
|
# Only performs passes on proper ASTs
|
|
103
105
|
if not isinstance(ir, ast.AstNode):
|
|
@@ -6,15 +6,16 @@ mypy apis into Jac and use jac py ast in it.
|
|
|
6
6
|
|
|
7
7
|
from __future__ import annotations
|
|
8
8
|
|
|
9
|
-
import os
|
|
10
9
|
import traceback
|
|
11
10
|
from typing import Callable, TypeVar
|
|
12
11
|
|
|
13
12
|
import jaclang.compiler.absyntree as ast
|
|
14
13
|
from jaclang.compiler.passes import Pass
|
|
14
|
+
from jaclang.settings import settings
|
|
15
15
|
from jaclang.utils.helpers import pascal_to_snake
|
|
16
16
|
from jaclang.vendor.mypy.nodes import Node as VNode # bit of a hack
|
|
17
17
|
|
|
18
|
+
|
|
18
19
|
import mypy.nodes as MypyNodes # noqa N812
|
|
19
20
|
import mypy.types as MypyTypes # noqa N812
|
|
20
21
|
from mypy.checkexpr import Type as MyType
|
|
@@ -29,7 +30,7 @@ class FuseTypeInfoPass(Pass):
|
|
|
29
30
|
node_type_hash: dict[MypyNodes.Node | VNode, MyType] = {}
|
|
30
31
|
|
|
31
32
|
def __debug_print(self, *argv: object) -> None:
|
|
32
|
-
if
|
|
33
|
+
if settings.fuse_type_info_debug:
|
|
33
34
|
print("FuseTypeInfo::", *argv)
|
|
34
35
|
|
|
35
36
|
def __call_type_handler(
|
|
@@ -7,7 +7,6 @@ symbols are available for matching.
|
|
|
7
7
|
|
|
8
8
|
import ast as py_ast
|
|
9
9
|
import importlib.util
|
|
10
|
-
import os
|
|
11
10
|
import sys
|
|
12
11
|
from os import path
|
|
13
12
|
from typing import Optional
|
|
@@ -16,6 +15,7 @@ from typing import Optional
|
|
|
16
15
|
import jaclang.compiler.absyntree as ast
|
|
17
16
|
from jaclang.compiler.passes import Pass
|
|
18
17
|
from jaclang.compiler.passes.main import SubNodeTabPass
|
|
18
|
+
from jaclang.settings import settings
|
|
19
19
|
from jaclang.utils.helpers import import_target_to_relative_path
|
|
20
20
|
|
|
21
21
|
|
|
@@ -36,7 +36,8 @@ class ImportPass(Pass):
|
|
|
36
36
|
self.run_again = False
|
|
37
37
|
all_imports = self.get_all_sub_nodes(node, ast.ModulePath)
|
|
38
38
|
for i in all_imports:
|
|
39
|
-
|
|
39
|
+
lang = i.parent_of_type(ast.Import).hint.tag.value
|
|
40
|
+
if lang == "jac" and not i.sub_module:
|
|
40
41
|
self.run_again = True
|
|
41
42
|
mod = self.import_module(
|
|
42
43
|
node=i,
|
|
@@ -48,9 +49,7 @@ class ImportPass(Pass):
|
|
|
48
49
|
self.annex_impl(mod)
|
|
49
50
|
i.sub_module = mod
|
|
50
51
|
i.add_kids_right([mod], pos_update=False)
|
|
51
|
-
elif
|
|
52
|
-
"JAC_PROC_DEBUG", False
|
|
53
|
-
):
|
|
52
|
+
elif lang == "py" and settings.jac_proc_debug:
|
|
54
53
|
mod = self.import_py_module(node=i, mod_path=node.loc.mod_path)
|
|
55
54
|
i.sub_module = mod
|
|
56
55
|
i.add_kids_right([mod], pos_update=False)
|
|
@@ -492,17 +492,20 @@ class PyastGenPass(Pass):
|
|
|
492
492
|
py_nodes.append(
|
|
493
493
|
self.sync(ast3.Expr(value=node.doc.gen.py_ast[0]), jac_node=node.doc)
|
|
494
494
|
)
|
|
495
|
-
|
|
496
|
-
|
|
497
|
-
|
|
498
|
-
py_compat_path_str.append(path.path_str.lstrip("."))
|
|
499
|
-
path_alias[path.path_str] = path.alias.sym_name if path.alias else None
|
|
495
|
+
path_alias: dict[str, Optional[str]] = (
|
|
496
|
+
{node.from_loc.path_str: None} if node.from_loc else {}
|
|
497
|
+
)
|
|
500
498
|
imp_from = {}
|
|
501
499
|
if node.items:
|
|
502
500
|
for item in node.items.items:
|
|
503
|
-
|
|
504
|
-
item.
|
|
505
|
-
|
|
501
|
+
if isinstance(item, ast.ModuleItem):
|
|
502
|
+
imp_from[item.name.sym_name] = (
|
|
503
|
+
item.alias.sym_name if item.alias else False
|
|
504
|
+
)
|
|
505
|
+
elif isinstance(item, ast.ModulePath):
|
|
506
|
+
path_alias[item.path_str] = (
|
|
507
|
+
item.alias.sym_name if item.alias else None
|
|
508
|
+
)
|
|
506
509
|
|
|
507
510
|
keys = []
|
|
508
511
|
values = []
|
|
@@ -557,9 +560,9 @@ class PyastGenPass(Pass):
|
|
|
557
560
|
arg="lng",
|
|
558
561
|
value=self.sync(
|
|
559
562
|
ast3.Constant(
|
|
560
|
-
value=node.
|
|
563
|
+
value=node.hint.tag.value
|
|
561
564
|
),
|
|
562
|
-
node.
|
|
565
|
+
node.hint,
|
|
563
566
|
),
|
|
564
567
|
)
|
|
565
568
|
),
|
|
@@ -594,10 +597,13 @@ class PyastGenPass(Pass):
|
|
|
594
597
|
)
|
|
595
598
|
)
|
|
596
599
|
if node.is_absorb:
|
|
600
|
+
source = node.items.items[0]
|
|
601
|
+
if not isinstance(source, ast.ModulePath):
|
|
602
|
+
raise self.ice()
|
|
597
603
|
py_nodes.append(
|
|
598
604
|
self.sync(
|
|
599
605
|
py_node=ast3.ImportFrom(
|
|
600
|
-
module=
|
|
606
|
+
module=(source.path_str.lstrip(".") if source else None),
|
|
601
607
|
names=[self.sync(ast3.alias(name="*"), node)],
|
|
602
608
|
level=0,
|
|
603
609
|
),
|
|
@@ -608,15 +614,17 @@ class PyastGenPass(Pass):
|
|
|
608
614
|
self.warning(
|
|
609
615
|
"Includes import * in target module into current namespace."
|
|
610
616
|
)
|
|
611
|
-
if not node.
|
|
612
|
-
py_nodes.append(
|
|
613
|
-
self.sync(ast3.Import(names=[i.gen.py_ast[0] for i in node.paths]))
|
|
614
|
-
)
|
|
617
|
+
if not node.from_loc:
|
|
618
|
+
py_nodes.append(self.sync(ast3.Import(names=node.items.gen.py_ast)))
|
|
615
619
|
else:
|
|
616
620
|
py_nodes.append(
|
|
617
621
|
self.sync(
|
|
618
622
|
ast3.ImportFrom(
|
|
619
|
-
module=
|
|
623
|
+
module=(
|
|
624
|
+
node.from_loc.path_str.lstrip(".")
|
|
625
|
+
if node.from_loc
|
|
626
|
+
else None
|
|
627
|
+
),
|
|
620
628
|
names=node.items.gen.py_ast,
|
|
621
629
|
level=0,
|
|
622
630
|
)
|
|
@@ -1674,7 +1682,7 @@ class PyastGenPass(Pass):
|
|
|
1674
1682
|
self.sync(
|
|
1675
1683
|
ast3.Try(
|
|
1676
1684
|
body=self.resolve_stmt_block(node.body),
|
|
1677
|
-
handlers=node.excepts.gen.py_ast if node.excepts else
|
|
1685
|
+
handlers=node.excepts.gen.py_ast if node.excepts else [],
|
|
1678
1686
|
orelse=node.else_body.gen.py_ast if node.else_body else [],
|
|
1679
1687
|
finalbody=node.finally_body.gen.py_ast if node.finally_body else [],
|
|
1680
1688
|
)
|
|
@@ -2376,7 +2384,19 @@ class PyastGenPass(Pass):
|
|
|
2376
2384
|
node.gen.py_ast = [
|
|
2377
2385
|
self.sync(
|
|
2378
2386
|
ast3.Lambda(
|
|
2379
|
-
args=
|
|
2387
|
+
args=(
|
|
2388
|
+
node.signature.gen.py_ast[0]
|
|
2389
|
+
if node.signature
|
|
2390
|
+
else self.sync(
|
|
2391
|
+
ast3.arguments(
|
|
2392
|
+
posonlyargs=[],
|
|
2393
|
+
args=[],
|
|
2394
|
+
kwonlyargs=[],
|
|
2395
|
+
kw_defaults=[],
|
|
2396
|
+
defaults=[],
|
|
2397
|
+
)
|
|
2398
|
+
)
|
|
2399
|
+
),
|
|
2380
2400
|
body=node.body.gen.py_ast[0],
|
|
2381
2401
|
)
|
|
2382
2402
|
)
|
|
@@ -2435,11 +2455,16 @@ class PyastGenPass(Pass):
|
|
|
2435
2455
|
)
|
|
2436
2456
|
]
|
|
2437
2457
|
elif node.op.name in [Tok.STAR_MUL]:
|
|
2458
|
+
ctx_val = (
|
|
2459
|
+
node.operand.py_ctx_func()
|
|
2460
|
+
if isinstance(node.operand, ast.AstSymbolNode)
|
|
2461
|
+
else ast3.Load()
|
|
2462
|
+
)
|
|
2438
2463
|
node.gen.py_ast = [
|
|
2439
2464
|
self.sync(
|
|
2440
2465
|
ast3.Starred(
|
|
2441
2466
|
value=node.operand.gen.py_ast[0],
|
|
2442
|
-
ctx=
|
|
2467
|
+
ctx=ctx_val,
|
|
2443
2468
|
)
|
|
2444
2469
|
)
|
|
2445
2470
|
]
|
|
@@ -3648,7 +3673,22 @@ class PyastGenPass(Pass):
|
|
|
3648
3673
|
pos_start: int,
|
|
3649
3674
|
pos_end: int,
|
|
3650
3675
|
"""
|
|
3651
|
-
|
|
3676
|
+
|
|
3677
|
+
def handle_node_value(value: str) -> int:
|
|
3678
|
+
if value.startswith(("0x", "0X")):
|
|
3679
|
+
return int(value, 16)
|
|
3680
|
+
elif value.startswith(("0b", "0B")):
|
|
3681
|
+
return int(value, 2)
|
|
3682
|
+
elif value.startswith(("0o", "0O")):
|
|
3683
|
+
return int(value, 8)
|
|
3684
|
+
else:
|
|
3685
|
+
return int(value)
|
|
3686
|
+
|
|
3687
|
+
node.gen.py_ast = [
|
|
3688
|
+
self.sync(
|
|
3689
|
+
ast3.Constant(value=handle_node_value(str(node.value)), kind=None)
|
|
3690
|
+
)
|
|
3691
|
+
]
|
|
3652
3692
|
|
|
3653
3693
|
def exit_string(self, node: ast.String) -> None:
|
|
3654
3694
|
"""Sub objects.
|
|
@@ -1372,12 +1372,13 @@ class PyastBuildPass(Pass[ast.PythonModuleAst]):
|
|
|
1372
1372
|
pos_end=0,
|
|
1373
1373
|
)
|
|
1374
1374
|
pytag = ast.SubTag[ast.Name](tag=lang, kid=[lang])
|
|
1375
|
+
items = ast.SubNodeList[ast.ModulePath](items=paths, delim=Tok.COMMA, kid=paths)
|
|
1375
1376
|
ret = ast.Import(
|
|
1376
|
-
|
|
1377
|
-
|
|
1378
|
-
items=
|
|
1377
|
+
hint=pytag,
|
|
1378
|
+
from_loc=None,
|
|
1379
|
+
items=items,
|
|
1379
1380
|
is_absorb=False,
|
|
1380
|
-
kid=[pytag,
|
|
1381
|
+
kid=[pytag, items],
|
|
1381
1382
|
)
|
|
1382
1383
|
return ret
|
|
1383
1384
|
|
|
@@ -1448,8 +1449,8 @@ class PyastBuildPass(Pass[ast.PythonModuleAst]):
|
|
|
1448
1449
|
raise self.ice("No valid names in import from")
|
|
1449
1450
|
pytag = ast.SubTag[ast.Name](tag=lang, kid=[lang])
|
|
1450
1451
|
ret = ast.Import(
|
|
1451
|
-
|
|
1452
|
-
|
|
1452
|
+
hint=pytag,
|
|
1453
|
+
from_loc=path,
|
|
1453
1454
|
items=items,
|
|
1454
1455
|
is_absorb=False,
|
|
1455
1456
|
kid=[pytag, path, items],
|
|
@@ -61,14 +61,21 @@ class SymTabPass(Pass):
|
|
|
61
61
|
node.sym_name_node.py_ctx_func = ast3.Store
|
|
62
62
|
if isinstance(node, (ast.TupleVal, ast.ListVal)) and node.values:
|
|
63
63
|
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
64
|
+
# Handling of UnaryExpr case for item is only necessary for
|
|
65
|
+
# the generation of Starred nodes in the AST for examples
|
|
66
|
+
# like `(a, *b) = (1, 2, 3, 4)`.
|
|
67
|
+
def fix(item: ast.TupleVal | ast.ListVal | ast.UnaryExpr) -> None:
|
|
68
|
+
if isinstance(item, ast.UnaryExpr):
|
|
69
|
+
if isinstance(item.operand, ast.AstSymbolNode):
|
|
70
|
+
item.operand.py_ctx_func = ast3.Store
|
|
71
|
+
elif isinstance(item, (ast.TupleVal, ast.ListVal)):
|
|
72
|
+
for i in item.values.items if item.values else []:
|
|
73
|
+
if isinstance(i, ast.AstSymbolNode):
|
|
74
|
+
i.py_ctx_func = ast3.Store
|
|
75
|
+
elif isinstance(i, ast.AtomTrailer):
|
|
76
|
+
self.chain_def_insert(self.unwind_atom_trailer(i))
|
|
77
|
+
if isinstance(i, (ast.TupleVal, ast.ListVal, ast.UnaryExpr)):
|
|
78
|
+
fix(i)
|
|
72
79
|
|
|
73
80
|
fix(node)
|
|
74
81
|
self.handle_hit_outcome(node)
|
|
@@ -381,16 +388,22 @@ class SymTabBuildPass(SymTabPass):
|
|
|
381
388
|
is_absorb: bool,
|
|
382
389
|
sub_module: Optional[Module],
|
|
383
390
|
"""
|
|
384
|
-
if node.
|
|
391
|
+
if not node.is_absorb:
|
|
385
392
|
for i in node.items.items:
|
|
386
393
|
self.def_insert(i, single_decl="import item")
|
|
387
|
-
elif node.is_absorb and node.
|
|
388
|
-
|
|
394
|
+
elif node.is_absorb and node.hint.tag.value == "jac":
|
|
395
|
+
source = node.items.items[0]
|
|
396
|
+
if (
|
|
397
|
+
not isinstance(source, ast.ModulePath)
|
|
398
|
+
or not source.sub_module
|
|
399
|
+
or not source.sub_module.sym_tab
|
|
400
|
+
):
|
|
389
401
|
self.error(
|
|
390
|
-
f"Module {node.
|
|
402
|
+
f"Module {node.from_loc.path_str if node.from_loc else 'from location'}"
|
|
403
|
+
f" not found to include *, or ICE occurred!"
|
|
391
404
|
)
|
|
392
405
|
else:
|
|
393
|
-
for v in
|
|
406
|
+
for v in source.sub_module.sym_tab.tab.values():
|
|
394
407
|
self.def_insert(v.decl, table_override=self.cur_scope())
|
|
395
408
|
|
|
396
409
|
def enter_module_path(self, node: ast.ModulePath) -> None:
|