jaclang 0.7.2__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.

Files changed (92) hide show
  1. jaclang/cli/cli.py +2 -2
  2. jaclang/compiler/absyntree.py +499 -294
  3. jaclang/compiler/codeloc.py +2 -2
  4. jaclang/compiler/constant.py +100 -2
  5. jaclang/compiler/jac.lark +27 -19
  6. jaclang/compiler/parser.py +119 -92
  7. jaclang/compiler/passes/main/access_modifier_pass.py +20 -12
  8. jaclang/compiler/passes/main/def_impl_match_pass.py +28 -14
  9. jaclang/compiler/passes/main/def_use_pass.py +59 -40
  10. jaclang/compiler/passes/main/fuse_typeinfo_pass.py +65 -43
  11. jaclang/compiler/passes/main/import_pass.py +8 -6
  12. jaclang/compiler/passes/main/pyast_gen_pass.py +97 -42
  13. jaclang/compiler/passes/main/pyast_load_pass.py +47 -12
  14. jaclang/compiler/passes/main/pyjac_ast_link_pass.py +19 -10
  15. jaclang/compiler/passes/main/registry_pass.py +6 -6
  16. jaclang/compiler/passes/main/sub_node_tab_pass.py +0 -5
  17. jaclang/compiler/passes/main/sym_tab_build_pass.py +43 -235
  18. jaclang/compiler/passes/main/tests/test_decl_def_match_pass.py +21 -4
  19. jaclang/compiler/passes/main/tests/test_def_use_pass.py +5 -10
  20. jaclang/compiler/passes/main/type_check_pass.py +2 -1
  21. jaclang/compiler/passes/tool/jac_formatter_pass.py +30 -9
  22. jaclang/compiler/passes/tool/tests/fixtures/corelib.jac +16 -0
  23. jaclang/compiler/passes/tool/tests/fixtures/corelib_fmt.jac +16 -0
  24. jaclang/compiler/passes/tool/tests/fixtures/genai/essay_review.jac +1 -1
  25. jaclang/compiler/passes/tool/tests/fixtures/genai/expert_answer.jac +1 -1
  26. jaclang/compiler/passes/tool/tests/fixtures/genai/joke_gen.jac +1 -1
  27. jaclang/compiler/passes/tool/tests/fixtures/genai/odd_word_out.jac +1 -1
  28. jaclang/compiler/passes/tool/tests/fixtures/genai/personality_finder.jac +1 -1
  29. jaclang/compiler/passes/tool/tests/fixtures/genai/text_to_type.jac +1 -1
  30. jaclang/compiler/passes/tool/tests/fixtures/genai/translator.jac +1 -1
  31. jaclang/compiler/passes/tool/tests/fixtures/genai/wikipedia.jac +1 -1
  32. jaclang/compiler/passes/transform.py +2 -4
  33. jaclang/{core/registry.py → compiler/semtable.py} +1 -3
  34. jaclang/compiler/symtable.py +142 -101
  35. jaclang/compiler/tests/test_parser.py +2 -2
  36. jaclang/core/aott.py +15 -11
  37. jaclang/core/{construct.py → architype.py} +25 -240
  38. jaclang/core/constructs.py +44 -0
  39. jaclang/core/context.py +157 -0
  40. jaclang/core/importer.py +18 -9
  41. jaclang/core/memory.py +99 -0
  42. jaclang/core/test.py +90 -0
  43. jaclang/core/utils.py +2 -2
  44. jaclang/langserve/engine.py +127 -50
  45. jaclang/langserve/server.py +34 -61
  46. jaclang/langserve/tests/fixtures/base_module_structure.jac +28 -0
  47. jaclang/langserve/tests/fixtures/circle.jac +16 -12
  48. jaclang/langserve/tests/fixtures/circle_err.jac +3 -3
  49. jaclang/langserve/tests/fixtures/circle_pure.test.jac +15 -0
  50. jaclang/langserve/tests/fixtures/import_include_statements.jac +6 -0
  51. jaclang/langserve/tests/fixtures/py_import.py +26 -0
  52. jaclang/langserve/tests/test_server.py +93 -18
  53. jaclang/langserve/utils.py +124 -10
  54. jaclang/plugin/builtin.py +1 -1
  55. jaclang/plugin/default.py +23 -9
  56. jaclang/plugin/feature.py +25 -7
  57. jaclang/plugin/spec.py +18 -20
  58. jaclang/settings.py +3 -0
  59. jaclang/tests/fixtures/abc.jac +16 -12
  60. jaclang/tests/fixtures/aott_raise.jac +1 -1
  61. jaclang/tests/fixtures/byllmissue.jac +9 -0
  62. jaclang/tests/fixtures/edgetypeissue.jac +10 -0
  63. jaclang/tests/fixtures/hello.jac +1 -1
  64. jaclang/tests/fixtures/impl_match_confused.impl.jac +1 -0
  65. jaclang/tests/fixtures/impl_match_confused.jac +5 -0
  66. jaclang/tests/fixtures/maxfail_run_test.jac +17 -5
  67. jaclang/tests/fixtures/run_test.jac +17 -5
  68. jaclang/tests/fixtures/with_llm_function.jac +1 -1
  69. jaclang/tests/fixtures/with_llm_lower.jac +1 -1
  70. jaclang/tests/fixtures/with_llm_method.jac +1 -1
  71. jaclang/tests/fixtures/with_llm_type.jac +1 -1
  72. jaclang/tests/fixtures/with_llm_vision.jac +1 -1
  73. jaclang/tests/test_bugs.py +19 -0
  74. jaclang/tests/test_cli.py +1 -1
  75. jaclang/tests/test_language.py +161 -96
  76. jaclang/tests/test_reference.py +1 -1
  77. jaclang/utils/lang_tools.py +5 -4
  78. jaclang/utils/test.py +2 -1
  79. jaclang/utils/treeprinter.py +22 -8
  80. {jaclang-0.7.2.dist-info → jaclang-0.7.6.dist-info}/METADATA +1 -1
  81. {jaclang-0.7.2.dist-info → jaclang-0.7.6.dist-info}/RECORD +83 -80
  82. jaclang/core/llms/__init__.py +0 -20
  83. jaclang/core/llms/anthropic.py +0 -90
  84. jaclang/core/llms/base.py +0 -206
  85. jaclang/core/llms/groq.py +0 -70
  86. jaclang/core/llms/huggingface.py +0 -76
  87. jaclang/core/llms/ollama.py +0 -81
  88. jaclang/core/llms/openai.py +0 -65
  89. jaclang/core/llms/togetherai.py +0 -63
  90. jaclang/core/llms/utils.py +0 -9
  91. {jaclang-0.7.2.dist-info → jaclang-0.7.6.dist-info}/WHEEL +0 -0
  92. {jaclang-0.7.2.dist-info → jaclang-0.7.6.dist-info}/entry_points.txt +0 -0
@@ -478,3 +478,19 @@ obj JacPlugin {
478
478
  (walker_obj: Any, expr: Any) -> bool {
479
479
  return walker_obj._jac_.visit_node(expr);
480
480
  }
481
+
482
+ glob expected_area = 78.53981633974483;
483
+
484
+ test a1 {
485
+ check assertAlmostEqual(calculate_area(RAD), expected_area);
486
+ }
487
+
488
+ test a2 {
489
+ c = Circle(RAD);
490
+ check assertAlmostEqual(c.area(), expected_area);
491
+ }
492
+
493
+ test a3 {
494
+ c = Circle(RAD);
495
+ check assertEqual(c.shape_type, ShapeType.CIRCLE);
496
+ }
@@ -1,4 +1,4 @@
1
- import:py from jaclang.core.llms, Anthropic;
1
+ import:py from mtllm.llms, Anthropic;
2
2
 
3
3
  glob llm = Anthropic(model_name="claude-3-sonnet-20240229");
4
4
 
@@ -1,4 +1,4 @@
1
- import:py from jaclang.core.llms, Anthropic;
1
+ import:py from mtllm.llms, Anthropic;
2
2
 
3
3
  glob llm = Anthropic(model_name="claude-3-sonnet-20240229");
4
4
 
@@ -1,4 +1,4 @@
1
- import:py from jaclang.core.llms, Anthropic;
1
+ import:py from mtllm.llms, Anthropic;
2
2
 
3
3
  glob llm = Anthropic(model_name="claude-3-sonnet-20240229");
4
4
 
@@ -1,4 +1,4 @@
1
- import:py from jaclang.core.llms, Anthropic;
1
+ import:py from mtllm.llms, Anthropic;
2
2
 
3
3
  glob llm = Anthropic(model_name="claude-3-sonnet-20240229");
4
4
 
@@ -1,4 +1,4 @@
1
- import:py from jaclang.core.llms, Anthropic;
1
+ import:py from mtllm.llms, Anthropic;
2
2
 
3
3
  glob llm = Anthropic(model_name="claude-3-sonnet-20240229");
4
4
 
@@ -1,4 +1,4 @@
1
- import:py from jaclang.core.llms, Anthropic;
1
+ import:py from mtllm.llms, Anthropic;
2
2
 
3
3
  glob llm = Anthropic(model_name="claude-3-sonnet-20240229");
4
4
 
@@ -1,4 +1,4 @@
1
- import:py from jaclang.core.llms, Anthropic;
1
+ import:py from mtllm.llms, Anthropic;
2
2
 
3
3
  glob llm = Anthropic(model_name="claude-3-sonnet-20240229");
4
4
 
@@ -1,5 +1,5 @@
1
1
  import:py wikipedia;
2
- import:py from jaclang.core.llms, Anthropic;
2
+ import:py from mtllm.llms, Anthropic;
3
3
 
4
4
  glob llm = Anthropic(model_name="claude-3-sonnet-20240229");
5
5
 
@@ -22,7 +22,7 @@ class Alert:
22
22
  def __str__(self) -> str:
23
23
  """Return string representation of alert."""
24
24
  return (
25
- f"{self.loc.mod_path}, line {self.loc.first_line},"
25
+ f" {self.loc.mod_path}, line {self.loc.first_line},"
26
26
  f" col {self.loc.col_start}: {self.msg}"
27
27
  )
28
28
 
@@ -40,7 +40,7 @@ class Transform(ABC, Generic[T]):
40
40
  prior: Optional[Transform] = None,
41
41
  ) -> None:
42
42
  """Initialize pass."""
43
- self.logger = logging.getLogger(self.__class__.__module__)
43
+ self.logger = logging.getLogger(self.__class__.__name__)
44
44
  self.errors_had: list[Alert] = [] if not prior else prior.errors_had
45
45
  self.warnings_had: list[Alert] = [] if not prior else prior.warnings_had
46
46
  self.cur_node: AstNode = input_ir # tracks current node during traversal
@@ -59,7 +59,6 @@ class Transform(ABC, Generic[T]):
59
59
  self.__class__,
60
60
  )
61
61
  self.errors_had.append(alrt)
62
- # print("Error:", str(alrt))
63
62
  self.logger.error(str(alrt))
64
63
 
65
64
  def log_warning(self, msg: str, node_override: Optional[AstNode] = None) -> None:
@@ -70,5 +69,4 @@ class Transform(ABC, Generic[T]):
70
69
  self.__class__,
71
70
  )
72
71
  self.warnings_had.append(alrt)
73
- # print("Warning:", str(alrt))
74
72
  self.logger.warning(str(alrt))
@@ -12,9 +12,7 @@ from typing import Optional
12
12
  class SemInfo:
13
13
  """Semantic information class."""
14
14
 
15
- def __init__(
16
- self, name: str, type: Optional[str] = None, semstr: Optional[str] = None
17
- ) -> None:
15
+ def __init__(self, name: str, type: Optional[str] = None, semstr: str = "") -> None:
18
16
  """Initialize the class."""
19
17
  self.name = name
20
18
  self.type = type
@@ -2,77 +2,14 @@
2
2
 
3
3
  from __future__ import annotations
4
4
 
5
- from enum import Enum
6
- from typing import Optional, TYPE_CHECKING
5
+ import ast as ast3
6
+ from typing import Optional, Sequence
7
7
 
8
+ import jaclang.compiler.absyntree as ast
9
+ from jaclang.compiler.constant import SymbolAccess, SymbolType
8
10
  from jaclang.utils.treeprinter import dotgen_symtab_tree, print_symtab_tree
9
11
 
10
12
 
11
- if TYPE_CHECKING:
12
- import jaclang.compiler.absyntree as ast
13
-
14
-
15
- class SymbolType(Enum):
16
- """Symbol types."""
17
-
18
- MODULE = "module" # LSP: Module
19
- MOD_VAR = "mod_var" # LSP: Variable
20
- VAR = "variable" # LSP: Variable
21
- IMM_VAR = "immutable" # LSP: Constant
22
- ABILITY = "ability" # LSP: Function
23
- OBJECT_ARCH = "object" # LSP: Class
24
- NODE_ARCH = "node" # LSP: Class
25
- EDGE_ARCH = "edge" # LSP: Class
26
- WALKER_ARCH = "walker" # LSP: Class
27
- ENUM_ARCH = "enum" # LSP: Enum
28
- TEST = "test" # LSP: Function
29
- TYPE = "type" # LSP: TypeParameter
30
- IMPL = "impl" # LSP: Interface or Property
31
- HAS_VAR = "field" # LSP: Field
32
- METHOD = "method" # LSP: Method
33
- CONSTRUCTOR = "constructor" # LSP: Constructor
34
- ENUM_MEMBER = "enum_member" # LSP: EnumMember
35
- NUMBER = "number" # LSP: Number
36
- STRING = "string" # LSP: String
37
- BOOL = "bool" # LSP: Boolean
38
- SEQUENCE = "sequence" # LSP: Array
39
- NULL = "null" # LSP: Null
40
-
41
- def __str__(self) -> str:
42
- """Stringify."""
43
- return self.value
44
-
45
-
46
- class SymbolInfo:
47
- """Symbol Info."""
48
-
49
- def __init__(
50
- self, typ: str = "NoType", acc_tag: Optional[SymbolAccess] = None
51
- ) -> None: # noqa: ANN401
52
- """Initialize."""
53
- self.typ = typ
54
- self.acc_tag: Optional[SymbolAccess] = acc_tag
55
- self.typ_sym_table: Optional[SymbolTable] = None
56
-
57
- @property
58
- def clean_type(self) -> str:
59
- """Get clean type."""
60
- ret_type = self.typ.replace("builtins.", "").replace("NoType", "")
61
- return ret_type
62
-
63
-
64
- class SymbolAccess(Enum):
65
- """Symbol types."""
66
-
67
- PRIVATE = "private"
68
- PUBLIC = "public"
69
- PROTECTED = "protected"
70
-
71
- def __str__(self) -> str:
72
- """Stringify."""
73
- return self.value
74
-
75
-
76
13
  # Symbols can have mulitple definitions but resolves decl to be the
77
14
  # first such definition in a given scope.
78
15
  class Symbol:
@@ -80,20 +17,19 @@ class Symbol:
80
17
 
81
18
  def __init__(
82
19
  self,
83
- defn: ast.AstSymbolNode,
20
+ defn: ast.NameAtom,
84
21
  access: SymbolAccess,
85
22
  parent_tab: SymbolTable,
86
- typ: Optional[type] = None,
87
23
  ) -> None:
88
24
  """Initialize."""
89
- self.typ = typ
90
- self.defn: list[ast.AstSymbolNode] = [defn]
91
- defn.sym_link = self
92
- self.access = access
25
+ self.defn: list[ast.NameAtom] = [defn]
26
+ self.uses: list[ast.NameAtom] = []
27
+ defn.sym = self
28
+ self.access: SymbolAccess = access
93
29
  self.parent_tab = parent_tab
94
30
 
95
31
  @property
96
- def decl(self) -> ast.AstSymbolNode:
32
+ def decl(self) -> ast.NameAtom:
97
33
  """Get decl."""
98
34
  return self.defn[0]
99
35
 
@@ -105,33 +41,32 @@ class Symbol:
105
41
  @property
106
42
  def sym_type(self) -> SymbolType:
107
43
  """Get sym_type."""
108
- return self.decl.sym_type
44
+ return self.decl.sym_category
109
45
 
110
46
  @property
111
- def sym_path_str(self) -> str:
47
+ def sym_dotted_name(self) -> str:
112
48
  """Return a full path of the symbol."""
113
49
  out = [self.defn[0].sym_name]
114
- current_tab = self.parent_tab
50
+ current_tab: SymbolTable | None = self.parent_tab
115
51
  while current_tab is not None:
116
52
  out.append(current_tab.name)
117
- if current_tab.has_parent():
118
- current_tab = current_tab.parent
119
- else:
120
- break
53
+ current_tab = current_tab.parent
121
54
  out.reverse()
122
55
  return ".".join(out)
123
56
 
124
- def add_defn(self, node: ast.AstSymbolNode) -> None:
57
+ def add_defn(self, node: ast.NameAtom) -> None:
125
58
  """Add defn."""
126
59
  self.defn.append(node)
127
- node.sym_link = self
60
+ node.sym = self
61
+
62
+ def add_use(self, node: ast.NameAtom) -> None:
63
+ """Add use."""
64
+ self.uses.append(node)
65
+ node.sym = self
128
66
 
129
67
  def __repr__(self) -> str:
130
68
  """Repr."""
131
- return (
132
- f"Symbol({self.sym_name}, {self.sym_type}, {self.access}, "
133
- f"{self.typ}, {self.defn})"
134
- )
69
+ return f"Symbol({self.sym_name}, {self.sym_type}, {self.access}, {self.defn})"
135
70
 
136
71
 
137
72
  class SymbolTable:
@@ -143,27 +78,25 @@ class SymbolTable:
143
78
  """Initialize."""
144
79
  self.name = name
145
80
  self.owner = owner
146
- self.parent = parent if parent else self
81
+ self.parent = parent
147
82
  self.kid: list[SymbolTable] = []
148
83
  self.tab: dict[str, Symbol] = {}
149
- self.uses: list[ast.AstSymbolNode] = []
84
+ self.inherit: list[SymbolTable] = []
150
85
 
151
- def has_parent(self) -> bool:
152
- """Check if has parent."""
153
- return self.parent != self
154
-
155
- def get_parent(self) -> SymbolTable:
86
+ def get_parent(self) -> Optional[SymbolTable]:
156
87
  """Get parent."""
157
- if self.parent == self:
158
- raise Exception("No parent")
159
88
  return self.parent
160
89
 
161
90
  def lookup(self, name: str, deep: bool = True) -> Optional[Symbol]:
162
91
  """Lookup a variable in the symbol table."""
163
92
  if name in self.tab:
164
93
  return self.tab[name]
165
- if deep and self.has_parent():
166
- return self.get_parent().lookup(name, deep)
94
+ for i in self.inherit:
95
+ found = i.lookup(name, deep=False)
96
+ if found:
97
+ return found
98
+ if deep and self.parent:
99
+ return self.parent.lookup(name, deep)
167
100
  return None
168
101
 
169
102
  def insert(
@@ -184,7 +117,7 @@ class SymbolTable:
184
117
  )
185
118
  if node.sym_name not in self.tab:
186
119
  self.tab[node.sym_name] = Symbol(
187
- defn=node,
120
+ defn=node.name_spec,
188
121
  access=(
189
122
  access_spec
190
123
  if isinstance(access_spec, SymbolAccess)
@@ -193,8 +126,8 @@ class SymbolTable:
193
126
  parent_tab=self,
194
127
  )
195
128
  else:
196
- self.tab[node.sym_name].add_defn(node)
197
- node.sym_link = self.tab[node.sym_name]
129
+ self.tab[node.sym_name].add_defn(node.name_spec)
130
+ node.name_spec.sym = self.tab[node.sym_name]
198
131
  return collision
199
132
 
200
133
  def find_scope(self, name: str) -> Optional[SymbolTable]:
@@ -209,6 +142,114 @@ class SymbolTable:
209
142
  self.kid.append(SymbolTable(name, key_node, self))
210
143
  return self.kid[-1]
211
144
 
145
+ def inherit_sym_tab(self, target_sym_tab: SymbolTable) -> None:
146
+ """Inherit symbol table."""
147
+ for i in target_sym_tab.tab.values():
148
+ self.def_insert(i.decl, access_spec=i.access)
149
+
150
+ def def_insert(
151
+ self,
152
+ node: ast.AstSymbolNode,
153
+ access_spec: Optional[ast.AstAccessNode] | SymbolAccess = None,
154
+ single_decl: Optional[str] = None,
155
+ ) -> Optional[Symbol]:
156
+ """Insert into symbol table."""
157
+ if node.sym and self == node.sym.parent_tab:
158
+ return node.sym
159
+ self.insert(node=node, single=single_decl is not None, access_spec=access_spec)
160
+ self.update_py_ctx_for_def(node)
161
+ return node.sym
162
+
163
+ def chain_def_insert(self, node_list: list[ast.AstSymbolNode]) -> None:
164
+ """Link chain of containing names to symbol."""
165
+ if not node_list:
166
+ return
167
+ cur_sym_tab: SymbolTable | None = node_list[0].sym_tab
168
+ node_list[-1].name_spec.py_ctx_func = ast3.Store
169
+ if isinstance(node_list[-1].name_spec, ast.AstSymbolNode):
170
+ node_list[-1].name_spec.py_ctx_func = ast3.Store
171
+
172
+ node_list = node_list[:-1] # Just performs lookup mappings of pre assign chain
173
+ for i in node_list:
174
+ cur_sym_tab = (
175
+ lookup.decl.sym_tab
176
+ if (
177
+ lookup := self.use_lookup(
178
+ i,
179
+ sym_table=cur_sym_tab,
180
+ )
181
+ )
182
+ else None
183
+ )
184
+
185
+ def use_lookup(
186
+ self,
187
+ node: ast.AstSymbolNode,
188
+ sym_table: Optional[SymbolTable] = None,
189
+ ) -> Optional[Symbol]:
190
+ """Link to symbol."""
191
+ if node.sym:
192
+ return node.sym
193
+ if not sym_table:
194
+ sym_table = node.sym_tab
195
+ if sym_table:
196
+ lookup = sym_table.lookup(name=node.sym_name, deep=True)
197
+ lookup.add_use(node.name_spec) if lookup else None
198
+ return node.sym
199
+
200
+ def chain_use_lookup(self, node_list: Sequence[ast.AstSymbolNode]) -> None:
201
+ """Link chain of containing names to symbol."""
202
+ if not node_list:
203
+ return
204
+ cur_sym_tab: SymbolTable | None = node_list[0].sym_tab
205
+ for i in node_list:
206
+ if cur_sym_tab is None:
207
+ break
208
+ cur_sym_tab = (
209
+ lookup.decl.sym_tab
210
+ if (
211
+ lookup := self.use_lookup(
212
+ i,
213
+ sym_table=cur_sym_tab,
214
+ )
215
+ )
216
+ else None
217
+ )
218
+
219
+ def update_py_ctx_for_def(self, node: ast.AstSymbolNode) -> None:
220
+ """Update python context for definition."""
221
+ node.name_spec.py_ctx_func = ast3.Store
222
+ if isinstance(node, (ast.TupleVal, ast.ListVal)) and node.values:
223
+ # Handling of UnaryExpr case for item is only necessary for
224
+ # the generation of Starred nodes in the AST for examples
225
+ # like `(a, *b) = (1, 2, 3, 4)`.
226
+ def fix(item: ast.TupleVal | ast.ListVal | ast.UnaryExpr) -> None:
227
+ if isinstance(item, ast.UnaryExpr):
228
+ if isinstance(item.operand, ast.AstSymbolNode):
229
+ item.operand.name_spec.py_ctx_func = ast3.Store
230
+ elif isinstance(item, (ast.TupleVal, ast.ListVal)):
231
+ for i in item.values.items if item.values else []:
232
+ if isinstance(i, ast.AstSymbolNode):
233
+ i.name_spec.py_ctx_func = ast3.Store
234
+ elif isinstance(i, ast.AtomTrailer):
235
+ self.chain_def_insert(i.as_attr_list)
236
+ if isinstance(i, (ast.TupleVal, ast.ListVal, ast.UnaryExpr)):
237
+ fix(i)
238
+
239
+ fix(node)
240
+
241
+ def inherit_baseclasses_sym(self, node: ast.Architype | ast.Enum) -> None:
242
+ """Inherit base classes symbol tables."""
243
+ if node.base_classes:
244
+ for base_cls in node.base_classes.items:
245
+ if (
246
+ isinstance(base_cls, ast.AstSymbolNode)
247
+ and (found := self.use_lookup(base_cls))
248
+ and found
249
+ ):
250
+ self.inherit.append(found.decl.sym_tab)
251
+ base_cls.name_spec.name_of = found.decl.name_of
252
+
212
253
  def pp(self, depth: Optional[int] = None) -> str:
213
254
  """Pretty print."""
214
255
  return print_symtab_tree(root=self, depth=depth)
@@ -102,9 +102,9 @@ class TestLarkParser(TestCaseMicroSuite):
102
102
  "JacSource",
103
103
  "EmptyToken",
104
104
  "AstSymbolNode",
105
+ "AstSymbolStubNode",
105
106
  "AstImplNeedingNode",
106
107
  "AstAccessNode",
107
- "TokenSymbol",
108
108
  "Literal",
109
109
  "AstDocNode",
110
110
  "AstSemStrNode",
@@ -119,7 +119,7 @@ class TestLarkParser(TestCaseMicroSuite):
119
119
  "ArchBlockStmt",
120
120
  "EnumBlockStmt",
121
121
  "CodeBlockStmt",
122
- "NameSpec",
122
+ "NameAtom",
123
123
  "ArchSpec",
124
124
  "MatchPattern",
125
125
  ]
jaclang/core/aott.py CHANGED
@@ -17,15 +17,19 @@ try:
17
17
  except ImportError:
18
18
  Image = None
19
19
 
20
- from jaclang.core.llms.base import BaseLLM
21
- from jaclang.core.registry import SemInfo, SemRegistry, SemScope
20
+ from jaclang.compiler.semtable import SemInfo, SemRegistry, SemScope
21
+
22
+ try:
23
+ from mtllm.llms import BaseLLM
24
+ except ImportError:
25
+ BaseLLM = None
22
26
 
23
27
 
24
28
  IMG_FORMATS = ["PngImageFile", "JpegImageFile"]
25
29
 
26
30
 
27
31
  def aott_raise(
28
- model: BaseLLM,
32
+ model: BaseLLM, # type: ignore
29
33
  information: str,
30
34
  inputs_information: str | list[dict],
31
35
  output_information: str,
@@ -108,7 +112,7 @@ def get_info_types(
108
112
  else None
109
113
  )
110
114
  info_str.append(
111
- f"{sem_info.semstr} ({sem_info.name}) ({sem_info.type}) = {get_object_string(incl[1])}"
115
+ f"{sem_info.semstr} ({sem_info.name}) ({sem_info.type}) = {get_object_string(incl[1])}".strip()
112
116
  )
113
117
  return ("\n".join(info_str), collected_types)
114
118
 
@@ -179,7 +183,7 @@ def get_type_explanation(
179
183
  if sem_info.type == "Enum" and isinstance(type_info, list):
180
184
  for enum_item in type_info:
181
185
  type_info_str.append(
182
- f"{enum_item.semstr} ({enum_item.name}) (EnumItem)"
186
+ f"{enum_item.semstr} ({enum_item.name}) (EnumItem)".strip()
183
187
  )
184
188
  type_example[0] = type_example[0].replace("(", f".{enum_item.name}")
185
189
  elif sem_info.type in ["obj", "class", "node", "edge"] and isinstance(
@@ -189,7 +193,7 @@ def get_type_explanation(
189
193
  if arch_item.type in ["obj", "class", "node", "edge"]:
190
194
  continue
191
195
  type_info_str.append(
192
- f"{arch_item.semstr} ({arch_item.name}) ({arch_item.type})"
196
+ f"{arch_item.semstr} ({arch_item.name}) ({arch_item.type})".strip()
193
197
  )
194
198
  type_example.append(f"{arch_item.name}={arch_item.type}, ")
195
199
  if arch_item.type and extract_non_primary_type(arch_item.type):
@@ -199,7 +203,7 @@ def get_type_explanation(
199
203
  else:
200
204
  type_example.append(")")
201
205
  return (
202
- f"{sem_info.semstr} ({sem_info.name}) ({sem_info.type}) eg:- {''.join(type_example)} -> {', '.join(type_info_str)}", # noqa: E501
206
+ f"{sem_info.semstr} ({sem_info.name}) ({sem_info.type}) eg:- {''.join(type_example)} -> {', '.join(type_info_str)}".strip(), # noqa: E501
203
207
  set(type_info_types),
204
208
  )
205
209
  return None, None
@@ -270,7 +274,7 @@ def get_input_information(
270
274
  typ_anno = get_type_annotation(i[3])
271
275
  type_collector.extend(extract_non_primary_type(typ_anno))
272
276
  inputs_information_list.append(
273
- f"{i[0]} ({i[2]}) ({typ_anno}) = {get_object_string(i[3])}"
277
+ f"{i[0] if i[0] else ''} ({i[2]}) ({typ_anno}) = {get_object_string(i[3])}".strip()
274
278
  )
275
279
  return "\n".join(inputs_information_list)
276
280
  else:
@@ -281,7 +285,7 @@ def get_input_information(
281
285
  image_repr: list[dict] = [
282
286
  {
283
287
  "type": "text",
284
- "text": f"{i[0]} ({i[2]}) (Image) = ",
288
+ "text": f"{i[0] if i[0] else ''} ({i[2]}) (Image) = ".strip(),
285
289
  },
286
290
  {"type": "image_url", "image_url": {"url": img_base64}},
287
291
  ]
@@ -292,13 +296,13 @@ def get_input_information(
292
296
  inputs_information_dict_list.append(
293
297
  {
294
298
  "type": "text",
295
- "text": f"{i[0]} ({i[2]}) ({typ_anno}) = {get_object_string(i[3])}",
299
+ "text": f"{i[0] if i[0] else ''} ({i[2]}) ({typ_anno}) = {get_object_string(i[3])}".strip(),
296
300
  }
297
301
  )
298
302
  return inputs_information_dict_list
299
303
 
300
304
 
301
- def image_to_base64(image: Image) -> str:
305
+ def image_to_base64(image: Image) -> str: # type: ignore
302
306
  """Convert an image to base64 expected by OpenAI."""
303
307
  if not Image:
304
308
  log = logging.getLogger(__name__)