jaclang 0.8.9__py3-none-any.whl → 0.8.10__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 (103) hide show
  1. jaclang/cli/cli.py +147 -25
  2. jaclang/cli/cmdreg.py +144 -8
  3. jaclang/compiler/__init__.py +6 -1
  4. jaclang/compiler/codeinfo.py +16 -1
  5. jaclang/compiler/constant.py +33 -13
  6. jaclang/compiler/jac.lark +130 -31
  7. jaclang/compiler/larkparse/jac_parser.py +2 -2
  8. jaclang/compiler/parser.py +567 -176
  9. jaclang/compiler/passes/__init__.py +2 -1
  10. jaclang/compiler/passes/ast_gen/__init__.py +5 -0
  11. jaclang/compiler/passes/ast_gen/base_ast_gen_pass.py +54 -0
  12. jaclang/compiler/passes/ast_gen/jsx_processor.py +344 -0
  13. jaclang/compiler/passes/ecmascript/__init__.py +25 -0
  14. jaclang/compiler/passes/ecmascript/es_unparse.py +576 -0
  15. jaclang/compiler/passes/ecmascript/esast_gen_pass.py +2068 -0
  16. jaclang/compiler/passes/ecmascript/estree.py +972 -0
  17. jaclang/compiler/passes/ecmascript/tests/__init__.py +1 -0
  18. jaclang/compiler/passes/ecmascript/tests/fixtures/advanced_language_features.jac +170 -0
  19. jaclang/compiler/passes/ecmascript/tests/fixtures/class_separate_impl.impl.jac +30 -0
  20. jaclang/compiler/passes/ecmascript/tests/fixtures/class_separate_impl.jac +14 -0
  21. jaclang/compiler/passes/ecmascript/tests/fixtures/client_jsx.jac +89 -0
  22. jaclang/compiler/passes/ecmascript/tests/fixtures/core_language_features.jac +195 -0
  23. jaclang/compiler/passes/ecmascript/tests/test_esast_gen_pass.py +167 -0
  24. jaclang/compiler/passes/ecmascript/tests/test_js_generation.py +239 -0
  25. jaclang/compiler/passes/main/__init__.py +0 -3
  26. jaclang/compiler/passes/main/annex_pass.py +23 -1
  27. jaclang/compiler/passes/main/pyast_gen_pass.py +324 -234
  28. jaclang/compiler/passes/main/pyast_load_pass.py +46 -11
  29. jaclang/compiler/passes/main/pyjac_ast_link_pass.py +2 -0
  30. jaclang/compiler/passes/main/sym_tab_build_pass.py +18 -1
  31. jaclang/compiler/passes/main/tests/fixtures/autoimpl.cl.jac +7 -0
  32. jaclang/compiler/passes/main/tests/fixtures/checker_arity.jac +3 -0
  33. jaclang/compiler/passes/main/tests/fixtures/checker_class_construct.jac +33 -0
  34. jaclang/compiler/passes/main/tests/fixtures/defuse_modpath.jac +7 -0
  35. jaclang/compiler/passes/main/tests/fixtures/member_access_type_resolve.jac +2 -1
  36. jaclang/compiler/passes/main/tests/test_checker_pass.py +31 -2
  37. jaclang/compiler/passes/main/tests/test_def_use_pass.py +12 -0
  38. jaclang/compiler/passes/main/tests/test_import_pass.py +23 -4
  39. jaclang/compiler/passes/main/tests/test_pyast_gen_pass.py +25 -0
  40. jaclang/compiler/passes/main/type_checker_pass.py +7 -0
  41. jaclang/compiler/passes/tool/doc_ir_gen_pass.py +115 -0
  42. jaclang/compiler/passes/tool/fuse_comments_pass.py +1 -10
  43. jaclang/compiler/passes/tool/tests/test_jac_format_pass.py +4 -1
  44. jaclang/compiler/passes/transform.py +9 -1
  45. jaclang/compiler/passes/uni_pass.py +5 -7
  46. jaclang/compiler/program.py +22 -25
  47. jaclang/compiler/tests/test_client_codegen.py +113 -0
  48. jaclang/compiler/tests/test_importer.py +12 -10
  49. jaclang/compiler/tests/test_parser.py +249 -3
  50. jaclang/compiler/type_system/type_evaluator.jac +169 -50
  51. jaclang/compiler/type_system/type_utils.py +1 -1
  52. jaclang/compiler/type_system/types.py +6 -0
  53. jaclang/compiler/unitree.py +430 -84
  54. jaclang/langserve/engine.jac +224 -288
  55. jaclang/langserve/sem_manager.jac +12 -8
  56. jaclang/langserve/server.jac +48 -48
  57. jaclang/langserve/tests/fixtures/greet.py +17 -0
  58. jaclang/langserve/tests/fixtures/md_path.jac +22 -0
  59. jaclang/langserve/tests/fixtures/user.jac +15 -0
  60. jaclang/langserve/tests/test_server.py +66 -371
  61. jaclang/lib.py +1 -1
  62. jaclang/runtimelib/client_bundle.py +169 -0
  63. jaclang/runtimelib/client_runtime.jac +586 -0
  64. jaclang/runtimelib/constructs.py +2 -0
  65. jaclang/runtimelib/machine.py +259 -100
  66. jaclang/runtimelib/meta_importer.py +111 -22
  67. jaclang/runtimelib/mtp.py +15 -0
  68. jaclang/runtimelib/server.py +1089 -0
  69. jaclang/runtimelib/tests/fixtures/client_app.jac +18 -0
  70. jaclang/runtimelib/tests/fixtures/custom_access_validation.jac +1 -1
  71. jaclang/runtimelib/tests/fixtures/savable_object.jac +4 -5
  72. jaclang/runtimelib/tests/fixtures/serve_api.jac +75 -0
  73. jaclang/runtimelib/tests/test_client_bundle.py +55 -0
  74. jaclang/runtimelib/tests/test_client_render.py +63 -0
  75. jaclang/runtimelib/tests/test_serve.py +1069 -0
  76. jaclang/settings.py +0 -2
  77. jaclang/tests/fixtures/iife_functions.jac +142 -0
  78. jaclang/tests/fixtures/iife_functions_client.jac +143 -0
  79. jaclang/tests/fixtures/multistatement_lambda.jac +116 -0
  80. jaclang/tests/fixtures/multistatement_lambda_client.jac +113 -0
  81. jaclang/tests/fixtures/needs_import_dup.jac +6 -4
  82. jaclang/tests/fixtures/py_run.py +7 -5
  83. jaclang/tests/fixtures/pyfunc_fstr.py +2 -2
  84. jaclang/tests/fixtures/simple_lambda_test.jac +12 -0
  85. jaclang/tests/test_cli.py +1 -1
  86. jaclang/tests/test_language.py +10 -39
  87. jaclang/tests/test_reference.py +17 -2
  88. jaclang/utils/NonGPT.py +375 -0
  89. jaclang/utils/helpers.py +44 -16
  90. jaclang/utils/lang_tools.py +31 -4
  91. jaclang/utils/tests/test_lang_tools.py +1 -1
  92. jaclang/utils/treeprinter.py +8 -3
  93. {jaclang-0.8.9.dist-info → jaclang-0.8.10.dist-info}/METADATA +3 -3
  94. {jaclang-0.8.9.dist-info → jaclang-0.8.10.dist-info}/RECORD +96 -66
  95. jaclang/compiler/passes/main/binder_pass.py +0 -594
  96. jaclang/compiler/passes/main/tests/fixtures/sym_binder.jac +0 -47
  97. jaclang/compiler/passes/main/tests/test_binder_pass.py +0 -111
  98. jaclang/langserve/tests/session.jac +0 -294
  99. jaclang/langserve/tests/test_dev_server.py +0 -80
  100. jaclang/runtimelib/importer.py +0 -351
  101. jaclang/tests/test_typecheck.py +0 -542
  102. {jaclang-0.8.9.dist-info → jaclang-0.8.10.dist-info}/WHEEL +0 -0
  103. {jaclang-0.8.9.dist-info → jaclang-0.8.10.dist-info}/entry_points.txt +0 -0
@@ -0,0 +1,18 @@
1
+ """Sample Jac module containing client-side declarations."""
2
+
3
+ cl let API_LABEL: str = "Runtime Test";
4
+
5
+ cl obj ButtonProps {
6
+ has label: str = "Tap Me";
7
+ has color: str = "primary";
8
+ }
9
+
10
+ cl def client_page() {
11
+ let props = ButtonProps(label="Tap Me", color="primary");
12
+ return <div class="app">
13
+ <h1>{API_LABEL}</h1>
14
+ <button class={props.color} data-id="button">
15
+ {props.label}
16
+ </button>
17
+ </div>;
18
+ }
@@ -27,7 +27,7 @@ node A {
27
27
  walker create_other_root {
28
28
  can enter with `root entry {
29
29
  other_root = `root().__jac__;
30
- _jl.save(other_root);
30
+ save(other_root);
31
31
  print(other_root.id);
32
32
  }
33
33
  }
@@ -43,10 +43,8 @@ walker create_custom_object {
43
43
  }
44
44
 
45
45
  can exit1 with `root exit {
46
- # get directly from shelf
47
- o = _jl.get_context().mem.__shelf__.get(str(self.obj.__jac__.id)).archetype;
48
- print(jid(o));
49
- print(o);
46
+ print(jid(self.obj));
47
+ print(self.obj);
50
48
  }
51
49
  }
52
50
 
@@ -87,6 +85,7 @@ walker delete_custom_object {
87
85
  has object_id: str;
88
86
 
89
87
  can enter1 with `root entry {
90
- _jl.destroy([&(self.object_id)]);
88
+ savable_object = &(self.object_id);
89
+ del savable_object;
91
90
  }
92
91
  }
@@ -0,0 +1,75 @@
1
+ """Example Jac program for REST API server."""
2
+
3
+ # Define some nodes
4
+ node Task {
5
+ has title: str;
6
+ has completed: bool = False;
7
+ has priority: int = 0;
8
+ }
9
+
10
+ node User {
11
+ has name: str;
12
+ has email: str;
13
+ }
14
+
15
+ # Define a walker to create tasks
16
+ walker CreateTask {
17
+ has title: str;
18
+ has priority: int = 1;
19
+
20
+ can create with `root entry {
21
+ task_list = here ++> Task(title=self.title, priority=self.priority);
22
+ task = task_list[0] if task_list else None;
23
+ if task {
24
+ print("Created task: " + task.title);
25
+ }
26
+ }
27
+ }
28
+
29
+ # Define a walker to list all tasks
30
+ walker ListTasks {
31
+ has tasks: list = [];
32
+
33
+ can collect with `root entry {
34
+ visit [-->];
35
+ }
36
+
37
+ can gather with Task entry {
38
+ print("Found task: " + here.title);
39
+ }
40
+ }
41
+
42
+ # Define a walker to mark tasks as complete
43
+ walker CompleteTask {
44
+ has title: str;
45
+
46
+ can search with `root entry {
47
+ visit [-->];
48
+ }
49
+
50
+ can mark_complete with Task entry {
51
+ if here.title == self.title {
52
+ here.completed = True;
53
+ print("Completed task: " + here.title);
54
+ }
55
+ }
56
+ }
57
+
58
+ """Function to add two numbers together."""
59
+ def add_numbers(a: int, b: int) -> int {
60
+ return a + b;
61
+ }
62
+
63
+ """Function to generate a greeting message."""
64
+ def greet(name: str = "World") -> str {
65
+ return "Hello, " + name + "!";
66
+ }
67
+
68
+ cl let WELCOME_TITLE: str = "Runtime Test";
69
+
70
+ cl def client_page() {
71
+ return <section class="welcome">
72
+ <h1>{WELCOME_TITLE}</h1>
73
+ <p>{greet()}</p>
74
+ </section>;
75
+ }
@@ -0,0 +1,55 @@
1
+ """Tests for client bundle generation."""
2
+
3
+ from __future__ import annotations
4
+
5
+ from pathlib import Path
6
+
7
+ from jaclang.runtimelib.client_bundle import ClientBundleBuilder
8
+ from jaclang.runtimelib.machine import JacMachine as Jac
9
+ from jaclang.utils.test import TestCase
10
+
11
+
12
+ class ClientBundleBuilderTests(TestCase):
13
+ """Validate client bundle compilation."""
14
+
15
+ def setUp(self) -> None:
16
+ Jac.reset_machine()
17
+ return super().setUp()
18
+
19
+ def tearDown(self) -> None:
20
+ Jac.reset_machine()
21
+ return super().tearDown()
22
+
23
+ def test_build_bundle_for_module(self) -> None:
24
+ """Compile a Jac module and ensure client bundle metadata is emitted."""
25
+ fixtures_dir = Path(__file__).parent / "fixtures"
26
+ (module,) = Jac.jac_import("client_app", str(fixtures_dir))
27
+
28
+ builder = ClientBundleBuilder()
29
+ bundle = builder.build(module)
30
+
31
+ self.assertIn("function __jacJsx", bundle.code)
32
+ # Check that registration mechanism is present
33
+ self.assertIn('moduleFunctions[funcName] = funcRef;', bundle.code)
34
+ self.assertIn('scope[funcName] = funcRef;', bundle.code)
35
+ self.assertIn('moduleGlobals[gName] = existing;', bundle.code)
36
+ self.assertIn('scope[gName] = defaultValue;', bundle.code)
37
+ # Check that actual client functions and globals are defined
38
+ self.assertIn('function client_page()', bundle.code)
39
+ self.assertIn('class ButtonProps', bundle.code)
40
+ self.assertIn('const API_LABEL = "Runtime Test";', bundle.code)
41
+ # Check hydration logic is present
42
+ self.assertIn("__jacHydrateFromDom", bundle.code)
43
+ self.assertIn("__jacEnsureHydration", bundle.code)
44
+ self.assertIn('getElementById("__jac_init__")', bundle.code)
45
+ self.assertIn('getElementById("__jac_root")', bundle.code)
46
+ # Check globals iteration logic
47
+ self.assertIn("for (const gName of __objectKeys(payloadGlobals))", bundle.code)
48
+ self.assertIn("client_page", bundle.client_functions)
49
+ self.assertIn("ButtonProps", bundle.client_functions)
50
+ self.assertIn("API_LABEL", bundle.client_globals)
51
+ self.assertGreater(len(bundle.hash), 10)
52
+
53
+ cached = builder.build(module)
54
+ self.assertEqual(bundle.hash, cached.hash)
55
+ self.assertEqual(bundle.code, cached.code)
@@ -0,0 +1,63 @@
1
+ """Offline tests for client page rendering without sockets."""
2
+
3
+ from __future__ import annotations
4
+
5
+ import json
6
+ import re
7
+ from pathlib import Path
8
+
9
+ from jaclang.runtimelib.machine import JacMachine as Jac
10
+ from jaclang.runtimelib.server import JacAPIServer
11
+ from jaclang.utils.test import TestCase
12
+
13
+
14
+ class ClientRenderTests(TestCase):
15
+ """Validate client bundle helpers without opening sockets."""
16
+
17
+ def setUp(self) -> None:
18
+ Jac.reset_machine()
19
+ super().setUp()
20
+
21
+ def tearDown(self) -> None:
22
+ Jac.reset_machine()
23
+ super().tearDown()
24
+
25
+ def _make_server(self) -> JacAPIServer:
26
+ fixtures_dir = Path(__file__).parent / "fixtures"
27
+ Jac.jac_import("client_app", str(fixtures_dir))
28
+ server = JacAPIServer(
29
+ module_name="client_app", session_path=str(self.fixture_abs_path("client.session"))
30
+ )
31
+ server.load_module()
32
+ return server
33
+
34
+ def test_render_client_page_returns_html(self) -> None:
35
+ server = self._make_server()
36
+ server.user_manager.create_user("tester", "pass")
37
+ html_bundle = server.render_client_page("client_page", {}, "tester")
38
+
39
+ self.assertIn("<!DOCTYPE html>", html_bundle["html"])
40
+ self.assertIn('<div id="__jac_root"></div>', html_bundle["html"])
41
+ self.assertIn("/static/client.js?hash=", html_bundle["html"])
42
+
43
+ init_match = re.search(
44
+ r'<script id="__jac_init__" type="application/json">([^<]*)</script>',
45
+ html_bundle["html"],
46
+ )
47
+ self.assertIsNotNone(init_match)
48
+ payload = json.loads(init_match.group(1)) if init_match else {}
49
+ self.assertEqual(payload.get("module"), "client_app")
50
+ self.assertEqual(payload.get("function"), "client_page")
51
+ self.assertEqual(payload.get("globals", {}).get("API_LABEL"), "Runtime Test")
52
+ self.assertEqual(payload.get("argOrder"), [])
53
+
54
+ bundle_code = server.get_client_bundle_code()
55
+ self.assertIn("function __jacJsx", bundle_code)
56
+ self.assertEqual(bundle_code, html_bundle["bundle_code"])
57
+
58
+ def test_render_unknown_page_raises(self) -> None:
59
+ server = self._make_server()
60
+ server.user_manager.create_user("tester", "pass")
61
+
62
+ with self.assertRaises(ValueError):
63
+ server.render_client_page("missing", {}, "tester")