jaclang 0.7.2__py3-none-any.whl → 0.7.8__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/__init__.py +11 -12
- 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/compiler/passes/utils/mypy_ast_build.py +1 -8
- 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/{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 +25 -77
- 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/test_bugs.py +19 -0
- jaclang/tests/test_cli.py +1 -1
- jaclang/tests/test_language.py +65 -100
- 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.8.dist-info}/METADATA +1 -1
- {jaclang-0.7.2.dist-info → jaclang-0.7.8.dist-info}/RECORD +79 -83
- jaclang/core/aott.py +0 -310
- 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/tests/fixtures/math_question.jpg +0 -0
- jaclang/tests/fixtures/with_llm_function.jac +0 -33
- jaclang/tests/fixtures/with_llm_lower.jac +0 -45
- jaclang/tests/fixtures/with_llm_method.jac +0 -51
- jaclang/tests/fixtures/with_llm_type.jac +0 -52
- jaclang/tests/fixtures/with_llm_vision.jac +0 -25
- {jaclang-0.7.2.dist-info → jaclang-0.7.8.dist-info}/WHEEL +0 -0
- {jaclang-0.7.2.dist-info → jaclang-0.7.8.dist-info}/entry_points.txt +0 -0
jaclang/compiler/parser.py
CHANGED
|
@@ -24,6 +24,7 @@ class JacParser(Pass):
|
|
|
24
24
|
"""Initialize parser."""
|
|
25
25
|
self.source = input_ir
|
|
26
26
|
self.mod_path = input_ir.loc.mod_path
|
|
27
|
+
self.node_list: list[ast.AstNode] = []
|
|
27
28
|
if JacParser.dev_mode:
|
|
28
29
|
JacParser.make_dev()
|
|
29
30
|
Pass.__init__(self, input_ir=input_ir, prior=None)
|
|
@@ -44,8 +45,9 @@ class JacParser(Pass):
|
|
|
44
45
|
catch_error = ast.EmptyToken()
|
|
45
46
|
catch_error.file_path = self.mod_path
|
|
46
47
|
catch_error.line_no = e.line
|
|
48
|
+
catch_error.end_line = e.line
|
|
47
49
|
catch_error.c_start = e.column
|
|
48
|
-
catch_error.c_end = e.column
|
|
50
|
+
catch_error.c_end = e.column + 1
|
|
49
51
|
self.error(f"Syntax Error: {e}", node_override=catch_error)
|
|
50
52
|
except Exception as e:
|
|
51
53
|
self.error(f"Internal Error: {e}")
|
|
@@ -66,6 +68,7 @@ class JacParser(Pass):
|
|
|
66
68
|
name=token.type,
|
|
67
69
|
value=token.value,
|
|
68
70
|
line=token.line if token.line is not None else 0,
|
|
71
|
+
end_line=token.end_line if token.end_line is not None else 0,
|
|
69
72
|
col_start=token.column if token.column is not None else 0,
|
|
70
73
|
col_end=token.end_column if token.end_column is not None else 0,
|
|
71
74
|
pos_start=token.start_pos if token.start_pos is not None else 0,
|
|
@@ -128,6 +131,7 @@ class JacParser(Pass):
|
|
|
128
131
|
def nu(self, node: ast.T) -> ast.T:
|
|
129
132
|
"""Update node."""
|
|
130
133
|
self.parse_ref.cur_node = node
|
|
134
|
+
self.parse_ref.node_list.append(node)
|
|
131
135
|
return node
|
|
132
136
|
|
|
133
137
|
def start(self, kid: list[ast.Module]) -> ast.Module:
|
|
@@ -135,6 +139,7 @@ class JacParser(Pass):
|
|
|
135
139
|
|
|
136
140
|
start: module
|
|
137
141
|
"""
|
|
142
|
+
kid[0]._in_mod_nodes = self.parse_ref.node_list
|
|
138
143
|
return self.nu(kid[0])
|
|
139
144
|
|
|
140
145
|
def module(
|
|
@@ -437,13 +442,14 @@ class JacParser(Pass):
|
|
|
437
442
|
else:
|
|
438
443
|
raise self.ice()
|
|
439
444
|
|
|
440
|
-
def architype(
|
|
445
|
+
def architype(
|
|
446
|
+
self, kid: list[ast.AstNode]
|
|
447
|
+
) -> ast.ArchSpec | ast.ArchDef | ast.Enum | ast.EnumDef:
|
|
441
448
|
"""Grammar rule.
|
|
442
449
|
|
|
443
|
-
architype: decorators
|
|
444
|
-
| enum
|
|
450
|
+
architype: decorators? architype_decl
|
|
445
451
|
| architype_def
|
|
446
|
-
|
|
|
452
|
+
| enum
|
|
447
453
|
"""
|
|
448
454
|
if isinstance(kid[0], ast.SubNodeList):
|
|
449
455
|
if isinstance(kid[1], ast.ArchSpec):
|
|
@@ -452,7 +458,8 @@ class JacParser(Pass):
|
|
|
452
458
|
return self.nu(kid[1])
|
|
453
459
|
else:
|
|
454
460
|
raise self.ice()
|
|
455
|
-
|
|
461
|
+
|
|
462
|
+
elif isinstance(kid[0], (ast.ArchSpec, ast.ArchDef, ast.Enum, ast.EnumDef)):
|
|
456
463
|
return self.nu(kid[0])
|
|
457
464
|
else:
|
|
458
465
|
raise self.ice()
|
|
@@ -569,25 +576,14 @@ class JacParser(Pass):
|
|
|
569
576
|
else:
|
|
570
577
|
raise self.ice()
|
|
571
578
|
|
|
572
|
-
def
|
|
573
|
-
"""Grammar rule.
|
|
574
|
-
|
|
575
|
-
any_ref: named_ref
|
|
576
|
-
| arch_ref
|
|
577
|
-
"""
|
|
578
|
-
if isinstance(kid[0], ast.NameSpec):
|
|
579
|
-
return self.nu(kid[0])
|
|
580
|
-
else:
|
|
581
|
-
raise self.ice()
|
|
582
|
-
|
|
583
|
-
def named_ref(self, kid: list[ast.AstNode]) -> ast.NameSpec:
|
|
579
|
+
def named_ref(self, kid: list[ast.AstNode]) -> ast.NameAtom:
|
|
584
580
|
"""Grammar rule.
|
|
585
581
|
|
|
586
582
|
named_ref: special_ref
|
|
587
583
|
| KWESC_NAME
|
|
588
584
|
| NAME
|
|
589
585
|
"""
|
|
590
|
-
if isinstance(kid[0], ast.
|
|
586
|
+
if isinstance(kid[0], ast.NameAtom):
|
|
591
587
|
return self.nu(kid[0])
|
|
592
588
|
else:
|
|
593
589
|
raise self.ice()
|
|
@@ -602,23 +598,25 @@ class JacParser(Pass):
|
|
|
602
598
|
| KW_SELF
|
|
603
599
|
| KW_HERE
|
|
604
600
|
"""
|
|
605
|
-
if isinstance(kid[0], ast.
|
|
606
|
-
return self.nu(
|
|
607
|
-
ast.SpecialVarRef(
|
|
608
|
-
var=kid[0],
|
|
609
|
-
kid=kid,
|
|
610
|
-
)
|
|
611
|
-
)
|
|
601
|
+
if isinstance(kid[0], ast.Name):
|
|
602
|
+
return self.nu(ast.SpecialVarRef(var=kid[0]))
|
|
612
603
|
else:
|
|
613
604
|
raise self.ice()
|
|
614
605
|
|
|
615
606
|
def enum(self, kid: list[ast.AstNode]) -> ast.Enum | ast.EnumDef:
|
|
616
607
|
"""Grammar rule.
|
|
617
608
|
|
|
618
|
-
enum:
|
|
619
|
-
|
|
|
609
|
+
enum: decorators? enum_decl
|
|
610
|
+
| enum_def
|
|
620
611
|
"""
|
|
621
|
-
if isinstance(kid[0],
|
|
612
|
+
if isinstance(kid[0], ast.SubNodeList):
|
|
613
|
+
if isinstance(kid[1], ast.Enum):
|
|
614
|
+
kid[1].decorators = kid[0]
|
|
615
|
+
kid[1].add_kids_left([kid[0]])
|
|
616
|
+
return self.nu(kid[1])
|
|
617
|
+
else:
|
|
618
|
+
raise self.ice()
|
|
619
|
+
elif isinstance(kid[0], (ast.Enum, ast.EnumDef)):
|
|
622
620
|
return self.nu(kid[0])
|
|
623
621
|
else:
|
|
624
622
|
|
|
@@ -691,6 +689,7 @@ class JacParser(Pass):
|
|
|
691
689
|
enum_stmt: NAME (COLON STRING)? EQ expression
|
|
692
690
|
| NAME (COLON STRING)?
|
|
693
691
|
| py_code_block
|
|
692
|
+
| free_code
|
|
694
693
|
"""
|
|
695
694
|
if isinstance(kid[0], ast.PyInlineCode):
|
|
696
695
|
return self.nu(kid[0])
|
|
@@ -739,7 +738,8 @@ class JacParser(Pass):
|
|
|
739
738
|
is_enum_stmt=True,
|
|
740
739
|
)
|
|
741
740
|
)
|
|
742
|
-
|
|
741
|
+
elif isinstance(kid[0], (ast.PyInlineCode, ast.ModuleCode)):
|
|
742
|
+
return self.nu(kid[0])
|
|
743
743
|
raise self.ice()
|
|
744
744
|
|
|
745
745
|
def ability(
|
|
@@ -747,9 +747,9 @@ class JacParser(Pass):
|
|
|
747
747
|
) -> ast.Ability | ast.AbilityDef | ast.FuncCall:
|
|
748
748
|
"""Grammer rule.
|
|
749
749
|
|
|
750
|
-
ability: decorators?
|
|
751
|
-
| decorators? KW_ASYNC? ability_decl
|
|
750
|
+
ability: decorators? KW_ASYNC? ability_decl
|
|
752
751
|
| decorators? genai_ability
|
|
752
|
+
| ability_def
|
|
753
753
|
"""
|
|
754
754
|
chomp = [*kid]
|
|
755
755
|
decorators = chomp[0] if isinstance(chomp[0], ast.SubNodeList) else None
|
|
@@ -768,7 +768,7 @@ class JacParser(Pass):
|
|
|
768
768
|
if isinstance(decorators, ast.SubNodeList):
|
|
769
769
|
for dec in decorators.items:
|
|
770
770
|
if (
|
|
771
|
-
isinstance(dec, ast.
|
|
771
|
+
isinstance(dec, ast.NameAtom)
|
|
772
772
|
and dec.sym_name == "staticmethod"
|
|
773
773
|
and isinstance(ability, (ast.Ability))
|
|
774
774
|
):
|
|
@@ -785,7 +785,7 @@ class JacParser(Pass):
|
|
|
785
785
|
"""Grammar rule.
|
|
786
786
|
|
|
787
787
|
ability_decl: KW_OVERRIDE? KW_STATIC? KW_CAN access_tag? STRING?
|
|
788
|
-
|
|
788
|
+
named_ref (func_decl | event_clause) (code_block | SEMI)
|
|
789
789
|
"""
|
|
790
790
|
chomp = [*kid]
|
|
791
791
|
is_override = (
|
|
@@ -805,7 +805,7 @@ class JacParser(Pass):
|
|
|
805
805
|
signature = chomp[0]
|
|
806
806
|
chomp = chomp[1:]
|
|
807
807
|
body = chomp[0] if isinstance(chomp[0], ast.SubNodeList) else None
|
|
808
|
-
if isinstance(name, ast.
|
|
808
|
+
if isinstance(name, ast.NameAtom) and isinstance(
|
|
809
809
|
signature, (ast.FuncSignature, ast.EventSignature)
|
|
810
810
|
):
|
|
811
811
|
return self.nu(
|
|
@@ -852,7 +852,7 @@ class JacParser(Pass):
|
|
|
852
852
|
"""Grammar rule.
|
|
853
853
|
|
|
854
854
|
abstract_ability: KW_OVERRIDE? KW_STATIC? KW_CAN access_tag? STRING?
|
|
855
|
-
|
|
855
|
+
named_ref (func_decl | event_clause) KW_ABSTRACT SEMI
|
|
856
856
|
"""
|
|
857
857
|
chomp = [*kid]
|
|
858
858
|
is_override = (
|
|
@@ -872,7 +872,7 @@ class JacParser(Pass):
|
|
|
872
872
|
chomp = chomp[1:]
|
|
873
873
|
signature = chomp[0]
|
|
874
874
|
chomp = chomp[1:]
|
|
875
|
-
if isinstance(name, ast.
|
|
875
|
+
if isinstance(name, ast.NameAtom) and isinstance(
|
|
876
876
|
signature, (ast.FuncSignature, ast.EventSignature)
|
|
877
877
|
):
|
|
878
878
|
return self.nu(
|
|
@@ -896,7 +896,7 @@ class JacParser(Pass):
|
|
|
896
896
|
"""Grammar rule.
|
|
897
897
|
|
|
898
898
|
genai_ability: KW_OVERRIDE? KW_STATIC? KW_CAN access_tag? STRING?
|
|
899
|
-
|
|
899
|
+
named_ref (func_decl) KW_BY atomic_call SEMI
|
|
900
900
|
"""
|
|
901
901
|
chomp = [*kid]
|
|
902
902
|
is_override = (
|
|
@@ -919,7 +919,7 @@ class JacParser(Pass):
|
|
|
919
919
|
has_by = isinstance(chomp[0], ast.Token) and chomp[0].name == Tok.KW_BY
|
|
920
920
|
chomp = chomp[1:] if has_by else chomp
|
|
921
921
|
if (
|
|
922
|
-
isinstance(name, ast.
|
|
922
|
+
isinstance(name, ast.NameAtom)
|
|
923
923
|
and isinstance(signature, (ast.FuncSignature, ast.EventSignature))
|
|
924
924
|
and isinstance(chomp[0], ast.FuncCall)
|
|
925
925
|
and has_by
|
|
@@ -1080,7 +1080,7 @@ class JacParser(Pass):
|
|
|
1080
1080
|
| doc_tag? has_stmt
|
|
1081
1081
|
"""
|
|
1082
1082
|
if isinstance(kid[0], ast.ArchBlockStmt):
|
|
1083
|
-
|
|
1083
|
+
ret = self.nu(kid[0])
|
|
1084
1084
|
elif (
|
|
1085
1085
|
isinstance(kid[1], ast.ArchBlockStmt)
|
|
1086
1086
|
and isinstance(kid[1], ast.AstDocNode)
|
|
@@ -1088,10 +1088,12 @@ class JacParser(Pass):
|
|
|
1088
1088
|
):
|
|
1089
1089
|
kid[1].doc = kid[0]
|
|
1090
1090
|
kid[1].add_kids_left([kid[0]])
|
|
1091
|
-
|
|
1092
|
-
|
|
1091
|
+
ret = self.nu(kid[1])
|
|
1093
1092
|
else:
|
|
1094
1093
|
raise self.ice()
|
|
1094
|
+
if isinstance(ret, ast.Ability):
|
|
1095
|
+
ret.signature.is_method = True
|
|
1096
|
+
return ret
|
|
1095
1097
|
|
|
1096
1098
|
def has_stmt(self, kid: list[ast.AstNode]) -> ast.ArchHas:
|
|
1097
1099
|
"""Grammar rule.
|
|
@@ -1209,6 +1211,7 @@ class JacParser(Pass):
|
|
|
1209
1211
|
file_path=self.parse_ref.mod_path,
|
|
1210
1212
|
value=kid[0].value,
|
|
1211
1213
|
line=kid[0].loc.first_line,
|
|
1214
|
+
end_line=kid[0].loc.last_line,
|
|
1212
1215
|
col_start=kid[0].loc.col_start,
|
|
1213
1216
|
col_end=kid[0].loc.col_end,
|
|
1214
1217
|
pos_start=kid[0].pos_start,
|
|
@@ -1258,7 +1261,7 @@ class JacParser(Pass):
|
|
|
1258
1261
|
| try_stmt
|
|
1259
1262
|
| if_stmt
|
|
1260
1263
|
| expression SEMI
|
|
1261
|
-
| yield_expr SEMI
|
|
1264
|
+
| (yield_expr | KW_YIELD) SEMI
|
|
1262
1265
|
| static_assignment
|
|
1263
1266
|
| assignment SEMI
|
|
1264
1267
|
| global_ref SEMI
|
|
@@ -1271,6 +1274,18 @@ class JacParser(Pass):
|
|
|
1271
1274
|
"""
|
|
1272
1275
|
if isinstance(kid[0], ast.CodeBlockStmt) and len(kid) < 2:
|
|
1273
1276
|
return self.nu(kid[0])
|
|
1277
|
+
elif isinstance(kid[0], ast.Token) and kid[0].name == Tok.KW_YIELD:
|
|
1278
|
+
return ast.ExprStmt(
|
|
1279
|
+
expr=(
|
|
1280
|
+
expr := ast.YieldExpr(
|
|
1281
|
+
expr=None,
|
|
1282
|
+
with_from=False,
|
|
1283
|
+
kid=kid,
|
|
1284
|
+
)
|
|
1285
|
+
),
|
|
1286
|
+
in_fstring=False,
|
|
1287
|
+
kid=[expr],
|
|
1288
|
+
)
|
|
1274
1289
|
elif isinstance(kid[0], ast.Expr):
|
|
1275
1290
|
return ast.ExprStmt(
|
|
1276
1291
|
expr=kid[0],
|
|
@@ -1617,6 +1632,21 @@ class JacParser(Pass):
|
|
|
1617
1632
|
else:
|
|
1618
1633
|
raise self.ice()
|
|
1619
1634
|
|
|
1635
|
+
def check_stmt(self, kid: list[ast.AstNode]) -> ast.CheckStmt:
|
|
1636
|
+
"""Grammar rule.
|
|
1637
|
+
|
|
1638
|
+
check_stmt: KW_CHECK expression
|
|
1639
|
+
"""
|
|
1640
|
+
if isinstance(kid[1], ast.Expr):
|
|
1641
|
+
return self.nu(
|
|
1642
|
+
ast.CheckStmt(
|
|
1643
|
+
target=kid[1],
|
|
1644
|
+
kid=kid,
|
|
1645
|
+
)
|
|
1646
|
+
)
|
|
1647
|
+
else:
|
|
1648
|
+
raise self.ice()
|
|
1649
|
+
|
|
1620
1650
|
def ctrl_stmt(self, kid: list[ast.AstNode]) -> ast.CtrlStmt:
|
|
1621
1651
|
"""Grammar rule.
|
|
1622
1652
|
|
|
@@ -2300,7 +2330,7 @@ class JacParser(Pass):
|
|
|
2300
2330
|
"""Grammar rule.
|
|
2301
2331
|
|
|
2302
2332
|
atomic_chain: atomic_chain NULL_OK? (filter_compr | assign_compr | index_slice)
|
|
2303
|
-
| atomic_chain NULL_OK? (DOT_BKWD | DOT_FWD | DOT)
|
|
2333
|
+
| atomic_chain NULL_OK? (DOT_BKWD | DOT_FWD | DOT) named_ref
|
|
2304
2334
|
| (atomic_call | atom | edge_ref_chain)
|
|
2305
2335
|
"""
|
|
2306
2336
|
if len(kid) < 2 and isinstance(kid[0], ast.Expr):
|
|
@@ -2436,10 +2466,11 @@ class JacParser(Pass):
|
|
|
2436
2466
|
def atom(self, kid: list[ast.AstNode]) -> ast.Expr:
|
|
2437
2467
|
"""Grammar rule.
|
|
2438
2468
|
|
|
2439
|
-
atom:
|
|
2469
|
+
atom: named_ref
|
|
2440
2470
|
| LPAREN (expression | yield_expr) RPAREN
|
|
2441
2471
|
| atom_collection
|
|
2442
2472
|
| atom_literal
|
|
2473
|
+
| type_ref
|
|
2443
2474
|
"""
|
|
2444
2475
|
if len(kid) == 1:
|
|
2445
2476
|
if isinstance(kid[0], ast.AtomExpr):
|
|
@@ -2464,7 +2495,6 @@ class JacParser(Pass):
|
|
|
2464
2495
|
|
|
2465
2496
|
yield_expr:
|
|
2466
2497
|
| KW_YIELD KW_FROM? expression
|
|
2467
|
-
| KW_YIELD
|
|
2468
2498
|
"""
|
|
2469
2499
|
if isinstance(kid[-1], ast.Expr):
|
|
2470
2500
|
return self.nu(
|
|
@@ -2474,19 +2504,6 @@ class JacParser(Pass):
|
|
|
2474
2504
|
kid=kid,
|
|
2475
2505
|
)
|
|
2476
2506
|
)
|
|
2477
|
-
elif (
|
|
2478
|
-
len(kid) == 1
|
|
2479
|
-
and isinstance(kid[0], ast.Token)
|
|
2480
|
-
and kid[0].name == Tok.KW_YIELD
|
|
2481
|
-
):
|
|
2482
|
-
return self.nu(
|
|
2483
|
-
ast.YieldExpr(
|
|
2484
|
-
expr=None,
|
|
2485
|
-
with_from=False,
|
|
2486
|
-
kid=kid,
|
|
2487
|
-
)
|
|
2488
|
-
)
|
|
2489
|
-
|
|
2490
2507
|
else:
|
|
2491
2508
|
raise self.ice()
|
|
2492
2509
|
|
|
@@ -2730,11 +2747,11 @@ class JacParser(Pass):
|
|
|
2730
2747
|
def kw_expr(self, kid: list[ast.AstNode]) -> ast.KWPair:
|
|
2731
2748
|
"""Grammar rule.
|
|
2732
2749
|
|
|
2733
|
-
kw_expr:
|
|
2750
|
+
kw_expr: named_ref EQ expression | STAR_POW expression
|
|
2734
2751
|
"""
|
|
2735
2752
|
if (
|
|
2736
2753
|
len(kid) == 3
|
|
2737
|
-
and isinstance(kid[0], ast.
|
|
2754
|
+
and isinstance(kid[0], ast.NameAtom)
|
|
2738
2755
|
and isinstance(kid[2], ast.Expr)
|
|
2739
2756
|
):
|
|
2740
2757
|
return self.nu(
|
|
@@ -3031,11 +3048,11 @@ class JacParser(Pass):
|
|
|
3031
3048
|
|
|
3032
3049
|
node_ref: NODE_OP NAME
|
|
3033
3050
|
"""
|
|
3034
|
-
if isinstance(kid[0], ast.Token) and isinstance(kid[1], ast.
|
|
3051
|
+
if isinstance(kid[0], ast.Token) and isinstance(kid[1], ast.NameAtom):
|
|
3035
3052
|
return self.nu(
|
|
3036
3053
|
ast.ArchRef(
|
|
3037
|
-
|
|
3038
|
-
|
|
3054
|
+
arch_type=kid[0],
|
|
3055
|
+
arch_name=kid[1],
|
|
3039
3056
|
kid=kid,
|
|
3040
3057
|
)
|
|
3041
3058
|
)
|
|
@@ -3047,11 +3064,11 @@ class JacParser(Pass):
|
|
|
3047
3064
|
|
|
3048
3065
|
edge_ref: EDGE_OP NAME
|
|
3049
3066
|
"""
|
|
3050
|
-
if isinstance(kid[0], ast.Token) and isinstance(kid[1], ast.
|
|
3067
|
+
if isinstance(kid[0], ast.Token) and isinstance(kid[1], ast.NameAtom):
|
|
3051
3068
|
return self.nu(
|
|
3052
3069
|
ast.ArchRef(
|
|
3053
|
-
|
|
3054
|
-
|
|
3070
|
+
arch_type=kid[0],
|
|
3071
|
+
arch_name=kid[1],
|
|
3055
3072
|
kid=kid,
|
|
3056
3073
|
)
|
|
3057
3074
|
)
|
|
@@ -3063,11 +3080,11 @@ class JacParser(Pass):
|
|
|
3063
3080
|
|
|
3064
3081
|
walker_ref: WALKER_OP NAME
|
|
3065
3082
|
"""
|
|
3066
|
-
if isinstance(kid[0], ast.Token) and isinstance(kid[1], ast.
|
|
3083
|
+
if isinstance(kid[0], ast.Token) and isinstance(kid[1], ast.NameAtom):
|
|
3067
3084
|
return self.nu(
|
|
3068
3085
|
ast.ArchRef(
|
|
3069
|
-
|
|
3070
|
-
|
|
3086
|
+
arch_type=kid[0],
|
|
3087
|
+
arch_name=kid[1],
|
|
3071
3088
|
kid=kid,
|
|
3072
3089
|
)
|
|
3073
3090
|
)
|
|
@@ -3079,11 +3096,11 @@ class JacParser(Pass):
|
|
|
3079
3096
|
|
|
3080
3097
|
class_ref: CLASS_OP name_ref
|
|
3081
3098
|
"""
|
|
3082
|
-
if isinstance(kid[0], ast.Token) and isinstance(kid[1], ast.
|
|
3099
|
+
if isinstance(kid[0], ast.Token) and isinstance(kid[1], ast.NameAtom):
|
|
3083
3100
|
return self.nu(
|
|
3084
3101
|
ast.ArchRef(
|
|
3085
|
-
|
|
3086
|
-
|
|
3102
|
+
arch_type=kid[0],
|
|
3103
|
+
arch_name=kid[1],
|
|
3087
3104
|
kid=kid,
|
|
3088
3105
|
)
|
|
3089
3106
|
)
|
|
@@ -3095,11 +3112,11 @@ class JacParser(Pass):
|
|
|
3095
3112
|
|
|
3096
3113
|
object_ref: OBJECT_OP name_ref
|
|
3097
3114
|
"""
|
|
3098
|
-
if isinstance(kid[0], ast.Token) and isinstance(kid[1], ast.
|
|
3115
|
+
if isinstance(kid[0], ast.Token) and isinstance(kid[1], ast.NameAtom):
|
|
3099
3116
|
return self.nu(
|
|
3100
3117
|
ast.ArchRef(
|
|
3101
|
-
|
|
3102
|
-
|
|
3118
|
+
arch_type=kid[0],
|
|
3119
|
+
arch_name=kid[1],
|
|
3103
3120
|
kid=kid,
|
|
3104
3121
|
)
|
|
3105
3122
|
)
|
|
@@ -3111,11 +3128,11 @@ class JacParser(Pass):
|
|
|
3111
3128
|
|
|
3112
3129
|
type_ref: TYPE_OP name_ref
|
|
3113
3130
|
"""
|
|
3114
|
-
if isinstance(kid[0], ast.Token) and isinstance(kid[1], ast.
|
|
3131
|
+
if isinstance(kid[0], ast.Token) and isinstance(kid[1], ast.NameAtom):
|
|
3115
3132
|
return self.nu(
|
|
3116
3133
|
ast.ArchRef(
|
|
3117
|
-
|
|
3118
|
-
|
|
3134
|
+
arch_type=kid[0],
|
|
3135
|
+
arch_name=kid[1],
|
|
3119
3136
|
kid=kid,
|
|
3120
3137
|
)
|
|
3121
3138
|
)
|
|
@@ -3127,11 +3144,11 @@ class JacParser(Pass):
|
|
|
3127
3144
|
|
|
3128
3145
|
enum_ref: ENUM_OP NAME
|
|
3129
3146
|
"""
|
|
3130
|
-
if isinstance(kid[0], ast.Token) and isinstance(kid[1], ast.
|
|
3147
|
+
if isinstance(kid[0], ast.Token) and isinstance(kid[1], ast.NameAtom):
|
|
3131
3148
|
return self.nu(
|
|
3132
3149
|
ast.ArchRef(
|
|
3133
|
-
|
|
3134
|
-
|
|
3150
|
+
arch_type=kid[0],
|
|
3151
|
+
arch_name=kid[1],
|
|
3135
3152
|
kid=kid,
|
|
3136
3153
|
)
|
|
3137
3154
|
)
|
|
@@ -3143,11 +3160,11 @@ class JacParser(Pass):
|
|
|
3143
3160
|
|
|
3144
3161
|
ability_ref: ABILITY_OP (special_ref | name_ref)
|
|
3145
3162
|
"""
|
|
3146
|
-
if isinstance(kid[0], ast.Token) and isinstance(kid[1], ast.
|
|
3163
|
+
if isinstance(kid[0], ast.Token) and isinstance(kid[1], ast.NameAtom):
|
|
3147
3164
|
return self.nu(
|
|
3148
3165
|
ast.ArchRef(
|
|
3149
|
-
|
|
3150
|
-
|
|
3166
|
+
arch_type=kid[0],
|
|
3167
|
+
arch_name=kid[1],
|
|
3151
3168
|
kid=kid,
|
|
3152
3169
|
)
|
|
3153
3170
|
)
|
|
@@ -3601,7 +3618,7 @@ class JacParser(Pass):
|
|
|
3601
3618
|
as_pattern: pattern KW_AS NAME
|
|
3602
3619
|
"""
|
|
3603
3620
|
if isinstance(kid[0], ast.MatchPattern) and isinstance(
|
|
3604
|
-
kid[2], ast.
|
|
3621
|
+
kid[2], ast.NameAtom
|
|
3605
3622
|
):
|
|
3606
3623
|
return self.nu(
|
|
3607
3624
|
ast.MatchAs(
|
|
@@ -3672,7 +3689,7 @@ class JacParser(Pass):
|
|
|
3672
3689
|
kid=kid,
|
|
3673
3690
|
)
|
|
3674
3691
|
)
|
|
3675
|
-
if isinstance(kid[0], ast.
|
|
3692
|
+
if isinstance(kid[0], ast.NameAtom):
|
|
3676
3693
|
return self.nu(
|
|
3677
3694
|
ast.MatchAs(
|
|
3678
3695
|
name=kid[0],
|
|
@@ -3784,7 +3801,7 @@ class JacParser(Pass):
|
|
|
3784
3801
|
chomp = chomp[2:]
|
|
3785
3802
|
else:
|
|
3786
3803
|
raise self.ice()
|
|
3787
|
-
elif isinstance(cur_element, ast.
|
|
3804
|
+
elif isinstance(cur_element, ast.NameAtom):
|
|
3788
3805
|
chomp = chomp[1:]
|
|
3789
3806
|
else:
|
|
3790
3807
|
break
|
|
@@ -3815,7 +3832,7 @@ class JacParser(Pass):
|
|
|
3815
3832
|
else None
|
|
3816
3833
|
)
|
|
3817
3834
|
)
|
|
3818
|
-
if isinstance(name, (ast.
|
|
3835
|
+
if isinstance(name, (ast.NameAtom, ast.AtomTrailer)):
|
|
3819
3836
|
kid_nodes = [name, lparen]
|
|
3820
3837
|
if arg:
|
|
3821
3838
|
kid_nodes.append(arg)
|
|
@@ -3878,7 +3895,7 @@ class JacParser(Pass):
|
|
|
3878
3895
|
name = kid[2]
|
|
3879
3896
|
eq = kid[3]
|
|
3880
3897
|
value = kid[4]
|
|
3881
|
-
if not isinstance(name, ast.
|
|
3898
|
+
if not isinstance(name, ast.NameAtom) or not isinstance(
|
|
3882
3899
|
value, ast.MatchPattern
|
|
3883
3900
|
):
|
|
3884
3901
|
raise self.ice()
|
|
@@ -3891,14 +3908,14 @@ class JacParser(Pass):
|
|
|
3891
3908
|
name = kid[0]
|
|
3892
3909
|
eq = kid[1]
|
|
3893
3910
|
value = kid[2]
|
|
3894
|
-
if not isinstance(name, ast.
|
|
3911
|
+
if not isinstance(name, ast.NameAtom) or not isinstance(
|
|
3895
3912
|
value, ast.MatchPattern
|
|
3896
3913
|
):
|
|
3897
3914
|
raise self.ice()
|
|
3898
3915
|
new_kid = [
|
|
3899
3916
|
ast.MatchKVPair(key=name, value=value, kid=[name, eq, value])
|
|
3900
3917
|
]
|
|
3901
|
-
if isinstance(name, ast.
|
|
3918
|
+
if isinstance(name, ast.NameAtom) and isinstance(value, ast.MatchPattern):
|
|
3902
3919
|
valid_kid = [i for i in new_kid if isinstance(i, ast.MatchKVPair)]
|
|
3903
3920
|
return ast.SubNodeList[ast.MatchKVPair](
|
|
3904
3921
|
items=valid_kid,
|
|
@@ -3913,6 +3930,15 @@ class JacParser(Pass):
|
|
|
3913
3930
|
ret_type = ast.Token
|
|
3914
3931
|
if token.type in [Tok.NAME, Tok.KWESC_NAME]:
|
|
3915
3932
|
ret_type = ast.Name
|
|
3933
|
+
if token.type in [
|
|
3934
|
+
Tok.KW_INIT,
|
|
3935
|
+
Tok.KW_POST_INIT,
|
|
3936
|
+
Tok.KW_ROOT,
|
|
3937
|
+
Tok.KW_SUPER,
|
|
3938
|
+
Tok.KW_SELF,
|
|
3939
|
+
Tok.KW_HERE,
|
|
3940
|
+
]:
|
|
3941
|
+
ret_type = ast.Name
|
|
3916
3942
|
elif token.type == Tok.SEMI:
|
|
3917
3943
|
ret_type = ast.Semi
|
|
3918
3944
|
elif token.type == Tok.NULL:
|
|
@@ -3942,6 +3968,7 @@ class JacParser(Pass):
|
|
|
3942
3968
|
name=token.type,
|
|
3943
3969
|
value=token.value[2:] if token.type == Tok.KWESC_NAME else token.value,
|
|
3944
3970
|
line=token.line if token.line is not None else 0,
|
|
3971
|
+
end_line=token.end_line if token.end_line is not None else 0,
|
|
3945
3972
|
col_start=token.column if token.column is not None else 0,
|
|
3946
3973
|
col_end=token.end_column if token.end_column is not None else 0,
|
|
3947
3974
|
pos_start=token.start_pos if token.start_pos is not None else 0,
|
|
@@ -7,27 +7,36 @@ import os
|
|
|
7
7
|
from typing import Optional
|
|
8
8
|
|
|
9
9
|
import jaclang.compiler.absyntree as ast
|
|
10
|
-
from jaclang.compiler.
|
|
10
|
+
from jaclang.compiler.constant import SymbolAccess
|
|
11
|
+
from jaclang.compiler.passes import Pass
|
|
12
|
+
from jaclang.compiler.symtable import SymbolTable
|
|
13
|
+
from jaclang.settings import settings
|
|
11
14
|
|
|
12
15
|
|
|
13
|
-
class AccessCheckPass(
|
|
16
|
+
class AccessCheckPass(Pass):
|
|
14
17
|
"""Jac Ast Access Check pass."""
|
|
15
18
|
|
|
16
19
|
def after_pass(self) -> None:
|
|
17
20
|
"""After pass."""
|
|
18
21
|
pass
|
|
19
22
|
|
|
23
|
+
def exit_node(self, node: ast.AstNode) -> None:
|
|
24
|
+
"""Exit node."""
|
|
25
|
+
super().exit_node(node)
|
|
26
|
+
if settings.lsp_debug and isinstance(node, ast.NameAtom) and not node.sym:
|
|
27
|
+
self.warning(f"Name {node.sym_name} not present in symbol table")
|
|
28
|
+
|
|
20
29
|
def access_check(self, node: ast.Name) -> None:
|
|
21
30
|
"""Access check."""
|
|
22
31
|
node_info = (
|
|
23
32
|
node.sym_tab.lookup(node.sym_name)
|
|
24
|
-
if isinstance(node.sym_tab,
|
|
33
|
+
if isinstance(node.sym_tab, SymbolTable)
|
|
25
34
|
else None
|
|
26
35
|
)
|
|
27
36
|
|
|
28
|
-
if node.
|
|
37
|
+
if node.sym:
|
|
29
38
|
decl_package_path = os.path.dirname(
|
|
30
|
-
os.path.abspath(node.
|
|
39
|
+
os.path.abspath(node.sym.defn[-1].loc.mod_path)
|
|
31
40
|
)
|
|
32
41
|
use_package_path = os.path.dirname(os.path.abspath(node.loc.mod_path))
|
|
33
42
|
else:
|
|
@@ -35,7 +44,7 @@ class AccessCheckPass(SymTabPass):
|
|
|
35
44
|
|
|
36
45
|
if (
|
|
37
46
|
node_info
|
|
38
|
-
and node.
|
|
47
|
+
and node.sym
|
|
39
48
|
and node_info.access == SymbolAccess.PROTECTED
|
|
40
49
|
and decl_package_path != use_package_path
|
|
41
50
|
):
|
|
@@ -46,12 +55,12 @@ class AccessCheckPass(SymTabPass):
|
|
|
46
55
|
|
|
47
56
|
if (
|
|
48
57
|
node_info
|
|
49
|
-
and node.
|
|
58
|
+
and node.sym
|
|
50
59
|
and node_info.access == SymbolAccess.PRIVATE
|
|
51
|
-
and node.
|
|
60
|
+
and node.sym.defn[-1].loc.mod_path != node.loc.mod_path
|
|
52
61
|
):
|
|
53
62
|
return self.error(
|
|
54
|
-
f'Can not access private variable "{node.sym_name}" from {node.
|
|
63
|
+
f'Can not access private variable "{node.sym_name}" from {node.sym.defn[-1].loc.mod_path}'
|
|
55
64
|
f" to {node.loc.mod_path}."
|
|
56
65
|
)
|
|
57
66
|
|
|
@@ -59,7 +68,6 @@ class AccessCheckPass(SymTabPass):
|
|
|
59
68
|
self, node: ast.AstSymbolNode, acc_tag: Optional[SymbolAccess] = None
|
|
60
69
|
) -> None:
|
|
61
70
|
"""Access register."""
|
|
62
|
-
node.sym_info.acc_tag = acc_tag
|
|
63
71
|
|
|
64
72
|
def enter_global_vars(self, node: ast.GlobalVars) -> None:
|
|
65
73
|
"""Sub objects.
|
|
@@ -167,7 +175,7 @@ class AccessCheckPass(SymTabPass):
|
|
|
167
175
|
if isinstance(node.parent, ast.FuncCall):
|
|
168
176
|
self.access_check(node)
|
|
169
177
|
|
|
170
|
-
if node.
|
|
171
|
-
node=node.
|
|
178
|
+
if node.sym and Pass.has_parent_of_type(
|
|
179
|
+
node=node.sym.defn[-1], typ=ast.GlobalVars
|
|
172
180
|
):
|
|
173
181
|
self.access_check(node)
|