jaclang 0.8.4__py3-none-any.whl → 0.8.5__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 +74 -22
- jaclang/compiler/jac.lark +3 -3
- jaclang/compiler/larkparse/jac_parser.py +2 -2
- jaclang/compiler/parser.py +14 -21
- jaclang/compiler/passes/main/__init__.py +3 -1
- jaclang/compiler/passes/main/binder_pass.py +594 -0
- jaclang/compiler/passes/main/import_pass.py +8 -256
- jaclang/compiler/passes/main/inheritance_pass.py +2 -2
- jaclang/compiler/passes/main/pyast_gen_pass.py +35 -69
- jaclang/compiler/passes/main/pyast_load_pass.py +24 -13
- jaclang/compiler/passes/main/sem_def_match_pass.py +1 -1
- jaclang/compiler/passes/main/tests/fixtures/M1.jac +3 -0
- jaclang/compiler/passes/main/tests/fixtures/sym_binder.jac +47 -0
- jaclang/compiler/passes/main/tests/test_binder_pass.py +111 -0
- jaclang/compiler/passes/main/tests/test_pyast_gen_pass.py +13 -13
- jaclang/compiler/passes/main/tests/test_sem_def_match_pass.py +6 -6
- jaclang/compiler/passes/tool/doc_ir_gen_pass.py +2 -0
- jaclang/compiler/passes/tool/tests/fixtures/simple_walk_fmt.jac +6 -0
- jaclang/compiler/program.py +15 -8
- jaclang/compiler/tests/test_sr_errors.py +32 -0
- jaclang/compiler/unitree.py +21 -15
- jaclang/langserve/engine.jac +23 -4
- jaclang/langserve/tests/test_server.py +13 -0
- jaclang/runtimelib/importer.py +33 -62
- jaclang/runtimelib/utils.py +29 -0
- jaclang/tests/fixtures/pyfunc_fmt.py +60 -0
- jaclang/tests/fixtures/pyfunc_fstr.py +25 -0
- jaclang/tests/fixtures/pyfunc_kwesc.py +33 -0
- jaclang/tests/fixtures/python_run_test.py +19 -0
- jaclang/tests/test_cli.py +67 -0
- jaclang/tests/test_language.py +96 -1
- jaclang/utils/lang_tools.py +3 -3
- jaclang/utils/module_resolver.py +90 -0
- jaclang/utils/symtable_test_helpers.py +125 -0
- jaclang/utils/test.py +3 -4
- jaclang/vendor/interegular/__init__.py +34 -0
- jaclang/vendor/interegular/comparator.py +163 -0
- jaclang/vendor/interegular/fsm.py +1015 -0
- jaclang/vendor/interegular/patterns.py +732 -0
- jaclang/vendor/interegular/py.typed +0 -0
- jaclang/vendor/interegular/utils/__init__.py +15 -0
- jaclang/vendor/interegular/utils/simple_parser.py +165 -0
- jaclang/vendor/interegular-0.3.3.dist-info/INSTALLER +1 -0
- jaclang/vendor/interegular-0.3.3.dist-info/LICENSE.txt +21 -0
- jaclang/vendor/interegular-0.3.3.dist-info/METADATA +64 -0
- jaclang/vendor/interegular-0.3.3.dist-info/RECORD +20 -0
- jaclang/vendor/interegular-0.3.3.dist-info/REQUESTED +0 -0
- jaclang/vendor/interegular-0.3.3.dist-info/WHEEL +5 -0
- jaclang/vendor/interegular-0.3.3.dist-info/top_level.txt +1 -0
- {jaclang-0.8.4.dist-info → jaclang-0.8.5.dist-info}/METADATA +1 -1
- {jaclang-0.8.4.dist-info → jaclang-0.8.5.dist-info}/RECORD +53 -29
- {jaclang-0.8.4.dist-info → jaclang-0.8.5.dist-info}/WHEEL +0 -0
- {jaclang-0.8.4.dist-info → jaclang-0.8.5.dist-info}/entry_points.txt +0 -0
jaclang/cli/cli.py
CHANGED
|
@@ -21,6 +21,7 @@ from jaclang.runtimelib.machine import (
|
|
|
21
21
|
JacMachine as Jac,
|
|
22
22
|
JacMachineInterface as JacInterface,
|
|
23
23
|
)
|
|
24
|
+
from jaclang.runtimelib.utils import read_file_with_encoding
|
|
24
25
|
from jaclang.utils.helpers import debugger as db
|
|
25
26
|
from jaclang.utils.lang_tools import AstTool
|
|
26
27
|
|
|
@@ -98,7 +99,15 @@ def proc_file_sess(
|
|
|
98
99
|
)
|
|
99
100
|
base, mod = os.path.split(filename)
|
|
100
101
|
base = base if base else "./"
|
|
101
|
-
|
|
102
|
+
if filename.endswith(".jac") or filename.endswith(".jir"):
|
|
103
|
+
mod = mod[:-4]
|
|
104
|
+
elif filename.endswith(".py"):
|
|
105
|
+
mod = mod[:-3]
|
|
106
|
+
else:
|
|
107
|
+
print(
|
|
108
|
+
"Not a valid file!\nOnly supports `.jac`, `.jir`, and `.py`",
|
|
109
|
+
file=sys.stderr,
|
|
110
|
+
)
|
|
102
111
|
mach = ExecutionContext(session=session, root=root)
|
|
103
112
|
Jac.set_context(mach)
|
|
104
113
|
return base, mod, mach
|
|
@@ -111,19 +120,20 @@ def run(
|
|
|
111
120
|
main: bool = True,
|
|
112
121
|
cache: bool = True,
|
|
113
122
|
) -> None:
|
|
114
|
-
"""Run the specified .jac file.
|
|
123
|
+
"""Run the specified .jac, .jir, or .py file.
|
|
115
124
|
|
|
116
|
-
Executes a Jac program file, loading it into the Jac runtime environment
|
|
117
|
-
and running its code.
|
|
125
|
+
Executes a Jac program file or Python file, loading it into the Jac runtime environment
|
|
126
|
+
and running its code. Python files are converted to Jac AST for execution.
|
|
118
127
|
|
|
119
128
|
Args:
|
|
120
|
-
filename: Path to the .jac or .
|
|
129
|
+
filename: Path to the .jac, .jir, or .py file to run
|
|
121
130
|
session: Optional session identifier for persistent state
|
|
122
131
|
main: Treat the module as __main__ (default: True)
|
|
123
132
|
cache: Use cached compilation if available (default: True)
|
|
124
133
|
|
|
125
134
|
Examples:
|
|
126
135
|
jac run myprogram.jac
|
|
136
|
+
jac run myscript.py
|
|
127
137
|
jac run myprogram.jac --session mysession
|
|
128
138
|
jac run myprogram.jac --no-main
|
|
129
139
|
"""
|
|
@@ -132,7 +142,7 @@ def run(
|
|
|
132
142
|
base, mod, mach = proc_file_sess(filename, session)
|
|
133
143
|
Jac.set_base_path(base)
|
|
134
144
|
|
|
135
|
-
if filename.endswith(".jac"):
|
|
145
|
+
if filename.endswith((".jac", ".py")):
|
|
136
146
|
try:
|
|
137
147
|
Jac.jac_import(
|
|
138
148
|
target=mod,
|
|
@@ -140,7 +150,7 @@ def run(
|
|
|
140
150
|
override_name="__main__" if main else None,
|
|
141
151
|
)
|
|
142
152
|
except Exception as e:
|
|
143
|
-
print(e, file=sys.stderr)
|
|
153
|
+
print(f"Error running {filename}: {e}", file=sys.stderr)
|
|
144
154
|
elif filename.endswith(".jir"):
|
|
145
155
|
try:
|
|
146
156
|
with open(filename, "rb") as f:
|
|
@@ -151,10 +161,13 @@ def run(
|
|
|
151
161
|
override_name="__main__" if main else None,
|
|
152
162
|
)
|
|
153
163
|
except Exception as e:
|
|
154
|
-
print(e, file=sys.stderr)
|
|
155
|
-
|
|
164
|
+
print(f"Error running {filename}: {e}", file=sys.stderr)
|
|
156
165
|
else:
|
|
157
|
-
print(
|
|
166
|
+
print(
|
|
167
|
+
"Not a valid file!\nOnly supports `.jac`, `.jir`, and `.py`",
|
|
168
|
+
file=sys.stderr,
|
|
169
|
+
)
|
|
170
|
+
|
|
158
171
|
mach.close()
|
|
159
172
|
|
|
160
173
|
|
|
@@ -231,6 +244,41 @@ def build(filename: str) -> None:
|
|
|
231
244
|
print("Not a .jac file.", file=sys.stderr)
|
|
232
245
|
|
|
233
246
|
|
|
247
|
+
@cmd_registry.register
|
|
248
|
+
def bind(filename: str, typecheck: bool = False) -> None:
|
|
249
|
+
"""Bind the specified .jac file.
|
|
250
|
+
|
|
251
|
+
Parses and binds a Jac source file, resolving symbols and preparing it for execution.
|
|
252
|
+
This step is necessary before running the program, as it ensures all references
|
|
253
|
+
are correctly linked and the program structure is validated.
|
|
254
|
+
TODO: performs type checking.
|
|
255
|
+
|
|
256
|
+
Args:
|
|
257
|
+
filename: Path to the .jac file to bind
|
|
258
|
+
typecheck: Print the symbol table after binding (default: False)
|
|
259
|
+
|
|
260
|
+
Examples:
|
|
261
|
+
jac bind myprogram.jac
|
|
262
|
+
jac bind myprogram.jac -t
|
|
263
|
+
"""
|
|
264
|
+
if filename.endswith((".jac", ".py")):
|
|
265
|
+
(out := JacProgram()).bind(file_path=filename)
|
|
266
|
+
errs = len(out.errors_had)
|
|
267
|
+
warnings = len(out.warnings_had)
|
|
268
|
+
if typecheck:
|
|
269
|
+
for mods in out.mod.hub.values():
|
|
270
|
+
if mods.name == "builtins":
|
|
271
|
+
continue
|
|
272
|
+
header = (
|
|
273
|
+
f"{'=' * 6} SymTable({mods.name}) {'=' * (22 - len(mods.name))}"
|
|
274
|
+
)
|
|
275
|
+
divider = "=" * 40
|
|
276
|
+
print(f"{divider}\n{header}\n{divider}\n{mods.sym_tab.sym_pp()}")
|
|
277
|
+
print(f"Errors: {errs}, Warnings: {warnings}")
|
|
278
|
+
else:
|
|
279
|
+
print("Not a .jac/.py file.", file=sys.stderr)
|
|
280
|
+
|
|
281
|
+
|
|
234
282
|
@cmd_registry.register
|
|
235
283
|
def check(filename: str, print_errs: bool = True) -> None:
|
|
236
284
|
"""Run type checker for a specified .jac file.
|
|
@@ -546,16 +594,21 @@ def py2jac(filename: str) -> None:
|
|
|
546
594
|
jac py2jac myscript.py > converted.jac
|
|
547
595
|
"""
|
|
548
596
|
if filename.endswith(".py"):
|
|
549
|
-
|
|
550
|
-
|
|
551
|
-
|
|
552
|
-
|
|
553
|
-
|
|
554
|
-
|
|
555
|
-
|
|
556
|
-
|
|
557
|
-
|
|
558
|
-
|
|
597
|
+
file_source = read_file_with_encoding(filename)
|
|
598
|
+
code = PyastBuildPass(
|
|
599
|
+
ir_in=uni.PythonModuleAst(
|
|
600
|
+
ast3.parse(file_source),
|
|
601
|
+
orig_src=uni.Source(file_source, filename),
|
|
602
|
+
),
|
|
603
|
+
prog=JacProgram(),
|
|
604
|
+
).ir_out.unparse(requires_format=False)
|
|
605
|
+
formatted_code = JacProgram().jac_str_formatter(
|
|
606
|
+
source_str=code, file_path=filename
|
|
607
|
+
)
|
|
608
|
+
if formatted_code:
|
|
609
|
+
print(formatted_code)
|
|
610
|
+
else:
|
|
611
|
+
print("Error converting Python code to Jac.", file=sys.stderr)
|
|
559
612
|
else:
|
|
560
613
|
print("Not a .py file.")
|
|
561
614
|
|
|
@@ -575,8 +628,7 @@ def jac2py(filename: str) -> None:
|
|
|
575
628
|
jac jac2py myprogram.jac > converted.py
|
|
576
629
|
"""
|
|
577
630
|
if filename.endswith(".jac"):
|
|
578
|
-
|
|
579
|
-
code = JacProgram().compile(file_path=filename).gen.py
|
|
631
|
+
code = JacProgram().compile(file_path=filename).gen.py
|
|
580
632
|
print(code)
|
|
581
633
|
else:
|
|
582
634
|
print("Not a .jac file.", file=sys.stderr)
|
jaclang/compiler/jac.lark
CHANGED
|
@@ -62,7 +62,7 @@ ability: decorators? KW_ASYNC? (ability_decl | function_decl)
|
|
|
62
62
|
|
|
63
63
|
function_decl: KW_OVERRIDE? KW_STATIC? KW_DEF access_tag? named_ref func_decl? (block_tail | KW_ABSTRACT? SEMI)
|
|
64
64
|
ability_decl: KW_OVERRIDE? KW_STATIC? KW_CAN access_tag? named_ref event_clause (block_tail | KW_ABSTRACT? SEMI)
|
|
65
|
-
block_tail: code_block | KW_BY
|
|
65
|
+
block_tail: code_block | KW_BY expression SEMI
|
|
66
66
|
event_clause: KW_WITH expression? (KW_EXIT | KW_ENTRY)
|
|
67
67
|
|
|
68
68
|
func_decl: (LPAREN func_decl_params? RPAREN) (RETURN_HINT expression)?
|
|
@@ -331,9 +331,9 @@ index_slice: LSQUARE
|
|
|
331
331
|
| list_val
|
|
332
332
|
|
|
333
333
|
// [Heading]: Function calls.
|
|
334
|
-
atomic_call: atomic_chain LPAREN param_list?
|
|
334
|
+
atomic_call: atomic_chain LPAREN param_list? by_llm? RPAREN
|
|
335
335
|
|
|
336
|
-
|
|
336
|
+
by_llm: KW_BY expression
|
|
337
337
|
|
|
338
338
|
param_list: expr_list COMMA kw_expr_list COMMA?
|
|
339
339
|
| kw_expr_list COMMA?
|