jaclang 0.0.6__py3-none-any.whl → 0.0.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/__init__.py +2 -1
- jaclang/cli/__jac_gen__/__init__.py +0 -0
- jaclang/cli/__jac_gen__/cli.py +175 -0
- jaclang/cli/__jac_gen__/cmds.py +132 -0
- jaclang/cli/cmds.jac +3 -0
- jaclang/cli/impl/__jac_gen__/__init__.py +0 -0
- jaclang/cli/impl/__jac_gen__/cli_impl.py +16 -0
- jaclang/cli/impl/__jac_gen__/cmds_impl.py +26 -0
- jaclang/cli/impl/cmds_impl.jac +17 -3
- jaclang/core/__jac_gen__/__init__.py +0 -0
- jaclang/core/__jac_gen__/primitives.py +567 -0
- jaclang/core/impl/__jac_gen__/__init__.py +0 -0
- jaclang/core/impl/__jac_gen__/arch_impl.py +24 -0
- jaclang/core/impl/__jac_gen__/element_impl.py +26 -0
- jaclang/core/impl/__jac_gen__/exec_ctx_impl.py +12 -0
- jaclang/core/impl/__jac_gen__/memory_impl.py +14 -0
- jaclang/core/impl/element_impl.jac +2 -2
- jaclang/core/primitives.jac +1 -0
- jaclang/jac/absyntree.py +65 -42
- jaclang/jac/constant.py +4 -0
- jaclang/jac/importer.py +18 -60
- jaclang/jac/langserve.py +26 -0
- jaclang/jac/lexer.py +9 -1
- jaclang/jac/parser.py +135 -123
- jaclang/jac/passes/blue/ast_build_pass.py +410 -353
- jaclang/jac/passes/blue/blue_pygen_pass.py +15 -0
- jaclang/jac/passes/blue/decl_def_match_pass.py +33 -21
- jaclang/jac/passes/blue/import_pass.py +1 -1
- jaclang/jac/passes/blue/pyout_pass.py +47 -12
- jaclang/jac/passes/blue/sym_tab_build_pass.py +38 -127
- jaclang/jac/passes/blue/tests/test_ast_build_pass.py +2 -2
- jaclang/jac/passes/blue/tests/test_blue_pygen_pass.py +9 -30
- jaclang/jac/passes/blue/tests/test_decl_def_match_pass.py +13 -13
- jaclang/jac/passes/blue/tests/test_sym_tab_build_pass.py +6 -4
- jaclang/jac/passes/ir_pass.py +1 -1
- jaclang/jac/passes/purple/__jac_gen__/__init__.py +0 -0
- jaclang/jac/passes/purple/__jac_gen__/analyze_pass.py +37 -0
- jaclang/jac/passes/purple/__jac_gen__/purple_pygen_pass.py +305 -0
- jaclang/jac/passes/purple/impl/__jac_gen__/__init__.py +0 -0
- jaclang/jac/passes/purple/impl/__jac_gen__/purple_pygen_pass_impl.py +23 -0
- jaclang/jac/symtable.py +12 -4
- jaclang/jac/tests/fixtures/__jac_gen__/__init__.py +0 -0
- jaclang/jac/tests/fixtures/__jac_gen__/hello_world.py +16 -0
- jaclang/jac/tests/fixtures/fam.jac +7 -8
- jaclang/jac/transform.py +4 -3
- jaclang/jac/transpiler.py +13 -9
- jaclang/utils/fstring_parser.py +2 -2
- jaclang/utils/helpers.py +41 -0
- jaclang/utils/test.py +30 -0
- jaclang/vendor/__init__.py +1 -0
- jaclang/vendor/pygls/__init__.py +25 -0
- jaclang/vendor/pygls/capabilities.py +502 -0
- jaclang/vendor/pygls/client.py +176 -0
- jaclang/vendor/pygls/constants.py +26 -0
- jaclang/vendor/pygls/exceptions.py +220 -0
- jaclang/vendor/pygls/feature_manager.py +241 -0
- jaclang/vendor/pygls/lsp/__init__.py +139 -0
- jaclang/vendor/pygls/lsp/client.py +2224 -0
- jaclang/vendor/pygls/lsprotocol/__init__.py +2 -0
- jaclang/vendor/pygls/lsprotocol/_hooks.py +1233 -0
- jaclang/vendor/pygls/lsprotocol/converters.py +17 -0
- jaclang/vendor/pygls/lsprotocol/types.py +12820 -0
- jaclang/vendor/pygls/lsprotocol/validators.py +47 -0
- jaclang/vendor/pygls/progress.py +79 -0
- jaclang/vendor/pygls/protocol.py +1184 -0
- jaclang/vendor/pygls/server.py +620 -0
- jaclang/vendor/pygls/uris.py +184 -0
- jaclang/vendor/pygls/workspace/__init__.py +81 -0
- jaclang/vendor/pygls/workspace/position.py +204 -0
- jaclang/vendor/pygls/workspace/text_document.py +234 -0
- jaclang/vendor/pygls/workspace/workspace.py +311 -0
- {jaclang-0.0.6.dist-info → jaclang-0.0.8.dist-info}/METADATA +1 -1
- jaclang-0.0.8.dist-info/RECORD +118 -0
- jaclang/core/jaclang.jac +0 -62
- jaclang-0.0.6.dist-info/RECORD +0 -76
- /jaclang/{utils → vendor}/sly/__init__.py +0 -0
- /jaclang/{utils → vendor}/sly/docparse.py +0 -0
- /jaclang/{utils → vendor}/sly/lex.py +0 -0
- /jaclang/{utils → vendor}/sly/yacc.py +0 -0
- {jaclang-0.0.6.dist-info → jaclang-0.0.8.dist-info}/WHEEL +0 -0
- {jaclang-0.0.6.dist-info → jaclang-0.0.8.dist-info}/entry_points.txt +0 -0
- {jaclang-0.0.6.dist-info → jaclang-0.0.8.dist-info}/top_level.txt +0 -0
jaclang/jac/absyntree.py
CHANGED
|
@@ -14,7 +14,7 @@ class AstNode:
|
|
|
14
14
|
|
|
15
15
|
def __init__(
|
|
16
16
|
self,
|
|
17
|
-
parent: Optional[
|
|
17
|
+
parent: Optional[AstNode],
|
|
18
18
|
mod_link: Optional[Module],
|
|
19
19
|
kid: list,
|
|
20
20
|
line: int,
|
|
@@ -180,7 +180,7 @@ class Test(AstNode):
|
|
|
180
180
|
sym_tab=name.sym_tab,
|
|
181
181
|
)
|
|
182
182
|
)
|
|
183
|
-
kid[
|
|
183
|
+
kid[0] = self.name # Index is 0 since Doc string is inserted after init
|
|
184
184
|
self.body = body
|
|
185
185
|
super().__init__(
|
|
186
186
|
parent=parent, mod_link=mod_link, kid=kid, line=line, sym_tab=sym_tab
|
|
@@ -210,6 +210,22 @@ class ModuleCode(AstNode):
|
|
|
210
210
|
)
|
|
211
211
|
|
|
212
212
|
|
|
213
|
+
class PyInlineCode(AstNode):
|
|
214
|
+
"""Inline Python code node type for Jac Ast."""
|
|
215
|
+
|
|
216
|
+
def __init__(
|
|
217
|
+
self,
|
|
218
|
+
code: Token,
|
|
219
|
+
parent: Optional[AstNode],
|
|
220
|
+
mod_link: Optional[Module],
|
|
221
|
+
kid: list[AstNode],
|
|
222
|
+
line: int,
|
|
223
|
+
) -> None:
|
|
224
|
+
"""Initialize inline python code node."""
|
|
225
|
+
self.code = code
|
|
226
|
+
super().__init__(parent=parent, mod_link=mod_link, kid=kid, line=line)
|
|
227
|
+
|
|
228
|
+
|
|
213
229
|
class Import(AstNode):
|
|
214
230
|
"""Import node type for Jac Ast."""
|
|
215
231
|
|
|
@@ -343,8 +359,7 @@ class ArchDef(AstNode):
|
|
|
343
359
|
def __init__(
|
|
344
360
|
self,
|
|
345
361
|
doc: Optional[Token],
|
|
346
|
-
|
|
347
|
-
arch: ArchRef,
|
|
362
|
+
target: ArchRefChain,
|
|
348
363
|
body: ArchBlock,
|
|
349
364
|
parent: Optional[AstNode],
|
|
350
365
|
mod_link: Optional[Module],
|
|
@@ -354,8 +369,7 @@ class ArchDef(AstNode):
|
|
|
354
369
|
) -> None:
|
|
355
370
|
"""Initialize arch def node."""
|
|
356
371
|
self.doc = doc
|
|
357
|
-
self.
|
|
358
|
-
self.arch = arch
|
|
372
|
+
self.target = target
|
|
359
373
|
self.body = body
|
|
360
374
|
super().__init__(
|
|
361
375
|
parent=parent, mod_link=mod_link, kid=kid, line=line, sym_tab=sym_tab
|
|
@@ -405,7 +419,7 @@ class Ability(OOPAccessNode):
|
|
|
405
419
|
|
|
406
420
|
def __init__(
|
|
407
421
|
self,
|
|
408
|
-
name_ref: Name | SpecialVarRef
|
|
422
|
+
name_ref: Name | SpecialVarRef,
|
|
409
423
|
is_func: bool,
|
|
410
424
|
is_async: bool,
|
|
411
425
|
is_static: bool,
|
|
@@ -452,14 +466,6 @@ class Ability(OOPAccessNode):
|
|
|
452
466
|
else:
|
|
453
467
|
raise NotImplementedError
|
|
454
468
|
|
|
455
|
-
def resolve_ability_symtab_name(self) -> str:
|
|
456
|
-
"""Resolve ability name in symbol table."""
|
|
457
|
-
return (
|
|
458
|
-
f"{self.arch_attached.parent.name.value}.{self.py_resolve_name()}"
|
|
459
|
-
if self.arch_attached and isinstance(self.arch_attached.parent, Architype)
|
|
460
|
-
else self.py_resolve_name()
|
|
461
|
-
)
|
|
462
|
-
|
|
463
469
|
|
|
464
470
|
class AbilityDef(AstNode):
|
|
465
471
|
"""AbilityDef node type for Jac Ast."""
|
|
@@ -467,8 +473,7 @@ class AbilityDef(AstNode):
|
|
|
467
473
|
def __init__(
|
|
468
474
|
self,
|
|
469
475
|
doc: Optional[Token],
|
|
470
|
-
target:
|
|
471
|
-
ability: ArchRef,
|
|
476
|
+
target: ArchRefChain,
|
|
472
477
|
signature: FuncSignature | EventSignature,
|
|
473
478
|
body: CodeBlock,
|
|
474
479
|
parent: Optional[AstNode],
|
|
@@ -480,26 +485,12 @@ class AbilityDef(AstNode):
|
|
|
480
485
|
"""Initialize ability def node."""
|
|
481
486
|
self.doc = doc
|
|
482
487
|
self.target = target
|
|
483
|
-
self.ability = ability
|
|
484
488
|
self.signature = signature
|
|
485
489
|
self.body = body
|
|
486
490
|
super().__init__(
|
|
487
491
|
parent=parent, mod_link=mod_link, kid=kid, line=line, sym_tab=sym_tab
|
|
488
492
|
)
|
|
489
493
|
|
|
490
|
-
def py_resolve_name(self) -> str:
|
|
491
|
-
"""Resolve name."""
|
|
492
|
-
ability_name = self.ability.py_resolve_name()
|
|
493
|
-
if self.target:
|
|
494
|
-
owner = self.target.names[-1]
|
|
495
|
-
if isinstance(owner, ArchRef):
|
|
496
|
-
owner = owner.py_resolve_name()
|
|
497
|
-
ability_name = f"{owner}.{ability_name}"
|
|
498
|
-
return ability_name
|
|
499
|
-
raise Exception("Invalid AST: Expected reference to Architype!")
|
|
500
|
-
else:
|
|
501
|
-
return ability_name
|
|
502
|
-
|
|
503
494
|
|
|
504
495
|
class EventSignature(AstNode):
|
|
505
496
|
"""EventSignature node type for Jac Ast."""
|
|
@@ -529,7 +520,7 @@ class DottedNameList(AstNode):
|
|
|
529
520
|
|
|
530
521
|
def __init__(
|
|
531
522
|
self,
|
|
532
|
-
names: list[Token | SpecialVarRef |
|
|
523
|
+
names: list[Token | SpecialVarRef | Name],
|
|
533
524
|
parent: Optional[AstNode],
|
|
534
525
|
mod_link: Optional[Module],
|
|
535
526
|
kid: list[AstNode],
|
|
@@ -543,6 +534,31 @@ class DottedNameList(AstNode):
|
|
|
543
534
|
)
|
|
544
535
|
|
|
545
536
|
|
|
537
|
+
class ArchRefChain(AstNode):
|
|
538
|
+
"""Arch ref list node type for Jac Ast."""
|
|
539
|
+
|
|
540
|
+
def __init__(
|
|
541
|
+
self,
|
|
542
|
+
archs: list[ArchRef],
|
|
543
|
+
parent: Optional[AstNode],
|
|
544
|
+
mod_link: Optional[Module],
|
|
545
|
+
kid: list[AstNode],
|
|
546
|
+
line: int,
|
|
547
|
+
sym_tab: Optional[SymbolTable] = None,
|
|
548
|
+
) -> None:
|
|
549
|
+
"""Initialize name list ."""
|
|
550
|
+
self.archs = archs
|
|
551
|
+
super().__init__(
|
|
552
|
+
parent=parent, mod_link=mod_link, kid=kid, line=line, sym_tab=sym_tab
|
|
553
|
+
)
|
|
554
|
+
|
|
555
|
+
def py_resolve_name(self) -> str:
|
|
556
|
+
"""Resolve name."""
|
|
557
|
+
return ".".join(
|
|
558
|
+
[f"({x.arch.value[1]}){x.py_resolve_name()}" for x in self.archs]
|
|
559
|
+
)
|
|
560
|
+
|
|
561
|
+
|
|
546
562
|
class FuncSignature(AstNode):
|
|
547
563
|
"""FuncSignature node type for Jac Ast."""
|
|
548
564
|
|
|
@@ -615,7 +631,7 @@ class Enum(OOPAccessNode):
|
|
|
615
631
|
self,
|
|
616
632
|
name: Name,
|
|
617
633
|
doc: Optional[Token],
|
|
618
|
-
decorators: Optional[
|
|
634
|
+
decorators: Optional[Decorators],
|
|
619
635
|
access: Optional[Token],
|
|
620
636
|
base_classes: "BaseClasses",
|
|
621
637
|
body: Optional["EnumBlock"],
|
|
@@ -647,8 +663,7 @@ class EnumDef(AstNode):
|
|
|
647
663
|
def __init__(
|
|
648
664
|
self,
|
|
649
665
|
doc: Optional[Token],
|
|
650
|
-
|
|
651
|
-
mod: Optional[DottedNameList],
|
|
666
|
+
target: ArchRefChain,
|
|
652
667
|
body: EnumBlock,
|
|
653
668
|
parent: Optional[AstNode],
|
|
654
669
|
mod_link: Optional[Module],
|
|
@@ -657,9 +672,8 @@ class EnumDef(AstNode):
|
|
|
657
672
|
sym_tab: Optional[SymbolTable] = None,
|
|
658
673
|
) -> None:
|
|
659
674
|
"""Initialize arch def node."""
|
|
660
|
-
self.enum = enum
|
|
661
675
|
self.doc = doc
|
|
662
|
-
self.
|
|
676
|
+
self.target = target
|
|
663
677
|
self.body = body
|
|
664
678
|
super().__init__(
|
|
665
679
|
parent=parent, mod_link=mod_link, kid=kid, line=line, sym_tab=sym_tab
|
|
@@ -690,7 +704,7 @@ class ArchBlock(AstNode):
|
|
|
690
704
|
|
|
691
705
|
def __init__(
|
|
692
706
|
self,
|
|
693
|
-
members: list[
|
|
707
|
+
members: list[ArchHas | Ability],
|
|
694
708
|
parent: Optional[AstNode],
|
|
695
709
|
mod_link: Optional[Module],
|
|
696
710
|
kid: list[AstNode],
|
|
@@ -1714,8 +1728,8 @@ class AtomTrailer(AstNode):
|
|
|
1714
1728
|
|
|
1715
1729
|
def __init__(
|
|
1716
1730
|
self,
|
|
1717
|
-
target:
|
|
1718
|
-
right:
|
|
1731
|
+
target: AtomType,
|
|
1732
|
+
right: IndexSlice | ArchRef | Token,
|
|
1719
1733
|
null_ok: bool,
|
|
1720
1734
|
parent: Optional[AstNode],
|
|
1721
1735
|
mod_link: Optional[Module],
|
|
@@ -1996,6 +2010,10 @@ class Parse(AstNode):
|
|
|
1996
2010
|
parent=parent, mod_link=mod_link, kid=kid, line=line, sym_tab=sym_tab
|
|
1997
2011
|
)
|
|
1998
2012
|
|
|
2013
|
+
def __repr__(self) -> str:
|
|
2014
|
+
"""Return string representation of parse node."""
|
|
2015
|
+
return super().__repr__() + f" ({self.name})" + " line: " + str(self.line)
|
|
2016
|
+
|
|
1999
2017
|
|
|
2000
2018
|
class Token(AstNode):
|
|
2001
2019
|
"""Token node type for Jac Ast."""
|
|
@@ -2153,9 +2171,14 @@ def replace_node(node: AstNode, new_node: Optional[AstNode]) -> AstNode | None:
|
|
|
2153
2171
|
return new_node
|
|
2154
2172
|
|
|
2155
2173
|
|
|
2156
|
-
def append_node(
|
|
2174
|
+
def append_node(
|
|
2175
|
+
node: AstNode, new_node: Optional[AstNode], front: bool = False
|
|
2176
|
+
) -> AstNode | None:
|
|
2157
2177
|
"""Replace node with new_node."""
|
|
2158
|
-
|
|
2178
|
+
if front:
|
|
2179
|
+
node.kid.insert(0, new_node)
|
|
2180
|
+
else:
|
|
2181
|
+
node.kid.append(new_node)
|
|
2159
2182
|
if new_node:
|
|
2160
2183
|
new_node.parent = node
|
|
2161
2184
|
return new_node
|
jaclang/jac/constant.py
CHANGED
|
@@ -28,6 +28,9 @@ class Constants(str, Enum):
|
|
|
28
28
|
WITH_DIR = "_jac_apply_dir_"
|
|
29
29
|
EDGE_DIR = "_jac_Edge_Dir_"
|
|
30
30
|
|
|
31
|
+
PYNLINE = "::py::"
|
|
32
|
+
JAC_GEN_DIR = "__jac_gen__"
|
|
33
|
+
|
|
31
34
|
def __str__(self) -> str:
|
|
32
35
|
"""Return the string representation of the token."""
|
|
33
36
|
return self.value
|
|
@@ -55,6 +58,7 @@ class Tokens(str, Enum):
|
|
|
55
58
|
FLOAT = "FLOAT"
|
|
56
59
|
STRING = "STRING"
|
|
57
60
|
DOC_STRING = "DOC_STRING"
|
|
61
|
+
PYNLINE = "PYNLINE"
|
|
58
62
|
FSTRING = "FSTRING"
|
|
59
63
|
BOOL = "BOOL"
|
|
60
64
|
INT = "INT"
|
jaclang/jac/importer.py
CHANGED
|
@@ -4,12 +4,12 @@ import marshal
|
|
|
4
4
|
import sys
|
|
5
5
|
import traceback
|
|
6
6
|
import types
|
|
7
|
-
from os import
|
|
7
|
+
from os import path
|
|
8
8
|
from typing import Callable, Optional
|
|
9
9
|
|
|
10
|
-
from jaclang.jac.constant import Constants as Con
|
|
10
|
+
from jaclang.jac.constant import Constants as Con
|
|
11
11
|
from jaclang.jac.transpiler import transpile_jac_blue, transpile_jac_purple
|
|
12
|
-
from jaclang.utils.helpers import
|
|
12
|
+
from jaclang.utils.helpers import handle_jac_error
|
|
13
13
|
|
|
14
14
|
|
|
15
15
|
def import_jac_module(
|
|
@@ -20,9 +20,7 @@ def import_jac_module(
|
|
|
20
20
|
override_name: Optional[str] = None,
|
|
21
21
|
) -> Optional[types.ModuleType]:
|
|
22
22
|
"""Core Import Process."""
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
dir_path, file_name = path.split(target)
|
|
23
|
+
dir_path, file_name = path.split(path.join(*(target.split("."))) + ".jac")
|
|
26
24
|
module_name = path.splitext(file_name)[0]
|
|
27
25
|
package_path = dir_path.replace(path.sep, ".")
|
|
28
26
|
|
|
@@ -36,11 +34,13 @@ def import_jac_module(
|
|
|
36
34
|
else:
|
|
37
35
|
frame = inspect.stack()[2]
|
|
38
36
|
caller_dir = path.dirname(path.abspath(frame[0].f_code.co_filename))
|
|
39
|
-
|
|
37
|
+
caller_dir = path.join(caller_dir, dir_path)
|
|
38
|
+
|
|
39
|
+
gen_dir = path.join(caller_dir, Con.JAC_GEN_DIR)
|
|
40
|
+
full_target = path.normpath(path.join(caller_dir, file_name))
|
|
40
41
|
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
py_file_path = path.join(dev_dir, module_name + ".py")
|
|
42
|
+
py_file_path = path.join(gen_dir, module_name + ".py")
|
|
43
|
+
pyc_file_path = path.join(gen_dir, module_name + ".pyc")
|
|
44
44
|
if (
|
|
45
45
|
cachable
|
|
46
46
|
and path.exists(py_file_path)
|
|
@@ -48,33 +48,21 @@ def import_jac_module(
|
|
|
48
48
|
):
|
|
49
49
|
with open(py_file_path, "r") as f:
|
|
50
50
|
code_string = f.read()
|
|
51
|
+
with open(pyc_file_path, "rb") as f:
|
|
52
|
+
codeobj = marshal.load(f)
|
|
51
53
|
else:
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
54
|
+
if transpiler_func(file_path=full_target, base_dir=caller_dir):
|
|
55
|
+
return None
|
|
56
|
+
with open(py_file_path, "r") as f:
|
|
57
|
+
code_string = f.read()
|
|
58
|
+
with open(pyc_file_path, "rb") as f:
|
|
59
|
+
codeobj = marshal.load(f)
|
|
55
60
|
|
|
56
61
|
module = types.ModuleType(module_name)
|
|
57
62
|
module.__file__ = full_target
|
|
58
63
|
module.__name__ = override_name if override_name else module_name
|
|
59
64
|
module.__dict__["_jac_pycodestring_"] = code_string
|
|
60
65
|
|
|
61
|
-
if (
|
|
62
|
-
cachable
|
|
63
|
-
and path.exists(py_file_path + "c")
|
|
64
|
-
and path.getmtime(py_file_path + "c") > path.getmtime(full_target)
|
|
65
|
-
):
|
|
66
|
-
with open(py_file_path + "c", "rb") as f:
|
|
67
|
-
codeobj = marshal.load(f)
|
|
68
|
-
else:
|
|
69
|
-
try:
|
|
70
|
-
codeobj = compile(code_string, f"_jac_py_gen ({module.__file__})", "exec")
|
|
71
|
-
except Exception as e:
|
|
72
|
-
tb = traceback.extract_tb(e.__traceback__)
|
|
73
|
-
err = handle_jac_error(code_string, e, tb)
|
|
74
|
-
raise type(e)(str(e) + "\n" + err)
|
|
75
|
-
with open(py_file_path + "c", "wb") as f:
|
|
76
|
-
marshal.dump(codeobj, f)
|
|
77
|
-
|
|
78
66
|
try:
|
|
79
67
|
exec(codeobj, module.__dict__)
|
|
80
68
|
except Exception as e:
|
|
@@ -96,36 +84,6 @@ def import_jac_module(
|
|
|
96
84
|
return module
|
|
97
85
|
|
|
98
86
|
|
|
99
|
-
def handle_jac_error(code_string: str, e: Exception, tb: traceback.StackSummary) -> str:
|
|
100
|
-
"""Handle Jac Error."""
|
|
101
|
-
except_line = e.end_lineno if isinstance(e, SyntaxError) else list(tb)[-1].lineno
|
|
102
|
-
if not isinstance(except_line, int) or except_line == 0:
|
|
103
|
-
return ""
|
|
104
|
-
py_error_region = clip_code_section(
|
|
105
|
-
add_line_numbers(code_string), except_line, Val.JAC_ERROR_LINE_RANGE
|
|
106
|
-
)
|
|
107
|
-
try:
|
|
108
|
-
jac_err_line = int(code_string.splitlines()[except_line - 1].split()[-1])
|
|
109
|
-
mod_index = int(code_string.splitlines()[except_line - 1].split()[-2])
|
|
110
|
-
mod_paths = code_string.split(Con.JAC_DEBUG_SPLITTER)[1].strip().splitlines()
|
|
111
|
-
target_mod = mod_paths[mod_index]
|
|
112
|
-
with open(target_mod, "r") as file:
|
|
113
|
-
jac_code_string = file.read()
|
|
114
|
-
jac_error_region = clip_code_section(
|
|
115
|
-
add_line_numbers(jac_code_string), jac_err_line, Val.JAC_ERROR_LINE_RANGE
|
|
116
|
-
)
|
|
117
|
-
except Exception as e:
|
|
118
|
-
jac_error_region = str(e)
|
|
119
|
-
target_mod = ""
|
|
120
|
-
snippet = (
|
|
121
|
-
f"{Con.JAC_ERROR_PREAMBLE}\n"
|
|
122
|
-
f"{target_mod}\n"
|
|
123
|
-
f"JacCode Snippet:\n{jac_error_region}\n"
|
|
124
|
-
f"PyCode Snippet:\n{py_error_region}\n"
|
|
125
|
-
)
|
|
126
|
-
return snippet
|
|
127
|
-
|
|
128
|
-
|
|
129
87
|
def jac_blue_import(
|
|
130
88
|
target: str,
|
|
131
89
|
base_path: Optional[str] = None,
|
jaclang/jac/langserve.py
ADDED
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
"""Example language server for JAC."""
|
|
2
|
+
|
|
3
|
+
from jaclang.vendor.pygls.lsprotocol.types import (
|
|
4
|
+
CompletionItem,
|
|
5
|
+
CompletionList,
|
|
6
|
+
CompletionParams,
|
|
7
|
+
TEXT_DOCUMENT_COMPLETION,
|
|
8
|
+
)
|
|
9
|
+
from jaclang.vendor.pygls.server import LanguageServer
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
server = LanguageServer("example-server", "v0.1")
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
@server.feature(TEXT_DOCUMENT_COMPLETION)
|
|
16
|
+
def completions(params: CompletionParams) -> CompletionList:
|
|
17
|
+
"""Provide completions for the current line."""
|
|
18
|
+
items = []
|
|
19
|
+
document = server.workspace.get_document(params.text_document.uri)
|
|
20
|
+
current_line = document.lines[params.position.line].strip()
|
|
21
|
+
if current_line.endswith("hello."):
|
|
22
|
+
items = [
|
|
23
|
+
CompletionItem(label="world"),
|
|
24
|
+
CompletionItem(label="friend"),
|
|
25
|
+
]
|
|
26
|
+
return CompletionList(is_incomplete=False, items=items)
|
jaclang/jac/lexer.py
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
from typing import Generator
|
|
3
3
|
|
|
4
4
|
from jaclang.jac.transform import ABCLexerMeta, Transform
|
|
5
|
-
from jaclang.
|
|
5
|
+
from jaclang.vendor.sly.lex import Lexer, Token
|
|
6
6
|
|
|
7
7
|
|
|
8
8
|
class JacLexer(Lexer, Transform, metaclass=ABCLexerMeta):
|
|
@@ -25,6 +25,7 @@ class JacLexer(Lexer, Transform, metaclass=ABCLexerMeta):
|
|
|
25
25
|
"FLOAT",
|
|
26
26
|
"STRING",
|
|
27
27
|
"DOC_STRING",
|
|
28
|
+
"PYNLINE",
|
|
28
29
|
"FSTRING",
|
|
29
30
|
"BOOL",
|
|
30
31
|
"INT",
|
|
@@ -189,6 +190,7 @@ class JacLexer(Lexer, Transform, metaclass=ABCLexerMeta):
|
|
|
189
190
|
# Regular expression rules for tokens
|
|
190
191
|
FLOAT = r"(\d+(\.\d*)?|\.\d+)([eE][+-]?\d+)?"
|
|
191
192
|
DOC_STRING = r'"""(.|\n|\r)*?"""|\'\'\'(.|\n|\r)*?\'\'\'' # type: ignore
|
|
193
|
+
PYNLINE = r"::py::(.|\n|\r)*?::py::" # type: ignore
|
|
192
194
|
FSTRING = r'f"[^"\r\n]*"|f\'[^\'\r\n]*\''
|
|
193
195
|
STRING = r'"[^"\r\n]*"|\'[^\'\r\n]*\''
|
|
194
196
|
BOOL = r"True|False"
|
|
@@ -372,6 +374,12 @@ class JacLexer(Lexer, Transform, metaclass=ABCLexerMeta):
|
|
|
372
374
|
self.lineno += t.value.count("\r")
|
|
373
375
|
return t
|
|
374
376
|
|
|
377
|
+
def PYNLINE(self, t: Token) -> Token: # noqa
|
|
378
|
+
"""Add docstring to lexer."""
|
|
379
|
+
self.lineno += t.value.count("\n")
|
|
380
|
+
self.lineno += t.value.count("\r")
|
|
381
|
+
return t
|
|
382
|
+
|
|
375
383
|
# Transform Implementations
|
|
376
384
|
# -------------------------
|
|
377
385
|
def transform(self, ir: str) -> Generator:
|