jaclang 0.7.5__py3-none-any.whl → 0.7.6__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 +167 -26
- jaclang/compiler/constant.py +98 -2
- jaclang/compiler/jac.lark +2 -0
- jaclang/compiler/parser.py +4 -0
- jaclang/compiler/passes/main/access_modifier_pass.py +5 -3
- jaclang/compiler/passes/main/def_impl_match_pass.py +3 -1
- jaclang/compiler/passes/main/def_use_pass.py +27 -39
- jaclang/compiler/passes/main/fuse_typeinfo_pass.py +34 -12
- jaclang/compiler/passes/main/sub_node_tab_pass.py +0 -5
- jaclang/compiler/passes/main/sym_tab_build_pass.py +31 -181
- 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/symtable.py +118 -65
- jaclang/core/aott.py +7 -3
- jaclang/core/importer.py +1 -1
- jaclang/langserve/engine.py +100 -36
- jaclang/langserve/server.py +34 -61
- jaclang/langserve/tests/fixtures/base_module_structure.jac +28 -0
- 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 +90 -6
- jaclang/langserve/utils.py +114 -4
- jaclang/plugin/default.py +2 -2
- jaclang/plugin/feature.py +1 -1
- jaclang/plugin/spec.py +1 -1
- jaclang/tests/fixtures/aott_raise.jac +1 -1
- jaclang/tests/fixtures/edgetypeissue.jac +10 -0
- jaclang/tests/fixtures/hello.jac +1 -1
- 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_language.py +106 -96
- {jaclang-0.7.5.dist-info → jaclang-0.7.6.dist-info}/METADATA +1 -1
- {jaclang-0.7.5.dist-info → jaclang-0.7.6.dist-info}/RECORD +45 -50
- 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/edgetypetest.jac +0 -16
- {jaclang-0.7.5.dist-info → jaclang-0.7.6.dist-info}/WHEEL +0 -0
- {jaclang-0.7.5.dist-info → jaclang-0.7.6.dist-info}/entry_points.txt +0 -0
jaclang/compiler/absyntree.py
CHANGED
|
@@ -3,24 +3,38 @@
|
|
|
3
3
|
from __future__ import annotations
|
|
4
4
|
|
|
5
5
|
import ast as ast3
|
|
6
|
+
import builtins
|
|
6
7
|
import os
|
|
7
8
|
from hashlib import md5
|
|
8
9
|
from types import EllipsisType
|
|
9
|
-
from typing import
|
|
10
|
+
from typing import (
|
|
11
|
+
Any,
|
|
12
|
+
Callable,
|
|
13
|
+
Generic,
|
|
14
|
+
Optional,
|
|
15
|
+
Sequence,
|
|
16
|
+
TYPE_CHECKING,
|
|
17
|
+
Type,
|
|
18
|
+
TypeVar,
|
|
19
|
+
)
|
|
20
|
+
|
|
10
21
|
|
|
11
22
|
from jaclang.compiler import TOKEN_MAP
|
|
12
23
|
from jaclang.compiler.codeloc import CodeGenTarget, CodeLocInfo
|
|
13
|
-
from jaclang.compiler.constant import
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
SymbolAccess,
|
|
19
|
-
SymbolTable,
|
|
24
|
+
from jaclang.compiler.constant import (
|
|
25
|
+
Constants as Con,
|
|
26
|
+
EdgeDir,
|
|
27
|
+
JacSemTokenModifier as SemTokMod,
|
|
28
|
+
JacSemTokenType as SemTokType,
|
|
20
29
|
SymbolType,
|
|
21
30
|
)
|
|
31
|
+
from jaclang.compiler.constant import DELIM_MAP, SymbolAccess, Tokens as Tok
|
|
32
|
+
from jaclang.compiler.semtable import SemRegistry
|
|
22
33
|
from jaclang.utils.treeprinter import dotgen_ast_tree, print_ast_tree
|
|
23
34
|
|
|
35
|
+
if TYPE_CHECKING:
|
|
36
|
+
from jaclang.compiler.symtable import Symbol, SymbolTable
|
|
37
|
+
|
|
24
38
|
|
|
25
39
|
class AstNode:
|
|
26
40
|
"""Abstract syntax tree node for Jac."""
|
|
@@ -29,12 +43,35 @@ class AstNode:
|
|
|
29
43
|
"""Initialize ast."""
|
|
30
44
|
self.parent: Optional[AstNode] = None
|
|
31
45
|
self.kid: list[AstNode] = [x.set_parent(self) for x in kid]
|
|
32
|
-
self.
|
|
46
|
+
self._sym_tab: Optional[SymbolTable] = None
|
|
33
47
|
self._sub_node_tab: dict[type, list[AstNode]] = {}
|
|
48
|
+
self._in_mod_nodes: list[AstNode] = []
|
|
34
49
|
self.gen: CodeGenTarget = CodeGenTarget()
|
|
35
50
|
self.meta: dict[str, str] = {}
|
|
36
51
|
self.loc: CodeLocInfo = CodeLocInfo(*self.resolve_tok_range())
|
|
37
52
|
|
|
53
|
+
@property
|
|
54
|
+
def sym_tab(self) -> SymbolTable:
|
|
55
|
+
"""Get symbol table."""
|
|
56
|
+
# sym_tab should never be accessed without being set in codebase
|
|
57
|
+
if not self._sym_tab:
|
|
58
|
+
import traceback
|
|
59
|
+
|
|
60
|
+
if self.parent:
|
|
61
|
+
print(f"Parent: {self.parent.pp()}")
|
|
62
|
+
print("Node: ", self.pp())
|
|
63
|
+
stack_trace = traceback.format_stack()
|
|
64
|
+
print("".join(stack_trace))
|
|
65
|
+
raise ValueError(
|
|
66
|
+
f"Symbol table not set for {type(self).__name__}. Impossible."
|
|
67
|
+
)
|
|
68
|
+
return self._sym_tab
|
|
69
|
+
|
|
70
|
+
@sym_tab.setter
|
|
71
|
+
def sym_tab(self, sym_tab: SymbolTable) -> None:
|
|
72
|
+
"""Set symbol table."""
|
|
73
|
+
self._sym_tab = sym_tab
|
|
74
|
+
|
|
38
75
|
def add_kids_left(
|
|
39
76
|
self, nodes: Sequence[AstNode], pos_update: bool = True
|
|
40
77
|
) -> AstNode:
|
|
@@ -352,6 +389,17 @@ class AstImplOnlyNode(CodeBlockStmt, ElementStmt, AstSymbolNode):
|
|
|
352
389
|
sym_category=SymbolType.IMPL,
|
|
353
390
|
)
|
|
354
391
|
|
|
392
|
+
@property
|
|
393
|
+
def sym_tab(self) -> SymbolTable:
|
|
394
|
+
"""Get symbol table."""
|
|
395
|
+
return super().sym_tab
|
|
396
|
+
|
|
397
|
+
@sym_tab.setter
|
|
398
|
+
def sym_tab(self, sym_tab: SymbolTable) -> None:
|
|
399
|
+
"""Set symbol table."""
|
|
400
|
+
self._sym_tab = sym_tab
|
|
401
|
+
self.name_spec._sym_tab = sym_tab
|
|
402
|
+
|
|
355
403
|
def create_impl_name_node(self) -> Name:
|
|
356
404
|
"""Create impl name."""
|
|
357
405
|
ret = Name(
|
|
@@ -451,6 +499,41 @@ class NameAtom(AtomExpr, EnumBlockStmt):
|
|
|
451
499
|
"""Set type symbol table."""
|
|
452
500
|
self._type_sym_tab = type_sym_tab
|
|
453
501
|
|
|
502
|
+
@property
|
|
503
|
+
def sem_token(self) -> Optional[tuple[SemTokType, SemTokMod]]:
|
|
504
|
+
"""Resolve semantic token."""
|
|
505
|
+
if isinstance(self.name_of, BuiltinType):
|
|
506
|
+
return SemTokType.CLASS, SemTokMod.DECLARATION
|
|
507
|
+
name_of = (
|
|
508
|
+
self.sym.decl.name_of
|
|
509
|
+
if self.sym and not isinstance(self.sym.decl.name_of, Name)
|
|
510
|
+
else self.name_of
|
|
511
|
+
)
|
|
512
|
+
if isinstance(name_of, ModulePath):
|
|
513
|
+
return SemTokType.NAMESPACE, SemTokMod.DEFINITION
|
|
514
|
+
if isinstance(name_of, Architype):
|
|
515
|
+
return SemTokType.CLASS, SemTokMod.DECLARATION
|
|
516
|
+
if isinstance(name_of, Enum):
|
|
517
|
+
return SemTokType.ENUM, SemTokMod.DECLARATION
|
|
518
|
+
if isinstance(name_of, Ability) and name_of.is_method:
|
|
519
|
+
return SemTokType.METHOD, SemTokMod.DECLARATION
|
|
520
|
+
if isinstance(name_of, (Ability, Test)):
|
|
521
|
+
return SemTokType.FUNCTION, SemTokMod.DECLARATION
|
|
522
|
+
if isinstance(name_of, ParamVar):
|
|
523
|
+
return SemTokType.PARAMETER, SemTokMod.DECLARATION
|
|
524
|
+
if self.sym and self.sym_name.isupper():
|
|
525
|
+
return SemTokType.VARIABLE, SemTokMod.READONLY
|
|
526
|
+
if (
|
|
527
|
+
self.sym
|
|
528
|
+
and self.sym.decl.name_of == self.sym.decl
|
|
529
|
+
and self.sym_name in dir(builtins)
|
|
530
|
+
and callable(getattr(builtins, self.sym_name))
|
|
531
|
+
):
|
|
532
|
+
return SemTokType.FUNCTION, SemTokMod.DEFINITION
|
|
533
|
+
if self.sym:
|
|
534
|
+
return SemTokType.PROPERTY, SemTokMod.DEFINITION
|
|
535
|
+
return None
|
|
536
|
+
|
|
454
537
|
|
|
455
538
|
class ArchSpec(ElementStmt, CodeBlockStmt, AstSymbolNode, AstDocNode, AstSemStrNode):
|
|
456
539
|
"""ArchSpec node type for Jac Ast."""
|
|
@@ -558,7 +641,10 @@ class Module(AstDocNode):
|
|
|
558
641
|
@property
|
|
559
642
|
def annexable_by(self) -> Optional[str]:
|
|
560
643
|
"""Get annexable by."""
|
|
561
|
-
if not self.stub_only and
|
|
644
|
+
if not self.stub_only and (
|
|
645
|
+
self.loc.mod_path.endswith("impl.jac")
|
|
646
|
+
or self.loc.mod_path.endswith("test.jac")
|
|
647
|
+
):
|
|
562
648
|
head_mod_name = self.name.split(".")[0]
|
|
563
649
|
potential_path = os.path.join(
|
|
564
650
|
os.path.dirname(self.loc.mod_path),
|
|
@@ -566,7 +652,8 @@ class Module(AstDocNode):
|
|
|
566
652
|
)
|
|
567
653
|
if os.path.exists(potential_path):
|
|
568
654
|
return potential_path
|
|
569
|
-
|
|
655
|
+
annex_dir = os.path.split(os.path.dirname(self.loc.mod_path))[-1]
|
|
656
|
+
if annex_dir.endswith(".impl") or annex_dir.endswith(".test"):
|
|
570
657
|
head_mod_name = os.path.split(os.path.dirname(self.loc.mod_path))[
|
|
571
658
|
-1
|
|
572
659
|
].split(".")[0]
|
|
@@ -821,13 +908,12 @@ class ModulePath(AstSymbolNode):
|
|
|
821
908
|
level: int,
|
|
822
909
|
alias: Optional[Name],
|
|
823
910
|
kid: Sequence[AstNode],
|
|
824
|
-
sub_module: Optional[Module] = None,
|
|
825
911
|
) -> None:
|
|
826
912
|
"""Initialize module path node."""
|
|
827
913
|
self.path = path
|
|
828
914
|
self.level = level
|
|
829
915
|
self.alias = alias
|
|
830
|
-
self.sub_module =
|
|
916
|
+
self.sub_module: Optional[Module] = None
|
|
831
917
|
|
|
832
918
|
name_spec = alias if alias else path[0] if path else None
|
|
833
919
|
if not isinstance(name_spec, Name):
|
|
@@ -880,12 +966,11 @@ class ModuleItem(AstSymbolNode):
|
|
|
880
966
|
name: Name,
|
|
881
967
|
alias: Optional[Name],
|
|
882
968
|
kid: Sequence[AstNode],
|
|
883
|
-
sub_module: Optional[Module] = None,
|
|
884
969
|
) -> None:
|
|
885
970
|
"""Initialize module item node."""
|
|
886
971
|
self.name = name
|
|
887
972
|
self.alias = alias
|
|
888
|
-
self.sub_module =
|
|
973
|
+
self.sub_module: Optional[Module] = None
|
|
889
974
|
AstNode.__init__(self, kid=kid)
|
|
890
975
|
AstSymbolNode.__init__(
|
|
891
976
|
self,
|
|
@@ -894,6 +979,24 @@ class ModuleItem(AstSymbolNode):
|
|
|
894
979
|
sym_category=SymbolType.MOD_VAR,
|
|
895
980
|
)
|
|
896
981
|
|
|
982
|
+
@property
|
|
983
|
+
def from_parent(self) -> Import:
|
|
984
|
+
"""Get import parent."""
|
|
985
|
+
if (
|
|
986
|
+
not self.parent
|
|
987
|
+
or not self.parent.parent
|
|
988
|
+
or not isinstance(self.parent.parent, Import)
|
|
989
|
+
):
|
|
990
|
+
raise ValueError("Import parent not found. Not Possible.")
|
|
991
|
+
return self.parent.parent
|
|
992
|
+
|
|
993
|
+
@property
|
|
994
|
+
def from_mod_path(self) -> ModulePath:
|
|
995
|
+
"""Get relevant module path."""
|
|
996
|
+
if not self.from_parent.from_loc:
|
|
997
|
+
raise ValueError("Module items should have module path. Not Possible.")
|
|
998
|
+
return self.from_parent.from_loc
|
|
999
|
+
|
|
897
1000
|
def normalize(self, deep: bool = False) -> bool:
|
|
898
1001
|
"""Normalize module item node."""
|
|
899
1002
|
res = True
|
|
@@ -1149,6 +1252,7 @@ class Ability(
|
|
|
1149
1252
|
ElementStmt,
|
|
1150
1253
|
AstAsyncNode,
|
|
1151
1254
|
ArchBlockStmt,
|
|
1255
|
+
EnumBlockStmt,
|
|
1152
1256
|
CodeBlockStmt,
|
|
1153
1257
|
AstSemStrNode,
|
|
1154
1258
|
AstImplNeedingNode,
|
|
@@ -1195,6 +1299,17 @@ class Ability(
|
|
|
1195
1299
|
"""Check if is func."""
|
|
1196
1300
|
return self.signature.is_method
|
|
1197
1301
|
|
|
1302
|
+
@property
|
|
1303
|
+
def owner_method(self) -> Optional[Architype | Enum]:
|
|
1304
|
+
"""Check if is owner method."""
|
|
1305
|
+
return (
|
|
1306
|
+
self.parent.parent
|
|
1307
|
+
if self.parent
|
|
1308
|
+
and self.parent.parent
|
|
1309
|
+
and isinstance(self.parent.parent, (Architype, Enum))
|
|
1310
|
+
else None
|
|
1311
|
+
)
|
|
1312
|
+
|
|
1198
1313
|
@property
|
|
1199
1314
|
def is_genai_ability(self) -> bool:
|
|
1200
1315
|
"""Check if is genai_ability."""
|
|
@@ -3051,6 +3166,22 @@ class AtomTrailer(Expr):
|
|
|
3051
3166
|
self.set_kids(nodes=new_kid)
|
|
3052
3167
|
return res
|
|
3053
3168
|
|
|
3169
|
+
@property
|
|
3170
|
+
def as_attr_list(self) -> list[AstSymbolNode]:
|
|
3171
|
+
"""Unwind trailer into list of ast symbol nodes."""
|
|
3172
|
+
left = self.right if isinstance(self.right, AtomTrailer) else self.target
|
|
3173
|
+
right = self.target if isinstance(self.right, AtomTrailer) else self.right
|
|
3174
|
+
trag_list: list[AstSymbolNode] = (
|
|
3175
|
+
[right] if isinstance(right, AstSymbolNode) else []
|
|
3176
|
+
)
|
|
3177
|
+
while isinstance(left, AtomTrailer) and left.is_attr:
|
|
3178
|
+
if isinstance(left.right, AstSymbolNode):
|
|
3179
|
+
trag_list.insert(0, left.right)
|
|
3180
|
+
left = left.target
|
|
3181
|
+
if isinstance(left, AstSymbolNode):
|
|
3182
|
+
trag_list.insert(0, left)
|
|
3183
|
+
return trag_list
|
|
3184
|
+
|
|
3054
3185
|
|
|
3055
3186
|
class AtomUnit(Expr):
|
|
3056
3187
|
"""AtomUnit node type for Jac Ast."""
|
|
@@ -3869,7 +4000,9 @@ class Name(Token, NameAtom):
|
|
|
3869
4000
|
)
|
|
3870
4001
|
|
|
3871
4002
|
@staticmethod
|
|
3872
|
-
def gen_stub_from_node(
|
|
4003
|
+
def gen_stub_from_node(
|
|
4004
|
+
node: AstSymbolNode, name_str: str, set_name_of: Optional[AstSymbolNode] = None
|
|
4005
|
+
) -> Name:
|
|
3873
4006
|
"""Generate name from node."""
|
|
3874
4007
|
ret = Name(
|
|
3875
4008
|
file_path=node.loc.mod_path,
|
|
@@ -3882,8 +4015,9 @@ class Name(Token, NameAtom):
|
|
|
3882
4015
|
pos_start=node.loc.pos_start,
|
|
3883
4016
|
pos_end=node.loc.pos_end,
|
|
3884
4017
|
)
|
|
3885
|
-
ret.name_of =
|
|
3886
|
-
|
|
4018
|
+
ret.name_of = set_name_of if set_name_of else ret
|
|
4019
|
+
if node._sym_tab:
|
|
4020
|
+
ret.sym_tab = node.sym_tab
|
|
3887
4021
|
return ret
|
|
3888
4022
|
|
|
3889
4023
|
|
|
@@ -4121,6 +4255,7 @@ class CommentToken(Token):
|
|
|
4121
4255
|
name: str,
|
|
4122
4256
|
value: str,
|
|
4123
4257
|
line: int,
|
|
4258
|
+
end_line: int,
|
|
4124
4259
|
col_start: int,
|
|
4125
4260
|
col_end: int,
|
|
4126
4261
|
pos_start: int,
|
|
@@ -4129,15 +4264,21 @@ class CommentToken(Token):
|
|
|
4129
4264
|
is_inline: bool = False,
|
|
4130
4265
|
) -> None:
|
|
4131
4266
|
"""Initialize token."""
|
|
4132
|
-
self.file_path = file_path
|
|
4133
|
-
self.name = name
|
|
4134
|
-
self.value = value
|
|
4135
|
-
self.line_no = line
|
|
4136
|
-
self.c_start = col_start
|
|
4137
|
-
self.c_end = col_end
|
|
4138
|
-
self.pos_start = pos_start
|
|
4139
|
-
self.pos_end = pos_end
|
|
4140
4267
|
self.is_inline = is_inline
|
|
4268
|
+
|
|
4269
|
+
Token.__init__(
|
|
4270
|
+
self,
|
|
4271
|
+
file_path=file_path,
|
|
4272
|
+
name=name,
|
|
4273
|
+
value=value,
|
|
4274
|
+
line=line,
|
|
4275
|
+
end_line=end_line,
|
|
4276
|
+
col_start=col_start,
|
|
4277
|
+
col_end=col_end,
|
|
4278
|
+
pos_start=pos_start,
|
|
4279
|
+
pos_end=pos_end,
|
|
4280
|
+
)
|
|
4281
|
+
|
|
4141
4282
|
AstNode.__init__(self, kid=kid)
|
|
4142
4283
|
|
|
4143
4284
|
|
jaclang/compiler/constant.py
CHANGED
|
@@ -1,9 +1,93 @@
|
|
|
1
1
|
"""Constants across the project."""
|
|
2
2
|
|
|
3
|
-
from enum import Enum
|
|
3
|
+
from enum import Enum, IntEnum, IntFlag, StrEnum
|
|
4
4
|
|
|
5
5
|
|
|
6
|
-
class
|
|
6
|
+
class SymbolType(Enum):
|
|
7
|
+
"""Symbol types."""
|
|
8
|
+
|
|
9
|
+
MODULE = "module" # LSP: Module
|
|
10
|
+
MOD_VAR = "mod_var" # LSP: Variable
|
|
11
|
+
VAR = "variable" # LSP: Variable
|
|
12
|
+
IMM_VAR = "immutable" # LSP: Constant
|
|
13
|
+
ABILITY = "ability" # LSP: Function
|
|
14
|
+
OBJECT_ARCH = "object" # LSP: Class
|
|
15
|
+
NODE_ARCH = "node" # LSP: Class
|
|
16
|
+
EDGE_ARCH = "edge" # LSP: Class
|
|
17
|
+
WALKER_ARCH = "walker" # LSP: Class
|
|
18
|
+
ENUM_ARCH = "enum" # LSP: Enum
|
|
19
|
+
TEST = "test" # LSP: Function
|
|
20
|
+
TYPE = "type" # LSP: TypeParameter
|
|
21
|
+
IMPL = "impl" # LSP: Interface or Property
|
|
22
|
+
HAS_VAR = "field" # LSP: Field
|
|
23
|
+
METHOD = "method" # LSP: Method
|
|
24
|
+
CONSTRUCTOR = "constructor" # LSP: Constructor
|
|
25
|
+
ENUM_MEMBER = "enum_member" # LSP: EnumMember
|
|
26
|
+
NUMBER = "number" # LSP: Number
|
|
27
|
+
STRING = "string" # LSP: String
|
|
28
|
+
BOOL = "bool" # LSP: Boolean
|
|
29
|
+
SEQUENCE = "sequence" # LSP: Array
|
|
30
|
+
NULL = "null" # LSP: Null
|
|
31
|
+
UNKNOWN = "unknown" # LSP: Unknown
|
|
32
|
+
|
|
33
|
+
def __str__(self) -> str:
|
|
34
|
+
"""Stringify."""
|
|
35
|
+
return self.value
|
|
36
|
+
|
|
37
|
+
|
|
38
|
+
class JacSemTokenType(IntEnum):
|
|
39
|
+
"""LSP Token types for Jac."""
|
|
40
|
+
|
|
41
|
+
NAMESPACE = 0
|
|
42
|
+
TYPE = 1
|
|
43
|
+
CLASS = 2
|
|
44
|
+
ENUM = 3
|
|
45
|
+
INTERFACE = 4
|
|
46
|
+
STRUCT = 5
|
|
47
|
+
TYPE_PARAMETER = 6
|
|
48
|
+
PARAMETER = 7
|
|
49
|
+
VARIABLE = 8
|
|
50
|
+
PROPERTY = 9
|
|
51
|
+
ENUM_MEMBER = 10
|
|
52
|
+
EVENT = 11
|
|
53
|
+
FUNCTION = 12
|
|
54
|
+
METHOD = 13
|
|
55
|
+
MACRO = 14
|
|
56
|
+
KEYWORD = 15
|
|
57
|
+
MODIFIER = 16
|
|
58
|
+
COMMENT = 17
|
|
59
|
+
STRING = 18
|
|
60
|
+
NUMBER = 19
|
|
61
|
+
REGEXP = 20
|
|
62
|
+
OPERATOR = 21
|
|
63
|
+
|
|
64
|
+
@staticmethod
|
|
65
|
+
def as_str_list() -> list[str]:
|
|
66
|
+
"""Return the string representation of the token."""
|
|
67
|
+
return [i.name.lower() for i in JacSemTokenType]
|
|
68
|
+
|
|
69
|
+
|
|
70
|
+
class JacSemTokenModifier(IntFlag):
|
|
71
|
+
"""LSP Token modifiers for Jac."""
|
|
72
|
+
|
|
73
|
+
DECLARATION = 1 << 0
|
|
74
|
+
DEFINITION = 1 << 1
|
|
75
|
+
READONLY = 1 << 2
|
|
76
|
+
STATIC = 1 << 3
|
|
77
|
+
DEPRECATED = 1 << 4
|
|
78
|
+
ABSTRACT = 1 << 5
|
|
79
|
+
ASYNC = 1 << 6
|
|
80
|
+
MODIFICATION = 1 << 7
|
|
81
|
+
DOCUMENTATION = 1 << 8
|
|
82
|
+
DEFAULT_LIBRARY = 1 << 9
|
|
83
|
+
|
|
84
|
+
@staticmethod
|
|
85
|
+
def as_str_list() -> list[str]:
|
|
86
|
+
"""Return the string representation of the token."""
|
|
87
|
+
return [i.name.lower() for i in JacSemTokenModifier if i.name]
|
|
88
|
+
|
|
89
|
+
|
|
90
|
+
class Constants(StrEnum):
|
|
7
91
|
"""Token constants for Jac."""
|
|
8
92
|
|
|
9
93
|
JAC_LANG_IMP = "jac"
|
|
@@ -49,6 +133,18 @@ class Values(int, Enum):
|
|
|
49
133
|
JAC_ERROR_LINE_RANGE = 3
|
|
50
134
|
|
|
51
135
|
|
|
136
|
+
class SymbolAccess(Enum):
|
|
137
|
+
"""Symbol types."""
|
|
138
|
+
|
|
139
|
+
PRIVATE = "private"
|
|
140
|
+
PUBLIC = "public"
|
|
141
|
+
PROTECTED = "protected"
|
|
142
|
+
|
|
143
|
+
def __str__(self) -> str:
|
|
144
|
+
"""Stringify."""
|
|
145
|
+
return self.value
|
|
146
|
+
|
|
147
|
+
|
|
52
148
|
# Done like this for type checker
|
|
53
149
|
# validated synced with test
|
|
54
150
|
class Tokens(str, Enum):
|
jaclang/compiler/jac.lark
CHANGED
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)
|
|
@@ -67,6 +68,7 @@ class JacParser(Pass):
|
|
|
67
68
|
name=token.type,
|
|
68
69
|
value=token.value,
|
|
69
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,
|
|
70
72
|
col_start=token.column if token.column is not None else 0,
|
|
71
73
|
col_end=token.end_column if token.end_column is not None else 0,
|
|
72
74
|
pos_start=token.start_pos if token.start_pos is not None else 0,
|
|
@@ -129,6 +131,7 @@ class JacParser(Pass):
|
|
|
129
131
|
def nu(self, node: ast.T) -> ast.T:
|
|
130
132
|
"""Update node."""
|
|
131
133
|
self.parse_ref.cur_node = node
|
|
134
|
+
self.parse_ref.node_list.append(node)
|
|
132
135
|
return node
|
|
133
136
|
|
|
134
137
|
def start(self, kid: list[ast.Module]) -> ast.Module:
|
|
@@ -136,6 +139,7 @@ class JacParser(Pass):
|
|
|
136
139
|
|
|
137
140
|
start: module
|
|
138
141
|
"""
|
|
142
|
+
kid[0]._in_mod_nodes = self.parse_ref.node_list
|
|
139
143
|
return self.nu(kid[0])
|
|
140
144
|
|
|
141
145
|
def module(
|
|
@@ -7,11 +7,13 @@ 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
|
|
11
13
|
from jaclang.settings import settings
|
|
12
14
|
|
|
13
15
|
|
|
14
|
-
class AccessCheckPass(
|
|
16
|
+
class AccessCheckPass(Pass):
|
|
15
17
|
"""Jac Ast Access Check pass."""
|
|
16
18
|
|
|
17
19
|
def after_pass(self) -> None:
|
|
@@ -28,7 +30,7 @@ class AccessCheckPass(SymTabPass):
|
|
|
28
30
|
"""Access check."""
|
|
29
31
|
node_info = (
|
|
30
32
|
node.sym_tab.lookup(node.sym_name)
|
|
31
|
-
if isinstance(node.sym_tab,
|
|
33
|
+
if isinstance(node.sym_tab, SymbolTable)
|
|
32
34
|
else None
|
|
33
35
|
)
|
|
34
36
|
|
|
@@ -52,7 +52,9 @@ class DeclImplMatchPass(Pass):
|
|
|
52
52
|
if lookup and not isinstance(
|
|
53
53
|
lookup.decl.name_of, ast.AstImplNeedingNode
|
|
54
54
|
):
|
|
55
|
-
lookup =
|
|
55
|
+
lookup = (
|
|
56
|
+
sym_tab.parent.lookup(arch_refs[0]) if sym_tab.parent else None
|
|
57
|
+
)
|
|
56
58
|
decl_node = (
|
|
57
59
|
self.defn_lookup(lookup)
|
|
58
60
|
if len(arch_refs) == 1 and lookup
|