From a275919ea9141a9d8c966ccef040666d9bda3b60 Mon Sep 17 00:00:00 2001 From: zinc Date: Wed, 14 Oct 2026 15:37:28 +0330 Subject: agent/spec-conformance: unmerged work from previous session --- tests/conformance/4-statements/asm_arith_mnemonics.zc | 11 +++++++++++ tests/conformance/4-statements/asm_constant_name.zc | 6 ++++++ .../conformance/4-statements/asm_expression_value.zc | 5 +++++ tests/conformance/4-statements/asm_float_literal.zc | 7 +++++++ tests/conformance/4-statements/asm_function_name.zc | 6 ++++++ .../conformance/4-statements/asm_negative_literal.zc | 5 +++++ tests/conformance/4-statements/asm_statement_local.zc | 5 +++++ .../4-statements/asm_string_pushes_address.zc | 5 +++++ tests/conformance/4-statements/asm_unknown_name.zc | 5 +++++ .../conformance/4-statements/break_inner_loop_only.zc | 12 ++++++++++++ tests/conformance/4-statements/break_outside.zc | 5 +++++ .../4-statements/checked_owned_never_used.zc | 9 +++++++++ .../4-statements/continue_in_switch_outside_loop.zc | 5 +++++ tests/conformance/4-statements/continue_outside.zc | 5 +++++ tests/conformance/4-statements/decl_const_assign.zc | 5 +++++ .../conformance/4-statements/decl_const_increment.zc | 5 +++++ .../4-statements/decl_const_local_typed_float.zc | 6 ++++++ .../4-statements/decl_const_takes_initializer_type.zc | 6 ++++++ tests/conformance/4-statements/decl_for_init_scope.zc | 5 +++++ .../4-statements/decl_for_let_init_scope.zc | 5 +++++ tests/conformance/4-statements/decl_let_array.zc | 10 ++++++++++ tests/conformance/4-statements/decl_let_bstr.zc | 9 +++++++++ tests/conformance/4-statements/decl_let_char_ptr.zc | 9 +++++++++ .../conformance/4-statements/decl_let_float_local.zc | 10 ++++++++++ .../4-statements/decl_let_function_type.zc | 6 ++++++ .../4-statements/decl_let_integer_is_word.zc | 5 +++++ tests/conformance/4-statements/decl_let_multiple.zc | 10 ++++++++++ .../4-statements/decl_redeclare_same_block.zc | 5 +++++ .../4-statements/decl_scope_ends_with_block.zc | 5 +++++ .../4-statements/decl_shadow_function_name.zc | 6 ++++++ tests/conformance/4-statements/decl_shadow_global.zc | 6 ++++++ .../4-statements/decl_shadow_outer_block.zc | 10 ++++++++++ tests/conformance/4-statements/decl_shadow_param.zc | 6 ++++++ tests/conformance/4-statements/decl_tag_only.zc | 10 ++++++++++ .../4-statements/decl_typed_array_declarator.zc | 10 ++++++++++ tests/conformance/4-statements/decl_typed_multi.zc | 11 +++++++++++ .../4-statements/decl_typed_tag_u_hand_up.zc | 14 ++++++++++++++ .../4-statements/decl_uninit_global_is_zero.zc | 8 ++++++++ tests/conformance/4-statements/decl_void_variable.zc | 5 +++++ tests/conformance/4-statements/do_basic.zc | 11 +++++++++++ tests/conformance/4-statements/do_break.zc | 6 ++++++ .../4-statements/do_continue_jumps_to_test.zc | 6 ++++++ tests/conformance/4-statements/do_runs_once.zc | 6 ++++++ tests/conformance/4-statements/for_basic.zc | 5 +++++ .../conformance/4-statements/for_cond_tests_first.zc | 5 +++++ .../4-statements/for_continue_runs_step.zc | 10 ++++++++++ tests/conformance/4-statements/for_empty_parts.zc | 10 ++++++++++ tests/conformance/4-statements/for_expression_init.zc | 5 +++++ tests/conformance/4-statements/for_let_init.zc | 5 +++++ .../4-statements/for_variable_is_scoped.zc | 11 +++++++++++ .../conformance/4-statements/hints_forms_accepted.zc | 9 +++++++++ tests/conformance/4-statements/if_basic.zc | 10 ++++++++++ .../4-statements/if_branch_is_own_scope.zc | 5 +++++ .../conformance/4-statements/if_else_binds_nearest.zc | 8 ++++++++ .../if_else_binds_nearest_outer_not_taken.zc | 8 ++++++++ tests/conformance/4-statements/if_else_chain.zc | 9 +++++++++ tests/conformance/4-statements/if_float_condition.zc | 11 +++++++++++ .../conformance/4-statements/memdebug_double_free.zc | 10 ++++++++++ tests/conformance/4-statements/memdebug_off.zc | 8 ++++++++ tests/conformance/4-statements/memdebug_report.zc | 15 +++++++++++++++ .../conformance/4-statements/memdebug_report_line.zc | 15 +++++++++++++++ .../4-statements/memdebug_scrub_accepted.zc | 7 +++++++ .../conformance/4-statements/memdebug_scrub_fills.zc | 10 ++++++++++ .../4-statements/memdebug_statement_form.zc | 6 ++++++ .../4-statements/memdebug_use_after_free.zc | 10 ++++++++++ .../conformance/4-statements/nested_return_in_loop.zc | 9 +++++++++ tests/conformance/4-statements/o3_asm_cannot_reach.zc | 6 ++++++ tests/conformance/4-statements/o3_block.zc | 11 +++++++++++ tests/conformance/4-statements/o3_fn_form.zc | 7 +++++++ tests/conformance/4-statements/o3_function_sum.zc | 13 +++++++++++++ .../4-statements/o3_nested_is_ordinary_block.zc | 6 ++++++ tests/conformance/4-statements/o3_no_address_of.zc | 6 ++++++ .../o3_outside_function_ordinary_block.zc | 7 +++++++ .../4-statements/o3_parameter_needs_type.zc | 7 +++++++ tests/conformance/4-statements/o3_single_variable.zc | 6 ++++++ .../4-statements/o3_variable_needs_type.zc | 6 ++++++ tests/conformance/4-statements/return_bare_is_zero.zc | 6 ++++++ .../4-statements/return_fall_off_is_zero.zc | 6 ++++++ .../4-statements/return_frees_owned_locals.zc | 11 +++++++++++ .../4-statements/return_outside_function.zc | 6 ++++++ .../4-statements/return_value_converted_float.zc | 7 +++++++ .../4-statements/return_value_converted_int.zc | 6 ++++++ .../4-statements/return_void_value_typecheck_on.zc | 7 +++++++ tests/conformance/4-statements/stmt_block_scope.zc | 5 +++++ .../conformance/4-statements/stmt_empty_statement.zc | 5 +++++ .../4-statements/stmt_expression_value_dropped.zc | 5 +++++ .../4-statements/stmt_fresh_value_thrown_away.zc | 5 +++++ .../4-statements/stmt_u_result_thrown_away.zc | 6 ++++++ .../switch_break_in_loop_leaves_switch_only.zc | 13 +++++++++++++ .../4-statements/switch_break_leaves_early.zc | 10 ++++++++++ .../conformance/4-statements/switch_case_own_block.zc | 11 +++++++++++ tests/conformance/4-statements/switch_case_three.zc | 10 ++++++++++ .../4-statements/switch_case_underscore.zc | 7 +++++++ .../4-statements/switch_continue_continues_loop.zc | 10 ++++++++++ .../4-statements/switch_default_and_underscore.zc | 5 +++++ .../switch_default_first_position_not_matched.zc | 10 ++++++++++ .../switch_default_first_position_taken.zc | 10 ++++++++++ .../conformance/4-statements/switch_default_middle.zc | 7 +++++++ tests/conformance/4-statements/switch_default_runs.zc | 10 ++++++++++ .../switch_duplicate_labels_first_wins.zc | 10 ++++++++++ .../4-statements/switch_expression_evaluated_once.zc | 10 ++++++++++ tests/conformance/4-statements/switch_label_forms.zc | 16 ++++++++++++++++ tests/conformance/4-statements/switch_nested.zc | 14 ++++++++++++++ .../4-statements/switch_no_fallthrough_k2.zc | 10 ++++++++++ .../4-statements/switch_no_match_no_default.zc | 11 +++++++++++ .../4-statements/switch_non_constant_label.zc | 5 +++++ .../4-statements/switch_return_inside_case.zc | 6 ++++++ .../switch_tagged_all_covered_no_warning.zc | 11 +++++++++++ .../4-statements/switch_tagged_binding_count.zc | 11 +++++++++++ .../switch_tagged_binding_scoped_to_case.zc | 12 ++++++++++++ .../conformance/4-statements/switch_tagged_circle.zc | 11 +++++++++++ .../4-statements/switch_tagged_default_no_warning.zc | 11 +++++++++++ .../conformance/4-statements/switch_tagged_example.zc | 11 +++++++++++ .../4-statements/switch_tagged_match_by_tag.zc | 19 +++++++++++++++++++ .../4-statements/switch_tagged_uncovered_warning.zc | 11 +++++++++++ .../switch_tagged_uncovered_warning_not_error.zc | 11 +++++++++++ tests/conformance/4-statements/switch_two_defaults.zc | 5 +++++ .../4-statements/switch_two_underscores.zc | 5 +++++ tests/conformance/4-statements/unchecked_fn.zc | 6 ++++++ .../4-statements/unchecked_fn_does_not_extend.zc | 6 ++++++ .../conformance/4-statements/unchecked_stmt_block.zc | 9 +++++++++ .../conformance/4-statements/unchecked_stmt_single.zc | 10 ++++++++++ .../4-statements/unchecked_toplevel_rest_of_unit.zc | 10 ++++++++++ .../4-statements/unchecked_tracked_local_rejected.zc | 9 +++++++++ tests/conformance/4-statements/while_basic.zc | 5 +++++ tests/conformance/4-statements/while_continue.zc | 10 ++++++++++ .../4-statements/while_one_exit_by_return.zc | 6 ++++++ .../4-statements/while_one_exits_by_break.zc | 5 +++++ tests/conformance/4-statements/while_tests_before.zc | 5 +++++ 129 files changed, 1042 insertions(+) create mode 100644 tests/conformance/4-statements/asm_arith_mnemonics.zc create mode 100644 tests/conformance/4-statements/asm_constant_name.zc create mode 100644 tests/conformance/4-statements/asm_expression_value.zc create mode 100644 tests/conformance/4-statements/asm_float_literal.zc create mode 100644 tests/conformance/4-statements/asm_function_name.zc create mode 100644 tests/conformance/4-statements/asm_negative_literal.zc create mode 100644 tests/conformance/4-statements/asm_statement_local.zc create mode 100644 tests/conformance/4-statements/asm_string_pushes_address.zc create mode 100644 tests/conformance/4-statements/asm_unknown_name.zc create mode 100644 tests/conformance/4-statements/break_inner_loop_only.zc create mode 100644 tests/conformance/4-statements/break_outside.zc create mode 100644 tests/conformance/4-statements/checked_owned_never_used.zc create mode 100644 tests/conformance/4-statements/continue_in_switch_outside_loop.zc create mode 100644 tests/conformance/4-statements/continue_outside.zc create mode 100644 tests/conformance/4-statements/decl_const_assign.zc create mode 100644 tests/conformance/4-statements/decl_const_increment.zc create mode 100644 tests/conformance/4-statements/decl_const_local_typed_float.zc create mode 100644 tests/conformance/4-statements/decl_const_takes_initializer_type.zc create mode 100644 tests/conformance/4-statements/decl_for_init_scope.zc create mode 100644 tests/conformance/4-statements/decl_for_let_init_scope.zc create mode 100644 tests/conformance/4-statements/decl_let_array.zc create mode 100644 tests/conformance/4-statements/decl_let_bstr.zc create mode 100644 tests/conformance/4-statements/decl_let_char_ptr.zc create mode 100644 tests/conformance/4-statements/decl_let_float_local.zc create mode 100644 tests/conformance/4-statements/decl_let_function_type.zc create mode 100644 tests/conformance/4-statements/decl_let_integer_is_word.zc create mode 100644 tests/conformance/4-statements/decl_let_multiple.zc create mode 100644 tests/conformance/4-statements/decl_redeclare_same_block.zc create mode 100644 tests/conformance/4-statements/decl_scope_ends_with_block.zc create mode 100644 tests/conformance/4-statements/decl_shadow_function_name.zc create mode 100644 tests/conformance/4-statements/decl_shadow_global.zc create mode 100644 tests/conformance/4-statements/decl_shadow_outer_block.zc create mode 100644 tests/conformance/4-statements/decl_shadow_param.zc create mode 100644 tests/conformance/4-statements/decl_tag_only.zc create mode 100644 tests/conformance/4-statements/decl_typed_array_declarator.zc create mode 100644 tests/conformance/4-statements/decl_typed_multi.zc create mode 100644 tests/conformance/4-statements/decl_typed_tag_u_hand_up.zc create mode 100644 tests/conformance/4-statements/decl_uninit_global_is_zero.zc create mode 100644 tests/conformance/4-statements/decl_void_variable.zc create mode 100644 tests/conformance/4-statements/do_basic.zc create mode 100644 tests/conformance/4-statements/do_break.zc create mode 100644 tests/conformance/4-statements/do_continue_jumps_to_test.zc create mode 100644 tests/conformance/4-statements/do_runs_once.zc create mode 100644 tests/conformance/4-statements/for_basic.zc create mode 100644 tests/conformance/4-statements/for_cond_tests_first.zc create mode 100644 tests/conformance/4-statements/for_continue_runs_step.zc create mode 100644 tests/conformance/4-statements/for_empty_parts.zc create mode 100644 tests/conformance/4-statements/for_expression_init.zc create mode 100644 tests/conformance/4-statements/for_let_init.zc create mode 100644 tests/conformance/4-statements/for_variable_is_scoped.zc create mode 100644 tests/conformance/4-statements/hints_forms_accepted.zc create mode 100644 tests/conformance/4-statements/if_basic.zc create mode 100644 tests/conformance/4-statements/if_branch_is_own_scope.zc create mode 100644 tests/conformance/4-statements/if_else_binds_nearest.zc create mode 100644 tests/conformance/4-statements/if_else_binds_nearest_outer_not_taken.zc create mode 100644 tests/conformance/4-statements/if_else_chain.zc create mode 100644 tests/conformance/4-statements/if_float_condition.zc create mode 100644 tests/conformance/4-statements/memdebug_double_free.zc create mode 100644 tests/conformance/4-statements/memdebug_off.zc create mode 100644 tests/conformance/4-statements/memdebug_report.zc create mode 100644 tests/conformance/4-statements/memdebug_report_line.zc create mode 100644 tests/conformance/4-statements/memdebug_scrub_accepted.zc create mode 100644 tests/conformance/4-statements/memdebug_scrub_fills.zc create mode 100644 tests/conformance/4-statements/memdebug_statement_form.zc create mode 100644 tests/conformance/4-statements/memdebug_use_after_free.zc create mode 100644 tests/conformance/4-statements/nested_return_in_loop.zc create mode 100644 tests/conformance/4-statements/o3_asm_cannot_reach.zc create mode 100644 tests/conformance/4-statements/o3_block.zc create mode 100644 tests/conformance/4-statements/o3_fn_form.zc create mode 100644 tests/conformance/4-statements/o3_function_sum.zc create mode 100644 tests/conformance/4-statements/o3_nested_is_ordinary_block.zc create mode 100644 tests/conformance/4-statements/o3_no_address_of.zc create mode 100644 tests/conformance/4-statements/o3_outside_function_ordinary_block.zc create mode 100644 tests/conformance/4-statements/o3_parameter_needs_type.zc create mode 100644 tests/conformance/4-statements/o3_single_variable.zc create mode 100644 tests/conformance/4-statements/o3_variable_needs_type.zc create mode 100644 tests/conformance/4-statements/return_bare_is_zero.zc create mode 100644 tests/conformance/4-statements/return_fall_off_is_zero.zc create mode 100644 tests/conformance/4-statements/return_frees_owned_locals.zc create mode 100644 tests/conformance/4-statements/return_outside_function.zc create mode 100644 tests/conformance/4-statements/return_value_converted_float.zc create mode 100644 tests/conformance/4-statements/return_value_converted_int.zc create mode 100644 tests/conformance/4-statements/return_void_value_typecheck_on.zc create mode 100644 tests/conformance/4-statements/stmt_block_scope.zc create mode 100644 tests/conformance/4-statements/stmt_empty_statement.zc create mode 100644 tests/conformance/4-statements/stmt_expression_value_dropped.zc create mode 100644 tests/conformance/4-statements/stmt_fresh_value_thrown_away.zc create mode 100644 tests/conformance/4-statements/stmt_u_result_thrown_away.zc create mode 100644 tests/conformance/4-statements/switch_break_in_loop_leaves_switch_only.zc create mode 100644 tests/conformance/4-statements/switch_break_leaves_early.zc create mode 100644 tests/conformance/4-statements/switch_case_own_block.zc create mode 100644 tests/conformance/4-statements/switch_case_three.zc create mode 100644 tests/conformance/4-statements/switch_case_underscore.zc create mode 100644 tests/conformance/4-statements/switch_continue_continues_loop.zc create mode 100644 tests/conformance/4-statements/switch_default_and_underscore.zc create mode 100644 tests/conformance/4-statements/switch_default_first_position_not_matched.zc create mode 100644 tests/conformance/4-statements/switch_default_first_position_taken.zc create mode 100644 tests/conformance/4-statements/switch_default_middle.zc create mode 100644 tests/conformance/4-statements/switch_default_runs.zc create mode 100644 tests/conformance/4-statements/switch_duplicate_labels_first_wins.zc create mode 100644 tests/conformance/4-statements/switch_expression_evaluated_once.zc create mode 100644 tests/conformance/4-statements/switch_label_forms.zc create mode 100644 tests/conformance/4-statements/switch_nested.zc create mode 100644 tests/conformance/4-statements/switch_no_fallthrough_k2.zc create mode 100644 tests/conformance/4-statements/switch_no_match_no_default.zc create mode 100644 tests/conformance/4-statements/switch_non_constant_label.zc create mode 100644 tests/conformance/4-statements/switch_return_inside_case.zc create mode 100644 tests/conformance/4-statements/switch_tagged_all_covered_no_warning.zc create mode 100644 tests/conformance/4-statements/switch_tagged_binding_count.zc create mode 100644 tests/conformance/4-statements/switch_tagged_binding_scoped_to_case.zc create mode 100644 tests/conformance/4-statements/switch_tagged_circle.zc create mode 100644 tests/conformance/4-statements/switch_tagged_default_no_warning.zc create mode 100644 tests/conformance/4-statements/switch_tagged_example.zc create mode 100644 tests/conformance/4-statements/switch_tagged_match_by_tag.zc create mode 100644 tests/conformance/4-statements/switch_tagged_uncovered_warning.zc create mode 100644 tests/conformance/4-statements/switch_tagged_uncovered_warning_not_error.zc create mode 100644 tests/conformance/4-statements/switch_two_defaults.zc create mode 100644 tests/conformance/4-statements/switch_two_underscores.zc create mode 100644 tests/conformance/4-statements/unchecked_fn.zc create mode 100644 tests/conformance/4-statements/unchecked_fn_does_not_extend.zc create mode 100644 tests/conformance/4-statements/unchecked_stmt_block.zc create mode 100644 tests/conformance/4-statements/unchecked_stmt_single.zc create mode 100644 tests/conformance/4-statements/unchecked_toplevel_rest_of_unit.zc create mode 100644 tests/conformance/4-statements/unchecked_tracked_local_rejected.zc create mode 100644 tests/conformance/4-statements/while_basic.zc create mode 100644 tests/conformance/4-statements/while_continue.zc create mode 100644 tests/conformance/4-statements/while_one_exit_by_return.zc create mode 100644 tests/conformance/4-statements/while_one_exits_by_break.zc create mode 100644 tests/conformance/4-statements/while_tests_before.zc (limited to 'tests/conformance/4-statements') diff --git a/tests/conformance/4-statements/asm_arith_mnemonics.zc b/tests/conformance/4-statements/asm_arith_mnemonics.zc new file mode 100644 index 0000000..79e06da --- /dev/null +++ b/tests/conformance/4-statements/asm_arith_mnemonics.zc @@ -0,0 +1,11 @@ +// expect: 42/8/14/6/ +// spec 4.13.1: mnemonics * & | ^ +include rt; +void pn(int x) { rt.put_n(x); rt.put_c(10); } +fn main() { + pn(asm { 6 7 * }); + pn(asm { 12 10 & }); + pn(asm { 12 10 | }); + pn(asm { 12 10 ^ }); + return 0; +} diff --git a/tests/conformance/4-statements/asm_constant_name.zc b/tests/conformance/4-statements/asm_constant_name.zc new file mode 100644 index 0000000..b27f133 --- /dev/null +++ b/tests/conformance/4-statements/asm_constant_name.zc @@ -0,0 +1,6 @@ +// expect: 9/ +// spec 4.13.1: the name of a constant pushes its value +include rt; +void pn(int x) { rt.put_n(x); rt.put_c(10); } +const K = 9; +fn main() { pn(asm { K }); return 0; } diff --git a/tests/conformance/4-statements/asm_expression_value.zc b/tests/conformance/4-statements/asm_expression_value.zc new file mode 100644 index 0000000..68e483c --- /dev/null +++ b/tests/conformance/4-statements/asm_expression_value.zc @@ -0,0 +1,5 @@ +// expect: 5/ +// spec 4.13.1 example +include rt; +void pn(int x) { rt.put_n(x); rt.put_c(10); } +fn main() { int x = asm { 2 3 + }; pn(x); return 0; } diff --git a/tests/conformance/4-statements/asm_float_literal.zc b/tests/conformance/4-statements/asm_float_literal.zc new file mode 100644 index 0000000..dfb1e23 --- /dev/null +++ b/tests/conformance/4-statements/asm_float_literal.zc @@ -0,0 +1,7 @@ +// expect: 1.500000/ +// spec 4.13.1: a float literal emits flit and its bits +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 = asm { 1.5 }; pf(f); return 0; } + diff --git a/tests/conformance/4-statements/asm_function_name.zc b/tests/conformance/4-statements/asm_function_name.zc new file mode 100644 index 0000000..56d8bad --- /dev/null +++ b/tests/conformance/4-statements/asm_function_name.zc @@ -0,0 +1,6 @@ +// expect: 3/ +// spec 4.13.1: a function name pushes its address +include rt; +void pn(int x) { rt.put_n(x); rt.put_c(10); } +int three() { return 3; } +fn main() { fn() g = asm { three }; pn(g()); return 0; } diff --git a/tests/conformance/4-statements/asm_negative_literal.zc b/tests/conformance/4-statements/asm_negative_literal.zc new file mode 100644 index 0000000..ebd8432 --- /dev/null +++ b/tests/conformance/4-statements/asm_negative_literal.zc @@ -0,0 +1,5 @@ +// expect: -2/ +// spec 4.13.1: -n pushes a negative +include rt; +void pn(int x) { rt.put_n(x); rt.put_c(10); } +fn main() { int x = asm { -5 3 + }; pn(x); return 0; } diff --git a/tests/conformance/4-statements/asm_statement_local.zc b/tests/conformance/4-statements/asm_statement_local.zc new file mode 100644 index 0000000..9b7e985 --- /dev/null +++ b/tests/conformance/4-statements/asm_statement_local.zc @@ -0,0 +1,5 @@ +// expect: 8/ +// spec 4.13.1 example: the name of a local pushes its address +include rt; +void pn(int x) { rt.put_n(x); rt.put_c(10); } +fn main() { int y = 7; asm { y @ 1 + y ! } pn(y); return 0; } diff --git a/tests/conformance/4-statements/asm_string_pushes_address.zc b/tests/conformance/4-statements/asm_string_pushes_address.zc new file mode 100644 index 0000000..7041996 --- /dev/null +++ b/tests/conformance/4-statements/asm_string_pushes_address.zc @@ -0,0 +1,5 @@ +// expect: 104/ +// spec 4.13.1: a string pushes its address +include rt; +void pn(int x) { rt.put_n(x); rt.put_c(10); } +fn main() { char* s = asm { "hi" }; pn(s[0]); return 0; } diff --git a/tests/conformance/4-statements/asm_unknown_name.zc b/tests/conformance/4-statements/asm_unknown_name.zc new file mode 100644 index 0000000..f6436a8 --- /dev/null +++ b/tests/conformance/4-statements/asm_unknown_name.zc @@ -0,0 +1,5 @@ +// expect error: unknown name in asm +// spec 4.13.1 +include rt; +void pn(int x) { rt.put_n(x); rt.put_c(10); } +fn main() { int x = asm { nosuchthing }; return 0; } diff --git a/tests/conformance/4-statements/break_inner_loop_only.zc b/tests/conformance/4-statements/break_inner_loop_only.zc new file mode 100644 index 0000000..47db8ef --- /dev/null +++ b/tests/conformance/4-statements/break_inner_loop_only.zc @@ -0,0 +1,12 @@ +// expect: 6/ +// spec 4.8.1: break leaves the innermost loop +include rt; +void pn(int x) { rt.put_n(x); rt.put_c(10); } +fn main() { + int n = 0; + for (int i = 0; i < 3; i++) { + for (int j = 0; j < 5; j++) { if (j == 2) break; n++; } + } + pn(n); + return 0; +} diff --git a/tests/conformance/4-statements/break_outside.zc b/tests/conformance/4-statements/break_outside.zc new file mode 100644 index 0000000..6662c16 --- /dev/null +++ b/tests/conformance/4-statements/break_outside.zc @@ -0,0 +1,5 @@ +// expect error: break outside a loop or a switch +// spec 4.8.1 +include rt; +void pn(int x) { rt.put_n(x); rt.put_c(10); } +fn main() { break; return 0; } diff --git a/tests/conformance/4-statements/checked_owned_never_used.zc b/tests/conformance/4-statements/checked_owned_never_used.zc new file mode 100644 index 0000000..6c89dee --- /dev/null +++ b/tests/conformance/4-statements/checked_owned_never_used.zc @@ -0,0 +1,9 @@ +// expect error: p: owned object is never used +// spec 6.5.2 (the checked counterpart of unchecked_toplevel_rest_of_unit) +include rt; +void pn(int x) { rt.put_n(x); rt.put_c(10); } +fn main() { + int* p = rt.new(int); + pn(1); + return 0; +} diff --git a/tests/conformance/4-statements/continue_in_switch_outside_loop.zc b/tests/conformance/4-statements/continue_in_switch_outside_loop.zc new file mode 100644 index 0000000..eaca865 --- /dev/null +++ b/tests/conformance/4-statements/continue_in_switch_outside_loop.zc @@ -0,0 +1,5 @@ +// expect error: continue outside a loop +// spec 4.8.1 and 4.7.1: continue inside a switch continues the enclosing loop, there is none here +include rt; +void pn(int x) { rt.put_n(x); rt.put_c(10); } +fn main() { int k = 1; switch (k) { case 1: continue; } return 0; } diff --git a/tests/conformance/4-statements/continue_outside.zc b/tests/conformance/4-statements/continue_outside.zc new file mode 100644 index 0000000..7d8e808 --- /dev/null +++ b/tests/conformance/4-statements/continue_outside.zc @@ -0,0 +1,5 @@ +// expect error: continue outside a loop +// spec 4.8.1 +include rt; +void pn(int x) { rt.put_n(x); rt.put_c(10); } +fn main() { continue; return 0; } diff --git a/tests/conformance/4-statements/decl_const_assign.zc b/tests/conformance/4-statements/decl_const_assign.zc new file mode 100644 index 0000000..63728dc --- /dev/null +++ b/tests/conformance/4-statements/decl_const_assign.zc @@ -0,0 +1,5 @@ +// expect error: const storage cannot be modified +// spec 4.1.4 +include rt; +void pn(int x) { rt.put_n(x); rt.put_c(10); } +fn main() { const k = 1; k += 2; return 0; } diff --git a/tests/conformance/4-statements/decl_const_increment.zc b/tests/conformance/4-statements/decl_const_increment.zc new file mode 100644 index 0000000..28d7065 --- /dev/null +++ b/tests/conformance/4-statements/decl_const_increment.zc @@ -0,0 +1,5 @@ +// expect error: const storage cannot be modified +// spec 4.1.4 and 2.10.1 +include rt; +void pn(int x) { rt.put_n(x); rt.put_c(10); } +fn main() { const k = 1; k++; return 0; } diff --git a/tests/conformance/4-statements/decl_const_local_typed_float.zc b/tests/conformance/4-statements/decl_const_local_typed_float.zc new file mode 100644 index 0000000..d8470ae --- /dev/null +++ b/tests/conformance/4-statements/decl_const_local_typed_float.zc @@ -0,0 +1,6 @@ +// expect: 3.000000/ +// spec 4.1.4: const T k = e is a typed const +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() { const float k = 3; pf(k); return 0; } diff --git a/tests/conformance/4-statements/decl_const_takes_initializer_type.zc b/tests/conformance/4-statements/decl_const_takes_initializer_type.zc new file mode 100644 index 0000000..cfe2aec --- /dev/null +++ b/tests/conformance/4-statements/decl_const_takes_initializer_type.zc @@ -0,0 +1,6 @@ +// expect: 0.500000/ +// spec 4.1.4 and 2.10.2: a local const takes the type of its initializer (float here) +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() { const k = 1.5; pf(k - 1); return 0; } diff --git a/tests/conformance/4-statements/decl_for_init_scope.zc b/tests/conformance/4-statements/decl_for_init_scope.zc new file mode 100644 index 0000000..7d4cae3 --- /dev/null +++ b/tests/conformance/4-statements/decl_for_init_scope.zc @@ -0,0 +1,5 @@ +// expect error: i is used but never defined +// spec 4.1.8: a for initializer declaration is scoped to the loop +include rt; +void pn(int x) { rt.put_n(x); rt.put_c(10); } +fn main() { for (int i = 0; i < 2; i++) { } pn(i); return 0; } diff --git a/tests/conformance/4-statements/decl_for_let_init_scope.zc b/tests/conformance/4-statements/decl_for_let_init_scope.zc new file mode 100644 index 0000000..1f94e3b --- /dev/null +++ b/tests/conformance/4-statements/decl_for_let_init_scope.zc @@ -0,0 +1,5 @@ +// expect error: i is used but never defined +// spec 4.6 and 4.1.8 +include rt; +void pn(int x) { rt.put_n(x); rt.put_c(10); } +fn main() { for (let i = 0; i < 2; i++) { } pn(i); return 0; } diff --git a/tests/conformance/4-statements/decl_let_array.zc b/tests/conformance/4-statements/decl_let_array.zc new file mode 100644 index 0000000..9d8d701 --- /dev/null +++ b/tests/conformance/4-statements/decl_let_array.zc @@ -0,0 +1,10 @@ +// expect: 10/3/ +// spec 4.1.2: let a[10]; is an untyped array of 10 words (word[10]) +include rt; +void pn(int x) { rt.put_n(x); rt.put_c(10); } +fn main() { + let a[10]; + a[9] = 3; + pn(sizeof(a)); pn(a[9]); + return 0; +} diff --git a/tests/conformance/4-statements/decl_let_bstr.zc b/tests/conformance/4-statements/decl_let_bstr.zc new file mode 100644 index 0000000..c54d0d8 --- /dev/null +++ b/tests/conformance/4-statements/decl_let_bstr.zc @@ -0,0 +1,9 @@ +// expect: 3/98/ +// spec 4.1.2: bstr from a byte-string literal +include rt; +void pn(int x) { rt.put_n(x); rt.put_c(10); } +fn main() { + let t = b"abc"; + pn(len(t)); pn(t[1]); + return 0; +} diff --git a/tests/conformance/4-statements/decl_let_char_ptr.zc b/tests/conformance/4-statements/decl_let_char_ptr.zc new file mode 100644 index 0000000..4bc7a57 --- /dev/null +++ b/tests/conformance/4-statements/decl_let_char_ptr.zc @@ -0,0 +1,9 @@ +// expect: 2/105/ +// spec 4.1.2: char* from a word-string literal +include rt; +void pn(int x) { rt.put_n(x); rt.put_c(10); } +fn main() { + let s = "hi"; + pn(rt.len_w(s)); pn(s[1]); + return 0; +} diff --git a/tests/conformance/4-statements/decl_let_float_local.zc b/tests/conformance/4-statements/decl_let_float_local.zc new file mode 100644 index 0000000..118e6a9 --- /dev/null +++ b/tests/conformance/4-statements/decl_let_float_local.zc @@ -0,0 +1,10 @@ +// expect: 0.750000/ +// spec 4.1.2: a float local from a float initializer, so / is float division +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() { + let f = 1.5; + pf(f / 2); + return 0; +} diff --git a/tests/conformance/4-statements/decl_let_function_type.zc b/tests/conformance/4-statements/decl_let_function_type.zc new file mode 100644 index 0000000..9f9d76d --- /dev/null +++ b/tests/conformance/4-statements/decl_let_function_type.zc @@ -0,0 +1,6 @@ +// expect: 7/ +// spec 4.1.2: the function type of the initializer +include rt; +void pn(int x) { rt.put_n(x); rt.put_c(10); } +int add(int a, int b) { return a + b; } +fn main() { let h = add; pn(h(3, 4)); return 0; } diff --git a/tests/conformance/4-statements/decl_let_integer_is_word.zc b/tests/conformance/4-statements/decl_let_integer_is_word.zc new file mode 100644 index 0000000..8159089 --- /dev/null +++ b/tests/conformance/4-statements/decl_let_integer_is_word.zc @@ -0,0 +1,5 @@ +// expect: 3/ +// spec 4.1.2: a plain word for integers +include rt; +void pn(int x) { rt.put_n(x); rt.put_c(10); } +fn main() { let n = 3; pn(n); return 0; } diff --git a/tests/conformance/4-statements/decl_let_multiple.zc b/tests/conformance/4-statements/decl_let_multiple.zc new file mode 100644 index 0000000..e6ec7d4 --- /dev/null +++ b/tests/conformance/4-statements/decl_let_multiple.zc @@ -0,0 +1,10 @@ +// expect: 1/2/ +// spec 4.1.2: let a = e, b[10] +include rt; +void pn(int x) { rt.put_n(x); rt.put_c(10); } +fn main() { + let a = 1, b[4]; + b[3] = 2; + pn(a); pn(b[3]); + return 0; +} diff --git a/tests/conformance/4-statements/decl_redeclare_same_block.zc b/tests/conformance/4-statements/decl_redeclare_same_block.zc new file mode 100644 index 0000000..e593fb7 --- /dev/null +++ b/tests/conformance/4-statements/decl_redeclare_same_block.zc @@ -0,0 +1,5 @@ +// expect: 2/ +// spec 4.1.6: redeclaring a name in the same block is accepted and the new one hides the old one +include rt; +void pn(int x) { rt.put_n(x); rt.put_c(10); } +fn main() { int a = 1; int a = 2; pn(a); return 0; } diff --git a/tests/conformance/4-statements/decl_scope_ends_with_block.zc b/tests/conformance/4-statements/decl_scope_ends_with_block.zc new file mode 100644 index 0000000..4d868d7 --- /dev/null +++ b/tests/conformance/4-statements/decl_scope_ends_with_block.zc @@ -0,0 +1,5 @@ +// expect error: x is used but never defined +// spec 4.1.8: a local is scoped to its block +include rt; +void pn(int x) { rt.put_n(x); rt.put_c(10); } +fn main() { { int x = 1; } pn(x); return 0; } diff --git a/tests/conformance/4-statements/decl_shadow_function_name.zc b/tests/conformance/4-statements/decl_shadow_function_name.zc new file mode 100644 index 0000000..b7dcdd4 --- /dev/null +++ b/tests/conformance/4-statements/decl_shadow_function_name.zc @@ -0,0 +1,6 @@ +// expect: 5/ +// spec 4.1.6: a local may shadow a function name +include rt; +void pn(int x) { rt.put_n(x); rt.put_c(10); } +int twice(int x) { return x * 2; } +fn main() { int twice = 5; pn(twice); return 0; } diff --git a/tests/conformance/4-statements/decl_shadow_global.zc b/tests/conformance/4-statements/decl_shadow_global.zc new file mode 100644 index 0000000..279c063 --- /dev/null +++ b/tests/conformance/4-statements/decl_shadow_global.zc @@ -0,0 +1,6 @@ +// expect: 2/1/ +// spec 4.1.6: a local may shadow a global +include rt; +void pn(int x) { rt.put_n(x); rt.put_c(10); } +int g = 1; +fn main() { int g = 2; pn(g); pn(1); return 0; } diff --git a/tests/conformance/4-statements/decl_shadow_outer_block.zc b/tests/conformance/4-statements/decl_shadow_outer_block.zc new file mode 100644 index 0000000..eaf1fca --- /dev/null +++ b/tests/conformance/4-statements/decl_shadow_outer_block.zc @@ -0,0 +1,10 @@ +// expect: 2/1/ +// spec 4.1.6: a local may shadow a local of an outer block +include rt; +void pn(int x) { rt.put_n(x); rt.put_c(10); } +fn main() { + int a = 1; + { int a = 2; pn(a); } + pn(a); + return 0; +} diff --git a/tests/conformance/4-statements/decl_shadow_param.zc b/tests/conformance/4-statements/decl_shadow_param.zc new file mode 100644 index 0000000..9a91f1c --- /dev/null +++ b/tests/conformance/4-statements/decl_shadow_param.zc @@ -0,0 +1,6 @@ +// expect: 9/5/ +// spec 4.1.6: a local may shadow a parameter +include rt; +void pn(int x) { rt.put_n(x); rt.put_c(10); } +int f(int x) { { int x = 9; pn(x); } return x; } +fn main() { pn(f(5)); return 0; } diff --git a/tests/conformance/4-statements/decl_tag_only.zc b/tests/conformance/4-statements/decl_tag_only.zc new file mode 100644 index 0000000..6bd731e --- /dev/null +++ b/tests/conformance/4-statements/decl_tag_only.zc @@ -0,0 +1,10 @@ +// expect: 4/ +// spec 4.1.3: a declaration with only a tag declares an untyped local with that ownership tag +include rt; +void pn(int x) { rt.put_n(x); rt.put_c(10); } +fn main() { + .m r = rt.new(2); + r[0] = 4; + pn(r[0]); + return 0; +} diff --git a/tests/conformance/4-statements/decl_typed_array_declarator.zc b/tests/conformance/4-statements/decl_typed_array_declarator.zc new file mode 100644 index 0000000..1b144aa --- /dev/null +++ b/tests/conformance/4-statements/decl_typed_array_declarator.zc @@ -0,0 +1,10 @@ +// expect: 10/ +// spec 4.1.1: a declarator followed by [n] makes an array of n +include rt; +void pn(int x) { rt.put_n(x); rt.put_c(10); } +fn main() { + int a[10]; + pn(sizeof(a)); + return 0; +} +// zc0: skip diff --git a/tests/conformance/4-statements/decl_typed_multi.zc b/tests/conformance/4-statements/decl_typed_multi.zc new file mode 100644 index 0000000..4dc4d1c --- /dev/null +++ b/tests/conformance/4-statements/decl_typed_multi.zc @@ -0,0 +1,11 @@ +// expect: 8/ +// spec 4.1.1: T a = e, b, c[10]; +include rt; +void pn(int x) { rt.put_n(x); rt.put_c(10); } +fn main() { + int a = 1, b = 2, c[3]; + c[2] = 5; + pn(a + b + c[2]); + return 0; +} +// zc0: skip diff --git a/tests/conformance/4-statements/decl_typed_tag_u_hand_up.zc b/tests/conformance/4-statements/decl_typed_tag_u_hand_up.zc new file mode 100644 index 0000000..7bbf280 --- /dev/null +++ b/tests/conformance/4-statements/decl_typed_tag_u_hand_up.zc @@ -0,0 +1,14 @@ +// expect: 3/ +// spec 4.1.1: T*.u declaration; spec 6.3.1 the tag is the initial state +include rt; +void pn(int x) { rt.put_n(x); rt.put_c(10); } +.u make() { + int*.u p = rt.new(int); + *p = 3; + return u*p; +} +fn main() { + int* q = make(); + pn(*q); + return 0; +} diff --git a/tests/conformance/4-statements/decl_uninit_global_is_zero.zc b/tests/conformance/4-statements/decl_uninit_global_is_zero.zc new file mode 100644 index 0000000..6596d18 --- /dev/null +++ b/tests/conformance/4-statements/decl_uninit_global_is_zero.zc @@ -0,0 +1,8 @@ +// expect: 0/0/0/ +// spec 4.1.5 and 5.3.1: a global with no initializer is 0 +include rt; +void pn(int x) { rt.put_n(x); rt.put_c(10); } +int g; +int[4] ga; +fn main() { pn(g); pn(ga[0]); pn(ga[3]); return 0; } +// zc0: skip diff --git a/tests/conformance/4-statements/decl_void_variable.zc b/tests/conformance/4-statements/decl_void_variable.zc new file mode 100644 index 0000000..c9a8d85 --- /dev/null +++ b/tests/conformance/4-statements/decl_void_variable.zc @@ -0,0 +1,5 @@ +// expect error: a variable can't be void +// spec 4.1.7 +include rt; +void pn(int x) { rt.put_n(x); rt.put_c(10); } +fn main() { void v = 0; return 0; } diff --git a/tests/conformance/4-statements/do_basic.zc b/tests/conformance/4-statements/do_basic.zc new file mode 100644 index 0000000..0194f93 --- /dev/null +++ b/tests/conformance/4-statements/do_basic.zc @@ -0,0 +1,11 @@ +// expect: 13/ +// spec 4.5 +include rt; +void pn(int x) { rt.put_n(x); rt.put_c(10); } +fn main() { + int n = 0, i = 0; + do { i++; if (i == 2) continue; n = n + i; } while (i < 5); + pn(n); + return 0; +} +// zc0: skip diff --git a/tests/conformance/4-statements/do_break.zc b/tests/conformance/4-statements/do_break.zc new file mode 100644 index 0000000..6f27c2e --- /dev/null +++ b/tests/conformance/4-statements/do_break.zc @@ -0,0 +1,6 @@ +// expect: 3/ +// spec 4.8.1 +include rt; +void pn(int x) { rt.put_n(x); rt.put_c(10); } +fn main() { int n = 0; do { n++; if (n == 3) break; } while (1); pn(n); return 0; } +// zc0: skip diff --git a/tests/conformance/4-statements/do_continue_jumps_to_test.zc b/tests/conformance/4-statements/do_continue_jumps_to_test.zc new file mode 100644 index 0000000..0e5a7d1 --- /dev/null +++ b/tests/conformance/4-statements/do_continue_jumps_to_test.zc @@ -0,0 +1,6 @@ +// expect: 1/ +// spec 4.5: continue jumps to the test (the test is false, so the loop ends) +include rt; +void pn(int x) { rt.put_n(x); rt.put_c(10); } +fn main() { int n = 0; do { n++; continue; n = 99; } while (0); pn(n); return 0; } +// zc0: skip diff --git a/tests/conformance/4-statements/do_runs_once.zc b/tests/conformance/4-statements/do_runs_once.zc new file mode 100644 index 0000000..f320337 --- /dev/null +++ b/tests/conformance/4-statements/do_runs_once.zc @@ -0,0 +1,6 @@ +// expect: 1/ +// spec 4.5: runs the body, then tests +include rt; +void pn(int x) { rt.put_n(x); rt.put_c(10); } +fn main() { int n = 0; do { n++; } while (0); pn(n); return 0; } +// zc0: skip diff --git a/tests/conformance/4-statements/for_basic.zc b/tests/conformance/4-statements/for_basic.zc new file mode 100644 index 0000000..97b9d1c --- /dev/null +++ b/tests/conformance/4-statements/for_basic.zc @@ -0,0 +1,5 @@ +// expect: 10/ +// spec 4.6 +include rt; +void pn(int x) { rt.put_n(x); rt.put_c(10); } +fn main() { int s = 0; for (int i = 1; i <= 4; i++) s += i; pn(s); return 0; } diff --git a/tests/conformance/4-statements/for_cond_tests_first.zc b/tests/conformance/4-statements/for_cond_tests_first.zc new file mode 100644 index 0000000..6df4a4f --- /dev/null +++ b/tests/conformance/4-statements/for_cond_tests_first.zc @@ -0,0 +1,5 @@ +// expect: 0/ +// spec 4.6 +include rt; +void pn(int x) { rt.put_n(x); rt.put_c(10); } +fn main() { int n = 0; for (int i = 5; i < 3; i++) n++; pn(n); return 0; } diff --git a/tests/conformance/4-statements/for_continue_runs_step.zc b/tests/conformance/4-statements/for_continue_runs_step.zc new file mode 100644 index 0000000..371dc21 --- /dev/null +++ b/tests/conformance/4-statements/for_continue_runs_step.zc @@ -0,0 +1,10 @@ +// expect: 4/ +// spec 4.6 and 4.8.1: continue runs step then tests +include rt; +void pn(int x) { rt.put_n(x); rt.put_c(10); } +fn main() { + int c = 0; + for (int i = 0; i < 4; i++) { c++; continue; c = 99; } + pn(c); + return 0; +} diff --git a/tests/conformance/4-statements/for_empty_parts.zc b/tests/conformance/4-statements/for_empty_parts.zc new file mode 100644 index 0000000..7212ec6 --- /dev/null +++ b/tests/conformance/4-statements/for_empty_parts.zc @@ -0,0 +1,10 @@ +// expect: 3/ +// spec 4.6: init, cond and step may be empty; empty cond means true +include rt; +void pn(int x) { rt.put_n(x); rt.put_c(10); } +fn main() { + int i = 0; + for (;;) { i++; if (i == 3) break; } + pn(i); + return 0; +} diff --git a/tests/conformance/4-statements/for_expression_init.zc b/tests/conformance/4-statements/for_expression_init.zc new file mode 100644 index 0000000..3cf1093 --- /dev/null +++ b/tests/conformance/4-statements/for_expression_init.zc @@ -0,0 +1,5 @@ +// expect: 3/ +// spec 4.6: init may be an expression +include rt; +void pn(int x) { rt.put_n(x); rt.put_c(10); } +fn main() { int i; int n = 0; for (i = 0; i < 3; i++) n++; pn(n); return 0; } diff --git a/tests/conformance/4-statements/for_let_init.zc b/tests/conformance/4-statements/for_let_init.zc new file mode 100644 index 0000000..6041db1 --- /dev/null +++ b/tests/conformance/4-statements/for_let_init.zc @@ -0,0 +1,5 @@ +// expect: 6/ +// spec 4.6: init is a declaration (typed or let) +include rt; +void pn(int x) { rt.put_n(x); rt.put_c(10); } +fn main() { int s = 0; for (let i = 0; i < 4; i++) s += i; pn(s); return 0; } diff --git a/tests/conformance/4-statements/for_variable_is_scoped.zc b/tests/conformance/4-statements/for_variable_is_scoped.zc new file mode 100644 index 0000000..f154684 --- /dev/null +++ b/tests/conformance/4-statements/for_variable_is_scoped.zc @@ -0,0 +1,11 @@ +// expect: 100/5/ +// spec 4.6: the loop variable's scope is the loop (an outer i is untouched) +include rt; +void pn(int x) { rt.put_n(x); rt.put_c(10); } +fn main() { + int i = 100; + int last = 0; + for (int i = 0; i < 6; i++) last = i; + pn(i); pn(last); + return 0; +} diff --git a/tests/conformance/4-statements/hints_forms_accepted.zc b/tests/conformance/4-statements/hints_forms_accepted.zc new file mode 100644 index 0000000..a07ffd4 --- /dev/null +++ b/tests/conformance/4-statements/hints_forms_accepted.zc @@ -0,0 +1,9 @@ +// expect: 1/ +// spec 4.12: hints on, small, off have no effect on a normal run +include rt; +void pn(int x) { rt.put_n(x); rt.put_c(10); } +hints on; +hints small; +hints off; +fn main() { hints on; pn(1); return 0; } +// zc0: skip diff --git a/tests/conformance/4-statements/if_basic.zc b/tests/conformance/4-statements/if_basic.zc new file mode 100644 index 0000000..31cd9e1 --- /dev/null +++ b/tests/conformance/4-statements/if_basic.zc @@ -0,0 +1,10 @@ +// expect: 1/0/2/ +// spec 4.3 +include rt; +void pn(int x) { rt.put_n(x); rt.put_c(10); } +fn main() { + if (5) pn(1); else pn(9); + if (0) pn(9); else pn(0); + if (-3) pn(2); + return 0; +} diff --git a/tests/conformance/4-statements/if_branch_is_own_scope.zc b/tests/conformance/4-statements/if_branch_is_own_scope.zc new file mode 100644 index 0000000..d4f82ea --- /dev/null +++ b/tests/conformance/4-statements/if_branch_is_own_scope.zc @@ -0,0 +1,5 @@ +// expect error: q is used but never defined +// spec 4.3: each branch is its own block even without braces +include rt; +void pn(int x) { rt.put_n(x); rt.put_c(10); } +fn main() { if (1) int q = 5; pn(q); return 0; } diff --git a/tests/conformance/4-statements/if_else_binds_nearest.zc b/tests/conformance/4-statements/if_else_binds_nearest.zc new file mode 100644 index 0000000..0c9f235 --- /dev/null +++ b/tests/conformance/4-statements/if_else_binds_nearest.zc @@ -0,0 +1,8 @@ +// expect: 2/ +// spec 4.3: else binds to the nearest if +include rt; +void pn(int x) { rt.put_n(x); rt.put_c(10); } +fn main() { + if (1) if (0) pn(1); else pn(2); + return 0; +} diff --git a/tests/conformance/4-statements/if_else_binds_nearest_outer_not_taken.zc b/tests/conformance/4-statements/if_else_binds_nearest_outer_not_taken.zc new file mode 100644 index 0000000..8549864 --- /dev/null +++ b/tests/conformance/4-statements/if_else_binds_nearest_outer_not_taken.zc @@ -0,0 +1,8 @@ +// expect: +// spec 4.3: else binds to the nearest if, so nothing prints when the outer condition is false +include rt; +void pn(int x) { rt.put_n(x); rt.put_c(10); } +fn main() { + if (0) if (0) pn(1); else pn(2); + return 0; +} diff --git a/tests/conformance/4-statements/if_else_chain.zc b/tests/conformance/4-statements/if_else_chain.zc new file mode 100644 index 0000000..292a3b0 --- /dev/null +++ b/tests/conformance/4-statements/if_else_chain.zc @@ -0,0 +1,9 @@ +// expect: 3/ +// spec 4.3 +include rt; +void pn(int x) { rt.put_n(x); rt.put_c(10); } +fn main() { + int n = 7; + if (n < 3) pn(1); else if (n < 6) pn(2); else if (n < 9) pn(3); else pn(4); + return 0; +} diff --git a/tests/conformance/4-statements/if_float_condition.zc b/tests/conformance/4-statements/if_float_condition.zc new file mode 100644 index 0000000..02a988c --- /dev/null +++ b/tests/conformance/4-statements/if_float_condition.zc @@ -0,0 +1,11 @@ +// expect: 0/1/1/ +// spec 4.3: a float is false when +0.0 or -0.0 +include rt; +void pn(int x) { rt.put_n(x); rt.put_c(10); } +fn main() { + float z = 0.0, h = 0.5, n = 0.0 - 3.0; + if (z) pn(9); else pn(0); + if (h) pn(1); else pn(9); + if (n) pn(1); else pn(9); + return 0; +} diff --git a/tests/conformance/4-statements/memdebug_double_free.zc b/tests/conformance/4-statements/memdebug_double_free.zc new file mode 100644 index 0000000..ff91511 --- /dev/null +++ b/tests/conformance/4-statements/memdebug_double_free.zc @@ -0,0 +1,10 @@ +// expect error: zy: double free from line +// spec 4.11 +include rt; +void pn(int x) { rt.put_n(x); rt.put_c(10); } +memdebug on; +fn main() { + unchecked { int* p = rt.new(int); rt.free(p); rt.free(p); } + return 0; +} +// zc0: skip diff --git a/tests/conformance/4-statements/memdebug_off.zc b/tests/conformance/4-statements/memdebug_off.zc new file mode 100644 index 0000000..27de549 --- /dev/null +++ b/tests/conformance/4-statements/memdebug_off.zc @@ -0,0 +1,8 @@ +// expect: 1/ +// spec 4.11: memdebug off; stops the checks +include rt; +void pn(int x) { rt.put_n(x); rt.put_c(10); } +memdebug on; +memdebug off; +fn main() { unchecked { int* p = rt.new(int); rt.free(p); rt.free(p); } pn(1); return 0; } +// zc0: skip diff --git a/tests/conformance/4-statements/memdebug_report.zc b/tests/conformance/4-statements/memdebug_report.zc new file mode 100644 index 0000000..db81c6d --- /dev/null +++ b/tests/conformance/4-statements/memdebug_report.zc @@ -0,0 +1,15 @@ +// expect: 1/ +// spec 4.11: rt.memreport() returns the count of live recorded objects +include rt; +void pn(int x) { rt.put_n(x); rt.put_c(10); } +memdebug on; +fn main() { + unchecked { + int* q = rt.new(3); + int* r = rt.new(2); + rt.free(r); + pn(rt.memreport()); + } + return 0; +} +// zc0: skip diff --git a/tests/conformance/4-statements/memdebug_report_line.zc b/tests/conformance/4-statements/memdebug_report_line.zc new file mode 100644 index 0000000..8ab4273 --- /dev/null +++ b/tests/conformance/4-statements/memdebug_report_line.zc @@ -0,0 +1,15 @@ +// expect error: leak: line 8 +// spec 4.11: leak: line N W words per live recorded object (N is the allocation line) +include rt; +void pn(int x) { rt.put_n(x); rt.put_c(10); } +memdebug on; +fn main() { + unchecked { + int* q = rt.new(3); + int* r = rt.new(2); + rt.free(q); + rt.memreport(); + } + return 0; +} +// zc0: skip diff --git a/tests/conformance/4-statements/memdebug_scrub_accepted.zc b/tests/conformance/4-statements/memdebug_scrub_accepted.zc new file mode 100644 index 0000000..5253918 --- /dev/null +++ b/tests/conformance/4-statements/memdebug_scrub_accepted.zc @@ -0,0 +1,7 @@ +// expect: 1/ +// spec 4.11: memdebug scrub; is a form of the statement +include rt; +void pn(int x) { rt.put_n(x); rt.put_c(10); } +memdebug scrub; +fn main() { pn(1); return 0; } +// zc0: skip diff --git a/tests/conformance/4-statements/memdebug_scrub_fills.zc b/tests/conformance/4-statements/memdebug_scrub_fills.zc new file mode 100644 index 0000000..ad15e3d --- /dev/null +++ b/tests/conformance/4-statements/memdebug_scrub_fills.zc @@ -0,0 +1,10 @@ +// expect: 57005/ +// spec 4.11: memdebug scrub; fills freed payloads with 57005 +include rt; +void pn(int x) { rt.put_n(x); rt.put_c(10); } +memdebug scrub; +fn main() { + unchecked { int* p = rt.new(int); *p = 5; rt.free(p); pn(*p); } + return 0; +} +// zc0: skip diff --git a/tests/conformance/4-statements/memdebug_statement_form.zc b/tests/conformance/4-statements/memdebug_statement_form.zc new file mode 100644 index 0000000..e9273b1 --- /dev/null +++ b/tests/conformance/4-statements/memdebug_statement_form.zc @@ -0,0 +1,6 @@ +// expect: 1/ +// spec 4.11: memdebug is also a statement in a function +include rt; +void pn(int x) { rt.put_n(x); rt.put_c(10); } +fn main() { memdebug on; int* p = rt.new(int); rt.free(p); pn(1); return 0; } +// zc0: skip diff --git a/tests/conformance/4-statements/memdebug_use_after_free.zc b/tests/conformance/4-statements/memdebug_use_after_free.zc new file mode 100644 index 0000000..434aa5a --- /dev/null +++ b/tests/conformance/4-statements/memdebug_use_after_free.zc @@ -0,0 +1,10 @@ +// expect error: zy: use after free from line +// spec 4.11 +include rt; +void pn(int x) { rt.put_n(x); rt.put_c(10); } +memdebug on; +fn main() { + unchecked { int* p = rt.new(int); *p = 5; rt.free(p); pn(*p); } + return 0; +} +// zc0: skip diff --git a/tests/conformance/4-statements/nested_return_in_loop.zc b/tests/conformance/4-statements/nested_return_in_loop.zc new file mode 100644 index 0000000..ba246fb --- /dev/null +++ b/tests/conformance/4-statements/nested_return_in_loop.zc @@ -0,0 +1,9 @@ +// expect: 3/ +include rt; +void pn(int x) { rt.put_n(x); rt.put_c(10); } +int find(int want) { + for (int i = 0; i < 10; i++) { if (i == want) return i; } + return -1; +} +fn main() { pn(find(3)); return 0; } + diff --git a/tests/conformance/4-statements/o3_asm_cannot_reach.zc b/tests/conformance/4-statements/o3_asm_cannot_reach.zc new file mode 100644 index 0000000..4150742 --- /dev/null +++ b/tests/conformance/4-statements/o3_asm_cannot_reach.zc @@ -0,0 +1,6 @@ +// expect error: asm can't reach an o3 variable +// spec 4.10.1 +include rt; +void pn(int x) { rt.put_n(x); rt.put_c(10); } +fn main() { o3 { int x = 1; asm { x @ } } return 0; } +// zc0: skip diff --git a/tests/conformance/4-statements/o3_block.zc b/tests/conformance/4-statements/o3_block.zc new file mode 100644 index 0000000..3291152 --- /dev/null +++ b/tests/conformance/4-statements/o3_block.zc @@ -0,0 +1,11 @@ +// expect: 45/ +// spec 4.10.1: o3 { } marks a block +include rt; +void pn(int x) { rt.put_n(x); rt.put_c(10); } +fn main() { + int t = 0; + o3 { int s = 0; for (int i = 0; i < 10; i++) s += i; t = s; } + pn(t); + return 0; +} +// zc0: skip diff --git a/tests/conformance/4-statements/o3_fn_form.zc b/tests/conformance/4-statements/o3_fn_form.zc new file mode 100644 index 0000000..30cfc6b --- /dev/null +++ b/tests/conformance/4-statements/o3_fn_form.zc @@ -0,0 +1,7 @@ +// expect: 6/ +// spec 4.10.1: o3 fn f(...) +include rt; +void pn(int x) { rt.put_n(x); rt.put_c(10); } +o3 fn triple(int a) { return a * 3; } +fn main() { pn(triple(2)); return 0; } +// zc0: skip diff --git a/tests/conformance/4-statements/o3_function_sum.zc b/tests/conformance/4-statements/o3_function_sum.zc new file mode 100644 index 0000000..37b3ef4 --- /dev/null +++ b/tests/conformance/4-statements/o3_function_sum.zc @@ -0,0 +1,13 @@ +// expect: 10/ +// spec 4.10.1 example: o3 changes speed, not meaning +include rt; +void pn(int x) { rt.put_n(x); rt.put_c(10); } +o3 int sum(fixed int[?] a) { int s = 0; for (int i = 0; i < len(a); i++) s += a[i]; return s; } +fn main() { + fixed int[?] a = rt.new(fixed int[?], 4); + for (int i = 0; i < 4; i++) a[i] = i + 1; + pn(sum(a)); + rt.free(a); + return 0; +} +// zc0: skip diff --git a/tests/conformance/4-statements/o3_nested_is_ordinary_block.zc b/tests/conformance/4-statements/o3_nested_is_ordinary_block.zc new file mode 100644 index 0000000..4d2306d --- /dev/null +++ b/tests/conformance/4-statements/o3_nested_is_ordinary_block.zc @@ -0,0 +1,6 @@ +// expect: 2/ +// spec 4.10.2: a nested o3 is an ordinary block +include rt; +void pn(int x) { rt.put_n(x); rt.put_c(10); } +fn main() { o3 { int a = 1; o3 { int b = a + 1; pn(b); } } return 0; } +// zc0: skip diff --git a/tests/conformance/4-statements/o3_no_address_of.zc b/tests/conformance/4-statements/o3_no_address_of.zc new file mode 100644 index 0000000..47cad16 --- /dev/null +++ b/tests/conformance/4-statements/o3_no_address_of.zc @@ -0,0 +1,6 @@ +// expect error: an o3 variable has no address +// spec 4.10.1 +include rt; +void pn(int x) { rt.put_n(x); rt.put_c(10); } +fn main() { o3 { int x = 1; int* p = &x; } return 0; } +// zc0: skip diff --git a/tests/conformance/4-statements/o3_outside_function_ordinary_block.zc b/tests/conformance/4-statements/o3_outside_function_ordinary_block.zc new file mode 100644 index 0000000..7fe3f09 --- /dev/null +++ b/tests/conformance/4-statements/o3_outside_function_ordinary_block.zc @@ -0,0 +1,7 @@ +// expect: 1/ +// spec 4.10.2: an o3 { } outside a function is an ordinary block +include rt; +void pn(int x) { rt.put_n(x); rt.put_c(10); } +o3 { } +fn main() { pn(1); return 0; } +// zc0: skip diff --git a/tests/conformance/4-statements/o3_parameter_needs_type.zc b/tests/conformance/4-statements/o3_parameter_needs_type.zc new file mode 100644 index 0000000..37384be --- /dev/null +++ b/tests/conformance/4-statements/o3_parameter_needs_type.zc @@ -0,0 +1,7 @@ +// expect error: o3 parameters need a type +// spec 4.10.1 +include rt; +void pn(int x) { rt.put_n(x); rt.put_c(10); } +o3 fn f(a) { return a; } +fn main() { return 0; } +// zc0: skip diff --git a/tests/conformance/4-statements/o3_single_variable.zc b/tests/conformance/4-statements/o3_single_variable.zc new file mode 100644 index 0000000..3deca8d --- /dev/null +++ b/tests/conformance/4-statements/o3_single_variable.zc @@ -0,0 +1,6 @@ +// expect: 7/ +// spec 4.10.1: o3 T x = e; marks one variable +include rt; +void pn(int x) { rt.put_n(x); rt.put_c(10); } +fn main() { o3 int x = 7; pn(x); return 0; } +// zc0: skip diff --git a/tests/conformance/4-statements/o3_variable_needs_type.zc b/tests/conformance/4-statements/o3_variable_needs_type.zc new file mode 100644 index 0000000..0741302 --- /dev/null +++ b/tests/conformance/4-statements/o3_variable_needs_type.zc @@ -0,0 +1,6 @@ +// expect error: o3 variables need a type +// spec 4.10.1 +include rt; +void pn(int x) { rt.put_n(x); rt.put_c(10); } +fn main() { o3 { let x = 1; pn(x); } return 0; } +// zc0: skip diff --git a/tests/conformance/4-statements/return_bare_is_zero.zc b/tests/conformance/4-statements/return_bare_is_zero.zc new file mode 100644 index 0000000..deb9235 --- /dev/null +++ b/tests/conformance/4-statements/return_bare_is_zero.zc @@ -0,0 +1,6 @@ +// expect: 0/ +// spec 4.8.2: return; returns 0 +include rt; +void pn(int x) { rt.put_n(x); rt.put_c(10); } +int g() { return; } +fn main() { pn(g()); return 0; } diff --git a/tests/conformance/4-statements/return_fall_off_is_zero.zc b/tests/conformance/4-statements/return_fall_off_is_zero.zc new file mode 100644 index 0000000..e0d1229 --- /dev/null +++ b/tests/conformance/4-statements/return_fall_off_is_zero.zc @@ -0,0 +1,6 @@ +// expect: 0/ +// spec 4.8.2: falling off the end returns 0 +include rt; +void pn(int x) { rt.put_n(x); rt.put_c(10); } +int g() { int a = 1; a++; } +fn main() { pn(g()); return 0; } diff --git a/tests/conformance/4-statements/return_frees_owned_locals.zc b/tests/conformance/4-statements/return_frees_owned_locals.zc new file mode 100644 index 0000000..ccff11c --- /dev/null +++ b/tests/conformance/4-statements/return_frees_owned_locals.zc @@ -0,0 +1,11 @@ +// expect: 5/ +// spec 4.8.2 and 6.5.1: return frees every owned local of the scopes it leaves +include rt; +void pn(int x) { rt.put_n(x); rt.put_c(10); } +int f(int n) { + int* p = rt.new(int); + *p = n; + if (n > 1) return *p; + return 0; +} +fn main() { pn(f(5)); return 0; } diff --git a/tests/conformance/4-statements/return_outside_function.zc b/tests/conformance/4-statements/return_outside_function.zc new file mode 100644 index 0000000..82e8f35 --- /dev/null +++ b/tests/conformance/4-statements/return_outside_function.zc @@ -0,0 +1,6 @@ +// expect error: zc: line 5: +// spec 4.8.2 +include rt; +void pn(int x) { rt.put_n(x); rt.put_c(10); } +return 1; +fn main() { return 0; } diff --git a/tests/conformance/4-statements/return_value_converted_float.zc b/tests/conformance/4-statements/return_value_converted_float.zc new file mode 100644 index 0000000..43248e1 --- /dev/null +++ b/tests/conformance/4-statements/return_value_converted_float.zc @@ -0,0 +1,7 @@ +// expect: 2.000000/ +// spec 4.8.2: converted to the result type +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; } +float g() { return 2; } +fn main() { pf(g()); return 0; } diff --git a/tests/conformance/4-statements/return_value_converted_int.zc b/tests/conformance/4-statements/return_value_converted_int.zc new file mode 100644 index 0000000..346c67b --- /dev/null +++ b/tests/conformance/4-statements/return_value_converted_int.zc @@ -0,0 +1,6 @@ +// expect: -2/ +// spec 4.8.2 +include rt; +void pn(int x) { rt.put_n(x); rt.put_c(10); } +int g() { return -2.7; } +fn main() { pn(g()); return 0; } diff --git a/tests/conformance/4-statements/return_void_value_typecheck_on.zc b/tests/conformance/4-statements/return_void_value_typecheck_on.zc new file mode 100644 index 0000000..a1d35ef --- /dev/null +++ b/tests/conformance/4-statements/return_void_value_typecheck_on.zc @@ -0,0 +1,7 @@ +// expect error: type error: return value: expected void, got int +// spec 4.8.3 +include rt; +void pn(int x) { rt.put_n(x); rt.put_c(10); } +typecheck on; +void f() { return 4; } +fn main() { f(); return 0; } diff --git a/tests/conformance/4-statements/stmt_block_scope.zc b/tests/conformance/4-statements/stmt_block_scope.zc new file mode 100644 index 0000000..3b6fd6e --- /dev/null +++ b/tests/conformance/4-statements/stmt_block_scope.zc @@ -0,0 +1,5 @@ +// expect: 3/1/ +// spec 4.2: { ... } is a block with its own scope +include rt; +void pn(int x) { rt.put_n(x); rt.put_c(10); } +fn main() { int a = 1; { int a = 3; pn(a); } pn(a); return 0; } diff --git a/tests/conformance/4-statements/stmt_empty_statement.zc b/tests/conformance/4-statements/stmt_empty_statement.zc new file mode 100644 index 0000000..520a451 --- /dev/null +++ b/tests/conformance/4-statements/stmt_empty_statement.zc @@ -0,0 +1,5 @@ +// expect: 1/ +// spec 4.2: ; alone is empty +include rt; +void pn(int x) { rt.put_n(x); rt.put_c(10); } +fn main() { ;;; pn(1); ; return 0; } diff --git a/tests/conformance/4-statements/stmt_expression_value_dropped.zc b/tests/conformance/4-statements/stmt_expression_value_dropped.zc new file mode 100644 index 0000000..b69ccaf --- /dev/null +++ b/tests/conformance/4-statements/stmt_expression_value_dropped.zc @@ -0,0 +1,5 @@ +// expect: 2/ +// spec 4.2: the value of an expression statement is dropped +include rt; +void pn(int x) { rt.put_n(x); rt.put_c(10); } +fn main() { int a = 1; a + 5; a = a + 1; 7; pn(a); return 0; } diff --git a/tests/conformance/4-statements/stmt_fresh_value_thrown_away.zc b/tests/conformance/4-statements/stmt_fresh_value_thrown_away.zc new file mode 100644 index 0000000..999f8c0 --- /dev/null +++ b/tests/conformance/4-statements/stmt_fresh_value_thrown_away.zc @@ -0,0 +1,5 @@ +// expect error: a new object (or a u result) can't be thrown away +// spec 4.2 +include rt; +void pn(int x) { rt.put_n(x); rt.put_c(10); } +fn main() { rt.new(int); return 0; } diff --git a/tests/conformance/4-statements/stmt_u_result_thrown_away.zc b/tests/conformance/4-statements/stmt_u_result_thrown_away.zc new file mode 100644 index 0000000..834dd96 --- /dev/null +++ b/tests/conformance/4-statements/stmt_u_result_thrown_away.zc @@ -0,0 +1,6 @@ +// expect error: a new object (or a u result) can't be thrown away +// spec 4.2 +include rt; +void pn(int x) { rt.put_n(x); rt.put_c(10); } +int*.u mk() { int*.u p = rt.new(int); return u*p; } +fn main() { mk(); return 0; } diff --git a/tests/conformance/4-statements/switch_break_in_loop_leaves_switch_only.zc b/tests/conformance/4-statements/switch_break_in_loop_leaves_switch_only.zc new file mode 100644 index 0000000..d69b64a --- /dev/null +++ b/tests/conformance/4-statements/switch_break_in_loop_leaves_switch_only.zc @@ -0,0 +1,13 @@ +// expect: 3/ +// spec 4.7.1: break in a switch inside a loop leaves the switch, not the loop +include rt; +void pn(int x) { rt.put_n(x); rt.put_c(10); } +fn main() { + int n = 0; + for (int i = 0; i < 3; i++) { + switch (i) { case 1: break; default: n++; } + n++; + } + pn(n); + return 0; +} diff --git a/tests/conformance/4-statements/switch_break_leaves_early.zc b/tests/conformance/4-statements/switch_break_leaves_early.zc new file mode 100644 index 0000000..8adbe64 --- /dev/null +++ b/tests/conformance/4-statements/switch_break_leaves_early.zc @@ -0,0 +1,10 @@ +// expect: 1/9/ +// spec 4.7.1: break inside a switch leaves it early +include rt; +void pn(int x) { rt.put_n(x); rt.put_c(10); } +fn main() { + int k = 1; + switch (k) { case 1: pn(1); break; pn(2); } + pn(9); + return 0; +} diff --git a/tests/conformance/4-statements/switch_case_own_block.zc b/tests/conformance/4-statements/switch_case_own_block.zc new file mode 100644 index 0000000..16bc31f --- /dev/null +++ b/tests/conformance/4-statements/switch_case_own_block.zc @@ -0,0 +1,11 @@ +// expect: 5/6/ +// spec 4.7.2: the statements of a case form their own block +include rt; +void pn(int x) { rt.put_n(x); rt.put_c(10); } +void t(int k) { + switch (k) { + case 1: int x = 5; pn(x); + case 2: int x = 6; pn(x); + } +} +fn main() { t(1); t(2); return 0; } diff --git a/tests/conformance/4-statements/switch_case_three.zc b/tests/conformance/4-statements/switch_case_three.zc new file mode 100644 index 0000000..eefaced --- /dev/null +++ b/tests/conformance/4-statements/switch_case_three.zc @@ -0,0 +1,10 @@ +// expect: three/ +// spec 4.7.1 +include rt; +void pn(int x) { rt.put_n(x); rt.put_c(10); } +void ps(char* s) { rt.put_s(s); rt.put_c(10); } +fn main() { + int k = 3; + switch (k) { case 1, 2: ps("one-two"); case 3: ps("three"); break; default: ps("d"); } + return 0; +} diff --git a/tests/conformance/4-statements/switch_case_underscore.zc b/tests/conformance/4-statements/switch_case_underscore.zc new file mode 100644 index 0000000..4d05f8e --- /dev/null +++ b/tests/conformance/4-statements/switch_case_underscore.zc @@ -0,0 +1,7 @@ +// expect: d/one/ +// spec 4.7.1: case _ is a catch-all with the same meaning as default +include rt; +void pn(int x) { rt.put_n(x); rt.put_c(10); } +void ps(char* s) { rt.put_s(s); rt.put_c(10); } +void t(int k) { switch (k) { case 1: ps("one"); case _: ps("d"); } } +fn main() { t(8); t(1); return 0; } diff --git a/tests/conformance/4-statements/switch_continue_continues_loop.zc b/tests/conformance/4-statements/switch_continue_continues_loop.zc new file mode 100644 index 0000000..d408253 --- /dev/null +++ b/tests/conformance/4-statements/switch_continue_continues_loop.zc @@ -0,0 +1,10 @@ +// expect: 1/3/4/ +// spec 4.7.1: continue inside a switch continues the enclosing loop +include rt; +void pn(int x) { rt.put_n(x); rt.put_c(10); } +fn main() { + for (int i = 1; i <= 4; i++) { + switch (i) { case 2: continue; default: pn(i); } + } + return 0; +} diff --git a/tests/conformance/4-statements/switch_default_and_underscore.zc b/tests/conformance/4-statements/switch_default_and_underscore.zc new file mode 100644 index 0000000..92c9025 --- /dev/null +++ b/tests/conformance/4-statements/switch_default_and_underscore.zc @@ -0,0 +1,5 @@ +// expect error: a switch has one +// spec 4.7.1: default and _ are the same thing, so a switch can have only one of them +include rt; +void pn(int x) { rt.put_n(x); rt.put_c(10); } +fn main() { int k = 1; switch (k) { default: pn(1); case _: pn(2); } return 0; } diff --git a/tests/conformance/4-statements/switch_default_first_position_not_matched.zc b/tests/conformance/4-statements/switch_default_first_position_not_matched.zc new file mode 100644 index 0000000..4d63ae3 --- /dev/null +++ b/tests/conformance/4-statements/switch_default_first_position_not_matched.zc @@ -0,0 +1,10 @@ +// expect: one/ +// spec 4.7.1: default runs when no label matches, wherever it is written +include rt; +void pn(int x) { rt.put_n(x); rt.put_c(10); } +void ps(char* s) { rt.put_s(s); rt.put_c(10); } +fn main() { + int k = 1; + switch (k) { default: ps("d"); case 1: ps("one"); case 2: ps("two"); } + return 0; +} diff --git a/tests/conformance/4-statements/switch_default_first_position_taken.zc b/tests/conformance/4-statements/switch_default_first_position_taken.zc new file mode 100644 index 0000000..113795f --- /dev/null +++ b/tests/conformance/4-statements/switch_default_first_position_taken.zc @@ -0,0 +1,10 @@ +// expect: d/ +// spec 4.7.1: default runs when no label matches, wherever it is written +include rt; +void pn(int x) { rt.put_n(x); rt.put_c(10); } +void ps(char* s) { rt.put_s(s); rt.put_c(10); } +fn main() { + int k = 7; + switch (k) { default: ps("d"); case 1: ps("one"); case 2: ps("two"); } + return 0; +} diff --git a/tests/conformance/4-statements/switch_default_middle.zc b/tests/conformance/4-statements/switch_default_middle.zc new file mode 100644 index 0000000..a390efe --- /dev/null +++ b/tests/conformance/4-statements/switch_default_middle.zc @@ -0,0 +1,7 @@ +// expect: d/two/ +// spec 4.7.1: default in the middle +include rt; +void pn(int x) { rt.put_n(x); rt.put_c(10); } +void ps(char* s) { rt.put_s(s); rt.put_c(10); } +void t(int k) { switch (k) { case 1: ps("one"); default: ps("d"); case 2: ps("two"); } } +fn main() { t(5); t(2); return 0; } diff --git a/tests/conformance/4-statements/switch_default_runs.zc b/tests/conformance/4-statements/switch_default_runs.zc new file mode 100644 index 0000000..bc42976 --- /dev/null +++ b/tests/conformance/4-statements/switch_default_runs.zc @@ -0,0 +1,10 @@ +// expect: d/ +// spec 4.7.1 +include rt; +void pn(int x) { rt.put_n(x); rt.put_c(10); } +void ps(char* s) { rt.put_s(s); rt.put_c(10); } +fn main() { + int k = 9; + switch (k) { case 1, 2: ps("one-two"); case 3: ps("three"); break; default: ps("d"); } + return 0; +} diff --git a/tests/conformance/4-statements/switch_duplicate_labels_first_wins.zc b/tests/conformance/4-statements/switch_duplicate_labels_first_wins.zc new file mode 100644 index 0000000..e2a2e3b --- /dev/null +++ b/tests/conformance/4-statements/switch_duplicate_labels_first_wins.zc @@ -0,0 +1,10 @@ +// expect: first/ +// spec 4.7.2: duplicate labels are not an error, the first matching case in source order runs +include rt; +void pn(int x) { rt.put_n(x); rt.put_c(10); } +void ps(char* s) { rt.put_s(s); rt.put_c(10); } +fn main() { + int k = 4; + switch (k) { case 4: ps("first"); case 4: ps("second"); } + return 0; +} diff --git a/tests/conformance/4-statements/switch_expression_evaluated_once.zc b/tests/conformance/4-statements/switch_expression_evaluated_once.zc new file mode 100644 index 0000000..bf82b99 --- /dev/null +++ b/tests/conformance/4-statements/switch_expression_evaluated_once.zc @@ -0,0 +1,10 @@ +// expect: 1/hit/ +// spec 4.7.1 +include rt; +void pn(int x) { rt.put_n(x); rt.put_c(10); } +fn main() { + int i = 0; + switch (i++) { case 5: pn(5); case 6: pn(6); case 0: rt.put_s("hit"); } + pn(i); + return 0; +} diff --git a/tests/conformance/4-statements/switch_label_forms.zc b/tests/conformance/4-statements/switch_label_forms.zc new file mode 100644 index 0000000..ae131aa --- /dev/null +++ b/tests/conformance/4-statements/switch_label_forms.zc @@ -0,0 +1,16 @@ +// expect: neg/chr/sum/enum/ +// spec 4.7.1 and 3.14: labels are constant expressions +include rt; +void pn(int x) { rt.put_n(x); rt.put_c(10); } +enum color { RED, GREEN }; +void t(int k) { + switch (k) { + case -1: rt.put_s("neg"); + case 'a': rt.put_s("chr"); + case 1 + 1 * 3: rt.put_s("sum"); + case color.GREEN: rt.put_s("enum"); + } + rt.put_c(10); +} +fn main() { t(-1); pn(0); return 0; } +// zc0: skip diff --git a/tests/conformance/4-statements/switch_nested.zc b/tests/conformance/4-statements/switch_nested.zc new file mode 100644 index 0000000..7fd9a34 --- /dev/null +++ b/tests/conformance/4-statements/switch_nested.zc @@ -0,0 +1,14 @@ +// expect: in2/ +// spec 4.7.1 +include rt; +void pn(int x) { rt.put_n(x); rt.put_c(10); } +void ps(char* s) { rt.put_s(s); rt.put_c(10); } +fn main() { + int a = 1, b = 2; + switch (a) { + case 1: + switch (b) { case 1: ps("in1"); break; case 2: ps("in2"); break; } + case 2: ps("outer2"); + } + return 0; +} diff --git a/tests/conformance/4-statements/switch_no_fallthrough_k2.zc b/tests/conformance/4-statements/switch_no_fallthrough_k2.zc new file mode 100644 index 0000000..276ca30 --- /dev/null +++ b/tests/conformance/4-statements/switch_no_fallthrough_k2.zc @@ -0,0 +1,10 @@ +// expect: one-two/ +// spec 4.7.1: cases do not fall through +include rt; +void pn(int x) { rt.put_n(x); rt.put_c(10); } +void ps(char* s) { rt.put_s(s); rt.put_c(10); } +fn main() { + int k = 2; + switch (k) { case 1, 2: ps("one-two"); case 3: ps("three"); break; default: ps("d"); } + return 0; +} diff --git a/tests/conformance/4-statements/switch_no_match_no_default.zc b/tests/conformance/4-statements/switch_no_match_no_default.zc new file mode 100644 index 0000000..3021388 --- /dev/null +++ b/tests/conformance/4-statements/switch_no_match_no_default.zc @@ -0,0 +1,11 @@ +// expect: after/ +// spec 4.7.1 +include rt; +void pn(int x) { rt.put_n(x); rt.put_c(10); } +void ps(char* s) { rt.put_s(s); rt.put_c(10); } +fn main() { + int k = 5; + switch (k) { case 1: ps("one"); case 2: ps("two"); } + ps("after"); + return 0; +} diff --git a/tests/conformance/4-statements/switch_non_constant_label.zc b/tests/conformance/4-statements/switch_non_constant_label.zc new file mode 100644 index 0000000..dc42b5b --- /dev/null +++ b/tests/conformance/4-statements/switch_non_constant_label.zc @@ -0,0 +1,5 @@ +// expect error: expected a constant +// spec 4.7.2 +include rt; +void pn(int x) { rt.put_n(x); rt.put_c(10); } +fn main() { int k = 1, j = 2; switch (k) { case j: pn(1); } return 0; } diff --git a/tests/conformance/4-statements/switch_return_inside_case.zc b/tests/conformance/4-statements/switch_return_inside_case.zc new file mode 100644 index 0000000..7375e79 --- /dev/null +++ b/tests/conformance/4-statements/switch_return_inside_case.zc @@ -0,0 +1,6 @@ +// expect: 20/10/ +// spec 4.7.1 and 4.8.2 +include rt; +void pn(int x) { rt.put_n(x); rt.put_c(10); } +int f(int k) { switch (k) { case 1: return 10; case 2: return 20; } return 0; } +fn main() { pn(f(2)); pn(f(1)); return 0; } diff --git a/tests/conformance/4-statements/switch_tagged_all_covered_no_warning.zc b/tests/conformance/4-statements/switch_tagged_all_covered_no_warning.zc new file mode 100644 index 0000000..45a9846 --- /dev/null +++ b/tests/conformance/4-statements/switch_tagged_all_covered_no_warning.zc @@ -0,0 +1,11 @@ +// expect: 2/ +// spec 4.7.3: no warning when every member is covered +include rt; +void pn(int x) { rt.put_n(x); rt.put_c(10); } +enum e { a { int v; }, b }; +fn main() { + e* s = e.a(2); + switch (s) { case a(v): pn(v); case b: pn(0); } + rt.free(s); + return 0; +} diff --git a/tests/conformance/4-statements/switch_tagged_binding_count.zc b/tests/conformance/4-statements/switch_tagged_binding_count.zc new file mode 100644 index 0000000..08006a6 --- /dev/null +++ b/tests/conformance/4-statements/switch_tagged_binding_count.zc @@ -0,0 +1,11 @@ +// expect error: a case binds every field of its member +// spec 4.7.3 +include rt; +void pn(int x) { rt.put_n(x); rt.put_c(10); } +enum shape { circle { int r; }, rect { int w; int h; }, dot }; +fn main() { + shape* s = shape.rect(1, 2); + switch (s) { case rect(w): pn(w); default: pn(0); } + rt.free(s); + return 0; +} diff --git a/tests/conformance/4-statements/switch_tagged_binding_scoped_to_case.zc b/tests/conformance/4-statements/switch_tagged_binding_scoped_to_case.zc new file mode 100644 index 0000000..ed8ee03 --- /dev/null +++ b/tests/conformance/4-statements/switch_tagged_binding_scoped_to_case.zc @@ -0,0 +1,12 @@ +// expect error: w is used but never defined +// spec 4.7.3: each payload field is bound to a new local scoped to that case +include rt; +void pn(int x) { rt.put_n(x); rt.put_c(10); } +enum shape { circle { int r; }, rect { int w; int h; }, dot }; +fn main() { + shape* s = shape.rect(1, 2); + switch (s) { case rect(w, h): pn(w); default: pn(0); } + pn(w); + rt.free(s); + return 0; +} diff --git a/tests/conformance/4-statements/switch_tagged_circle.zc b/tests/conformance/4-statements/switch_tagged_circle.zc new file mode 100644 index 0000000..b1b1c55 --- /dev/null +++ b/tests/conformance/4-statements/switch_tagged_circle.zc @@ -0,0 +1,11 @@ +// expect: 7/ +// spec 4.7.3 +include rt; +void pn(int x) { rt.put_n(x); rt.put_c(10); } +enum shape { circle { int r; }, rect { int w; int h; }, dot }; +fn main() { + shape* s = shape.circle(7); + switch (s) { case circle(r): pn(r); case rect(w, h): pn(w * h); case dot: rt.put_s("dot"); } + rt.free(s); + return 0; +} diff --git a/tests/conformance/4-statements/switch_tagged_default_no_warning.zc b/tests/conformance/4-statements/switch_tagged_default_no_warning.zc new file mode 100644 index 0000000..0a22a7a --- /dev/null +++ b/tests/conformance/4-statements/switch_tagged_default_no_warning.zc @@ -0,0 +1,11 @@ +// expect: 1/ +// spec 4.7.3: no warning when there is a default +include rt; +void pn(int x) { rt.put_n(x); rt.put_c(10); } +enum shape { circle { int r; }, rect { int w; int h; }, dot }; +fn main() { + shape* s = shape.circle(1); + switch (s) { case circle(r): pn(r); default: pn(0); } + rt.free(s); + return 0; +} diff --git a/tests/conformance/4-statements/switch_tagged_example.zc b/tests/conformance/4-statements/switch_tagged_example.zc new file mode 100644 index 0000000..932aefc --- /dev/null +++ b/tests/conformance/4-statements/switch_tagged_example.zc @@ -0,0 +1,11 @@ +// expect: 20/ +// spec 4.7.3 example: prints 20 +include rt; +void pn(int x) { rt.put_n(x); rt.put_c(10); } +enum shape { circle { int r; }, rect { int w; int h; }, dot }; +fn main() { + shape* s = shape.rect(4, 5); + switch (s) { case circle(r): pn(r); case rect(w, h): pn(w * h); case dot: rt.put_s("dot"); } + rt.free(s); + return 0; +} diff --git a/tests/conformance/4-statements/switch_tagged_match_by_tag.zc b/tests/conformance/4-statements/switch_tagged_match_by_tag.zc new file mode 100644 index 0000000..9d2f7a1 --- /dev/null +++ b/tests/conformance/4-statements/switch_tagged_match_by_tag.zc @@ -0,0 +1,19 @@ +// expect: dot/dot2/ +// spec 4.7.3: case member: or case member(): matches by tag +include rt; +void pn(int x) { rt.put_n(x); rt.put_c(10); } +enum shape { circle { int r; }, rect { int w; int h; }, dot }; +void t(shape* s) { + switch (s) { case circle: rt.put_s("circle"); case rect(): rt.put_s("rect"); case dot: rt.put_s("dot"); } + rt.put_c(10); +} +void u(shape* s) { + switch (s) { case circle: rt.put_s("circle"); case rect: rt.put_s("rect"); case dot(): rt.put_s("dot2"); } + rt.put_c(10); +} +fn main() { + shape* a = shape.dot(); + t(a); u(a); + rt.free(a); + return 0; +} diff --git a/tests/conformance/4-statements/switch_tagged_uncovered_warning.zc b/tests/conformance/4-statements/switch_tagged_uncovered_warning.zc new file mode 100644 index 0000000..d567da5 --- /dev/null +++ b/tests/conformance/4-statements/switch_tagged_uncovered_warning.zc @@ -0,0 +1,11 @@ +// expect error: warning: this switch doesn't cover rect, dot +// spec 4.7.3: a switch on a tagged enum with no default that omits a member prints a warning +include rt; +void pn(int x) { rt.put_n(x); rt.put_c(10); } +enum shape { circle { int r; }, rect { int w; int h; }, dot }; +fn main() { + shape* s = shape.circle(1); + switch (s) { case circle(r): pn(r); } + rt.free(s); + return 0; +} diff --git a/tests/conformance/4-statements/switch_tagged_uncovered_warning_not_error.zc b/tests/conformance/4-statements/switch_tagged_uncovered_warning_not_error.zc new file mode 100644 index 0000000..dfacc9c --- /dev/null +++ b/tests/conformance/4-statements/switch_tagged_uncovered_warning_not_error.zc @@ -0,0 +1,11 @@ +// expect: zc: line 8: warning: this switch doesn't cover rect, dot/1/ +// spec 4.7.3 and 6.14: the warning is not an error, the program runs +include rt; +void pn(int x) { rt.put_n(x); rt.put_c(10); } +enum shape { circle { int r; }, rect { int w; int h; }, dot }; +fn main() { + shape* s = shape.circle(1); + switch (s) { case circle(r): pn(r); } + rt.free(s); + return 0; +} diff --git a/tests/conformance/4-statements/switch_two_defaults.zc b/tests/conformance/4-statements/switch_two_defaults.zc new file mode 100644 index 0000000..e1f4f90 --- /dev/null +++ b/tests/conformance/4-statements/switch_two_defaults.zc @@ -0,0 +1,5 @@ +// expect error: a switch has one default +// spec 4.7.1 +include rt; +void pn(int x) { rt.put_n(x); rt.put_c(10); } +fn main() { int k = 1; switch (k) { default: pn(1); default: pn(2); } return 0; } diff --git a/tests/conformance/4-statements/switch_two_underscores.zc b/tests/conformance/4-statements/switch_two_underscores.zc new file mode 100644 index 0000000..afc5f2b --- /dev/null +++ b/tests/conformance/4-statements/switch_two_underscores.zc @@ -0,0 +1,5 @@ +// expect error: a switch has one catch-all case +// spec 4.7.1 +include rt; +void pn(int x) { rt.put_n(x); rt.put_c(10); } +fn main() { int k = 1; switch (k) { case _: pn(1); case _: pn(2); } return 0; } diff --git a/tests/conformance/4-statements/unchecked_fn.zc b/tests/conformance/4-statements/unchecked_fn.zc new file mode 100644 index 0000000..fa2055e --- /dev/null +++ b/tests/conformance/4-statements/unchecked_fn.zc @@ -0,0 +1,6 @@ +// expect: 1/ +// spec 4.9: unchecked fn makes one function unchecked +include rt; +void pn(int x) { rt.put_n(x); rt.put_c(10); } +unchecked fn leaky() { int* p = rt.new(int); return 0; } +fn main() { leaky(); pn(1); return 0; } diff --git a/tests/conformance/4-statements/unchecked_fn_does_not_extend.zc b/tests/conformance/4-statements/unchecked_fn_does_not_extend.zc new file mode 100644 index 0000000..e93a582 --- /dev/null +++ b/tests/conformance/4-statements/unchecked_fn_does_not_extend.zc @@ -0,0 +1,6 @@ +// expect error: q: owned object is never used +// spec 4.9: only that function is unchecked +include rt; +void pn(int x) { rt.put_n(x); rt.put_c(10); } +unchecked fn leaky() { int* p = rt.new(int); return 0; } +fn main() { int* q = rt.new(int); leaky(); return 0; } diff --git a/tests/conformance/4-statements/unchecked_stmt_block.zc b/tests/conformance/4-statements/unchecked_stmt_block.zc new file mode 100644 index 0000000..eca1a38 --- /dev/null +++ b/tests/conformance/4-statements/unchecked_stmt_block.zc @@ -0,0 +1,9 @@ +// expect: ok/ +// spec 4.9 and 8.3: in unchecked code a second free of an object is ignored +include rt; +void pn(int x) { rt.put_n(x); rt.put_c(10); } +fn main() { + unchecked { int* p = rt.new(int); rt.free(p); rt.free(p); } + rt.put_s("ok"); rt.put_c(10); + return 0; +} diff --git a/tests/conformance/4-statements/unchecked_stmt_single.zc b/tests/conformance/4-statements/unchecked_stmt_single.zc new file mode 100644 index 0000000..2bdccb1 --- /dev/null +++ b/tests/conformance/4-statements/unchecked_stmt_single.zc @@ -0,0 +1,10 @@ +// expect: 3/ +// spec 4.9: unchecked stmt +include rt; +void pn(int x) { rt.put_n(x); rt.put_c(10); } +fn main() { + int a = 1; + unchecked a = a + 2; + pn(a); + return 0; +} diff --git a/tests/conformance/4-statements/unchecked_toplevel_rest_of_unit.zc b/tests/conformance/4-statements/unchecked_toplevel_rest_of_unit.zc new file mode 100644 index 0000000..439eca7 --- /dev/null +++ b/tests/conformance/4-statements/unchecked_toplevel_rest_of_unit.zc @@ -0,0 +1,10 @@ +// expect: 1/ +// spec 4.9: unchecked; at top level switches the analyzer off for the rest of the unit +include rt; +void pn(int x) { rt.put_n(x); rt.put_c(10); } +unchecked; +fn main() { + int* p = rt.new(int); + pn(1); + return 0; +} diff --git a/tests/conformance/4-statements/unchecked_tracked_local_rejected.zc b/tests/conformance/4-statements/unchecked_tracked_local_rejected.zc new file mode 100644 index 0000000..a5f0d6d --- /dev/null +++ b/tests/conformance/4-statements/unchecked_tracked_local_rejected.zc @@ -0,0 +1,9 @@ +// expect error: p: is tracked by the analyzer and can't be used in unchecked code +// spec 4.9 +include rt; +void pn(int x) { rt.put_n(x); rt.put_c(10); } +fn main() { + int* p = rt.new(int); + unchecked { *p = 2; } + return 0; +} diff --git a/tests/conformance/4-statements/while_basic.zc b/tests/conformance/4-statements/while_basic.zc new file mode 100644 index 0000000..05fa171 --- /dev/null +++ b/tests/conformance/4-statements/while_basic.zc @@ -0,0 +1,5 @@ +// expect: 10/ +// spec 4.4 +include rt; +void pn(int x) { rt.put_n(x); rt.put_c(10); } +fn main() { int i = 0, s = 0; while (i < 5) { i++; s += i; } pn(s - 5); return 0; } diff --git a/tests/conformance/4-statements/while_continue.zc b/tests/conformance/4-statements/while_continue.zc new file mode 100644 index 0000000..28c32b0 --- /dev/null +++ b/tests/conformance/4-statements/while_continue.zc @@ -0,0 +1,10 @@ +// expect: 25/ +// spec 4.8.1: continue goes to the next iteration of a while (the test) +include rt; +void pn(int x) { rt.put_n(x); rt.put_c(10); } +fn main() { + int i = 0, s = 0; + while (i < 10) { i++; if (i % 2 == 0) continue; s += i; } + pn(s); + return 0; +} diff --git a/tests/conformance/4-statements/while_one_exit_by_return.zc b/tests/conformance/4-statements/while_one_exit_by_return.zc new file mode 100644 index 0000000..6e71d2f --- /dev/null +++ b/tests/conformance/4-statements/while_one_exit_by_return.zc @@ -0,0 +1,6 @@ +// expect: 4/ +// spec 4.4 +include rt; +void pn(int x) { rt.put_n(x); rt.put_c(10); } +int f() { int i = 0; while (1) { i++; if (i == 4) return i; } } +fn main() { pn(f()); return 0; } diff --git a/tests/conformance/4-statements/while_one_exits_by_break.zc b/tests/conformance/4-statements/while_one_exits_by_break.zc new file mode 100644 index 0000000..e105204 --- /dev/null +++ b/tests/conformance/4-statements/while_one_exits_by_break.zc @@ -0,0 +1,5 @@ +// expect: 3/ +// spec 4.4: while (1) exits by break or return +include rt; +void pn(int x) { rt.put_n(x); rt.put_c(10); } +fn main() { int i = 0; while (1) { i++; if (i == 3) break; } pn(i); return 0; } diff --git a/tests/conformance/4-statements/while_tests_before.zc b/tests/conformance/4-statements/while_tests_before.zc new file mode 100644 index 0000000..069afbf --- /dev/null +++ b/tests/conformance/4-statements/while_tests_before.zc @@ -0,0 +1,5 @@ +// expect: 0/ +// spec 4.4: tests before each pass +include rt; +void pn(int x) { rt.put_n(x); rt.put_c(10); } +fn main() { int n = 0; while (0) n++; pn(n); return 0; } -- cgit v1.2.3