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.
- jaclang/cli/cli.py +147 -25
- jaclang/cli/cmdreg.py +144 -8
- jaclang/compiler/__init__.py +6 -1
- jaclang/compiler/codeinfo.py +16 -1
- jaclang/compiler/constant.py +33 -13
- jaclang/compiler/jac.lark +130 -31
- jaclang/compiler/larkparse/jac_parser.py +2 -2
- jaclang/compiler/parser.py +567 -176
- jaclang/compiler/passes/__init__.py +2 -1
- jaclang/compiler/passes/ast_gen/__init__.py +5 -0
- jaclang/compiler/passes/ast_gen/base_ast_gen_pass.py +54 -0
- jaclang/compiler/passes/ast_gen/jsx_processor.py +344 -0
- jaclang/compiler/passes/ecmascript/__init__.py +25 -0
- jaclang/compiler/passes/ecmascript/es_unparse.py +576 -0
- jaclang/compiler/passes/ecmascript/esast_gen_pass.py +2068 -0
- jaclang/compiler/passes/ecmascript/estree.py +972 -0
- jaclang/compiler/passes/ecmascript/tests/__init__.py +1 -0
- jaclang/compiler/passes/ecmascript/tests/fixtures/advanced_language_features.jac +170 -0
- jaclang/compiler/passes/ecmascript/tests/fixtures/class_separate_impl.impl.jac +30 -0
- jaclang/compiler/passes/ecmascript/tests/fixtures/class_separate_impl.jac +14 -0
- jaclang/compiler/passes/ecmascript/tests/fixtures/client_jsx.jac +89 -0
- jaclang/compiler/passes/ecmascript/tests/fixtures/core_language_features.jac +195 -0
- jaclang/compiler/passes/ecmascript/tests/test_esast_gen_pass.py +167 -0
- jaclang/compiler/passes/ecmascript/tests/test_js_generation.py +239 -0
- jaclang/compiler/passes/main/__init__.py +0 -3
- jaclang/compiler/passes/main/annex_pass.py +23 -1
- jaclang/compiler/passes/main/pyast_gen_pass.py +324 -234
- jaclang/compiler/passes/main/pyast_load_pass.py +46 -11
- jaclang/compiler/passes/main/pyjac_ast_link_pass.py +2 -0
- jaclang/compiler/passes/main/sym_tab_build_pass.py +18 -1
- jaclang/compiler/passes/main/tests/fixtures/autoimpl.cl.jac +7 -0
- jaclang/compiler/passes/main/tests/fixtures/checker_arity.jac +3 -0
- jaclang/compiler/passes/main/tests/fixtures/checker_class_construct.jac +33 -0
- jaclang/compiler/passes/main/tests/fixtures/defuse_modpath.jac +7 -0
- jaclang/compiler/passes/main/tests/fixtures/member_access_type_resolve.jac +2 -1
- jaclang/compiler/passes/main/tests/test_checker_pass.py +31 -2
- jaclang/compiler/passes/main/tests/test_def_use_pass.py +12 -0
- jaclang/compiler/passes/main/tests/test_import_pass.py +23 -4
- jaclang/compiler/passes/main/tests/test_pyast_gen_pass.py +25 -0
- jaclang/compiler/passes/main/type_checker_pass.py +7 -0
- jaclang/compiler/passes/tool/doc_ir_gen_pass.py +115 -0
- jaclang/compiler/passes/tool/fuse_comments_pass.py +1 -10
- jaclang/compiler/passes/tool/tests/test_jac_format_pass.py +4 -1
- jaclang/compiler/passes/transform.py +9 -1
- jaclang/compiler/passes/uni_pass.py +5 -7
- jaclang/compiler/program.py +22 -25
- jaclang/compiler/tests/test_client_codegen.py +113 -0
- jaclang/compiler/tests/test_importer.py +12 -10
- jaclang/compiler/tests/test_parser.py +249 -3
- jaclang/compiler/type_system/type_evaluator.jac +169 -50
- jaclang/compiler/type_system/type_utils.py +1 -1
- jaclang/compiler/type_system/types.py +6 -0
- jaclang/compiler/unitree.py +430 -84
- jaclang/langserve/engine.jac +224 -288
- jaclang/langserve/sem_manager.jac +12 -8
- jaclang/langserve/server.jac +48 -48
- jaclang/langserve/tests/fixtures/greet.py +17 -0
- jaclang/langserve/tests/fixtures/md_path.jac +22 -0
- jaclang/langserve/tests/fixtures/user.jac +15 -0
- jaclang/langserve/tests/test_server.py +66 -371
- jaclang/lib.py +1 -1
- jaclang/runtimelib/client_bundle.py +169 -0
- jaclang/runtimelib/client_runtime.jac +586 -0
- jaclang/runtimelib/constructs.py +2 -0
- jaclang/runtimelib/machine.py +259 -100
- jaclang/runtimelib/meta_importer.py +111 -22
- jaclang/runtimelib/mtp.py +15 -0
- jaclang/runtimelib/server.py +1089 -0
- jaclang/runtimelib/tests/fixtures/client_app.jac +18 -0
- jaclang/runtimelib/tests/fixtures/custom_access_validation.jac +1 -1
- jaclang/runtimelib/tests/fixtures/savable_object.jac +4 -5
- jaclang/runtimelib/tests/fixtures/serve_api.jac +75 -0
- jaclang/runtimelib/tests/test_client_bundle.py +55 -0
- jaclang/runtimelib/tests/test_client_render.py +63 -0
- jaclang/runtimelib/tests/test_serve.py +1069 -0
- jaclang/settings.py +0 -2
- jaclang/tests/fixtures/iife_functions.jac +142 -0
- jaclang/tests/fixtures/iife_functions_client.jac +143 -0
- jaclang/tests/fixtures/multistatement_lambda.jac +116 -0
- jaclang/tests/fixtures/multistatement_lambda_client.jac +113 -0
- jaclang/tests/fixtures/needs_import_dup.jac +6 -4
- jaclang/tests/fixtures/py_run.py +7 -5
- jaclang/tests/fixtures/pyfunc_fstr.py +2 -2
- jaclang/tests/fixtures/simple_lambda_test.jac +12 -0
- jaclang/tests/test_cli.py +1 -1
- jaclang/tests/test_language.py +10 -39
- jaclang/tests/test_reference.py +17 -2
- jaclang/utils/NonGPT.py +375 -0
- jaclang/utils/helpers.py +44 -16
- jaclang/utils/lang_tools.py +31 -4
- jaclang/utils/tests/test_lang_tools.py +1 -1
- jaclang/utils/treeprinter.py +8 -3
- {jaclang-0.8.9.dist-info → jaclang-0.8.10.dist-info}/METADATA +3 -3
- {jaclang-0.8.9.dist-info → jaclang-0.8.10.dist-info}/RECORD +96 -66
- jaclang/compiler/passes/main/binder_pass.py +0 -594
- jaclang/compiler/passes/main/tests/fixtures/sym_binder.jac +0 -47
- jaclang/compiler/passes/main/tests/test_binder_pass.py +0 -111
- jaclang/langserve/tests/session.jac +0 -294
- jaclang/langserve/tests/test_dev_server.py +0 -80
- jaclang/runtimelib/importer.py +0 -351
- jaclang/tests/test_typecheck.py +0 -542
- {jaclang-0.8.9.dist-info → jaclang-0.8.10.dist-info}/WHEEL +0 -0
- {jaclang-0.8.9.dist-info → jaclang-0.8.10.dist-info}/entry_points.txt +0 -0
jaclang/settings.py
CHANGED
|
@@ -0,0 +1,142 @@
|
|
|
1
|
+
"""Test Immediately Invoked Function Expressions (IIFE)."""
|
|
2
|
+
|
|
3
|
+
with entry {
|
|
4
|
+
# Test 1: Basic IIFE with no parameters
|
|
5
|
+
let result1 = (def get_value() -> int {
|
|
6
|
+
return 42;
|
|
7
|
+
})();
|
|
8
|
+
|
|
9
|
+
print("Test 1 - Basic IIFE:", result1);
|
|
10
|
+
# Expected: 42
|
|
11
|
+
|
|
12
|
+
# Test 2: IIFE with parameters
|
|
13
|
+
let result2 = (def calculate(x: int, y: int) -> int {
|
|
14
|
+
return x * y + x + y;
|
|
15
|
+
})(5, 3);
|
|
16
|
+
|
|
17
|
+
print("Test 2 - IIFE with parameters (5, 3):", result2);
|
|
18
|
+
# Expected: 23 (15 + 5 + 3)
|
|
19
|
+
|
|
20
|
+
# Test 3: IIFE with local variables
|
|
21
|
+
let result3 = (def compute() -> int {
|
|
22
|
+
let a = 10;
|
|
23
|
+
let b = 20;
|
|
24
|
+
let c = 30;
|
|
25
|
+
return a + b + c;
|
|
26
|
+
})();
|
|
27
|
+
|
|
28
|
+
print("Test 3 - IIFE with local variables:", result3);
|
|
29
|
+
# Expected: 60
|
|
30
|
+
|
|
31
|
+
# Test 4: IIFE with conditional logic
|
|
32
|
+
let result4 = (def check_number(n: int) -> str {
|
|
33
|
+
if n > 0 {
|
|
34
|
+
return "positive";
|
|
35
|
+
} elif n < 0 {
|
|
36
|
+
return "negative";
|
|
37
|
+
} else {
|
|
38
|
+
return "zero";
|
|
39
|
+
}
|
|
40
|
+
})(15);
|
|
41
|
+
|
|
42
|
+
print("Test 4 - IIFE with conditional:", result4);
|
|
43
|
+
# Expected: positive
|
|
44
|
+
|
|
45
|
+
# Test 5: IIFE with loop
|
|
46
|
+
let result5 = (def sum_to_n(n: int) -> int {
|
|
47
|
+
let total = 0;
|
|
48
|
+
let i = 1;
|
|
49
|
+
while i <= n {
|
|
50
|
+
total = total + i;
|
|
51
|
+
i = i + 1;
|
|
52
|
+
}
|
|
53
|
+
return total;
|
|
54
|
+
})(5);
|
|
55
|
+
|
|
56
|
+
print("Test 5 - IIFE with loop (sum 1 to 5):", result5);
|
|
57
|
+
# Expected: 15
|
|
58
|
+
|
|
59
|
+
# Test 6: IIFE returning a function
|
|
60
|
+
let adder = (def make_adder(x: int) {
|
|
61
|
+
return lambda y: int: x + y;
|
|
62
|
+
})(10);
|
|
63
|
+
|
|
64
|
+
print("Test 6 - IIFE returning function, adder(5):", adder(5));
|
|
65
|
+
# Expected: 15
|
|
66
|
+
|
|
67
|
+
# Test 7: Nested IIFE
|
|
68
|
+
let result7 = (def outer() -> int {
|
|
69
|
+
let x = (def inner() -> int {
|
|
70
|
+
return 100;
|
|
71
|
+
})();
|
|
72
|
+
return x + 50;
|
|
73
|
+
})();
|
|
74
|
+
|
|
75
|
+
print("Test 7 - Nested IIFE:", result7);
|
|
76
|
+
# Expected: 150
|
|
77
|
+
|
|
78
|
+
# Test 8: IIFE with multiple operations
|
|
79
|
+
let result8 = (def process_data(data: list) -> int {
|
|
80
|
+
let sum = 0;
|
|
81
|
+
let count = 0;
|
|
82
|
+
for item in data {
|
|
83
|
+
sum = sum + item;
|
|
84
|
+
count = count + 1;
|
|
85
|
+
}
|
|
86
|
+
if count > 0 {
|
|
87
|
+
return sum / count;
|
|
88
|
+
} else {
|
|
89
|
+
return 0;
|
|
90
|
+
}
|
|
91
|
+
})([10, 20, 30, 40, 50]);
|
|
92
|
+
|
|
93
|
+
print("Test 8 - IIFE computing average:", result8);
|
|
94
|
+
# Expected: 30
|
|
95
|
+
|
|
96
|
+
# Test 9: IIFE with try-catch
|
|
97
|
+
let result9 = (def safe_operation(a: int, b: int) -> str {
|
|
98
|
+
try {
|
|
99
|
+
let result = a / b;
|
|
100
|
+
return f"Success: {result}";
|
|
101
|
+
} except Exception {
|
|
102
|
+
return "Error occurred";
|
|
103
|
+
}
|
|
104
|
+
})(10, 2);
|
|
105
|
+
|
|
106
|
+
print("Test 9 - IIFE with try-catch:", result9);
|
|
107
|
+
# Expected: Success: 5.0
|
|
108
|
+
|
|
109
|
+
# Test 10: IIFE used in assignment chain
|
|
110
|
+
let x = 5;
|
|
111
|
+
let result10 = x + (def double(n: int) -> int {
|
|
112
|
+
return n * 2;
|
|
113
|
+
})(x);
|
|
114
|
+
|
|
115
|
+
print("Test 10 - IIFE in expression (5 + double(5)):", result10);
|
|
116
|
+
# Expected: 15
|
|
117
|
+
|
|
118
|
+
# Test 11: IIFE with object/dict creation
|
|
119
|
+
let result11 = (def create_object() -> dict {
|
|
120
|
+
let obj = {
|
|
121
|
+
"name": "Test",
|
|
122
|
+
"value": 123,
|
|
123
|
+
"active": True
|
|
124
|
+
};
|
|
125
|
+
return obj;
|
|
126
|
+
})();
|
|
127
|
+
|
|
128
|
+
print("Test 11 - IIFE creating object:", result11);
|
|
129
|
+
# Expected: {'name': 'Test', 'value': 123, 'active': True}
|
|
130
|
+
|
|
131
|
+
# Test 12: IIFE with string manipulation
|
|
132
|
+
let result12 = (def format_message(name: str, age: int) -> str {
|
|
133
|
+
let message = f"Hello, {name}!";
|
|
134
|
+
let age_part = f" You are {age} years old.";
|
|
135
|
+
return message + age_part;
|
|
136
|
+
})("Alice", 25);
|
|
137
|
+
|
|
138
|
+
print("Test 12 - IIFE with string manipulation:", result12);
|
|
139
|
+
# Expected: Hello, Alice! You are 25 years old.
|
|
140
|
+
|
|
141
|
+
print("\nAll IIFE tests completed!");
|
|
142
|
+
}
|
|
@@ -0,0 +1,143 @@
|
|
|
1
|
+
"""Test Immediately Invoked Function Expressions (IIFE) for client-side (JavaScript) execution."""
|
|
2
|
+
|
|
3
|
+
cl with entry {
|
|
4
|
+
# Test 1: Basic IIFE with no parameters
|
|
5
|
+
let result1 = (def get_value() -> int {
|
|
6
|
+
return 42;
|
|
7
|
+
})();
|
|
8
|
+
|
|
9
|
+
print("Test 1 - Basic IIFE:", result1);
|
|
10
|
+
# Expected: 42
|
|
11
|
+
|
|
12
|
+
# Test 2: IIFE with parameters
|
|
13
|
+
let result2 = (def calculate(x: int, y: int) -> int {
|
|
14
|
+
return x * y + x + y;
|
|
15
|
+
})(5, 3);
|
|
16
|
+
|
|
17
|
+
print("Test 2 - IIFE with parameters (5, 3):", result2);
|
|
18
|
+
# Expected: 23 (15 + 5 + 3)
|
|
19
|
+
|
|
20
|
+
# Test 3: IIFE with local variables
|
|
21
|
+
let result3 = (def compute() -> int {
|
|
22
|
+
let a = 10;
|
|
23
|
+
let b = 20;
|
|
24
|
+
let c = 30;
|
|
25
|
+
return a + b + c;
|
|
26
|
+
})();
|
|
27
|
+
|
|
28
|
+
print("Test 3 - IIFE with local variables:", result3);
|
|
29
|
+
# Expected: 60
|
|
30
|
+
|
|
31
|
+
# Test 4: IIFE with conditional logic
|
|
32
|
+
let result4 = (def check_number(n: int) -> str {
|
|
33
|
+
if n > 0 {
|
|
34
|
+
return "positive";
|
|
35
|
+
} elif n < 0 {
|
|
36
|
+
return "negative";
|
|
37
|
+
} else {
|
|
38
|
+
return "zero";
|
|
39
|
+
}
|
|
40
|
+
})(15);
|
|
41
|
+
|
|
42
|
+
print("Test 4 - IIFE with conditional:", result4);
|
|
43
|
+
# Expected: positive
|
|
44
|
+
|
|
45
|
+
# Test 5: IIFE with loop
|
|
46
|
+
let result5 = (def sum_to_n(n: int) -> int {
|
|
47
|
+
let total = 0;
|
|
48
|
+
let i = 1;
|
|
49
|
+
while i <= n {
|
|
50
|
+
total = total + i;
|
|
51
|
+
i = i + 1;
|
|
52
|
+
}
|
|
53
|
+
return total;
|
|
54
|
+
})(5);
|
|
55
|
+
|
|
56
|
+
print("Test 5 - IIFE with loop (sum 1 to 5):", result5);
|
|
57
|
+
# Expected: 15
|
|
58
|
+
|
|
59
|
+
# Test 6: IIFE returning a function
|
|
60
|
+
let adder = (def make_adder(x: int) {
|
|
61
|
+
return lambda y: int: x + y;
|
|
62
|
+
})(10);
|
|
63
|
+
|
|
64
|
+
print("Test 6 - IIFE returning function, adder(5):", adder(5));
|
|
65
|
+
# Expected: 15
|
|
66
|
+
|
|
67
|
+
# Test 7: Nested IIFE
|
|
68
|
+
let result7 = (def outer() -> int {
|
|
69
|
+
let x = (def inner() -> int {
|
|
70
|
+
return 100;
|
|
71
|
+
})();
|
|
72
|
+
return x + 50;
|
|
73
|
+
})();
|
|
74
|
+
|
|
75
|
+
print("Test 7 - Nested IIFE:", result7);
|
|
76
|
+
# Expected: 150
|
|
77
|
+
|
|
78
|
+
# Test 8: IIFE with array operations
|
|
79
|
+
let result8 = (def process_data(data: list) -> int {
|
|
80
|
+
let sum = 0;
|
|
81
|
+
let count = 0;
|
|
82
|
+
for item in data {
|
|
83
|
+
sum = sum + item;
|
|
84
|
+
count = count + 1;
|
|
85
|
+
}
|
|
86
|
+
if count > 0 {
|
|
87
|
+
return sum / count;
|
|
88
|
+
} else {
|
|
89
|
+
return 0;
|
|
90
|
+
}
|
|
91
|
+
})([10, 20, 30, 40, 50]);
|
|
92
|
+
|
|
93
|
+
print("Test 8 - IIFE computing average:", result8);
|
|
94
|
+
# Expected: 30
|
|
95
|
+
|
|
96
|
+
# Test 9: IIFE used in assignment chain
|
|
97
|
+
let x = 5;
|
|
98
|
+
let result9 = x + (def double(n: int) -> int {
|
|
99
|
+
return n * 2;
|
|
100
|
+
})(x);
|
|
101
|
+
|
|
102
|
+
print("Test 9 - IIFE in expression (5 + double(5)):", result9);
|
|
103
|
+
# Expected: 15
|
|
104
|
+
|
|
105
|
+
# Test 10: IIFE with object creation
|
|
106
|
+
let result10 = (def create_object() -> dict {
|
|
107
|
+
let obj = {
|
|
108
|
+
"name": "Test",
|
|
109
|
+
"value": 123,
|
|
110
|
+
"active": True
|
|
111
|
+
};
|
|
112
|
+
return obj;
|
|
113
|
+
})();
|
|
114
|
+
|
|
115
|
+
print("Test 10 - IIFE creating object:", result10);
|
|
116
|
+
# Expected: {name: 'Test', value: 123, active: true}
|
|
117
|
+
|
|
118
|
+
# Test 11: IIFE with string manipulation
|
|
119
|
+
let result11 = (def format_message(name: str, age: int) -> str {
|
|
120
|
+
let message = "Hello, " + name + "!";
|
|
121
|
+
let age_part = " You are " + str(age) + " years old.";
|
|
122
|
+
return message + age_part;
|
|
123
|
+
})("Alice", 25);
|
|
124
|
+
|
|
125
|
+
print("Test 11 - IIFE with string manipulation:", result11);
|
|
126
|
+
# Expected: Hello, Alice! You are 25 years old.
|
|
127
|
+
|
|
128
|
+
# Test 12: IIFE with closure
|
|
129
|
+
let counter = (def create_counter() {
|
|
130
|
+
let count = 0;
|
|
131
|
+
return lambda () {
|
|
132
|
+
count = count + 1;
|
|
133
|
+
return count;
|
|
134
|
+
};
|
|
135
|
+
})();
|
|
136
|
+
|
|
137
|
+
print("Test 12 - IIFE with closure, call 1:", counter());
|
|
138
|
+
print("Test 12 - IIFE with closure, call 2:", counter());
|
|
139
|
+
print("Test 12 - IIFE with closure, call 3:", counter());
|
|
140
|
+
# Expected: 1, 2, 3
|
|
141
|
+
|
|
142
|
+
print("\nAll client-side IIFE tests completed!");
|
|
143
|
+
}
|
|
@@ -0,0 +1,116 @@
|
|
|
1
|
+
"""Test multi-statement lambda expressions."""
|
|
2
|
+
|
|
3
|
+
with entry {
|
|
4
|
+
# Test 1: Basic multi-statement lambda
|
|
5
|
+
let add_and_multiply = lambda x: int, y: int -> int {
|
|
6
|
+
let sum = x + y;
|
|
7
|
+
let product = x * y;
|
|
8
|
+
return sum + product;
|
|
9
|
+
};
|
|
10
|
+
|
|
11
|
+
let result1 = add_and_multiply(3, 4);
|
|
12
|
+
print("Test 1 - Multi-statement lambda (3 + 4) + (3 * 4):", result1);
|
|
13
|
+
# Expected: 19 (7 + 12)
|
|
14
|
+
|
|
15
|
+
# Test 2: Lambda with conditional logic
|
|
16
|
+
let get_grade = lambda score: int -> str {
|
|
17
|
+
if score >= 90 {
|
|
18
|
+
return "A";
|
|
19
|
+
} elif score >= 80 {
|
|
20
|
+
return "B";
|
|
21
|
+
} elif score >= 70 {
|
|
22
|
+
return "C";
|
|
23
|
+
} else {
|
|
24
|
+
return "F";
|
|
25
|
+
}
|
|
26
|
+
};
|
|
27
|
+
|
|
28
|
+
print("Test 2 - Grade for 85:", get_grade(85));
|
|
29
|
+
print("Test 2 - Grade for 95:", get_grade(95));
|
|
30
|
+
print("Test 2 - Grade for 65:", get_grade(65));
|
|
31
|
+
# Expected: B, A, F
|
|
32
|
+
|
|
33
|
+
# Test 3: Lambda with loop
|
|
34
|
+
let sum_range = lambda n: int -> int {
|
|
35
|
+
let total = 0;
|
|
36
|
+
let i = 0;
|
|
37
|
+
while i < n {
|
|
38
|
+
total = total + i;
|
|
39
|
+
i = i + 1;
|
|
40
|
+
}
|
|
41
|
+
return total;
|
|
42
|
+
};
|
|
43
|
+
|
|
44
|
+
print("Test 3 - Sum of 0 to 9:", sum_range(10));
|
|
45
|
+
# Expected: 45
|
|
46
|
+
|
|
47
|
+
# Test 4: Lambda with multiple statements and variables
|
|
48
|
+
let complex_calc = lambda a: int, b: int, c: int -> int {
|
|
49
|
+
let x = a * 2;
|
|
50
|
+
let y = b + 10;
|
|
51
|
+
let z = c - 5;
|
|
52
|
+
let result = x + y + z;
|
|
53
|
+
return result;
|
|
54
|
+
};
|
|
55
|
+
|
|
56
|
+
print("Test 4 - Complex calculation (5, 3, 8):", complex_calc(5, 3, 8));
|
|
57
|
+
# Expected: (10 + 13 + 3) = 26
|
|
58
|
+
|
|
59
|
+
# Test 5: Lambda that returns another lambda
|
|
60
|
+
let make_adder = lambda x: int {
|
|
61
|
+
return lambda y: int: x + y;
|
|
62
|
+
};
|
|
63
|
+
|
|
64
|
+
let add_five = make_adder(5);
|
|
65
|
+
print("Test 5 - add_five(10):", add_five(10));
|
|
66
|
+
# Expected: 15
|
|
67
|
+
|
|
68
|
+
# Test 6: Lambda with try-catch
|
|
69
|
+
let safe_divide = lambda a: int, b: int -> str {
|
|
70
|
+
try {
|
|
71
|
+
let result = a / b;
|
|
72
|
+
return f"Result: {result}";
|
|
73
|
+
} except Exception {
|
|
74
|
+
return "Division by zero error";
|
|
75
|
+
}
|
|
76
|
+
};
|
|
77
|
+
|
|
78
|
+
print("Test 6 - safe_divide(10, 2):", safe_divide(10, 2));
|
|
79
|
+
print("Test 6 - safe_divide(10, 0):", safe_divide(10, 0));
|
|
80
|
+
# Expected: Result: 5.0, Division by zero error
|
|
81
|
+
|
|
82
|
+
# Test 7: Lambda as higher-order function argument
|
|
83
|
+
let apply_operation = lambda x: int, y: int -> int {
|
|
84
|
+
let multiply = lambda a: int, b: int -> int {
|
|
85
|
+
let result = a * b;
|
|
86
|
+
return result;
|
|
87
|
+
};
|
|
88
|
+
return multiply(x, y);
|
|
89
|
+
};
|
|
90
|
+
|
|
91
|
+
print("Test 7 - apply_operation(6, 7):", apply_operation(6, 7));
|
|
92
|
+
# Expected: 42
|
|
93
|
+
|
|
94
|
+
# Test 8: Lambda with list operations
|
|
95
|
+
let process_list = lambda items: list {
|
|
96
|
+
let result = [];
|
|
97
|
+
for item in items {
|
|
98
|
+
result.append(item * 2);
|
|
99
|
+
}
|
|
100
|
+
return result;
|
|
101
|
+
};
|
|
102
|
+
|
|
103
|
+
print("Test 8 - process_list([1, 2, 3, 4]):", process_list([1, 2, 3, 4]));
|
|
104
|
+
# Expected: [2, 4, 6, 8]
|
|
105
|
+
|
|
106
|
+
# Test 9: Lambda with explicit function signature syntax
|
|
107
|
+
let format_pair = lambda (first: str, second: str) -> str {
|
|
108
|
+
let separator = "-";
|
|
109
|
+
return first + separator + second;
|
|
110
|
+
};
|
|
111
|
+
|
|
112
|
+
print("Test 9 - format_pair('foo', 'bar'):", format_pair("foo", "bar"));
|
|
113
|
+
# Expected: foo-bar
|
|
114
|
+
|
|
115
|
+
print("\nAll multi-statement lambda tests completed!");
|
|
116
|
+
}
|
|
@@ -0,0 +1,113 @@
|
|
|
1
|
+
"""Test multi-statement lambda expressions for client-side (JavaScript) execution."""
|
|
2
|
+
|
|
3
|
+
cl with entry {
|
|
4
|
+
# Test 1: Basic multi-statement lambda
|
|
5
|
+
let add_and_multiply = lambda x: int, y: int -> int {
|
|
6
|
+
let sum = x + y;
|
|
7
|
+
let product = x * y;
|
|
8
|
+
return sum + product;
|
|
9
|
+
};
|
|
10
|
+
|
|
11
|
+
let result1 = add_and_multiply(3, 4);
|
|
12
|
+
print("Test 1 - Multi-statement lambda (3 + 4) + (3 * 4):", result1);
|
|
13
|
+
# Expected: 19 (7 + 12)
|
|
14
|
+
|
|
15
|
+
# Test 2: Lambda with conditional logic
|
|
16
|
+
let get_grade = lambda score: int -> str {
|
|
17
|
+
if score >= 90 {
|
|
18
|
+
return "A";
|
|
19
|
+
} elif score >= 80 {
|
|
20
|
+
return "B";
|
|
21
|
+
} elif score >= 70 {
|
|
22
|
+
return "C";
|
|
23
|
+
} else {
|
|
24
|
+
return "F";
|
|
25
|
+
}
|
|
26
|
+
};
|
|
27
|
+
|
|
28
|
+
print("Test 2 - Grade for 85:", get_grade(85));
|
|
29
|
+
print("Test 2 - Grade for 95:", get_grade(95));
|
|
30
|
+
print("Test 2 - Grade for 65:", get_grade(65));
|
|
31
|
+
# Expected: B, A, F
|
|
32
|
+
|
|
33
|
+
# Test 3: Lambda with loop
|
|
34
|
+
let sum_range = lambda n: int -> int {
|
|
35
|
+
let total = 0;
|
|
36
|
+
let i = 0;
|
|
37
|
+
while i < n {
|
|
38
|
+
total = total + i;
|
|
39
|
+
i = i + 1;
|
|
40
|
+
}
|
|
41
|
+
return total;
|
|
42
|
+
};
|
|
43
|
+
|
|
44
|
+
print("Test 3 - Sum of 0 to 9:", sum_range(10));
|
|
45
|
+
# Expected: 45
|
|
46
|
+
|
|
47
|
+
# Test 4: Lambda with multiple statements and variables
|
|
48
|
+
let complex_calc = lambda a: int, b: int, c: int -> int {
|
|
49
|
+
let x = a * 2;
|
|
50
|
+
let y = b + 10;
|
|
51
|
+
let z = c - 5;
|
|
52
|
+
let result = x + y + z;
|
|
53
|
+
return result;
|
|
54
|
+
};
|
|
55
|
+
|
|
56
|
+
print("Test 4 - Complex calculation (5, 3, 8):", complex_calc(5, 3, 8));
|
|
57
|
+
# Expected: (10 + 13 + 3) = 26
|
|
58
|
+
|
|
59
|
+
# Test 5: Lambda that returns another lambda
|
|
60
|
+
let make_adder = lambda x: int {
|
|
61
|
+
return lambda y: int: x + y;
|
|
62
|
+
};
|
|
63
|
+
|
|
64
|
+
let add_five = make_adder(5);
|
|
65
|
+
print("Test 5 - add_five(10):", add_five(10));
|
|
66
|
+
# Expected: 15
|
|
67
|
+
|
|
68
|
+
# Test 6: Lambda as higher-order function argument
|
|
69
|
+
let apply_operation = lambda op: any, x: int, y: int -> int {
|
|
70
|
+
return op(x, y);
|
|
71
|
+
};
|
|
72
|
+
|
|
73
|
+
let multiply_op = lambda a: int, b: int -> int {
|
|
74
|
+
let result = a * b;
|
|
75
|
+
return result;
|
|
76
|
+
};
|
|
77
|
+
|
|
78
|
+
print("Test 6 - apply_operation with multiply:", apply_operation(multiply_op, 6, 7));
|
|
79
|
+
# Expected: 42
|
|
80
|
+
|
|
81
|
+
# Test 7: Lambda with array operations
|
|
82
|
+
let process_list = lambda items: list {
|
|
83
|
+
let result = [];
|
|
84
|
+
for item in items {
|
|
85
|
+
result.append(item * 2);
|
|
86
|
+
}
|
|
87
|
+
return result;
|
|
88
|
+
};
|
|
89
|
+
|
|
90
|
+
print("Test 7 - process_list([1, 2, 3, 4]):", process_list([1, 2, 3, 4]));
|
|
91
|
+
# Expected: [2, 4, 6, 8]
|
|
92
|
+
|
|
93
|
+
# Test 8: Lambda with string concatenation
|
|
94
|
+
let format_name = lambda first: str, last: str -> str {
|
|
95
|
+
let space = " ";
|
|
96
|
+
let full_name = first + space + last;
|
|
97
|
+
return full_name;
|
|
98
|
+
};
|
|
99
|
+
|
|
100
|
+
print("Test 8 - format_name('John', 'Doe'):", format_name("John", "Doe"));
|
|
101
|
+
# Expected: John Doe
|
|
102
|
+
|
|
103
|
+
# Test 9: Lambda with explicit function signature syntax
|
|
104
|
+
let join_labels = lambda (left: str, right: str) -> str {
|
|
105
|
+
let delimiter = " :: ";
|
|
106
|
+
return left + delimiter + right;
|
|
107
|
+
};
|
|
108
|
+
|
|
109
|
+
print("Test 9 - join_labels('alpha', 'beta'):", join_labels("alpha", "beta"));
|
|
110
|
+
# Expected: alpha :: beta
|
|
111
|
+
|
|
112
|
+
print("\nAll client-side multi-statement lambda tests completed!");
|
|
113
|
+
}
|
|
@@ -1,17 +1,19 @@
|
|
|
1
1
|
"""Test of jac importing python."""
|
|
2
2
|
import os;
|
|
3
|
-
import pyfunc;
|
|
3
|
+
import jaclang.tests.fixtures.pyfunc as pyfunc;
|
|
4
4
|
import random;
|
|
5
|
-
import from pyfunc { my_print }
|
|
5
|
+
import from jaclang.tests.fixtures.pyfunc { my_print }
|
|
6
6
|
|
|
7
7
|
with entry {
|
|
8
8
|
|
|
9
|
+
pyfunc.__name__ = "pyfunc";
|
|
10
|
+
pyfunc.__spec__ = None;
|
|
9
11
|
my_print(pyfunc);
|
|
10
12
|
print(random.random());
|
|
11
13
|
}
|
|
12
14
|
|
|
13
|
-
import circle_pysolo;
|
|
14
|
-
import from circle_pysolo { calculate_area }
|
|
15
|
+
import jaclang.tests.fixtures.circle_pysolo;
|
|
16
|
+
import from jaclang.tests.fixtures.circle_pysolo { calculate_area }
|
|
15
17
|
|
|
16
18
|
with entry {
|
|
17
19
|
print(f"are {calculate_area(2.0)}");
|
jaclang/tests/fixtures/py_run.py
CHANGED
|
@@ -1,8 +1,9 @@
|
|
|
1
|
-
|
|
2
|
-
print("Hello, World!")
|
|
1
|
+
"""Simple Python script used by CLI integration tests."""
|
|
3
2
|
|
|
4
3
|
a = 5
|
|
5
4
|
b = 3
|
|
5
|
+
|
|
6
|
+
print("Hello, World!")
|
|
6
7
|
sum_ab = a + b
|
|
7
8
|
print("Sum:", sum_ab)
|
|
8
9
|
|
|
@@ -12,12 +13,13 @@ if num % 2 == 0:
|
|
|
12
13
|
else:
|
|
13
14
|
print(num, "is odd")
|
|
14
15
|
|
|
15
|
-
# Loop through a list
|
|
16
16
|
fruits = ["apple", "banana", "cherry"]
|
|
17
17
|
for fruit in fruits:
|
|
18
18
|
print(fruit)
|
|
19
19
|
|
|
20
|
-
|
|
20
|
+
|
|
21
|
+
def greet(name: str) -> str:
|
|
21
22
|
return f"Hello, {name}!"
|
|
22
23
|
|
|
23
|
-
|
|
24
|
+
|
|
25
|
+
print(greet("Alice"))
|
|
@@ -21,5 +21,5 @@ print(f"Hello {name} , yoo {relation} is {mom_name}. Myself, I am {name}.")
|
|
|
21
21
|
item = "Apple"
|
|
22
22
|
price = 1.23
|
|
23
23
|
|
|
24
|
-
print(f"Left aligned: {item:<10} | Price: {price:.2f}")
|
|
25
|
-
print(f"
|
|
24
|
+
print(f"Left aligned: {item:<10}".rstrip() + f" | Price: {price:.2f}")
|
|
25
|
+
print(f"name = {name} 🤔")
|
jaclang/tests/test_cli.py
CHANGED
|
@@ -674,7 +674,7 @@ class JacCliTests(TestCase):
|
|
|
674
674
|
self.assertEqual(
|
|
675
675
|
process.returncode, 1, "run command should exit with code 1 on syntax error"
|
|
676
676
|
)
|
|
677
|
-
self.assertIn("Error
|
|
677
|
+
self.assertIn("Error", stderr)
|
|
678
678
|
|
|
679
679
|
# Test build command with syntax error
|
|
680
680
|
process = subprocess.Popen(
|
jaclang/tests/test_language.py
CHANGED
|
@@ -346,7 +346,10 @@ class JacLanguageTests(TestCase):
|
|
|
346
346
|
sys.stdout = sys.__stdout__
|
|
347
347
|
stdout_value = captured_output.getvalue()
|
|
348
348
|
self.assertIn("one level deeperslHello World!", stdout_value)
|
|
349
|
-
self.
|
|
349
|
+
self.assertTrue(
|
|
350
|
+
"module 'pyfunc' from " in stdout_value
|
|
351
|
+
or "module 'jaclang.tests.fixtures.pyfunc' from " in stdout_value
|
|
352
|
+
)
|
|
350
353
|
|
|
351
354
|
def test_deep_outer_imports_from_loc(self) -> None:
|
|
352
355
|
"""Parse micro jac file."""
|
|
@@ -357,7 +360,10 @@ class JacLanguageTests(TestCase):
|
|
|
357
360
|
sys.stdout = sys.__stdout__
|
|
358
361
|
stdout_value = captured_output.getvalue()
|
|
359
362
|
self.assertIn("one level deeperslHello World!", stdout_value)
|
|
360
|
-
self.
|
|
363
|
+
self.assertTrue(
|
|
364
|
+
"module 'jaclang.tests.fixtures.pyfunc' from " in stdout_value
|
|
365
|
+
or "module 'pyfunc' from " in stdout_value
|
|
366
|
+
)
|
|
361
367
|
|
|
362
368
|
def test_has_lambda_goodness(self) -> None:
|
|
363
369
|
"""Test has lambda_goodness."""
|
|
@@ -551,7 +557,7 @@ class JacLanguageTests(TestCase):
|
|
|
551
557
|
),
|
|
552
558
|
prog=JacProgram(),
|
|
553
559
|
).ir_out.unparse()
|
|
554
|
-
self.assertIn("class X {\n with entry {\n a_b = 67;", output)
|
|
560
|
+
self.assertIn("class X {\n with entry {\n let a_b = 67;", output)
|
|
555
561
|
self.assertIn("br = b'Hello\\\\\\\\nWorld'", output)
|
|
556
562
|
self.assertIn(
|
|
557
563
|
"class Circle {\n def init(self: Circle, radius: float", output
|
|
@@ -1604,39 +1610,4 @@ class JacLanguageTests(TestCase):
|
|
|
1604
1610
|
sys.stdout = sys.__stdout__
|
|
1605
1611
|
stdout_value = captured_output.getvalue().split("\n")
|
|
1606
1612
|
self.assertIn("Matched a.b.c Hello Jaseci!", stdout_value[0])
|
|
1607
|
-
|
|
1608
|
-
def test_known_builtins_matches_actual(self) -> None:
|
|
1609
|
-
"""Test that KNOWN_BUILTINS in PyastGenPass matches actual builtins."""
|
|
1610
|
-
from jaclang.compiler.passes.main.pyast_gen_pass import PyastGenPass
|
|
1611
|
-
import jaclang.runtimelib.builtin as builtin_module
|
|
1612
|
-
|
|
1613
|
-
# Get actual builtins from the module (excluding private members)
|
|
1614
|
-
actual_builtins = {
|
|
1615
|
-
name for name in builtin_module.__all__
|
|
1616
|
-
if not name.startswith('_')
|
|
1617
|
-
}
|
|
1618
|
-
|
|
1619
|
-
# Exceptions: builtins that are imported from other sources
|
|
1620
|
-
# - Enum: imported via needs_enum() from standard library's enum module
|
|
1621
|
-
exceptions = {'Enum'}
|
|
1622
|
-
actual_builtins_to_check = actual_builtins - exceptions
|
|
1623
|
-
|
|
1624
|
-
# Get the KNOWN_BUILTINS set from PyastGenPass
|
|
1625
|
-
known_builtins = PyastGenPass.KNOWN_BUILTINS
|
|
1626
|
-
|
|
1627
|
-
# Find missing and extra builtins
|
|
1628
|
-
missing = actual_builtins_to_check - known_builtins
|
|
1629
|
-
extra = known_builtins - actual_builtins_to_check
|
|
1630
|
-
|
|
1631
|
-
# Build error message
|
|
1632
|
-
error_msg = []
|
|
1633
|
-
if missing:
|
|
1634
|
-
error_msg.append(f"Missing from KNOWN_BUILTINS: {sorted(missing)}")
|
|
1635
|
-
if extra:
|
|
1636
|
-
error_msg.append(f"Extra in KNOWN_BUILTINS (not in builtin module): {sorted(extra)}")
|
|
1637
|
-
|
|
1638
|
-
# Assert they match
|
|
1639
|
-
self.assertEqual(
|
|
1640
|
-
known_builtins, actual_builtins_to_check,
|
|
1641
|
-
"\n".join(error_msg) if error_msg else ""
|
|
1642
|
-
)
|
|
1613
|
+
|