diff options
| author | 2026-10-15 21:44:40 +0330 | |
|---|---|---|
| committer | 2026-10-15 21:44:40 +0330 | |
| commit | f3dcfd9805e1bd23b002f648d4391ec397122d9c (patch) | |
| tree | 91acab7da09c9225a2d838791d70e5c2e7db54b9 /tests | |
| parent | merge work/small-oob: bytes test out-of-bounds read (diff) | |
| parent | examples/actors_demo: print the fan-out replies in worker order, not arrival ... (diff) | |
merge work/known-bugs: constant-expression precedence, local const in constant expressions, duplicate case labels, unterminated strings, droppable cycles in one collection, js vm exit, docs, actors_demo orderHEADmain
Diffstat (limited to 'tests')
26 files changed, 94 insertions, 48 deletions
diff --git a/tests/conformance/1-source/string_unterminated.zc b/tests/conformance/1-source/string_unterminated.zc new file mode 100644 index 0000000..aca63d3 --- /dev/null +++ b/tests/conformance/1-source/string_unterminated.zc @@ -0,0 +1,5 @@ +// expect error: zc: line 4: unterminated string literal +// spec 1.4.4 (was appendix b.2.11): a string with no closing quote is reported where it starts +include rt; +fn main() { rt.put_s("never closed); return 0; } +// zc0: skip diff --git a/tests/conformance/3-expressions/const_expr_array_length.zc b/tests/conformance/3-expressions/const_expr_array_length.zc index 07434a9..c6f11e3 100644 --- a/tests/conformance/3-expressions/const_expr_array_length.zc +++ b/tests/conformance/3-expressions/const_expr_array_length.zc @@ -1,4 +1,4 @@ -// expect: 10/ +// expect: 8/ include rt; void pn(int x) { rt.put_n(x); rt.put_c(10); } fn main() { diff --git a/tests/conformance/3-expressions/const_expr_case_label.zc b/tests/conformance/3-expressions/const_expr_case_label.zc index 3f1e781..0c76d4b 100644 --- a/tests/conformance/3-expressions/const_expr_case_label.zc +++ b/tests/conformance/3-expressions/const_expr_case_label.zc @@ -1,9 +1,9 @@ -// expect: nine/ +// expect: seven/ include rt; fn main() { - int k = 9; + int k = 7; switch (k) { - case 1 + 2 * 3: rt.put_s("nine"); + case 1 + 2 * 3: rt.put_s("seven"); default: rt.put_s("other"); } rt.put_c(10); diff --git a/tests/conformance/3-expressions/const_expr_division.zc b/tests/conformance/3-expressions/const_expr_division.zc new file mode 100644 index 0000000..90db20c --- /dev/null +++ b/tests/conformance/3-expressions/const_expr_division.zc @@ -0,0 +1,7 @@ +// expect: 3/-3/2/ +include rt; +void pn(int x) { rt.put_n(x); rt.put_c(10); } +const Z = 6 / 2; +const N = -7 / 2; +const P = 1 + 6 / 3 * 2 - 3; +fn main() { pn(Z); pn(N + 0); pn(P); return 0; } diff --git a/tests/conformance/3-expressions/const_expr_division_by_zero.zc b/tests/conformance/3-expressions/const_expr_division_by_zero.zc new file mode 100644 index 0000000..f1011ff --- /dev/null +++ b/tests/conformance/3-expressions/const_expr_division_by_zero.zc @@ -0,0 +1,4 @@ +// expect error: division by zero in a constant expression +include rt; +const Z = 1 / (2 - 2); +fn main() { return 0; } diff --git a/tests/conformance/3-expressions/const_expr_division_rejected.zc b/tests/conformance/3-expressions/const_expr_division_rejected.zc deleted file mode 100644 index f095247..0000000 --- a/tests/conformance/3-expressions/const_expr_division_rejected.zc +++ /dev/null @@ -1,4 +0,0 @@ -// expect error: expected ';', found '/' -include rt; -const Z = 6 / 2; -fn main() { return 0; } diff --git a/tests/conformance/3-expressions/const_expr_local_const.zc b/tests/conformance/3-expressions/const_expr_local_const.zc new file mode 100644 index 0000000..46a8d55 --- /dev/null +++ b/tests/conformance/3-expressions/const_expr_local_const.zc @@ -0,0 +1,11 @@ +// expect: 5/11/7/ +include rt; +void pn(int x) { rt.put_n(x); rt.put_c(10); } +fn main() { + const n = 5; + const m = n * 2 + 1; + int[m] a; + const int k = 7; + pn(n); pn(len(a)); switch (7) { case k: pn(k); } + return 0; +} diff --git a/tests/conformance/3-expressions/const_expr_local_const_rejected.zc b/tests/conformance/3-expressions/const_expr_local_const_rejected.zc deleted file mode 100644 index edab64e..0000000 --- a/tests/conformance/3-expressions/const_expr_local_const_rejected.zc +++ /dev/null @@ -1,7 +0,0 @@ -// expect error: expected a constant -include rt; -fn main() { - const n = 5; - int[n] a; - return 0; -} diff --git a/tests/conformance/3-expressions/const_expr_modulo.zc b/tests/conformance/3-expressions/const_expr_modulo.zc new file mode 100644 index 0000000..3f32f46 --- /dev/null +++ b/tests/conformance/3-expressions/const_expr_modulo.zc @@ -0,0 +1,6 @@ +// expect: 1/10/ +include rt; +void pn(int x) { rt.put_n(x); rt.put_c(10); } +const Z = 7 % 2; +const Q = 1 + 20 % 7 * 3; +fn main() { pn(Z); pn(Q - 9); return 0; } diff --git a/tests/conformance/3-expressions/const_expr_modulo_rejected.zc b/tests/conformance/3-expressions/const_expr_modulo_rejected.zc deleted file mode 100644 index 4c54ffe..0000000 --- a/tests/conformance/3-expressions/const_expr_modulo_rejected.zc +++ /dev/null @@ -1,4 +0,0 @@ -// expect error: zc: line 3: -include rt; -const Z = 7 % 2; -fn main() { return 0; } diff --git a/tests/conformance/3-expressions/const_expr_neg_not_parens.zc b/tests/conformance/3-expressions/const_expr_neg_not_parens.zc index 6e96bdc..714990a 100644 --- a/tests/conformance/3-expressions/const_expr_neg_not_parens.zc +++ b/tests/conformance/3-expressions/const_expr_neg_not_parens.zc @@ -1,4 +1,4 @@ -// expect: -3/-6/-1/24/ +// expect: -3/-4/-1/24/ include rt; void pn(int x) { rt.put_n(x); rt.put_c(10); } const A = -3; diff --git a/tests/conformance/3-expressions/const_expr_left_to_right.zc b/tests/conformance/3-expressions/const_expr_precedence.zc index 68e26ab..c173959 100644 --- a/tests/conformance/3-expressions/const_expr_left_to_right.zc +++ b/tests/conformance/3-expressions/const_expr_precedence.zc @@ -1,8 +1,9 @@ -// expect: 9/5/7/255/ +// expect: 7/5/7/255/16/ include rt; void pn(int x) { rt.put_n(x); rt.put_c(10); } const X = 1 + 2 * 3; const Y = 10 - 2 - 3; const V = 1 | 2 + 4; const W = ~0 & 255; -fn main() { pn(X); pn(Y); pn(V); pn(W); return 0; } +const S = 1 + 3 << 1 + 1 >> 1 - 1 | 6 & 2; +fn main() { pn(X); pn(Y); pn(V); pn(W); pn(S - 2); return 0; } diff --git a/tests/conformance/3-expressions/const_expr_xor.zc b/tests/conformance/3-expressions/const_expr_xor.zc new file mode 100644 index 0000000..30ca0a7 --- /dev/null +++ b/tests/conformance/3-expressions/const_expr_xor.zc @@ -0,0 +1,6 @@ +// expect: 5/7/ +include rt; +void pn(int x) { rt.put_n(x); rt.put_c(10); } +const Z = 7 ^ 2; +const Q = 1 ^ 2 | 4 & 4; +fn main() { pn(Z); pn(Q); return 0; } diff --git a/tests/conformance/3-expressions/const_expr_xor_rejected.zc b/tests/conformance/3-expressions/const_expr_xor_rejected.zc deleted file mode 100644 index eb1ad25..0000000 --- a/tests/conformance/3-expressions/const_expr_xor_rejected.zc +++ /dev/null @@ -1,4 +0,0 @@ -// expect error: zc: line 3: -include rt; -const Z = 7 ^ 2; -fn main() { return 0; } diff --git a/tests/conformance/4-statements/switch_duplicate_label_rejected.zc b/tests/conformance/4-statements/switch_duplicate_label_rejected.zc new file mode 100644 index 0000000..54f3b56 --- /dev/null +++ b/tests/conformance/4-statements/switch_duplicate_label_rejected.zc @@ -0,0 +1,6 @@ +// expect error: duplicate case label +// spec 4.7.2: a label seen twice in one switch is an error +include rt; +enum color { RED, GREEN }; +fn main() { int k = 1; switch (k) { case RED, GREEN: k = 2; case 2 - 1: k = 3; } return 0; } +// zc0: skip diff --git a/tests/conformance/4-statements/switch_duplicate_labels_first_wins.zc b/tests/conformance/4-statements/switch_duplicate_labels_first_wins.zc deleted file mode 100644 index 67a0204..0000000 --- a/tests/conformance/4-statements/switch_duplicate_labels_first_wins.zc +++ /dev/null @@ -1,11 +0,0 @@ -// expect: first/ -// spec 4.7.2: duplicate labels are not an error, the first matching case in source order runs -include rt; -void pn(int x) { rt.put_n(x); rt.put_c(10); } -void ps(char* s) { rt.put_s(s); rt.put_c(10); } -fn main() { - int k = 4; - switch (k) { case 4: ps("first"); case 4: ps("second"); } - return 0; -} -// zc0: skip diff --git a/tests/conformance/4-statements/switch_label_forms.zc b/tests/conformance/4-statements/switch_label_forms.zc index cfe2712..ef5e33b 100644 --- a/tests/conformance/4-statements/switch_label_forms.zc +++ b/tests/conformance/4-statements/switch_label_forms.zc @@ -1,5 +1,5 @@ // expect: neg/chr/sum/enum/ -// spec 4.7.1 and 3.14: labels are constant expressions (no precedence: 1 + 1 * 3 is 6) +// spec 4.7.1 and 3.14: labels are constant expressions (c precedence: 1 + 1 * 3 is 4) include rt; void pn(int x) { rt.put_n(x); rt.put_c(10); } enum color { RED, GREEN }; @@ -12,5 +12,5 @@ void t(int k) { } rt.put_c(10); } -fn main() { t(-1); t('a'); t(6); t(1); return 0; } +fn main() { t(-1); t('a'); t(4); t(1); return 0; } // zc0: skip diff --git a/tests/conformance/4-statements/switch_same_label_other_switch.zc b/tests/conformance/4-statements/switch_same_label_other_switch.zc new file mode 100644 index 0000000..bb52a94 --- /dev/null +++ b/tests/conformance/4-statements/switch_same_label_other_switch.zc @@ -0,0 +1,5 @@ +// expect: 2/ +// spec 4.7.2: equal labels in two different switches are fine +include rt; +fn main() { int k = 1; switch (k) { case 1: k = 2; } switch (k) { case 1: k = 9; case 2: rt.put_n(k); } rt.put_c(10); return 0; } +// zc0: skip diff --git a/tests/conformance/5-declarations/global_const_expr_init.zc b/tests/conformance/5-declarations/global_const_expr_init.zc index 8a9d30b..64a4d06 100644 --- a/tests/conformance/5-declarations/global_const_expr_init.zc +++ b/tests/conformance/5-declarations/global_const_expr_init.zc @@ -1,5 +1,5 @@ -// expect: 4/ -// spec 5.3.2 and 3.14.1 (left to right: ((1+2)*2)-2) +// expect: 3/ +// spec 5.3.2 and 3.14.1 (c precedence: 1+(2*2)-2) include rt; void pn(int x) { rt.put_n(x); rt.put_c(10); } int g = 1 + 2 * 2 - 2; diff --git a/tests/conformance/6-ownership/drop_gc_cycle.zc b/tests/conformance/6-ownership/drop_gc_cycle.zc index 01db6b8..d31dc6b 100644 --- a/tests/conformance/6-ownership/drop_gc_cycle.zc +++ b/tests/conformance/6-ownership/drop_gc_cycle.zc @@ -1,5 +1,5 @@ -// expect: 0 1 2 2 0/ -// destructors 6.15.3: two unreachable values with drops that reach each other are finalized one per collection (each is in a cycle, so nothing outside it drops first), each exactly once, then freed +// expect: 0 2 2 2 0/ +// destructors 6.15.3: two unreachable values with drops that reach each other are both finalized in one collection (each is in a cycle, so nothing outside it drops first), each exactly once, then freed include rt; int n; word g; diff --git a/tests/conformance/6-ownership/drop_gc_cycle_long.zc b/tests/conformance/6-ownership/drop_gc_cycle_long.zc new file mode 100644 index 0000000..3de3f1e --- /dev/null +++ b/tests/conformance/6-ownership/drop_gc_cycle_long.zc @@ -0,0 +1,24 @@ +// expect: 0 5 15 5 0/ +// destructors 6.15.3: an unreachable cycle of five values with drops is finalized whole by one collection, each value once, then freed +include rt; +int n, sum; +word g; +struct node { node* next; int v; void drop() { n++; sum = sum + this.v; } } +unchecked fn make() { + node* a = rt.new(node); node* p = a; int i; + a.v = 1; + for (i = 2; i <= 5; i++) { node* q = rt.new(node); q.v = i; p.next = q; p = q; } + p.next = a; + g = a; + return 0; +} +fn main() { + make(); + rt.gc(); rt.put_n(n); rt.put_c(32); + g = 0; + rt.gc(); rt.put_n(n); rt.put_c(32); rt.put_n(sum); rt.put_c(32); + rt.gc(); rt.put_n(n); rt.put_c(32); + rt.put_n(rt.dcount); rt.put_c(10); + return 0; +} +// zc0: skip diff --git a/tests/conformance/9-appendix-b/b2_15_duplicate_case.zc b/tests/conformance/9-appendix-b/b2_15_duplicate_case.zc index 63c30ec..e724c63 100644 --- a/tests/conformance/9-appendix-b/b2_15_duplicate_case.zc +++ b/tests/conformance/9-appendix-b/b2_15_duplicate_case.zc @@ -1,5 +1,5 @@ // expect error: duplicate -// spec appendix b.2.15: duplicate case labels are not diagnosed (4.7.2 says they are allowed) +// spec 4.7.2 (was appendix b.2.15): duplicate case labels are an error include rt; void pn(int x) { rt.put_n(x); rt.put_c(10); } fn main() { int k = 1; switch (k) { case 1: pn(1); case 1: pn(2); } return 0; } diff --git a/tests/conformance/9-appendix-b/b2_16_local_const_in_const_expr.zc b/tests/conformance/9-appendix-b/b2_16_local_const_in_const_expr.zc index 70093c9..649321f 100644 --- a/tests/conformance/9-appendix-b/b2_16_local_const_in_const_expr.zc +++ b/tests/conformance/9-appendix-b/b2_16_local_const_in_const_expr.zc @@ -1,5 +1,5 @@ // expect: 5/ -// spec appendix b.2.16 and 3.14.2: a local const is not a constant expression +// spec 3.14.2 (was appendix b.2.16): a local const is a constant expression include rt; void pn(int x) { rt.put_n(x); rt.put_c(10); } fn main() { const n = 5; int[n] a; pn(5); return 0; } diff --git a/tests/conformance/known.txt b/tests/conformance/known.txt index 8eeb0d3..685b089 100644 --- a/tests/conformance/known.txt +++ b/tests/conformance/known.txt @@ -3,8 +3,6 @@ # appendix b.2.8 (a global named in an initializer is its address) is documented behavior per 5.3.2 and 3.14.2: no entry 4-statements/o3_outside_function_ordinary_block.zc zy c top-level o3 { } is rejected; spec 4.10.2 says it is an ordinary block 9-appendix-b/b2_10_recovery_hides_errors.zc zy c appendix b.2.10 confirmed; by design per 8.2 -9-appendix-b/b2_15_duplicate_case.zc zy c appendix b.2.15 confirmed; 4.7.2 says duplicates are allowed -9-appendix-b/b2_16_local_const_in_const_expr.zc zy c appendix b.2.16 confirmed; 3.14.2 documents it 2-types/conv_argument_and_return.zc zc0 b types are read and dropped: no conversion, no sized cut (appendix a) 2-types/conv_assignment_to_float.zc zc0 b types are read and dropped: no conversion, no sized cut (appendix a) 2-types/conv_f32_rounds.zc zc0 b types are read and dropped: no conversion, no sized cut (appendix a) diff --git a/tests/test.sh b/tests/test.sh index c31cfb7..45883d0 100755 --- a/tests/test.sh +++ b/tests/test.sh @@ -733,6 +733,7 @@ s_js() { chk "$(node $T/jsvm/tinyvm.js examples/primes.zc | tail -1)" "widest gap: 72, after 31397" "js vm: primes" chk "$(node $T/jsvm/tinyvm.js tests/programs/growone.zc)" "12 1" "js vm: a block past the initial heap grows the machine" chk "$(node $T/jsvm/tinyvm.js tests/programs/trace.zc 2>&1 | md5sum)" "$(md5sum < tests/programs/trace.expected)" "js vm: backtraces read the return stack through gate op 56" + node $T/jsvm/tinyvm.js tests/programs/trace.zc >/dev/null 2>&1; chk "$?" "2" "js vm: a runtime fault stops the run with exit status 2 (syscall 7), as the native core does" chk "$(node $T/jsvm/tinyvm.js tests/programs/replace_owner.zc)" "$(cat tests/programs/replace_owner.expected)" "js vm: replacement ownership and cleanup" chk "$(node $T/jsvm/tinyvm.js tests/programs/embed.zc | tr '\n' '/')" "hello/world 11 42 5 255 8 -1 0 119 15 5 255 3 98 321 63/" "js vm: embed declarations read their files through node" if sh src/tools/findcc.sh --wasm >/dev/null 2>&1 && command -v wasm-ld >/dev/null; then diff --git a/tests/xref.baseline b/tests/xref.baseline index 2f000af..3011e75 100644 --- a/tests/xref.baseline +++ b/tests/xref.baseline @@ -308,6 +308,8 @@ lkeycap local_bind lkeyn local_bind zc_init lkeys local_bind lkeys_initial +lkval localdecl reserve_locals +lkval_initial lleaf assigncheck embed_bind expr localdecl reassign_free reserve_locals lleaf_initial lname newloc reserve_locals @@ -721,7 +723,7 @@ xc_on xc_init xc_src unit_stdin xcls array_cap array_len array_pop array_push array_resize chk_reset ctx_pop kw_asm kwcall quote_tokens xconst array_dynamic_literal array_literal_tokens bin call chk_reset closure drop_attach heap_box kw_share_value methcall postfix_tail primary printcall unary -xcval array_literal_tokens primary unary +xcval array_literal_tokens bin primary unary xfloat array_dynamic_literal array_len array_literal_tokens array_pop array_push array_resize bin blockexpr call closure drop_attach expr fcoerce femit ftest heap_box incdec kw_cfunc kw_for methcall postfix_tail primary printcall reassign_free ternary unary xgive argcheck args chk_reset xlend assigncheck expr unary |
