jaclang 0.5.7__py3-none-any.whl → 0.5.9__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 +113 -7
- jaclang/cli/cmdreg.py +12 -0
- jaclang/compiler/__init__.py +58 -2
- jaclang/compiler/absyntree.py +1775 -61
- jaclang/compiler/codeloc.py +7 -0
- jaclang/compiler/compile.py +1 -1
- jaclang/compiler/constant.py +17 -0
- jaclang/compiler/parser.py +134 -112
- jaclang/compiler/passes/ir_pass.py +18 -0
- jaclang/compiler/passes/main/__init__.py +2 -0
- jaclang/compiler/passes/main/def_impl_match_pass.py +19 -3
- jaclang/compiler/passes/main/def_use_pass.py +1 -1
- jaclang/compiler/passes/main/fuse_typeinfo_pass.py +357 -0
- jaclang/compiler/passes/main/import_pass.py +7 -3
- jaclang/compiler/passes/main/pyast_gen_pass.py +350 -109
- jaclang/compiler/passes/main/pyast_load_pass.py +1779 -206
- jaclang/compiler/passes/main/registry_pass.py +126 -0
- jaclang/compiler/passes/main/schedules.py +4 -1
- jaclang/compiler/passes/main/sym_tab_build_pass.py +20 -28
- jaclang/compiler/passes/main/tests/test_pyast_build_pass.py +14 -5
- jaclang/compiler/passes/main/tests/test_registry_pass.py +39 -0
- jaclang/compiler/passes/main/tests/test_sym_tab_build_pass.py +8 -8
- jaclang/compiler/passes/main/tests/test_typeinfo_pass.py +7 -0
- jaclang/compiler/passes/main/type_check_pass.py +0 -1
- jaclang/compiler/passes/tool/jac_formatter_pass.py +8 -17
- jaclang/compiler/passes/tool/tests/test_unparse_validate.py +65 -0
- jaclang/compiler/passes/utils/mypy_ast_build.py +28 -14
- jaclang/compiler/symtable.py +23 -2
- jaclang/compiler/tests/test_parser.py +53 -0
- jaclang/compiler/workspace.py +52 -26
- jaclang/core/aott.py +193 -28
- jaclang/core/construct.py +59 -2
- jaclang/core/registry.py +115 -0
- jaclang/core/utils.py +25 -0
- jaclang/plugin/default.py +108 -26
- jaclang/plugin/feature.py +22 -4
- jaclang/plugin/spec.py +13 -7
- jaclang/utils/helpers.py +66 -3
- jaclang/utils/lang_tools.py +6 -38
- jaclang/utils/test.py +1 -0
- jaclang/utils/tests/test_lang_tools.py +11 -14
- jaclang/utils/treeprinter.py +10 -2
- {jaclang-0.5.7.dist-info → jaclang-0.5.9.dist-info}/METADATA +1 -1
- {jaclang-0.5.7.dist-info → jaclang-0.5.9.dist-info}/RECORD +47 -43
- {jaclang-0.5.7.dist-info → jaclang-0.5.9.dist-info}/WHEEL +1 -1
- jaclang/compiler/__jac_gen__/__init__.py +0 -0
- jaclang/compiler/__jac_gen__/jac_parser.py +0 -4069
- {jaclang-0.5.7.dist-info → jaclang-0.5.9.dist-info}/entry_points.txt +0 -0
- {jaclang-0.5.7.dist-info → jaclang-0.5.9.dist-info}/top_level.txt +0 -0
jaclang/plugin/default.py
CHANGED
|
@@ -2,7 +2,9 @@
|
|
|
2
2
|
|
|
3
3
|
from __future__ import annotations
|
|
4
4
|
|
|
5
|
+
import fnmatch
|
|
5
6
|
import os
|
|
7
|
+
import pickle
|
|
6
8
|
import types
|
|
7
9
|
from dataclasses import field
|
|
8
10
|
from functools import wraps
|
|
@@ -10,7 +12,15 @@ from typing import Any, Callable, Optional, Type
|
|
|
10
12
|
|
|
11
13
|
from jaclang.compiler.absyntree import Module
|
|
12
14
|
from jaclang.compiler.constant import EdgeDir, colors
|
|
13
|
-
from jaclang.core.aott import
|
|
15
|
+
from jaclang.core.aott import (
|
|
16
|
+
aott_raise,
|
|
17
|
+
extract_non_primary_type,
|
|
18
|
+
get_all_type_explanations,
|
|
19
|
+
get_info_types,
|
|
20
|
+
get_object_string,
|
|
21
|
+
get_reasoning_output,
|
|
22
|
+
get_type_annotation,
|
|
23
|
+
)
|
|
14
24
|
from jaclang.core.construct import (
|
|
15
25
|
Architype,
|
|
16
26
|
DSFunc,
|
|
@@ -27,6 +37,7 @@ from jaclang.core.construct import (
|
|
|
27
37
|
root,
|
|
28
38
|
)
|
|
29
39
|
from jaclang.core.importer import jac_importer
|
|
40
|
+
from jaclang.core.registry import SemScope
|
|
30
41
|
from jaclang.core.utils import traverse_graph
|
|
31
42
|
from jaclang.plugin.feature import JacFeature as Jac
|
|
32
43
|
from jaclang.plugin.spec import T
|
|
@@ -185,20 +196,58 @@ class JacFeatureDefaults:
|
|
|
185
196
|
|
|
186
197
|
@staticmethod
|
|
187
198
|
@hookimpl
|
|
188
|
-
def run_test(
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
:
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
199
|
+
def run_test(
|
|
200
|
+
filepath: str,
|
|
201
|
+
filter: Optional[str],
|
|
202
|
+
xit: bool,
|
|
203
|
+
maxfail: Optional[int],
|
|
204
|
+
directory: Optional[str],
|
|
205
|
+
verbose: bool,
|
|
206
|
+
) -> bool:
|
|
207
|
+
"""Run the test suite in the specified .jac file."""
|
|
208
|
+
test_file = False
|
|
209
|
+
if filepath:
|
|
210
|
+
if filepath.endswith(".jac"):
|
|
211
|
+
base, mod_name = os.path.split(filepath)
|
|
212
|
+
base = base if base else "./"
|
|
213
|
+
mod_name = mod_name[:-4]
|
|
214
|
+
JacTestCheck.reset()
|
|
215
|
+
Jac.jac_import(target=mod_name, base_path=base)
|
|
216
|
+
JacTestCheck.run_test(xit, maxfail, verbose)
|
|
217
|
+
else:
|
|
218
|
+
print("Not a .jac file.")
|
|
200
219
|
else:
|
|
201
|
-
|
|
220
|
+
directory = directory if directory else os.getcwd()
|
|
221
|
+
|
|
222
|
+
if filter or directory:
|
|
223
|
+
current_dir = directory if directory else os.getcwd()
|
|
224
|
+
for root_dir, _, files in os.walk(current_dir, topdown=True):
|
|
225
|
+
files = (
|
|
226
|
+
[file for file in files if fnmatch.fnmatch(file, filter)]
|
|
227
|
+
if filter
|
|
228
|
+
else files
|
|
229
|
+
)
|
|
230
|
+
files = [
|
|
231
|
+
file
|
|
232
|
+
for file in files
|
|
233
|
+
if not file.endswith((".test.jac", ".impl.jac"))
|
|
234
|
+
]
|
|
235
|
+
for file in files:
|
|
236
|
+
if file.endswith(".jac"):
|
|
237
|
+
test_file = True
|
|
238
|
+
print(f"\n\n\t\t* Inside {root_dir}" + "/" + f"{file} *")
|
|
239
|
+
JacTestCheck.reset()
|
|
240
|
+
Jac.jac_import(target=file[:-4], base_path=root_dir)
|
|
241
|
+
JacTestCheck.run_test(xit, maxfail, verbose)
|
|
242
|
+
|
|
243
|
+
if JacTestCheck.breaker and (xit or maxfail):
|
|
244
|
+
break
|
|
245
|
+
if JacTestCheck.breaker and (xit or maxfail):
|
|
246
|
+
break
|
|
247
|
+
JacTestCheck.breaker = False
|
|
248
|
+
JacTestCheck.failcount = 0
|
|
249
|
+
print("No test files found.") if not test_file else None
|
|
250
|
+
|
|
202
251
|
return True
|
|
203
252
|
|
|
204
253
|
@staticmethod
|
|
@@ -389,33 +438,66 @@ class JacFeatureDefaults:
|
|
|
389
438
|
@staticmethod
|
|
390
439
|
@hookimpl
|
|
391
440
|
def with_llm(
|
|
441
|
+
file_loc: str,
|
|
392
442
|
model: Any, # noqa: ANN401
|
|
393
443
|
model_params: dict[str, Any],
|
|
394
|
-
|
|
395
|
-
|
|
444
|
+
scope: str,
|
|
445
|
+
incl_info: list[tuple[str, str]],
|
|
446
|
+
excl_info: list[tuple[str, str]],
|
|
396
447
|
inputs: tuple,
|
|
397
448
|
outputs: tuple,
|
|
398
449
|
action: str,
|
|
399
450
|
) -> Any: # noqa: ANN401
|
|
400
451
|
"""Jac's with_llm feature."""
|
|
452
|
+
with open(
|
|
453
|
+
os.path.join(
|
|
454
|
+
os.path.dirname(file_loc),
|
|
455
|
+
"__jac_gen__",
|
|
456
|
+
os.path.basename(file_loc).replace(".jac", ".registry.pkl"),
|
|
457
|
+
),
|
|
458
|
+
"rb",
|
|
459
|
+
) as f:
|
|
460
|
+
mod_registry = pickle.load(f)
|
|
461
|
+
|
|
462
|
+
_scope = SemScope.get_scope_from_str(scope)
|
|
463
|
+
assert _scope is not None
|
|
464
|
+
|
|
401
465
|
reason = False
|
|
402
466
|
if "reason" in model_params:
|
|
403
467
|
reason = model_params.pop("reason")
|
|
404
|
-
|
|
405
|
-
|
|
406
|
-
|
|
407
|
-
|
|
468
|
+
|
|
469
|
+
type_collector: list = []
|
|
470
|
+
information, collected_types = get_info_types(_scope, mod_registry, incl_info)
|
|
471
|
+
type_collector.extend(collected_types)
|
|
472
|
+
|
|
473
|
+
inputs_information_list = []
|
|
474
|
+
for i in inputs:
|
|
475
|
+
typ_anno = get_type_annotation(i[3])
|
|
476
|
+
type_collector.extend(extract_non_primary_type(typ_anno))
|
|
477
|
+
inputs_information_list.append(
|
|
478
|
+
f"{i[0]} ({i[2]}) ({typ_anno}) = {get_object_string(i[3])}"
|
|
479
|
+
)
|
|
480
|
+
inputs_information = "\n".join(inputs_information_list)
|
|
481
|
+
|
|
482
|
+
output_information = f"{outputs[0]} ({outputs[2]})"
|
|
483
|
+
type_collector.extend(extract_non_primary_type(outputs[2]))
|
|
484
|
+
|
|
485
|
+
type_explanations_list = list(
|
|
486
|
+
get_all_type_explanations(type_collector, mod_registry).values()
|
|
487
|
+
)
|
|
488
|
+
type_explanations = "\n".join(type_explanations_list)
|
|
489
|
+
|
|
408
490
|
meaning_in = aott_raise(
|
|
409
|
-
|
|
410
|
-
|
|
411
|
-
|
|
412
|
-
|
|
491
|
+
information,
|
|
492
|
+
inputs_information,
|
|
493
|
+
output_information,
|
|
494
|
+
type_explanations,
|
|
413
495
|
action,
|
|
414
496
|
reason,
|
|
415
497
|
)
|
|
416
498
|
meaning_out = model.__infer__(meaning_in, **model_params)
|
|
417
|
-
|
|
418
|
-
return
|
|
499
|
+
reasoning, output = get_reasoning_output(meaning_out)
|
|
500
|
+
return output
|
|
419
501
|
|
|
420
502
|
|
|
421
503
|
class JacBuiltin:
|
jaclang/plugin/feature.py
CHANGED
|
@@ -96,9 +96,23 @@ class JacFeature:
|
|
|
96
96
|
return pm.hook.create_test(test_fun=test_fun)
|
|
97
97
|
|
|
98
98
|
@staticmethod
|
|
99
|
-
def run_test(
|
|
99
|
+
def run_test(
|
|
100
|
+
filepath: str,
|
|
101
|
+
filter: Optional[str] = None,
|
|
102
|
+
xit: bool = False,
|
|
103
|
+
maxfail: Optional[int] = None,
|
|
104
|
+
directory: Optional[str] = None,
|
|
105
|
+
verbose: bool = False,
|
|
106
|
+
) -> bool:
|
|
100
107
|
"""Run the test suite in the specified .jac file."""
|
|
101
|
-
return pm.hook.run_test(
|
|
108
|
+
return pm.hook.run_test(
|
|
109
|
+
filepath=filepath,
|
|
110
|
+
filter=filter,
|
|
111
|
+
xit=xit,
|
|
112
|
+
maxfail=maxfail,
|
|
113
|
+
directory=directory,
|
|
114
|
+
verbose=verbose,
|
|
115
|
+
)
|
|
102
116
|
|
|
103
117
|
@staticmethod
|
|
104
118
|
def elvis(op1: Optional[T], op2: T) -> T:
|
|
@@ -213,18 +227,22 @@ class JacFeature:
|
|
|
213
227
|
|
|
214
228
|
@staticmethod
|
|
215
229
|
def with_llm(
|
|
230
|
+
file_loc: str,
|
|
216
231
|
model: Any, # noqa: ANN401
|
|
217
232
|
model_params: dict[str, Any],
|
|
218
|
-
|
|
219
|
-
|
|
233
|
+
scope: str,
|
|
234
|
+
incl_info: list[tuple[str, str]],
|
|
235
|
+
excl_info: list[tuple[str, str]],
|
|
220
236
|
inputs: tuple,
|
|
221
237
|
outputs: tuple,
|
|
222
238
|
action: str,
|
|
223
239
|
) -> Any: # noqa: ANN401
|
|
224
240
|
"""Jac's with_llm feature."""
|
|
225
241
|
return pm.hook.with_llm(
|
|
242
|
+
file_loc=file_loc,
|
|
226
243
|
model=model,
|
|
227
244
|
model_params=model_params,
|
|
245
|
+
scope=scope,
|
|
228
246
|
incl_info=incl_info,
|
|
229
247
|
excl_info=excl_info,
|
|
230
248
|
inputs=inputs,
|
jaclang/plugin/spec.py
CHANGED
|
@@ -88,11 +88,15 @@ class JacFeatureSpec:
|
|
|
88
88
|
|
|
89
89
|
@staticmethod
|
|
90
90
|
@hookspec(firstresult=True)
|
|
91
|
-
def run_test(
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
:
|
|
95
|
-
|
|
91
|
+
def run_test(
|
|
92
|
+
filepath: str,
|
|
93
|
+
filter: Optional[str],
|
|
94
|
+
xit: bool,
|
|
95
|
+
maxfail: Optional[int],
|
|
96
|
+
directory: Optional[str],
|
|
97
|
+
verbose: bool,
|
|
98
|
+
) -> bool:
|
|
99
|
+
"""Run the test suite in the specified .jac file."""
|
|
96
100
|
raise NotImplementedError
|
|
97
101
|
|
|
98
102
|
@staticmethod
|
|
@@ -207,10 +211,12 @@ class JacFeatureSpec:
|
|
|
207
211
|
@staticmethod
|
|
208
212
|
@hookspec(firstresult=True)
|
|
209
213
|
def with_llm(
|
|
214
|
+
file_loc: str,
|
|
210
215
|
model: Any, # noqa: ANN401
|
|
211
216
|
model_params: dict[str, Any],
|
|
212
|
-
|
|
213
|
-
|
|
217
|
+
scope: str,
|
|
218
|
+
incl_info: list[tuple[str, str]],
|
|
219
|
+
excl_info: list[tuple[str, str]],
|
|
214
220
|
inputs: tuple,
|
|
215
221
|
outputs: tuple,
|
|
216
222
|
action: str,
|
jaclang/utils/helpers.py
CHANGED
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
"""Utility functions and classes for Jac compilation toolchain."""
|
|
2
2
|
|
|
3
|
+
import dis
|
|
4
|
+
import marshal
|
|
3
5
|
import os
|
|
6
|
+
import pdb
|
|
4
7
|
import re
|
|
5
8
|
|
|
6
9
|
|
|
7
|
-
import jaclang.compiler.absyntree as ast
|
|
8
|
-
|
|
9
|
-
|
|
10
10
|
def pascal_to_snake(pascal_string: str) -> str:
|
|
11
11
|
"""Convert pascal case to snake case."""
|
|
12
12
|
snake_string = re.sub(r"(?<!^)(?=[A-Z])", "_", pascal_string).lower()
|
|
@@ -43,6 +43,7 @@ def get_ast_nodes_as_snake_case() -> list[str]:
|
|
|
43
43
|
"""Get all AST nodes as snake case."""
|
|
44
44
|
import inspect
|
|
45
45
|
import sys
|
|
46
|
+
import jaclang.compiler.absyntree as ast
|
|
46
47
|
|
|
47
48
|
module_name = ast.__name__
|
|
48
49
|
module = sys.modules[module_name]
|
|
@@ -85,6 +86,46 @@ def extract_headings(file_path: str) -> dict[str, tuple[int, int]]:
|
|
|
85
86
|
return headings
|
|
86
87
|
|
|
87
88
|
|
|
89
|
+
def auto_generate_refs() -> None:
|
|
90
|
+
"""Auto generate lang reference for docs."""
|
|
91
|
+
file_path = os.path.join(
|
|
92
|
+
os.path.split(os.path.dirname(__file__))[0], "../jaclang/compiler/jac.lark"
|
|
93
|
+
)
|
|
94
|
+
result = extract_headings(file_path)
|
|
95
|
+
created_file_path = os.path.join(
|
|
96
|
+
os.path.split(os.path.dirname(__file__))[0],
|
|
97
|
+
"../support/jac-lang.org/docs/learn/jac_ref.md",
|
|
98
|
+
)
|
|
99
|
+
destination_folder = os.path.join(
|
|
100
|
+
os.path.split(os.path.dirname(__file__))[0], "../examples/reference/"
|
|
101
|
+
)
|
|
102
|
+
with open(created_file_path, "w") as md_file:
|
|
103
|
+
md_file.write(
|
|
104
|
+
'# Jac Language Reference\n\n--8<-- "examples/reference/introduction.md"\n\n'
|
|
105
|
+
)
|
|
106
|
+
for heading, lines in result.items():
|
|
107
|
+
heading = heading.strip()
|
|
108
|
+
heading_snakecase = heading_to_snake(heading)
|
|
109
|
+
content = (
|
|
110
|
+
f'## {heading}\n**Grammar Snippet**\n```yaml linenums="{lines[0]}"\n--8<-- '
|
|
111
|
+
f'"jaclang/compiler/jac.lark:{lines[0]}:{lines[1]}"\n```\n'
|
|
112
|
+
f'**Code Example**\n=== "Jac"\n ```jac linenums="1"\n --8<-- "examples/reference/'
|
|
113
|
+
f'{heading_snakecase}.jac"\n'
|
|
114
|
+
f' ```\n=== "Python"\n ```python linenums="1"\n --8<-- "examples/reference/'
|
|
115
|
+
f'{heading_snakecase}.py"\n ```\n'
|
|
116
|
+
"**Description**\n\n--8<-- "
|
|
117
|
+
f'"examples/reference/'
|
|
118
|
+
f'{heading_snakecase}.md"\n'
|
|
119
|
+
)
|
|
120
|
+
with open(created_file_path, "a") as md_file:
|
|
121
|
+
md_file.write(f"{content}\n")
|
|
122
|
+
md_file_name = f"{heading_snakecase}.md"
|
|
123
|
+
md_file_path = os.path.join(destination_folder, md_file_name)
|
|
124
|
+
if not os.path.exists(md_file_path):
|
|
125
|
+
with open(md_file_path, "w") as md_file:
|
|
126
|
+
md_file.write("")
|
|
127
|
+
|
|
128
|
+
|
|
88
129
|
def import_target_to_relative_path(
|
|
89
130
|
import_target: str, base_path: str | None = None, file_extension: str = ".jac"
|
|
90
131
|
) -> str:
|
|
@@ -104,3 +145,25 @@ def import_target_to_relative_path(
|
|
|
104
145
|
base_path = os.path.dirname(base_path)
|
|
105
146
|
relative_path = os.path.join(base_path, *actual_parts) + file_extension
|
|
106
147
|
return relative_path
|
|
148
|
+
|
|
149
|
+
|
|
150
|
+
class Jdb(pdb.Pdb):
|
|
151
|
+
"""Jac debugger."""
|
|
152
|
+
|
|
153
|
+
def __init__(self, *args, **kwargs) -> None: # noqa
|
|
154
|
+
"""Initialize the Jac debugger."""
|
|
155
|
+
super().__init__(*args, **kwargs)
|
|
156
|
+
self.prompt = "Jdb > "
|
|
157
|
+
|
|
158
|
+
def has_breakpoint(self, bytecode: bytes) -> bool:
|
|
159
|
+
"""Check for breakpoint."""
|
|
160
|
+
code = marshal.loads(bytecode)
|
|
161
|
+
instructions = dis.get_instructions(code)
|
|
162
|
+
return any(
|
|
163
|
+
instruction.opname in ("LOAD_GLOBAL", "LOAD_NAME", "LOAD_FAST")
|
|
164
|
+
and instruction.argval == "breakpoint"
|
|
165
|
+
for instruction in instructions
|
|
166
|
+
)
|
|
167
|
+
|
|
168
|
+
|
|
169
|
+
debugger = Jdb()
|
jaclang/utils/lang_tools.py
CHANGED
|
@@ -8,8 +8,9 @@ from typing import List, Optional, Type
|
|
|
8
8
|
|
|
9
9
|
import jaclang.compiler.absyntree as ast
|
|
10
10
|
from jaclang.compiler.compile import jac_file_to_pass
|
|
11
|
+
from jaclang.compiler.passes.main.schedules import py_code_gen_typed
|
|
11
12
|
from jaclang.compiler.symtable import SymbolTable
|
|
12
|
-
from jaclang.utils.helpers import
|
|
13
|
+
from jaclang.utils.helpers import auto_generate_refs, pascal_to_snake
|
|
13
14
|
|
|
14
15
|
|
|
15
16
|
class AstKidInfo:
|
|
@@ -209,7 +210,7 @@ class AstTool:
|
|
|
209
210
|
[base, mod] = os.path.split(file_name)
|
|
210
211
|
base = base if base else "./"
|
|
211
212
|
ir = jac_file_to_pass(
|
|
212
|
-
file_name
|
|
213
|
+
file_name, schedule=py_code_gen_typed
|
|
213
214
|
).ir # Assuming jac_file_to_pass is defined elsewhere
|
|
214
215
|
|
|
215
216
|
match output:
|
|
@@ -229,6 +230,8 @@ class AstTool:
|
|
|
229
230
|
return ir.pp()
|
|
230
231
|
case "ast.":
|
|
231
232
|
return ir.dotgen()
|
|
233
|
+
case "unparse":
|
|
234
|
+
return ir.unparse()
|
|
232
235
|
case "pyast":
|
|
233
236
|
return (
|
|
234
237
|
f"\n{py_ast.dump(ir.gen.py_ast[0], indent=2)}"
|
|
@@ -255,40 +258,5 @@ class AstTool:
|
|
|
255
258
|
|
|
256
259
|
def automate_ref(self) -> str:
|
|
257
260
|
"""Automate the reference guide generation."""
|
|
258
|
-
|
|
259
|
-
os.path.split(os.path.dirname(__file__))[0], "../jaclang/compiler/jac.lark"
|
|
260
|
-
)
|
|
261
|
-
result = extract_headings(file_path)
|
|
262
|
-
created_file_path = os.path.join(
|
|
263
|
-
os.path.split(os.path.dirname(__file__))[0],
|
|
264
|
-
"../support/jac-lang.org/docs/learn/jac_ref.md",
|
|
265
|
-
)
|
|
266
|
-
destination_folder = os.path.join(
|
|
267
|
-
os.path.split(os.path.dirname(__file__))[0], "../examples/reference/"
|
|
268
|
-
)
|
|
269
|
-
with open(created_file_path, "w") as md_file:
|
|
270
|
-
md_file.write(
|
|
271
|
-
'# Jac Language Reference\n\n--8<-- "examples/reference/introduction.md"\n\n'
|
|
272
|
-
)
|
|
273
|
-
for heading, lines in result.items():
|
|
274
|
-
heading = heading.strip()
|
|
275
|
-
heading_snakecase = heading_to_snake(heading)
|
|
276
|
-
content = (
|
|
277
|
-
f'## {heading}\n**Grammar Snippet**\n```yaml linenums="{lines[0]}"\n--8<-- '
|
|
278
|
-
f'"jaclang/compiler/jac.lark:{lines[0]}:{lines[1]}"\n```\n'
|
|
279
|
-
f'**Code Example**\n=== "Jac"\n ```jac linenums="1"\n --8<-- "examples/reference/'
|
|
280
|
-
f'{heading_snakecase}.jac"\n'
|
|
281
|
-
f' ```\n=== "Python"\n ```python linenums="1"\n --8<-- "examples/reference/'
|
|
282
|
-
f'{heading_snakecase}.py"\n ```\n'
|
|
283
|
-
"**Description**\n\n--8<-- "
|
|
284
|
-
f'"examples/reference/'
|
|
285
|
-
f'{heading_snakecase}.md"\n'
|
|
286
|
-
)
|
|
287
|
-
with open(created_file_path, "a") as md_file:
|
|
288
|
-
md_file.write(f"{content}\n")
|
|
289
|
-
md_file_name = f"{heading_snakecase}.md"
|
|
290
|
-
md_file_path = os.path.join(destination_folder, md_file_name)
|
|
291
|
-
if not os.path.exists(md_file_path):
|
|
292
|
-
with open(md_file_path, "w") as md_file:
|
|
293
|
-
md_file.write("")
|
|
261
|
+
auto_generate_refs()
|
|
294
262
|
return "References generated."
|
jaclang/utils/test.py
CHANGED
|
@@ -37,20 +37,14 @@ class JacFormatPassTests(TestCase):
|
|
|
37
37
|
|
|
38
38
|
def test_print(self) -> None:
|
|
39
39
|
"""Testing for print AstTool."""
|
|
40
|
-
|
|
41
|
-
os.path.dirname(jaclang.__file__),
|
|
40
|
+
jac_file = os.path.join(
|
|
41
|
+
os.path.dirname(jaclang.__file__),
|
|
42
|
+
"../examples/reference/names_and_references.jac",
|
|
42
43
|
)
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
out = AstTool().ir(["ast", jac_directory + jac_file])
|
|
48
|
-
if out == "0:0 - 0:0\tModule\n0:0 - 0:0\t+-- EmptyToken - \n":
|
|
49
|
-
continue
|
|
50
|
-
self.assertIn("+-- Token", out, msg)
|
|
51
|
-
self.assertIsNotNone(out, msg=msg)
|
|
52
|
-
passed += 1
|
|
53
|
-
self.assertGreater(passed, 10)
|
|
44
|
+
msg = "error in " + jac_file
|
|
45
|
+
out = AstTool().ir(["ast", jac_file])
|
|
46
|
+
self.assertIn("+-- Token", out, msg)
|
|
47
|
+
self.assertIsNotNone(out, msg=msg)
|
|
54
48
|
|
|
55
49
|
def test_print_py(self) -> None:
|
|
56
50
|
"""Testing for print_py AstTool."""
|
|
@@ -58,8 +52,11 @@ class JacFormatPassTests(TestCase):
|
|
|
58
52
|
os.path.dirname(jaclang.__file__), "../examples/reference/"
|
|
59
53
|
)
|
|
60
54
|
jac_py_files = [
|
|
61
|
-
f
|
|
55
|
+
f
|
|
56
|
+
for f in os.listdir(jac_py_directory)
|
|
57
|
+
if f.endswith(("names_and_references.jac", "names_and_references.py"))
|
|
62
58
|
]
|
|
59
|
+
|
|
63
60
|
for file in jac_py_files:
|
|
64
61
|
msg = "error in " + file
|
|
65
62
|
out = AstTool().ir(["pyast", jac_py_directory + file])
|
jaclang/utils/treeprinter.py
CHANGED
|
@@ -88,10 +88,14 @@ def print_ast_tree(
|
|
|
88
88
|
from jaclang.compiler.absyntree import AstSymbolNode, Token
|
|
89
89
|
|
|
90
90
|
def __node_repr_in_tree(node: AstNode) -> str:
|
|
91
|
-
if isinstance(node, Token):
|
|
91
|
+
if isinstance(node, Token) and isinstance(node, AstSymbolNode):
|
|
92
|
+
return (
|
|
93
|
+
f"{node.__class__.__name__} - {node.value} - Type: {node.sym_info.typ}"
|
|
94
|
+
)
|
|
95
|
+
elif isinstance(node, Token):
|
|
92
96
|
return f"{node.__class__.__name__} - {node.value}"
|
|
93
97
|
elif isinstance(node, AstSymbolNode):
|
|
94
|
-
return f"{node.__class__.__name__} - {node.sym_name}"
|
|
98
|
+
return f"{node.__class__.__name__} - {node.sym_name} - Type: {node.sym_info.typ}"
|
|
95
99
|
else:
|
|
96
100
|
return f"{node.__class__.__name__}"
|
|
97
101
|
|
|
@@ -211,6 +215,10 @@ def _build_symbol_tree_common(
|
|
|
211
215
|
symbol_node = SymbolTree(node_name=f"{sym.sym_name}", parent=symbols)
|
|
212
216
|
SymbolTree(node_name=f"{sym.access} {sym.sym_type}", parent=symbol_node)
|
|
213
217
|
|
|
218
|
+
# if isinstance(node.owner, ast.AstSymbolNode) and node.owner.sym_info:
|
|
219
|
+
# print("From tree printer", id(node.owner))
|
|
220
|
+
# SymbolTree(node_name=f"Datatype: {node.owner.sym_info.typ}", parent=symbol_node)
|
|
221
|
+
|
|
214
222
|
if sym.decl and sym.decl.loc.first_line > 0:
|
|
215
223
|
SymbolTree(
|
|
216
224
|
node_name=f"decl: line {sym.decl.loc.first_line}, col {sym.decl.loc.col_start}",
|