aboutsummaryrefslogtreecommitdiff
path: root/tests/conformance/3-expressions
diff options
context:
space:
mode:
Diffstat (limited to 'tests/conformance/3-expressions')
-rw-r--r--tests/conformance/3-expressions/assign_target_address_first.zc11
-rw-r--r--tests/conformance/3-expressions/assign_to_deref_and_field.zc15
-rw-r--r--tests/conformance/3-expressions/assign_to_literal.zc6
-rw-r--r--tests/conformance/3-expressions/assign_to_non_lvalue.zc7
-rw-r--r--tests/conformance/3-expressions/assign_yields_value.zc11
-rw-r--r--tests/conformance/3-expressions/block_expr_array_literal_vs_block.zc13
-rw-r--r--tests/conformance/3-expressions/block_expr_break_rejected.zc6
-rw-r--r--tests/conformance/3-expressions/block_expr_continue_rejected.zc6
-rw-r--r--tests/conformance/3-expressions/block_expr_m_tail_rejected.zc6
-rw-r--r--tests/conformance/3-expressions/block_expr_return_rejected.zc6
-rw-r--r--tests/conformance/3-expressions/block_expr_scope.zc10
-rw-r--r--tests/conformance/3-expressions/block_expr_u_tail.zc9
-rw-r--r--tests/conformance/3-expressions/block_expr_value.zc11
-rw-r--r--tests/conformance/3-expressions/bstr_compare.zc13
-rw-r--r--tests/conformance/3-expressions/bstr_compare_unsigned.zc8
-rw-r--r--tests/conformance/3-expressions/bstr_concat_and_len.zc9
-rw-r--r--tests/conformance/3-expressions/bstr_index_and_range.zc11
-rw-r--r--tests/conformance/3-expressions/bstr_index_not_lvalue.zc7
-rw-r--r--tests/conformance/3-expressions/bstr_mix_compare_error.zc6
-rw-r--r--tests/conformance/3-expressions/bstr_mix_error.zc6
-rw-r--r--tests/conformance/3-expressions/bstr_put_s_writes_bytes.zc7
-rw-r--r--tests/conformance/3-expressions/bstr_results_shared_not_freed.zc9
-rw-r--r--tests/conformance/3-expressions/bstr_slice.zc14
-rw-r--r--tests/conformance/3-expressions/call_23_parameters.zc8
-rw-r--r--tests/conformance/3-expressions/call_24_parameters.zc7
-rw-r--r--tests/conformance/3-expressions/call_24_parameters_prototype.zc6
-rw-r--r--tests/conformance/3-expressions/call_25_parameters_rejected.zc8
-rw-r--r--tests/conformance/3-expressions/call_before_definition.zc5
-rw-r--r--tests/conformance/3-expressions/call_new_without_rt.zc10
-rw-r--r--tests/conformance/3-expressions/call_params_converted_to_float.zc5
-rw-r--r--tests/conformance/3-expressions/call_params_sized_cut.zc6
-rw-r--r--tests/conformance/3-expressions/call_static_and_const.zc6
-rw-r--r--tests/conformance/3-expressions/call_tag_limit.zc4
-rw-r--r--tests/conformance/3-expressions/call_through_value.zc5
-rw-r--r--tests/conformance/3-expressions/call_type_name_as_value.zc4
-rw-r--r--tests/conformance/3-expressions/call_void_bare_return_value_zero.zc5
-rw-r--r--tests/conformance/3-expressions/call_void_value_zero.zc6
-rw-r--r--tests/conformance/3-expressions/call_wrong_arg_count.zc4
-rw-r--r--tests/conformance/3-expressions/cast_as_char_unchanged.zc9
-rw-r--r--tests/conformance/3-expressions/cast_forms.zc14
-rw-r--r--tests/conformance/3-expressions/cast_name_is_paren_expression.zc8
-rw-r--r--tests/conformance/3-expressions/closure_capture_by_reference.zc11
-rw-r--r--tests/conformance/3-expressions/closure_in_o3_rejected.zc9
-rw-r--r--tests/conformance/3-expressions/closure_outlives_creator.zc15
-rw-r--r--tests/conformance/3-expressions/closure_writes_visible_outside.zc11
-rw-r--r--tests/conformance/3-expressions/compound_assign_evaluates_once.zc11
-rw-r--r--tests/conformance/3-expressions/compound_assign_owner_rejected.zc7
-rw-r--r--tests/conformance/3-expressions/compound_assign_yields_value.zc9
-rw-r--r--tests/conformance/3-expressions/const_expr_array_length.zc9
-rw-r--r--tests/conformance/3-expressions/const_expr_case_label.zc12
-rw-r--r--tests/conformance/3-expressions/const_expr_compare_rejected.zc4
-rw-r--r--tests/conformance/3-expressions/const_expr_division_rejected.zc4
-rw-r--r--tests/conformance/3-expressions/const_expr_function_address.zc7
-rw-r--r--tests/conformance/3-expressions/const_expr_global_const_array_length.zc7
-rw-r--r--tests/conformance/3-expressions/const_expr_left_to_right.zc8
-rw-r--r--tests/conformance/3-expressions/const_expr_local_const_rejected.zc7
-rw-r--r--tests/conformance/3-expressions/const_expr_modulo_rejected.zc4
-rw-r--r--tests/conformance/3-expressions/const_expr_names.zc8
-rw-r--r--tests/conformance/3-expressions/const_expr_neg_not_parens.zc8
-rw-r--r--tests/conformance/3-expressions/const_expr_shift.zc6
-rw-r--r--tests/conformance/3-expressions/const_expr_ternary_rejected.zc4
-rw-r--r--tests/conformance/3-expressions/const_expr_xor_rejected.zc4
-rw-r--r--tests/conformance/3-expressions/decr_prefix_postfix.zc11
-rw-r--r--tests/conformance/3-expressions/dyn_array_array_len_cap_const.zc9
-rw-r--r--tests/conformance/3-expressions/dyn_array_cap_at_least_doubles.zc17
-rw-r--r--tests/conformance/3-expressions/dyn_array_const_index_warning.zc8
-rw-r--r--tests/conformance/3-expressions/dyn_array_index_negative.zc11
-rw-r--r--tests/conformance/3-expressions/dyn_array_index_out_of_range.zc12
-rw-r--r--tests/conformance/3-expressions/dyn_array_intrinsics.zc11
-rw-r--r--tests/conformance/3-expressions/dyn_array_len_of_pointer_typecheck.zc7
-rw-r--r--tests/conformance/3-expressions/dyn_array_new_len_cap.zc13
-rw-r--r--tests/conformance/3-expressions/dyn_array_pop_empty.zc10
-rw-r--r--tests/conformance/3-expressions/dyn_array_pop_returns_last.zc10
-rw-r--r--tests/conformance/3-expressions/dyn_array_push_aggregate.zc9
-rw-r--r--tests/conformance/3-expressions/dyn_array_receiver_calls.zc11
-rw-r--r--tests/conformance/3-expressions/dyn_array_resize.zc16
-rw-r--r--tests/conformance/3-expressions/eval_order_arguments.zc9
-rw-r--r--tests/conformance/3-expressions/eval_order_binary_calls.zc10
-rw-r--r--tests/conformance/3-expressions/eval_order_calls_left_to_right.zc11
-rw-r--r--tests/conformance/3-expressions/eval_order_operands.zc10
-rw-r--r--tests/conformance/3-expressions/float_as_keeps_bits.zc10
-rw-r--r--tests/conformance/3-expressions/float_basic_arith.zc12
-rw-r--r--tests/conformance/3-expressions/float_cast_value_and_bits.zc15
-rw-r--r--tests/conformance/3-expressions/float_division_int_stored.zc10
-rw-r--r--tests/conformance/3-expressions/float_int_ops_on_bits.zc12
-rw-r--r--tests/conformance/3-expressions/float_lit_exponent_arith.zc8
-rw-r--r--tests/conformance/3-expressions/float_mixed_comparisons.zc8
-rw-r--r--tests/conformance/3-expressions/float_negate_is_zero_minus.zc14
-rw-r--r--tests/conformance/3-expressions/float_operand_conversion.zc12
-rw-r--r--tests/conformance/3-expressions/float_tracked_through_locals_fields_params.zc20
-rw-r--r--tests/conformance/3-expressions/incr_needs_lvalue.zc7
-rw-r--r--tests/conformance/3-expressions/incr_needs_lvalue_prefix.zc6
-rw-r--r--tests/conformance/3-expressions/incr_on_float_changes_bits.zc10
-rw-r--r--tests/conformance/3-expressions/int_add_wrap.zc15
-rw-r--r--tests/conformance/3-expressions/int_bitwise_and.zc15
-rw-r--r--tests/conformance/3-expressions/int_bitwise_or.zc13
-rw-r--r--tests/conformance/3-expressions/int_bitwise_xor.zc15
-rw-r--r--tests/conformance/3-expressions/int_compare_ge.zc17
-rw-r--r--tests/conformance/3-expressions/int_compare_signed.zc19
-rw-r--r--tests/conformance/3-expressions/int_div_signs.zc19
-rw-r--r--tests/conformance/3-expressions/int_div_zero.zc13
-rw-r--r--tests/conformance/3-expressions/int_logical_or_values.zc17
-rw-r--r--tests/conformance/3-expressions/int_logical_values.zc17
-rw-r--r--tests/conformance/3-expressions/int_min_div_minus1.zc9
-rw-r--r--tests/conformance/3-expressions/int_min_mod_minus1.zc9
-rw-r--r--tests/conformance/3-expressions/int_mod_signs.zc19
-rw-r--r--tests/conformance/3-expressions/int_mod_zero.zc13
-rw-r--r--tests/conformance/3-expressions/int_mul_wrap.zc15
-rw-r--r--tests/conformance/3-expressions/int_shl_count_mod64.zc23
-rw-r--r--tests/conformance/3-expressions/int_shr_arith.zc23
-rw-r--r--tests/conformance/3-expressions/int_sub_wrap.zc13
-rw-r--r--tests/conformance/3-expressions/member_dot_arrow_same.zc14
-rw-r--r--tests/conformance/3-expressions/member_field_wins_over_method.zc12
-rw-r--r--tests/conformance/3-expressions/member_method_call.zc12
-rw-r--r--tests/conformance/3-expressions/member_missing_field_suggestion.zc8
-rw-r--r--tests/conformance/3-expressions/member_two_pointer_levels.zc9
-rw-r--r--tests/conformance/3-expressions/prec_as_binds_tight.zc10
-rw-r--r--tests/conformance/3-expressions/prec_as_then_star.zc7
-rw-r--r--tests/conformance/3-expressions/prec_assign_lower_than_ternary.zc12
-rw-r--r--tests/conformance/3-expressions/prec_assign_right_assoc.zc9
-rw-r--r--tests/conformance/3-expressions/prec_chains.zc55
-rw-r--r--tests/conformance/3-expressions/prec_compound_assign_right.zc9
-rw-r--r--tests/conformance/3-expressions/prec_deref_postfix.zc12
-rw-r--r--tests/conformance/3-expressions/prec_left_add.zc39
-rw-r--r--tests/conformance/3-expressions/prec_left_and.zc41
-rw-r--r--tests/conformance/3-expressions/prec_left_andand.zc41
-rw-r--r--tests/conformance/3-expressions/prec_left_div.zc43
-rw-r--r--tests/conformance/3-expressions/prec_left_eq.zc43
-rw-r--r--tests/conformance/3-expressions/prec_left_ge.zc43
-rw-r--r--tests/conformance/3-expressions/prec_left_gt.zc43
-rw-r--r--tests/conformance/3-expressions/prec_left_le.zc43
-rw-r--r--tests/conformance/3-expressions/prec_left_lt.zc43
-rw-r--r--tests/conformance/3-expressions/prec_left_mod.zc43
-rw-r--r--tests/conformance/3-expressions/prec_left_mul.zc39
-rw-r--r--tests/conformance/3-expressions/prec_left_ne.zc43
-rw-r--r--tests/conformance/3-expressions/prec_left_or.zc41
-rw-r--r--tests/conformance/3-expressions/prec_left_oror.zc41
-rw-r--r--tests/conformance/3-expressions/prec_left_shl.zc43
-rw-r--r--tests/conformance/3-expressions/prec_left_shr.zc43
-rw-r--r--tests/conformance/3-expressions/prec_left_sub.zc43
-rw-r--r--tests/conformance/3-expressions/prec_left_xor.zc41
-rw-r--r--tests/conformance/3-expressions/prec_postfix_incr_value.zc11
-rw-r--r--tests/conformance/3-expressions/prec_postfix_tighter_than_prefix.zc12
-rw-r--r--tests/conformance/3-expressions/prec_table_examples.zc24
-rw-r--r--tests/conformance/3-expressions/prec_ternary_cond_is_binary.zc12
-rw-r--r--tests/conformance/3-expressions/prec_ternary_else_assign.zc13
-rw-r--r--tests/conformance/3-expressions/prec_ternary_middle_full_expr.zc10
-rw-r--r--tests/conformance/3-expressions/prec_unary_vs_binary.zc12
-rw-r--r--tests/conformance/3-expressions/ptr_add_words.zc14
-rw-r--r--tests/conformance/3-expressions/ptr_addr_of_forms.zc24
-rw-r--r--tests/conformance/3-expressions/ptr_deref_struct_is_address.zc11
-rw-r--r--tests/conformance/3-expressions/ptr_difference.zc12
-rw-r--r--tests/conformance/3-expressions/ptr_field_of_new_object.zc7
-rw-r--r--tests/conformance/3-expressions/ptr_index_must_be_number.zc8
-rw-r--r--tests/conformance/3-expressions/ptr_index_new_object.zc6
-rw-r--r--tests/conformance/3-expressions/ptr_index_scaled.zc13
-rw-r--r--tests/conformance/3-expressions/short_circuit.zc15
-rw-r--r--tests/conformance/3-expressions/short_circuit_and_evaluates_right.zc10
-rw-r--r--tests/conformance/3-expressions/short_circuit_or_evaluates_right_when_zero.zc10
-rw-r--r--tests/conformance/3-expressions/short_circuit_or_skips_right.zc10
-rw-r--r--tests/conformance/3-expressions/sizeof_expr_not_run.zc10
-rw-r--r--tests/conformance/3-expressions/sizeof_packed.zc6
-rw-r--r--tests/conformance/3-expressions/ternary_nests_right.zc10
-rw-r--r--tests/conformance/3-expressions/ternary_one_branch_only.zc14
-rw-r--r--tests/conformance/3-expressions/typeof_print.zc9
-rw-r--r--tests/conformance/3-expressions/unary_minus_wraps.zc9
-rw-r--r--tests/conformance/3-expressions/unary_ops_values.zc8
167 files changed, 2340 insertions, 0 deletions
diff --git a/tests/conformance/3-expressions/assign_target_address_first.zc b/tests/conformance/3-expressions/assign_target_address_first.zc
new file mode 100644
index 0000000..5fe6093
--- /dev/null
+++ b/tests/conformance/3-expressions/assign_target_address_first.zc
@@ -0,0 +1,11 @@
+// expect: 2/0/
+include rt;
+void pn(int x) { rt.put_n(x); rt.put_c(10); }
+fn main() {
+ int i = 0;
+ int[3] a = {0, 0, 0};
+ a[i] = i = 2;
+ pn(a[0]); pn(a[2]);
+ return 0;
+}
+// zc0: skip
diff --git a/tests/conformance/3-expressions/assign_to_deref_and_field.zc b/tests/conformance/3-expressions/assign_to_deref_and_field.zc
new file mode 100644
index 0000000..c6af1ca
--- /dev/null
+++ b/tests/conformance/3-expressions/assign_to_deref_and_field.zc
@@ -0,0 +1,15 @@
+// expect: 5/6/
+include rt;
+void pn(int x) { rt.put_n(x); rt.put_c(10); }
+struct pt { int x; int y; }
+fn main() {
+ int[2] a;
+ int* p = a;
+ *p = 5;
+ pt* q = rt.new(pt);
+ q.y = 6;
+ pn(a[0]); pn(q.y);
+ rt.free(q);
+ return 0;
+}
+// zc0: skip
diff --git a/tests/conformance/3-expressions/assign_to_literal.zc b/tests/conformance/3-expressions/assign_to_literal.zc
new file mode 100644
index 0000000..d204ff3
--- /dev/null
+++ b/tests/conformance/3-expressions/assign_to_literal.zc
@@ -0,0 +1,6 @@
+// expect error: this can't be assigned to
+include rt;
+fn main() {
+ 3 = 4;
+ return 0;
+}
diff --git a/tests/conformance/3-expressions/assign_to_non_lvalue.zc b/tests/conformance/3-expressions/assign_to_non_lvalue.zc
new file mode 100644
index 0000000..7436a12
--- /dev/null
+++ b/tests/conformance/3-expressions/assign_to_non_lvalue.zc
@@ -0,0 +1,7 @@
+// expect error: this can't be assigned to
+include rt;
+fn main() {
+ int a = 1;
+ (a + 1) = 5;
+ return 0;
+}
diff --git a/tests/conformance/3-expressions/assign_yields_value.zc b/tests/conformance/3-expressions/assign_yields_value.zc
new file mode 100644
index 0000000..9796283
--- /dev/null
+++ b/tests/conformance/3-expressions/assign_yields_value.zc
@@ -0,0 +1,11 @@
+// expect: 9/9/
+include rt;
+void pn(int x) { rt.put_n(x); rt.put_c(10); }
+fn main() {
+ int a, b;
+ b = (a = 4) + 5;
+ pn(b);
+ int[2] arr;
+ pn(arr[1] = 9);
+ return 0;
+}
diff --git a/tests/conformance/3-expressions/block_expr_array_literal_vs_block.zc b/tests/conformance/3-expressions/block_expr_array_literal_vs_block.zc
new file mode 100644
index 0000000..7596210
--- /dev/null
+++ b/tests/conformance/3-expressions/block_expr_array_literal_vs_block.zc
@@ -0,0 +1,13 @@
+// expect: 3/5/0/
+include rt;
+void pn(int x) { rt.put_n(x); rt.put_c(10); }
+fn main() {
+ int[] a = { 1, 2, 3 };
+ pn(len(a));
+ int[] b = { 5 };
+ pn(b[0]);
+ let c = { 5; };
+ pn(c);
+ return 0;
+}
+// zc0: skip
diff --git a/tests/conformance/3-expressions/block_expr_break_rejected.zc b/tests/conformance/3-expressions/block_expr_break_rejected.zc
new file mode 100644
index 0000000..1cce727
--- /dev/null
+++ b/tests/conformance/3-expressions/block_expr_break_rejected.zc
@@ -0,0 +1,6 @@
+// expect error: break can't leave
+include rt;
+fn main() {
+ while (1) { let v = { break; 1 }; }
+ return 0;
+}
diff --git a/tests/conformance/3-expressions/block_expr_continue_rejected.zc b/tests/conformance/3-expressions/block_expr_continue_rejected.zc
new file mode 100644
index 0000000..6a4c27a
--- /dev/null
+++ b/tests/conformance/3-expressions/block_expr_continue_rejected.zc
@@ -0,0 +1,6 @@
+// expect error: continue can't leave
+include rt;
+fn main() {
+ while (1) { let v = { continue; 1 }; }
+ return 0;
+}
diff --git a/tests/conformance/3-expressions/block_expr_m_tail_rejected.zc b/tests/conformance/3-expressions/block_expr_m_tail_rejected.zc
new file mode 100644
index 0000000..9986568
--- /dev/null
+++ b/tests/conformance/3-expressions/block_expr_m_tail_rejected.zc
@@ -0,0 +1,6 @@
+// expect error: t: has to be u to be handed up as the block's value
+include rt;
+fn main() {
+ int* p = { int* t = rt.new(int); t };
+ return 0;
+}
diff --git a/tests/conformance/3-expressions/block_expr_return_rejected.zc b/tests/conformance/3-expressions/block_expr_return_rejected.zc
new file mode 100644
index 0000000..4300368
--- /dev/null
+++ b/tests/conformance/3-expressions/block_expr_return_rejected.zc
@@ -0,0 +1,6 @@
+// expect error: return can't leave a block expression
+include rt;
+fn main() {
+ let v = { return 3; };
+ return 0;
+}
diff --git a/tests/conformance/3-expressions/block_expr_scope.zc b/tests/conformance/3-expressions/block_expr_scope.zc
new file mode 100644
index 0000000..0ac644a
--- /dev/null
+++ b/tests/conformance/3-expressions/block_expr_scope.zc
@@ -0,0 +1,10 @@
+// expect: 8/
+include rt;
+void pn(int x) { rt.put_n(x); rt.put_c(10); }
+fn main() {
+ int t = 8;
+ let v = { int t = 100; t + 1 };
+ pn(t);
+ return 0;
+}
+// zc0: skip
diff --git a/tests/conformance/3-expressions/block_expr_u_tail.zc b/tests/conformance/3-expressions/block_expr_u_tail.zc
new file mode 100644
index 0000000..61c4f03
--- /dev/null
+++ b/tests/conformance/3-expressions/block_expr_u_tail.zc
@@ -0,0 +1,9 @@
+// expect: 4/
+include rt;
+void pn(int x) { rt.put_n(x); rt.put_c(10); }
+fn main() {
+ int* p = { int* t = rt.new(int); *t = 4; u*t };
+ pn(*p);
+ return 0;
+}
+// zc0: skip
diff --git a/tests/conformance/3-expressions/block_expr_value.zc b/tests/conformance/3-expressions/block_expr_value.zc
new file mode 100644
index 0000000..b6c973e
--- /dev/null
+++ b/tests/conformance/3-expressions/block_expr_value.zc
@@ -0,0 +1,11 @@
+// expect: 49/0/
+include rt;
+void pn(int x) { rt.put_n(x); rt.put_c(10); }
+fn main() {
+ let sq = { let t = 3 + 4; t * t };
+ pn(sq);
+ let z = { let q = 1; q = q + 1; };
+ pn(z);
+ return 0;
+}
+// zc0: skip
diff --git a/tests/conformance/3-expressions/bstr_compare.zc b/tests/conformance/3-expressions/bstr_compare.zc
new file mode 100644
index 0000000..de4abd3
--- /dev/null
+++ b/tests/conformance/3-expressions/bstr_compare.zc
@@ -0,0 +1,13 @@
+// expect: 1/1/0/1/1/0/1/
+include rt;
+void pn(int x) { rt.put_n(x); rt.put_c(10); }
+fn main() {
+ pn(b"abc" < b"abd");
+ pn(b"ab" < b"abc");
+ pn(b"abc" < b"abc");
+ pn(b"abc" <= b"abc");
+ pn(b"abc" == b"abc");
+ pn(b"abc" != b"abc");
+ pn(b"b" > b"abc");
+ return 0;
+}
diff --git a/tests/conformance/3-expressions/bstr_compare_unsigned.zc b/tests/conformance/3-expressions/bstr_compare_unsigned.zc
new file mode 100644
index 0000000..df936d6
--- /dev/null
+++ b/tests/conformance/3-expressions/bstr_compare_unsigned.zc
@@ -0,0 +1,8 @@
+// expect: 1/0/
+include rt;
+void pn(int x) { rt.put_n(x); rt.put_c(10); }
+fn main() {
+ pn(b"é" > b"z");
+ pn(b"é" < b"z");
+ return 0;
+}
diff --git a/tests/conformance/3-expressions/bstr_concat_and_len.zc b/tests/conformance/3-expressions/bstr_concat_and_len.zc
new file mode 100644
index 0000000..4bdc8c5
--- /dev/null
+++ b/tests/conformance/3-expressions/bstr_concat_and_len.zc
@@ -0,0 +1,9 @@
+// expect: 5/abcde/
+include rt;
+void pn(int x) { rt.put_n(x); rt.put_c(10); }
+fn main() {
+ bstr s = b"abc" + b"de";
+ pn(len(s));
+ rt.put_s(s); rt.put_c(10);
+ return 0;
+}
diff --git a/tests/conformance/3-expressions/bstr_index_and_range.zc b/tests/conformance/3-expressions/bstr_index_and_range.zc
new file mode 100644
index 0000000..84b1b83
--- /dev/null
+++ b/tests/conformance/3-expressions/bstr_index_and_range.zc
@@ -0,0 +1,11 @@
+// expect: 98/0/0/0/
+include rt;
+void pn(int x) { rt.put_n(x); rt.put_c(10); }
+fn main() {
+ bstr s = b"abc";
+ pn(s[1]);
+ pn(s[3]);
+ pn(s[5]);
+ pn(s[-1]);
+ return 0;
+}
diff --git a/tests/conformance/3-expressions/bstr_index_not_lvalue.zc b/tests/conformance/3-expressions/bstr_index_not_lvalue.zc
new file mode 100644
index 0000000..71762e4
--- /dev/null
+++ b/tests/conformance/3-expressions/bstr_index_not_lvalue.zc
@@ -0,0 +1,7 @@
+// expect error: zc: line 5:
+include rt;
+fn main() {
+ bstr s = b"abc";
+ s[0] = 65;
+ return 0;
+}
diff --git a/tests/conformance/3-expressions/bstr_mix_compare_error.zc b/tests/conformance/3-expressions/bstr_mix_compare_error.zc
new file mode 100644
index 0000000..e8acc38
--- /dev/null
+++ b/tests/conformance/3-expressions/bstr_mix_compare_error.zc
@@ -0,0 +1,6 @@
+// expect error: a byte string needs a byte string on the other side
+include rt;
+fn main() {
+ int x = (b"a" == 5);
+ return 0;
+}
diff --git a/tests/conformance/3-expressions/bstr_mix_error.zc b/tests/conformance/3-expressions/bstr_mix_error.zc
new file mode 100644
index 0000000..08daf37
--- /dev/null
+++ b/tests/conformance/3-expressions/bstr_mix_error.zc
@@ -0,0 +1,6 @@
+// expect error: a byte string needs a byte string on the other side
+include rt;
+fn main() {
+ bstr s = b"a" + "b";
+ return 0;
+}
diff --git a/tests/conformance/3-expressions/bstr_put_s_writes_bytes.zc b/tests/conformance/3-expressions/bstr_put_s_writes_bytes.zc
new file mode 100644
index 0000000..bf36611
--- /dev/null
+++ b/tests/conformance/3-expressions/bstr_put_s_writes_bytes.zc
@@ -0,0 +1,7 @@
+// expect: hi there/
+include rt;
+fn main() {
+ rt.put_s(b"hi there");
+ rt.put_c(10);
+ return 0;
+}
diff --git a/tests/conformance/3-expressions/bstr_results_shared_not_freed.zc b/tests/conformance/3-expressions/bstr_results_shared_not_freed.zc
new file mode 100644
index 0000000..ef32171
--- /dev/null
+++ b/tests/conformance/3-expressions/bstr_results_shared_not_freed.zc
@@ -0,0 +1,9 @@
+// expect: 4/
+include rt;
+void pn(int x) { rt.put_n(x); rt.put_c(10); }
+fn main() {
+ bstr s = b"ab" + b"cd";
+ rt.free(s);
+ pn(len(s));
+ return 0;
+}
diff --git a/tests/conformance/3-expressions/bstr_slice.zc b/tests/conformance/3-expressions/bstr_slice.zc
new file mode 100644
index 0000000..5fa20e5
--- /dev/null
+++ b/tests/conformance/3-expressions/bstr_slice.zc
@@ -0,0 +1,14 @@
+// expect: el/he/lo//0//
+include rt;
+void pn(int x) { rt.put_n(x); rt.put_c(10); }
+fn main() {
+ bstr t = b"hello";
+ rt.put_s(t[1:3]); rt.put_c(10);
+ rt.put_s(t[-5:2]); rt.put_c(10);
+ rt.put_s(t[3:100]); rt.put_c(10);
+ bstr e = t[4:2];
+ rt.put_s(e); rt.put_c(10);
+ pn(len(e));
+ rt.put_s(t[2:2]); rt.put_c(10);
+ return 0;
+}
diff --git a/tests/conformance/3-expressions/call_23_parameters.zc b/tests/conformance/3-expressions/call_23_parameters.zc
new file mode 100644
index 0000000..d53d037
--- /dev/null
+++ b/tests/conformance/3-expressions/call_23_parameters.zc
@@ -0,0 +1,8 @@
+// expect: 276/
+// spec 3.11.3: at most 24 parameters (23 is under the limit)
+include rt;
+void pn(int x) { rt.put_n(x); rt.put_c(10); }
+int s23(int a1, int a2, int a3, int a4, int a5, int a6, int a7, int a8, int a9, int a10, int a11, int a12, int a13, int a14, int a15, int a16, int a17, int a18, int a19, int a20, int a21, int a22, int a23) {
+ return a1 + a2 + a3 + a4 + a5 + a6 + a7 + a8 + a9 + a10 + a11 + a12 + a13 + a14 + a15 + a16 + a17 + a18 + a19 + a20 + a21 + a22 + a23;
+}
+fn main() { pn(s23(1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23)); return 0; }
diff --git a/tests/conformance/3-expressions/call_24_parameters.zc b/tests/conformance/3-expressions/call_24_parameters.zc
new file mode 100644
index 0000000..4ebe585
--- /dev/null
+++ b/tests/conformance/3-expressions/call_24_parameters.zc
@@ -0,0 +1,7 @@
+// expect: 300/
+include rt;
+void pn(int x) { rt.put_n(x); rt.put_c(10); }
+int s24(int a1, int a2, int a3, int a4, int a5, int a6, int a7, int a8, int a9, int a10, int a11, int a12, int a13, int a14, int a15, int a16, int a17, int a18, int a19, int a20, int a21, int a22, int a23, int a24) {
+ return a1 + a2 + a3 + a4 + a5 + a6 + a7 + a8 + a9 + a10 + a11 + a12 + a13 + a14 + a15 + a16 + a17 + a18 + a19 + a20 + a21 + a22 + a23 + a24;
+}
+fn main() { pn(s24(1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24)); return 0; }
diff --git a/tests/conformance/3-expressions/call_24_parameters_prototype.zc b/tests/conformance/3-expressions/call_24_parameters_prototype.zc
new file mode 100644
index 0000000..85542aa
--- /dev/null
+++ b/tests/conformance/3-expressions/call_24_parameters_prototype.zc
@@ -0,0 +1,6 @@
+// expect: 0/
+// spec 5.2.2: up to 24 parameters (a prototype)
+include rt;
+void pn(int x) { rt.put_n(x); rt.put_c(10); }
+int s24(int a1, int a2, int a3, int a4, int a5, int a6, int a7, int a8, int a9, int a10, int a11, int a12, int a13, int a14, int a15, int a16, int a17, int a18, int a19, int a20, int a21, int a22, int a23, int a24);
+fn main() { pn(0); return 0; }
diff --git a/tests/conformance/3-expressions/call_25_parameters_rejected.zc b/tests/conformance/3-expressions/call_25_parameters_rejected.zc
new file mode 100644
index 0000000..d8b8896
--- /dev/null
+++ b/tests/conformance/3-expressions/call_25_parameters_rejected.zc
@@ -0,0 +1,8 @@
+// expect error: too many parameters
+// spec 3.11.3 and 5.2.2: at most 24 parameters
+include rt;
+void pn(int x) { rt.put_n(x); rt.put_c(10); }
+int s25(int a1, int a2, int a3, int a4, int a5, int a6, int a7, int a8, int a9, int a10, int a11, int a12, int a13, int a14, int a15, int a16, int a17, int a18, int a19, int a20, int a21, int a22, int a23, int a24, int a25) {
+ return a1;
+}
+fn main() { return 0; }
diff --git a/tests/conformance/3-expressions/call_before_definition.zc b/tests/conformance/3-expressions/call_before_definition.zc
new file mode 100644
index 0000000..0442130
--- /dev/null
+++ b/tests/conformance/3-expressions/call_before_definition.zc
@@ -0,0 +1,5 @@
+// expect: 5/
+include rt;
+void pn(int x) { rt.put_n(x); rt.put_c(10); }
+fn main() { pn(later(2, 3)); return 0; }
+int later(int a, int b) { return a + b; }
diff --git a/tests/conformance/3-expressions/call_new_without_rt.zc b/tests/conformance/3-expressions/call_new_without_rt.zc
new file mode 100644
index 0000000..397ba89
--- /dev/null
+++ b/tests/conformance/3-expressions/call_new_without_rt.zc
@@ -0,0 +1,10 @@
+// expect: 5/
+include rt;
+void pn(int x) { rt.put_n(x); rt.put_c(10); }
+fn main() {
+ int* p = new(int);
+ *p = 5;
+ pn(*p);
+ return 0;
+}
+// zc0: skip
diff --git a/tests/conformance/3-expressions/call_params_converted_to_float.zc b/tests/conformance/3-expressions/call_params_converted_to_float.zc
new file mode 100644
index 0000000..04219a9
--- /dev/null
+++ b/tests/conformance/3-expressions/call_params_converted_to_float.zc
@@ -0,0 +1,5 @@
+// expect: 4.000000/
+include rt;
+fn pf(x) { asm { x @ #1220 } rt.put_c(10); return 0; }
+float dbl(float x) { return x * 2; }
+fn main() { pf(dbl(2)); return 0; }
diff --git a/tests/conformance/3-expressions/call_params_sized_cut.zc b/tests/conformance/3-expressions/call_params_sized_cut.zc
new file mode 100644
index 0000000..ed71cbe
--- /dev/null
+++ b/tests/conformance/3-expressions/call_params_sized_cut.zc
@@ -0,0 +1,6 @@
+// expect: 44/-56/
+include rt;
+void pn(int x) { rt.put_n(x); rt.put_c(10); }
+int a(u8 x) { return x; }
+int b(i8 x) { return x; }
+fn main() { pn(a(300)); pn(b(200)); return 0; }
diff --git a/tests/conformance/3-expressions/call_static_and_const.zc b/tests/conformance/3-expressions/call_static_and_const.zc
new file mode 100644
index 0000000..d711488
--- /dev/null
+++ b/tests/conformance/3-expressions/call_static_and_const.zc
@@ -0,0 +1,6 @@
+// expect: 7/24/
+include rt;
+void pn(int x) { rt.put_n(x); rt.put_c(10); }
+struct S { const MAX = 24; static fn seven() { return 7; } }
+fn main() { pn(S.seven()); pn(S.MAX); return 0; }
+// zc0: skip
diff --git a/tests/conformance/3-expressions/call_tag_limit.zc b/tests/conformance/3-expressions/call_tag_limit.zc
new file mode 100644
index 0000000..2ffd802
--- /dev/null
+++ b/tests/conformance/3-expressions/call_tag_limit.zc
@@ -0,0 +1,4 @@
+// expect error: only the first 12 parameters can be tagged
+include rt;
+void f(int*.m a1, int*.m a2, int*.m a3, int*.m a4, int*.m a5, int*.m a6, int*.m a7, int*.m a8, int*.m a9, int*.m a10, int*.m a11, int*.m a12, int*.m a13) { }
+fn main() { return 0; }
diff --git a/tests/conformance/3-expressions/call_through_value.zc b/tests/conformance/3-expressions/call_through_value.zc
new file mode 100644
index 0000000..98a5c34
--- /dev/null
+++ b/tests/conformance/3-expressions/call_through_value.zc
@@ -0,0 +1,5 @@
+// expect: 9/
+include rt;
+void pn(int x) { rt.put_n(x); rt.put_c(10); }
+int sq(int x) { return x * x; }
+fn main() { int(int) f = sq; pn(f(3)); return 0; }
diff --git a/tests/conformance/3-expressions/call_type_name_as_value.zc b/tests/conformance/3-expressions/call_type_name_as_value.zc
new file mode 100644
index 0000000..75c50d0
--- /dev/null
+++ b/tests/conformance/3-expressions/call_type_name_as_value.zc
@@ -0,0 +1,4 @@
+// expect error: S: is a type, not a value
+include rt;
+struct S { int a; }
+fn main() { rt.put_n(S); return 0; }
diff --git a/tests/conformance/3-expressions/call_void_bare_return_value_zero.zc b/tests/conformance/3-expressions/call_void_bare_return_value_zero.zc
new file mode 100644
index 0000000..3a437c9
--- /dev/null
+++ b/tests/conformance/3-expressions/call_void_bare_return_value_zero.zc
@@ -0,0 +1,5 @@
+// expect: 0/
+include rt;
+void pn(int x) { rt.put_n(x); rt.put_c(10); }
+void f() { return; }
+fn main() { pn(f()); return 0; }
diff --git a/tests/conformance/3-expressions/call_void_value_zero.zc b/tests/conformance/3-expressions/call_void_value_zero.zc
new file mode 100644
index 0000000..9fab2d4
--- /dev/null
+++ b/tests/conformance/3-expressions/call_void_value_zero.zc
@@ -0,0 +1,6 @@
+// expect: 0/
+include rt;
+void pn(int x) { rt.put_n(x); rt.put_c(10); }
+int sink;
+void f() { sink = 1; }
+fn main() { pn(f()); return 0; }
diff --git a/tests/conformance/3-expressions/call_wrong_arg_count.zc b/tests/conformance/3-expressions/call_wrong_arg_count.zc
new file mode 100644
index 0000000..8c87e43
--- /dev/null
+++ b/tests/conformance/3-expressions/call_wrong_arg_count.zc
@@ -0,0 +1,4 @@
+// expect error: f: wrong number of arguments
+include rt;
+int f(int a, int b) { return a + b; }
+fn main() { rt.put_n(f(1, 2, 3)); return 0; }
diff --git a/tests/conformance/3-expressions/cast_as_char_unchanged.zc b/tests/conformance/3-expressions/cast_as_char_unchanged.zc
new file mode 100644
index 0000000..3b54628
--- /dev/null
+++ b/tests/conformance/3-expressions/cast_as_char_unchanged.zc
@@ -0,0 +1,9 @@
+// expect: 300/44/
+include rt;
+void pn(int x) { rt.put_n(x); rt.put_c(10); }
+fn main() {
+ int x = 300;
+ pn(x as char);
+ pn(x as u8);
+ return 0;
+}
diff --git a/tests/conformance/3-expressions/cast_forms.zc b/tests/conformance/3-expressions/cast_forms.zc
new file mode 100644
index 0000000..d8ef2bf
--- /dev/null
+++ b/tests/conformance/3-expressions/cast_forms.zc
@@ -0,0 +1,14 @@
+// expect: 2/3/44/3/
+include rt;
+void pn(int x) { rt.put_n(x); rt.put_c(10); }
+fn main() {
+ float f = 2.9;
+ pn((int)f);
+ char* s = "abc";
+ pn(rt.len_w((char*)s));
+ pn((u8)300);
+ int myv = 3;
+ pn((myv));
+ return 0;
+}
+// zc0: skip
diff --git a/tests/conformance/3-expressions/cast_name_is_paren_expression.zc b/tests/conformance/3-expressions/cast_name_is_paren_expression.zc
new file mode 100644
index 0000000..de9b281
--- /dev/null
+++ b/tests/conformance/3-expressions/cast_name_is_paren_expression.zc
@@ -0,0 +1,8 @@
+// expect: 6/
+include rt;
+void pn(int x) { rt.put_n(x); rt.put_c(10); }
+fn main() {
+ int myv = 3;
+ pn((myv) * 2);
+ return 0;
+}
diff --git a/tests/conformance/3-expressions/closure_capture_by_reference.zc b/tests/conformance/3-expressions/closure_capture_by_reference.zc
new file mode 100644
index 0000000..3b4163f
--- /dev/null
+++ b/tests/conformance/3-expressions/closure_capture_by_reference.zc
@@ -0,0 +1,11 @@
+// expect: 21/
+include rt;
+void pn(int x) { rt.put_n(x); rt.put_c(10); }
+fn main() {
+ int k = 10;
+ let cl = fn(x) { return x + k; };
+ k = 20;
+ pn(cl(1));
+ return 0;
+}
+// zc0: skip
diff --git a/tests/conformance/3-expressions/closure_in_o3_rejected.zc b/tests/conformance/3-expressions/closure_in_o3_rejected.zc
new file mode 100644
index 0000000..66bb267
--- /dev/null
+++ b/tests/conformance/3-expressions/closure_in_o3_rejected.zc
@@ -0,0 +1,9 @@
+// expect error: closures can't be made inside an o3 region
+include rt;
+fn main() {
+ o3 {
+ int k = 1;
+ int(int) f = fn(int x) { return x + k; };
+ }
+ return 0;
+}
diff --git a/tests/conformance/3-expressions/closure_outlives_creator.zc b/tests/conformance/3-expressions/closure_outlives_creator.zc
new file mode 100644
index 0000000..82e88d7
--- /dev/null
+++ b/tests/conformance/3-expressions/closure_outlives_creator.zc
@@ -0,0 +1,15 @@
+// expect: 11/12/
+include rt;
+void pn(int x) { rt.put_n(x); rt.put_c(10); }
+.u counter() {
+ int c = 10;
+ let f = fn() { c++; return c; };
+ return u*f;
+}
+fn main() {
+ let ctr = counter();
+ pn(ctr());
+ pn(ctr());
+ return 0;
+}
+// zc0: skip
diff --git a/tests/conformance/3-expressions/closure_writes_visible_outside.zc b/tests/conformance/3-expressions/closure_writes_visible_outside.zc
new file mode 100644
index 0000000..aac5390
--- /dev/null
+++ b/tests/conformance/3-expressions/closure_writes_visible_outside.zc
@@ -0,0 +1,11 @@
+// expect: 3/
+include rt;
+void pn(int x) { rt.put_n(x); rt.put_c(10); }
+fn main() {
+ int n = 0;
+ let inc = fn() { n++; return n; };
+ inc(); inc(); inc();
+ pn(n);
+ return 0;
+}
+// zc0: skip
diff --git a/tests/conformance/3-expressions/compound_assign_evaluates_once.zc b/tests/conformance/3-expressions/compound_assign_evaluates_once.zc
new file mode 100644
index 0000000..db8ebc5
--- /dev/null
+++ b/tests/conformance/3-expressions/compound_assign_evaluates_once.zc
@@ -0,0 +1,11 @@
+// expect: 1/15/
+include rt;
+void pn(int x) { rt.put_n(x); rt.put_c(10); }
+fn main() {
+ int i = 0;
+ int[3] a = {10, 20, 30};
+ a[i++] += 5;
+ pn(i); pn(a[0]);
+ return 0;
+}
+// zc0: skip
diff --git a/tests/conformance/3-expressions/compound_assign_owner_rejected.zc b/tests/conformance/3-expressions/compound_assign_owner_rejected.zc
new file mode 100644
index 0000000..5c080dc
--- /dev/null
+++ b/tests/conformance/3-expressions/compound_assign_owner_rejected.zc
@@ -0,0 +1,7 @@
+// expect error: owns an object; compound assignment would lose it
+include rt;
+fn main() {
+ int* p = rt.new(int);
+ p += 1;
+ return 0;
+}
diff --git a/tests/conformance/3-expressions/compound_assign_yields_value.zc b/tests/conformance/3-expressions/compound_assign_yields_value.zc
new file mode 100644
index 0000000..2bff56f
--- /dev/null
+++ b/tests/conformance/3-expressions/compound_assign_yields_value.zc
@@ -0,0 +1,9 @@
+// expect: 12/12/
+include rt;
+void pn(int x) { rt.put_n(x); rt.put_c(10); }
+fn main() {
+ int a = 7;
+ pn(a += 5);
+ pn(a);
+ return 0;
+}
diff --git a/tests/conformance/3-expressions/const_expr_array_length.zc b/tests/conformance/3-expressions/const_expr_array_length.zc
new file mode 100644
index 0000000..07434a9
--- /dev/null
+++ b/tests/conformance/3-expressions/const_expr_array_length.zc
@@ -0,0 +1,9 @@
+// expect: 10/
+include rt;
+void pn(int x) { rt.put_n(x); rt.put_c(10); }
+fn main() {
+ int[2 + 3 * 2] a;
+ pn(sizeof(a));
+ return 0;
+}
+// zc0: skip
diff --git a/tests/conformance/3-expressions/const_expr_case_label.zc b/tests/conformance/3-expressions/const_expr_case_label.zc
new file mode 100644
index 0000000..3f1e781
--- /dev/null
+++ b/tests/conformance/3-expressions/const_expr_case_label.zc
@@ -0,0 +1,12 @@
+// expect: nine/
+include rt;
+fn main() {
+ int k = 9;
+ switch (k) {
+ case 1 + 2 * 3: rt.put_s("nine");
+ default: rt.put_s("other");
+ }
+ rt.put_c(10);
+ return 0;
+}
+// zc0: skip
diff --git a/tests/conformance/3-expressions/const_expr_compare_rejected.zc b/tests/conformance/3-expressions/const_expr_compare_rejected.zc
new file mode 100644
index 0000000..a37fb78
--- /dev/null
+++ b/tests/conformance/3-expressions/const_expr_compare_rejected.zc
@@ -0,0 +1,4 @@
+// expect error: zc: line 3:
+include rt;
+const Z = 1 < 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
new file mode 100644
index 0000000..f095247
--- /dev/null
+++ b/tests/conformance/3-expressions/const_expr_division_rejected.zc
@@ -0,0 +1,4 @@
+// expect error: expected ';', found '/'
+include rt;
+const Z = 6 / 2;
+fn main() { return 0; }
diff --git a/tests/conformance/3-expressions/const_expr_function_address.zc b/tests/conformance/3-expressions/const_expr_function_address.zc
new file mode 100644
index 0000000..b444722
--- /dev/null
+++ b/tests/conformance/3-expressions/const_expr_function_address.zc
@@ -0,0 +1,7 @@
+// expect: 1/
+include rt;
+void pn(int x) { rt.put_n(x); rt.put_c(10); }
+int f() { return 1; }
+const FA = f;
+fn main() { fn() p = FA; pn(p()); return 0; }
+// zc0: skip
diff --git a/tests/conformance/3-expressions/const_expr_global_const_array_length.zc b/tests/conformance/3-expressions/const_expr_global_const_array_length.zc
new file mode 100644
index 0000000..1b918ed
--- /dev/null
+++ b/tests/conformance/3-expressions/const_expr_global_const_array_length.zc
@@ -0,0 +1,7 @@
+// expect: 4/
+include rt;
+void pn(int x) { rt.put_n(x); rt.put_c(10); }
+const N = 4;
+int[N] garr;
+fn main() { pn(sizeof(garr)); return 0; }
+// zc0: skip
diff --git a/tests/conformance/3-expressions/const_expr_left_to_right.zc b/tests/conformance/3-expressions/const_expr_left_to_right.zc
new file mode 100644
index 0000000..68e26ab
--- /dev/null
+++ b/tests/conformance/3-expressions/const_expr_left_to_right.zc
@@ -0,0 +1,8 @@
+// expect: 9/5/7/255/
+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; }
diff --git a/tests/conformance/3-expressions/const_expr_local_const_rejected.zc b/tests/conformance/3-expressions/const_expr_local_const_rejected.zc
new file mode 100644
index 0000000..edab64e
--- /dev/null
+++ b/tests/conformance/3-expressions/const_expr_local_const_rejected.zc
@@ -0,0 +1,7 @@
+// 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_rejected.zc b/tests/conformance/3-expressions/const_expr_modulo_rejected.zc
new file mode 100644
index 0000000..4c54ffe
--- /dev/null
+++ b/tests/conformance/3-expressions/const_expr_modulo_rejected.zc
@@ -0,0 +1,4 @@
+// expect error: zc: line 3:
+include rt;
+const Z = 7 % 2;
+fn main() { return 0; }
diff --git a/tests/conformance/3-expressions/const_expr_names.zc b/tests/conformance/3-expressions/const_expr_names.zc
new file mode 100644
index 0000000..b9fa851
--- /dev/null
+++ b/tests/conformance/3-expressions/const_expr_names.zc
@@ -0,0 +1,8 @@
+// expect: 5/7/
+include rt;
+void pn(int x) { rt.put_n(x); rt.put_c(10); }
+enum { EA = 2, EB };
+const K = EA + EB;
+const L = K + 2;
+fn main() { pn(K); pn(L); return 0; }
+// zc0: skip
diff --git a/tests/conformance/3-expressions/const_expr_neg_not_parens.zc b/tests/conformance/3-expressions/const_expr_neg_not_parens.zc
new file mode 100644
index 0000000..6e96bdc
--- /dev/null
+++ b/tests/conformance/3-expressions/const_expr_neg_not_parens.zc
@@ -0,0 +1,8 @@
+// expect: -3/-6/-1/24/
+include rt;
+void pn(int x) { rt.put_n(x); rt.put_c(10); }
+const A = -3;
+const B = -(1 + 2 * 3) + 3;
+const C = ~0;
+const D = (1 + 2) * (3 + 5);
+fn main() { pn(A); pn(B + 0); pn(C); pn(D); return 0; }
diff --git a/tests/conformance/3-expressions/const_expr_shift.zc b/tests/conformance/3-expressions/const_expr_shift.zc
new file mode 100644
index 0000000..6b7e056
--- /dev/null
+++ b/tests/conformance/3-expressions/const_expr_shift.zc
@@ -0,0 +1,6 @@
+// expect: 16/1/
+include rt;
+void pn(int x) { rt.put_n(x); rt.put_c(10); }
+const S = 1 << 4;
+const T = 256 >> 8;
+fn main() { pn(S); pn(T); return 0; }
diff --git a/tests/conformance/3-expressions/const_expr_ternary_rejected.zc b/tests/conformance/3-expressions/const_expr_ternary_rejected.zc
new file mode 100644
index 0000000..81af58b
--- /dev/null
+++ b/tests/conformance/3-expressions/const_expr_ternary_rejected.zc
@@ -0,0 +1,4 @@
+// expect error: zc: line 3:
+include rt;
+const Z = 1 ? 2 : 3;
+fn main() { return 0; }
diff --git a/tests/conformance/3-expressions/const_expr_xor_rejected.zc b/tests/conformance/3-expressions/const_expr_xor_rejected.zc
new file mode 100644
index 0000000..eb1ad25
--- /dev/null
+++ b/tests/conformance/3-expressions/const_expr_xor_rejected.zc
@@ -0,0 +1,4 @@
+// expect error: zc: line 3:
+include rt;
+const Z = 7 ^ 2;
+fn main() { return 0; }
diff --git a/tests/conformance/3-expressions/decr_prefix_postfix.zc b/tests/conformance/3-expressions/decr_prefix_postfix.zc
new file mode 100644
index 0000000..ba38935
--- /dev/null
+++ b/tests/conformance/3-expressions/decr_prefix_postfix.zc
@@ -0,0 +1,11 @@
+// expect: 4/3/2/2/
+include rt;
+void pn(int x) { rt.put_n(x); rt.put_c(10); }
+fn main() {
+ int a = 4;
+ pn(a--);
+ pn(a);
+ pn(--a);
+ pn(a);
+ return 0;
+}
diff --git a/tests/conformance/3-expressions/dyn_array_array_len_cap_const.zc b/tests/conformance/3-expressions/dyn_array_array_len_cap_const.zc
new file mode 100644
index 0000000..d1bf61d
--- /dev/null
+++ b/tests/conformance/3-expressions/dyn_array_array_len_cap_const.zc
@@ -0,0 +1,9 @@
+// expect: 5/5/
+include rt;
+void pn(int x) { rt.put_n(x); rt.put_c(10); }
+fn main() {
+ int[5] a;
+ pn(len(a)); pn(cap(a));
+ return 0;
+}
+// zc0: skip
diff --git a/tests/conformance/3-expressions/dyn_array_cap_at_least_doubles.zc b/tests/conformance/3-expressions/dyn_array_cap_at_least_doubles.zc
new file mode 100644
index 0000000..5a55545
--- /dev/null
+++ b/tests/conformance/3-expressions/dyn_array_cap_at_least_doubles.zc
@@ -0,0 +1,17 @@
+// expect: 1/1/10/
+include rt;
+void pn(int x) { rt.put_n(x); rt.put_c(10); }
+fn main() {
+ int[?] a = rt.new(int[?]);
+ int c0 = cap(a);
+ int i = 0;
+ while (i < c0) { push(a, i); i++; }
+ pn(cap(a) == c0);
+ push(a, 99);
+ pn(cap(a) >= 2 * c0);
+ int j = 0;
+ while (j < 9) { push(a, j); j++; }
+ pn(len(a) - c0);
+ return 0;
+}
+// zc0: skip
diff --git a/tests/conformance/3-expressions/dyn_array_const_index_warning.zc b/tests/conformance/3-expressions/dyn_array_const_index_warning.zc
new file mode 100644
index 0000000..36890d7
--- /dev/null
+++ b/tests/conformance/3-expressions/dyn_array_const_index_warning.zc
@@ -0,0 +1,8 @@
+// expect: zc: line 5: warning: out-of-bounds access: index 2 is outside length 2 (storage declared or allocated on line 4)/zy: index 2 out of range (length 2)/
+include rt;
+fn main() {
+ int[?] a = {1, 2};
+ rt.put_n(a[2]);
+ return 0;
+}
+// zc0: skip
diff --git a/tests/conformance/3-expressions/dyn_array_index_negative.zc b/tests/conformance/3-expressions/dyn_array_index_negative.zc
new file mode 100644
index 0000000..c87e786
--- /dev/null
+++ b/tests/conformance/3-expressions/dyn_array_index_negative.zc
@@ -0,0 +1,11 @@
+// expect: zy: index -1 out of range (length 2)/
+include rt;
+void pn(int x) { rt.put_n(x); rt.put_c(10); }
+fn main() {
+ int[?] a = {1, 2};
+ int i = 0 - 1;
+ pn(a[i]);
+ pn(99);
+ return 0;
+}
+// zc0: skip
diff --git a/tests/conformance/3-expressions/dyn_array_index_out_of_range.zc b/tests/conformance/3-expressions/dyn_array_index_out_of_range.zc
new file mode 100644
index 0000000..eff8061
--- /dev/null
+++ b/tests/conformance/3-expressions/dyn_array_index_out_of_range.zc
@@ -0,0 +1,12 @@
+// expect: 2/zy: index 2 out of range (length 2)/
+include rt;
+void pn(int x) { rt.put_n(x); rt.put_c(10); }
+fn main() {
+ int[?] a = {1, 2};
+ int i = 2;
+ pn(len(a));
+ pn(a[i]);
+ pn(99);
+ return 0;
+}
+// zc0: skip
diff --git a/tests/conformance/3-expressions/dyn_array_intrinsics.zc b/tests/conformance/3-expressions/dyn_array_intrinsics.zc
new file mode 100644
index 0000000..6056423
--- /dev/null
+++ b/tests/conformance/3-expressions/dyn_array_intrinsics.zc
@@ -0,0 +1,11 @@
+// expect: 4/4/4/4/3/2/
+include rt;
+void pn(int x) { rt.put_n(x); rt.put_c(10); }
+fn main() {
+ int[?] a = {1, 2};
+ push(a, 3); a.push(4);
+ pn(len(a)); pn(cap(a)); pn(a[3]);
+ pn(pop(a)); pn(a.pop()); pn(a.len());
+ return 0;
+}
+// zc0: skip
diff --git a/tests/conformance/3-expressions/dyn_array_len_of_pointer_typecheck.zc b/tests/conformance/3-expressions/dyn_array_len_of_pointer_typecheck.zc
new file mode 100644
index 0000000..4153ee4
--- /dev/null
+++ b/tests/conformance/3-expressions/dyn_array_len_of_pointer_typecheck.zc
@@ -0,0 +1,7 @@
+// expect error: len needs an array
+include rt;
+typecheck on;
+fn main() {
+ rt.put_n(len("text"));
+ return 0;
+}
diff --git a/tests/conformance/3-expressions/dyn_array_new_len_cap.zc b/tests/conformance/3-expressions/dyn_array_new_len_cap.zc
new file mode 100644
index 0000000..b491d62
--- /dev/null
+++ b/tests/conformance/3-expressions/dyn_array_new_len_cap.zc
@@ -0,0 +1,13 @@
+// expect: 0/1/1/5/
+include rt;
+void pn(int x) { rt.put_n(x); rt.put_c(10); }
+fn main() {
+ int[?] a = rt.new(int[?]);
+ pn(len(a)); pn(cap(a) >= 4);
+ int i = 0;
+ while (i < 5) { push(a, i); i++; }
+ pn(cap(a) >= 8);
+ pn(len(a));
+ return 0;
+}
+// zc0: skip
diff --git a/tests/conformance/3-expressions/dyn_array_pop_empty.zc b/tests/conformance/3-expressions/dyn_array_pop_empty.zc
new file mode 100644
index 0000000..6f5fdd0
--- /dev/null
+++ b/tests/conformance/3-expressions/dyn_array_pop_empty.zc
@@ -0,0 +1,10 @@
+// expect: zy: index -1 out of range (length 0)/
+include rt;
+void pn(int x) { rt.put_n(x); rt.put_c(10); }
+fn main() {
+ int[?] a = rt.new(int[?]);
+ pn(pop(a));
+ pn(99);
+ return 0;
+}
+// zc0: skip
diff --git a/tests/conformance/3-expressions/dyn_array_pop_returns_last.zc b/tests/conformance/3-expressions/dyn_array_pop_returns_last.zc
new file mode 100644
index 0000000..f3773bb
--- /dev/null
+++ b/tests/conformance/3-expressions/dyn_array_pop_returns_last.zc
@@ -0,0 +1,10 @@
+// expect: 3/2/
+include rt;
+void pn(int x) { rt.put_n(x); rt.put_c(10); }
+fn main() {
+ int[?] a = {1, 2, 3};
+ pn(pop(a));
+ pn(a.pop());
+ return 0;
+}
+// zc0: skip
diff --git a/tests/conformance/3-expressions/dyn_array_push_aggregate.zc b/tests/conformance/3-expressions/dyn_array_push_aggregate.zc
new file mode 100644
index 0000000..5dce054
--- /dev/null
+++ b/tests/conformance/3-expressions/dyn_array_push_aggregate.zc
@@ -0,0 +1,9 @@
+// expect error: push takes scalar or reference elements
+include rt;
+struct pt { int x; int y; }
+fn main() {
+ pt[?] a = rt.new(pt[?]);
+ pt* p = rt.new(pt);
+ push(a, p);
+ return 0;
+}
diff --git a/tests/conformance/3-expressions/dyn_array_receiver_calls.zc b/tests/conformance/3-expressions/dyn_array_receiver_calls.zc
new file mode 100644
index 0000000..6290f13
--- /dev/null
+++ b/tests/conformance/3-expressions/dyn_array_receiver_calls.zc
@@ -0,0 +1,11 @@
+// expect: 3/4/
+include rt;
+void pn(int x) { rt.put_n(x); rt.put_c(10); }
+fn main() {
+ int[?] a = {1, 2};
+ a.push(3);
+ pn(a.len());
+ pn(a.cap());
+ return 0;
+}
+// zc0: skip
diff --git a/tests/conformance/3-expressions/dyn_array_resize.zc b/tests/conformance/3-expressions/dyn_array_resize.zc
new file mode 100644
index 0000000..c0ae4f5
--- /dev/null
+++ b/tests/conformance/3-expressions/dyn_array_resize.zc
@@ -0,0 +1,16 @@
+// expect: 5/0/0/3/7/2/
+include rt;
+void pn(int x) { rt.put_n(x); rt.put_c(10); }
+fn main() {
+ int[?] a = {7, 8, 9};
+ resize(a, 5);
+ pn(len(a)); pn(a[3]); pn(a[4]);
+ resize(a, 1);
+ a.resize(3);
+ pn(len(a));
+ pn(a[0]);
+ resize(a, 2);
+ pn(len(a));
+ return 0;
+}
+// zc0: skip
diff --git a/tests/conformance/3-expressions/eval_order_arguments.zc b/tests/conformance/3-expressions/eval_order_arguments.zc
new file mode 100644
index 0000000..d7bbb76
--- /dev/null
+++ b/tests/conformance/3-expressions/eval_order_arguments.zc
@@ -0,0 +1,9 @@
+// expect: 1/
+include rt;
+void pn(int x) { rt.put_n(x); rt.put_c(10); }
+void two(int a, int b) { pn(a * 10 + b); }
+fn main() {
+ int i = 0;
+ two(i++, i++);
+ return 0;
+}
diff --git a/tests/conformance/3-expressions/eval_order_binary_calls.zc b/tests/conformance/3-expressions/eval_order_binary_calls.zc
new file mode 100644
index 0000000..36b4c8a
--- /dev/null
+++ b/tests/conformance/3-expressions/eval_order_binary_calls.zc
@@ -0,0 +1,10 @@
+// expect: 12/
+include rt;
+int trace;
+int step(int v) { trace = trace * 10 + v; return v; }
+void pn(int x) { rt.put_n(x); rt.put_c(10); }
+fn main() {
+ int r = step(1) - step(2) * 1;
+ pn(trace);
+ return 0;
+}
diff --git a/tests/conformance/3-expressions/eval_order_calls_left_to_right.zc b/tests/conformance/3-expressions/eval_order_calls_left_to_right.zc
new file mode 100644
index 0000000..9c7fed3
--- /dev/null
+++ b/tests/conformance/3-expressions/eval_order_calls_left_to_right.zc
@@ -0,0 +1,11 @@
+// expect: 123/
+include rt;
+int trace;
+int step(int v) { trace = trace * 10 + v; return v; }
+int add3(int a, int b, int c) { return a + b + c; }
+void pn(int x) { rt.put_n(x); rt.put_c(10); }
+fn main() {
+ int r = add3(step(1), step(2), step(3));
+ pn(trace);
+ return 0;
+}
diff --git a/tests/conformance/3-expressions/eval_order_operands.zc b/tests/conformance/3-expressions/eval_order_operands.zc
new file mode 100644
index 0000000..a8f289c
--- /dev/null
+++ b/tests/conformance/3-expressions/eval_order_operands.zc
@@ -0,0 +1,10 @@
+// expect: 38/11/
+include rt;
+void pn(int x) { rt.put_n(x); rt.put_c(10); }
+fn main() {
+ int a = 18;
+ pn(a++ + ++a);
+ int j = 1;
+ pn(j + (j = 5) * 2);
+ return 0;
+}
diff --git a/tests/conformance/3-expressions/float_as_keeps_bits.zc b/tests/conformance/3-expressions/float_as_keeps_bits.zc
new file mode 100644
index 0000000..69bf4c3
--- /dev/null
+++ b/tests/conformance/3-expressions/float_as_keeps_bits.zc
@@ -0,0 +1,10 @@
+// expect: 0.000000/4607182418800017408/
+include rt;
+void pn(int x) { rt.put_n(x); rt.put_c(10); }
+fn pf(x) { asm { x @ #1220 } rt.put_c(10); return 0; }
+fn main() {
+ pf(3 as float);
+ float one = 1.0;
+ pn(one as int);
+ return 0;
+}
diff --git a/tests/conformance/3-expressions/float_basic_arith.zc b/tests/conformance/3-expressions/float_basic_arith.zc
new file mode 100644
index 0000000..caed2b2
--- /dev/null
+++ b/tests/conformance/3-expressions/float_basic_arith.zc
@@ -0,0 +1,12 @@
+// expect: 3.500000/inf/-inf/nan/3.000000/
+include rt;
+fn pf(x) { asm { x @ #1220 } rt.put_c(10); return 0; }
+fn main() {
+ pf(7 / 2.0);
+ pf(1.0 / 0.0);
+ pf(-1.0 / 0.0);
+ pf(0.0 / 0.0);
+ float r = 7 / 2;
+ pf(r);
+ return 0;
+}
diff --git a/tests/conformance/3-expressions/float_cast_value_and_bits.zc b/tests/conformance/3-expressions/float_cast_value_and_bits.zc
new file mode 100644
index 0000000..290263f
--- /dev/null
+++ b/tests/conformance/3-expressions/float_cast_value_and_bits.zc
@@ -0,0 +1,15 @@
+// expect: -2/3.000000/1/0/
+include rt;
+void pn(int x) { rt.put_n(x); rt.put_c(10); }
+fn pf(x) { asm { x @ #1220 } rt.put_c(10); return 0; }
+fn main() {
+ float f = -2.9;
+ int i = 3;
+ pn((int)f);
+ pf((float)i);
+ word w = 4607182418800017408;
+ pn(w as float == 1.0);
+ pn((3 as float) == 3.0);
+ return 0;
+}
+// zc0: skip
diff --git a/tests/conformance/3-expressions/float_division_int_stored.zc b/tests/conformance/3-expressions/float_division_int_stored.zc
new file mode 100644
index 0000000..c105e0b
--- /dev/null
+++ b/tests/conformance/3-expressions/float_division_int_stored.zc
@@ -0,0 +1,10 @@
+// expect: 3.000000/0.500000/
+include rt;
+fn pf(x) { asm { x @ #1220 } rt.put_c(10); return 0; }
+fn main() {
+ float r = 7 / 2;
+ pf(r);
+ float s = 1 / 2.0;
+ pf(s);
+ return 0;
+}
diff --git a/tests/conformance/3-expressions/float_int_ops_on_bits.zc b/tests/conformance/3-expressions/float_int_ops_on_bits.zc
new file mode 100644
index 0000000..38a45a8
--- /dev/null
+++ b/tests/conformance/3-expressions/float_int_ops_on_bits.zc
@@ -0,0 +1,12 @@
+// expect: 1/1/
+include rt;
+void pn(int x) { rt.put_n(x); rt.put_c(10); }
+fn main() {
+ float f = 1.0;
+ int bits = f as int;
+ word r = f & 4607182418800017408;
+ word r2 = f | 0;
+ pn(r == bits);
+ pn(r2 == bits);
+ return 0;
+}
diff --git a/tests/conformance/3-expressions/float_lit_exponent_arith.zc b/tests/conformance/3-expressions/float_lit_exponent_arith.zc
new file mode 100644
index 0000000..5b718c8
--- /dev/null
+++ b/tests/conformance/3-expressions/float_lit_exponent_arith.zc
@@ -0,0 +1,8 @@
+// expect: 1000.000000/0.001000/
+include rt;
+fn pf(x) { asm { x @ #1220 } rt.put_c(10); return 0; }
+fn main() {
+ pf(1e3);
+ pf(1e-3);
+ return 0;
+}
diff --git a/tests/conformance/3-expressions/float_mixed_comparisons.zc b/tests/conformance/3-expressions/float_mixed_comparisons.zc
new file mode 100644
index 0000000..b03394a
--- /dev/null
+++ b/tests/conformance/3-expressions/float_mixed_comparisons.zc
@@ -0,0 +1,8 @@
+// expect: 1/1/1/0/1/
+include rt;
+void pn(int x) { rt.put_n(x); rt.put_c(10); }
+fn main() {
+ float f = 2.5;
+ pn(1 < f); pn(f > 2); pn(2.0 == 2); pn(f == 2); pn(3 >= 2.5);
+ return 0;
+}
diff --git a/tests/conformance/3-expressions/float_negate_is_zero_minus.zc b/tests/conformance/3-expressions/float_negate_is_zero_minus.zc
new file mode 100644
index 0000000..5c673db
--- /dev/null
+++ b/tests/conformance/3-expressions/float_negate_is_zero_minus.zc
@@ -0,0 +1,14 @@
+// expect: -1.500000/0/0/
+include rt;
+void pn(int x) { rt.put_n(x); rt.put_c(10); }
+fn pf(x) { asm { x @ #1220 } rt.put_c(10); return 0; }
+fn main() {
+ float f = 1.5;
+ pf(-f);
+ float z = -0.0;
+ pn(z as int);
+ float y = 0.0;
+ float ny = -y;
+ pn(ny as int);
+ return 0;
+}
diff --git a/tests/conformance/3-expressions/float_operand_conversion.zc b/tests/conformance/3-expressions/float_operand_conversion.zc
new file mode 100644
index 0000000..018a7c6
--- /dev/null
+++ b/tests/conformance/3-expressions/float_operand_conversion.zc
@@ -0,0 +1,12 @@
+// expect: 3.500000/0.500000/3.000000/2.000000/
+include rt;
+fn pf(x) { asm { x @ #1220 } rt.put_c(10); return 0; }
+fn main() {
+ float f = 1.5;
+ int i = 2;
+ pf(f + i);
+ pf(f - 1);
+ pf(f * i);
+ pf(i * 1.0);
+ return 0;
+}
diff --git a/tests/conformance/3-expressions/float_tracked_through_locals_fields_params.zc b/tests/conformance/3-expressions/float_tracked_through_locals_fields_params.zc
new file mode 100644
index 0000000..87f2c72
--- /dev/null
+++ b/tests/conformance/3-expressions/float_tracked_through_locals_fields_params.zc
@@ -0,0 +1,20 @@
+// expect: 2.500000/2.500000/2.500000/2.500000/
+include rt;
+fn pf(x) { asm { x @ #1220 } rt.put_c(10); return 0; }
+struct box { float v; }
+float g;
+float half(float x) { return x / 2; }
+float getg() { return g; }
+fn main() {
+ float a = 5;
+ pf(a / 2);
+ box* b = rt.new(box);
+ b.v = 5;
+ pf(b.v / 2);
+ pf(half(5));
+ g = 5;
+ pf(getg() / 2);
+ rt.free(b);
+ return 0;
+}
+// zc0: skip
diff --git a/tests/conformance/3-expressions/incr_needs_lvalue.zc b/tests/conformance/3-expressions/incr_needs_lvalue.zc
new file mode 100644
index 0000000..69f84f8
--- /dev/null
+++ b/tests/conformance/3-expressions/incr_needs_lvalue.zc
@@ -0,0 +1,7 @@
+// expect error: ++ and -- need something to assign to
+include rt;
+fn main() {
+ int a = 1;
+ (a + 1)++;
+ return 0;
+}
diff --git a/tests/conformance/3-expressions/incr_needs_lvalue_prefix.zc b/tests/conformance/3-expressions/incr_needs_lvalue_prefix.zc
new file mode 100644
index 0000000..c4f617f
--- /dev/null
+++ b/tests/conformance/3-expressions/incr_needs_lvalue_prefix.zc
@@ -0,0 +1,6 @@
+// expect error: ++ and -- need something to assign to
+include rt;
+fn main() {
+ ++5;
+ return 0;
+}
diff --git a/tests/conformance/3-expressions/incr_on_float_changes_bits.zc b/tests/conformance/3-expressions/incr_on_float_changes_bits.zc
new file mode 100644
index 0000000..7062daf
--- /dev/null
+++ b/tests/conformance/3-expressions/incr_on_float_changes_bits.zc
@@ -0,0 +1,10 @@
+// expect: 0/1/
+include rt;
+void pn(int x) { rt.put_n(x); rt.put_c(10); }
+fn main() {
+ float f = 1.5;
+ f++;
+ pn(f == 1.5);
+ pn(f as int == 4609434218613702657);
+ return 0;
+}
diff --git a/tests/conformance/3-expressions/int_add_wrap.zc b/tests/conformance/3-expressions/int_add_wrap.zc
new file mode 100644
index 0000000..8c4e0d2
--- /dev/null
+++ b/tests/conformance/3-expressions/int_add_wrap.zc
@@ -0,0 +1,15 @@
+// expect: -9223372036854775808/-9223372036854775808/9223372036854775807/9223372036854775807/-2/-2/3/3/
+// spec 3.4.1
+include rt;
+void pn(int x) { rt.put_n(x); rt.put_c(10); }
+fn main() {
+ pn(9223372036854775807 + 1);
+ { int a = 9223372036854775807, b = 1; pn(a + b); }
+ pn((-9223372036854775807 - 1) + -1);
+ { int a = (-9223372036854775807 - 1), b = -1; pn(a + b); }
+ pn(9223372036854775807 + 9223372036854775807);
+ { int a = 9223372036854775807, b = 9223372036854775807; pn(a + b); }
+ pn(1 + 2);
+ { int a = 1, b = 2; pn(a + b); }
+ return 0;
+}
diff --git a/tests/conformance/3-expressions/int_bitwise_and.zc b/tests/conformance/3-expressions/int_bitwise_and.zc
new file mode 100644
index 0000000..5ce4641
--- /dev/null
+++ b/tests/conformance/3-expressions/int_bitwise_and.zc
@@ -0,0 +1,15 @@
+// expect: 255/255/2/2/-9223372036854775808/-9223372036854775808/0/0/
+// spec 3.4.5: bitwise on all 64 bits
+include rt;
+void pn(int x) { rt.put_n(x); rt.put_c(10); }
+fn main() {
+ pn(-1 & 255);
+ { int a = -1, b = 255; pn(a & b); }
+ pn(6 & 3);
+ { int a = 6, b = 3; pn(a & b); }
+ pn((-9223372036854775807 - 1) & -1);
+ { int a = (-9223372036854775807 - 1), b = -1; pn(a & b); }
+ pn(0 & -1);
+ { int a = 0, b = -1; pn(a & b); }
+ return 0;
+}
diff --git a/tests/conformance/3-expressions/int_bitwise_or.zc b/tests/conformance/3-expressions/int_bitwise_or.zc
new file mode 100644
index 0000000..fc5cdc2
--- /dev/null
+++ b/tests/conformance/3-expressions/int_bitwise_or.zc
@@ -0,0 +1,13 @@
+// expect: -1/-1/7/7/-9223372036854775807/-9223372036854775807/
+// spec 3.4.5
+include rt;
+void pn(int x) { rt.put_n(x); rt.put_c(10); }
+fn main() {
+ pn(-256 | 255);
+ { int a = -256, b = 255; pn(a | b); }
+ pn(6 | 3);
+ { int a = 6, b = 3; pn(a | b); }
+ pn((-9223372036854775807 - 1) | 1);
+ { int a = (-9223372036854775807 - 1), b = 1; pn(a | b); }
+ return 0;
+}
diff --git a/tests/conformance/3-expressions/int_bitwise_xor.zc b/tests/conformance/3-expressions/int_bitwise_xor.zc
new file mode 100644
index 0000000..3aea716
--- /dev/null
+++ b/tests/conformance/3-expressions/int_bitwise_xor.zc
@@ -0,0 +1,15 @@
+// expect: -2/-2/5/5/0/0/-6/-6/
+// spec 3.4.5
+include rt;
+void pn(int x) { rt.put_n(x); rt.put_c(10); }
+fn main() {
+ pn(-1 ^ 1);
+ { int a = -1, b = 1; pn(a ^ b); }
+ pn(6 ^ 3);
+ { int a = 6, b = 3; pn(a ^ b); }
+ pn((-9223372036854775807 - 1) ^ (-9223372036854775807 - 1));
+ { int a = (-9223372036854775807 - 1), b = (-9223372036854775807 - 1); pn(a ^ b); }
+ pn(5 ^ -1);
+ { int a = 5, b = -1; pn(a ^ b); }
+ return 0;
+}
diff --git a/tests/conformance/3-expressions/int_compare_ge.zc b/tests/conformance/3-expressions/int_compare_ge.zc
new file mode 100644
index 0000000..c8b886b
--- /dev/null
+++ b/tests/conformance/3-expressions/int_compare_ge.zc
@@ -0,0 +1,17 @@
+// expect: 0/0/0/0/1/1/1/1/1/1/
+// spec 3.4.5
+include rt;
+void pn(int x) { rt.put_n(x); rt.put_c(10); }
+fn main() {
+ pn(-1 >= 0);
+ { int a = -1, b = 0; pn(a >= b); }
+ pn((-9223372036854775807 - 1) >= 9223372036854775807);
+ { int a = (-9223372036854775807 - 1), b = 9223372036854775807; pn(a >= b); }
+ pn(9223372036854775807 >= (-9223372036854775807 - 1));
+ { int a = 9223372036854775807, b = (-9223372036854775807 - 1); pn(a >= b); }
+ pn(0 >= 0);
+ { int a = 0, b = 0; pn(a >= b); }
+ pn(4 >= 3);
+ { int a = 4, b = 3; pn(a >= b); }
+ return 0;
+}
diff --git a/tests/conformance/3-expressions/int_compare_signed.zc b/tests/conformance/3-expressions/int_compare_signed.zc
new file mode 100644
index 0000000..c09bedd
--- /dev/null
+++ b/tests/conformance/3-expressions/int_compare_signed.zc
@@ -0,0 +1,19 @@
+// expect: 1/1/1/1/1/1/0/0/0/0/1/1/
+// spec 3.4.5
+include rt;
+void pn(int x) { rt.put_n(x); rt.put_c(10); }
+fn main() {
+ pn(-1 < 0);
+ { int a = -1, b = 0; pn(a < b); }
+ pn(-1 < 1);
+ { int a = -1, b = 1; pn(a < b); }
+ pn((-9223372036854775807 - 1) < 9223372036854775807);
+ { int a = (-9223372036854775807 - 1), b = 9223372036854775807; pn(a < b); }
+ pn(9223372036854775807 < (-9223372036854775807 - 1));
+ { int a = 9223372036854775807, b = (-9223372036854775807 - 1); pn(a < b); }
+ pn(0 < 0);
+ { int a = 0, b = 0; pn(a < b); }
+ pn(3 < 4);
+ { int a = 3, b = 4; pn(a < b); }
+ return 0;
+}
diff --git a/tests/conformance/3-expressions/int_div_signs.zc b/tests/conformance/3-expressions/int_div_signs.zc
new file mode 100644
index 0000000..c6bcdca
--- /dev/null
+++ b/tests/conformance/3-expressions/int_div_signs.zc
@@ -0,0 +1,19 @@
+// expect: 3/3/-3/-3/-3/-3/3/3/0/0/14/14/
+// spec 3.4.2
+include rt;
+void pn(int x) { rt.put_n(x); rt.put_c(10); }
+fn main() {
+ pn(7 / 2);
+ { int a = 7, b = 2; pn(a / b); }
+ pn(7 / -2);
+ { int a = 7, b = -2; pn(a / b); }
+ pn(-7 / 2);
+ { int a = -7, b = 2; pn(a / b); }
+ pn(-7 / -2);
+ { int a = -7, b = -2; pn(a / b); }
+ pn(0 / 5);
+ { int a = 0, b = 5; pn(a / b); }
+ pn(100 / 7);
+ { int a = 100, b = 7; pn(a / b); }
+ return 0;
+}
diff --git a/tests/conformance/3-expressions/int_div_zero.zc b/tests/conformance/3-expressions/int_div_zero.zc
new file mode 100644
index 0000000..ee1eec5
--- /dev/null
+++ b/tests/conformance/3-expressions/int_div_zero.zc
@@ -0,0 +1,13 @@
+// expect: 0/0/0/0/0/0/
+// spec 3.4.3: division by zero gives 0
+include rt;
+void pn(int x) { rt.put_n(x); rt.put_c(10); }
+fn main() {
+ pn(5 / 0);
+ { int a = 5, b = 0; pn(a / b); }
+ pn(-5 / 0);
+ { int a = -5, b = 0; pn(a / b); }
+ pn(0 / 0);
+ { int a = 0, b = 0; pn(a / b); }
+ return 0;
+}
diff --git a/tests/conformance/3-expressions/int_logical_or_values.zc b/tests/conformance/3-expressions/int_logical_or_values.zc
new file mode 100644
index 0000000..ec84c41
--- /dev/null
+++ b/tests/conformance/3-expressions/int_logical_or_values.zc
@@ -0,0 +1,17 @@
+// expect: 1/1/1/1/0/0/1/1/1/1/
+// spec 3.4.6: || gives 0 or 1
+include rt;
+void pn(int x) { rt.put_n(x); rt.put_c(10); }
+fn main() {
+ pn(0 || 9);
+ { int a = 0, b = 9; pn(a || b); }
+ pn(5 || 0);
+ { int a = 5, b = 0; pn(a || b); }
+ pn(0 || 0);
+ { int a = 0, b = 0; pn(a || b); }
+ pn(-3 || -3);
+ { int a = -3, b = -3; pn(a || b); }
+ pn((-9223372036854775807 - 1) || 0);
+ { int a = (-9223372036854775807 - 1), b = 0; pn(a || b); }
+ return 0;
+}
diff --git a/tests/conformance/3-expressions/int_logical_values.zc b/tests/conformance/3-expressions/int_logical_values.zc
new file mode 100644
index 0000000..3382025
--- /dev/null
+++ b/tests/conformance/3-expressions/int_logical_values.zc
@@ -0,0 +1,17 @@
+// expect: 1/1/0/0/0/0/0/0/1/1/
+// spec 3.4.6: && gives 0 or 1
+include rt;
+void pn(int x) { rt.put_n(x); rt.put_c(10); }
+fn main() {
+ pn(5 && 7);
+ { int a = 5, b = 7; pn(a && b); }
+ pn(5 && 0);
+ { int a = 5, b = 0; pn(a && b); }
+ pn(0 && 7);
+ { int a = 0, b = 7; pn(a && b); }
+ pn(0 && 0);
+ { int a = 0, b = 0; pn(a && b); }
+ pn(-1 && (-9223372036854775807 - 1));
+ { int a = -1, b = (-9223372036854775807 - 1); pn(a && b); }
+ return 0;
+}
diff --git a/tests/conformance/3-expressions/int_min_div_minus1.zc b/tests/conformance/3-expressions/int_min_div_minus1.zc
new file mode 100644
index 0000000..8f13ef1
--- /dev/null
+++ b/tests/conformance/3-expressions/int_min_div_minus1.zc
@@ -0,0 +1,9 @@
+// expect: -9223372036854775808/-9223372036854775808/
+// spec 3.4.3
+include rt;
+void pn(int x) { rt.put_n(x); rt.put_c(10); }
+fn main() {
+ pn((-9223372036854775807 - 1) / -1);
+ { int a = (-9223372036854775807 - 1), b = -1; pn(a / b); }
+ return 0;
+}
diff --git a/tests/conformance/3-expressions/int_min_mod_minus1.zc b/tests/conformance/3-expressions/int_min_mod_minus1.zc
new file mode 100644
index 0000000..bd8b36e
--- /dev/null
+++ b/tests/conformance/3-expressions/int_min_mod_minus1.zc
@@ -0,0 +1,9 @@
+// expect: 0/0/
+// spec 3.4.3
+include rt;
+void pn(int x) { rt.put_n(x); rt.put_c(10); }
+fn main() {
+ pn((-9223372036854775807 - 1) % -1);
+ { int a = (-9223372036854775807 - 1), b = -1; pn(a % b); }
+ return 0;
+}
diff --git a/tests/conformance/3-expressions/int_mod_signs.zc b/tests/conformance/3-expressions/int_mod_signs.zc
new file mode 100644
index 0000000..4ed0c6f
--- /dev/null
+++ b/tests/conformance/3-expressions/int_mod_signs.zc
@@ -0,0 +1,19 @@
+// expect: 1/1/1/1/-1/-1/-1/-1/0/0/2/2/
+// spec 3.4.2
+include rt;
+void pn(int x) { rt.put_n(x); rt.put_c(10); }
+fn main() {
+ pn(7 % 2);
+ { int a = 7, b = 2; pn(a % b); }
+ pn(7 % -2);
+ { int a = 7, b = -2; pn(a % b); }
+ pn(-7 % 2);
+ { int a = -7, b = 2; pn(a % b); }
+ pn(-7 % -2);
+ { int a = -7, b = -2; pn(a % b); }
+ pn(0 % 5);
+ { int a = 0, b = 5; pn(a % b); }
+ pn(100 % 7);
+ { int a = 100, b = 7; pn(a % b); }
+ return 0;
+}
diff --git a/tests/conformance/3-expressions/int_mod_zero.zc b/tests/conformance/3-expressions/int_mod_zero.zc
new file mode 100644
index 0000000..4a77a7b
--- /dev/null
+++ b/tests/conformance/3-expressions/int_mod_zero.zc
@@ -0,0 +1,13 @@
+// expect: 5/5/-5/-5/0/0/
+// spec 3.4.3: n % 0 is n
+include rt;
+void pn(int x) { rt.put_n(x); rt.put_c(10); }
+fn main() {
+ pn(5 % 0);
+ { int a = 5, b = 0; pn(a % b); }
+ pn(-5 % 0);
+ { int a = -5, b = 0; pn(a % b); }
+ pn(0 % 0);
+ { int a = 0, b = 0; pn(a % b); }
+ return 0;
+}
diff --git a/tests/conformance/3-expressions/int_mul_wrap.zc b/tests/conformance/3-expressions/int_mul_wrap.zc
new file mode 100644
index 0000000..66d9e3b
--- /dev/null
+++ b/tests/conformance/3-expressions/int_mul_wrap.zc
@@ -0,0 +1,15 @@
+// expect: -2/-2/-9223372036709301616/-9223372036709301616/-9223372036854775808/-9223372036854775808/-20/-20/
+// spec 3.4.1
+include rt;
+void pn(int x) { rt.put_n(x); rt.put_c(10); }
+fn main() {
+ pn(9223372036854775807 * 2);
+ { int a = 9223372036854775807, b = 2; pn(a * b); }
+ pn(3037000500 * 3037000500);
+ { int a = 3037000500, b = 3037000500; pn(a * b); }
+ pn((-9223372036854775807 - 1) * -1);
+ { int a = (-9223372036854775807 - 1), b = -1; pn(a * b); }
+ pn(-4 * 5);
+ { int a = -4, b = 5; pn(a * b); }
+ return 0;
+}
diff --git a/tests/conformance/3-expressions/int_shl_count_mod64.zc b/tests/conformance/3-expressions/int_shl_count_mod64.zc
new file mode 100644
index 0000000..ed90516
--- /dev/null
+++ b/tests/conformance/3-expressions/int_shl_count_mod64.zc
@@ -0,0 +1,23 @@
+// expect: -9223372036854775808/-9223372036854775808/1/1/2/2/-9223372036854775808/-9223372036854775808/-4611686018427387904/-4611686018427387904/-2/-2/1/1/5/5/
+// spec 3.4.4
+include rt;
+void pn(int x) { rt.put_n(x); rt.put_c(10); }
+fn main() {
+ pn(1 << 63);
+ { int a = 1, b = 63; pn(a << b); }
+ pn(1 << 64);
+ { int a = 1, b = 64; pn(a << b); }
+ pn(1 << 65);
+ { int a = 1, b = 65; pn(a << b); }
+ pn(1 << -1);
+ { int a = 1, b = -1; pn(a << b); }
+ pn(3 << 62);
+ { int a = 3, b = 62; pn(a << b); }
+ pn(-1 << 1);
+ { int a = -1, b = 1; pn(a << b); }
+ pn(1 << 128);
+ { int a = 1, b = 128; pn(a << b); }
+ pn(5 << 0);
+ { int a = 5, b = 0; pn(a << b); }
+ return 0;
+}
diff --git a/tests/conformance/3-expressions/int_shr_arith.zc b/tests/conformance/3-expressions/int_shr_arith.zc
new file mode 100644
index 0000000..8bd8de5
--- /dev/null
+++ b/tests/conformance/3-expressions/int_shr_arith.zc
@@ -0,0 +1,23 @@
+// expect: -4/-4/-1/-1/-1/-1/2/2/-1/-1/128/128/-1/-1/5/5/
+// spec 3.4.4
+include rt;
+void pn(int x) { rt.put_n(x); rt.put_c(10); }
+fn main() {
+ pn(-8 >> 1);
+ { int a = -8, b = 1; pn(a >> b); }
+ pn(-1 >> 63);
+ { int a = -1, b = 63; pn(a >> b); }
+ pn(-1 >> 64);
+ { int a = -1, b = 64; pn(a >> b); }
+ pn(5 >> -63);
+ { int a = 5, b = -63; pn(a >> b); }
+ pn((-9223372036854775807 - 1) >> 63);
+ { int a = (-9223372036854775807 - 1), b = 63; pn(a >> b); }
+ pn(1024 >> 3);
+ { int a = 1024, b = 3; pn(a >> b); }
+ pn(-1 >> 1);
+ { int a = -1, b = 1; pn(a >> b); }
+ pn(5 >> 64);
+ { int a = 5, b = 64; pn(a >> b); }
+ return 0;
+}
diff --git a/tests/conformance/3-expressions/int_sub_wrap.zc b/tests/conformance/3-expressions/int_sub_wrap.zc
new file mode 100644
index 0000000..f906dd0
--- /dev/null
+++ b/tests/conformance/3-expressions/int_sub_wrap.zc
@@ -0,0 +1,13 @@
+// expect: 9223372036854775807/9223372036854775807/-9223372036854775808/-9223372036854775808/-2/-2/
+// spec 3.4.1
+include rt;
+void pn(int x) { rt.put_n(x); rt.put_c(10); }
+fn main() {
+ pn((-9223372036854775807 - 1) - 1);
+ { int a = (-9223372036854775807 - 1), b = 1; pn(a - b); }
+ pn(0 - (-9223372036854775807 - 1));
+ { int a = 0, b = (-9223372036854775807 - 1); pn(a - b); }
+ pn(5 - 7);
+ { int a = 5, b = 7; pn(a - b); }
+ return 0;
+}
diff --git a/tests/conformance/3-expressions/member_dot_arrow_same.zc b/tests/conformance/3-expressions/member_dot_arrow_same.zc
new file mode 100644
index 0000000..f900a1d
--- /dev/null
+++ b/tests/conformance/3-expressions/member_dot_arrow_same.zc
@@ -0,0 +1,14 @@
+// expect: 3/4/5/6/
+include rt;
+void pn(int x) { rt.put_n(x); rt.put_c(10); }
+struct pt { int x; int y; }
+fn main() {
+ pt a;
+ a.x = 3; a->y = 4;
+ pt* p = &a;
+ pn(a.x); pn(a->y);
+ p.x = 5; p->y = 6;
+ pn(p.x); pn(p->y);
+ return 0;
+}
+// zc0: skip
diff --git a/tests/conformance/3-expressions/member_field_wins_over_method.zc b/tests/conformance/3-expressions/member_field_wins_over_method.zc
new file mode 100644
index 0000000..34680a9
--- /dev/null
+++ b/tests/conformance/3-expressions/member_field_wins_over_method.zc
@@ -0,0 +1,12 @@
+// expect: 5/
+include rt;
+void pn(int x) { rt.put_n(x); rt.put_c(10); }
+struct fw { int get; int get() { return 99; } }
+fn main() {
+ fw* a = rt.new(fw);
+ a.get = 5;
+ pn(a.get);
+ rt.free(a);
+ return 0;
+}
+// zc0: skip
diff --git a/tests/conformance/3-expressions/member_method_call.zc b/tests/conformance/3-expressions/member_method_call.zc
new file mode 100644
index 0000000..cc44c62
--- /dev/null
+++ b/tests/conformance/3-expressions/member_method_call.zc
@@ -0,0 +1,12 @@
+// expect: 7/
+include rt;
+void pn(int x) { rt.put_n(x); rt.put_c(10); }
+struct acc { int total; fn add(n) { this.total = this.total + n; return this.total; } }
+fn main() {
+ acc* a = rt.new(acc);
+ a.add(3);
+ pn(a.add(4));
+ rt.free(a);
+ return 0;
+}
+// zc0: skip
diff --git a/tests/conformance/3-expressions/member_missing_field_suggestion.zc b/tests/conformance/3-expressions/member_missing_field_suggestion.zc
new file mode 100644
index 0000000..8713561
--- /dev/null
+++ b/tests/conformance/3-expressions/member_missing_field_suggestion.zc
@@ -0,0 +1,8 @@
+// expect error: pt has no field nmae; did you mean 'name'?
+include rt;
+struct pt { int name; int y; }
+fn main() {
+ pt* p = rt.new(pt);
+ rt.put_n(p.nmae);
+ return 0;
+}
diff --git a/tests/conformance/3-expressions/member_two_pointer_levels.zc b/tests/conformance/3-expressions/member_two_pointer_levels.zc
new file mode 100644
index 0000000..d1870f4
--- /dev/null
+++ b/tests/conformance/3-expressions/member_two_pointer_levels.zc
@@ -0,0 +1,9 @@
+// expect error: zc: line 7:
+include rt;
+struct pt { int x; int y; }
+fn main() {
+ pt* p = rt.new(pt);
+ pt** pp = &p;
+ rt.put_n(pp.x);
+ return 0;
+}
diff --git a/tests/conformance/3-expressions/prec_as_binds_tight.zc b/tests/conformance/3-expressions/prec_as_binds_tight.zc
new file mode 100644
index 0000000..baf41e0
--- /dev/null
+++ b/tests/conformance/3-expressions/prec_as_binds_tight.zc
@@ -0,0 +1,10 @@
+// expect: -1/260/45/
+include rt;
+void pn(int x) { rt.put_n(x); rt.put_c(10); }
+fn main() {
+ pn(-2 as int + 1);
+ pn(250 + 10 as u8);
+ int k = 1;
+ pn(k + 300 as u8);
+ return 0;
+}
diff --git a/tests/conformance/3-expressions/prec_as_then_star.zc b/tests/conformance/3-expressions/prec_as_then_star.zc
new file mode 100644
index 0000000..046f069
--- /dev/null
+++ b/tests/conformance/3-expressions/prec_as_then_star.zc
@@ -0,0 +1,7 @@
+// expect error: zc: line 5:
+include rt;
+fn main() {
+ int x = 3, y = 4;
+ rt.put_n(x as int * y);
+ return 0;
+}
diff --git a/tests/conformance/3-expressions/prec_assign_lower_than_ternary.zc b/tests/conformance/3-expressions/prec_assign_lower_than_ternary.zc
new file mode 100644
index 0000000..9ca1541
--- /dev/null
+++ b/tests/conformance/3-expressions/prec_assign_lower_than_ternary.zc
@@ -0,0 +1,12 @@
+// expect: 5/5/
+include rt;
+void pn(int x) { rt.put_n(x); rt.put_c(10); }
+fn main() {
+ int a, c = 0;
+ a = 1 ? 5 : 6;
+ pn(a);
+ a = 0 ? 7 : 1 ? 5 : 9;
+ pn(a);
+ return 0;
+}
+// zc0: skip
diff --git a/tests/conformance/3-expressions/prec_assign_right_assoc.zc b/tests/conformance/3-expressions/prec_assign_right_assoc.zc
new file mode 100644
index 0000000..4cb885e
--- /dev/null
+++ b/tests/conformance/3-expressions/prec_assign_right_assoc.zc
@@ -0,0 +1,9 @@
+// expect: 7/7/7/
+include rt;
+void pn(int x) { rt.put_n(x); rt.put_c(10); }
+fn main() {
+ int a, b;
+ pn(a = b = 7);
+ pn(a); pn(b);
+ return 0;
+}
diff --git a/tests/conformance/3-expressions/prec_chains.zc b/tests/conformance/3-expressions/prec_chains.zc
new file mode 100644
index 0000000..c8cd31f
--- /dev/null
+++ b/tests/conformance/3-expressions/prec_chains.zc
@@ -0,0 +1,55 @@
+// expect: 0/0/1/1/1/1/1/1/-1/-1/1/1/1/1/13/13/1/1/1/1/3/3/1/1/1/1/1/1/1/1/7/7/1/1/7/7/-1/-1/1/1/0/0/1/1/0/0/1/1/
+// random chains of binary operators of several levels (spec 3.2.1)
+include rt;
+void pn(int x) { rt.put_n(x); rt.put_c(10); }
+fn main() {
+ pn(12 != 7 <= 1 & 9 + 7 && 2 << 0 & 7 | 4 > 3);
+ { int v0 = 12, v1 = 7, v2 = 1, v3 = 9, v4 = 7, v5 = 2, v6 = 0, v7 = 7, v8 = 4, v9 = 3; pn(v0 != v1 <= v2 & v3 + v4 && v5 << v6 & v7 | v8 > v9); }
+ pn(3 >> 1 | 2 >> 1 == 9 * -1 | 0 >> 0 >= 7 <= -1);
+ { int v0 = 3, v1 = 1, v2 = 2, v3 = 1, v4 = 9, v5 = -1, v6 = 0, v7 = 0, v8 = 7, v9 = -1; pn(v0 >> v1 | v2 >> v3 == v4 * v5 | v6 >> v7 >= v8 <= v9); }
+ pn(1 > -2 || -2 == 7 ^ 6 * 6 >> 6);
+ { int v0 = 1, v1 = -2, v2 = -2, v3 = 7, v4 = 6, v5 = 6, v6 = 6; pn(v0 > v1 || v2 == v3 ^ v4 * v5 >> v6); }
+ pn(2 >= -2 << 4 && 12 && -2 << 7 <= -2 + 6);
+ { int v0 = 2, v1 = -2, v2 = 4, v3 = 12, v4 = -2, v5 = 7, v6 = -2, v7 = 6; pn(v0 >= v1 << v2 && v3 && v4 << v5 <= v6 + v7); }
+ pn(5 + 0 * -2 > 4 | -2);
+ { int v0 = 5, v1 = 0, v2 = -2, v3 = 4, v4 = -2; pn(v0 + v1 * v2 > v3 | v4); }
+ pn(7 && 6 <= 2 * 4 == -2 ^ 0 == 6 <= -1);
+ { int v0 = 7, v1 = 6, v2 = 2, v3 = 4, v4 = -2, v5 = 0, v6 = 6, v7 = -1; pn(v0 && v1 <= v2 * v3 == v4 ^ v5 == v6 <= v7); }
+ pn(9 - -2 & 1 == -1 & 2 & -2 || 2 || 6 + 7 * -2);
+ { int v0 = 9, v1 = -2, v2 = 1, v3 = -1, v4 = 2, v5 = -2, v6 = 2, v7 = 6, v8 = 7, v9 = -2; pn(v0 - v1 & v2 == v3 & v4 & v5 || v6 || v7 + v8 * v9); }
+ pn(12 >= -2 | 2 + 3 & 5 | 12);
+ { int v0 = 12, v1 = -2, v2 = 2, v3 = 3, v4 = 5, v5 = 12; pn(v0 >= v1 | v2 + v3 & v4 | v5); }
+ pn(12 != -1 | 5 ^ 6 && 9 && 9 + 2);
+ { int v0 = 12, v1 = -1, v2 = 5, v3 = 6, v4 = 9, v5 = 9, v6 = 2; pn(v0 != v1 | v2 ^ v3 && v4 && v5 + v6); }
+ pn(3 <= 7 || -1 - -2 != 12 < 4 & 6 >= 12 ^ 12);
+ { int v0 = 3, v1 = 7, v2 = -1, v3 = -2, v4 = 12, v5 = 4, v6 = 6, v7 = 12, v8 = 12; pn(v0 <= v1 || v2 - v3 != v4 < v5 & v6 >= v7 ^ v8); }
+ pn(-1 == 3 * 2 | 3 | 2 << 2 <= 6);
+ { int v0 = -1, v1 = 3, v2 = 2, v3 = 3, v4 = 2, v5 = 2, v6 = 6; pn(v0 == v1 * v2 | v3 | v4 << v5 <= v6); }
+ pn(5 < 1 << 7 | 6 * 1 == 0 << 2 + -1 + -1);
+ { int v0 = 5, v1 = 1, v2 = 7, v3 = 6, v4 = 1, v5 = 0, v6 = 2, v7 = -1, v8 = -1; pn(v0 < v1 << v2 | v3 * v4 == v5 << v6 + v7 + v8); }
+ pn(-1 > 1 < 1 >> 3 - 7 << 7 == 6 | 3 < 5 + 7);
+ { int v0 = -1, v1 = 1, v2 = 1, v3 = 3, v4 = 7, v5 = 7, v6 = 6, v7 = 3, v8 = 5, v9 = 7; pn(v0 > v1 < v2 >> v3 - v4 << v5 == v6 | v7 < v8 + v9); }
+ pn(7 * 1 < 3 ^ 3 != 9 < 4 >= 9);
+ { int v0 = 7, v1 = 1, v2 = 3, v3 = 3, v4 = 9, v5 = 4, v6 = 9; pn(v0 * v1 < v2 ^ v3 != v4 < v5 >= v6); }
+ pn(2 <= 4 ^ 0 * 6 < 5 + 5 > 12);
+ { int v0 = 2, v1 = 4, v2 = 0, v3 = 6, v4 = 5, v5 = 5, v6 = 12; pn(v0 <= v1 ^ v2 * v3 < v4 + v5 > v6); }
+ pn(-2 + 2 | 5 > -2 < 12 * 6 ^ 6);
+ { int v0 = -2, v1 = 2, v2 = 5, v3 = -2, v4 = 12, v5 = 6, v6 = 6; pn(v0 + v1 | v2 > v3 < v4 * v5 ^ v6); }
+ pn(4 == 12 == 12 < 2 != -1 - 9);
+ { int v0 = 4, v1 = 12, v2 = 12, v3 = 2, v4 = -1, v5 = 9; pn(v0 == v1 == v2 < v3 != v4 - v5); }
+ pn(5 | 3 - 12 & 6 | 1);
+ { int v0 = 5, v1 = 3, v2 = 12, v3 = 6, v4 = 1; pn(v0 | v1 - v2 & v3 | v4); }
+ pn(-2 >> 3 | 9 & 12 < 6 < -1 ^ -1 + 2 << 4 < 7);
+ { int v0 = -2, v1 = 3, v2 = 9, v3 = 12, v4 = 6, v5 = -1, v6 = -1, v7 = 2, v8 = 4, v9 = 7; pn(v0 >> v1 | v2 & v3 < v4 < v5 ^ v6 + v7 << v8 < v9); }
+ pn(6 && 2 + 9 < -1 > 12 | 3 <= 9 != 2 <= -1);
+ { int v0 = 6, v1 = 2, v2 = 9, v3 = -1, v4 = 12, v5 = 3, v6 = 9, v7 = 2, v8 = -1; pn(v0 && v1 + v2 < v3 > v4 | v5 <= v6 != v7 <= v8); }
+ pn(2 & 1 * 2 - 1 | 0);
+ { int v0 = 2, v1 = 1, v2 = 2, v3 = 1, v4 = 0; pn(v0 & v1 * v2 - v3 | v4); }
+ pn(3 ^ 2 - -2 || 2 != 9 && 12 + -1 > 5);
+ { int v0 = 3, v1 = 2, v2 = -2, v3 = 2, v4 = 9, v5 = 12, v6 = -1, v7 = 5; pn(v0 ^ v1 - v2 || v3 != v4 && v5 + v6 > v7); }
+ pn(1 + 9 && 0 + 9 + 1 >= -2 << 6 == 5 - 2);
+ { int v0 = 1, v1 = 9, v2 = 0, v3 = 9, v4 = 1, v5 = -2, v6 = 6, v7 = 5, v8 = 2; pn(v0 + v1 && v2 + v3 + v4 >= v5 << v6 == v7 - v8); }
+ pn(9 != 3 || 7 + 12 < 1 > 2);
+ { int v0 = 9, v1 = 3, v2 = 7, v3 = 12, v4 = 1, v5 = 2; pn(v0 != v1 || v2 + v3 < v4 > v5); }
+ return 0;
+}
diff --git a/tests/conformance/3-expressions/prec_compound_assign_right.zc b/tests/conformance/3-expressions/prec_compound_assign_right.zc
new file mode 100644
index 0000000..3dee965
--- /dev/null
+++ b/tests/conformance/3-expressions/prec_compound_assign_right.zc
@@ -0,0 +1,9 @@
+// expect: 12/3/
+include rt;
+void pn(int x) { rt.put_n(x); rt.put_c(10); }
+fn main() {
+ int a = 2, b = 3;
+ a *= b += 3;
+ pn(a); pn(b - 3);
+ return 0;
+}
diff --git a/tests/conformance/3-expressions/prec_deref_postfix.zc b/tests/conformance/3-expressions/prec_deref_postfix.zc
new file mode 100644
index 0000000..2a3355f
--- /dev/null
+++ b/tests/conformance/3-expressions/prec_deref_postfix.zc
@@ -0,0 +1,12 @@
+// expect: 5/6/8/
+include rt;
+void pn(int x) { rt.put_n(x); rt.put_c(10); }
+fn main() {
+ int[3] a = {5, 6, 7};
+ int* p = a;
+ pn(*p);
+ pn(*p + 1);
+ pn(*p++ + 3);
+ return 0;
+}
+// zc0: skip
diff --git a/tests/conformance/3-expressions/prec_left_add.zc b/tests/conformance/3-expressions/prec_left_add.zc
new file mode 100644
index 0000000..f3c7da6
--- /dev/null
+++ b/tests/conformance/3-expressions/prec_left_add.zc
@@ -0,0 +1,39 @@
+// expect: 1/1/1/1/101/101/3/3/4/4/0/0/1/1/0/0/1/1/1/1/1/1/872/872/-1/-1/76/76/-2/-2/-8/-8/
+// first operator + followed by each other binary operator; operands chosen so that the two groupings differ
+include rt;
+void pn(int x) { rt.put_n(x); rt.put_c(10); }
+fn main() {
+ pn(2 + -8 || 100);
+ { int a = 2, b = -8, c = 100; pn(a + b || c); }
+ pn(9 + 0 && -8);
+ { int a = 9, b = 0, c = -8; pn(a + b && c); }
+ pn(100 + -3 | 5);
+ { int a = 100, b = -3, c = 5; pn(a + b | c); }
+ pn(5 + -8 ^ -2);
+ { int a = 5, b = -8, c = -2; pn(a + b ^ c); }
+ pn(5 + 0 & 6);
+ { int a = 5, b = 0, c = 6; pn(a + b & c); }
+ pn(8 + 4 == -2);
+ { int a = 8, b = 4, c = -2; pn(a + b == c); }
+ pn(5 + 6 != 100);
+ { int a = 5, b = 6, c = 100; pn(a + b != c); }
+ pn(3 + 100 < 12);
+ { int a = 3, b = 100, c = 12; pn(a + b < c); }
+ pn(6 + 4 > -8);
+ { int a = 6, b = 4, c = -8; pn(a + b > c); }
+ pn(5 + -2 <= 100);
+ { int a = 5, b = -2, c = 100; pn(a + b <= c); }
+ pn(6 + 7 >= 2);
+ { int a = 6, b = 7, c = 2; pn(a + b >= c); }
+ pn(100 + 9 << 3);
+ { int a = 100, b = 9, c = 3; pn(a + b << c); }
+ pn(4 + -8 >> 3);
+ { int a = 4, b = -8, c = 3; pn(a + b >> c); }
+ pn(100 + 12 * -2);
+ { int a = 100, b = 12, c = -2; pn(a + b * c); }
+ pn(-2 + 3 / 12);
+ { int a = -2, b = 3, c = 12; pn(a + b / c); }
+ pn(-8 + 3 % 1);
+ { int a = -8, b = 3, c = 1; pn(a + b % c); }
+ return 0;
+}
diff --git a/tests/conformance/3-expressions/prec_left_and.zc b/tests/conformance/3-expressions/prec_left_and.zc
new file mode 100644
index 0000000..32a00cc
--- /dev/null
+++ b/tests/conformance/3-expressions/prec_left_and.zc
@@ -0,0 +1,41 @@
+// expect: 1/1/1/1/7/7/-6/-6/1/1/0/0/0/0/1/1/0/0/0/0/12/12/5/5/0/0/4/4/0/0/0/0/0/0/
+// first operator & followed by each other binary operator; operands chosen so that the two groupings differ
+include rt;
+void pn(int x) { rt.put_n(x); rt.put_c(10); }
+fn main() {
+ pn(-2 & 3 || 4);
+ { int a = -2, b = 3, c = 4; pn(a & b || c); }
+ pn(4 & -1 && 12);
+ { int a = 4, b = -1, c = 12; pn(a & b && c); }
+ pn(4 & 2 | 7);
+ { int a = 4, b = 2, c = 7; pn(a & b | c); }
+ pn(4 & 100 ^ -2);
+ { int a = 4, b = 100, c = -2; pn(a & b ^ c); }
+ pn(9 & 12 == 12);
+ { int a = 9, b = 12, c = 12; pn(a & b == c); }
+ pn(100 & 8 != -2);
+ { int a = 100, b = 8, c = -2; pn(a & b != c); }
+ pn(0 & 8 < 1);
+ { int a = 0, b = 8, c = 1; pn(a & b < c); }
+ pn(5 & 8 > 4);
+ { int a = 5, b = 8, c = 4; pn(a & b > c); }
+ pn(4 & 8 <= 2);
+ { int a = 4, b = 8, c = 2; pn(a & b <= c); }
+ pn(4 & -2 >= -1);
+ { int a = 4, b = -2, c = -1; pn(a & b >= c); }
+ pn(-3 & 3 << 2);
+ { int a = -3, b = 3, c = 2; pn(a & b << c); }
+ pn(5 & -1 >> 2);
+ { int a = 5, b = -1, c = 2; pn(a & b >> c); }
+ pn(0 & 9 + 2);
+ { int a = 0, b = 9, c = 2; pn(a & b + c); }
+ pn(5 & 4 - 6);
+ { int a = 5, b = 4, c = 6; pn(a & b - c); }
+ pn(1 & 5 * 2);
+ { int a = 1, b = 5, c = 2; pn(a & b * c); }
+ pn(12 & 9 / 3);
+ { int a = 12, b = 9, c = 3; pn(a & b / c); }
+ pn(12 & 5 % 5);
+ { int a = 12, b = 5, c = 5; pn(a & b % c); }
+ return 0;
+}
diff --git a/tests/conformance/3-expressions/prec_left_andand.zc b/tests/conformance/3-expressions/prec_left_andand.zc
new file mode 100644
index 0000000..3e7a456
--- /dev/null
+++ b/tests/conformance/3-expressions/prec_left_andand.zc
@@ -0,0 +1,41 @@
+// expect: 1/1/1/1/0/0/1/1/0/0/0/0/0/0/0/0/0/0/1/1/1/1/1/1/1/1/1/1/1/1/1/1/0/0/
+// first operator && followed by each other binary operator; operands chosen so that the two groupings differ
+include rt;
+void pn(int x) { rt.put_n(x); rt.put_c(10); }
+fn main() {
+ pn(0 && 6 || 8);
+ { int a = 0, b = 6, c = 8; pn(a && b || c); }
+ pn(5 && 4 | 4);
+ { int a = 5, b = 4, c = 4; pn(a && b | c); }
+ pn(3 && 7 ^ 7);
+ { int a = 3, b = 7, c = 7; pn(a && b ^ c); }
+ pn(-2 && 12 & 6);
+ { int a = -2, b = 12, c = 6; pn(a && b & c); }
+ pn(-2 && 6 == 1);
+ { int a = -2, b = 6, c = 1; pn(a && b == c); }
+ pn(0 && 8 != 8);
+ { int a = 0, b = 8, c = 8; pn(a && b != c); }
+ pn(7 && 9 < 5);
+ { int a = 7, b = 9, c = 5; pn(a && b < c); }
+ pn(3 && -3 > -2);
+ { int a = 3, b = -3, c = -2; pn(a && b > c); }
+ pn(1 && 12 <= 4);
+ { int a = 1, b = 12, c = 4; pn(a && b <= c); }
+ pn(7 && 4 >= 2);
+ { int a = 7, b = 4, c = 2; pn(a && b >= c); }
+ pn(-2 && 2 << 4);
+ { int a = -2, b = 2, c = 4; pn(a && b << c); }
+ pn(-3 && 9 >> 3);
+ { int a = -3, b = 9, c = 3; pn(a && b >> c); }
+ pn(5 && -3 + 4);
+ { int a = 5, b = -3, c = 4; pn(a && b + c); }
+ pn(8 && -1 - 6);
+ { int a = 8, b = -1, c = 6; pn(a && b - c); }
+ pn(-2 && 3 * 7);
+ { int a = -2, b = 3, c = 7; pn(a && b * c); }
+ pn(-2 && 3 / -1);
+ { int a = -2, b = 3, c = -1; pn(a && b / c); }
+ pn(9 && 100 % 5);
+ { int a = 9, b = 100, c = 5; pn(a && b % c); }
+ return 0;
+}
diff --git a/tests/conformance/3-expressions/prec_left_div.zc b/tests/conformance/3-expressions/prec_left_div.zc
new file mode 100644
index 0000000..d2c30b1
--- /dev/null
+++ b/tests/conformance/3-expressions/prec_left_div.zc
@@ -0,0 +1,43 @@
+// expect: 1/1/1/1/7/7/8/8/12/12/1/1/1/1/0/0/0/0/1/1/1/1/48/48/0/0/-8/-8/-7/-7/3/3/0/0/1/1/
+// first operator / followed by each other binary operator; operands chosen so that the two groupings differ
+include rt;
+void pn(int x) { rt.put_n(x); rt.put_c(10); }
+fn main() {
+ pn(-2 / -8 || 5);
+ { int a = -2, b = -8, c = 5; pn(a / b || c); }
+ pn(-2 / -1 && 1);
+ { int a = -2, b = -1, c = 1; pn(a / b && c); }
+ pn(3 / 6 | 7);
+ { int a = 3, b = 6, c = 7; pn(a / b | c); }
+ pn(-1 / -1 ^ 9);
+ { int a = -1, b = -1, c = 9; pn(a / b ^ c); }
+ pn(12 / 1 & -2);
+ { int a = 12, b = 1, c = -2; pn(a / b & c); }
+ pn(-1 / 9 == 0);
+ { int a = -1, b = 9, c = 0; pn(a / b == c); }
+ pn(100 / 0 != 6);
+ { int a = 100, b = 0, c = 6; pn(a / b != c); }
+ pn(7 / -3 < -2);
+ { int a = 7, b = -3, c = -2; pn(a / b < c); }
+ pn(4 / 7 > 6);
+ { int a = 4, b = 7, c = 6; pn(a / b > c); }
+ pn(-8 / 5 <= -1);
+ { int a = -8, b = 5, c = -1; pn(a / b <= c); }
+ pn(100 / 0 >= -3);
+ { int a = 100, b = 0, c = -3; pn(a / b >= c); }
+ pn(100 / 8 << 2);
+ { int a = 100, b = 8, c = 2; pn(a / b << c); }
+ pn(7 / 12 >> 2);
+ { int a = 7, b = 12, c = 2; pn(a / b >> c); }
+ pn(8 / 12 + -8);
+ { int a = 8, b = 12, c = -8; pn(a / b + c); }
+ pn(4 / 7 - 7);
+ { int a = 4, b = 7, c = 7; pn(a / b - c); }
+ pn(12 / 12 * 3);
+ { int a = 12, b = 12, c = 3; pn(a / b * c); }
+ pn(1 / 8 / -8);
+ { int a = 1, b = 8, c = -8; pn(a / b / c); }
+ pn(9 / 1 % -2);
+ { int a = 9, b = 1, c = -2; pn(a / b % c); }
+ return 0;
+}
diff --git a/tests/conformance/3-expressions/prec_left_eq.zc b/tests/conformance/3-expressions/prec_left_eq.zc
new file mode 100644
index 0000000..2a436e6
--- /dev/null
+++ b/tests/conformance/3-expressions/prec_left_eq.zc
@@ -0,0 +1,43 @@
+// expect: 1/1/0/0/-7/-7/6/6/0/0/1/1/1/1/0/0/0/0/0/0/0/0/0/0/1/1/0/0/0/0/0/0/0/0/1/1/
+// first operator == followed by each other binary operator; operands chosen so that the two groupings differ
+include rt;
+void pn(int x) { rt.put_n(x); rt.put_c(10); }
+fn main() {
+ pn(6 == 100 || 7);
+ { int a = 6, b = 100, c = 7; pn(a == b || c); }
+ pn(1 == 8 && 7);
+ { int a = 1, b = 8, c = 7; pn(a == b && c); }
+ pn(-2 == -2 | -8);
+ { int a = -2, b = -2, c = -8; pn(a == b | c); }
+ pn(5 == 5 ^ 7);
+ { int a = 5, b = 5, c = 7; pn(a == b ^ c); }
+ pn(4 == 4 & 100);
+ { int a = 4, b = 4, c = 100; pn(a == b & c); }
+ pn(4 == 4 == 1);
+ { int a = 4, b = 4, c = 1; pn(a == b == c); }
+ pn(7 == -1 != -1);
+ { int a = 7, b = -1, c = -1; pn(a == b != c); }
+ pn(100 == 0 < 8);
+ { int a = 100, b = 0, c = 8; pn(a == b < c); }
+ pn(5 == -8 > -2);
+ { int a = 5, b = -8, c = -2; pn(a == b > c); }
+ pn(6 == 1 <= 3);
+ { int a = 6, b = 1, c = 3; pn(a == b <= c); }
+ pn(100 == 2 >= -8);
+ { int a = 100, b = 2, c = -8; pn(a == b >= c); }
+ pn(9 == 9 << 5);
+ { int a = 9, b = 9, c = 5; pn(a == b << c); }
+ pn(2 == 8 >> 2);
+ { int a = 2, b = 8, c = 2; pn(a == b >> c); }
+ pn(2 == 6 + -2);
+ { int a = 2, b = 6, c = -2; pn(a == b + c); }
+ pn(9 == 12 - -8);
+ { int a = 9, b = 12, c = -8; pn(a == b - c); }
+ pn(1 == 1 * -2);
+ { int a = 1, b = 1, c = -2; pn(a == b * c); }
+ pn(-8 == -8 / -1);
+ { int a = -8, b = -8, c = -1; pn(a == b / c); }
+ pn(0 == 9 % 9);
+ { int a = 0, b = 9, c = 9; pn(a == b % c); }
+ return 0;
+}
diff --git a/tests/conformance/3-expressions/prec_left_ge.zc b/tests/conformance/3-expressions/prec_left_ge.zc
new file mode 100644
index 0000000..c5b2d73
--- /dev/null
+++ b/tests/conformance/3-expressions/prec_left_ge.zc
@@ -0,0 +1,43 @@
+// expect: 1/1/0/0/5/5/-3/-3/0/0/0/0/1/1/0/0/0/0/0/0/0/0/1/1/1/1/0/0/0/0/0/0/1/1/1/1/
+// first operator >= followed by each other binary operator; operands chosen so that the two groupings differ
+include rt;
+void pn(int x) { rt.put_n(x); rt.put_c(10); }
+fn main() {
+ pn(-8 >= 8 || 7);
+ { int a = -8, b = 8, c = 7; pn(a >= b || c); }
+ pn(5 >= 12 && 2);
+ { int a = 5, b = 12, c = 2; pn(a >= b && c); }
+ pn(6 >= 7 | 5);
+ { int a = 6, b = 7, c = 5; pn(a >= b | c); }
+ pn(-1 >= 5 ^ -3);
+ { int a = -1, b = 5, c = -3; pn(a >= b ^ c); }
+ pn(9 >= 12 & 8);
+ { int a = 9, b = 12, c = 8; pn(a >= b & c); }
+ pn(1 >= 12 == 12);
+ { int a = 1, b = 12, c = 12; pn(a >= b == c); }
+ pn(-3 >= -2 != 5);
+ { int a = -3, b = -2, c = 5; pn(a >= b != c); }
+ pn(0 >= 1 < 0);
+ { int a = 0, b = 1, c = 0; pn(a >= b < c); }
+ pn(5 >= 100 > 5);
+ { int a = 5, b = 100, c = 5; pn(a >= b > c); }
+ pn(12 >= 12 <= -1);
+ { int a = 12, b = 12, c = -1; pn(a >= b <= c); }
+ pn(1 >= 9 >= 7);
+ { int a = 1, b = 9, c = 7; pn(a >= b >= c); }
+ pn(6 >= -1 << 7);
+ { int a = 6, b = -1, c = 7; pn(a >= b << c); }
+ pn(6 >= 100 >> 5);
+ { int a = 6, b = 100, c = 5; pn(a >= b >> c); }
+ pn(4 >= 1 + 8);
+ { int a = 4, b = 1, c = 8; pn(a >= b + c); }
+ pn(-1 >= 9 - -8);
+ { int a = -1, b = 9, c = -8; pn(a >= b - c); }
+ pn(7 >= 4 * 5);
+ { int a = 7, b = 4, c = 5; pn(a >= b * c); }
+ pn(2 >= 8 / 0);
+ { int a = 2, b = 8, c = 0; pn(a >= b / c); }
+ pn(7 >= 9 % 5);
+ { int a = 7, b = 9, c = 5; pn(a >= b % c); }
+ return 0;
+}
diff --git a/tests/conformance/3-expressions/prec_left_gt.zc b/tests/conformance/3-expressions/prec_left_gt.zc
new file mode 100644
index 0000000..138989c
--- /dev/null
+++ b/tests/conformance/3-expressions/prec_left_gt.zc
@@ -0,0 +1,43 @@
+// expect: 1/1/0/0/-1/-1/-8/-8/0/0/0/0/1/1/1/1/0/0/0/0/1/1/0/0/1/1/0/0/0/0/0/0/1/1/1/1/
+// first operator > followed by each other binary operator; operands chosen so that the two groupings differ
+include rt;
+void pn(int x) { rt.put_n(x); rt.put_c(10); }
+fn main() {
+ pn(0 > 2 || 2);
+ { int a = 0, b = 2, c = 2; pn(a > b || c); }
+ pn(5 > 7 && 3);
+ { int a = 5, b = 7, c = 3; pn(a > b && c); }
+ pn(-1 > 5 | -1);
+ { int a = -1, b = 5, c = -1; pn(a > b | c); }
+ pn(7 > 8 ^ -8);
+ { int a = 7, b = 8, c = -8; pn(a > b ^ c); }
+ pn(12 > 1 & 12);
+ { int a = 12, b = 1, c = 12; pn(a > b & c); }
+ pn(3 > 8 == 4);
+ { int a = 3, b = 8, c = 4; pn(a > b == c); }
+ pn(-8 > 1 != 8);
+ { int a = -8, b = 1, c = 8; pn(a > b != c); }
+ pn(-3 > 7 < 1);
+ { int a = -3, b = 7, c = 1; pn(a > b < c); }
+ pn(100 > 9 > 3);
+ { int a = 100, b = 9, c = 3; pn(a > b > c); }
+ pn(3 > -3 <= -8);
+ { int a = 3, b = -3, c = -8; pn(a > b <= c); }
+ pn(-1 > 100 >= -8);
+ { int a = -1, b = 100, c = -8; pn(a > b >= c); }
+ pn(9 > 4 << 2);
+ { int a = 9, b = 4, c = 2; pn(a > b << c); }
+ pn(3 > -1 >> 5);
+ { int a = 3, b = -1, c = 5; pn(a > b >> c); }
+ pn(-3 > 7 + 9);
+ { int a = -3, b = 7, c = 9; pn(a > b + c); }
+ pn(-2 > 2 - -2);
+ { int a = -2, b = 2, c = -2; pn(a > b - c); }
+ pn(0 > -3 * -8);
+ { int a = 0, b = -3, c = -8; pn(a > b * c); }
+ pn(1 > 8 / -1);
+ { int a = 1, b = 8, c = -1; pn(a > b / c); }
+ pn(4 > 4 % 1);
+ { int a = 4, b = 4, c = 1; pn(a > b % c); }
+ return 0;
+}
diff --git a/tests/conformance/3-expressions/prec_left_le.zc b/tests/conformance/3-expressions/prec_left_le.zc
new file mode 100644
index 0000000..e204439
--- /dev/null
+++ b/tests/conformance/3-expressions/prec_left_le.zc
@@ -0,0 +1,43 @@
+// expect: 1/1/1/1/-7/-7/7/7/0/0/0/0/1/1/1/1/0/0/0/0/0/0/1/1/1/1/0/0/0/0/0/0/1/1/0/0/
+// first operator <= followed by each other binary operator; operands chosen so that the two groupings differ
+include rt;
+void pn(int x) { rt.put_n(x); rt.put_c(10); }
+fn main() {
+ pn(12 <= 0 || 4);
+ { int a = 12, b = 0, c = 4; pn(a <= b || c); }
+ pn(3 <= 7 && -1);
+ { int a = 3, b = 7, c = -1; pn(a <= b && c); }
+ pn(4 <= 6 | -8);
+ { int a = 4, b = 6, c = -8; pn(a <= b | c); }
+ pn(0 <= 8 ^ 6);
+ { int a = 0, b = 8, c = 6; pn(a <= b ^ c); }
+ pn(-8 <= 12 & 4);
+ { int a = -8, b = 12, c = 4; pn(a <= b & c); }
+ pn(-3 <= -2 == 6);
+ { int a = -3, b = -2, c = 6; pn(a <= b == c); }
+ pn(6 <= 3 != -2);
+ { int a = 6, b = 3, c = -2; pn(a <= b != c); }
+ pn(9 <= -8 < 1);
+ { int a = 9, b = -8, c = 1; pn(a <= b < c); }
+ pn(-3 <= -1 > 9);
+ { int a = -3, b = -1, c = 9; pn(a <= b > c); }
+ pn(-8 <= 9 <= 0);
+ { int a = -8, b = 9, c = 0; pn(a <= b <= c); }
+ pn(-8 <= 9 >= 6);
+ { int a = -8, b = 9, c = 6; pn(a <= b >= c); }
+ pn(-3 <= 3 << 2);
+ { int a = -3, b = 3, c = 2; pn(a <= b << c); }
+ pn(-2 <= 3 >> 1);
+ { int a = -2, b = 3, c = 1; pn(a <= b >> c); }
+ pn(4 <= -2 + -3);
+ { int a = 4, b = -2, c = -3; pn(a <= b + c); }
+ pn(6 <= -3 - 3);
+ { int a = 6, b = -3, c = 3; pn(a <= b - c); }
+ pn(-3 <= -2 * 3);
+ { int a = -3, b = -2, c = 3; pn(a <= b * c); }
+ pn(0 <= 9 / 2);
+ { int a = 0, b = 9, c = 2; pn(a <= b / c); }
+ pn(3 <= 8 % 7);
+ { int a = 3, b = 8, c = 7; pn(a <= b % c); }
+ return 0;
+}
diff --git a/tests/conformance/3-expressions/prec_left_lt.zc b/tests/conformance/3-expressions/prec_left_lt.zc
new file mode 100644
index 0000000..36a0c5f
--- /dev/null
+++ b/tests/conformance/3-expressions/prec_left_lt.zc
@@ -0,0 +1,43 @@
+// expect: 1/1/1/1/-7/-7/6/6/0/0/1/1/1/1/1/1/0/0/1/1/0/0/1/1/1/1/0/0/1/1/1/1/1/1/1/1/
+// first operator < followed by each other binary operator; operands chosen so that the two groupings differ
+include rt;
+void pn(int x) { rt.put_n(x); rt.put_c(10); }
+fn main() {
+ pn(6 < 9 || 7);
+ { int a = 6, b = 9, c = 7; pn(a < b || c); }
+ pn(1 < 7 && -2);
+ { int a = 1, b = 7, c = -2; pn(a < b && c); }
+ pn(3 < 12 | -8);
+ { int a = 3, b = 12, c = -8; pn(a < b | c); }
+ pn(7 < 12 ^ 7);
+ { int a = 7, b = 12, c = 7; pn(a < b ^ c); }
+ pn(7 < -3 & 9);
+ { int a = 7, b = -3, c = 9; pn(a < b & c); }
+ pn(7 < 7 == 0);
+ { int a = 7, b = 7, c = 0; pn(a < b == c); }
+ pn(3 < 2 != 1);
+ { int a = 3, b = 2, c = 1; pn(a < b != c); }
+ pn(4 < 100 < 4);
+ { int a = 4, b = 100, c = 4; pn(a < b < c); }
+ pn(-1 < 8 > 6);
+ { int a = -1, b = 8, c = 6; pn(a < b > c); }
+ pn(6 < 7 <= 9);
+ { int a = 6, b = 7, c = 9; pn(a < b <= c); }
+ pn(-1 < 0 >= 8);
+ { int a = -1, b = 0, c = 8; pn(a < b >= c); }
+ pn(9 < 12 << 6);
+ { int a = 9, b = 12, c = 6; pn(a < b << c); }
+ pn(-3 < 0 >> 4);
+ { int a = -3, b = 0, c = 4; pn(a < b >> c); }
+ pn(4 < -2 + 1);
+ { int a = 4, b = -2, c = 1; pn(a < b + c); }
+ pn(-8 < 4 - 2);
+ { int a = -8, b = 4, c = 2; pn(a < b - c); }
+ pn(6 < 3 * 3);
+ { int a = 6, b = 3, c = 3; pn(a < b * c); }
+ pn(-1 < 100 / 6);
+ { int a = -1, b = 100, c = 6; pn(a < b / c); }
+ pn(-2 < -8 % -2);
+ { int a = -2, b = -8, c = -2; pn(a < b % c); }
+ return 0;
+}
diff --git a/tests/conformance/3-expressions/prec_left_mod.zc b/tests/conformance/3-expressions/prec_left_mod.zc
new file mode 100644
index 0000000..a69cf77
--- /dev/null
+++ b/tests/conformance/3-expressions/prec_left_mod.zc
@@ -0,0 +1,43 @@
+// expect: 1/1/1/1/-7/-7/1/1/-4/-4/0/0/1/1/1/1/0/0/1/1/0/0/0/0/-2/-2/-2/-2/-9/-9/4/4/0/0/1/1/
+// first operator % followed by each other binary operator; operands chosen so that the two groupings differ
+include rt;
+void pn(int x) { rt.put_n(x); rt.put_c(10); }
+fn main() {
+ pn(2 % 5 || 2);
+ { int a = 2, b = 5, c = 2; pn(a % b || c); }
+ pn(-1 % 100 && 100);
+ { int a = -1, b = 100, c = 100; pn(a % b && c); }
+ pn(7 % 6 | -8);
+ { int a = 7, b = 6, c = -8; pn(a % b | c); }
+ pn(3 % 100 ^ 2);
+ { int a = 3, b = 100, c = 2; pn(a % b ^ c); }
+ pn(-2 % -8 & -3);
+ { int a = -2, b = -8, c = -3; pn(a % b & c); }
+ pn(9 % 6 == 2);
+ { int a = 9, b = 6, c = 2; pn(a % b == c); }
+ pn(7 % 8 != -8);
+ { int a = 7, b = 8, c = -8; pn(a % b != c); }
+ pn(9 % 9 < 3);
+ { int a = 9, b = 9, c = 3; pn(a % b < c); }
+ pn(5 % -8 > 100);
+ { int a = 5, b = -8, c = 100; pn(a % b > c); }
+ pn(8 % -8 <= 0);
+ { int a = 8, b = -8, c = 0; pn(a % b <= c); }
+ pn(-1 % -2 >= 5);
+ { int a = -1, b = -2, c = 5; pn(a % b >= c); }
+ pn(100 % 5 << 6);
+ { int a = 100, b = 5, c = 6; pn(a % b << c); }
+ pn(-8 % 0 >> 2);
+ { int a = -8, b = 0, c = 2; pn(a % b >> c); }
+ pn(-1 % 0 + -1);
+ { int a = -1, b = 0, c = -1; pn(a % b + c); }
+ pn(-3 % 3 - 9);
+ { int a = -3, b = 3, c = 9; pn(a % b - c); }
+ pn(5 % 2 * 4);
+ { int a = 5, b = 2, c = 4; pn(a % b * c); }
+ pn(-8 % 5 / 100);
+ { int a = -8, b = 5, c = 100; pn(a % b / c); }
+ pn(5 % 4 % 2);
+ { int a = 5, b = 4, c = 2; pn(a % b % c); }
+ return 0;
+}
diff --git a/tests/conformance/3-expressions/prec_left_mul.zc b/tests/conformance/3-expressions/prec_left_mul.zc
new file mode 100644
index 0000000..4e2dacc
--- /dev/null
+++ b/tests/conformance/3-expressions/prec_left_mul.zc
@@ -0,0 +1,39 @@
+// expect: 1/1/1/1/-2/-2/27/27/0/0/0/0/1/1/1/1/1/1/1/1/1/1/4/4/106/106/7/7/-36/-36/0/0/
+// first operator * followed by each other binary operator; operands chosen so that the two groupings differ
+include rt;
+void pn(int x) { rt.put_n(x); rt.put_c(10); }
+fn main() {
+ pn(4 * -2 || -8);
+ { int a = 4, b = -2, c = -8; pn(a * b || c); }
+ pn(4 * 12 && 100);
+ { int a = 4, b = 12, c = 100; pn(a * b && c); }
+ pn(-2 * 5 | -2);
+ { int a = -2, b = 5, c = -2; pn(a * b | c); }
+ pn(4 * 7 ^ 7);
+ { int a = 4, b = 7, c = 7; pn(a * b ^ c); }
+ pn(6 * 8 & 9);
+ { int a = 6, b = 8, c = 9; pn(a * b & c); }
+ pn(-3 * 8 == 8);
+ { int a = -3, b = 8, c = 8; pn(a * b == c); }
+ pn(6 * 5 != -2);
+ { int a = 6, b = 5, c = -2; pn(a * b != c); }
+ pn(8 * -2 < -3);
+ { int a = 8, b = -2, c = -3; pn(a * b < c); }
+ pn(-2 * -3 > 3);
+ { int a = -2, b = -3, c = 3; pn(a * b > c); }
+ pn(-3 * 9 <= 2);
+ { int a = -3, b = 9, c = 2; pn(a * b <= c); }
+ pn(2 * 12 >= 9);
+ { int a = 2, b = 12, c = 9; pn(a * b >= c); }
+ pn(3 * 100 >> 6);
+ { int a = 3, b = 100, c = 6; pn(a * b >> c); }
+ pn(-3 * -2 + 100);
+ { int a = -3, b = -2, c = 100; pn(a * b + c); }
+ pn(-2 * -2 - -3);
+ { int a = -2, b = -2, c = -3; pn(a * b - c); }
+ pn(-8 * 9 / 2);
+ { int a = -8, b = 9, c = 2; pn(a * b / c); }
+ pn(6 * 9 % 6);
+ { int a = 6, b = 9, c = 6; pn(a * b % c); }
+ return 0;
+}
diff --git a/tests/conformance/3-expressions/prec_left_ne.zc b/tests/conformance/3-expressions/prec_left_ne.zc
new file mode 100644
index 0000000..e14991f
--- /dev/null
+++ b/tests/conformance/3-expressions/prec_left_ne.zc
@@ -0,0 +1,43 @@
+// expect: 1/1/1/1/5/5/8/8/0/0/0/0/0/0/1/1/0/0/1/1/1/1/1/1/1/1/1/1/0/0/1/1/1/1/1/1/
+// first operator != followed by each other binary operator; operands chosen so that the two groupings differ
+include rt;
+void pn(int x) { rt.put_n(x); rt.put_c(10); }
+fn main() {
+ pn(1 != 12 || -1);
+ { int a = 1, b = 12, c = -1; pn(a != b || c); }
+ pn(1 != 5 && -8);
+ { int a = 1, b = 5, c = -8; pn(a != b && c); }
+ pn(1 != -3 | 5);
+ { int a = 1, b = -3, c = 5; pn(a != b | c); }
+ pn(2 != 6 ^ 9);
+ { int a = 2, b = 6, c = 9; pn(a != b ^ c); }
+ pn(6 != -3 & -8);
+ { int a = 6, b = -3, c = -8; pn(a != b & c); }
+ pn(2 != -8 == -1);
+ { int a = 2, b = -8, c = -1; pn(a != b == c); }
+ pn(7 != 0 != 1);
+ { int a = 7, b = 0, c = 1; pn(a != b != c); }
+ pn(4 != -1 < -3);
+ { int a = 4, b = -1, c = -3; pn(a != b < c); }
+ pn(1 != 2 > -2);
+ { int a = 1, b = 2, c = -2; pn(a != b > c); }
+ pn(8 != -8 <= -3);
+ { int a = 8, b = -8, c = -3; pn(a != b <= c); }
+ pn(3 != 6 >= 100);
+ { int a = 3, b = 6, c = 100; pn(a != b >= c); }
+ pn(2 != 4 << 7);
+ { int a = 2, b = 4, c = 7; pn(a != b << c); }
+ pn(4 != 12 >> 1);
+ { int a = 4, b = 12, c = 1; pn(a != b >> c); }
+ pn(1 != 4 + -2);
+ { int a = 1, b = 4, c = -2; pn(a != b + c); }
+ pn(-2 != 1 - 3);
+ { int a = -2, b = 1, c = 3; pn(a != b - c); }
+ pn(3 != 8 * -2);
+ { int a = 3, b = 8, c = -2; pn(a != b * c); }
+ pn(4 != 2 / 4);
+ { int a = 4, b = 2, c = 4; pn(a != b / c); }
+ pn(12 != 7 % 1);
+ { int a = 12, b = 7, c = 1; pn(a != b % c); }
+ return 0;
+}
diff --git a/tests/conformance/3-expressions/prec_left_or.zc b/tests/conformance/3-expressions/prec_left_or.zc
new file mode 100644
index 0000000..85b7181
--- /dev/null
+++ b/tests/conformance/3-expressions/prec_left_or.zc
@@ -0,0 +1,41 @@
+// expect: 1/1/1/1/-2/-2/13/13/1/1/5/5/-1/-1/9/9/101/101/-3/-3/-186/-186/101/101/-7/-7/-3/-3/-1/-1/-1/-1/11/11/
+// first operator | followed by each other binary operator; operands chosen so that the two groupings differ
+include rt;
+void pn(int x) { rt.put_n(x); rt.put_c(10); }
+fn main() {
+ pn(-1 | 0 || 1);
+ { int a = -1, b = 0, c = 1; pn(a | b || c); }
+ pn(3 | 0 && 7);
+ { int a = 3, b = 0, c = 7; pn(a | b && c); }
+ pn(-2 | 0 ^ -2);
+ { int a = -2, b = 0, c = -2; pn(a | b ^ c); }
+ pn(12 | 7 & 1);
+ { int a = 12, b = 7, c = 1; pn(a | b & c); }
+ pn(1 | -3 == 2);
+ { int a = 1, b = -3, c = 2; pn(a | b == c); }
+ pn(5 | 5 != -8);
+ { int a = 5, b = 5, c = -8; pn(a | b != c); }
+ pn(-1 | 100 < 12);
+ { int a = -1, b = 100, c = 12; pn(a | b < c); }
+ pn(9 | -1 > 1);
+ { int a = 9, b = -1, c = 1; pn(a | b > c); }
+ pn(100 | 0 <= 4);
+ { int a = 100, b = 0, c = 4; pn(a | b <= c); }
+ pn(-3 | 6 >= 6);
+ { int a = -3, b = 6, c = 6; pn(a | b >= c); }
+ pn(6 | -3 << 6);
+ { int a = 6, b = -3, c = 6; pn(a | b << c); }
+ pn(100 | 7 >> 2);
+ { int a = 100, b = 7, c = 2; pn(a | b >> c); }
+ pn(-8 | 8 + 9);
+ { int a = -8, b = 8, c = 9; pn(a | b + c); }
+ pn(-3 | 1 - -3);
+ { int a = -3, b = 1, c = -3; pn(a | b - c); }
+ pn(-2 | -3 * 7);
+ { int a = -2, b = -3, c = 7; pn(a | b * c); }
+ pn(-3 | -2 / 2);
+ { int a = -3, b = -2, c = 2; pn(a | b / c); }
+ pn(9 | 2 % -8);
+ { int a = 9, b = 2, c = -8; pn(a | b % c); }
+ return 0;
+}
diff --git a/tests/conformance/3-expressions/prec_left_oror.zc b/tests/conformance/3-expressions/prec_left_oror.zc
new file mode 100644
index 0000000..5a70617
--- /dev/null
+++ b/tests/conformance/3-expressions/prec_left_oror.zc
@@ -0,0 +1,41 @@
+// expect: 1/1/1/1/1/1/1/1/1/1/1/1/1/1/1/1/1/1/1/1/1/1/1/1/1/1/1/1/1/1/1/1/1/1/
+// first operator || followed by each other binary operator; operands chosen so that the two groupings differ
+include rt;
+void pn(int x) { rt.put_n(x); rt.put_c(10); }
+fn main() {
+ pn(12 || 9 && 0);
+ { int a = 12, b = 9, c = 0; pn(a || b && c); }
+ pn(7 || 0 | 4);
+ { int a = 7, b = 0, c = 4; pn(a || b | c); }
+ pn(4 || -1 ^ 7);
+ { int a = 4, b = -1, c = 7; pn(a || b ^ c); }
+ pn(3 || -8 & 100);
+ { int a = 3, b = -8, c = 100; pn(a || b & c); }
+ pn(4 || 100 == -8);
+ { int a = 4, b = 100, c = -8; pn(a || b == c); }
+ pn(100 || -3 != 1);
+ { int a = 100, b = -3, c = 1; pn(a || b != c); }
+ pn(7 || 2 < -2);
+ { int a = 7, b = 2, c = -2; pn(a || b < c); }
+ pn(-1 || 0 > 4);
+ { int a = -1, b = 0, c = 4; pn(a || b > c); }
+ pn(100 || -3 <= -1);
+ { int a = 100, b = -3, c = -1; pn(a || b <= c); }
+ pn(1 || 8 >= 12);
+ { int a = 1, b = 8, c = 12; pn(a || b >= c); }
+ pn(-8 || 100 << 3);
+ { int a = -8, b = 100, c = 3; pn(a || b << c); }
+ pn(9 || 12 >> 2);
+ { int a = 9, b = 12, c = 2; pn(a || b >> c); }
+ pn(1 || -1 + 8);
+ { int a = 1, b = -1, c = 8; pn(a || b + c); }
+ pn(-3 || 100 - 100);
+ { int a = -3, b = 100, c = 100; pn(a || b - c); }
+ pn(12 || -2 * -3);
+ { int a = 12, b = -2, c = -3; pn(a || b * c); }
+ pn(-8 || 0 / -2);
+ { int a = -8, b = 0, c = -2; pn(a || b / c); }
+ pn(-1 || 4 % -1);
+ { int a = -1, b = 4, c = -1; pn(a || b % c); }
+ return 0;
+}
diff --git a/tests/conformance/3-expressions/prec_left_shl.zc b/tests/conformance/3-expressions/prec_left_shl.zc
new file mode 100644
index 0000000..78eef19
--- /dev/null
+++ b/tests/conformance/3-expressions/prec_left_shl.zc
@@ -0,0 +1,43 @@
+// expect: 1/1/0/0/72/72/36/36/0/0/0/0/1/1/0/0/1/1/1/1/1/1/-64/-64/32/32/2594073385365405696/2594073385365405696/900719925474099200/900719925474099200/-144115188075855872/-144115188075855872/2/2/-1/-1/
+// first operator << followed by each other binary operator; operands chosen so that the two groupings differ
+include rt;
+void pn(int x) { rt.put_n(x); rt.put_c(10); }
+fn main() {
+ pn(3 << 3 || 2);
+ { int a = 3, b = 3, c = 2; pn(a << b || c); }
+ pn(-8 << 7 && 0);
+ { int a = -8, b = 7, c = 0; pn(a << b && c); }
+ pn(4 << 4 | 8);
+ { int a = 4, b = 4, c = 8; pn(a << b | c); }
+ pn(1 << 6 ^ 100);
+ { int a = 1, b = 6, c = 100; pn(a << b ^ c); }
+ pn(3 << 5 & 1);
+ { int a = 3, b = 5, c = 1; pn(a << b & c); }
+ pn(2 << 3 == 6);
+ { int a = 2, b = 3, c = 6; pn(a << b == c); }
+ pn(-3 << 6 != 100);
+ { int a = -3, b = 6, c = 100; pn(a << b != c); }
+ pn(5 << 6 < 9);
+ { int a = 5, b = 6, c = 9; pn(a << b < c); }
+ pn(7 << 0 > 3);
+ { int a = 7, b = 0, c = 3; pn(a << b > c); }
+ pn(0 << 1 <= 3);
+ { int a = 0, b = 1, c = 3; pn(a << b <= c); }
+ pn(8 << 0 >= 3);
+ { int a = 8, b = 0, c = 3; pn(a << b >= c); }
+ pn(-1 << 1 << 5);
+ { int a = -1, b = 1, c = 5; pn(a << b << c); }
+ pn(4 << 5 >> 2);
+ { int a = 4, b = 5, c = 2; pn(a << b >> c); }
+ pn(9 << 2 + -8);
+ { int a = 9, b = 2, c = -8; pn(a << b + c); }
+ pn(100 << 1 - 12);
+ { int a = 100, b = 1, c = 12; pn(a << b - c); }
+ pn(-8 << 6 * 9);
+ { int a = -8, b = 6, c = 9; pn(a << b * c); }
+ pn(2 << 0 / 7);
+ { int a = 2, b = 0, c = 7; pn(a << b / c); }
+ pn(-1 << 5 % 5);
+ { int a = -1, b = 5, c = 5; pn(a << b % c); }
+ return 0;
+}
diff --git a/tests/conformance/3-expressions/prec_left_shr.zc b/tests/conformance/3-expressions/prec_left_shr.zc
new file mode 100644
index 0000000..e3de1cd
--- /dev/null
+++ b/tests/conformance/3-expressions/prec_left_shr.zc
@@ -0,0 +1,43 @@
+// expect: 1/1/1/1/-4/-4/-6/-6/0/0/0/0/1/1/1/1/1/1/1/1/0/0/-128/-128/0/0/0/0/-1/-1/0/0/4/4/7/7/
+// first operator >> followed by each other binary operator; operands chosen so that the two groupings differ
+include rt;
+void pn(int x) { rt.put_n(x); rt.put_c(10); }
+fn main() {
+ pn(9 >> 5 || 9);
+ { int a = 9, b = 5, c = 9; pn(a >> b || c); }
+ pn(100 >> 6 && -1);
+ { int a = 100, b = 6, c = -1; pn(a >> b && c); }
+ pn(4 >> 0 | -8);
+ { int a = 4, b = 0, c = -8; pn(a >> b | c); }
+ pn(-3 >> 1 ^ 4);
+ { int a = -3, b = 1, c = 4; pn(a >> b ^ c); }
+ pn(8 >> 3 & 0);
+ { int a = 8, b = 3, c = 0; pn(a >> b & c); }
+ pn(5 >> 2 == 9);
+ { int a = 5, b = 2, c = 9; pn(a >> b == c); }
+ pn(5 >> 7 != 1);
+ { int a = 5, b = 7, c = 1; pn(a >> b != c); }
+ pn(-3 >> 0 < -2);
+ { int a = -3, b = 0, c = -2; pn(a >> b < c); }
+ pn(100 >> 6 > -2);
+ { int a = 100, b = 6, c = -2; pn(a >> b > c); }
+ pn(-8 >> 0 <= -3);
+ { int a = -8, b = 0, c = -3; pn(a >> b <= c); }
+ pn(8 >> 7 >= 100);
+ { int a = 8, b = 7, c = 100; pn(a >> b >= c); }
+ pn(-3 >> 3 << 7);
+ { int a = -3, b = 3, c = 7; pn(a >> b << c); }
+ pn(6 >> 6 >> 5);
+ { int a = 6, b = 6, c = 5; pn(a >> b >> c); }
+ pn(0 >> 2 + 8);
+ { int a = 0, b = 2, c = 8; pn(a >> b + c); }
+ pn(-2 >> 0 - 4);
+ { int a = -2, b = 0, c = 4; pn(a >> b - c); }
+ pn(9 >> 3 * 8);
+ { int a = 9, b = 3, c = 8; pn(a >> b * c); }
+ pn(4 >> 0 / 4);
+ { int a = 4, b = 0, c = 4; pn(a >> b / c); }
+ pn(7 >> 7 % 1);
+ { int a = 7, b = 7, c = 1; pn(a >> b % c); }
+ return 0;
+}
diff --git a/tests/conformance/3-expressions/prec_left_sub.zc b/tests/conformance/3-expressions/prec_left_sub.zc
new file mode 100644
index 0000000..6cdb21d
--- /dev/null
+++ b/tests/conformance/3-expressions/prec_left_sub.zc
@@ -0,0 +1,43 @@
+// expect: 1/1/1/1/-1/-1/-13/-13/0/0/0/0/1/1/1/1/0/0/1/1/0/0/768/768/-3/-3/6/6/-16/-16/-28/-28/7/7/8/8/
+// first operator - followed by each other binary operator; operands chosen so that the two groupings differ
+include rt;
+void pn(int x) { rt.put_n(x); rt.put_c(10); }
+fn main() {
+ pn(5 - 6 || -1);
+ { int a = 5, b = 6, c = -1; pn(a - b || c); }
+ pn(-1 - 12 && -2);
+ { int a = -1, b = 12, c = -2; pn(a - b && c); }
+ pn(4 - 7 | -1);
+ { int a = 4, b = 7, c = -1; pn(a - b | c); }
+ pn(12 - -2 ^ -3);
+ { int a = 12, b = -2, c = -3; pn(a - b ^ c); }
+ pn(4 - 1 & 4);
+ { int a = 4, b = 1, c = 4; pn(a - b & c); }
+ pn(12 - 1 == 12);
+ { int a = 12, b = 1, c = 12; pn(a - b == c); }
+ pn(100 - 1 != 7);
+ { int a = 100, b = 1, c = 7; pn(a - b != c); }
+ pn(8 - -3 < 100);
+ { int a = 8, b = -3, c = 100; pn(a - b < c); }
+ pn(-1 - -3 > 2);
+ { int a = -1, b = -3, c = 2; pn(a - b > c); }
+ pn(1 - -2 <= 9);
+ { int a = 1, b = -2, c = 9; pn(a - b <= c); }
+ pn(8 - 9 >= 7);
+ { int a = 8, b = 9, c = 7; pn(a - b >= c); }
+ pn(7 - 1 << 7);
+ { int a = 7, b = 1, c = 7; pn(a - b << c); }
+ pn(0 - 9 >> 2);
+ { int a = 0, b = 9, c = 2; pn(a - b >> c); }
+ pn(5 - 7 + 8);
+ { int a = 5, b = 7, c = 8; pn(a - b + c); }
+ pn(-2 - 8 - 6);
+ { int a = -2, b = 8, c = 6; pn(a - b - c); }
+ pn(-8 - 5 * 4);
+ { int a = -8, b = 5, c = 4; pn(a - b * c); }
+ pn(7 - 5 / 6);
+ { int a = 7, b = 5, c = 6; pn(a - b / c); }
+ pn(6 - -2 % 6);
+ { int a = 6, b = -2, c = 6; pn(a - b % c); }
+ return 0;
+}
diff --git a/tests/conformance/3-expressions/prec_left_xor.zc b/tests/conformance/3-expressions/prec_left_xor.zc
new file mode 100644
index 0000000..a977688
--- /dev/null
+++ b/tests/conformance/3-expressions/prec_left_xor.zc
@@ -0,0 +1,41 @@
+// expect: 1/1/1/1/7/7/2/2/4/4/7/7/8/8/4/4/-3/-3/-2/-2/3/3/-3/-3/12/12/-8/-8/87/87/-2/-2/3/3/
+// first operator ^ followed by each other binary operator; operands chosen so that the two groupings differ
+include rt;
+void pn(int x) { rt.put_n(x); rt.put_c(10); }
+fn main() {
+ pn(5 ^ -8 || 9);
+ { int a = 5, b = -8, c = 9; pn(a ^ b || c); }
+ pn(-2 ^ 5 && -3);
+ { int a = -2, b = 5, c = -3; pn(a ^ b && c); }
+ pn(7 ^ 4 | 4);
+ { int a = 7, b = 4, c = 4; pn(a ^ b | c); }
+ pn(7 ^ -1 & 5);
+ { int a = 7, b = -1, c = 5; pn(a ^ b & c); }
+ pn(4 ^ 4 == 6);
+ { int a = 4, b = 4, c = 6; pn(a ^ b == c); }
+ pn(6 ^ -8 != 12);
+ { int a = 6, b = -8, c = 12; pn(a ^ b != c); }
+ pn(8 ^ -1 < -1);
+ { int a = 8, b = -1, c = -1; pn(a ^ b < c); }
+ pn(4 ^ 2 > 5);
+ { int a = 4, b = 2, c = 5; pn(a ^ b > c); }
+ pn(-3 ^ 8 <= 6);
+ { int a = -3, b = 8, c = 6; pn(a ^ b <= c); }
+ pn(-2 ^ -8 >= 1);
+ { int a = -2, b = -8, c = 1; pn(a ^ b >= c); }
+ pn(3 ^ 0 << 2);
+ { int a = 3, b = 0, c = 2; pn(a ^ b << c); }
+ pn(2 ^ -2 >> 2);
+ { int a = 2, b = -2, c = 2; pn(a ^ b >> c); }
+ pn(9 ^ -2 + 7);
+ { int a = 9, b = -2, c = 7; pn(a ^ b + c); }
+ pn(3 ^ -8 - -3);
+ { int a = 3, b = -8, c = -3; pn(a ^ b - c); }
+ pn(6 ^ 9 * 9);
+ { int a = 6, b = 9, c = 9; pn(a ^ b * c); }
+ pn(-2 ^ -2 / -8);
+ { int a = -2, b = -2, c = -8; pn(a ^ b / c); }
+ pn(3 ^ 12 % -3);
+ { int a = 3, b = 12, c = -3; pn(a ^ b % c); }
+ return 0;
+}
diff --git a/tests/conformance/3-expressions/prec_postfix_incr_value.zc b/tests/conformance/3-expressions/prec_postfix_incr_value.zc
new file mode 100644
index 0000000..b5ad819
--- /dev/null
+++ b/tests/conformance/3-expressions/prec_postfix_incr_value.zc
@@ -0,0 +1,11 @@
+// expect: 5/6/7/7/
+include rt;
+void pn(int x) { rt.put_n(x); rt.put_c(10); }
+fn main() {
+ int a = 5;
+ pn(a++);
+ pn(a);
+ pn(++a);
+ pn(a);
+ return 0;
+}
diff --git a/tests/conformance/3-expressions/prec_postfix_tighter_than_prefix.zc b/tests/conformance/3-expressions/prec_postfix_tighter_than_prefix.zc
new file mode 100644
index 0000000..36cccf5
--- /dev/null
+++ b/tests/conformance/3-expressions/prec_postfix_tighter_than_prefix.zc
@@ -0,0 +1,12 @@
+// expect: -6/6/-5/
+include rt;
+void pn(int x) { rt.put_n(x); rt.put_c(10); }
+fn main() {
+ int[3] a = {5, 6, 7};
+ int i = 1;
+ pn(-a[i]);
+ pn(- -a[i]);
+ pn(-a[i - 1]);
+ return 0;
+}
+// zc0: skip
diff --git a/tests/conformance/3-expressions/prec_table_examples.zc b/tests/conformance/3-expressions/prec_table_examples.zc
new file mode 100644
index 0000000..f78562d
--- /dev/null
+++ b/tests/conformance/3-expressions/prec_table_examples.zc
@@ -0,0 +1,24 @@
+// expect: 1/1/0/3/0/6/8/1/1/3/10/5/2/1/0/3/-1/
+include rt;
+void pn(int x) { rt.put_n(x); rt.put_c(10); }
+fn main() {
+ pn(1 || 0 && 0);
+ pn(0 && 0 || 1);
+ pn(1 | 2 && 0);
+ pn(0 == 0 | 2);
+ pn(6 & 3 == 3);
+ pn(1 + 2 << 1);
+ pn(1 << 2 + 1);
+ pn(2 < 3 == 1);
+ pn(1 < 2 < 3 ? 1 : 0);
+ pn(1 ^ 3 & 2);
+ pn(7 & 3 ^ 1 | 8);
+ pn(10 - 3 - 2);
+ pn(100 / 10 / 5);
+ pn(1 < 2 < 3);
+ pn(3 > 2 > 1);
+ pn(0 ? 1 : 0 ? 2 : 3);
+ pn(-2 as int + 1);
+ return 0;
+}
+// zc0: skip
diff --git a/tests/conformance/3-expressions/prec_ternary_cond_is_binary.zc b/tests/conformance/3-expressions/prec_ternary_cond_is_binary.zc
new file mode 100644
index 0000000..2890f6e
--- /dev/null
+++ b/tests/conformance/3-expressions/prec_ternary_cond_is_binary.zc
@@ -0,0 +1,12 @@
+// expect: 3/8/
+include rt;
+void pn(int x) { rt.put_n(x); rt.put_c(10); }
+fn main() {
+ int a, b = 3;
+ a = b == 3 ? 3 : 4;
+ pn(a);
+ a = b + 1 > 3 && b ? 8 : 9;
+ pn(a);
+ return 0;
+}
+// zc0: skip
diff --git a/tests/conformance/3-expressions/prec_ternary_else_assign.zc b/tests/conformance/3-expressions/prec_ternary_else_assign.zc
new file mode 100644
index 0000000..400e780
--- /dev/null
+++ b/tests/conformance/3-expressions/prec_ternary_else_assign.zc
@@ -0,0 +1,13 @@
+// expect: 0/5/
+include rt;
+void pn(int x) { rt.put_n(x); rt.put_c(10); }
+fn main() {
+ int a = 1, c = 0;
+ a ? 1 : c = 5;
+ pn(c);
+ a = 0;
+ a ? 1 : c = 5;
+ pn(c);
+ return 0;
+}
+// zc0: skip
diff --git a/tests/conformance/3-expressions/prec_ternary_middle_full_expr.zc b/tests/conformance/3-expressions/prec_ternary_middle_full_expr.zc
new file mode 100644
index 0000000..21ac07c
--- /dev/null
+++ b/tests/conformance/3-expressions/prec_ternary_middle_full_expr.zc
@@ -0,0 +1,10 @@
+// expect: 4/4/
+include rt;
+void pn(int x) { rt.put_n(x); rt.put_c(10); }
+fn main() {
+ int a = 1, b = 0;
+ int r = a ? b = 4 : 7;
+ pn(r); pn(b);
+ return 0;
+}
+// zc0: skip
diff --git a/tests/conformance/3-expressions/prec_unary_vs_binary.zc b/tests/conformance/3-expressions/prec_unary_vs_binary.zc
new file mode 100644
index 0000000..a7b7e48
--- /dev/null
+++ b/tests/conformance/3-expressions/prec_unary_vs_binary.zc
@@ -0,0 +1,12 @@
+// expect: -6/-6/6/-9/1/
+include rt;
+void pn(int x) { rt.put_n(x); rt.put_c(10); }
+fn main() {
+ int a = 2, b = 3;
+ pn(-a * b);
+ pn(- a * b);
+ pn(-(-a) * b);
+ pn(~a * 3 + 0);
+ pn(!a + 1 == 1);
+ return 0;
+}
diff --git a/tests/conformance/3-expressions/ptr_add_words.zc b/tests/conformance/3-expressions/ptr_add_words.zc
new file mode 100644
index 0000000..6b869f6
--- /dev/null
+++ b/tests/conformance/3-expressions/ptr_add_words.zc
@@ -0,0 +1,14 @@
+// expect: 5/1/
+include rt;
+void pn(int x) { rt.put_n(x); rt.put_c(10); }
+struct point { int x; int y; }
+fn main() {
+ point* p = rt.new(point, 3);
+ p[1].x = 5;
+ int* q = (int*)p;
+ pn(q[2]);
+ pn((int)(p + 1) - (int)p);
+ rt.free(p);
+ return 0;
+}
+// zc0: skip
diff --git a/tests/conformance/3-expressions/ptr_addr_of_forms.zc b/tests/conformance/3-expressions/ptr_addr_of_forms.zc
new file mode 100644
index 0000000..4bcf8cf
--- /dev/null
+++ b/tests/conformance/3-expressions/ptr_addr_of_forms.zc
@@ -0,0 +1,24 @@
+// expect: 1/1/1/1/
+include rt;
+void pn(int x) { rt.put_n(x); rt.put_c(10); }
+struct pt { int x; int y; }
+int gv;
+fn main() {
+ int a = 3;
+ int* pa = &a;
+ *pa = 4;
+ pn(a == 4);
+ *(&gv) = 8;
+ pn(gv == 8);
+ pt* q = rt.new(pt);
+ int* py = &q.y;
+ *py = 6;
+ pn(q.y == 6);
+ int[3] arr;
+ int* pe = &arr[2];
+ *pe = 1;
+ pn(arr[2]);
+ rt.free(q);
+ return 0;
+}
+// zc0: skip
diff --git a/tests/conformance/3-expressions/ptr_deref_struct_is_address.zc b/tests/conformance/3-expressions/ptr_deref_struct_is_address.zc
new file mode 100644
index 0000000..f495fc5
--- /dev/null
+++ b/tests/conformance/3-expressions/ptr_deref_struct_is_address.zc
@@ -0,0 +1,11 @@
+// expect: 1/
+include rt;
+void pn(int x) { rt.put_n(x); rt.put_c(10); }
+struct point { int x; int y; }
+fn main() {
+ point* p = rt.new(point, 4);
+ pn((int)(*(p + 2)) == (int)(p + 2));
+ rt.free(p);
+ return 0;
+}
+// zc0: skip
diff --git a/tests/conformance/3-expressions/ptr_difference.zc b/tests/conformance/3-expressions/ptr_difference.zc
new file mode 100644
index 0000000..ea5eb15
--- /dev/null
+++ b/tests/conformance/3-expressions/ptr_difference.zc
@@ -0,0 +1,12 @@
+// expect: 3/-3/2/
+include rt;
+void pn(int x) { rt.put_n(x); rt.put_c(10); }
+fn main() {
+ int[8] a;
+ int* p = a;
+ int* q = p + 3;
+ pn(q - p);
+ pn(p - q);
+ pn((q - 1) - p);
+ return 0;
+}
diff --git a/tests/conformance/3-expressions/ptr_field_of_new_object.zc b/tests/conformance/3-expressions/ptr_field_of_new_object.zc
new file mode 100644
index 0000000..3d01581
--- /dev/null
+++ b/tests/conformance/3-expressions/ptr_field_of_new_object.zc
@@ -0,0 +1,7 @@
+// expect error: use a field of a new object only after binding it to a name
+include rt;
+struct pt { int x; int y; }
+fn main() {
+ rt.put_n(rt.new(pt).x);
+ return 0;
+}
diff --git a/tests/conformance/3-expressions/ptr_index_must_be_number.zc b/tests/conformance/3-expressions/ptr_index_must_be_number.zc
new file mode 100644
index 0000000..766e348
--- /dev/null
+++ b/tests/conformance/3-expressions/ptr_index_must_be_number.zc
@@ -0,0 +1,8 @@
+// expect error: type error
+include rt;
+typecheck on;
+fn main() {
+ int[2] a; int* p = a;
+ rt.put_n(a[p]);
+ return 0;
+}
diff --git a/tests/conformance/3-expressions/ptr_index_new_object.zc b/tests/conformance/3-expressions/ptr_index_new_object.zc
new file mode 100644
index 0000000..7f729fa
--- /dev/null
+++ b/tests/conformance/3-expressions/ptr_index_new_object.zc
@@ -0,0 +1,6 @@
+// expect error: index a new object only after binding it to a name
+include rt;
+fn main() {
+ rt.put_n(rt.new(int)[0]);
+ return 0;
+}
diff --git a/tests/conformance/3-expressions/ptr_index_scaled.zc b/tests/conformance/3-expressions/ptr_index_scaled.zc
new file mode 100644
index 0000000..fd61dd9
--- /dev/null
+++ b/tests/conformance/3-expressions/ptr_index_scaled.zc
@@ -0,0 +1,13 @@
+// expect: 7/9/
+include rt;
+void pn(int x) { rt.put_n(x); rt.put_c(10); }
+struct trip { int a; int b; int c; }
+fn main() {
+ trip* t = rt.new(trip, 2);
+ int* w = (int*)t;
+ w[3] = 7; w[5] = 9;
+ pn(t[1].a); pn(t[1].c);
+ rt.free(t);
+ return 0;
+}
+// zc0: skip
diff --git a/tests/conformance/3-expressions/short_circuit.zc b/tests/conformance/3-expressions/short_circuit.zc
new file mode 100644
index 0000000..ac23ade
--- /dev/null
+++ b/tests/conformance/3-expressions/short_circuit.zc
@@ -0,0 +1,15 @@
+// expect: 1/1/0/1/
+include rt;
+int calls;
+int seen(int v) { calls++; return v; }
+void pn(int x) { rt.put_n(x); rt.put_c(10); }
+fn main() {
+ calls = 0;
+ int r = seen(1) || seen(0) && seen(1);
+ pn(r); pn(calls);
+ calls = 0;
+ r = seen(0) && seen(1);
+ pn(r);
+ pn(calls);
+ return 0;
+}
diff --git a/tests/conformance/3-expressions/short_circuit_and_evaluates_right.zc b/tests/conformance/3-expressions/short_circuit_and_evaluates_right.zc
new file mode 100644
index 0000000..ae3e774
--- /dev/null
+++ b/tests/conformance/3-expressions/short_circuit_and_evaluates_right.zc
@@ -0,0 +1,10 @@
+// expect: 1/2/
+include rt;
+int calls;
+int seen(int v) { calls++; return v; }
+void pn(int x) { rt.put_n(x); rt.put_c(10); }
+fn main() {
+ int r = seen(7) && seen(9);
+ pn(r); pn(calls);
+ return 0;
+}
diff --git a/tests/conformance/3-expressions/short_circuit_or_evaluates_right_when_zero.zc b/tests/conformance/3-expressions/short_circuit_or_evaluates_right_when_zero.zc
new file mode 100644
index 0000000..056159a
--- /dev/null
+++ b/tests/conformance/3-expressions/short_circuit_or_evaluates_right_when_zero.zc
@@ -0,0 +1,10 @@
+// expect: 1/2/
+include rt;
+int calls;
+int seen(int v) { calls++; return v; }
+void pn(int x) { rt.put_n(x); rt.put_c(10); }
+fn main() {
+ int r = seen(0) || seen(3);
+ pn(r); pn(calls);
+ return 0;
+}
diff --git a/tests/conformance/3-expressions/short_circuit_or_skips_right.zc b/tests/conformance/3-expressions/short_circuit_or_skips_right.zc
new file mode 100644
index 0000000..1e573ee
--- /dev/null
+++ b/tests/conformance/3-expressions/short_circuit_or_skips_right.zc
@@ -0,0 +1,10 @@
+// expect: 1/1/
+include rt;
+int calls;
+int seen(int v) { calls++; return v; }
+void pn(int x) { rt.put_n(x); rt.put_c(10); }
+fn main() {
+ int r = seen(7) || seen(0);
+ pn(r); pn(calls);
+ return 0;
+}
diff --git a/tests/conformance/3-expressions/sizeof_expr_not_run.zc b/tests/conformance/3-expressions/sizeof_expr_not_run.zc
new file mode 100644
index 0000000..1714a38
--- /dev/null
+++ b/tests/conformance/3-expressions/sizeof_expr_not_run.zc
@@ -0,0 +1,10 @@
+// expect: 0/1/
+include rt;
+void pn(int x) { rt.put_n(x); rt.put_c(10); }
+fn main() {
+ int i = 0;
+ int n = sizeof(i++);
+ pn(i); pn(n);
+ return 0;
+}
+// zc0: skip
diff --git a/tests/conformance/3-expressions/sizeof_packed.zc b/tests/conformance/3-expressions/sizeof_packed.zc
new file mode 100644
index 0000000..86df5b1
--- /dev/null
+++ b/tests/conformance/3-expressions/sizeof_packed.zc
@@ -0,0 +1,6 @@
+// expect: 13/1/
+include rt;
+void pn(int x) { rt.put_n(x); rt.put_c(10); }
+struct four { u8 a, b, c, d; }
+fn main() { pn(sizeof(u8[100])); pn(sizeof(four)); return 0; }
+// zc0: skip
diff --git a/tests/conformance/3-expressions/ternary_nests_right.zc b/tests/conformance/3-expressions/ternary_nests_right.zc
new file mode 100644
index 0000000..1b61fef
--- /dev/null
+++ b/tests/conformance/3-expressions/ternary_nests_right.zc
@@ -0,0 +1,10 @@
+// expect: 3/2/1/
+include rt;
+void pn(int x) { rt.put_n(x); rt.put_c(10); }
+fn main() {
+ pn(0 ? 1 : 0 ? 2 : 3);
+ pn(0 ? 1 : 1 ? 2 : 3);
+ pn(1 ? 1 : 1 ? 2 : 3);
+ return 0;
+}
+// zc0: skip
diff --git a/tests/conformance/3-expressions/ternary_one_branch_only.zc b/tests/conformance/3-expressions/ternary_one_branch_only.zc
new file mode 100644
index 0000000..b0a423f
--- /dev/null
+++ b/tests/conformance/3-expressions/ternary_one_branch_only.zc
@@ -0,0 +1,14 @@
+// expect: 1/1/0/
+include rt;
+int calls;
+int seen(int v) { calls++; return v; }
+void pn(int x) { rt.put_n(x); rt.put_c(10); }
+fn main() {
+ int r = 1 ? seen(1) : seen(2);
+ pn(r);
+ pn(calls);
+ r = 0 ? seen(5) : 0;
+ pn(calls - 1);
+ return 0;
+}
+// zc0: skip
diff --git a/tests/conformance/3-expressions/typeof_print.zc b/tests/conformance/3-expressions/typeof_print.zc
new file mode 100644
index 0000000..b003572
--- /dev/null
+++ b/tests/conformance/3-expressions/typeof_print.zc
@@ -0,0 +1,9 @@
+// expect: int(int, char*)/fixed u8[?]/
+include rt;
+include run;
+fn main() {
+ run.tprint(typeof(int(int, char*))); rt.put_c(10);
+ run.tprint(typeof(fixed u8[?])); rt.put_c(10);
+ return 0;
+}
+// zc0: skip
diff --git a/tests/conformance/3-expressions/unary_minus_wraps.zc b/tests/conformance/3-expressions/unary_minus_wraps.zc
new file mode 100644
index 0000000..aba1c47
--- /dev/null
+++ b/tests/conformance/3-expressions/unary_minus_wraps.zc
@@ -0,0 +1,9 @@
+// expect: -9223372036854775808/
+include rt;
+void pn(int x) { rt.put_n(x); rt.put_c(10); }
+fn main() {
+ int a = 0x7fffffffffffffff;
+ a = a + 1;
+ pn(-a);
+ return 0;
+}
diff --git a/tests/conformance/3-expressions/unary_ops_values.zc b/tests/conformance/3-expressions/unary_ops_values.zc
new file mode 100644
index 0000000..c477efe
--- /dev/null
+++ b/tests/conformance/3-expressions/unary_ops_values.zc
@@ -0,0 +1,8 @@
+// expect: 0/1/-1/-6/5/-5/1/0/
+include rt;
+void pn(int x) { rt.put_n(x); rt.put_c(10); }
+fn main() {
+ int a = 5, z = 0;
+ pn(!a); pn(!z); pn(~z); pn(~a); pn(-(-a)); pn(-a); pn(!!a); pn(!!z);
+ return 0;
+}