jaclang 0.0.5__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/cli.jac +2 -2
- jaclang/cli/cmds.jac +8 -2
- 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/cli_impl.jac +25 -8
- jaclang/cli/impl/cmds_impl.jac +35 -6
- 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 +3 -3
- jaclang/core/impl/exec_ctx_impl.jac +3 -6
- jaclang/core/primitives.jac +4 -3
- jaclang/jac/absyntree.py +555 -180
- jaclang/jac/constant.py +6 -0
- jaclang/jac/importer.py +34 -56
- jaclang/jac/langserve.py +26 -0
- jaclang/jac/lexer.py +35 -3
- jaclang/jac/parser.py +146 -115
- jaclang/jac/passes/blue/__init__.py +8 -3
- jaclang/jac/passes/blue/ast_build_pass.py +454 -305
- jaclang/jac/passes/blue/blue_pygen_pass.py +112 -74
- jaclang/jac/passes/blue/decl_def_match_pass.py +49 -277
- jaclang/jac/passes/blue/import_pass.py +1 -1
- jaclang/jac/passes/blue/pyout_pass.py +74 -0
- jaclang/jac/passes/blue/semantic_check_pass.py +37 -0
- jaclang/jac/passes/blue/sym_tab_build_pass.py +1045 -0
- jaclang/jac/passes/blue/tests/test_ast_build_pass.py +2 -2
- jaclang/jac/passes/blue/tests/test_blue_pygen_pass.py +9 -28
- jaclang/jac/passes/blue/tests/test_decl_def_match_pass.py +13 -22
- jaclang/jac/passes/blue/tests/test_sym_tab_build_pass.py +22 -0
- jaclang/jac/passes/ir_pass.py +8 -6
- 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/passes/purple/impl/purple_pygen_pass_impl.jac +2 -5
- jaclang/jac/symtable.py +154 -0
- 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/tests/fixtures/mod_doc_test.jac +1 -0
- jaclang/jac/tests/test_parser.py +8 -0
- jaclang/jac/transform.py +41 -14
- jaclang/jac/transpiler.py +18 -9
- jaclang/utils/fstring_parser.py +2 -2
- jaclang/utils/helpers.py +41 -0
- jaclang/utils/lang_tools.py +12 -2
- jaclang/utils/test.py +41 -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.5.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/jac/passes/blue/tests/test_type_analyze_pass.py +0 -53
- jaclang/jac/passes/blue/type_analyze_pass.py +0 -728
- jaclang/jac/sym_table.py +0 -127
- jaclang-0.0.5.dist-info/RECORD +0 -73
- /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.5.dist-info → jaclang-0.0.8.dist-info}/WHEEL +0 -0
- {jaclang-0.0.5.dist-info → jaclang-0.0.8.dist-info}/entry_points.txt +0 -0
- {jaclang-0.0.5.dist-info → jaclang-0.0.8.dist-info}/top_level.txt +0 -0
|
@@ -84,8 +84,8 @@ class BluePygenPass(Pass):
|
|
|
84
84
|
# self.emit_ln(node, "print(__jac_tmp__)\nraise e")
|
|
85
85
|
self.emit_ln(
|
|
86
86
|
node,
|
|
87
|
-
"e =
|
|
88
|
-
"if '
|
|
87
|
+
"e.args = (f'{e.args[0]}\\n' + __jac_tmp__,) + e.args[1:] "
|
|
88
|
+
f"if '{Con.JAC_ERROR_PREAMBLE}' not in str(e) else e.args",
|
|
89
89
|
)
|
|
90
90
|
self.emit_ln(node, "raise e")
|
|
91
91
|
self.indent_level -= 1
|
|
@@ -179,26 +179,57 @@ class BluePygenPass(Pass):
|
|
|
179
179
|
self.emit_ln(node, node.doc.value)
|
|
180
180
|
self.emit(node, node.assignments.meta["py_code"])
|
|
181
181
|
|
|
182
|
-
# NOTE: Incomplete for Jac Purple and Red
|
|
183
182
|
def exit_test(self, node: ast.Test) -> None:
|
|
184
183
|
"""Sub objects.
|
|
185
184
|
|
|
186
|
-
name:
|
|
187
|
-
doc: Optional[
|
|
188
|
-
|
|
189
|
-
body: "CodeBlock",
|
|
185
|
+
name: Optional[Name],
|
|
186
|
+
doc: Optional[Token],
|
|
187
|
+
body: CodeBlock,
|
|
190
188
|
"""
|
|
191
|
-
|
|
189
|
+
test_name = node.name.value
|
|
190
|
+
test_code = "import unittest as __jac_unittest__\n"
|
|
191
|
+
test_code += "__jac_tc__ = __jac_unittest__.TestCase()\n"
|
|
192
|
+
test_code += "__jac_suite__ = __jac_unittest__.TestSuite()\n"
|
|
193
|
+
test_code += "class __jac_check:\n"
|
|
194
|
+
test_code += " def __getattr__(self, name):\n"
|
|
195
|
+
test_code += " return getattr(__jac_tc__, 'assert'+name)"
|
|
196
|
+
self.emit_ln_unique(self.preamble, test_code)
|
|
197
|
+
self.emit_ln(node, f"def test_{test_name}():")
|
|
198
|
+
self.indent_level += 1
|
|
199
|
+
if node.doc:
|
|
200
|
+
self.emit_ln(node, node.doc.value)
|
|
201
|
+
self.emit_ln(node, "check = __jac_check()")
|
|
202
|
+
self.emit_ln(node, node.body.meta["py_code"])
|
|
203
|
+
self.indent_level -= 1
|
|
204
|
+
self.emit_ln(
|
|
205
|
+
node,
|
|
206
|
+
f"__jac_suite__.addTest(__jac_unittest__.FunctionTestCase(test_{test_name}))",
|
|
207
|
+
)
|
|
192
208
|
|
|
193
209
|
def exit_module_code(self, node: ast.ModuleCode) -> None:
|
|
194
210
|
"""Sub objects.
|
|
195
211
|
|
|
196
|
-
doc: Optional[
|
|
197
|
-
|
|
212
|
+
doc: Optional[Token],
|
|
213
|
+
name: Optional[Name],
|
|
214
|
+
body: CodeBlock,
|
|
215
|
+
|
|
198
216
|
"""
|
|
199
217
|
if node.doc:
|
|
200
218
|
self.emit_ln(node, node.doc.value)
|
|
201
|
-
|
|
219
|
+
if node.name:
|
|
220
|
+
self.emit_ln(node, f"if __name__ == '{node.name.meta['py_code']}':")
|
|
221
|
+
self.indent_level += 1
|
|
222
|
+
self.emit(node, node.body.meta["py_code"])
|
|
223
|
+
self.indent_level -= 1
|
|
224
|
+
else:
|
|
225
|
+
self.emit(node, node.body.meta["py_code"])
|
|
226
|
+
|
|
227
|
+
def exit_py_inline_code(self, node: ast.PyInlineCode) -> None:
|
|
228
|
+
"""Sub objects.
|
|
229
|
+
|
|
230
|
+
code: Token,
|
|
231
|
+
"""
|
|
232
|
+
self.emit_ln(node, node.code.value)
|
|
202
233
|
|
|
203
234
|
def exit_import(self, node: ast.Import) -> None:
|
|
204
235
|
"""Sub objects.
|
|
@@ -225,6 +256,7 @@ class BluePygenPass(Pass):
|
|
|
225
256
|
self.warning(
|
|
226
257
|
"Includes import * in target module into current namespace."
|
|
227
258
|
)
|
|
259
|
+
return
|
|
228
260
|
if not node.items:
|
|
229
261
|
if not node.alias:
|
|
230
262
|
self.emit_ln(node, f"import {node.path.meta['py_code']}")
|
|
@@ -290,8 +322,6 @@ class BluePygenPass(Pass):
|
|
|
290
322
|
self.emit_ln(node, node.doc.value)
|
|
291
323
|
if node.body:
|
|
292
324
|
self.emit(node, node.body.meta["py_code"])
|
|
293
|
-
else:
|
|
294
|
-
self.decl_def_missing(node.name.meta["py_code"])
|
|
295
325
|
self.indent_level -= 1
|
|
296
326
|
|
|
297
327
|
def exit_arch_def(self, node: ast.ArchDef) -> None:
|
|
@@ -322,15 +352,16 @@ class BluePygenPass(Pass):
|
|
|
322
352
|
def exit_ability(self, node: ast.Ability) -> None:
|
|
323
353
|
"""Sub objects.
|
|
324
354
|
|
|
325
|
-
|
|
355
|
+
name_ref: Name | SpecialVarRef | ArchRef,
|
|
326
356
|
is_func: bool,
|
|
327
357
|
is_async: bool,
|
|
328
358
|
is_static: bool,
|
|
359
|
+
is_abstract: bool,
|
|
329
360
|
doc: Optional[Token],
|
|
330
|
-
decorators: Optional[
|
|
361
|
+
decorators: Optional[Decorators],
|
|
331
362
|
access: Optional[Token],
|
|
332
|
-
signature: Optional[
|
|
333
|
-
body: Optional[
|
|
363
|
+
signature: Optional[FuncSignature | TypeSpec | EventSignature],
|
|
364
|
+
body: Optional[CodeBlock],
|
|
334
365
|
arch_attached: Optional["ArchBlock"] = None,
|
|
335
366
|
"""
|
|
336
367
|
ability_name = node.py_resolve_name()
|
|
@@ -339,9 +370,15 @@ class BluePygenPass(Pass):
|
|
|
339
370
|
if node.decorators:
|
|
340
371
|
self.emit(node, node.decorators.meta["py_code"])
|
|
341
372
|
if isinstance(node.signature, (ast.FuncSignature, ast.EventSignature)):
|
|
373
|
+
if "->" in node.signature.meta["py_code"]:
|
|
374
|
+
node.signature.meta["py_code"] = node.signature.meta["py_code"].replace(
|
|
375
|
+
" ->", ") ->"
|
|
376
|
+
)
|
|
377
|
+
else:
|
|
378
|
+
node.signature.meta["py_code"] += ")"
|
|
342
379
|
if node.arch_attached and not node.is_static:
|
|
343
380
|
self.emit_ln(
|
|
344
|
-
node, f"def {ability_name}(self{node.signature.meta['py_code']}:"
|
|
381
|
+
node, f"def {ability_name}(self,{node.signature.meta['py_code']}:"
|
|
345
382
|
)
|
|
346
383
|
else:
|
|
347
384
|
if node.arch_attached and node.is_static:
|
|
@@ -363,8 +400,8 @@ class BluePygenPass(Pass):
|
|
|
363
400
|
self.emit(node, node.body.meta["py_code"])
|
|
364
401
|
self.indent_level -= 1
|
|
365
402
|
self.emit_jac_error_handler(node)
|
|
366
|
-
|
|
367
|
-
self.
|
|
403
|
+
elif node.is_abstract:
|
|
404
|
+
self.emit_ln(node, "pass")
|
|
368
405
|
self.indent_level -= 1
|
|
369
406
|
|
|
370
407
|
def exit_ability_def(self, node: ast.AbilityDef) -> None:
|
|
@@ -381,40 +418,55 @@ class BluePygenPass(Pass):
|
|
|
381
418
|
|
|
382
419
|
members: list["ArchHas | Ability"],
|
|
383
420
|
"""
|
|
384
|
-
has_members = [
|
|
385
|
-
i for i in node.members if isinstance(i, ast.ArchHas) and not i.is_static
|
|
386
|
-
]
|
|
387
|
-
if has_members:
|
|
388
|
-
self.emit_ln(node, "def __jac_has(self):")
|
|
389
|
-
self.indent_level += 1
|
|
390
|
-
for i in has_members:
|
|
391
|
-
self.emit_ln(node, f"self._jac_has_{i.h_id}()")
|
|
392
|
-
self.indent_level -= 1
|
|
393
|
-
|
|
394
421
|
init_func = None
|
|
395
422
|
for i in node.members:
|
|
396
423
|
if isinstance(i, ast.Ability) and i.py_resolve_name() == "__init__":
|
|
397
424
|
init_func = i
|
|
398
425
|
break
|
|
399
|
-
|
|
400
|
-
if
|
|
401
|
-
|
|
402
|
-
|
|
403
|
-
|
|
404
|
-
)
|
|
405
|
-
|
|
406
|
-
|
|
426
|
+
static_has_members = [
|
|
427
|
+
i for i in node.members if isinstance(i, ast.ArchHas) and i.is_static
|
|
428
|
+
]
|
|
429
|
+
for i in static_has_members:
|
|
430
|
+
self.emit(node, i.meta["py_code"])
|
|
431
|
+
self.emit(node, "\n")
|
|
432
|
+
|
|
433
|
+
if init_func and init_func.decorators:
|
|
434
|
+
self.emit(node, init_func.decorators.meta["py_code"])
|
|
435
|
+
self.emit_ln(node, "def __init__(self,")
|
|
407
436
|
self.indent_level += 1
|
|
437
|
+
if has_members := [
|
|
438
|
+
i for i in node.members if isinstance(i, ast.ArchHas) and not i.is_static
|
|
439
|
+
]:
|
|
440
|
+
for i in has_members:
|
|
441
|
+
for j in i.vars.vars:
|
|
442
|
+
self.emit_ln(node, f"{j.name.value} = None,")
|
|
443
|
+
if init_func and init_func.signature:
|
|
444
|
+
if "->" in init_func.signature.meta["py_code"]:
|
|
445
|
+
init_func.signature.meta["py_code"] = init_func.signature.meta[
|
|
446
|
+
"py_code"
|
|
447
|
+
].split("->")[0]
|
|
448
|
+
if len(init_func.signature.meta["py_code"]):
|
|
449
|
+
self.emit_ln(node, f"{init_func.signature.meta['py_code']},")
|
|
450
|
+
self.emit_ln(node, " *args, **kwargs):")
|
|
408
451
|
if not init_func:
|
|
409
452
|
self.emit_ln(node, "super().__init__(*args, **kwargs)")
|
|
410
|
-
|
|
411
|
-
|
|
453
|
+
for i in has_members:
|
|
454
|
+
for j in i.vars.vars:
|
|
455
|
+
if j.value:
|
|
456
|
+
self.emit_ln(
|
|
457
|
+
node,
|
|
458
|
+
f"self.{j.name.value} = {j.value.meta['py_code']} if {j.name.value} is "
|
|
459
|
+
f"None else {j.name.value}",
|
|
460
|
+
)
|
|
461
|
+
else:
|
|
462
|
+
self.emit_ln(node, f"self.{j.name.value} = {j.name.value}")
|
|
412
463
|
if init_func and init_func.body:
|
|
413
464
|
self.emit(node, f"{init_func.body.meta['py_code']}")
|
|
414
465
|
self.indent_level -= 1
|
|
415
466
|
for i in node.members:
|
|
416
|
-
|
|
417
|
-
|
|
467
|
+
if i not in has_members + static_has_members:
|
|
468
|
+
self.emit(node, i.meta["py_code"])
|
|
469
|
+
self.emit(node, "\n")
|
|
418
470
|
|
|
419
471
|
def exit_arch_has(self, node: ast.ArchHas) -> None:
|
|
420
472
|
"""Sub objects.
|
|
@@ -425,17 +477,7 @@ class BluePygenPass(Pass):
|
|
|
425
477
|
vars: "HasVarList",
|
|
426
478
|
is_frozen: bool,
|
|
427
479
|
"""
|
|
428
|
-
|
|
429
|
-
if node.doc:
|
|
430
|
-
self.emit_ln(node, node.doc.value)
|
|
431
|
-
self.emit_ln(node, node.vars.meta["py_code"].replace("self.", ""))
|
|
432
|
-
else:
|
|
433
|
-
self.emit_ln(node, f"def _jac_has_{node.h_id}(self):")
|
|
434
|
-
self.indent_level += 1
|
|
435
|
-
if node.doc:
|
|
436
|
-
self.emit_ln(node, node.doc.value)
|
|
437
|
-
self.emit(node, node.vars.meta["py_code"])
|
|
438
|
-
self.indent_level -= 1
|
|
480
|
+
self.emit(node, node.vars.meta["py_code"])
|
|
439
481
|
|
|
440
482
|
def exit_has_var_list(self, node: ast.HasVarList) -> None:
|
|
441
483
|
"""Sub objects.
|
|
@@ -455,11 +497,11 @@ class BluePygenPass(Pass):
|
|
|
455
497
|
if node.value:
|
|
456
498
|
self.emit(
|
|
457
499
|
node,
|
|
458
|
-
f"
|
|
500
|
+
f"{node.name.value}: {node.type_tag.meta['py_code']} = {node.value.meta['py_code']}",
|
|
459
501
|
)
|
|
460
502
|
else:
|
|
461
503
|
self.emit(
|
|
462
|
-
node, f"
|
|
504
|
+
node, f"{node.name.value}: {node.type_tag.meta['py_code']} = None"
|
|
463
505
|
)
|
|
464
506
|
|
|
465
507
|
def exit_type_spec_list(self, node: ast.TypeSpecList) -> None:
|
|
@@ -503,6 +545,13 @@ class BluePygenPass(Pass):
|
|
|
503
545
|
"""
|
|
504
546
|
self.emit(node, ".".join([i.meta["py_code"] for i in node.names]))
|
|
505
547
|
|
|
548
|
+
def exit_arch_ref_chain(self, node: ast.ArchRefChain) -> None:
|
|
549
|
+
"""Sub objects.
|
|
550
|
+
|
|
551
|
+
archs: list[ArchRef],
|
|
552
|
+
"""
|
|
553
|
+
self.emit(node, ".".join([i.meta["py_code"] for i in node.archs]))
|
|
554
|
+
|
|
506
555
|
def exit_func_signature(self, node: ast.FuncSignature) -> None:
|
|
507
556
|
"""Sub objects.
|
|
508
557
|
|
|
@@ -511,20 +560,7 @@ class BluePygenPass(Pass):
|
|
|
511
560
|
self.is_arch_attached = False
|
|
512
561
|
"""
|
|
513
562
|
if node.params:
|
|
514
|
-
if (
|
|
515
|
-
isinstance(node.parent, ast.Ability)
|
|
516
|
-
and node.parent.arch_attached
|
|
517
|
-
and not node.parent.is_static
|
|
518
|
-
):
|
|
519
|
-
self.emit(node, ", ")
|
|
520
563
|
self.emit(node, node.params.meta["py_code"])
|
|
521
|
-
if (
|
|
522
|
-
isinstance(node.parent, ast.Ability)
|
|
523
|
-
and node.parent.arch_attached
|
|
524
|
-
and node.parent.py_resolve_name() == "__init__"
|
|
525
|
-
):
|
|
526
|
-
self.emit(node, ", *args, **kwargs")
|
|
527
|
-
self.emit(node, ")")
|
|
528
564
|
if node.return_type:
|
|
529
565
|
self.emit(node, f" -> {node.return_type.meta['py_code']}")
|
|
530
566
|
|
|
@@ -582,8 +618,6 @@ class BluePygenPass(Pass):
|
|
|
582
618
|
self.emit_ln(node, node.doc.value)
|
|
583
619
|
if node.body:
|
|
584
620
|
self.emit(node, node.body.meta["py_code"])
|
|
585
|
-
else:
|
|
586
|
-
self.decl_def_missing(node.name.meta["py_code"])
|
|
587
621
|
self.indent_level -= 1
|
|
588
622
|
|
|
589
623
|
def exit_enum_def(self, node: ast.EnumDef) -> None:
|
|
@@ -603,7 +637,7 @@ class BluePygenPass(Pass):
|
|
|
603
637
|
if isinstance(i, ast.Name):
|
|
604
638
|
self.emit_ln(node, i.meta["py_code"] + " = __jac_auto__()")
|
|
605
639
|
else:
|
|
606
|
-
self.
|
|
640
|
+
self.emit_ln(node, i.meta["py_code"])
|
|
607
641
|
|
|
608
642
|
def exit_code_block(self, node: ast.CodeBlock) -> None:
|
|
609
643
|
"""Sub objects.
|
|
@@ -1237,9 +1271,13 @@ class BluePygenPass(Pass):
|
|
|
1237
1271
|
|
|
1238
1272
|
values: list[Assignment],
|
|
1239
1273
|
"""
|
|
1240
|
-
|
|
1241
|
-
|
|
1242
|
-
|
|
1274
|
+
if isinstance(node.parent, ast.GlobalVars):
|
|
1275
|
+
for i in node.values:
|
|
1276
|
+
self.emit_ln(node, i.meta["py_code"])
|
|
1277
|
+
else:
|
|
1278
|
+
self.emit(
|
|
1279
|
+
node, f"{', '.join([value.meta['py_code'] for value in node.values])}"
|
|
1280
|
+
)
|
|
1243
1281
|
|
|
1244
1282
|
def exit_index_slice(self, node: ast.IndexSlice) -> None:
|
|
1245
1283
|
"""Sub objects.
|
|
@@ -2,290 +2,62 @@
|
|
|
2
2
|
import jaclang.jac.absyntree as ast
|
|
3
3
|
from jaclang.jac.passes import Pass
|
|
4
4
|
from jaclang.jac.passes.blue import SubNodeTabPass
|
|
5
|
-
from jaclang.jac.
|
|
5
|
+
from jaclang.jac.symtable import SymbolHitType, SymbolTable, SymbolType
|
|
6
6
|
|
|
7
7
|
|
|
8
|
-
class DeclDefMatchPass(Pass
|
|
8
|
+
class DeclDefMatchPass(Pass):
|
|
9
9
|
"""Decls and Def matching pass."""
|
|
10
10
|
|
|
11
11
|
def before_pass(self) -> None:
|
|
12
|
-
"""
|
|
13
|
-
self.
|
|
12
|
+
"""Before pass."""
|
|
13
|
+
self.need_match = []
|
|
14
|
+
if not self.ir.sym_tab:
|
|
15
|
+
return self.ice("Expected symbol table on node.")
|
|
16
|
+
self.connect_decl_def(self.ir.sym_tab)
|
|
17
|
+
self.terminate()
|
|
14
18
|
|
|
15
19
|
def after_pass(self) -> None:
|
|
16
20
|
"""Rebuild sub node table."""
|
|
17
|
-
self.ir = SubNodeTabPass(
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
21
|
+
self.ir = SubNodeTabPass(
|
|
22
|
+
prior=self, mod_path=self.mod_path, input_ir=self.ir
|
|
23
|
+
).ir
|
|
24
|
+
|
|
25
|
+
def connect_decl_def(self, sym_tab: SymbolTable) -> None:
|
|
26
|
+
"""Connect Decls and Defs."""
|
|
27
|
+
for sym in sym_tab.tab.values():
|
|
28
|
+
if sym.sym_type == SymbolType.IMPL:
|
|
29
|
+
# currently strips the type info from impls
|
|
30
|
+
arch_refs = [x[3:] for x in sym.name.split(".")]
|
|
31
|
+
lookup = sym_tab.lookup(arch_refs[0], sym_hit=SymbolHitType.DECL_DEFN)
|
|
32
|
+
decl_node = lookup.decl if lookup else None
|
|
33
|
+
for name in arch_refs[1:]:
|
|
34
|
+
if decl_node:
|
|
35
|
+
lookup = (
|
|
36
|
+
decl_node.sym_tab.lookup(
|
|
37
|
+
name, sym_hit=SymbolHitType.DECL_DEFN
|
|
38
|
+
)
|
|
39
|
+
if decl_node.sym_tab
|
|
40
|
+
else None
|
|
41
|
+
)
|
|
42
|
+
decl_node = lookup.decl if lookup else None
|
|
34
43
|
else:
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
def exit_test(self, node: ast.Test) -> None:
|
|
41
|
-
"""Sub objects.
|
|
42
|
-
|
|
43
|
-
name: Name,
|
|
44
|
-
doc: Optional[DocString],
|
|
45
|
-
description: Token,
|
|
46
|
-
body: CodeBlock,
|
|
47
|
-
"""
|
|
48
|
-
|
|
49
|
-
def enter_import(self, node: ast.Import) -> None:
|
|
50
|
-
"""Sub objects.
|
|
51
|
-
|
|
52
|
-
lang: Name,
|
|
53
|
-
path: ModulePath,
|
|
54
|
-
alias: Optional[Name],
|
|
55
|
-
items: Optional[ModuleItems],
|
|
56
|
-
is_absorb: bool,
|
|
57
|
-
sub_module: Optional[Module],
|
|
58
|
-
"""
|
|
59
|
-
if not node.is_absorb:
|
|
60
|
-
self.sym_tab = self.sym_tab.push(node.path.path_str)
|
|
61
|
-
|
|
62
|
-
def exit_import(self, node: ast.Import) -> None:
|
|
63
|
-
"""Sub objects.
|
|
64
|
-
|
|
65
|
-
lang: Name,
|
|
66
|
-
path: ModulePath,
|
|
67
|
-
alias: Optional[Name],
|
|
68
|
-
items: Optional[ModuleItems],
|
|
69
|
-
is_absorb: bool,
|
|
70
|
-
sub_module: Optional[Module],
|
|
71
|
-
"""
|
|
72
|
-
if not node.is_absorb and not self.sym_tab.parent:
|
|
73
|
-
self.ice("Import should have a parent sym_table scope.")
|
|
74
|
-
elif not node.is_absorb:
|
|
75
|
-
self.sym_tab = self.sym_tab.pop()
|
|
76
|
-
if node.items: # now treat imported items as global
|
|
77
|
-
for i in node.items.items:
|
|
78
|
-
name = i.alias if i.alias else i.name
|
|
79
|
-
decl = self.sym_tab.lookup(name.value)
|
|
80
|
-
if not decl:
|
|
81
|
-
self.sym_tab.set(
|
|
82
|
-
DefDeclSymbol(name=name.value, node=i, has_def=True)
|
|
44
|
+
break
|
|
45
|
+
if not decl_node:
|
|
46
|
+
self.error(
|
|
47
|
+
f"Unable to match implementation {sym.name} to a declaration.",
|
|
48
|
+
sym.defn[-1],
|
|
83
49
|
)
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
"""Sub objects.
|
|
99
|
-
|
|
100
|
-
name: Name,
|
|
101
|
-
arch_type: Token,
|
|
102
|
-
doc: Optional[DocString],
|
|
103
|
-
decorators: Optional[Decorators],
|
|
104
|
-
access: Optional[Token],
|
|
105
|
-
base_classes: BaseClasses,
|
|
106
|
-
body: Optional[ArchBlock],
|
|
107
|
-
"""
|
|
108
|
-
# if no body, check for def
|
|
109
|
-
# if no def, register as decl
|
|
110
|
-
# if complete register as def
|
|
111
|
-
# nota: can allow static overriding perhaps?
|
|
112
|
-
# note: if arch has not body ok, imports body is the arch itself
|
|
113
|
-
|
|
114
|
-
def exit_arch_def(self, node: ast.ArchDef) -> None:
|
|
115
|
-
"""Sub objects.
|
|
116
|
-
|
|
117
|
-
doc: Optional[DocString],
|
|
118
|
-
mod: Optional[DottedNameList],
|
|
119
|
-
arch: ObjectRef | NodeRef | EdgeRef | WalkerRef,
|
|
120
|
-
body: ArchBlock,
|
|
121
|
-
"""
|
|
122
|
-
|
|
123
|
-
def enter_ability(self, node: ast.Ability) -> None:
|
|
124
|
-
"""Sub objects.
|
|
125
|
-
|
|
126
|
-
name_ref: Name | SpecialVarRef | ArchRef,
|
|
127
|
-
is_func: bool,
|
|
128
|
-
is_async: bool,
|
|
129
|
-
is_static: bool,
|
|
130
|
-
doc: Optional[Token],
|
|
131
|
-
decorators: Optional["Decorators"],
|
|
132
|
-
access: Optional[Token],
|
|
133
|
-
signature: Optional["FuncSignature | TypeSpec | EventSignature"],
|
|
134
|
-
body: Optional["CodeBlock"],
|
|
135
|
-
|
|
136
|
-
arch_attached: Optional["ArchBlock"] = None,
|
|
137
|
-
"""
|
|
138
|
-
self.sym_tab = self.sym_tab.push(node.py_resolve_name())
|
|
139
|
-
|
|
140
|
-
def exit_ability(self, node: ast.Ability) -> None:
|
|
141
|
-
"""Sub objects.
|
|
142
|
-
|
|
143
|
-
name: Name,
|
|
144
|
-
is_func: bool,
|
|
145
|
-
doc: Optional[DocString],
|
|
146
|
-
decorators: Optional["Decorators"],
|
|
147
|
-
access: Optional[Token],
|
|
148
|
-
signature: "FuncSignature | TypeSpec | EventSignature",
|
|
149
|
-
body: Optional["CodeBlock"],
|
|
150
|
-
arch_attached: Optional["ArchBlock"] = None,
|
|
151
|
-
"""
|
|
152
|
-
self.sym_tab = self.sym_tab.pop()
|
|
153
|
-
ability_name = node.py_resolve_name()
|
|
154
|
-
name = (
|
|
155
|
-
f"{node.arch_attached.parent.name.value}.{ability_name}"
|
|
156
|
-
if node.arch_attached
|
|
157
|
-
and isinstance(node.arch_attached.parent, ast.Architype)
|
|
158
|
-
else ability_name
|
|
159
|
-
)
|
|
160
|
-
decl = self.sym_tab.lookup(name)
|
|
161
|
-
if decl and decl.has_decl:
|
|
162
|
-
self.error(
|
|
163
|
-
f"Ability bound with name {name} already defined on "
|
|
164
|
-
f"Line {decl.node.line} in {decl.node.mod_link.rel_mod_path}."
|
|
165
|
-
)
|
|
166
|
-
elif decl and decl.has_def:
|
|
167
|
-
decl.has_decl = True
|
|
168
|
-
decl.node = node
|
|
169
|
-
decl.node.body = (
|
|
170
|
-
decl.other_node.body
|
|
171
|
-
if isinstance(decl.other_node, ast.AbilityDef)
|
|
172
|
-
else self.ice("Expected node of type AbilityDef in symbol table.")
|
|
173
|
-
)
|
|
174
|
-
ast.append_node(decl.node, decl.other_node)
|
|
175
|
-
self.sym_tab.set(decl)
|
|
176
|
-
else:
|
|
177
|
-
decl = DefDeclSymbol(name=name, node=node, has_decl=True)
|
|
178
|
-
if node.body:
|
|
179
|
-
decl.has_def = True
|
|
180
|
-
decl.other_node = node
|
|
181
|
-
self.sym_tab.set(decl)
|
|
182
|
-
|
|
183
|
-
def enter_ability_def(self, node: ast.AbilityDef) -> None:
|
|
184
|
-
"""Sub objects.
|
|
185
|
-
|
|
186
|
-
doc: Optional[DocString],
|
|
187
|
-
target: Optional["DottedNameList"],
|
|
188
|
-
ability: "ArchRef",
|
|
189
|
-
signature: "FuncSignature | EventSignature",
|
|
190
|
-
body: "CodeBlock",
|
|
191
|
-
"""
|
|
192
|
-
self.sym_tab = self.sym_tab.push(node.ability.py_resolve_name())
|
|
193
|
-
|
|
194
|
-
def exit_ability_def(self, node: ast.AbilityDef) -> None:
|
|
195
|
-
"""Sub objects.
|
|
196
|
-
|
|
197
|
-
doc: Optional[DocString],
|
|
198
|
-
target: Optional["DottedNameList"],
|
|
199
|
-
ability: "ArchRef",
|
|
200
|
-
signature: "FuncSignature | EventSignature",
|
|
201
|
-
body: "CodeBlock",
|
|
202
|
-
"""
|
|
203
|
-
self.sym_tab = self.sym_tab.pop()
|
|
204
|
-
name = node.ability.py_resolve_name()
|
|
205
|
-
if node.target:
|
|
206
|
-
owner = node.target.names[-1]
|
|
207
|
-
if not isinstance(owner, ast.ArchRef):
|
|
208
|
-
self.error("Expected reference to Architype!")
|
|
209
|
-
owner = ""
|
|
210
|
-
else:
|
|
211
|
-
owner = owner.py_resolve_name()
|
|
212
|
-
name = f"{owner}.{name}"
|
|
213
|
-
decl = self.sym_tab.lookup(name)
|
|
214
|
-
if decl and decl.has_def:
|
|
215
|
-
self.error(
|
|
216
|
-
f"Ability bound with name {name} already defined on "
|
|
217
|
-
f"Line {decl.other_node.line} in {decl.other_node.mod_link.rel_mod_path}."
|
|
218
|
-
)
|
|
219
|
-
elif decl and decl.has_decl:
|
|
220
|
-
decl.has_def = True
|
|
221
|
-
decl.other_node = node
|
|
222
|
-
decl.node.body = decl.other_node.body
|
|
223
|
-
ast.append_node(decl.node, decl.other_node)
|
|
224
|
-
self.sym_tab.set(decl)
|
|
225
|
-
else:
|
|
226
|
-
self.sym_tab.set(DefDeclSymbol(name=name, other_node=node, has_def=True))
|
|
227
|
-
|
|
228
|
-
def enter_arch_block(self, node: ast.ArchBlock) -> None:
|
|
229
|
-
"""Sub objects.
|
|
230
|
-
|
|
231
|
-
members: list['ArchHas | Ability'],
|
|
232
|
-
"""
|
|
233
|
-
# Tags all function signatures whether method style or not
|
|
234
|
-
for i in self.get_all_sub_nodes(node, ast.Ability):
|
|
235
|
-
i.arch_attached = node
|
|
236
|
-
|
|
237
|
-
def exit_enum(self, node: ast.Enum) -> None:
|
|
238
|
-
"""Sub objects.
|
|
239
|
-
|
|
240
|
-
name: Name,
|
|
241
|
-
doc: Optional[DocString],
|
|
242
|
-
decorators: Optional[Decorators],
|
|
243
|
-
access: Optional[Token],
|
|
244
|
-
base_classes: BaseClasses,
|
|
245
|
-
body: Optional[EnumBlock],
|
|
246
|
-
"""
|
|
247
|
-
name = node.name.value
|
|
248
|
-
decl = self.sym_tab.lookup(name)
|
|
249
|
-
if decl and decl.has_decl:
|
|
250
|
-
self.error(
|
|
251
|
-
f"Enum bound with name {name} already defined on Line {decl.node.line}."
|
|
252
|
-
)
|
|
253
|
-
elif decl and decl.has_def:
|
|
254
|
-
decl.has_decl = True
|
|
255
|
-
decl.node = node
|
|
256
|
-
decl.node.body = (
|
|
257
|
-
decl.other_node.body
|
|
258
|
-
if isinstance(decl.other_node, ast.EnumDef)
|
|
259
|
-
else self.ice("Expected node of type EnumDef in symbol table.")
|
|
260
|
-
)
|
|
261
|
-
ast.append_node(decl.node, decl.other_node)
|
|
262
|
-
self.sym_tab.set(decl)
|
|
263
|
-
else:
|
|
264
|
-
decl = DefDeclSymbol(name=name, node=node, has_decl=True)
|
|
265
|
-
if node.body:
|
|
266
|
-
decl.has_def = True
|
|
267
|
-
decl.other_node = node
|
|
268
|
-
self.sym_tab.set(decl)
|
|
269
|
-
|
|
270
|
-
def exit_enum_def(self, node: ast.EnumDef) -> None:
|
|
271
|
-
"""Sub objects.
|
|
272
|
-
|
|
273
|
-
doc: Optional[Token],
|
|
274
|
-
enum: ArchRef,
|
|
275
|
-
mod: Optional[DottedNameList],
|
|
276
|
-
body: EnumBlock,
|
|
277
|
-
"""
|
|
278
|
-
name = node.enum.py_resolve_name()
|
|
279
|
-
decl = self.sym_tab.lookup(name)
|
|
280
|
-
if decl and decl.has_def:
|
|
281
|
-
self.error(
|
|
282
|
-
f"Enum bound with name {name} already defined on Line {decl.other_node.line}."
|
|
283
|
-
)
|
|
284
|
-
elif decl and decl.has_decl:
|
|
285
|
-
decl.has_def = True
|
|
286
|
-
decl.other_node = node
|
|
287
|
-
decl.node.body = decl.other_node.body
|
|
288
|
-
ast.append_node(decl.node, decl.other_node)
|
|
289
|
-
self.sym_tab.set(decl)
|
|
290
|
-
else:
|
|
291
|
-
self.sym_tab.set(DefDeclSymbol(name=name, other_node=node, has_def=True))
|
|
50
|
+
continue
|
|
51
|
+
elif isinstance(decl_node, ast.Ability) and decl_node.is_abstract:
|
|
52
|
+
self.error(
|
|
53
|
+
f"Abstract ability {decl_node.py_resolve_name()} should not have a definition.",
|
|
54
|
+
decl_node,
|
|
55
|
+
)
|
|
56
|
+
continue
|
|
57
|
+
ast.append_node(decl_node, sym.defn[-1].body) # type: ignore
|
|
58
|
+
decl_node.body = sym.defn[-1].body # type: ignore
|
|
59
|
+
decl_node.sym_tab.tab = sym.defn[-1].sym_tab.tab # type: ignore
|
|
60
|
+
sym.decl = decl_node
|
|
61
|
+
|
|
62
|
+
for i in sym_tab.kid:
|
|
63
|
+
self.connect_decl_def(i)
|
|
@@ -26,7 +26,7 @@ class ImportPass(Pass):
|
|
|
26
26
|
ast.append_node(i, self.import_module(i, node.mod_path))
|
|
27
27
|
i.sub_module = i.kid[-1]
|
|
28
28
|
self.enter_import(i)
|
|
29
|
-
SubNodeTabPass(mod_path=node.mod_path, input_ir=node)
|
|
29
|
+
SubNodeTabPass(prior=self, mod_path=node.mod_path, input_ir=node)
|
|
30
30
|
|
|
31
31
|
def enter_import(self, node: ast.Import) -> None:
|
|
32
32
|
"""Sub objects.
|