jaclang 0.8.1__py3-none-any.whl → 0.8.2__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.

Potentially problematic release.


This version of jaclang might be problematic. Click here for more details.

Files changed (77) hide show
  1. jaclang/__init__.py +6 -0
  2. jaclang/cli/cli.py +21 -50
  3. jaclang/compiler/codeinfo.py +0 -1
  4. jaclang/compiler/jac.lark +12 -10
  5. jaclang/compiler/larkparse/jac_parser.py +2 -2
  6. jaclang/compiler/parser.py +18 -10
  7. jaclang/compiler/passes/main/__init__.py +0 -14
  8. jaclang/compiler/passes/main/annex_pass.py +2 -8
  9. jaclang/compiler/passes/main/cfg_build_pass.py +38 -12
  10. jaclang/compiler/passes/main/import_pass.py +3 -11
  11. jaclang/compiler/passes/main/pyast_gen_pass.py +243 -592
  12. jaclang/compiler/passes/main/sym_tab_link_pass.py +2 -5
  13. jaclang/compiler/passes/main/tests/test_cfg_build_pass.py +2 -8
  14. jaclang/compiler/passes/main/tests/test_decl_impl_match_pass.py +7 -8
  15. jaclang/compiler/passes/main/tests/test_import_pass.py +5 -18
  16. jaclang/compiler/passes/main/tests/test_pyast_gen_pass.py +2 -6
  17. jaclang/compiler/passes/main/tests/test_sub_node_pass.py +1 -3
  18. jaclang/compiler/passes/main/tests/test_sym_tab_link_pass.py +20 -17
  19. jaclang/compiler/passes/tool/doc_ir_gen_pass.py +237 -105
  20. jaclang/compiler/passes/tool/jac_formatter_pass.py +2 -0
  21. jaclang/compiler/passes/tool/tests/fixtures/archetype_frmt.jac +14 -0
  22. jaclang/compiler/passes/tool/tests/fixtures/general_format_checks/triple_quoted_string.jac +5 -4
  23. jaclang/compiler/passes/tool/tests/fixtures/import_fmt.jac +6 -0
  24. jaclang/compiler/passes/tool/tests/fixtures/simple_walk_fmt.jac +3 -3
  25. jaclang/compiler/passes/tool/tests/fixtures/tagbreak.jac +9 -0
  26. jaclang/compiler/passes/tool/tests/test_jac_format_pass.py +18 -3
  27. jaclang/compiler/passes/tool/tests/test_unparse_validate.py +2 -2
  28. jaclang/compiler/program.py +21 -60
  29. jaclang/compiler/tests/fixtures/pkg_import_lib_py/__init__.py +2 -8
  30. jaclang/compiler/tests/fixtures/pkg_import_lib_py/sub/__init__.py +1 -5
  31. jaclang/compiler/tests/test_importer.py +10 -13
  32. jaclang/compiler/unitree.py +32 -16
  33. jaclang/langserve/__init__.jac +1 -1
  34. jaclang/langserve/engine.jac +113 -108
  35. jaclang/langserve/server.jac +17 -2
  36. jaclang/langserve/tests/server_test/test_lang_serve.py +138 -46
  37. jaclang/langserve/tests/server_test/utils.py +35 -9
  38. jaclang/langserve/tests/test_sem_tokens.py +1 -1
  39. jaclang/langserve/tests/test_server.py +3 -7
  40. jaclang/runtimelib/archetype.py +127 -5
  41. jaclang/runtimelib/importer.py +51 -94
  42. jaclang/runtimelib/machine.py +391 -268
  43. jaclang/runtimelib/meta_importer.py +86 -0
  44. jaclang/runtimelib/tests/fixtures/graph_purger.jac +24 -26
  45. jaclang/runtimelib/tests/fixtures/other_root_access.jac +25 -16
  46. jaclang/runtimelib/tests/test_jaseci.py +3 -1
  47. jaclang/tests/fixtures/arch_rel_import_creation.jac +23 -23
  48. jaclang/tests/fixtures/async_ability.jac +43 -10
  49. jaclang/tests/fixtures/async_function.jac +18 -0
  50. jaclang/tests/fixtures/async_walker.jac +17 -12
  51. jaclang/tests/fixtures/create_dynamic_archetype.jac +25 -28
  52. jaclang/tests/fixtures/deep/deeper/deep_outer_import.jac +7 -4
  53. jaclang/tests/fixtures/deep/deeper/snd_lev.jac +2 -2
  54. jaclang/tests/fixtures/deep/deeper/snd_lev_dup.jac +6 -0
  55. jaclang/tests/fixtures/deep/one_lev.jac +2 -2
  56. jaclang/tests/fixtures/deep/one_lev_dup.jac +4 -3
  57. jaclang/tests/fixtures/dynamic_archetype.jac +19 -12
  58. jaclang/tests/fixtures/foo.jac +14 -22
  59. jaclang/tests/fixtures/jac_from_py.py +1 -1
  60. jaclang/tests/fixtures/jp_importer.jac +6 -6
  61. jaclang/tests/fixtures/jp_importer_auto.jac +5 -3
  62. jaclang/tests/fixtures/unicode_strings.jac +24 -0
  63. jaclang/tests/fixtures/walker_update.jac +5 -7
  64. jaclang/tests/test_language.py +138 -140
  65. jaclang/tests/test_reference.py +9 -4
  66. jaclang/tests/test_typecheck.py +13 -26
  67. jaclang/utils/lang_tools.py +7 -5
  68. jaclang/utils/module_resolver.py +23 -0
  69. {jaclang-0.8.1.dist-info → jaclang-0.8.2.dist-info}/METADATA +1 -1
  70. {jaclang-0.8.1.dist-info → jaclang-0.8.2.dist-info}/RECORD +72 -70
  71. jaclang/compiler/passes/main/tests/fixtures/main_err.jac +0 -6
  72. jaclang/compiler/passes/main/tests/fixtures/second_err.jac +0 -4
  73. jaclang/compiler/passes/tool/tests/fixtures/corelib.jac +0 -644
  74. jaclang/compiler/passes/tool/tests/test_doc_ir_gen_pass.py +0 -29
  75. jaclang/tests/fixtures/deep/deeper/__init__.jac +0 -1
  76. {jaclang-0.8.1.dist-info → jaclang-0.8.2.dist-info}/WHEEL +0 -0
  77. {jaclang-0.8.1.dist-info → jaclang-0.8.2.dist-info}/entry_points.txt +0 -0
@@ -94,6 +94,8 @@ class JacFormatPass(Transform[uni.Module, uni.Module]):
94
94
  part_str = self.format_doc_ir(
95
95
  part, indent_level, current_line_budget, is_broken
96
96
  )
97
+ if part_str.startswith("\n"):
98
+ result = result.rstrip(" ")
97
99
  result += part_str
98
100
 
99
101
  if "\n" in part_str:
@@ -0,0 +1,14 @@
1
+ obj Anchor(ArchetypeProtocol) {
2
+ static def on_entry(cls: type, triggers: list[type]);
3
+ static def on_exit(cls: type, triggers: list[type]);
4
+ def make_public_ro;
5
+ def make_public_rw;
6
+ def make_private;
7
+ def is_public_ro -> bool;
8
+ def is_public_rw -> bool;
9
+ def is_private -> bool;
10
+ def is_readable(caller_id: UUID) -> bool;
11
+ def is_writable(caller_id: UUID) -> bool;
12
+ def give_access(caller_id: UUID, read_write: bool = False);
13
+ def revoke_access(caller_id: UUID);
14
+ }
@@ -1,6 +1,7 @@
1
1
  with entry {
2
- triple_quoted_string = """This is a triple quoted string.
3
- It can span multiple lines.
4
- It can contain any number of quotes or apostrophes.
5
- """;
2
+ triple_quoted_string =
3
+ """This is a triple quoted string.
4
+ It can span multiple lines.
5
+ It can contain any number of quotes or apostrophes.
6
+ """;
6
7
  }
@@ -0,0 +1,6 @@
1
+ import from datetime { datetime }
2
+ import from uuid { UUID, uuid4 }
3
+ import from jaclang.compiler.constant { EdgeDir }
4
+ import from jaclang.plugin { Archetype, ArchetypeProtocol, DSFunc, AbsRootHook, hookimpl }
5
+ import math;
6
+ import numpy as np;
@@ -10,7 +10,7 @@ edge Checking {}
10
10
 
11
11
  walker Creator {
12
12
  has count: int = 0;
13
-
13
+
14
14
  can create with `root | Item entry {
15
15
  here ++> Item();
16
16
  self.count += 1;
@@ -24,11 +24,11 @@ walker Creator {
24
24
  walker Walk {
25
25
  has count: int = 0;
26
26
  has value: int = 0;
27
-
27
+
28
28
  can skip_root with `root entry {
29
29
  visit [-->];
30
30
  }
31
-
31
+
32
32
  can step with Item entry {
33
33
  here.value = self.count;
34
34
  self.count += 1;
@@ -0,0 +1,9 @@
1
+ class SemTokManager {
2
+ """Initialize semantic token manager."""
3
+ def init(self: SemTokManager, ir: uni.Module) -> None {
4
+ self.sem_tokens: List[int] = self.gen_sem_tokens(ir);
5
+ self.aaaaastatic_sem_tokens:
6
+ List[Tuple[lspt.Position, int, int, uni.AstSymbolNode]] =
7
+ self.gen_sem_tok_node(ir);
8
+ }
9
+ }
@@ -51,6 +51,23 @@ class JacFormatPassTests(TestCaseMicroSuite):
51
51
  os.path.join(self.fixture_abs_path(""), "simple_walk_fmt.jac"),
52
52
  )
53
53
 
54
+ def test_tagbreak(self) -> None:
55
+ """Tests if the file matches a particular format."""
56
+ self.compare_files(
57
+ os.path.join(self.fixture_abs_path(""), "tagbreak.jac"),
58
+ )
59
+
60
+ def test_import_fmt(self) -> None:
61
+ """Tests if the file matches a particular format."""
62
+ self.compare_files(
63
+ os.path.join(self.fixture_abs_path(""), "import_fmt.jac"),
64
+ )
65
+
66
+ def test_archetype(self) -> None:
67
+ """Tests if the file matches a particular format."""
68
+ self.compare_files(
69
+ os.path.join(self.fixture_abs_path(""), "archetype_frmt.jac"),
70
+ )
54
71
  # def test_corelib_fmt(self) -> None:
55
72
  # """Tests if the file matches a particular format."""
56
73
  # self.compare_files(
@@ -99,9 +116,7 @@ class JacFormatPassTests(TestCaseMicroSuite):
99
116
  """
100
117
  code_gen_pure = JacProgram().compile(self.fixture_abs_path(filename))
101
118
  code_gen_format = JacProgram.jac_file_formatter(self.fixture_abs_path(filename))
102
- code_gen_jac = JacProgram().compile_from_str(
103
- source_str=code_gen_format, file_path=filename
104
- )
119
+ code_gen_jac = JacProgram().compile(use_str=code_gen_format, file_path=filename)
105
120
  if "circle_clean_tests.jac" in filename:
106
121
  tokens = code_gen_format.split()
107
122
  num_test = 0
@@ -34,8 +34,8 @@ class JacUnparseTests(TestCaseMicroSuite):
34
34
  )
35
35
  before = ast3.dump(code_gen_pure.gen.py_ast[0], indent=2)
36
36
  x = code_gen_pure.unparse()
37
- code_gen_jac = JacProgram().compile_from_str(
38
- source_str=x,
37
+ code_gen_jac = JacProgram().compile(
38
+ use_str=x,
39
39
  file_path=filename,
40
40
  )
41
41
  after = ast3.dump(code_gen_jac.gen.py_ast[0], indent=2)
@@ -12,14 +12,12 @@ from jaclang.compiler.parser import JacParser
12
12
  from jaclang.compiler.passes.main import (
13
13
  Alert,
14
14
  CFGBuildPass,
15
- CompilerMode,
16
15
  DeclImplMatchPass,
17
16
  DefUsePass,
18
17
  InheritancePass,
19
18
  JacAnnexPass,
20
19
  JacImportDepsPass,
21
20
  PyBytecodeGenPass,
22
- PyImportDepsPass,
23
21
  PyJacAstLinkPass,
24
22
  PyastBuildPass,
25
23
  PyastGenPass,
@@ -38,6 +36,7 @@ from jaclang.utils.log import logging
38
36
  logger = logging.getLogger(__name__)
39
37
 
40
38
  ir_gen_sched = [
39
+ SymTabBuildPass,
41
40
  DeclImplMatchPass,
42
41
  DefUsePass,
43
42
  CFGBuildPass,
@@ -63,29 +62,13 @@ class JacProgram:
63
62
 
64
63
  def get_bytecode(self, full_target: str) -> Optional[types.CodeType]:
65
64
  """Get the bytecode for a specific module."""
66
- if full_target in self.mod.hub:
65
+ if full_target in self.mod.hub and self.mod.hub[full_target].gen.py_bytecode:
67
66
  codeobj = self.mod.hub[full_target].gen.py_bytecode
68
67
  return marshal.loads(codeobj) if isinstance(codeobj, bytes) else None
69
- result = self.compile(file_path=full_target, mode=CompilerMode.COMPILE_SINGLE)
68
+ result = self.compile(file_path=full_target)
70
69
  return marshal.loads(result.gen.py_bytecode) if result.gen.py_bytecode else None
71
70
 
72
- def compile(
73
- self,
74
- file_path: str,
75
- mode: CompilerMode = CompilerMode.COMPILE,
76
- ) -> uni.Module:
77
- """Convert a Jac file to an AST."""
78
- with open(file_path, "r", encoding="utf-8") as file:
79
- return self.compile_from_str(
80
- source_str=file.read(), file_path=file_path, mode=mode
81
- )
82
-
83
- def compile_from_str(
84
- self,
85
- source_str: str,
86
- file_path: str,
87
- mode: CompilerMode = CompilerMode.COMPILE,
88
- ) -> uni.Module:
71
+ def parse_str(self, source_str: str, file_path: str) -> uni.Module:
89
72
  """Convert a Jac file to an AST."""
90
73
  had_error = False
91
74
  if file_path.endswith(".py"):
@@ -111,54 +94,32 @@ class JacProgram:
111
94
  if self.mod.main.stub_only:
112
95
  self.mod = uni.ProgramModule(mod)
113
96
  self.mod.hub[mod.loc.mod_path] = mod
114
- return self.run_pass_schedule(mod_targ=mod, mode=mode)
97
+ JacAnnexPass(ir_in=mod, prog=self)
98
+ return mod
115
99
 
116
- def run_pass_schedule(
117
- self,
118
- mod_targ: uni.Module,
119
- mode: CompilerMode = CompilerMode.COMPILE,
100
+ def compile(
101
+ self, file_path: str, use_str: str | None = None, no_cgen: bool = False
120
102
  ) -> uni.Module:
121
103
  """Convert a Jac file to an AST."""
122
- JacAnnexPass(ir_in=mod_targ, prog=self)
123
- SymTabBuildPass(ir_in=mod_targ, prog=self)
124
- if mode == CompilerMode.PARSE:
125
- return mod_targ
126
- elif mode in (CompilerMode.COMPILE_SINGLE, CompilerMode.NO_CGEN_SINGLE):
127
- self.schedule_runner(mod_targ, mode=mode)
128
- return mod_targ
104
+ if not use_str:
105
+ with open(file_path, "r", encoding="utf-8") as file:
106
+ use_str = file.read()
107
+ mod_targ = self.parse_str(use_str, file_path)
108
+ self.run_schedule(mod=mod_targ, passes=ir_gen_sched)
109
+ if not no_cgen:
110
+ self.run_schedule(mod=mod_targ, passes=py_code_gen)
111
+ return mod_targ
112
+
113
+ def build(self, file_path: str, use_str: str | None = None) -> uni.Module:
114
+ """Convert a Jac file to an AST."""
115
+ mod_targ = self.compile(file_path, use_str)
129
116
  JacImportDepsPass(ir_in=mod_targ, prog=self)
130
- if len(self.errors_had):
131
- return mod_targ
132
- SymTabLinkPass(ir_in=mod_targ, prog=self)
133
117
  for mod in self.mod.hub.values():
134
- self.schedule_runner(mod, mode=CompilerMode.COMPILE)
135
- if mode == CompilerMode.COMPILE:
136
- return mod_targ
137
- PyImportDepsPass(mod_targ, prog=self)
138
- SymTabLinkPass(ir_in=mod_targ, prog=self)
118
+ SymTabLinkPass(ir_in=mod, prog=self)
139
119
  for mod in self.mod.hub.values():
140
120
  DefUsePass(mod, prog=self)
141
- for mod in self.mod.hub.values():
142
- self.schedule_runner(mod, mode=CompilerMode.TYPECHECK)
143
121
  return mod_targ
144
122
 
145
- def schedule_runner(
146
- self,
147
- mod: uni.Module,
148
- mode: CompilerMode = CompilerMode.COMPILE,
149
- ) -> None:
150
- """Run premade passes on the module."""
151
- match mode:
152
- case CompilerMode.NO_CGEN | CompilerMode.NO_CGEN_SINGLE:
153
- passes = ir_gen_sched
154
- case CompilerMode.COMPILE | CompilerMode.COMPILE_SINGLE:
155
- passes = [*ir_gen_sched, *py_code_gen]
156
- case CompilerMode.TYPECHECK:
157
- passes = []
158
- case _:
159
- raise ValueError(f"Invalid mode: {mode}")
160
- self.run_schedule(mod, passes)
161
-
162
123
  def run_schedule(
163
124
  self,
164
125
  mod: uni.Module,
@@ -1,11 +1,5 @@
1
-
2
-
3
1
  from jaclang import JacMachineInterface as _
4
2
 
5
- (tool_func,) = _.py_jac_import(
6
- target="tools",
7
- base_path=__file__,
8
- items={"tool_func": None},
9
- )
3
+ from .tools import tool_func
10
4
 
11
- glob_var_lib = 'pkg_import_lib_py.glob_var_lib'
5
+ glob_var_lib = "pkg_import_lib_py.glob_var_lib"
@@ -1,7 +1,3 @@
1
1
  from jaclang import JacMachineInterface as _
2
2
 
3
- (help_func,) = _.py_jac_import(
4
- target=".helper",
5
- base_path=__file__,
6
- items={"help_func": None},
7
- )
3
+ from .helper import help_func
@@ -3,10 +3,10 @@
3
3
  import io
4
4
  import sys
5
5
 
6
- from jaclang import JacMachineInterface as Jac
6
+ from jaclang import JacMachine as Jac
7
7
  from jaclang.cli import cli
8
8
  from jaclang.compiler.program import JacProgram
9
- from jaclang.runtimelib.machine import JacMachineInterface, JacMachine
9
+ from jaclang.runtimelib.machine import JacMachineInterface
10
10
  from jaclang.utils.test import TestCase
11
11
 
12
12
 
@@ -15,29 +15,27 @@ class TestLoader(TestCase):
15
15
 
16
16
  def test_import_basic_python(self) -> None:
17
17
  """Test basic self loading."""
18
- mach = JacMachine(self.fixture_abs_path(__file__))
18
+ Jac.set_base_path(self.fixture_abs_path(__file__))
19
19
  JacMachineInterface.attach_program(
20
- mach,
21
20
  JacProgram(),
22
21
  )
23
- (h,) = Jac.jac_import(mach, "fixtures.hello_world", base_path=__file__)
22
+ (h,) = Jac.jac_import("fixtures.hello_world", base_path=__file__)
24
23
  self.assertEqual(h.hello(), "Hello World!") # type: ignore
25
24
 
26
25
  def test_modules_correct(self) -> None:
27
26
  """Test basic self loading."""
28
- mach = JacMachine(self.fixture_abs_path(__file__))
27
+ Jac.set_base_path(self.fixture_abs_path(__file__))
29
28
  JacMachineInterface.attach_program(
30
- mach,
31
29
  JacProgram(),
32
30
  )
33
- Jac.jac_import(mach, "fixtures.hello_world", base_path=__file__)
31
+ Jac.jac_import("fixtures.hello_world", base_path=__file__)
34
32
  self.assertIn(
35
33
  "module 'fixtures.hello_world'",
36
- str(mach.loaded_modules),
34
+ str(Jac.loaded_modules),
37
35
  )
38
36
  self.assertIn(
39
37
  "/tests/fixtures/hello_world.jac",
40
- str(mach.loaded_modules).replace("\\\\", "/"),
38
+ str(Jac.loaded_modules).replace("\\\\", "/"),
41
39
  )
42
40
 
43
41
  def test_jac_py_import(self) -> None:
@@ -92,12 +90,11 @@ class TestLoader(TestCase):
92
90
  sys.stdout = captured_output
93
91
 
94
92
  try:
95
- mach = JacMachine(self.fixture_abs_path(__file__))
93
+ Jac.set_base_path(self.fixture_abs_path(__file__))
96
94
  JacMachineInterface.attach_program(
97
- mach,
98
95
  JacProgram(),
99
96
  )
100
- Jac.jac_import(mach, module_name, base_path=__file__)
97
+ Jac.jac_import(module_name, base_path=__file__)
101
98
  cli.run(jac_file_path)
102
99
 
103
100
  # Reset stdout and get the output
@@ -849,15 +849,15 @@ class NameAtom(AtomExpr, EnumBlockStmt):
849
849
  return None
850
850
 
851
851
 
852
- class ArchSpec(ElementStmt, CodeBlockStmt, AstSymbolNode, AstDocNode):
852
+ class ArchSpec(ElementStmt, CodeBlockStmt, AstSymbolNode, AstAsyncNode, AstDocNode):
853
853
  """ArchSpec node type for Jac Ast."""
854
854
 
855
855
  def __init__(
856
856
  self, decorators: Sequence[Expr] | None, is_async: bool = False
857
857
  ) -> None:
858
858
  self.decorators = decorators
859
- self.is_async = is_async
860
859
  CodeBlockStmt.__init__(self)
860
+ AstAsyncNode.__init__(self, is_async=is_async)
861
861
 
862
862
 
863
863
  class MatchPattern(UniNode):
@@ -1777,6 +1777,22 @@ class Ability(
1777
1777
  def is_genai_ability(self) -> bool:
1778
1778
  return isinstance(self.body, FuncCall)
1779
1779
 
1780
+ def get_pos_argc_range(self) -> tuple[int, int]:
1781
+ """Get the range of positional arguments for this ability.
1782
+
1783
+ Returns -1 for maximum number of arguments if there is an unpacked parameter (e.g., *args).
1784
+ """
1785
+ mn, mx = 0, 0
1786
+ if isinstance(self.signature, FuncSignature):
1787
+ for param in self.signature.params:
1788
+ if param.unpack:
1789
+ if param.unpack == Tok.STAR_MUL:
1790
+ mx = -1
1791
+ break
1792
+ mn += 1
1793
+ mx += 1
1794
+ return mn, mx
1795
+
1780
1796
  def py_resolve_name(self) -> str:
1781
1797
  if isinstance(self.name_ref, Name):
1782
1798
  return self.name_ref.value
@@ -1914,12 +1930,10 @@ class EventSignature(WalkerStmtOnlyNode):
1914
1930
  self,
1915
1931
  event: Token,
1916
1932
  arch_tag_info: Optional[Expr],
1917
- return_type: Optional[Expr],
1918
1933
  kid: Sequence[UniNode],
1919
1934
  ) -> None:
1920
1935
  self.event = event
1921
1936
  self.arch_tag_info = arch_tag_info
1922
- self.return_type = return_type
1923
1937
  UniNode.__init__(self, kid=kid)
1924
1938
  WalkerStmtOnlyNode.__init__(self)
1925
1939
 
@@ -1932,14 +1946,10 @@ class EventSignature(WalkerStmtOnlyNode):
1932
1946
  if self.arch_tag_info
1933
1947
  else res
1934
1948
  )
1935
- res = res and self.return_type.normalize(deep) if self.return_type else res
1936
1949
  new_kid: list[UniNode] = [self.gen_token(Tok.KW_WITH)]
1937
1950
  if self.arch_tag_info:
1938
1951
  new_kid.append(self.arch_tag_info)
1939
1952
  new_kid.append(self.event)
1940
- if self.return_type:
1941
- new_kid.append(self.gen_token(Tok.RETURN_HINT))
1942
- new_kid.append(self.return_type)
1943
1953
  self.set_kids(nodes=new_kid)
1944
1954
  return res
1945
1955
 
@@ -3659,10 +3669,12 @@ class FuncCall(Expr):
3659
3669
  params: Sequence[Expr | KWPair] | None,
3660
3670
  genai_call: Optional[FuncCall],
3661
3671
  kid: Sequence[UniNode],
3672
+ body_genai_call: Optional[FuncCall] = None,
3662
3673
  ) -> None:
3663
3674
  self.target = target
3664
3675
  self.params = list(params) if params else []
3665
3676
  self.genai_call = genai_call
3677
+ self.body_genai_call = body_genai_call
3666
3678
  UniNode.__init__(self, kid=kid)
3667
3679
  Expr.__init__(self)
3668
3680
 
@@ -4578,17 +4590,21 @@ class String(Literal):
4578
4590
  return eval(self.value)
4579
4591
 
4580
4592
  elif self.value.startswith(("'", '"')):
4581
- repr_str = self.value.encode().decode("unicode_escape")
4582
- if (
4583
- (self.value.startswith('"""') and self.value.endswith('"""'))
4584
- or (self.value.startswith("'''") and self.value.endswith("'''"))
4585
- ) and not self.find_parent_of_type(FString):
4586
- return repr_str[3:-3]
4587
4593
  if (not self.find_parent_of_type(FString)) or (
4588
4594
  not (self.parent and isinstance(self.parent, FString))
4589
4595
  ):
4590
- return repr_str[1:-1]
4591
- return repr_str
4596
+ try:
4597
+ return ast3.literal_eval(self.value)
4598
+ except (ValueError, SyntaxError):
4599
+ if (
4600
+ self.value.startswith('"""') and self.value.endswith('"""')
4601
+ ) or (self.value.startswith("'''") and self.value.endswith("'''")):
4602
+ return self.value[3:-3]
4603
+ return self.value[1:-1]
4604
+ try:
4605
+ return ast3.literal_eval(self.value)
4606
+ except (ValueError, SyntaxError):
4607
+ return self.value
4592
4608
  else:
4593
4609
  return self.value
4594
4610
 
@@ -1 +1 @@
1
- """Jac Language Server Protocol implementation."""
1
+ """Jaclang langserve package."""