From 25bccf4883c7d5a6173cc8dd6a1e7f5739920a44 Mon Sep 17 00:00:00 2001 From: Christoffer Lerno Date: Mon, 10 Mar 2025 00:11:35 +0100 Subject: [PATCH] New faults and syntax (#2034) - Remove `[?]` syntax. - Change `int!` to `int?` syntax. - New `fault` declarations. - Enum associated values can reference the calling enum. --- lib/std/bits.c3 | 140 ++--- lib/std/collections/anylist.c3 | 42 +- lib/std/collections/elastic_array.c3 | 46 +- lib/std/collections/enummap.c3 | 2 +- lib/std/collections/enumset.c3 | 2 +- lib/std/collections/hashmap.c3 | 20 +- lib/std/collections/linkedlist.c3 | 28 +- lib/std/collections/list.c3 | 34 +- lib/std/collections/maybe.c3 | 6 +- lib/std/collections/object.c3 | 82 +-- lib/std/collections/priorityqueue.c3 | 8 +- lib/std/collections/range.c3 | 4 +- lib/std/collections/ringbuffer.c3 | 6 +- lib/std/compression/qoi.c3 | 48 +- lib/std/core/allocators/arena_allocator.c3 | 16 +- lib/std/core/allocators/dynamic_arena.c3 | 11 +- lib/std/core/allocators/heap_allocator.c3 | 12 +- lib/std/core/allocators/libc_allocator.c3 | 44 +- lib/std/core/allocators/on_stack_allocator.c3 | 6 +- lib/std/core/allocators/temp_allocator.c3 | 18 +- lib/std/core/allocators/tracking_allocator.c3 | 6 +- lib/std/core/array.c3 | 8 +- lib/std/core/builtin.c3 | 20 +- lib/std/core/conv.c3 | 57 +- lib/std/core/dstring.c3 | 14 +- lib/std/core/mem.c3 | 18 +- lib/std/core/mem_allocator.c3 | 40 +- lib/std/core/os/wasm_memory.c3 | 4 +- lib/std/core/private/macho_runtime.c3 | 17 +- lib/std/core/string.c3 | 139 +++-- lib/std/core/string_iterator.c3 | 12 +- lib/std/core/string_to_real.c3 | 40 +- lib/std/core/test.c3 | 4 +- lib/std/core/types.c3 | 35 +- lib/std/encoding/base32.c3 | 18 +- lib/std/encoding/base64.c3 | 26 +- lib/std/encoding/csv.c3 | 14 +- lib/std/encoding/encoding.c3 | 6 +- lib/std/encoding/hex.c3 | 16 +- lib/std/encoding/json.c3 | 77 ++- lib/std/experimental/FrameScheduler.c3 | 6 +- lib/std/io/bits.c3 | 6 +- lib/std/io/file.c3 | 54 +- lib/std/io/formatter.c3 | 69 ++- lib/std/io/formatter_private.c3 | 79 ++- lib/std/io/io.c3 | 46 +- lib/std/io/os/chdir.c3 | 18 +- lib/std/io/os/file_libc.c3 | 88 +-- lib/std/io/os/file_nolibc.c3 | 50 +- lib/std/io/os/fileinfo.c3 | 28 +- lib/std/io/os/getcwd.c3 | 8 +- lib/std/io/os/ls.c3 | 8 +- lib/std/io/os/mkdir.c3 | 24 +- lib/std/io/os/rmdir.c3 | 24 +- lib/std/io/os/rmtree.c3 | 10 +- lib/std/io/os/temp_directory.c3 | 12 +- lib/std/io/path.c3 | 131 +++-- lib/std/io/stream.c3 | 114 ++-- lib/std/io/stream/buffer.c3 | 22 +- lib/std/io/stream/bytebuffer.c3 | 26 +- lib/std/io/stream/bytereader.c3 | 20 +- lib/std/io/stream/bytewriter.c3 | 12 +- lib/std/io/stream/limitreader.c3 | 12 +- lib/std/io/stream/multireader.c3 | 12 +- lib/std/io/stream/multiwriter.c3 | 6 +- lib/std/io/stream/scanner.c3 | 18 +- lib/std/io/stream/teereader.c3 | 6 +- lib/std/math/bigint.c3 | 14 +- lib/std/math/math.c3 | 512 +++++++++--------- lib/std/math/math_matrix.c3 | 12 +- lib/std/math/math_nolibc/__tan.c3 | 2 +- lib/std/math/math_nolibc/__tandf.c3 | 2 +- lib/std/math/math_nolibc/atan.c3 | 12 +- lib/std/math/math_nolibc/rempi.c3 | 6 +- lib/std/math/uuid.c3 | 2 +- lib/std/net/http.c3 | 8 +- lib/std/net/inetaddr.c3 | 34 +- lib/std/net/net.c3 | 16 +- lib/std/net/os/posix.c3 | 40 +- lib/std/net/os/win32.c3 | 40 +- lib/std/net/socket.c3 | 48 +- lib/std/net/socket_private.c3 | 10 +- lib/std/net/tcp.c3 | 16 +- lib/std/net/udp.c3 | 8 +- lib/std/net/url.c3 | 42 +- lib/std/net/url_encoding.c3 | 15 +- lib/std/os/backtrace.c3 | 13 +- lib/std/os/env.c3 | 18 +- lib/std/os/linux/linux.c3 | 26 +- lib/std/os/macos/darwin.c3 | 16 +- lib/std/os/macos/objc.c3 | 14 +- lib/std/os/posix/files.c3 | 2 +- lib/std/os/subprocess.c3 | 92 ++-- lib/std/os/win32/process.c3 | 18 +- lib/std/sort/quicksort.c3 | 4 +- lib/std/text/i18n.c3 | 2 +- lib/std/threads/buffered_channel.c3 | 16 +- lib/std/threads/event/event_thread.c3 | 2 +- lib/std/threads/fixed_pool.c3 | 20 +- lib/std/threads/os/thread_posix.c3 | 75 +-- lib/std/threads/os/thread_win32.c3 | 74 +-- lib/std/threads/pool.c3 | 10 +- lib/std/threads/thread.c3 | 48 +- lib/std/threads/unbuffered_channel.c3 | 18 +- lib/std/time/time.c3 | 2 +- releasenotes.md | 4 + resources/examples/base64.c3 | 13 +- resources/examples/brainfk.c3 | 11 +- resources/examples/contextfree/boolerr.c3 | 27 +- resources/examples/contextfree/cleanup.c3 | 13 +- .../examples/contextfree/guess_number.c3 | 20 +- resources/examples/dynlib-test/add.c3 | 2 +- resources/examples/map.c3 | 20 +- resources/examples/nbodies.c3 | 2 +- resources/examples/plus_minus.c3 | 11 +- resources/examples/raylib/raylib_snake.c3 | 2 +- resources/examples/raylib/raylib_tetris.c3 | 12 +- resources/examples/retry.c3 | 13 +- resources/examples/staticlib-test/add.c3 | 2 +- resources/grammar/grammar.y | 2 +- resources/linux_stack.c3 | 2 +- src/compiler/abi/c_abi_x86.c | 1 - src/compiler/ast.c | 7 +- src/compiler/c_codegen.c | 4 +- src/compiler/codegen_internal.h | 1 - src/compiler/compiler_internal.h | 42 +- src/compiler/context.c | 14 +- src/compiler/copying.c | 14 +- src/compiler/enums.h | 39 +- src/compiler/expr.c | 8 +- src/compiler/headers.c | 5 +- src/compiler/json_output.c | 7 +- src/compiler/llvm_codegen.c | 27 +- src/compiler/llvm_codegen_debug_info.c | 2 - src/compiler/llvm_codegen_expr.c | 38 +- src/compiler/llvm_codegen_module.c | 1 - src/compiler/llvm_codegen_type.c | 42 -- src/compiler/llvm_codegen_value.c | 4 + src/compiler/number.c | 9 +- src/compiler/parse_expr.c | 2 +- src/compiler/parse_global.c | 94 ++-- src/compiler/parser_internal.h | 2 +- src/compiler/sema_casts.c | 148 ++--- src/compiler/sema_const.c | 8 +- src/compiler/sema_decls.c | 97 ++-- src/compiler/sema_expr.c | 131 ++--- src/compiler/sema_initializers.c | 2 +- src/compiler/sema_liveness.c | 9 +- src/compiler/sema_name_resolution.c | 3 +- src/compiler/sema_passes.c | 5 +- src/compiler/sema_stmts.c | 53 +- src/compiler/sema_types.c | 5 +- src/compiler/semantic_analyser.c | 5 +- src/compiler/types.c | 37 +- test/src/test_suite_runner.c3 | 14 +- test/test_suite/abi/small_struct_x64.c3t | 3 +- test/test_suite/any/any_in_any.c3t | 4 +- test/test_suite/any/variant_test.c3t | 2 +- .../test_suite/arrays/complex_array_const.c3t | 2 +- .../arrays/complex_inferred_array.c3t | 4 +- test/test_suite/arrays/inferred_array_err.c3 | 4 +- test/test_suite/arrays/inferred_array_err2.c3 | 2 +- .../arrays/inferred_array_optional.c3t | 10 +- test/test_suite/arrays/inferred_subarray.c3 | 4 +- .../assert/unreachable_in_macro.c3t | 9 +- .../attributes/user_defined_attributes.c3t | 2 +- .../builtins/builtin_with_optional.c3 | 4 +- test/test_suite/builtins/wide_strings.c3t | 20 +- ...e_strings_fail_on_bad_escape_codepoints.c3 | 4 +- ..._strings_fail_on_wrong_type_assignments.c3 | 4 +- .../cast/cast_string_to_infered_array.c3 | 2 +- test/test_suite/cast/cast_to_failable.c3 | 15 +- .../cast/implicit_infer_len_cast.c3t | 10 +- test/test_suite/cast/top_down_casts.c3t | 2 +- test/test_suite/clang/2002-01_02.c3t | 4 +- test/test_suite/clang/2002-07.c3t | 74 ++- test/test_suite/comments/simple_comments.c3 | 2 +- .../compile_time/comptime_array_folding.c3t | 2 +- .../test_suite/compile_time/concat_append.c3t | 2 +- .../concat_append_extended_and_edit.c3t | 2 +- .../compile_time/ct_cast_example.c3t | 2 +- .../compile_time/ct_subscript_inc.c3t | 12 +- .../compile_time/more_untyped_conversions.c3t | 2 +- test/test_suite/compile_time/stringify2.c3t | 2 +- .../compile_time/untyped_conversions.c3t | 14 +- .../compile_time/untyped_with_inferred.c3 | 2 +- .../compile_time_introspection/defined2.c3 | 2 +- .../compile_time_introspection/defined_err.c3 | 2 +- .../compile_time_introspection/paramsof.c3t | 6 +- .../compile_time_introspection/parentof.c3t | 4 +- .../compile_time_introspection/qnameof.c3t | 2 +- .../concurrency/atomic_load_store_debug.c3t | 2 +- .../constants/byte_literal_fail_base64.c3 | 2 +- .../constants/byte_literal_fail_base64_2.c3 | 2 +- .../constants/byte_literal_fail_base64_4.c3 | 2 +- .../constants/byte_literal_fail_hex.c3 | 2 +- test/test_suite/constants/byte_literals.c3t | 10 +- .../constants/empty_byte_literal.c3 | 2 +- test/test_suite/debug_symbols/defer_macro.c3t | 18 +- .../defer/defer_catch_direct_error.c3t | 8 +- test/test_suite/defer/defer_catch_err.c3t | 30 +- test/test_suite/defer/defer_catch_mix.c3t | 74 ++- test/test_suite/defer/defer_catch_try.c3t | 18 +- test/test_suite/defer/defer_with_catch.c3t | 2 +- test/test_suite/defer/defer_with_rethrow.c3 | 4 +- test/test_suite/defer/defer_with_return.c3 | 2 +- .../test_suite/defer/defer_with_unwrapped.c3t | 2 +- test/test_suite/define/forbidden_defines.c3 | 2 +- test/test_suite/distinct/distinct_invalid.c3 | 5 +- test/test_suite/dynamic/any_cast.c3 | 4 +- test/test_suite/dynamic/dynamic_mismatch.c3 | 2 +- test/test_suite/dynamic/dynamic_tracing.c3t | 6 +- test/test_suite/dynamic/inherit_linux.c3t | 2 +- test/test_suite/dynamic/inherit_macos.c3t | 2 +- .../dynamic/overlapping_function_linux.c3t | 3 +- .../dynamic/overlapping_function_macos.c3t | 2 +- test/test_suite/embed/embed_basic.c3t | 12 +- .../enum_associated_values_other.c3t | 3 +- test/test_suite/enumerations/enum_cast.c3t | 4 +- .../test_suite/enumerations/enum_recursive.c3 | 17 + test/test_suite/errors/anyfault_void.c3t | 39 +- test/test_suite/errors/bitshift_failable.c3 | 4 +- test/test_suite/errors/else_checks.c3t | 2 +- test/test_suite/errors/else_struct.c3t | 4 +- test/test_suite/errors/empty_fault.c3 | 4 +- test/test_suite/errors/error_decl_ok.c3 | 16 +- test/test_suite/errors/error_else.c3t | 13 +- test/test_suite/errors/error_introspect.c3t | 72 --- test/test_suite/errors/error_regression_2.c3t | 101 ++-- .../test_suite/errors/error_semantic_fails.c3 | 8 +- test/test_suite/errors/error_throw.c3 | 9 +- test/test_suite/errors/error_union.c3 | 5 +- test/test_suite/errors/failable_catch.c3t | 17 +- test/test_suite/errors/fault_conv.c3t | 21 +- .../errors/general_error_regression.c3t | 126 +---- .../errors/illegal_use_of_optional.c3 | 12 +- test/test_suite/errors/invalid_cast_ct.c3 | 16 - test/test_suite/errors/macro_err.c3t | 2 +- test/test_suite/errors/macro_err2.c3t | 8 +- test/test_suite/errors/macro_err3.c3t | 4 +- test/test_suite/errors/missing_bang.c3 | 6 +- .../errors/more_optional_discard.c3 | 8 +- test/test_suite/errors/more_optional_tests.c3 | 6 +- test/test_suite/errors/multiple_catch.c3t | 22 +- test/test_suite/errors/no_common.c3 | 2 +- .../errors/optional_chained_init.c3t | 24 +- test/test_suite/errors/optional_contracts.c3 | 23 +- test/test_suite/errors/optional_designated.c3 | 2 +- .../errors/optional_discarded_func.c3 | 20 +- .../errors/optional_discarded_macro.c3 | 20 +- test/test_suite/errors/optional_expr_list.c3t | 2 +- test/test_suite/errors/optional_inits.c3t | 16 +- test/test_suite/errors/optional_sizeof.c3 | 6 +- .../errors/optional_taddr_and_access.c3t | 20 +- .../errors/optional_untyped_list.c3 | 15 +- .../errors/optional_with_optional.c3t | 46 +- test/test_suite/errors/or_and_rethrow.c3t | 18 +- test/test_suite/errors/or_err_bool.c3t | 2 +- test/test_suite/errors/or_err_infer.c3t | 2 +- test/test_suite/errors/printing_errors.c3t | 25 +- test/test_suite/errors/rethrow.c3t | 4 +- test/test_suite/errors/rethrow_mingw.c3t | 4 +- test/test_suite/errors/rethrow_no_err.c3 | 6 +- .../errors/simple_static_failable.c3t | 11 +- test/test_suite/errors/ternary_void_fault.c3t | 2 +- test/test_suite/errors/try_assign.c3t | 8 +- test/test_suite/errors/try_catch_if.c3t | 10 +- .../errors/try_catch_unwrapping_while_if.c3 | 40 +- test/test_suite/errors/try_expr.c3t | 2 +- .../errors/try_unwrap_using_assert.c3 | 4 +- .../errors/try_with_assign_to_failable.c3 | 4 +- .../errors/try_with_chained_unwrap.c3t | 4 +- .../errors/try_with_chained_unwrap_errors.c3 | 26 +- test/test_suite/errors/try_with_unwrap.c3t | 8 +- test/test_suite/errors/try_with_unwrapper.c3t | 12 +- .../test_suite/errors/try_with_weird_stuff.c3 | 8 +- .../errors/type_optional_declaration_order.c3 | 20 +- test/test_suite/expressions/addr_of_fails.c3 | 5 +- .../expressions/arithmetics_sema_fail.c3 | 2 +- .../expressions/assign_deref_opt.c3 | 4 +- .../expressions/assign_optional.c3t | 10 +- .../expressions/casts/cast_failable.c3 | 9 +- .../casts/struct_cast_and_distinct.c3 | 10 +- .../expressions/casts/void_casting.c3t | 12 +- .../expressions/chained_ternary.c3t | 20 +- .../expressions/incdec_overload.c3t | 2 +- test/test_suite/expressions/negate_int.c3 | 24 +- test/test_suite/expressions/opt_in_conv.c3 | 2 +- .../expressions/optional_and_error.c3 | 2 +- .../expressions/optional_ternary.c3t | 45 +- test/test_suite/expressions/plus_int.c3 | 12 +- .../test_suite/expressions/pointer_access.c3t | 8 +- .../from_docs/examples_if_catch.c3t | 19 +- .../functions/c_vararg_expansion.c3t | 2 +- .../functions/default_param_fail.c3 | 7 +- test/test_suite/functions/failable_param.c3 | 2 +- .../functions/func_ptr_conversion_alias.c3t | 4 +- .../func_ptr_conversions_and_names.c3t | 10 +- .../functions/function_alias_llvm_check.c3t | 2 +- .../functions/missing_return_lambda.c3 | 4 +- test/test_suite/functions/pointer_escape.c3 | 2 +- .../functions/recursive_through_generic.c3 | 2 +- test/test_suite/functions/test_regression.c3t | 16 +- .../functions/test_regression_mingw.c3t | 16 +- .../generic/generic_lambda_complex.c3t | 28 +- test/test_suite/generic/nested_typedef.c3t | 4 +- test/test_suite/globals/global_init.c3 | 2 +- test/test_suite/globals/init_with_err.c3t | 23 +- .../initializer_lists/disallowed_lists.c3 | 2 +- .../initializer_lists/general_tests.c3t | 4 +- .../initializer_lists/infer_with_init.c3t | 6 +- test/test_suite/initializer_lists/statics.c3t | 4 +- .../initializer_lists/subarrays.c3t | 4 +- .../initializer_lists/zero_inferred_array.c3 | 2 +- .../literals/radix_numbers_errors.c3 | 2 +- test/test_suite/macros/implicit_return_opt.c3 | 2 +- test/test_suite/macros/macro_body_defer.c3t | 2 +- .../macro_chained_return_void_optional.c3t | 4 +- .../macros/macro_failable_return_rethrow.c3t | 4 +- test/test_suite/macros/macro_vasplat.c3t | 16 +- .../macros/unifying_implicit_void.c3t | 2 +- test/test_suite/macros/userland_bitcast.c3t | 2 +- .../methods/enum_distinct_err_methods.c3t | 97 +--- test/test_suite/pointers/const_ref.c3t | 4 +- test/test_suite/slices/array_to_const_err.c3 | 2 +- test/test_suite/slices/slice_negative_len.c3 | 2 +- test/test_suite/slices/slice_optional.c3t | 4 +- .../slices/slice_optional_index.c3t | 10 +- .../slices/slice_to_slice_assign.c3t | 2 +- .../slices/slice_to_slice_vector_assign.c3t | 2 +- .../slices/various_const_slicing.c3t | 2 +- .../statements/custom_foreach_with_ref.c3t | 2 +- .../test_suite/statements/dead_statements.c3t | 4 +- .../statements/defer_if_try_copy.c3t | 4 +- .../statements/for_with_optional.c3t | 6 +- test/test_suite/statements/foreach_custom.c3t | 2 +- .../statements/foreach_custom_macro.c3t | 4 +- test/test_suite/statements/foreach_errors.c3 | 4 +- .../statements/foreach_r_custom.c3t | 2 +- .../statements/foreach_r_custom_macro.c3t | 2 +- .../test_suite/statements/foreach_r_errors.c3 | 4 +- .../statements/foreach_r_with_error.c3 | 2 +- .../statements/foreach_with_error.c3 | 2 +- test/test_suite/statements/if_only_throw.c3t | 15 +- .../statements/if_while_do_error.c3 | 12 +- test/test_suite/statements/switch_errors.c3 | 9 +- .../statements/various_switching.c3t | 31 +- test/test_suite/strings/string_to_array.c3t | 4 +- .../struct/flex_array_comparison.c3 | 2 +- .../struct/flex_array_struct_err.c3 | 6 +- .../struct/flexible_array_resolve.c3 | 4 +- test/test_suite/struct/nested_struct_init.c3t | 12 +- test/test_suite/struct/struct_as_value.c3t | 2 +- test/test_suite/struct/struct_codegen.c3t | 2 +- test/test_suite/struct/struct_codegen_fam.c3t | 2 +- .../struct/struct_const_construct_simple.c3t | 2 +- test/test_suite/switch/bad_ranges.c3 | 4 +- test/test_suite/switch/failable_switch.c3 | 7 +- .../switch/switch_in_defer_macro.c3t | 104 ++-- test/test_suite/union/flexible_array_union.c3 | 2 +- test/test_suite/union/inferred_size_vector.c3 | 2 +- test/test_suite/vector/swizzling.c3 | 2 +- .../test_suite/vector/vector_to_array_fail.c3 | 8 +- .../test_suite/visibility/export_property.c3t | 6 +- test/unit/regression/castable_assignable.c3 | 2 +- test/unit/regression/catch_err.c3 | 10 +- test/unit/regression/faults.c3 | 21 - test/unit/regression/unwrapping.c3 | 2 +- test/unit/regression/vecpointer.c3 | 4 +- test/unit/regression/vector_conversion.c3 | 8 +- test/unit/regression/vector_method_reduce.c3 | 2 +- test/unit/regression/wstring.c3 | 4 +- test/unit/stdlib/compression/qoi.c3 | 2 +- test/unit/stdlib/conv_tests.c3 | 4 +- test/unit/stdlib/core/array.c3 | 4 +- test/unit/stdlib/core/bitorder.c3 | 4 +- test/unit/stdlib/core/builtintests.c3 | 4 +- test/unit/stdlib/core/formatter.c3 | 2 +- test/unit/stdlib/core/string.c3 | 2 +- test/unit/stdlib/core/test_test.c3 | 33 +- test/unit/stdlib/crypto/rc4.c3 | 2 +- test/unit/stdlib/encoding/base32.c3 | 8 +- test/unit/stdlib/io/bytestream.c3 | 4 +- test/unit/stdlib/io/scanner.c3 | 4 +- test/unit/stdlib/net/url.c3 | 2 +- test/unit/stdlib/net/url_encoding.c3 | 18 +- test/unit/stdlib/sort/insertionsort.c3 | 2 +- test/unit/stdlib/sort/quicksort.c3 | 2 +- test/unit/stdlib/string_to_float.c3 | 8 +- test/unit/stdlib/threads/channel.c3 | 28 +- test/unit/stdlib/threads/mutex.c3 | 2 +- test/unit/stdlib/time/format.c3 | 4 +- 392 files changed, 3129 insertions(+), 3658 deletions(-) create mode 100644 test/test_suite/enumerations/enum_recursive.c3 delete mode 100644 test/test_suite/errors/error_introspect.c3t delete mode 100644 test/test_suite/errors/invalid_cast_ct.c3 delete mode 100644 test/unit/regression/faults.c3 diff --git a/lib/std/bits.c3 b/lib/std/bits.c3 index 3b504e397..cd79c60b9 100644 --- a/lib/std/bits.c3 +++ b/lib/std/bits.c3 @@ -10,85 +10,85 @@ macro reverse(i) => $$bitreverse(i); *> macro bswap(i) @builtin => $$bswap(i); -macro uint[].popcount(self) => $$popcount(self); -macro uint[].ctz(self) => $$ctz(self); -macro uint[].clz(self) => $$clz(self); -macro uint[] uint[].fshl(hi, uint[] lo, uint[] shift) => $$fshl(hi, lo, shift); -macro uint[] uint[].fshr(hi, uint[] lo, uint[] shift) => $$fshr(hi, lo, shift); -macro uint[] uint[].rotl(self, uint[] shift) => $$fshl(self, self, shift); -macro uint[] uint[].rotr(self, uint[] shift) => $$fshr(self, self, shift); +macro uint[<*>].popcount(self) => $$popcount(self); +macro uint[<*>].ctz(self) => $$ctz(self); +macro uint[<*>].clz(self) => $$clz(self); +macro uint[<*>] uint[<*>].fshl(hi, uint[<*>] lo, uint[<*>] shift) => $$fshl(hi, lo, shift); +macro uint[<*>] uint[<*>].fshr(hi, uint[<*>] lo, uint[<*>] shift) => $$fshr(hi, lo, shift); +macro uint[<*>] uint[<*>].rotl(self, uint[<*>] shift) => $$fshl(self, self, shift); +macro uint[<*>] uint[<*>].rotr(self, uint[<*>] shift) => $$fshr(self, self, shift); -macro int[].popcount(self) => $$popcount(self); -macro int[].ctz(self) => $$ctz(self); -macro int[].clz(self) => $$clz(self); -macro int[] int[].fshl(hi, int[] lo, int[] shift) => $$fshl(hi, lo, shift); -macro int[] int[].fshr(hi, int[] lo, int[] shift) => $$fshr(hi, lo, shift); -macro int[] int[].rotl(self, int[] shift) => $$fshl(self, self, shift); -macro int[] int[].rotr(self, int[] shift) => $$fshr(self, self, shift); +macro int[<*>].popcount(self) => $$popcount(self); +macro int[<*>].ctz(self) => $$ctz(self); +macro int[<*>].clz(self) => $$clz(self); +macro int[<*>] int[<*>].fshl(hi, int[<*>] lo, int[<*>] shift) => $$fshl(hi, lo, shift); +macro int[<*>] int[<*>].fshr(hi, int[<*>] lo, int[<*>] shift) => $$fshr(hi, lo, shift); +macro int[<*>] int[<*>].rotl(self, int[<*>] shift) => $$fshl(self, self, shift); +macro int[<*>] int[<*>].rotr(self, int[<*>] shift) => $$fshr(self, self, shift); -macro ushort[].popcount(self) => $$popcount(self); -macro ushort[].ctz(self) => $$ctz(self); -macro ushort[].clz(self) => $$clz(self); -macro ushort[] ushort[].fshl(hi, ushort[] lo, ushort[] shift) => $$fshl(hi, lo, shift); -macro ushort[] ushort[].fshr(hi, ushort[] lo, ushort[] shift) => $$fshr(hi, lo, shift); -macro ushort[] ushort[].rotl(self, ushort[] shift) => $$fshl(self, self, shift); -macro ushort[] ushort[].rotr(self, ushort[] shift) => $$fshr(self, self, shift); +macro ushort[<*>].popcount(self) => $$popcount(self); +macro ushort[<*>].ctz(self) => $$ctz(self); +macro ushort[<*>].clz(self) => $$clz(self); +macro ushort[<*>] ushort[<*>].fshl(hi, ushort[<*>] lo, ushort[<*>] shift) => $$fshl(hi, lo, shift); +macro ushort[<*>] ushort[<*>].fshr(hi, ushort[<*>] lo, ushort[<*>] shift) => $$fshr(hi, lo, shift); +macro ushort[<*>] ushort[<*>].rotl(self, ushort[<*>] shift) => $$fshl(self, self, shift); +macro ushort[<*>] ushort[<*>].rotr(self, ushort[<*>] shift) => $$fshr(self, self, shift); -macro short[].popcount(self) => $$popcount(self); -macro short[].ctz(self) => $$ctz(self); -macro short[].clz(self) => $$clz(self); -macro short[] short[].fshl(hi, short[] lo, short[] shift) => $$fshl(hi, lo, shift); -macro short[] short[].fshr(hi, short[] lo, short[] shift) => $$fshr(hi, lo, shift); -macro short[] short[].rotl(self, short[] shift) => $$fshl(self, self, shift); -macro short[] short[].rotr(self, short[] shift) => $$fshr(self, self, shift); +macro short[<*>].popcount(self) => $$popcount(self); +macro short[<*>].ctz(self) => $$ctz(self); +macro short[<*>].clz(self) => $$clz(self); +macro short[<*>] short[<*>].fshl(hi, short[<*>] lo, short[<*>] shift) => $$fshl(hi, lo, shift); +macro short[<*>] short[<*>].fshr(hi, short[<*>] lo, short[<*>] shift) => $$fshr(hi, lo, shift); +macro short[<*>] short[<*>].rotl(self, short[<*>] shift) => $$fshl(self, self, shift); +macro short[<*>] short[<*>].rotr(self, short[<*>] shift) => $$fshr(self, self, shift); -macro char[].popcount(self) => $$popcount(self); -macro char[].ctz(self) => $$ctz(self); -macro char[].clz(self) => $$clz(self); -macro char[] char[].fshl(hi, char[] lo, char[] shift) => $$fshl(hi, lo, shift); -macro char[] char[].fshr(hi, char[] lo, char[] shift) => $$fshr(hi, lo, shift); -macro char[] char[].rotl(self, char[] shift) => $$fshl(self, self, shift); -macro char[] char[].rotr(self, char[] shift) => $$fshr(self, self, shift); +macro char[<*>].popcount(self) => $$popcount(self); +macro char[<*>].ctz(self) => $$ctz(self); +macro char[<*>].clz(self) => $$clz(self); +macro char[<*>] char[<*>].fshl(hi, char[<*>] lo, char[<*>] shift) => $$fshl(hi, lo, shift); +macro char[<*>] char[<*>].fshr(hi, char[<*>] lo, char[<*>] shift) => $$fshr(hi, lo, shift); +macro char[<*>] char[<*>].rotl(self, char[<*>] shift) => $$fshl(self, self, shift); +macro char[<*>] char[<*>].rotr(self, char[<*>] shift) => $$fshr(self, self, shift); -macro ichar[].popcount(self) => $$popcount(self); -macro ichar[].ctz(self) => $$ctz(self); -macro ichar[].clz(self) => $$clz(self); -macro ichar[] ichar[].fshl(hi, ichar[] lo, ichar[] shift) => $$fshl(hi, lo, shift); -macro ichar[] ichar[].fshr(hi, ichar[] lo, ichar[] shift) => $$fshr(hi, lo, shift); -macro ichar[] ichar[].rotl(self, ichar[] shift) => $$fshl(self, self, shift); -macro ichar[] ichar[].rotr(self, ichar[] shift) => $$fshr(self, self, shift); +macro ichar[<*>].popcount(self) => $$popcount(self); +macro ichar[<*>].ctz(self) => $$ctz(self); +macro ichar[<*>].clz(self) => $$clz(self); +macro ichar[<*>] ichar[<*>].fshl(hi, ichar[<*>] lo, ichar[<*>] shift) => $$fshl(hi, lo, shift); +macro ichar[<*>] ichar[<*>].fshr(hi, ichar[<*>] lo, ichar[<*>] shift) => $$fshr(hi, lo, shift); +macro ichar[<*>] ichar[<*>].rotl(self, ichar[<*>] shift) => $$fshl(self, self, shift); +macro ichar[<*>] ichar[<*>].rotr(self, ichar[<*>] shift) => $$fshr(self, self, shift); -macro ulong[].popcount(self) => $$popcount(self); -macro ulong[].ctz(self) => $$ctz(self); -macro ulong[].clz(self) => $$clz(self); -macro ulong[] ulong[].fshl(hi, ulong[] lo, ulong[] shift) => $$fshl(hi, lo, shift); -macro ulong[] ulong[].fshr(hi, ulong[] lo, ulong[] shift) => $$fshr(hi, lo, shift); -macro ulong[] ulong[].rotl(self, ulong[] shift) => $$fshl(self, self, shift); -macro ulong[] ulong[].rotr(self, ulong[] shift) => $$fshr(self, self, shift); +macro ulong[<*>].popcount(self) => $$popcount(self); +macro ulong[<*>].ctz(self) => $$ctz(self); +macro ulong[<*>].clz(self) => $$clz(self); +macro ulong[<*>] ulong[<*>].fshl(hi, ulong[<*>] lo, ulong[<*>] shift) => $$fshl(hi, lo, shift); +macro ulong[<*>] ulong[<*>].fshr(hi, ulong[<*>] lo, ulong[<*>] shift) => $$fshr(hi, lo, shift); +macro ulong[<*>] ulong[<*>].rotl(self, ulong[<*>] shift) => $$fshl(self, self, shift); +macro ulong[<*>] ulong[<*>].rotr(self, ulong[<*>] shift) => $$fshr(self, self, shift); -macro long[].popcount(self) => $$popcount(self); -macro long[].ctz(self) => $$ctz(self); -macro long[].clz(self) => $$clz(self); -macro long[] long[].fshl(hi, long[] lo, long[] shift) => $$fshl(hi, lo, shift); -macro long[] long[].fshr(hi, long[] lo, long[] shift) => $$fshr(hi, lo, shift); -macro long[] long[].rotl(self, long[] shift) => $$fshl(self, self, shift); -macro long[] long[].rotr(self, long[] shift) => $$fshr(self, self, shift); +macro long[<*>].popcount(self) => $$popcount(self); +macro long[<*>].ctz(self) => $$ctz(self); +macro long[<*>].clz(self) => $$clz(self); +macro long[<*>] long[<*>].fshl(hi, long[<*>] lo, long[<*>] shift) => $$fshl(hi, lo, shift); +macro long[<*>] long[<*>].fshr(hi, long[<*>] lo, long[<*>] shift) => $$fshr(hi, lo, shift); +macro long[<*>] long[<*>].rotl(self, long[<*>] shift) => $$fshl(self, self, shift); +macro long[<*>] long[<*>].rotr(self, long[<*>] shift) => $$fshr(self, self, shift); -macro uint128[].popcount(self) => $$popcount(self); -macro uint128[].ctz(self) => $$ctz(self); -macro uint128[].clz(self) => $$clz(self); -macro uint128[] uint128[].fshl(hi, uint128[] lo, uint128[] shift) => $$fshl(hi, lo, shift); -macro uint128[] uint128[].fshr(hi, uint128[] lo, uint128[] shift) => $$fshr(hi, lo, shift); -macro uint128[] uint128[].rotl(self, uint128[] shift) => $$fshl(self, self, shift); -macro uint128[] uint128[].rotr(self, uint128[] shift) => $$fshr(self, self, shift); +macro uint128[<*>].popcount(self) => $$popcount(self); +macro uint128[<*>].ctz(self) => $$ctz(self); +macro uint128[<*>].clz(self) => $$clz(self); +macro uint128[<*>] uint128[<*>].fshl(hi, uint128[<*>] lo, uint128[<*>] shift) => $$fshl(hi, lo, shift); +macro uint128[<*>] uint128[<*>].fshr(hi, uint128[<*>] lo, uint128[<*>] shift) => $$fshr(hi, lo, shift); +macro uint128[<*>] uint128[<*>].rotl(self, uint128[<*>] shift) => $$fshl(self, self, shift); +macro uint128[<*>] uint128[<*>].rotr(self, uint128[<*>] shift) => $$fshr(self, self, shift); -macro int128[].popcount(self) => $$popcount(self); -macro int128[].ctz(self) => $$ctz(self); -macro int128[].clz(self) => $$clz(self); -macro int128[] int128[].fshl(hi, int128[] lo, int128[] shift) => $$fshl(hi, lo, shift); -macro int128[] int128[].fshr(hi, int128[] lo, int128[] shift) => $$fshr(hi, lo, shift); -macro int128[] int128[].rotl(self, int128[] shift) => $$fshl(self, self, shift); -macro int128[] int128[].rotr(self, int128[] shift) => $$fshr(self, self, shift); +macro int128[<*>].popcount(self) => $$popcount(self); +macro int128[<*>].ctz(self) => $$ctz(self); +macro int128[<*>].clz(self) => $$clz(self); +macro int128[<*>] int128[<*>].fshl(hi, int128[<*>] lo, int128[<*>] shift) => $$fshl(hi, lo, shift); +macro int128[<*>] int128[<*>].fshr(hi, int128[<*>] lo, int128[<*>] shift) => $$fshr(hi, lo, shift); +macro int128[<*>] int128[<*>].rotl(self, int128[<*>] shift) => $$fshl(self, self, shift); +macro int128[<*>] int128[<*>].rotr(self, int128[<*>] shift) => $$fshr(self, self, shift); macro uint.popcount(self) => $$popcount(self); macro uint.ctz(self) => $$ctz(self); diff --git a/lib/std/collections/anylist.c3 b/lib/std/collections/anylist.c3 index 82a27d3bf..30fb898fd 100644 --- a/lib/std/collections/anylist.c3 +++ b/lib/std/collections/anylist.c3 @@ -49,7 +49,7 @@ fn AnyList* AnyList.tinit(&self, usz initial_capacity = 16) fn bool AnyList.is_initialized(&self) @inline => self.allocator != null; -fn usz! AnyList.to_format(&self, Formatter* formatter) @dynamic +fn usz? AnyList.to_format(&self, Formatter* formatter) @dynamic { switch (self.size) { @@ -96,22 +96,22 @@ fn void AnyList.free_element(&self, any element) @inline Pop a value who's type is known. If the type is incorrect, this will still pop the element. - @return! CastResult.TYPE_MISMATCH, IteratorResult.NO_MORE_ELEMENT + @return! TYPE_MISMATCH, NO_MORE_ELEMENT *> macro AnyList.pop(&self, $Type) { - if (!self.size) return IteratorResult.NO_MORE_ELEMENT?; + if (!self.size) return NO_MORE_ELEMENT?; defer self.free_element(self.entries[self.size]); return *anycast(self.entries[--self.size], $Type); } <* Pop the last value and allocate the copy using the given allocator. - @return! IteratorResult.NO_MORE_ELEMENT + @return! NO_MORE_ELEMENT *> -fn any! AnyList.copy_pop(&self, Allocator allocator) +fn any? AnyList.copy_pop(&self, Allocator allocator) { - if (!self.size) return IteratorResult.NO_MORE_ELEMENT?; + if (!self.size) return NO_MORE_ELEMENT?; defer self.free_element(self.entries[self.size]); return allocator::clone_any(allocator, self.entries[--self.size]); } @@ -119,17 +119,17 @@ fn any! AnyList.copy_pop(&self, Allocator allocator) <* Pop the last value and allocate the copy using the temp allocator - @return! IteratorResult.NO_MORE_ELEMENT + @return! NO_MORE_ELEMENT *> -fn any! AnyList.tcopy_pop(&self) => self.copy_pop(tmem()); +fn any? AnyList.tcopy_pop(&self) => self.copy_pop(tmem()); <* Pop the last value. It must later be released using list.free_element() - @return! IteratorResult.NO_MORE_ELEMENT + @return! NO_MORE_ELEMENT *> -fn any! AnyList.pop_retained(&self) +fn any? AnyList.pop_retained(&self) { - if (!self.size) return IteratorResult.NO_MORE_ELEMENT?; + if (!self.size) return NO_MORE_ELEMENT?; return self.entries[--self.size]; } @@ -147,7 +147,7 @@ fn void AnyList.clear(&self) *> macro AnyList.pop_first(&self, $Type) { - if (!self.size) return IteratorResult.NO_MORE_ELEMENT?; + if (!self.size) return NO_MORE_ELEMENT?; defer self.remove_at(0); return *anycast(self.entries[0], $Type); } @@ -155,9 +155,9 @@ macro AnyList.pop_first(&self, $Type) <* Same as pop_retained() but pops the first value instead. *> -fn any! AnyList.pop_first_retained(&self) +fn any? AnyList.pop_first_retained(&self) { - if (!self.size) return IteratorResult.NO_MORE_ELEMENT?; + if (!self.size) return NO_MORE_ELEMENT?; defer self.remove_at(0); return self.entries[0]; } @@ -166,9 +166,9 @@ fn any! AnyList.pop_first_retained(&self) <* Same as copy_pop() but pops the first value instead. *> -fn any! AnyList.copy_pop_first(&self, Allocator allocator = allocator::heap()) +fn any? AnyList.copy_pop_first(&self, Allocator allocator = allocator::heap()) { - if (!self.size) return IteratorResult.NO_MORE_ELEMENT?; + if (!self.size) return NO_MORE_ELEMENT?; defer self.free_element(self.entries[self.size]); defer self.remove_at(0); return allocator::clone_any(allocator, self.entries[0]); @@ -177,7 +177,7 @@ fn any! AnyList.copy_pop_first(&self, Allocator allocator = allocator::heap()) <* Same as temp_pop() but pops the first value instead. *> -fn any! AnyList.tcopy_pop_first(&self) => self.copy_pop_first(tmem()); +fn any? AnyList.tcopy_pop_first(&self) => self.copy_pop_first(tmem()); <* @require index < self.size @@ -271,9 +271,9 @@ macro AnyList.first(&self, $Type) return *anycast(self.first_any(), $Type); } -fn any! AnyList.first_any(&self) @inline +fn any? AnyList.first_any(&self) @inline { - return self.size ? self.entries[0] : IteratorResult.NO_MORE_ELEMENT?; + return self.size ? self.entries[0] : NO_MORE_ELEMENT?; } macro AnyList.last(&self, $Type) @@ -281,9 +281,9 @@ macro AnyList.last(&self, $Type) return *anycast(self.last_any(), $Type); } -fn any! AnyList.last_any(&self) @inline +fn any? AnyList.last_any(&self) @inline { - return self.size ? self.entries[self.size - 1] : IteratorResult.NO_MORE_ELEMENT?; + return self.size ? self.entries[self.size - 1] : NO_MORE_ELEMENT?; } fn bool AnyList.is_empty(&self) @inline diff --git a/lib/std/collections/elastic_array.c3 b/lib/std/collections/elastic_array.c3 index 07ae7536f..cac47d30b 100644 --- a/lib/std/collections/elastic_array.c3 +++ b/lib/std/collections/elastic_array.c3 @@ -4,7 +4,7 @@ <* @require MAX_SIZE >= 1 : `The size must be at least 1 element big.` *> -module std::collections::elastic_array{Type, MAX_SIZE}; +module std::collections::elastic_array {Type, MAX_SIZE}; import std::io, std::math, std::collections::list_common; def ElementPredicate = fn bool(Type *type); @@ -19,7 +19,7 @@ struct ElasticArray (Printable) Type[MAX_SIZE] entries; } -fn usz! ElasticArray.to_format(&self, Formatter* formatter) @dynamic +fn usz? ElasticArray.to_format(&self, Formatter* formatter) @dynamic { switch (self.size) { @@ -44,9 +44,9 @@ fn String ElasticArray.to_tstring(&self) return string::tformat("%s", *self); } -fn void! ElasticArray.push_try(&self, Type element) @inline +fn void? ElasticArray.push_try(&self, Type element) @inline { - if (self.size == MAX_SIZE) return AllocationFailure.OUT_OF_MEMORY?; + if (self.size == MAX_SIZE) return mem::OUT_OF_MEMORY?; self.entries[self.size++] = element; } @@ -58,9 +58,9 @@ fn void ElasticArray.push(&self, Type element) @inline self.entries[self.size++] = element; } -fn Type! ElasticArray.pop(&self) +fn Type? ElasticArray.pop(&self) { - if (!self.size) return IteratorResult.NO_MORE_ELEMENT?; + if (!self.size) return NO_MORE_ELEMENT?; return self.entries[--self.size]; } @@ -72,9 +72,9 @@ fn void ElasticArray.clear(&self) <* @require self.size > 0 *> -fn Type! ElasticArray.pop_first(&self) +fn Type? ElasticArray.pop_first(&self) { - if (!self.size) return IteratorResult.NO_MORE_ELEMENT?; + if (!self.size) return NO_MORE_ELEMENT?; defer self.remove_at(0); return self.entries[0]; } @@ -199,7 +199,7 @@ fn void ElasticArray.push_front(&self, Type type) @inline <* @require self.size < MAX_SIZE : `List would exceed max size` *> -fn void! ElasticArray.push_front_try(&self, Type type) @inline +fn void? ElasticArray.push_front_try(&self, Type type) @inline { return self.insert_at_try(0, type); } @@ -207,9 +207,9 @@ fn void! ElasticArray.push_front_try(&self, Type type) @inline <* @require index <= self.size *> -fn void! ElasticArray.insert_at_try(&self, usz index, Type value) +fn void? ElasticArray.insert_at_try(&self, usz index, Type value) { - if (self.size == MAX_SIZE) return AllocationFailure.OUT_OF_MEMORY?; + if (self.size == MAX_SIZE) return mem::OUT_OF_MEMORY?; self.insert_at(index, value); } @@ -235,27 +235,27 @@ fn void ElasticArray.set_at(&self, usz index, Type type) self.entries[index] = type; } -fn void! ElasticArray.remove_last(&self) @maydiscard +fn void? ElasticArray.remove_last(&self) @maydiscard { - if (!self.size) return IteratorResult.NO_MORE_ELEMENT?; + if (!self.size) return NO_MORE_ELEMENT?; self.size--; } -fn void! ElasticArray.remove_first(&self) @maydiscard +fn void? ElasticArray.remove_first(&self) @maydiscard { - if (!self.size) return IteratorResult.NO_MORE_ELEMENT?; + if (!self.size) return NO_MORE_ELEMENT?; self.remove_at(0); } -fn Type! ElasticArray.first(&self) +fn Type? ElasticArray.first(&self) { - if (!self.size) return IteratorResult.NO_MORE_ELEMENT?; + if (!self.size) return NO_MORE_ELEMENT?; return self.entries[0]; } -fn Type! ElasticArray.last(&self) +fn Type? ElasticArray.last(&self) { - if (!self.size) return IteratorResult.NO_MORE_ELEMENT?; + if (!self.size) return NO_MORE_ELEMENT?; return self.entries[self.size - 1]; } @@ -330,22 +330,22 @@ fn void ElasticArray.set(&self, usz index, Type value) @operator([]=) // Functions for equatable types -fn usz! ElasticArray.index_of(&self, Type type) @if(ELEMENT_IS_EQUATABLE) +fn usz? ElasticArray.index_of(&self, Type type) @if(ELEMENT_IS_EQUATABLE) { foreach (i, v : self) { if (equals(v, type)) return i; } - return SearchResult.MISSING?; + return NOT_FOUND?; } -fn usz! ElasticArray.rindex_of(&self, Type type) @if(ELEMENT_IS_EQUATABLE) +fn usz? ElasticArray.rindex_of(&self, Type type) @if(ELEMENT_IS_EQUATABLE) { foreach_r (i, v : self) { if (equals(v, type)) return i; } - return SearchResult.MISSING?; + return NOT_FOUND?; } fn bool ElasticArray.equals(&self, ElasticArray other_list) @if(ELEMENT_IS_EQUATABLE) diff --git a/lib/std/collections/enummap.c3 b/lib/std/collections/enummap.c3 index 98b7974b0..66730cef8 100644 --- a/lib/std/collections/enummap.c3 +++ b/lib/std/collections/enummap.c3 @@ -16,7 +16,7 @@ fn void EnumMap.init(&self, ValueType init_value) } } -fn usz! EnumMap.to_format(&self, Formatter* formatter) @dynamic +fn usz? EnumMap.to_format(&self, Formatter* formatter) @dynamic { usz n = formatter.print("{ ")!; foreach (i, &value : self.values) diff --git a/lib/std/collections/enumset.c3 b/lib/std/collections/enumset.c3 index 572dff60d..8a118afc8 100644 --- a/lib/std/collections/enumset.c3 +++ b/lib/std/collections/enumset.c3 @@ -126,7 +126,7 @@ fn EnumSet EnumSet.xor_of(&self, EnumSet s) $endif } -fn usz! EnumSet.to_format(&set, Formatter* formatter) @dynamic +fn usz? EnumSet.to_format(&set, Formatter* formatter) @dynamic { usz n = formatter.print("[")!; bool found; diff --git a/lib/std/collections/hashmap.c3 b/lib/std/collections/hashmap.c3 index b12987194..356eb8367 100644 --- a/lib/std/collections/hashmap.c3 +++ b/lib/std/collections/hashmap.c3 @@ -171,26 +171,26 @@ fn usz HashMap.len(&map) @inline return map.count; } -fn Value*! HashMap.get_ref(&map, Key key) +fn Value*? HashMap.get_ref(&map, Key key) { - if (!map.count) return SearchResult.MISSING?; + if (!map.count) return NOT_FOUND?; uint hash = rehash(key.hash()); for (Entry *e = map.table[index_for(hash, map.table.len)]; e != null; e = e.next) { if (e.hash == hash && equals(key, e.key)) return &e.value; } - return SearchResult.MISSING?; + return NOT_FOUND?; } -fn Entry*! HashMap.get_entry(&map, Key key) +fn Entry*? HashMap.get_entry(&map, Key key) { - if (!map.count) return SearchResult.MISSING?; + if (!map.count) return NOT_FOUND?; uint hash = rehash(key.hash()); for (Entry *e = map.table[index_for(hash, map.table.len)]; e != null; e = e.next) { if (e.hash == hash && equals(key, e.key)) return e; } - return SearchResult.MISSING?; + return NOT_FOUND?; } <* @@ -216,7 +216,7 @@ macro Value HashMap.@get_or_set(&map, Key key, Value #expr) return val; } -fn Value! HashMap.get(&map, Key key) @operator([]) +fn Value? HashMap.get(&map, Key key) @operator([]) { return *map.get_ref(key) @inline; } @@ -252,9 +252,9 @@ fn bool HashMap.set(&map, Key key, Value value) @operator([]=) return false; } -fn void! HashMap.remove(&map, Key key) @maydiscard +fn void? HashMap.remove(&map, Key key) @maydiscard { - if (!map.remove_entry_for_key(key)) return SearchResult.MISSING?; + if (!map.remove_entry_for_key(key)) return NOT_FOUND?; } fn void HashMap.clear(&map) @@ -413,7 +413,7 @@ fn void HashMap.resize(&map, uint new_capacity) @private map.threshold = (uint)(new_capacity * map.load_factor); } -fn usz! HashMap.to_format(&self, Formatter* f) @dynamic +fn usz? HashMap.to_format(&self, Formatter* f) @dynamic { usz len; len += f.print("{ ")!; diff --git a/lib/std/collections/linkedlist.c3 b/lib/std/collections/linkedlist.c3 index ba6e05f59..9d5fce0f0 100644 --- a/lib/std/collections/linkedlist.c3 +++ b/lib/std/collections/linkedlist.c3 @@ -85,18 +85,18 @@ fn void LinkedList.push(&self, Type value) self.size++; } -fn Type! LinkedList.peek(&self) => self.first() @inline; -fn Type! LinkedList.peek_last(&self) => self.last() @inline; +fn Type? LinkedList.peek(&self) => self.first() @inline; +fn Type? LinkedList.peek_last(&self) => self.last() @inline; -fn Type! LinkedList.first(&self) +fn Type? LinkedList.first(&self) { - if (!self._first) return IteratorResult.NO_MORE_ELEMENT?; + if (!self._first) return NO_MORE_ELEMENT?; return self._first.value; } -fn Type! LinkedList.last(&self) +fn Type? LinkedList.last(&self) { - if (!self._last) return IteratorResult.NO_MORE_ELEMENT?; + if (!self._last) return NO_MORE_ELEMENT?; return self._last.value; } @@ -231,9 +231,9 @@ fn usz LinkedList.remove(&self, Type t) @if(ELEMENT_IS_EQUATABLE) return start - self.size; } -fn Type! LinkedList.pop(&self) +fn Type? LinkedList.pop(&self) { - if (!self._last) return IteratorResult.NO_MORE_ELEMENT?; + if (!self._last) return NO_MORE_ELEMENT?; defer self.unlink_last(); return self._last.value; } @@ -243,22 +243,22 @@ fn bool LinkedList.is_empty(&self) return !self._first; } -fn Type! LinkedList.pop_front(&self) +fn Type? LinkedList.pop_front(&self) { - if (!self._first) return IteratorResult.NO_MORE_ELEMENT?; + if (!self._first) return NO_MORE_ELEMENT?; defer self.unlink_first(); return self._first.value; } -fn void! LinkedList.remove_last(&self) @maydiscard +fn void? LinkedList.remove_last(&self) @maydiscard { - if (!self._first) return IteratorResult.NO_MORE_ELEMENT?; + if (!self._first) return NO_MORE_ELEMENT?; self.unlink_last(); } -fn void! LinkedList.remove_first(&self) @maydiscard +fn void? LinkedList.remove_first(&self) @maydiscard { - if (!self._first) return IteratorResult.NO_MORE_ELEMENT?; + if (!self._first) return NO_MORE_ELEMENT?; self.unlink_first(); } diff --git a/lib/std/collections/list.c3 b/lib/std/collections/list.c3 index 70d512bbb..4dd97a6a3 100644 --- a/lib/std/collections/list.c3 +++ b/lib/std/collections/list.c3 @@ -87,7 +87,7 @@ fn void List.init_wrapping_array(&self, Allocator allocator, Type[] types) fn bool List.is_initialized(&self) @inline => self.allocator != null && self.allocator != (Allocator)&dummy; -fn usz! List.to_format(&self, Formatter* formatter) @dynamic +fn usz? List.to_format(&self, Formatter* formatter) @dynamic { switch (self.size) { @@ -113,9 +113,9 @@ fn void List.push(&self, Type element) @inline self.entries[self.set_size(self.size + 1)] = element; } -fn Type! List.pop(&self) +fn Type? List.pop(&self) { - if (!self.size) return IteratorResult.NO_MORE_ELEMENT?; + if (!self.size) return NO_MORE_ELEMENT?; defer self.set_size(self.size - 1); return self.entries[self.size - 1]; } @@ -125,9 +125,9 @@ fn void List.clear(&self) self.set_size(0); } -fn Type! List.pop_first(&self) +fn Type? List.pop_first(&self) { - if (!self.size) return IteratorResult.NO_MORE_ELEMENT?; + if (!self.size) return NO_MORE_ELEMENT?; defer self.remove_at(0); return self.entries[0]; } @@ -233,27 +233,27 @@ fn void List.set_at(&self, usz index, Type type) self.entries[index] = type; } -fn void! List.remove_last(&self) @maydiscard +fn void? List.remove_last(&self) @maydiscard { - if (!self.size) return IteratorResult.NO_MORE_ELEMENT?; + if (!self.size) return NO_MORE_ELEMENT?; self.set_size(self.size - 1); } -fn void! List.remove_first(&self) @maydiscard +fn void? List.remove_first(&self) @maydiscard { - if (!self.size) return IteratorResult.NO_MORE_ELEMENT?; + if (!self.size) return NO_MORE_ELEMENT?; self.remove_at(0); } -fn Type! List.first(&self) +fn Type? List.first(&self) { - if (!self.size) return IteratorResult.NO_MORE_ELEMENT?; + if (!self.size) return NO_MORE_ELEMENT?; return self.entries[0]; } -fn Type! List.last(&self) +fn Type? List.last(&self) { - if (!self.size) return IteratorResult.NO_MORE_ELEMENT?; + if (!self.size) return NO_MORE_ELEMENT?; return self.entries[self.size - 1]; } @@ -446,22 +446,22 @@ macro void List.post_alloc(&self) @private // Functions for equatable types -fn usz! List.index_of(&self, Type type) @if(ELEMENT_IS_EQUATABLE) +fn usz? List.index_of(&self, Type type) @if(ELEMENT_IS_EQUATABLE) { foreach (i, v : self) { if (equals(v, type)) return i; } - return SearchResult.MISSING?; + return NOT_FOUND?; } -fn usz! List.rindex_of(&self, Type type) @if(ELEMENT_IS_EQUATABLE) +fn usz? List.rindex_of(&self, Type type) @if(ELEMENT_IS_EQUATABLE) { foreach_r (i, v : self) { if (equals(v, type)) return i; } - return SearchResult.MISSING?; + return NOT_FOUND?; } fn bool List.equals(&self, List other_list) @if(ELEMENT_IS_EQUATABLE) diff --git a/lib/std/collections/maybe.c3 b/lib/std/collections/maybe.c3 index dd5dea31f..9442b1fa8 100644 --- a/lib/std/collections/maybe.c3 +++ b/lib/std/collections/maybe.c3 @@ -7,7 +7,7 @@ struct Maybe (Printable) bool has_value; } -fn usz! Maybe.to_format(&self, Formatter* f) @dynamic +fn usz? Maybe.to_format(&self, Formatter* f) @dynamic { if (self.has_value) return f.printf("[%s]", self.value); return f.printf("[EMPTY]"); @@ -30,7 +30,7 @@ fn Maybe value(Type val) const Maybe EMPTY = { }; -macro Type! Maybe.get(self) +macro Type? Maybe.get(self) { - return self.has_value ? self.value : SearchResult.MISSING?; + return self.has_value ? self.value : NOT_FOUND?; } diff --git a/lib/std/collections/object.c3 b/lib/std/collections/object.c3 index 703fcefff..812e1f7cc 100644 --- a/lib/std/collections/object.c3 +++ b/lib/std/collections/object.c3 @@ -25,7 +25,7 @@ struct Object (Printable) } -fn usz! Object.to_format(&self, Formatter* formatter) @dynamic +fn usz? Object.to_format(&self, Formatter* formatter) @dynamic { switch (self.type) { @@ -178,7 +178,7 @@ fn void Object.init_array_if_needed(&self) @private fn void Object.set_object(&self, String key, Object* new_object) @private { self.init_map_if_needed(); - ObjectInternalMapEntry*! entry = self.map.get_entry(key); + ObjectInternalMapEntry*? entry = self.map.get_entry(key); defer { (void)entry.value.free(); @@ -201,7 +201,7 @@ macro Object* Object.object_from_value(&self, value) @private $case $Type.typeid == Object*.typeid: return value; $case $Type.typeid == void*.typeid: - if (value != null) return CastResult.TYPE_MISMATCH?; + if (value != null) return TYPE_MISMATCH?; return &NULL_OBJECT; $case $assignable(value, String): return new_string(value, self.allocator); @@ -242,7 +242,7 @@ macro Object* Object.push(&self, value) <* @require self.is_keyable() *> -fn Object*! Object.get(&self, String key) => self.is_empty() ? SearchResult.MISSING? : self.map.get(key); +fn Object*? Object.get(&self, String key) => self.is_empty() ? NOT_FOUND? : self.map.get(key); fn bool Object.has_key(&self, String key) => self.is_map() && self.map.has_key(key); @@ -308,7 +308,7 @@ macro get_integer_value(Object* value, $Type) return ($Type)value.s.to_uint128(); $endif } - if (!value.is_int()) return NumberConversion.MALFORMED_INTEGER?; + if (!value.is_int()) return string::MALFORMED_INTEGER?; return ($Type)value.i; } @@ -331,77 +331,77 @@ macro Object.get_integer(&self, $Type, String key) @private return get_integer_value(self.get(key), $Type); } -fn ichar! Object.get_ichar(&self, String key) => self.get_integer(ichar, key); -fn short! Object.get_short(&self, String key) => self.get_integer(short, key); -fn int! Object.get_int(&self, String key) => self.get_integer(int, key); -fn long! Object.get_long(&self, String key) => self.get_integer(long, key); -fn int128! Object.get_int128(&self, String key) => self.get_integer(int128, key); +fn ichar? Object.get_ichar(&self, String key) => self.get_integer(ichar, key); +fn short? Object.get_short(&self, String key) => self.get_integer(short, key); +fn int? Object.get_int(&self, String key) => self.get_integer(int, key); +fn long? Object.get_long(&self, String key) => self.get_integer(long, key); +fn int128? Object.get_int128(&self, String key) => self.get_integer(int128, key); -fn ichar! Object.get_ichar_at(&self, usz index) => self.get_integer_at(ichar, index); -fn short! Object.get_short_at(&self, usz index) => self.get_integer_at(short, index); -fn int! Object.get_int_at(&self, usz index) => self.get_integer_at(int, index); -fn long! Object.get_long_at(&self, usz index) => self.get_integer_at(long, index); -fn int128! Object.get_int128_at(&self, usz index) => self.get_integer_at(int128, index); +fn ichar? Object.get_ichar_at(&self, usz index) => self.get_integer_at(ichar, index); +fn short? Object.get_short_at(&self, usz index) => self.get_integer_at(short, index); +fn int? Object.get_int_at(&self, usz index) => self.get_integer_at(int, index); +fn long? Object.get_long_at(&self, usz index) => self.get_integer_at(long, index); +fn int128? Object.get_int128_at(&self, usz index) => self.get_integer_at(int128, index); -fn char! Object.get_char(&self, String key) => self.get_integer(ichar, key); -fn short! Object.get_ushort(&self, String key) => self.get_integer(ushort, key); -fn uint! Object.get_uint(&self, String key) => self.get_integer(uint, key); -fn ulong! Object.get_ulong(&self, String key) => self.get_integer(ulong, key); -fn uint128! Object.get_uint128(&self, String key) => self.get_integer(uint128, key); +fn char? Object.get_char(&self, String key) => self.get_integer(ichar, key); +fn short? Object.get_ushort(&self, String key) => self.get_integer(ushort, key); +fn uint? Object.get_uint(&self, String key) => self.get_integer(uint, key); +fn ulong? Object.get_ulong(&self, String key) => self.get_integer(ulong, key); +fn uint128? Object.get_uint128(&self, String key) => self.get_integer(uint128, key); -fn char! Object.get_char_at(&self, usz index) => self.get_integer_at(char, index); -fn ushort! Object.get_ushort_at(&self, usz index) => self.get_integer_at(ushort, index); -fn uint! Object.get_uint_at(&self, usz index) => self.get_integer_at(uint, index); -fn ulong! Object.get_ulong_at(&self, usz index) => self.get_integer_at(ulong, index); -fn uint128! Object.get_uint128_at(&self, usz index) => self.get_integer_at(uint128, index); +fn char? Object.get_char_at(&self, usz index) => self.get_integer_at(char, index); +fn ushort? Object.get_ushort_at(&self, usz index) => self.get_integer_at(ushort, index); +fn uint? Object.get_uint_at(&self, usz index) => self.get_integer_at(uint, index); +fn ulong? Object.get_ulong_at(&self, usz index) => self.get_integer_at(ulong, index); +fn uint128? Object.get_uint128_at(&self, usz index) => self.get_integer_at(uint128, index); <* @require self.is_keyable() *> -fn String! Object.get_string(&self, String key) +fn String? Object.get_string(&self, String key) { Object* value = self.get(key)!; - if (!value.is_string()) return CastResult.TYPE_MISMATCH?; + if (!value.is_string()) return TYPE_MISMATCH?; return value.s; } <* @require self.is_indexable() *> -fn String! Object.get_string_at(&self, usz index) +fn String? Object.get_string_at(&self, usz index) { Object* value = self.get_at(index); - if (!value.is_string()) return CastResult.TYPE_MISMATCH?; + if (!value.is_string()) return TYPE_MISMATCH?; return value.s; } <* @require self.is_keyable() *> -macro String! Object.get_enum(&self, $EnumType, String key) +macro String? Object.get_enum(&self, $EnumType, String key) { Object value = self.get(key)!; - if ($EnumType.typeid != value.type) return CastResult.TYPE_MISMATCH?; + if ($EnumType.typeid != value.type) return TYPE_MISMATCH?; return ($EnumType)value.i; } <* @require self.is_indexable() *> -macro String! Object.get_enum_at(&self, $EnumType, usz index) +macro String? Object.get_enum_at(&self, $EnumType, usz index) { Object value = self.get_at(index); - if ($EnumType.typeid != value.type) return CastResult.TYPE_MISMATCH?; + if ($EnumType.typeid != value.type) return TYPE_MISMATCH?; return ($EnumType)value.i; } <* @require self.is_keyable() *> -fn bool! Object.get_bool(&self, String key) +fn bool? Object.get_bool(&self, String key) { Object* value = self.get(key)!; - if (!value.is_bool()) return CastResult.TYPE_MISMATCH?; + if (!value.is_bool()) return TYPE_MISMATCH?; return value.b; } @@ -409,17 +409,17 @@ fn bool! Object.get_bool(&self, String key) <* @require self.is_indexable() *> -fn bool! Object.get_bool_at(&self, usz index) +fn bool? Object.get_bool_at(&self, usz index) { Object* value = self.get_at(index); - if (!value.is_bool()) return CastResult.TYPE_MISMATCH?; + if (!value.is_bool()) return TYPE_MISMATCH?; return value.b; } <* @require self.is_keyable() *> -fn double! Object.get_float(&self, String key) +fn double? Object.get_float(&self, String key) { Object* value = self.get(key)!; switch (value.type.kindof) @@ -431,14 +431,14 @@ fn double! Object.get_float(&self, String key) case FLOAT: return value.f; default: - return CastResult.TYPE_MISMATCH?; + return TYPE_MISMATCH?; } } <* @require self.is_indexable() *> -fn double! Object.get_float_at(&self, usz index) +fn double? Object.get_float_at(&self, usz index) { Object* value = self.get_at(index); switch (value.type.kindof) @@ -450,7 +450,7 @@ fn double! Object.get_float_at(&self, usz index) case FLOAT: return value.f; default: - return CastResult.TYPE_MISMATCH?; + return TYPE_MISMATCH?; } } diff --git a/lib/std/collections/priorityqueue.c3 b/lib/std/collections/priorityqueue.c3 index 4a244292f..bce7fd1da 100644 --- a/lib/std/collections/priorityqueue.c3 +++ b/lib/std/collections/priorityqueue.c3 @@ -82,11 +82,11 @@ fn void PrivatePriorityQueue.remove_at(&self, usz index) <* @require self != null *> -fn Type! PrivatePriorityQueue.pop(&self) +fn Type? PrivatePriorityQueue.pop(&self) { usz i = 0; usz len = self.heap.len(); - if (!len) return IteratorResult.NO_MORE_ELEMENT?; + if (!len) return NO_MORE_ELEMENT?; usz new_count = len - 1; self.heap.swap(0, new_count); while OUTER: ((2 * i + 1) < new_count) @@ -120,7 +120,7 @@ fn Type! PrivatePriorityQueue.pop(&self) return self.heap.pop(); } -fn Type! PrivatePriorityQueue.first(&self) +fn Type? PrivatePriorityQueue.first(&self) { return self.heap.first(); } @@ -148,7 +148,7 @@ fn Type PrivatePriorityQueue.get(&self, usz index) @operator([]) return self.heap[index]; } -fn usz! PrivatePriorityQueue.to_format(&self, Formatter* formatter) @dynamic +fn usz? PrivatePriorityQueue.to_format(&self, Formatter* formatter) @dynamic { return self.heap.to_format(formatter); } diff --git a/lib/std/collections/range.c3 b/lib/std/collections/range.c3 index e689856ef..a5f48f115 100644 --- a/lib/std/collections/range.c3 +++ b/lib/std/collections/range.c3 @@ -29,7 +29,7 @@ fn Type Range.get(&self, usz index) @operator([]) return (Type)(self.start + (usz)index); } -fn usz! Range.to_format(&self, Formatter* formatter) @dynamic +fn usz? Range.to_format(&self, Formatter* formatter) @dynamic { return formatter.printf("[%s..%s]", self.start, self.end)!; } @@ -51,7 +51,7 @@ fn bool ExclusiveRange.contains(&self, Type value) @inline return value >= self.start && value < self.end; } -fn usz! ExclusiveRange.to_format(&self, Formatter* formatter) @dynamic +fn usz? ExclusiveRange.to_format(&self, Formatter* formatter) @dynamic { return formatter.printf("[%s..<%s]", self.start, self.end)!; } diff --git a/lib/std/collections/ringbuffer.c3 b/lib/std/collections/ringbuffer.c3 index d3213d770..666b4b135 100644 --- a/lib/std/collections/ringbuffer.c3 +++ b/lib/std/collections/ringbuffer.c3 @@ -43,12 +43,12 @@ fn Element RingBuffer.get(&self, usz index) @operator([]) return self.buf[index - avail]; } -fn Element! RingBuffer.pop(&self) +fn Element? RingBuffer.pop(&self) { switch { case self.written == 0: - return SearchResult.MISSING?; + return NO_MORE_ELEMENT?; case self.written < self.buf.len: self.written--; return self.buf[self.written]; @@ -58,7 +58,7 @@ fn Element! RingBuffer.pop(&self) } } -fn usz! RingBuffer.to_format(&self, Formatter* format) @dynamic +fn usz? RingBuffer.to_format(&self, Formatter* format) @dynamic { // Improve this? return format.printf("%s", self.buf); diff --git a/lib/std/compression/qoi.c3 b/lib/std/compression/qoi.c3 index 80f09d4de..00b55e658 100644 --- a/lib/std/compression/qoi.c3 +++ b/lib/std/compression/qoi.c3 @@ -42,14 +42,7 @@ struct QOIDesc QOI Errors. These are all the possible bad outcomes. *> -fault QOIError -{ - INVALID_PARAMETERS, - FILE_OPEN_FAILED, - FILE_WRITE_FAILED, - INVALID_DATA, - TOO_MANY_PIXELS -} +fault INVALID_PARAMETERS, FILE_OPEN_FAILED, FILE_WRITE_FAILED, INVALID_DATA, TOO_MANY_PIXELS; // Let the user decide if they want to use std::io @@ -71,7 +64,7 @@ import std::io; @param [in] input : `The raw RGB or RGBA pixels to encode` @param [&in] desc : `The descriptor of the image` *> -fn usz! write(String filename, char[] input, QOIDesc* desc) => @pool() +fn usz? write(String filename, char[] input, QOIDesc* desc) => @pool() { // encode data char[] output = encode(tmem(), input, desc)!; @@ -101,11 +94,12 @@ fn usz! write(String filename, char[] input, QOIDesc* desc) => @pool() @param [in] filename : `The file's name to read the image from` @param [&out] desc : `The descriptor to fill with the image's info` @param channels : `The channels to be used` + @return! FILE_OPEN_FAILED, INVALID_DATA, TOO_MANY_PIXELS *> -fn char[]! read(Allocator allocator, String filename, QOIDesc* desc, QOIChannels channels = AUTO) => @pool(allocator) +fn char[]? read(Allocator allocator, String filename, QOIDesc* desc, QOIChannels channels = AUTO) => @pool(allocator) { // read file - char[] data = file::load_temp(filename) ?? QOIError.FILE_OPEN_FAILED?!; + char[] data = file::load_temp(filename) ?? FILE_OPEN_FAILED?!; // pass data to decode function return decode(allocator, data, desc, channels); } @@ -128,18 +122,19 @@ import std::bits; @param [in] input : `The raw RGB or RGBA pixels to encode` @param [&in] desc : `The descriptor of the image` + @return! INVALID_PARAMETERS, TOO_MANY_PIXELS, INVALID_DATA *> -fn char[]! encode(Allocator allocator, char[] input, QOIDesc* desc) @nodiscard +fn char[]? encode(Allocator allocator, char[] input, QOIDesc* desc) @nodiscard { // check info in desc - if (desc.width == 0 || desc.height == 0) return QOIError.INVALID_PARAMETERS?; - if (desc.channels == AUTO) return QOIError.INVALID_PARAMETERS?; + if (desc.width == 0 || desc.height == 0) return INVALID_PARAMETERS?; + if (desc.channels == AUTO) return INVALID_PARAMETERS?; uint pixels = desc.width * desc.height; - if (pixels > PIXELS_MAX) return QOIError.TOO_MANY_PIXELS?; + if (pixels > PIXELS_MAX) return TOO_MANY_PIXELS?; // check input data size uint image_size = pixels * desc.channels.id; - if (image_size != input.len) return QOIError.INVALID_DATA?; + if (image_size != input.len) return INVALID_DATA?; // allocate memory for encoded data (output) // header + chunk tag and RGB(A) data for each pixel + end of stream @@ -282,31 +277,32 @@ fn char[]! encode(Allocator allocator, char[] input, QOIDesc* desc) @nodiscard @param [in] data : `The QOI image data to decode` @param [&out] desc : `The descriptor to fill with the image's info` @param channels : `The channels to be used` + @return! INVALID_DATA, TOO_MANY_PIXELS *> -fn char[]! decode(Allocator allocator, char[] data, QOIDesc* desc, QOIChannels channels = AUTO) @nodiscard +fn char[]? decode(Allocator allocator, char[] data, QOIDesc* desc, QOIChannels channels = AUTO) @nodiscard { // check input data - if (data.len < Header.sizeof + END_OF_STREAM.len) return QOIError.INVALID_DATA?; + if (data.len < Header.sizeof + END_OF_STREAM.len) return INVALID_DATA?; // get header Header* header = (Header*)data.ptr; // check magic bytes (FourCC) - if (bswap(header.be_magic) != 'qoif') return QOIError.INVALID_DATA?; + if (bswap(header.be_magic) != 'qoif') return INVALID_DATA?; // copy header data to desc desc.width = bswap(header.be_width); desc.height = bswap(header.be_height); desc.channels = @enumcast(QOIChannels, header.channels)!; // Rethrow if invalid desc.colorspace = @enumcast(QOIColorspace, header.colorspace)!; // Rethrow if invalid - if (desc.channels == AUTO) return QOIError.INVALID_DATA?; // Channels must be specified in the header + if (desc.channels == AUTO) return INVALID_DATA?; // Channels must be specified in the header // check width and height - if (desc.width == 0 || desc.height == 0) return QOIError.INVALID_DATA?; + if (desc.width == 0 || desc.height == 0) return INVALID_DATA?; // check pixel count ulong pixels = (ulong)desc.width * (ulong)desc.height; - if (pixels > PIXELS_MAX) return QOIError.TOO_MANY_PIXELS?; + if (pixels > PIXELS_MAX) return TOO_MANY_PIXELS?; uint pos = Header.sizeof; // Current position in data uint loc; // Current position in image (top-left corner) @@ -405,16 +401,20 @@ struct Header @packed char colorspace; // 0 = sRGB with linear alpha, 1 = all channels linear } -const char[?] END_OF_STREAM = {0, 0, 0, 0, 0, 0, 0, 1}; +const char[*] END_OF_STREAM = {0, 0, 0, 0, 0, 0, 0, 1}; // inefficient, but it's only run once at a time + +<* + @return! INVALID_DATA +*> macro @enumcast($Type, raw) { foreach (value : $Type.values) { if (value.id == raw) return value; } - return QOIError.INVALID_DATA?; + return INVALID_DATA?; } distinct Pixel = inline char[<4>]; diff --git a/lib/std/core/allocators/arena_allocator.c3 b/lib/std/core/allocators/arena_allocator.c3 index 59d440daf..32a748984 100644 --- a/lib/std/core/allocators/arena_allocator.c3 +++ b/lib/std/core/allocators/arena_allocator.c3 @@ -28,7 +28,7 @@ fn void ArenaAllocator.clear(&self) struct ArenaAllocatorHeader @local { usz size; - char[?] data; + char[*] data; } macro ArenaAllocator* wrap(char[] bytes) @@ -57,17 +57,18 @@ fn void ArenaAllocator.reset(&self, usz mark) @dynamic => self.used = mark; @require !alignment || math::is_power_of_2(alignment) @require alignment <= mem::MAX_MEMORY_ALIGNMENT : `alignment too big` @require size > 0 + @return! mem::INVALID_ALLOC_SIZE, mem::OUT_OF_MEMORY *> -fn void*! ArenaAllocator.acquire(&self, usz size, AllocInitType init_type, usz alignment) @dynamic +fn void*? ArenaAllocator.acquire(&self, usz size, AllocInitType init_type, usz alignment) @dynamic { alignment = alignment_for_allocation(alignment); usz total_len = self.data.len; - if (size > total_len) return AllocationFailure.CHUNK_TOO_LARGE?; + if (size > total_len) return mem::INVALID_ALLOC_SIZE?; void* start_mem = self.data.ptr; void* unaligned_pointer_to_offset = start_mem + self.used + ArenaAllocatorHeader.sizeof; void* mem = mem::aligned_pointer(unaligned_pointer_to_offset, alignment); usz end = (usz)(mem - self.data.ptr) + size; - if (end > total_len) return AllocationFailure.OUT_OF_MEMORY?; + if (end > total_len) return mem::OUT_OF_MEMORY?; self.used = end; ArenaAllocatorHeader* header = mem - ArenaAllocatorHeader.sizeof; header.size = size; @@ -80,13 +81,14 @@ fn void*! ArenaAllocator.acquire(&self, usz size, AllocInitType init_type, usz a @require alignment <= mem::MAX_MEMORY_ALIGNMENT : `alignment too big` @require old_pointer != null @require size > 0 + @return! mem::INVALID_ALLOC_SIZE, mem::OUT_OF_MEMORY *> -fn void*! ArenaAllocator.resize(&self, void *old_pointer, usz size, usz alignment) @dynamic +fn void*? ArenaAllocator.resize(&self, void *old_pointer, usz size, usz alignment) @dynamic { alignment = alignment_for_allocation(alignment); assert(old_pointer >= self.data.ptr, "Pointer originates from a different allocator."); usz total_len = self.data.len; - if (size > total_len) return AllocationFailure.CHUNK_TOO_LARGE?; + if (size > total_len) return mem::INVALID_ALLOC_SIZE?; ArenaAllocatorHeader* header = old_pointer - ArenaAllocatorHeader.sizeof; usz old_size = header.size; // Do last allocation and alignment match? @@ -99,7 +101,7 @@ fn void*! ArenaAllocator.resize(&self, void *old_pointer, usz size, usz alignmen else { usz new_used = self.used + size - old_size; - if (new_used > total_len) return AllocationFailure.OUT_OF_MEMORY?; + if (new_used > total_len) return mem::OUT_OF_MEMORY?; self.used = new_used; } header.size = size; diff --git a/lib/std/core/allocators/dynamic_arena.c3 b/lib/std/core/allocators/dynamic_arena.c3 index c8215aa17..86963ab9b 100644 --- a/lib/std/core/allocators/dynamic_arena.c3 +++ b/lib/std/core/allocators/dynamic_arena.c3 @@ -78,8 +78,9 @@ fn void DynamicArenaAllocator.release(&self, void* ptr, bool) @dynamic @require size > 0 : `Resize doesn't support zeroing` @require old_pointer != null : `Resize doesn't handle null pointers` @require self.page != null : `tried to realloc pointer on invalid allocator` + @return! mem::INVALID_ALLOC_SIZE, mem::OUT_OF_MEMORY *> -fn void*! DynamicArenaAllocator.resize(&self, void* old_pointer, usz size, usz alignment) @dynamic +fn void*? DynamicArenaAllocator.resize(&self, void* old_pointer, usz size, usz alignment) @dynamic { DynamicArenaPage* current_page = self.page; alignment = alignment_for_allocation(alignment); @@ -129,15 +130,16 @@ fn void DynamicArenaAllocator.reset(&self, usz mark = 0) @dynamic <* @require math::is_power_of_2(alignment) @require size > 0 + @return! mem::INVALID_ALLOC_SIZE, mem::OUT_OF_MEMORY *> -fn void*! DynamicArenaAllocator._alloc_new(&self, usz size, usz alignment) @local +fn void*? DynamicArenaAllocator._alloc_new(&self, usz size, usz alignment) @local { // First, make sure that we can align it, extending the page size if needed. usz page_size = max(self.page_size, mem::aligned_offset(size + DynamicArenaChunk.sizeof + alignment, alignment)); assert(page_size > size + DynamicArenaChunk.sizeof); // Grab the page without alignment (we do it ourselves) void* mem = allocator::malloc_try(self.backing_allocator, page_size)!; - DynamicArenaPage*! page = allocator::new_try(self.backing_allocator, DynamicArenaPage); + DynamicArenaPage*? page = allocator::new_try(self.backing_allocator, DynamicArenaPage); if (catch err = page) { allocator::free(self.backing_allocator, mem); @@ -159,8 +161,9 @@ fn void*! DynamicArenaAllocator._alloc_new(&self, usz size, usz alignment) @loca <* @require size > 0 : `acquire expects size > 0` @require !alignment || math::is_power_of_2(alignment) + @return! mem::INVALID_ALLOC_SIZE, mem::OUT_OF_MEMORY *> -fn void*! DynamicArenaAllocator.acquire(&self, usz size, AllocInitType init_type, usz alignment) @dynamic +fn void*? DynamicArenaAllocator.acquire(&self, usz size, AllocInitType init_type, usz alignment) @dynamic { alignment = alignment_for_allocation(alignment); DynamicArenaPage* page = self.page; diff --git a/lib/std/core/allocators/heap_allocator.c3 b/lib/std/core/allocators/heap_allocator.c3 index dbd5ca9cc..a085f73eb 100644 --- a/lib/std/core/allocators/heap_allocator.c3 +++ b/lib/std/core/allocators/heap_allocator.c3 @@ -21,7 +21,7 @@ fn void SimpleHeapAllocator.init(&self, MemoryAllocFn allocator) self.free_list = null; } -fn void*! SimpleHeapAllocator.acquire(&self, usz size, AllocInitType init_type, usz alignment) @dynamic +fn void*? SimpleHeapAllocator.acquire(&self, usz size, AllocInitType init_type, usz alignment) @dynamic { if (init_type == ZERO) { @@ -30,7 +30,7 @@ fn void*! SimpleHeapAllocator.acquire(&self, usz size, AllocInitType init_type, return alignment > 0 ? @aligned_alloc(self._alloc, size, alignment) : self._alloc(size); } -fn void*! SimpleHeapAllocator.resize(&self, void* old_pointer, usz size, usz alignment) @dynamic +fn void*? SimpleHeapAllocator.resize(&self, void* old_pointer, usz size, usz alignment) @dynamic { return alignment > 0 ? @aligned_realloc(self._calloc, self._free, old_pointer, size, alignment) @@ -52,7 +52,7 @@ fn void SimpleHeapAllocator.release(&self, void* old_pointer, bool aligned) @dyn <* @require old_pointer && bytes > 0 *> -fn void*! SimpleHeapAllocator._realloc(&self, void* old_pointer, usz bytes) @local +fn void*? SimpleHeapAllocator._realloc(&self, void* old_pointer, usz bytes) @local { // Find the block header. Header* block = (Header*)old_pointer - 1; @@ -64,14 +64,14 @@ fn void*! SimpleHeapAllocator._realloc(&self, void* old_pointer, usz bytes) @loc return new; } -fn void*! SimpleHeapAllocator._calloc(&self, usz bytes) @local +fn void*? SimpleHeapAllocator._calloc(&self, usz bytes) @local { void* data = self._alloc(bytes)!; mem::clear(data, bytes, mem::DEFAULT_MEM_ALIGNMENT); return data; } -fn void*! SimpleHeapAllocator._alloc(&self, usz bytes) @local +fn void*? SimpleHeapAllocator._alloc(&self, usz bytes) @local { usz aligned_bytes = mem::aligned_offset(bytes, mem::DEFAULT_MEM_ALIGNMENT); if (!self.free_list) @@ -120,7 +120,7 @@ fn void*! SimpleHeapAllocator._alloc(&self, usz bytes) @local return self._alloc(aligned_bytes); } -fn void! SimpleHeapAllocator.add_block(&self, usz aligned_bytes) @local +fn void? SimpleHeapAllocator.add_block(&self, usz aligned_bytes) @local { assert(mem::aligned_offset(aligned_bytes, mem::DEFAULT_MEM_ALIGNMENT) == aligned_bytes); char[] result = self.alloc_fn(aligned_bytes + Header.sizeof)!; diff --git a/lib/std/core/allocators/libc_allocator.c3 b/lib/std/core/allocators/libc_allocator.c3 index 87e2de68e..db33ff4f4 100644 --- a/lib/std/core/allocators/libc_allocator.c3 +++ b/lib/std/core/allocators/libc_allocator.c3 @@ -10,36 +10,36 @@ const LibcAllocator LIBC_ALLOCATOR = {}; distinct LibcAllocator (Allocator, Printable) = uptr; fn String LibcAllocator.to_string(&self, Allocator allocator) @dynamic => "Libc allocator".copy(allocator); -fn usz! LibcAllocator.to_format(&self, Formatter *format) @dynamic => format.print("Libc allocator"); +fn usz? LibcAllocator.to_format(&self, Formatter *format) @dynamic => format.print("Libc allocator"); module std::core::mem::allocator @if(env::POSIX); import std::os; import libc; -fn void*! LibcAllocator.acquire(&self, usz bytes, AllocInitType init_type, usz alignment) @dynamic +fn void*? LibcAllocator.acquire(&self, usz bytes, AllocInitType init_type, usz alignment) @dynamic { if (init_type == ZERO) { void* data @noinit; if (alignment > mem::DEFAULT_MEM_ALIGNMENT) { - if (posix::posix_memalign(&data, alignment, bytes)) return AllocationFailure.OUT_OF_MEMORY?; + if (posix::posix_memalign(&data, alignment, bytes)) return mem::OUT_OF_MEMORY?; mem::clear(data, bytes, mem::DEFAULT_MEM_ALIGNMENT); return data; } - return libc::calloc(1, bytes) ?: AllocationFailure.OUT_OF_MEMORY?; + return libc::calloc(1, bytes) ?: mem::OUT_OF_MEMORY?; } else { void* data @noinit; if (alignment > mem::DEFAULT_MEM_ALIGNMENT) { - if (posix::posix_memalign(&data, alignment, bytes)) return AllocationFailure.OUT_OF_MEMORY?; + if (posix::posix_memalign(&data, alignment, bytes)) return mem::OUT_OF_MEMORY?; } else { - if (!(data = libc::malloc(bytes))) return AllocationFailure.OUT_OF_MEMORY?; + if (!(data = libc::malloc(bytes))) return mem::OUT_OF_MEMORY?; } $if env::TESTING: for (usz i = 0; i < bytes; i++) ((char*)data)[i] = 0xAA; @@ -48,11 +48,11 @@ fn void*! LibcAllocator.acquire(&self, usz bytes, AllocInitType init_type, usz a } } -fn void*! LibcAllocator.resize(&self, void* old_ptr, usz new_bytes, usz alignment) @dynamic +fn void*? LibcAllocator.resize(&self, void* old_ptr, usz new_bytes, usz alignment) @dynamic { - if (alignment <= mem::DEFAULT_MEM_ALIGNMENT) return libc::realloc(old_ptr, new_bytes) ?: AllocationFailure.OUT_OF_MEMORY?; + if (alignment <= mem::DEFAULT_MEM_ALIGNMENT) return libc::realloc(old_ptr, new_bytes) ?: mem::OUT_OF_MEMORY?; void* new_ptr; - if (posix::posix_memalign(&new_ptr, alignment, new_bytes)) return AllocationFailure.OUT_OF_MEMORY?; + if (posix::posix_memalign(&new_ptr, alignment, new_bytes)) return mem::OUT_OF_MEMORY?; $switch: $case env::DARWIN: @@ -78,31 +78,31 @@ module std::core::mem::allocator @if(env::WIN32); import std::os::win32; import libc; -fn void*! LibcAllocator.acquire(&self, usz bytes, AllocInitType init_type, usz alignment) @dynamic +fn void*? LibcAllocator.acquire(&self, usz bytes, AllocInitType init_type, usz alignment) @dynamic { if (init_type == ZERO) { if (alignment > 0) { - return win32::_aligned_recalloc(null, 1, bytes, alignment) ?: AllocationFailure.OUT_OF_MEMORY?; + return win32::_aligned_recalloc(null, 1, bytes, alignment) ?: mem::OUT_OF_MEMORY?; } - return libc::calloc(1, bytes) ?: AllocationFailure.OUT_OF_MEMORY?; + return libc::calloc(1, bytes) ?: mem::OUT_OF_MEMORY?; } void* data = alignment > 0 ? win32::_aligned_malloc(bytes, alignment) : libc::malloc(bytes); - if (!data) return AllocationFailure.OUT_OF_MEMORY?; + if (!data) return mem::OUT_OF_MEMORY?; $if env::TESTING: for (usz i = 0; i < bytes; i++) ((char*)data)[i] = 0xAA; $endif return data; } -fn void*! LibcAllocator.resize(&self, void* old_ptr, usz new_bytes, usz alignment) @dynamic +fn void*? LibcAllocator.resize(&self, void* old_ptr, usz new_bytes, usz alignment) @dynamic { if (alignment) { - return win32::_aligned_realloc(old_ptr, new_bytes, alignment) ?: AllocationFailure.OUT_OF_MEMORY?; + return win32::_aligned_realloc(old_ptr, new_bytes, alignment) ?: mem::OUT_OF_MEMORY?; } - return libc::realloc(old_ptr, new_bytes) ?: AllocationFailure.OUT_OF_MEMORY?; + return libc::realloc(old_ptr, new_bytes) ?: mem::OUT_OF_MEMORY?; } fn void LibcAllocator.release(&self, void* old_ptr, bool aligned) @dynamic @@ -118,17 +118,17 @@ fn void LibcAllocator.release(&self, void* old_ptr, bool aligned) @dynamic module std::core::mem::allocator @if(!env::WIN32 && !env::POSIX && env::LIBC); import libc; -fn void*! LibcAllocator.acquire(&self, usz bytes, AllocInitType init_type, usz alignment) @dynamic +fn void*? LibcAllocator.acquire(&self, usz bytes, AllocInitType init_type, usz alignment) @dynamic { if (init_type == ZERO) { void* data = alignment ? @aligned_alloc(fn void*(usz bytes) => libc::calloc(bytes, 1), bytes, alignment)!! : libc::calloc(bytes, 1); - return data ?: AllocationFailure.OUT_OF_MEMORY?; + return data ?: mem::OUT_OF_MEMORYY?; } else { void* data = alignment ? @aligned_alloc(libc::malloc, bytes, alignment)!! : libc::malloc(bytes); - if (!data) return AllocationFailure.OUT_OF_MEMORY?; + if (!data) return mem::OUT_OF_MEMORY?; $if env::TESTING: for (usz i = 0; i < bytes; i++) ((char*)data)[i] = 0xAA; $endif @@ -137,14 +137,14 @@ fn void*! LibcAllocator.acquire(&self, usz bytes, AllocInitType init_type, usz a } -fn void*! LibcAllocator.resize(&self, void* old_ptr, usz new_bytes, usz alignment) @dynamic +fn void*? LibcAllocator.resize(&self, void* old_ptr, usz new_bytes, usz alignment) @dynamic { if (alignment) { void* data = @aligned_realloc(fn void*(usz bytes) => libc::malloc(bytes), libc::free, old_ptr, new_bytes, alignment)!!; - return data ?: AllocationFailure.OUT_OF_MEMORY?; + return data ?: mem::OUT_OF_MEMORY?; } - return libc::realloc(old_ptr, new_bytes) ?: AllocationFailure.OUT_OF_MEMORY?; + return libc::realloc(old_ptr, new_bytes) ?: mem::OUT_OF_MEMORY?; } diff --git a/lib/std/core/allocators/on_stack_allocator.c3 b/lib/std/core/allocators/on_stack_allocator.c3 index 490e790d0..45a1ed834 100644 --- a/lib/std/core/allocators/on_stack_allocator.c3 +++ b/lib/std/core/allocators/on_stack_allocator.c3 @@ -52,7 +52,7 @@ fn void OnStackAllocator.free(&self) struct OnStackAllocatorHeader { usz size; - char[?] data; + char[*] data; } <* @@ -104,7 +104,7 @@ fn OnStackAllocatorExtraChunk* on_stack_allocator_find_chunk(OnStackAllocator* a @require old_pointer != null @require alignment <= mem::MAX_MEMORY_ALIGNMENT : `alignment too big` *> -fn void*! OnStackAllocator.resize(&self, void* old_pointer, usz size, usz alignment) @dynamic +fn void*? OnStackAllocator.resize(&self, void* old_pointer, usz size, usz alignment) @dynamic { if (!allocation_in_stack_mem(self, old_pointer)) { @@ -124,7 +124,7 @@ fn void*! OnStackAllocator.resize(&self, void* old_pointer, usz size, usz alignm @require alignment <= mem::MAX_MEMORY_ALIGNMENT : `alignment too big` @require size > 0 *> -fn void*! OnStackAllocator.acquire(&self, usz size, AllocInitType init_type, usz alignment) @dynamic +fn void*? OnStackAllocator.acquire(&self, usz size, AllocInitType init_type, usz alignment) @dynamic { bool aligned = alignment > 0; alignment = alignment_for_allocation(alignment); diff --git a/lib/std/core/allocators/temp_allocator.c3 b/lib/std/core/allocators/temp_allocator.c3 index 502037ebd..48ff2d48c 100644 --- a/lib/std/core/allocators/temp_allocator.c3 +++ b/lib/std/core/allocators/temp_allocator.c3 @@ -4,7 +4,7 @@ import std::io, std::math; struct TempAllocatorChunk @local { usz size; - char[?] data; + char[*] data; } struct TempAllocator (Allocator) @@ -13,7 +13,7 @@ struct TempAllocator (Allocator) TempAllocatorPage* last_page; usz used; usz capacity; - char[?] data; + char[*] data; } const usz PAGE_IS_ALIGNED @private = (usz)isz.max + 1u; @@ -26,7 +26,7 @@ struct TempAllocatorPage usz mark; usz size; usz ident; - char[?] data; + char[*] data; } macro usz TempAllocatorPage.pagesize(&self) => self.size & ~PAGE_IS_ALIGNED; @@ -35,7 +35,7 @@ macro bool TempAllocatorPage.is_aligned(&self) => self.size & PAGE_IS_ALIGNED == <* @require size >= 16 *> -fn TempAllocator*! new_temp_allocator(usz size, Allocator allocator) +fn TempAllocator*? new_temp_allocator(usz size, Allocator allocator) { TempAllocator* temp = allocator::alloc_with_padding(allocator, TempAllocator, size)!; temp.last_page = null; @@ -90,13 +90,13 @@ fn void TempAllocator.reset(&self, usz mark) @dynamic self.used = mark; } -fn void! TempAllocator._free_page(&self, TempAllocatorPage* page) @inline @local +fn void? TempAllocator._free_page(&self, TempAllocatorPage* page) @inline @local { void* mem = page.start; return self.backing_allocator.release(mem, page.is_aligned()); } -fn void*! TempAllocator._realloc_page(&self, TempAllocatorPage* page, usz size, usz alignment) @inline @local +fn void*? TempAllocator._realloc_page(&self, TempAllocatorPage* page, usz size, usz alignment) @inline @local { // Then the actual start pointer: void* real_pointer = page.start; @@ -117,7 +117,7 @@ fn void*! TempAllocator._realloc_page(&self, TempAllocatorPage* page, usz size, return data; } -fn void*! TempAllocator.resize(&self, void* pointer, usz size, usz alignment) @dynamic +fn void*? TempAllocator.resize(&self, void* pointer, usz size, usz alignment) @dynamic { TempAllocatorChunk *chunk = pointer - TempAllocatorChunk.sizeof; if (chunk.size == (usz)-1) @@ -139,7 +139,7 @@ fn void*! TempAllocator.resize(&self, void* pointer, usz size, usz alignment) @d @require !alignment || math::is_power_of_2(alignment) @require alignment <= mem::MAX_MEMORY_ALIGNMENT : `alignment too big` *> -fn void*! TempAllocator.acquire(&self, usz size, AllocInitType init_type, usz alignment) @dynamic +fn void*? TempAllocator.acquire(&self, usz size, AllocInitType init_type, usz alignment) @dynamic { alignment = alignment_for_allocation(alignment); void* start_mem = &self.data; @@ -210,7 +210,7 @@ fn void*! TempAllocator.acquire(&self, usz size, AllocInitType init_type, usz al return &page.data[0]; } -fn void! TempAllocator.print_pages(&self, File* f) +fn void? TempAllocator.print_pages(&self, File* f) { TempAllocatorPage *last_page = self.last_page; if (!last_page) diff --git a/lib/std/core/allocators/tracking_allocator.c3 b/lib/std/core/allocators/tracking_allocator.c3 index fc889d23c..7ab889405 100644 --- a/lib/std/core/allocators/tracking_allocator.c3 +++ b/lib/std/core/allocators/tracking_allocator.c3 @@ -76,7 +76,7 @@ fn Allocation[] TrackingAllocator.allocations_tlist(&self, Allocator allocator) *> fn usz TrackingAllocator.allocation_count(&self) => self.map.count; -fn void*! TrackingAllocator.acquire(&self, usz size, AllocInitType init_type, usz alignment) @dynamic +fn void*? TrackingAllocator.acquire(&self, usz size, AllocInitType init_type, usz alignment) @dynamic { void* data = self.inner_allocator.acquire(size, init_type, alignment)!; self.allocs_total++; @@ -87,7 +87,7 @@ fn void*! TrackingAllocator.acquire(&self, usz size, AllocInitType init_type, us return data; } -fn void*! TrackingAllocator.resize(&self, void* old_pointer, usz size, usz alignment) @dynamic +fn void*? TrackingAllocator.resize(&self, void* old_pointer, usz size, usz alignment) @dynamic { void* data = self.inner_allocator.resize(old_pointer, size, alignment)!; self.map.remove((uptr)old_pointer); @@ -121,7 +121,7 @@ fn bool TrackingAllocator.has_leaks(&self) fn void TrackingAllocator.print_report(&self) => self.fprint_report(io::stdout())!!; -fn void! TrackingAllocator.fprint_report(&self, OutStream out) => @pool() +fn void? TrackingAllocator.fprint_report(&self, OutStream out) => @pool() { usz total = 0; usz entries = 0; diff --git a/lib/std/core/array.c3 b/lib/std/core/array.c3 index 0228c4a21..ca0bce992 100644 --- a/lib/std/core/array.c3 +++ b/lib/std/core/array.c3 @@ -5,7 +5,7 @@ import std::core::array::slice; @param [in] array @param [in] element @return "the first index of the element" - @return! SearchResult.MISSING + @return! NOT_FOUND *> macro index_of(array, element) { @@ -13,7 +13,7 @@ macro index_of(array, element) { if (*e == element) return i; } - return SearchResult.MISSING?; + return NOT_FOUND?; } <* @@ -34,7 +34,7 @@ macro slice2d(array_ptr, x = 0, xlen = 0, y = 0, ylen = 0) @param [in] array @param [in] element @return "the last index of the element" - @return! SearchResult.MISSING + @return! NOT_FOUND *> macro rindex_of(array, element) { @@ -42,7 +42,7 @@ macro rindex_of(array, element) { if (*e == element) return i; } - return SearchResult.MISSING?; + return NOT_FOUND?; } <* diff --git a/lib/std/core/builtin.c3 b/lib/std/core/builtin.c3 index 692630bbe..97fb66d7a 100644 --- a/lib/std/core/builtin.c3 +++ b/lib/std/core/builtin.c3 @@ -32,17 +32,17 @@ macro @is_valid_macro_slot(#arg) @const @builtin => !@typeis(#arg, EmptySlot); /* Use `IteratorResult` when reading the end of an iterator, or accessing a result out of bounds. */ -fault IteratorResult { NO_MORE_ELEMENT } +fault NO_MORE_ELEMENT @builtin; /* Use `SearchResult` when trying to return a value from some collection but the element is missing. */ -fault SearchResult { MISSING } +fault NOT_FOUND @builtin; /* Use `CastResult` when an attempt at conversion fails. */ -fault CastResult { TYPE_MISMATCH } +fault TYPE_MISMATCH @builtin; def VoidFn = fn void(); @@ -79,11 +79,11 @@ macro void @swap(#a, #b) @builtin @param $Type : `the type to convert to` @return `The any.ptr converted to its type.` @ensure @typeis(return, $Type*) - @return! CastResult.TYPE_MISMATCH + @return! TYPE_MISMATCH *> macro anycast(any v, $Type) @builtin { - if (v.type != $Type.typeid) return CastResult.TYPE_MISMATCH?; + if (v.type != $Type.typeid) return TYPE_MISMATCH?; return ($Type*)v.ptr; } @@ -92,7 +92,7 @@ fn bool print_backtrace(String message, int backtraces_to_ignore) @if(env::NATIV void*[256] buffer; void*[] backtraces = backtrace::capture_current(&buffer); backtraces_to_ignore++; - BacktraceList! backtrace = backtrace::symbolize_backtrace(tmem(), backtraces); + BacktraceList? backtrace = backtrace::symbolize_backtrace(tmem(), backtraces); if (catch backtrace) return false; if (backtrace.len() <= backtraces_to_ignore) return false; io::eprint("\nERROR: '"); @@ -247,7 +247,7 @@ macro bitcast(expr, $Type) @builtin @param [in] enum_name : `The name of the enum to search for` @require $Type.kindof == ENUM : `Only enums may be used` @ensure @typeis(return, $Type) - @return! SearchResult.MISSING + @return! NOT_FOUND *> macro enum_by_name($Type, String enum_name) @builtin { @@ -256,7 +256,7 @@ macro enum_by_name($Type, String enum_name) @builtin { if (name == enum_name) return $Type.from_ordinal(i); } - return SearchResult.MISSING?; + return NOT_FOUND?; } <* @@ -265,7 +265,7 @@ macro enum_by_name($Type, String enum_name) @builtin @require $defined($Type.#value) : `Expected '#value' to match an enum associated value` @require $assignable(value, $typeof(($Type){}.#value)) : `Expected the value to match the type of the associated value` @ensure @typeis(return, $Type) - @return! SearchResult.MISSING + @return! NOT_FOUND *> macro @enum_from_value($Type, #value, value) @builtin { @@ -274,7 +274,7 @@ macro @enum_from_value($Type, #value, value) @builtin { if (e.#value == value) return e; } - return SearchResult.MISSING?; + return NOT_FOUND?; } <* diff --git a/lib/std/core/conv.c3 b/lib/std/core/conv.c3 index 21ff905e8..83aa304ea 100644 --- a/lib/std/core/conv.c3 +++ b/lib/std/core/conv.c3 @@ -12,28 +12,29 @@ const uint UTF16_SURROGATE_HIGH_VALUE @private = 0xD800; <* @param c : `The utf32 codepoint to convert` @param [out] output : `the resulting buffer` + @return! string::CONVERSION_FAILED *> -fn usz! char32_to_utf8(Char32 c, char[] output) +fn usz? char32_to_utf8(Char32 c, char[] output) { - if (!output.len) return UnicodeResult.CONVERSION_FAILED?; + if (!output.len) return string::CONVERSION_FAILED?; switch (true) { case c <= 0x7f: output[0] = (char)c; return 1; case c <= 0x7ff: - if (output.len < 2) return UnicodeResult.CONVERSION_FAILED?; + if (output.len < 2) return string::CONVERSION_FAILED?; output[0] = (char)(0xC0 | c >> 6); output[1] = (char)(0x80 | (c & 0x3F)); return 2; case c <= 0xffff: - if (output.len < 3) return UnicodeResult.CONVERSION_FAILED?; + if (output.len < 3) return string::CONVERSION_FAILED?; output[0] = (char)(0xE0 | c >> 12); output[1] = (char)(0x80 | (c >> 6 & 0x3F)); output[2] = (char)(0x80 | (c & 0x3F)); return 3; case c <= 0x10ffff: - if (output.len < 4) return UnicodeResult.CONVERSION_FAILED?; + if (output.len < 4) return string::CONVERSION_FAILED?; output[0] = (char)(0xF0 | c >> 18); output[1] = (char)(0x80 | (c >> 12 & 0x3F)); output[2] = (char)(0x80 | (c >> 6 & 0x3F)); @@ -41,7 +42,7 @@ fn usz! char32_to_utf8(Char32 c, char[] output) return 4; default: // 0x10FFFF and above is not defined. - return UnicodeResult.CONVERSION_FAILED?; + return string::CONVERSION_FAILED?; } } @@ -73,7 +74,7 @@ fn void char32_to_utf16_unsafe(Char32 c, Char16** output) @param [inout] available : `amount of UTF16 data available.` @param [inout] output : `the resulting utf8 buffer to write to.` *> -fn void! char16_to_utf8_unsafe(Char16 *ptr, usz *available, char** output) +fn void? char16_to_utf8_unsafe(Char16 *ptr, usz *available, char** output) { Char16 high = *ptr; if (high & UTF16_SURROGATE_GENERIC_MASK != UTF16_SURROGATE_GENERIC_VALUE) @@ -83,15 +84,15 @@ fn void! char16_to_utf8_unsafe(Char16 *ptr, usz *available, char** output) return; } // Low surrogate first is an error - if (high & UTF16_SURROGATE_MASK != UTF16_SURROGATE_HIGH_VALUE) return UnicodeResult.INVALID_UTF16?; + if (high & UTF16_SURROGATE_MASK != UTF16_SURROGATE_HIGH_VALUE) return string::INVALID_UTF16?; // Unmatched high surrogate is an error - if (*available == 1) return UnicodeResult.INVALID_UTF16?; + if (*available == 1) return string::INVALID_UTF16?; Char16 low = ptr[1]; // Unmatched high surrogate, invalid - if (low & UTF16_SURROGATE_MASK != UTF16_SURROGATE_LOW_VALUE) return UnicodeResult.INVALID_UTF16?; + if (low & UTF16_SURROGATE_MASK != UTF16_SURROGATE_LOW_VALUE) return string::INVALID_UTF16?; // The high bits of the codepoint are the value bits of the high surrogate // The low bits of the codepoint are the value bits of the low surrogate @@ -134,10 +135,10 @@ fn usz char32_to_utf8_unsafe(Char32 c, char** output) @param [inout] size : `Set to max characters to read, set to characters read` @return `the parsed 32 bit codepoint` *> -fn Char32! utf8_to_char32(char* ptr, usz* size) +fn Char32? utf8_to_char32(char* ptr, usz* size) { usz max_size = *size; - if (max_size < 1) return UnicodeResult.INVALID_UTF8?; + if (max_size < 1) return string::INVALID_UTF8?; char c = (ptr++)[0]; if ((c & 0x80) == 0) @@ -147,40 +148,40 @@ fn Char32! utf8_to_char32(char* ptr, usz* size) } if ((c & 0xE0) == 0xC0) { - if (max_size < 2) return UnicodeResult.INVALID_UTF8?; + if (max_size < 2) return string::INVALID_UTF8?; *size = 2; Char32 uc = (c & 0x1F) << 6; c = *ptr; // Overlong sequence or invalid second. - if (!uc || c & 0xC0 != 0x80) return UnicodeResult.INVALID_UTF8?; + if (!uc || c & 0xC0 != 0x80) return string::INVALID_UTF8?; return uc + c & 0x3F; } if ((c & 0xF0) == 0xE0) { - if (max_size < 3) return UnicodeResult.INVALID_UTF8?; + if (max_size < 3) return string::INVALID_UTF8?; *size = 3; Char32 uc = (c & 0x0F) << 12; c = ptr++[0]; - if (c & 0xC0 != 0x80) return UnicodeResult.INVALID_UTF8?; + if (c & 0xC0 != 0x80) return string::INVALID_UTF8?; uc += (c & 0x3F) << 6; c = ptr++[0]; // Overlong sequence or invalid last - if (!uc || c & 0xC0 != 0x80) return UnicodeResult.INVALID_UTF8?; + if (!uc || c & 0xC0 != 0x80) return string::INVALID_UTF8?; return uc + c & 0x3F; } - if (max_size < 4) return UnicodeResult.INVALID_UTF8?; - if ((c & 0xF8) != 0xF0) return UnicodeResult.INVALID_UTF8?; + if (max_size < 4) return string::INVALID_UTF8?; + if ((c & 0xF8) != 0xF0) return string::INVALID_UTF8?; *size = 4; Char32 uc = (c & 0x07) << 18; c = ptr++[0]; - if (c & 0xC0 != 0x80) return UnicodeResult.INVALID_UTF8?; + if (c & 0xC0 != 0x80) return string::INVALID_UTF8?; uc += (c & 0x3F) << 12; c = ptr++[0]; - if (c & 0xC0 != 0x80) return UnicodeResult.INVALID_UTF8?; + if (c & 0xC0 != 0x80) return string::INVALID_UTF8?; uc += (c & 0x3F) << 6; c = ptr++[0]; // Overlong sequence or invalid last - if (!uc || c & 0xC0 != 0x80) return UnicodeResult.INVALID_UTF8?; + if (!uc || c & 0xC0 != 0x80) return string::INVALID_UTF8?; return uc + c & 0x3F; } @@ -300,7 +301,7 @@ fn usz utf16len_for_utf32(Char32[] utf32) @param [out] utf8_buffer @return `the number of bytes written.` *> -fn usz! utf32to8(Char32[] utf32, char[] utf8_buffer) +fn usz? utf32to8(Char32[] utf32, char[] utf8_buffer) { char[] buffer = utf8_buffer; foreach (uc : utf32) @@ -320,7 +321,7 @@ fn usz! utf32to8(Char32[] utf32, char[] utf8_buffer) @param [out] utf32_buffer @return `the number of Char32s written.` *> -fn usz! utf8to32(String utf8, Char32[] utf32_buffer) +fn usz? utf8to32(String utf8, Char32[] utf32_buffer) { usz len = utf8.len; Char32* ptr = utf32_buffer.ptr; @@ -328,7 +329,7 @@ fn usz! utf8to32(String utf8, Char32[] utf32_buffer) usz buf_len = utf32_buffer.len; for (usz i = 0; i < len;) { - if (len32 == buf_len) return UnicodeResult.CONVERSION_FAILED?; + if (len32 == buf_len) return string::CONVERSION_FAILED?; usz width = len - i; Char32 uc = utf8_to_char32(&utf8[i], &width) @inline!; i += width; @@ -347,7 +348,7 @@ fn usz! utf8to32(String utf8, Char32[] utf32_buffer) @param [in] utf16 : `The UTF16 array containing the data to convert.` @param [out] utf8_buffer : `the (sufficiently large) buffer to hold the UTF16 data.` *> -fn void! utf16to8_unsafe(Char16[] utf16, char* utf8_buffer) +fn void? utf16to8_unsafe(Char16[] utf16, char* utf8_buffer) { usz len16 = utf16.len; for (usz i = 0; i < len16;) @@ -366,7 +367,7 @@ fn void! utf16to8_unsafe(Char16[] utf16, char* utf8_buffer) @param [in] utf8 : `The UTF8 buffer containing the data to convert.` @param [out] utf32_buffer : `the (sufficiently large) buffer to hold the UTF8 data.` *> -fn void! utf8to32_unsafe(String utf8, Char32* utf32_buffer) +fn void? utf8to32_unsafe(String utf8, Char32* utf32_buffer) { usz len = utf8.len; for (usz i = 0; i < len;) @@ -386,7 +387,7 @@ fn void! utf8to32_unsafe(String utf8, Char32* utf32_buffer) @param [in] utf8 : `The UTF8 buffer containing the data to convert.` @param [out] utf16_buffer : `the (sufficiently large) buffer to hold the UTF8 data.` *> -fn void! utf8to16_unsafe(String utf8, Char16* utf16_buffer) +fn void? utf8to16_unsafe(String utf8, Char16* utf16_buffer) { usz len = utf8.len; for (usz i = 0; i < len;) diff --git a/lib/std/core/dstring.c3 b/lib/std/core/dstring.c3 index f52704559..80948fad1 100644 --- a/lib/std/core/dstring.c3 +++ b/lib/std/core/dstring.c3 @@ -324,13 +324,13 @@ fn void DString.clear(self) self.data().len = 0; } -fn usz! DString.write(&self, char[] buffer) @dynamic +fn usz? DString.write(&self, char[] buffer) @dynamic { self.append_chars((String)buffer); return buffer.len; } -fn void! DString.write_byte(&self, char c) @dynamic +fn void? DString.write_byte(&self, char c) @dynamic { self.append_char(c); } @@ -535,7 +535,7 @@ macro void DString.insert_at(&self, usz index, value) $endswitch } -fn usz! DString.appendf(&self, String format, args...) @maydiscard +fn usz? DString.appendf(&self, String format, args...) @maydiscard { if (!self.data()) self.tinit(format.len + 20); @pool(self.data().allocator) @@ -546,7 +546,7 @@ fn usz! DString.appendf(&self, String format, args...) @maydiscard }; } -fn usz! DString.appendfn(&self, String format, args...) @maydiscard +fn usz? DString.appendfn(&self, String format, args...) @maydiscard { if (!self.data()) self.tinit(format.len + 20); @pool(self.data().allocator) @@ -577,7 +577,7 @@ fn DString join(Allocator allocator, String[] s, String joiner) return res; } -fn void! out_string_append_fn(void* data, char c) @private +fn void? out_string_append_fn(void* data, char c) @private { DString* s = data; s.append_char(c); @@ -619,7 +619,7 @@ fn void DString.reserve(&self, usz addition) *self = (DString)allocator::realloc(data.allocator, data, StringData.sizeof + new_capacity); } -fn usz! DString.read_from_stream(&self, InStream reader) +fn usz? DString.read_from_stream(&self, InStream reader) { if (&reader.available) { @@ -654,5 +654,5 @@ struct StringData @private Allocator allocator; usz len; usz capacity; - char[?] chars; + char[*] chars; } diff --git a/lib/std/core/mem.c3 b/lib/std/core/mem.c3 index 212b17865..968862e08 100644 --- a/lib/std/core/mem.c3 +++ b/lib/std/core/mem.c3 @@ -8,6 +8,8 @@ import std::math; const MAX_MEMORY_ALIGNMENT = 0x1000_0000; const DEFAULT_MEM_ALIGNMENT = (void*.alignof) * 2; +fault OUT_OF_MEMORY, INVALID_ALLOC_SIZE; + macro bool @constant_is_power_of_2($x) @const @private { return $x != 0 && ($x & ($x - 1)) == 0; @@ -25,7 +27,7 @@ macro bool @constant_is_power_of_2($x) @const @private @return "A vector with the loaded values where the mask is true, passthru where the mask is false" *> -macro masked_load(ptr, bool[] mask, passthru) +macro masked_load(ptr, bool[<*>] mask, passthru) { return $$masked_load(ptr, mask, passthru, 0); } @@ -45,7 +47,7 @@ macro masked_load(ptr, bool[] mask, passthru) @return "A vector with the loaded values where the mask is true, passthru where the mask is false" *> -macro @masked_load_aligned(ptr, bool[] mask, passthru, usz $alignment) +macro @masked_load_aligned(ptr, bool[<*>] mask, passthru, usz $alignment) { return $$masked_load(ptr, mask, passthru, $alignment); } @@ -65,7 +67,7 @@ macro @masked_load_aligned(ptr, bool[] mask, passthru, usz $alignment) @return "A vector with the loaded values where the mask is true, passthru where the mask is false" *> -macro gather(ptrvec, bool[] mask, passthru) +macro gather(ptrvec, bool[<*>] mask, passthru) { return $$gather(ptrvec, mask, passthru, 0); } @@ -88,7 +90,7 @@ macro gather(ptrvec, bool[] mask, passthru) @return "A vector with the loaded values where the mask is true, passthru where the mask is false" *> -macro @gather_aligned(ptrvec, bool[] mask, passthru, usz $alignment) +macro @gather_aligned(ptrvec, bool[<*>] mask, passthru, usz $alignment) { return $$gather(ptrvec, mask, passthru, $alignment); } @@ -105,7 +107,7 @@ macro @gather_aligned(ptrvec, bool[] mask, passthru, usz $alignment) @require @typekind(value) == VECTOR : "Expected value to be a vector" @require value.len == mask.len : "Mask and value must have the same length" *> -macro masked_store(ptr, value, bool[] mask) +macro masked_store(ptr, value, bool[<*>] mask) { return $$masked_store(ptr, value, mask, 0); } @@ -122,7 +124,7 @@ macro masked_store(ptr, value, bool[] mask) @require @constant_is_power_of_2($alignment) : "The alignment must be a power of two" *> -macro @masked_store_aligned(ptr, value, bool[] mask, usz $alignment) +macro @masked_store_aligned(ptr, value, bool[<*>] mask, usz $alignment) { return $$masked_store(ptr, value, mask, $alignment); } @@ -138,7 +140,7 @@ macro @masked_store_aligned(ptr, value, bool[] mask, usz $alignment) @require mask.len == ptrvec.len : "Mask and ptrvec must have the same length" *> -macro scatter(ptrvec, value, bool[] mask) +macro scatter(ptrvec, value, bool[<*>] mask) { return $$scatter(ptrvec, value, mask, 0); } @@ -156,7 +158,7 @@ macro scatter(ptrvec, value, bool[] mask) @require mask.len == ptrvec.len : "Mask and ptrvec must have the same length" @require @constant_is_power_of_2($alignment) : "The alignment must be a power of two" *> -macro @scatter_aligned(ptrvec, value, bool[] mask, usz $alignment) +macro @scatter_aligned(ptrvec, value, bool[<*>] mask, usz $alignment) { return $$scatter(ptrvec, value, mask, $alignment); } diff --git a/lib/std/core/mem_allocator.c3 b/lib/std/core/mem_allocator.c3 index ad1d55824..4304f81e0 100644 --- a/lib/std/core/mem_allocator.c3 +++ b/lib/std/core/mem_allocator.c3 @@ -24,28 +24,26 @@ interface Allocator @require !alignment || math::is_power_of_2(alignment) @require alignment <= mem::MAX_MEMORY_ALIGNMENT : `alignment too big` @require size > 0 + @return! mem::INVALID_ALLOC_SIZE, mem::OUT_OF_MEMORY *> - fn void*! acquire(usz size, AllocInitType init_type, usz alignment = 0); + fn void*? acquire(usz size, AllocInitType init_type, usz alignment = 0); <* @require !alignment || math::is_power_of_2(alignment) @require alignment <= mem::MAX_MEMORY_ALIGNMENT : `alignment too big` @require ptr != null @require new_size > 0 + @return! mem::INVALID_ALLOC_SIZE, mem::OUT_OF_MEMORY *> - fn void*! resize(void* ptr, usz new_size, usz alignment = 0); + fn void*? resize(void* ptr, usz new_size, usz alignment = 0); <* @require ptr != null *> fn void release(void* ptr, bool aligned); } -def MemoryAllocFn = fn char[]!(usz); +def MemoryAllocFn = fn char[]?(usz); + -fault AllocationFailure -{ - OUT_OF_MEMORY, - CHUNK_TOO_LARGE, -} fn usz alignment_for_allocation(usz alignment) @inline @private { @@ -57,7 +55,7 @@ macro void* malloc(Allocator allocator, usz size) @nodiscard return malloc_try(allocator, size)!!; } -macro void*! malloc_try(Allocator allocator, usz size) @nodiscard +macro void*? malloc_try(Allocator allocator, usz size) @nodiscard { if (!size) return null; $if env::TESTING: @@ -74,7 +72,7 @@ macro void* calloc(Allocator allocator, usz size) @nodiscard return calloc_try(allocator, size)!!; } -macro void*! calloc_try(Allocator allocator, usz size) @nodiscard +macro void*? calloc_try(Allocator allocator, usz size) @nodiscard { if (!size) return null; return allocator.acquire(size, ZERO); @@ -85,7 +83,7 @@ macro void* realloc(Allocator allocator, void* ptr, usz new_size) @nodiscard return realloc_try(allocator, ptr, new_size)!!; } -macro void*! realloc_try(Allocator allocator, void* ptr, usz new_size) @nodiscard +macro void*? realloc_try(Allocator allocator, void* ptr, usz new_size) @nodiscard { if (!new_size) { @@ -105,7 +103,7 @@ macro void free(Allocator allocator, void* ptr) allocator.release(ptr, false); } -macro void*! malloc_aligned(Allocator allocator, usz size, usz alignment) @nodiscard +macro void*? malloc_aligned(Allocator allocator, usz size, usz alignment) @nodiscard { if (!size) return null; $if env::TESTING: @@ -117,13 +115,13 @@ macro void*! malloc_aligned(Allocator allocator, usz size, usz alignment) @nodis $endif } -macro void*! calloc_aligned(Allocator allocator, usz size, usz alignment) @nodiscard +macro void*? calloc_aligned(Allocator allocator, usz size, usz alignment) @nodiscard { if (!size) return null; return allocator.acquire(size, ZERO, alignment); } -macro void*! realloc_aligned(Allocator allocator, void* ptr, usz new_size, usz alignment) @nodiscard +macro void*? realloc_aligned(Allocator allocator, void* ptr, usz new_size, usz alignment) @nodiscard { if (!new_size) { @@ -305,7 +303,7 @@ fn any clone_any(Allocator allocator, any value) @nodiscard @require alignment > 0 @require bytes <= isz.max *> -macro void*! @aligned_alloc(#alloc_fn, usz bytes, usz alignment) +macro void*? @aligned_alloc(#alloc_fn, usz bytes, usz alignment) { if (alignment < void*.alignof) alignment = void*.alignof; usz header = AlignedBlock.sizeof + alignment; @@ -328,7 +326,7 @@ struct AlignedBlock void* start; } -macro void! @aligned_free(#free_fn, void* old_pointer) +macro void? @aligned_free(#free_fn, void* old_pointer) { AlignedBlock* desc = (AlignedBlock*)old_pointer - 1; $if @typekind(#free_fn(desc.start)) == OPTIONAL: @@ -342,7 +340,7 @@ macro void! @aligned_free(#free_fn, void* old_pointer) @require bytes > 0 @require alignment > 0 *> -macro void*! @aligned_realloc(#calloc_fn, #free_fn, void* old_pointer, usz bytes, usz alignment) +macro void*? @aligned_realloc(#calloc_fn, #free_fn, void* old_pointer, usz bytes, usz alignment) { AlignedBlock* desc = (AlignedBlock*)old_pointer - 1; void* data_start = desc.start; @@ -448,14 +446,14 @@ fn TempAllocator* temp_allocator_next() @private const NullAllocator NULL_ALLOCATOR = {}; distinct NullAllocator (Allocator) = uptr; -fn void*! NullAllocator.acquire(&self, usz bytes, AllocInitType init_type, usz alignment) @dynamic +fn void*? NullAllocator.acquire(&self, usz bytes, AllocInitType init_type, usz alignment) @dynamic { - return AllocationFailure.OUT_OF_MEMORY?; + return mem::OUT_OF_MEMORY?; } -fn void*! NullAllocator.resize(&self, void* old_ptr, usz new_bytes, usz alignment) @dynamic +fn void*? NullAllocator.resize(&self, void* old_ptr, usz new_bytes, usz alignment) @dynamic { - return AllocationFailure.OUT_OF_MEMORY?; + return mem::OUT_OF_MEMORY?; } fn void NullAllocator.release(&self, void* old_ptr, bool aligned) @dynamic diff --git a/lib/std/core/os/wasm_memory.c3 b/lib/std/core/os/wasm_memory.c3 index bf1db6935..44a3d3600 100644 --- a/lib/std/core/os/wasm_memory.c3 +++ b/lib/std/core/os/wasm_memory.c3 @@ -11,7 +11,7 @@ struct WasmMemory uptr use; } -fn char[]! WasmMemory.allocate_block(&self, usz bytes) +fn char[]? WasmMemory.allocate_block(&self, usz bytes) { if (!self.allocation) { @@ -25,7 +25,7 @@ fn char[]! WasmMemory.allocate_block(&self, usz bytes) } usz blocks_required = (bytes_required + WASM_BLOCK_SIZE + 1) / WASM_BLOCK_SIZE; - if ($$wasm_memory_grow(0, blocks_required) == -1) return AllocationFailure.OUT_OF_MEMORY?; + if ($$wasm_memory_grow(0, blocks_required) == -1) return mem::OUT_OF_MEMORY?; self.allocation = $$wasm_memory_size(0) * WASM_BLOCK_SIZE; defer self.use += bytes; return ((char*)self.use)[:bytes]; diff --git a/lib/std/core/private/macho_runtime.c3 b/lib/std/core/private/macho_runtime.c3 index d21b9ff46..7af986b61 100644 --- a/lib/std/core/private/macho_runtime.c3 +++ b/lib/std/core/private/macho_runtime.c3 @@ -56,10 +56,7 @@ struct MachHeader64 const LC_SEGMENT_64 = 0x19; -fault MachoSearch -{ - NOT_FOUND -} + fn bool name_cmp(char* a, char[16]* b) { for (usz i = 0; i < 16; i++) @@ -70,7 +67,7 @@ fn bool name_cmp(char* a, char[16]* b) return false; } -fn SegmentCommand64*! find_segment(MachHeader* header, char* segname) +fn SegmentCommand64*? find_segment(MachHeader* header, char* segname) { LoadCommand* command = (void*)header + MachHeader64.sizeof; for (uint i = 0; i < header.ncmds; i++) @@ -82,9 +79,9 @@ fn SegmentCommand64*! find_segment(MachHeader* header, char* segname) } command = (void*)command + command.cmdsize; } - return MachoSearch.NOT_FOUND?; + return NOT_FOUND?; } -fn Section64*! find_section(SegmentCommand64* command, char* sectname) +fn Section64*? find_section(SegmentCommand64* command, char* sectname) { Section64* section = (void*)command + SegmentCommand64.sizeof; for (uint i = 0; i < command.nsects; i++) @@ -92,13 +89,13 @@ fn Section64*! find_section(SegmentCommand64* command, char* sectname) if (name_cmp(sectname, §ion.sectname)) return section; section++; } - return MachoSearch.NOT_FOUND?; + return NOT_FOUND?; } macro find_segment_section_body(MachHeader* header, char* segname, char* sectname, $Type) { - Section64*! section = find_section(find_segment(header, segname), sectname); + Section64*? section = find_section(find_segment(header, segname), sectname); if (catch section) { return ($Type[]){}; @@ -214,7 +211,7 @@ struct TypeId usz sizeof; TypeId* inner; usz len; - typeid[?] additional; + typeid[*] additional; } fn void dl_reg_callback(MachHeader* mh, isz vmaddr_slide) diff --git a/lib/std/core/string.c3 b/lib/std/core/string.c3 index 6ba7eeeef..1dd2a8ed9 100644 --- a/lib/std/core/string.c3 +++ b/lib/std/core/string.c3 @@ -8,12 +8,8 @@ distinct WString = inline Char16*; def Char32 = uint; def Char16 = ushort; -fault UnicodeResult -{ - INVALID_UTF8, - INVALID_UTF16, - CONVERSION_FAILED, -} +fault INVALID_UTF8, INVALID_UTF16, CONVERSION_FAILED, EMPTY_STRING, NEGATIVE_VALUE, MALFORMED_INTEGER, + INTEGER_OVERFLOW, MALFORMED_FLOAT, FLOAT_OUT_OF_RANGE; const uint SURROGATE_OFFSET @private = 0x10000; const uint SURROGATE_GENERIC_MASK @private = 0xF800; @@ -23,16 +19,6 @@ const uint SURROGATE_BITS @private = 10; const uint SURROGATE_LOW_VALUE @private = 0xDC00; const uint SURROGATE_HIGH_VALUE @private = 0xD800; -fault NumberConversion -{ - EMPTY_STRING, - NEGATIVE_VALUE, - MALFORMED_INTEGER, - INTEGER_OVERFLOW, - MALFORMED_FLOAT, - FLOAT_OUT_OF_RANGE, -} - macro Char32* @wstring32(String $string) @builtin { @@ -254,7 +240,7 @@ fn String[] String.split(s, Allocator allocator, String needle, usz max = 0, boo bool no_more = false; while (!no_more) { - usz! index = i == max - 1 ? SearchResult.MISSING? : s.index_of(needle); + usz? index = i == max - 1 ? NOT_FOUND? : s.index_of(needle); String res @noinit; if (try index) { @@ -293,7 +279,7 @@ fn String[] String.split(s, Allocator allocator, String needle, usz max = 0, boo *> fn String[] String.tsplit(s, String needle, usz max = 0, bool skip_empty = false) => s.split(tmem(), needle, max, skip_empty) @inline; -fault SplitResult { BUFFER_EXCEEDED } +fault BUFFER_EXCEEDED; <* Split a string into parts, e.g "a|b|c" split with "|" yields { "a", "b", "c" } @@ -304,16 +290,16 @@ fault SplitResult { BUFFER_EXCEEDED } @param max : "Max number of elements, 0 means no limit, defaults to 0" @require needle.len > 0 : "The needle must be at least 1 character long" @ensure return.len > 0 - @return! SplitResult.BUFFER_EXCEEDED : `If there are more elements than would fit the buffer` + @return! BUFFER_EXCEEDED : `If there are more elements than would fit the buffer` *> -fn String[]! String.split_to_buffer(s, String needle, String[] buffer, usz max = 0, bool skip_empty = false) +fn String[]? String.split_to_buffer(s, String needle, String[] buffer, usz max = 0, bool skip_empty = false) { usz max_capacity = buffer.len; usz i = 0; bool no_more = false; while (!no_more) { - usz! index = i == max - 1 ? SearchResult.MISSING? : s.index_of(needle); + usz? index = i == max - 1 ? NOT_FOUND? : s.index_of(needle); String res @noinit; if (try index) { @@ -331,7 +317,7 @@ fn String[]! String.split_to_buffer(s, String needle, String[] buffer, usz max = } if (i == max_capacity) { - return SplitResult.BUFFER_EXCEEDED?; + return BUFFER_EXCEEDED?; } buffer[i++] = res; } @@ -359,15 +345,15 @@ fn bool String.contains(s, String needle) @pure @ensure return < s.len @return "the index of the needle" - @return! SearchResult.MISSING : "if the needle cannot be found" + @return! NOT_FOUND : "if the needle cannot be found" *> -fn usz! String.index_of_char(s, char needle) +fn usz? String.index_of_char(s, char needle) { foreach (i, c : s) { if (c == needle) return i; } - return SearchResult.MISSING?; + return NOT_FOUND?; } <* @@ -378,9 +364,9 @@ fn usz! String.index_of_char(s, char needle) @pure @ensure return < s.len @return "the index of the needle" - @return! SearchResult.MISSING : "if the needle cannot be found" + @return! NOT_FOUND : "if the needle cannot be found" *> -fn usz! String.index_of_chars(String s, char[] needle) +fn usz? String.index_of_chars(String s, char[] needle) { foreach (i, c : s) { @@ -390,7 +376,7 @@ fn usz! String.index_of_chars(String s, char[] needle) } } - return SearchResult.MISSING?; + return NOT_FOUND?; } <* @@ -402,17 +388,17 @@ fn usz! String.index_of_chars(String s, char[] needle) @pure @ensure return < s.len @return "the index of the needle" - @return! SearchResult.MISSING : "if the needle cannot be found starting from the start_index" + @return! NOT_FOUND : "if the needle cannot be found starting from the start_index" *> -fn usz! String.index_of_char_from(s, char needle, usz start_index) +fn usz? String.index_of_char_from(s, char needle, usz start_index) { usz len = s.len; - if (len <= start_index) return SearchResult.MISSING?; + if (len <= start_index) return NOT_FOUND?; for (usz i = start_index; i < len; i++) { if (s[i] == needle) return i; } - return SearchResult.MISSING?; + return NOT_FOUND?; } <* @@ -423,15 +409,15 @@ fn usz! String.index_of_char_from(s, char needle, usz start_index) @pure @ensure return < s.len @return "the index of the needle" - @return! SearchResult.MISSING : "if the needle cannot be found" + @return! NOT_FOUND : "if the needle cannot be found" *> -fn usz! String.rindex_of_char(s, char needle) +fn usz? String.rindex_of_char(s, char needle) { foreach_r (i, c : s) { if (c == needle) return i; } - return SearchResult.MISSING?; + return NOT_FOUND?; } <* @@ -443,9 +429,9 @@ fn usz! String.rindex_of_char(s, char needle) @ensure return < s.len @require needle.len > 0 : "The needle must be len 1 or more" @return "the index of the needle" - @return! SearchResult.MISSING : "if the needle cannot be found" + @return! NOT_FOUND : "if the needle cannot be found" *> -fn usz! String.index_of(s, String needle) +fn usz? String.index_of(s, String needle) { usz needed = needle.len; if (needed > 0 && s.len >= needed) @@ -456,7 +442,7 @@ fn usz! String.index_of(s, String needle) if (c == first && s[i:needed] == needle) return i; } } - return SearchResult.MISSING?; + return NOT_FOUND?; } <* @@ -468,9 +454,9 @@ fn usz! String.index_of(s, String needle) @ensure return < s.len @require needle.len > 0 : "The needle must be len 1 or more" @return "the index of the needle" - @return! SearchResult.MISSING : "if the needle cannot be found" + @return! NOT_FOUND : "if the needle cannot be found" *> -fn usz! String.rindex_of(s, String needle) +fn usz? String.rindex_of(s, String needle) { usz needed = needle.len; if (needed > 0 && s.len >= needed) @@ -481,7 +467,7 @@ fn usz! String.rindex_of(s, String needle) if (c == first && s[i:needed] == needle) return i; } } - return SearchResult.MISSING?; + return NOT_FOUND?; } fn String ZString.str_view(str) @@ -570,10 +556,9 @@ fn String ZString.tcopy(z) <* Convert an UTF-8 string to UTF-16 @return "The UTF-16 string as a slice, allocated using the given allocator" - @return! UnicodeResult.INVALID_UTF8 : "If the string contained an invalid UTF-8 sequence" - @return! AllocationFailure : "If allocation of the string fails" + @return! INVALID_UTF8 : "If the string contained an invalid UTF-8 sequence" *> -fn Char16[]! String.to_utf16(s, Allocator allocator) +fn Char16[]? String.to_utf16(s, Allocator allocator) { usz len16 = conv::utf16len_for_utf8(s); Char16* data = allocator::alloc_array_try(allocator, Char16, len16 + 1)!; @@ -582,16 +567,16 @@ fn Char16[]! String.to_utf16(s, Allocator allocator) return data[:len16]; } -fn Char16[]! String.to_temp_utf16(s) => s.to_utf16(tmem()); +fn Char16[]? String.to_temp_utf16(s) => s.to_utf16(tmem()); -fn WString! String.to_wstring(s, Allocator allocator) +fn WString? String.to_wstring(s, Allocator allocator) { return (WString)s.to_utf16(allocator).ptr; } -fn WString! String.to_temp_wstring(s) => s.to_wstring(tmem()); +fn WString? String.to_temp_wstring(s) => s.to_wstring(tmem()); -fn Char32[]! String.to_utf32(s, Allocator allocator) +fn Char32[]? String.to_utf32(s, Allocator allocator) { usz codepoints = conv::utf8_codepoints(s); Char32* data = allocator::alloc_array_try(allocator, Char32, codepoints + 1)!; @@ -600,7 +585,7 @@ fn Char32[]! String.to_utf32(s, Allocator allocator) return data[:codepoints]; } -fn Char32[]! String.to_temp_utf32(s) => s.to_utf32(tmem()); +fn Char32[]? String.to_temp_utf32(s) => s.to_utf32(tmem()); <* Convert a string to ASCII lower case in place. @@ -665,7 +650,7 @@ fn String String.to_upper_tcopy(s) return s.to_upper_copy(tmem()); } -fn String! from_utf32(Allocator allocator, Char32[] utf32) +fn String? from_utf32(Allocator allocator, Char32[] utf32) { usz len = conv::utf8len_for_utf32(utf32); char* data = allocator::malloc_try(allocator, len + 1)!; @@ -675,7 +660,7 @@ fn String! from_utf32(Allocator allocator, Char32[] utf32) return (String)data[:len]; } -fn String! from_utf16(Allocator allocator, Char16[] utf16) +fn String? from_utf16(Allocator allocator, Char16[] utf16) { usz len = conv::utf8len_for_utf16(utf16); char* data = allocator::malloc_try(allocator, len + 1)!; @@ -685,7 +670,7 @@ fn String! from_utf16(Allocator allocator, Char16[] utf16) return (String)data[:len]; } -fn String! from_wstring(Allocator allocator, WString wstring) +fn String? from_wstring(Allocator allocator, WString wstring) { usz utf16_len; while (wstring[utf16_len] != 0) utf16_len++; @@ -693,8 +678,8 @@ fn String! from_wstring(Allocator allocator, WString wstring) return from_utf16(allocator, utf16); } -fn String! tfrom_wstring(WString wstring) => from_wstring(tmem(), wstring) @inline; -fn String! tfrom_utf16(Char16[] utf16) => from_utf16(tmem(), utf16) @inline; +fn String? tfrom_wstring(WString wstring) => from_wstring(tmem(), wstring) @inline; +fn String? tfrom_utf16(Char16[] utf16) => from_utf16(tmem(), utf16) @inline; fn usz String.utf8_codepoints(s) { @@ -716,12 +701,12 @@ macro String.to_integer(string, $Type, int base = 10) usz index = 0; char* ptr = string.ptr; while (index < len && ascii::is_blank_m(ptr[index])) index++; - if (len == index) return NumberConversion.EMPTY_STRING?; + if (len == index) return EMPTY_STRING?; bool is_negative; switch (string[index]) { case '-': - if ($Type.min == 0) return NumberConversion.NEGATIVE_VALUE?; + if ($Type.min == 0) return NEGATIVE_VALUE?; is_negative = true; index++; case '+': @@ -729,7 +714,7 @@ macro String.to_integer(string, $Type, int base = 10) default: break; } - if (len == index) return NumberConversion.MALFORMED_INTEGER?; + if (len == index) return MALFORMED_INTEGER?; $Type base_used = ($Type)base; if (string[index] == '0' && base == 10) { @@ -752,7 +737,7 @@ macro String.to_integer(string, $Type, int base = 10) default: break; } - if (len == index) return NumberConversion.MALFORMED_INTEGER?; + if (len == index) return MALFORMED_INTEGER?; } $Type value = 0; while (index != len) @@ -762,41 +747,41 @@ macro String.to_integer(string, $Type, int base = 10) { case base_used != 16 || c < 'A': c -= '0'; case c <= 'F': c -= 'A' - 10; - case c < 'a' || c > 'f': return NumberConversion.MALFORMED_INTEGER?; + case c < 'a' || c > 'f': return MALFORMED_INTEGER?; default: c -= 'a' - 10; } - if (c >= base_used) return NumberConversion.MALFORMED_INTEGER?; + if (c >= base_used) return MALFORMED_INTEGER?; do { if (is_negative) { $Type new_value = value * base_used - c; - if (new_value > value) return NumberConversion.INTEGER_OVERFLOW?; + if (new_value > value) return INTEGER_OVERFLOW?; value = new_value; break; } $Type new_value = value * base_used + c; - if (new_value < value) return NumberConversion.INTEGER_OVERFLOW?; + if (new_value < value) return INTEGER_OVERFLOW?; value = new_value; }; } return value; } -fn int128! String.to_int128(s, int base = 10) => s.to_integer(int128, base); -fn long! String.to_long(s, int base = 10) => s.to_integer(long, base); -fn int! String.to_int(s, int base = 10) => s.to_integer(int, base); -fn short! String.to_short(s, int base = 10) => s.to_integer(short, base); -fn ichar! String.to_ichar(s, int base = 10) => s.to_integer(ichar, base); +fn int128? String.to_int128(s, int base = 10) => s.to_integer(int128, base); +fn long? String.to_long(s, int base = 10) => s.to_integer(long, base); +fn int? String.to_int(s, int base = 10) => s.to_integer(int, base); +fn short? String.to_short(s, int base = 10) => s.to_integer(short, base); +fn ichar? String.to_ichar(s, int base = 10) => s.to_integer(ichar, base); -fn uint128! String.to_uint128(s, int base = 10) => s.to_integer(uint128, base); -fn ulong! String.to_ulong(s, int base = 10) => s.to_integer(ulong, base); -fn uint! String.to_uint(s, int base = 10) => s.to_integer(uint, base); -fn ushort! String.to_ushort(s, int base = 10) => s.to_integer(ushort, base); -fn char! String.to_uchar(s, int base = 10) => s.to_integer(char, base); +fn uint128? String.to_uint128(s, int base = 10) => s.to_integer(uint128, base); +fn ulong? String.to_ulong(s, int base = 10) => s.to_integer(ulong, base); +fn uint? String.to_uint(s, int base = 10) => s.to_integer(uint, base); +fn ushort? String.to_ushort(s, int base = 10) => s.to_integer(ushort, base); +fn char? String.to_uchar(s, int base = 10) => s.to_integer(char, base); -fn double! String.to_double(s) => s.to_real(double); -fn float! String.to_float(s) => s.to_real(float); +fn double? String.to_double(s) => s.to_real(double); +fn float? String.to_float(s) => s.to_real(float); fn Splitter String.splitter(self, String split) { @@ -822,15 +807,15 @@ fn void Splitter.reset(&self) self.current = 0; } -fn String! Splitter.next(&self) +fn String? Splitter.next(&self) { while (true) { usz len = self.string.len; usz current = self.current; - if (current >= len) return IteratorResult.NO_MORE_ELEMENT?; + if (current >= len) return NO_MORE_ELEMENT?; String remaining = self.string[current..]; - usz! next = remaining.index_of(self.split); + usz? next = remaining.index_of(self.split); if (try next) { self.current = current + next + self.split.len; diff --git a/lib/std/core/string_iterator.c3 b/lib/std/core/string_iterator.c3 index abd7aa4a3..912ee6e33 100644 --- a/lib/std/core/string_iterator.c3 +++ b/lib/std/core/string_iterator.c3 @@ -11,22 +11,22 @@ fn void StringIterator.reset(&self) self.current = 0; } -fn Char32! StringIterator.next(&self) +fn Char32? StringIterator.next(&self) { usz len = self.utf8.len; usz current = self.current; - if (current >= len) return IteratorResult.NO_MORE_ELEMENT?; + if (current >= len) return NO_MORE_ELEMENT?; usz read = (len - current < 4 ? len - current : 4); Char32 res = conv::utf8_to_char32(&self.utf8[current], &read)!; self.current += read; return res; } -fn Char32! StringIterator.peek(&self) +fn Char32? StringIterator.peek(&self) { usz len = self.utf8.len; usz current = self.current; - if (current >= len) return IteratorResult.NO_MORE_ELEMENT?; + if (current >= len) return NO_MORE_ELEMENT?; usz read = (len - current < 4 ? len - current : 4); Char32 res = conv::utf8_to_char32(&self.utf8[current], &read)!; return res; @@ -37,13 +37,13 @@ fn bool StringIterator.has_next(&self) return self.current < self.utf8.len; } -fn Char32! StringIterator.get(&self) +fn Char32? StringIterator.get(&self) { usz len = self.utf8.len; usz current = self.current; usz read = (len - current < 4 ? len - current : 4); usz index = current > read ? current - read : 0; - if (index >= len) return IteratorResult.NO_MORE_ELEMENT?; + if (index >= len) return NO_MORE_ELEMENT?; Char32 res = conv::utf8_to_char32(&self.utf8[index], &read)!; return res; } diff --git a/lib/std/core/string_to_real.c3 b/lib/std/core/string_to_real.c3 index f0f2daced..ab9a019c8 100644 --- a/lib/std/core/string_to_real.c3 +++ b/lib/std/core/string_to_real.c3 @@ -34,13 +34,13 @@ const uint[2] B1B_MAX = { 9007199, 254740991 }; <* @require chars.len > 0 *> -macro double! decfloat(char[] chars, int $bits, int $emin, int sign) +macro double? decfloat(char[] chars, int $bits, int $emin, int sign) { uint[KMAX] x; const uint[2] TH = B1B_MAX; int emax = - $emin - $bits + 3; - const int[?] P10S = { 10, 100, 1000, 10000, 100000, 1000000, 10000000, 100000000 }; + const int[*] P10S = { 10, 100, 1000, 10000, 100000, 1000000, 10000000, 100000000 }; usz index; bool got_digit = chars[0] == '0'; bool got_rad; @@ -64,7 +64,7 @@ macro double! decfloat(char[] chars, int $bits, int $emin, int sign) got_rad = true; if (index == last_char) { - if (!got_digit) return NumberConversion.MALFORMED_FLOAT?; + if (!got_digit) return MALFORMED_FLOAT?; return sign * 0.0; } if (index != last_char && (c = chars[++index]) == '0') @@ -83,7 +83,7 @@ macro double! decfloat(char[] chars, int $bits, int $emin, int sign) switch { case c == '.': - if (got_rad) return NumberConversion.MALFORMED_FLOAT?; + if (got_rad) return MALFORMED_FLOAT?; got_rad = true; lrp = dc; case k < KMAX - 3: @@ -113,24 +113,24 @@ macro double! decfloat(char[] chars, int $bits, int $emin, int sign) c = chars[++index]; } if (!got_rad) lrp = dc; - if (!got_digit) return NumberConversion.MALFORMED_FLOAT?; + if (!got_digit) return MALFORMED_FLOAT?; if ((c | 32) == 'e') { - if (last_char == index) return NumberConversion.MALFORMED_FLOAT?; - long e10 = String.to_long((String)chars[index + 1..]) ?? NumberConversion.MALFORMED_FLOAT?!; + if (last_char == index) return MALFORMED_FLOAT?; + long e10 = String.to_long((String)chars[index + 1..]) ?? MALFORMED_FLOAT?!; lrp += e10; } else if (index != last_char) { - return NumberConversion.MALFORMED_FLOAT?; + return MALFORMED_FLOAT?; } // Handle zero specially to avoid nasty special cases later if (!x[0]) return sign * 0.0; // Optimize small integers (w/no exponent) and over/under-flow if (lrp == dc && dc < 10 && ($bits > 30 || (ulong)x[0] >> $bits == 0)) return sign * (double)x[0]; - if (lrp > - $emin / 2) return NumberConversion.FLOAT_OUT_OF_RANGE?; - if (lrp < $emin - 2 * math::DOUBLE_MANT_DIG) return NumberConversion.FLOAT_OUT_OF_RANGE?; + if (lrp > - $emin / 2) return FLOAT_OUT_OF_RANGE?; + if (lrp < $emin - 2 * math::DOUBLE_MANT_DIG) return FLOAT_OUT_OF_RANGE?; // Align incomplete final B1B digit if (j) @@ -320,12 +320,12 @@ macro double! decfloat(char[] chars, int $bits, int $emin, int sign) y *= 0.5; e2++; } - if (e2 + math::DOUBLE_MANT_DIG > emax || (denormal && frac)) return NumberConversion.MALFORMED_FLOAT?; + if (e2 + math::DOUBLE_MANT_DIG > emax || (denormal && frac)) return MALFORMED_FLOAT?; } return math::scalbn(y, e2); } -macro double! hexfloat(char[] chars, int $bits, int $emin, int sign) +macro double? hexfloat(char[] chars, int $bits, int $emin, int sign) { double scale = 1; uint x; @@ -351,7 +351,7 @@ macro double! hexfloat(char[] chars, int $bits, int $emin, int sign) got_rad = true; if (index == last_char) { - if (!got_digit) return NumberConversion.MALFORMED_FLOAT?; + if (!got_digit) return MALFORMED_FLOAT?; return sign * 0.0; } if (index != last_char && (c = chars[++index]) == '0') @@ -369,7 +369,7 @@ macro double! hexfloat(char[] chars, int $bits, int $emin, int sign) { if (c == '.') { - if (got_rad) return NumberConversion.MALFORMED_FLOAT?; + if (got_rad) return MALFORMED_FLOAT?; got_rad = true; rp = dc; } @@ -393,20 +393,20 @@ macro double! hexfloat(char[] chars, int $bits, int $emin, int sign) if (index == last_char) break; c = chars[++index]; } - if (!got_digit) return NumberConversion.MALFORMED_FLOAT?; + if (!got_digit) return MALFORMED_FLOAT?; if (!got_rad) rp = dc; for (; dc < 8; dc++) x *= 16; long e2; if ((c | 32) == 'p') { - long e2val = String.to_long((String)chars[index + 1..]) ?? (NumberConversion.MALFORMED_FLOAT?)!; + long e2val = String.to_long((String)chars[index + 1..]) ?? (MALFORMED_FLOAT?)!; e2 = e2val; } e2 += 4 * rp - 32; if (!x) return sign * 0.0; - if (e2 > -$emin) return NumberConversion.FLOAT_OUT_OF_RANGE?; - if (e2 < $emin - 2 * math::DOUBLE_MANT_DIG) return NumberConversion.FLOAT_OUT_OF_RANGE?; + if (e2 > -$emin) return FLOAT_OUT_OF_RANGE?; + if (e2 < $emin - 2 * math::DOUBLE_MANT_DIG) return FLOAT_OUT_OF_RANGE?; while (x < 0x80000000) { @@ -441,7 +441,7 @@ macro double! hexfloat(char[] chars, int $bits, int $emin, int sign) } y = bias + sign * (double)x + sign * y; y -= bias; - if (!y) return NumberConversion.FLOAT_OUT_OF_RANGE?; + if (!y) return FLOAT_OUT_OF_RANGE?; return math::scalbn(y, (int)e2); } @@ -463,7 +463,7 @@ macro String.to_real(chars, $Type) @private $endswitch while (chars.len && chars[0] == ' ') chars = chars[1..]; - if (!chars.len) return NumberConversion.MALFORMED_FLOAT?; + if (!chars.len) return MALFORMED_FLOAT?; if (chars.len != 1) { diff --git a/lib/std/core/test.c3 b/lib/std/core/test.c3 index d3d5fe19f..7103c610f 100644 --- a/lib/std/core/test.c3 +++ b/lib/std/core/test.c3 @@ -13,13 +13,13 @@ fault MathError DIVISION_BY_ZERO } -fn double! divide(int a, int b) +fn double? divide(int a, int b) { if (b == 0) return MathError.DIVISION_BY_ZERO?; return (double)(a) / (double)(b); } -fn void! test_div() @test +fn void? test_div() @test { test::eq(2, divide(6, 3)!); test::ne(1, 2); diff --git a/lib/std/core/types.c3 b/lib/std/core/types.c3 index c90f75a59..e5a4d891b 100644 --- a/lib/std/core/types.c3 +++ b/lib/std/core/types.c3 @@ -3,11 +3,7 @@ module std::core::types; import libc; -fault ConversionResult -{ - VALUE_OUT_OF_RANGE, - VALUE_OUT_OF_UNSIGNED_RANGE, -} +fault VALUE_OUT_OF_RANGE, VALUE_OUT_OF_UNSIGNED_RANGE; <* @require $Type.kindof.is_int() : "Type was not an integer" @@ -33,47 +29,47 @@ macro any_to_int(any v, $Type) { case ichar: ichar c = *(char*)v.ptr; - if (is_mixed_signed && c < 0) return ConversionResult.VALUE_OUT_OF_UNSIGNED_RANGE?; + if (is_mixed_signed && c < 0) return VALUE_OUT_OF_UNSIGNED_RANGE?; return ($Type)c; case short: short s = *(short*)v.ptr; - if (is_mixed_signed && s < 0) return ConversionResult.VALUE_OUT_OF_UNSIGNED_RANGE?; - if (s > max || s < min) return ConversionResult.VALUE_OUT_OF_RANGE?; + if (is_mixed_signed && s < 0) return VALUE_OUT_OF_UNSIGNED_RANGE?; + if (s > max || s < min) return VALUE_OUT_OF_RANGE?; return ($Type)s; case int: int i = *(int*)v.ptr; - if (is_mixed_signed && i < 0) return ConversionResult.VALUE_OUT_OF_UNSIGNED_RANGE?; - if (i > max || i < min) return ConversionResult.VALUE_OUT_OF_RANGE?; + if (is_mixed_signed && i < 0) return VALUE_OUT_OF_UNSIGNED_RANGE?; + if (i > max || i < min) return VALUE_OUT_OF_RANGE?; return ($Type)i; case long: long l = *(long*)v.ptr; - if (is_mixed_signed && l < 0) return ConversionResult.VALUE_OUT_OF_UNSIGNED_RANGE?; - if (l > max || l < min) return ConversionResult.VALUE_OUT_OF_RANGE?; + if (is_mixed_signed && l < 0) return VALUE_OUT_OF_UNSIGNED_RANGE?; + if (l > max || l < min) return VALUE_OUT_OF_RANGE?; return ($Type)l; case int128: int128 i = *(int128*)v.ptr; - if (is_mixed_signed && i < 0) return ConversionResult.VALUE_OUT_OF_UNSIGNED_RANGE?; - if (i > max || i < min) return ConversionResult.VALUE_OUT_OF_RANGE?; + if (is_mixed_signed && i < 0) return VALUE_OUT_OF_UNSIGNED_RANGE?; + if (i > max || i < min) return VALUE_OUT_OF_RANGE?; return ($Type)i; case char: char c = *(char*)v.ptr; - if (c > max) return ConversionResult.VALUE_OUT_OF_RANGE?; + if (c > max) return VALUE_OUT_OF_RANGE?; return ($Type)c; case ushort: ushort s = *(ushort*)v.ptr; - if (s > max || s < min) return ConversionResult.VALUE_OUT_OF_RANGE?; + if (s > max || s < min) return VALUE_OUT_OF_RANGE?; return ($Type)s; case uint: uint i = *(uint*)v.ptr; - if (i > max || i < min) return ConversionResult.VALUE_OUT_OF_RANGE?; + if (i > max || i < min) return VALUE_OUT_OF_RANGE?; return ($Type)i; case ulong: ulong l = *(ulong*)v.ptr; - if (l > max || l < min) return ConversionResult.VALUE_OUT_OF_RANGE?; + if (l > max || l < min) return VALUE_OUT_OF_RANGE?; return ($Type)l; case uint128: uint128 i = *(uint128*)v.ptr; - if (i > max || i < min) return ConversionResult.VALUE_OUT_OF_RANGE?; + if (i > max || i < min) return VALUE_OUT_OF_RANGE?; return ($Type)i; default: unreachable(); @@ -363,7 +359,6 @@ enum TypeKind : char ANYFAULT, ANY, ENUM, - FAULT, STRUCT, UNION, BITSTRUCT, diff --git a/lib/std/encoding/base32.c3 b/lib/std/encoding/base32.c3 index 9a2e949c8..7a9296196 100644 --- a/lib/std/encoding/base32.c3 +++ b/lib/std/encoding/base32.c3 @@ -20,7 +20,7 @@ const char DEFAULT_PAD = '='; @require padding < 0xFF : "Invalid padding character" @return "The encoded string." *> -fn String! encode(Allocator allocator, char[] src, char padding = DEFAULT_PAD, Base32Alphabet* alphabet = &STANDARD) +fn String? encode(Allocator allocator, char[] src, char padding = DEFAULT_PAD, Base32Alphabet* alphabet = &STANDARD) { char[] dst = allocator::alloc_array(allocator, char, encode_len(src.len, padding)); return encode_buffer(src, dst, padding, alphabet); @@ -34,14 +34,14 @@ fn String! encode(Allocator allocator, char[] src, char padding = DEFAULT_PAD, B @require padding < 0xFF : "Invalid padding character" @return "The decoded data." *> -fn char[]! decode(Allocator allocator, char[] src, char padding = DEFAULT_PAD, Base32Alphabet* alphabet = &STANDARD) +fn char[]? decode(Allocator allocator, char[] src, char padding = DEFAULT_PAD, Base32Alphabet* alphabet = &STANDARD) { char[] dst = allocator::alloc_array(allocator, char, decode_len(src.len, padding)); return decode_buffer(src, dst, padding, alphabet); } -fn String! tencode(char[] code, char padding = DEFAULT_PAD, Base32Alphabet* alphabet = &STANDARD) @inline => encode(tmem(), code, padding, alphabet); -fn char[]! tdecode(char[] code, char padding = DEFAULT_PAD, Base32Alphabet* alphabet = &STANDARD) @inline => decode(tmem(), code, padding, alphabet); +fn String? tencode(char[] code, char padding = DEFAULT_PAD, Base32Alphabet* alphabet = &STANDARD) @inline => encode(tmem(), code, padding, alphabet); +fn char[]? tdecode(char[] code, char padding = DEFAULT_PAD, Base32Alphabet* alphabet = &STANDARD) @inline => decode(tmem(), code, padding, alphabet); <* Calculate the length in bytes of the decoded data. @@ -84,9 +84,9 @@ fn usz encode_len(usz n, char padding) @require padding < 0xFF : "Invalid padding character" @require dst.len >= decode_len(src.len, padding) : "Destination buffer too small" @return "The resulting dst buffer" - @return! DecodingFailure + @return! encoding::INVALID_PADDING, encoding::INVALID_CHARACTER *> -fn char[]! decode_buffer(char[] src, char[] dst, char padding = DEFAULT_PAD, Base32Alphabet* alphabet = &STANDARD) +fn char[]? decode_buffer(char[] src, char[] dst, char padding = DEFAULT_PAD, Base32Alphabet* alphabet = &STANDARD) { if (src.len == 0) return dst[:0]; char* dst_ptr = dst; @@ -101,12 +101,12 @@ fn char[]! decode_buffer(char[] src, char[] dst, char padding = DEFAULT_PAD, Bas { if (src.len == 0) { - if (padding > 0) return DecodingFailure.INVALID_PADDING?; + if (padding > 0) return encoding::INVALID_PADDING?; break; } if (src[0] == padding) break; buf[i] = alphabet.reverse[src[0]]; - if (buf[i] == INVALID) return DecodingFailure.INVALID_CHARACTER?; + if (buf[i] == INVALID) return encoding::INVALID_CHARACTER?; src = src[1..]; } @@ -150,7 +150,7 @@ fn char[]! decode_buffer(char[] src, char[] dst, char padding = DEFAULT_PAD, Bas dst[0] = buf[1] >> 2 | buf[0] << 3; n++; default: - return DecodingFailure.INVALID_CHARACTER?; + return encoding::INVALID_CHARACTER?; } if (dst.len < 5) break; dst = dst[5..]; diff --git a/lib/std/encoding/base64.c3 b/lib/std/encoding/base64.c3 index bf600ba34..e5e8c64e1 100644 --- a/lib/std/encoding/base64.c3 +++ b/lib/std/encoding/base64.c3 @@ -49,14 +49,14 @@ fn String encode(Allocator allocator, char[] src, char padding = DEFAULT_PAD, Ba return encode_buffer(src, dst, padding, alphabet); } -fn char[]! decode(Allocator allocator, char[] src, char padding = DEFAULT_PAD, Base64Alphabet* alphabet = &STANDARD) +fn char[]? decode(Allocator allocator, char[] src, char padding = DEFAULT_PAD, Base64Alphabet* alphabet = &STANDARD) { char[] dst = allocator::alloc_array(allocator, char, decode_len(src.len, padding))!; return decode_buffer(src, dst, padding, alphabet); } fn String tencode(char[] code, char padding = DEFAULT_PAD, Base64Alphabet* alphabet = &STANDARD) @inline => encode(tmem(), code, padding, alphabet); -fn char[]! tdecode(char[] code, char padding = DEFAULT_PAD, Base64Alphabet* alphabet = &STANDARD) @inline => decode(tmem(), code, padding, alphabet); +fn char[]? tdecode(char[] code, char padding = DEFAULT_PAD, Base64Alphabet* alphabet = &STANDARD) @inline => decode(tmem(), code, padding, alphabet); <* @@ -79,19 +79,19 @@ fn usz encode_len(usz n, char padding) @param padding : "The padding character or 0 if none" @require padding < 0xFF : "Invalid padding character" @return "The size of the input once decoded." - @return! DecodingFailure.INVALID_PADDING + @return! encoding::INVALID_PADDING *> -fn usz! decode_len(usz n, char padding) +fn usz? decode_len(usz n, char padding) { usz dn = n / 4 * 3; usz trailing = n % 4; if (padding) { - if (trailing != 0) return DecodingFailure.INVALID_PADDING?; + if (trailing != 0) return encoding::INVALID_PADDING?; // source size is multiple of 4 return dn; } - if (trailing == 1) return DecodingFailure.INVALID_PADDING?; + if (trailing == 1) return encoding::INVALID_PADDING?; return dn + trailing * 3 / 4; } @@ -163,9 +163,9 @@ fn String encode_buffer(char[] src, char[] dst, char padding = DEFAULT_PAD, Base @require (decode_len(src.len, padding) ?? 0) <= dst.len : "Destination buffer too small" @require padding < 0xFF : "Invalid padding character" @return "The decoded data." - @return! DecodingFailure + @return! encoding::INVALID_CHARACTER, encoding::INVALID_PADDING *> -fn char[]! decode_buffer(char[] src, char[] dst, char padding = DEFAULT_PAD, Base64Alphabet* alphabet = &STANDARD) +fn char[]? decode_buffer(char[] src, char[] dst, char padding = DEFAULT_PAD, Base64Alphabet* alphabet = &STANDARD) { if (src.len == 0) return dst[:0]; usz dn = decode_len(src.len, padding)!; @@ -196,7 +196,7 @@ fn char[]! decode_buffer(char[] src, char[] dst, char padding = DEFAULT_PAD, Bas case c1: case c2: case c3: - return DecodingFailure.INVALID_CHARACTER?; + return encoding::INVALID_CHARACTER?; } uint group = (uint)c0 << 18 | (uint)c1 << 12 | (uint)c2 << 6 | (uint)c3; dst[0] = (char)(group >> 16); @@ -211,7 +211,7 @@ fn char[]! decode_buffer(char[] src, char[] dst, char padding = DEFAULT_PAD, Bas src = src[^trailing..]; char c0 = alphabet.reverse[src[0]]; char c1 = alphabet.reverse[src[1]]; - if (c0 == 0xFF || c1 == 0xFF) return DecodingFailure.INVALID_PADDING?; + if (c0 == 0xFF || c1 == 0xFF) return encoding::INVALID_PADDING?; if (!padding) { switch (src.len) @@ -221,7 +221,7 @@ fn char[]! decode_buffer(char[] src, char[] dst, char padding = DEFAULT_PAD, Bas dst[0] = (char)(group >> 16); case 3: char c2 = alphabet.reverse[src[2]]; - if (c2 == 0xFF) return DecodingFailure.INVALID_CHARACTER?; + if (c2 == 0xFF) return encoding::INVALID_CHARACTER?; uint group = (uint)c0 << 18 | (uint)c1 << 12 | (uint)c2 << 6; dst[0] = (char)(group >> 16); dst[1] = (char)(group >> 8); @@ -235,13 +235,13 @@ fn char[]! decode_buffer(char[] src, char[] dst, char padding = DEFAULT_PAD, Bas switch (padding) { case src[2]: - if (src[3] != padding) return DecodingFailure.INVALID_PADDING?; + if (src[3] != padding) return encoding::INVALID_PADDING?; uint group = (uint)c0 << 18 | (uint)c1 << 12; dst[0] = (char)(group >> 16); dn -= 2; case src[3]: char c2 = alphabet.reverse[src[2]]; - if (c2 == 0xFF) return DecodingFailure.INVALID_CHARACTER?; + if (c2 == 0xFF) return encoding::INVALID_CHARACTER?; uint group = (uint)c0 << 18 | (uint)c1 << 12 | (uint)c2 << 6; dst[0] = (char)(group >> 16); dst[1] = (char)(group >> 8); diff --git a/lib/std/encoding/csv.c3 b/lib/std/encoding/csv.c3 index 4d82cb125..c60ef8179 100644 --- a/lib/std/encoding/csv.c3 +++ b/lib/std/encoding/csv.c3 @@ -15,7 +15,7 @@ struct CsvRow (Printable) Allocator allocator; } -fn usz! CsvRow.to_format(&self, Formatter* f) @dynamic +fn usz? CsvRow.to_format(&self, Formatter* f) @dynamic { return f.printf("%s", self.list); } @@ -41,7 +41,7 @@ fn void CsvReader.init(&self, InStream stream, String separator = ",") <* @param [&inout] allocator *> -fn CsvRow! CsvReader.read_row(self, Allocator allocator) +fn CsvRow? CsvReader.read_row(self, Allocator allocator) { String row = io::readline(allocator, self.stream)!; defer catch allocator::free(allocator, row); @@ -49,7 +49,7 @@ fn CsvRow! CsvReader.read_row(self, Allocator allocator) return { list, row, allocator }; } -fn CsvRow! CsvReader.tread_row(self) +fn CsvRow? CsvReader.tread_row(self) { return self.read_row(tmem()) @inline; } @@ -64,12 +64,12 @@ fn void CsvRow.free(&self) self.allocator = null; } -fn void! CsvReader.skip_row(self) @maydiscard => @pool() +fn void? CsvReader.skip_row(self) @maydiscard => @pool() { (void)io::treadline(self.stream); } -macro void! CsvReader.@each_row(self, int rows = int.max; @body(String[] row)) @maydiscard +macro void? CsvReader.@each_row(self, int rows = int.max; @body(String[] row)) @maydiscard { InStream stream = self.stream; String sep = self.separator; @@ -77,10 +77,10 @@ macro void! CsvReader.@each_row(self, int rows = int.max; @body(String[] row)) @ { @stack_mem(512; Allocator mem) { - String! s = io::readline(mem, stream); + String? s = io::readline(mem, stream); if (catch err = s) { - if (err == IoError.EOF) return; + if (err == io::EOF) return; return err?; } @body(s.split(mem, sep)); diff --git a/lib/std/encoding/encoding.c3 b/lib/std/encoding/encoding.c3 index b81b4e945..e94d34f04 100644 --- a/lib/std/encoding/encoding.c3 +++ b/lib/std/encoding/encoding.c3 @@ -1,7 +1,3 @@ module std::encoding; -fault DecodingFailure -{ - INVALID_CHARACTER, - INVALID_PADDING, -} \ No newline at end of file +fault INVALID_CHARACTER, INVALID_PADDING; \ No newline at end of file diff --git a/lib/std/encoding/hex.c3 b/lib/std/encoding/hex.c3 index 1d31d6583..be6b24d79 100644 --- a/lib/std/encoding/hex.c3 +++ b/lib/std/encoding/hex.c3 @@ -8,7 +8,7 @@ fn String encode_buffer(char[] code, char[] buffer) return (String)buffer[:encode_bytes(code, buffer)]; } -fn char[]! decode_buffer(char[] code, char[] buffer) +fn char[]? decode_buffer(char[] code, char[] buffer) { return buffer[:decode_bytes(code, buffer)!]; } @@ -19,14 +19,14 @@ fn String encode(Allocator allocator, char[] code) return (String)data[:encode_bytes(code, data)]; } -fn char[]! decode(Allocator allocator, char[] code) +fn char[]? decode(Allocator allocator, char[] code) { char[] data = allocator::alloc_array(allocator, char, decode_len(code.len)); return data[:decode_bytes(code, data)!]; } fn String tencode(char[] code) @inline => encode(tmem(), code); -fn char[]! tdecode(char[] code) @inline => decode(tmem(), code); +fn char[]? tdecode(char[] code) @inline => decode(tmem(), code); <* @@ -72,24 +72,24 @@ macro usz decode_len(usz n) => n / 2; @param dst : "The decoded input." @require src.len % 2 == 0 : "src is not of even length" @require dst.len >= decode_len(src.len) : "Destination array is not large enough" - @return! DecodingFailure.INVALID_CHARACTER + @return! encoding::INVALID_CHARACTER *> -fn usz! decode_bytes(char[] src, char[] dst) +fn usz? decode_bytes(char[] src, char[] dst) { usz i; for (usz j = 1; j < src.len; j += 2) { char a = HEXREVERSE[src[j - 1]]; char b = HEXREVERSE[src[j]]; - if (a > 0x0f || b > 0x0f) return DecodingFailure.INVALID_CHARACTER?; + if (a > 0x0f || b > 0x0f) return encoding::INVALID_CHARACTER?; dst[i] = (a << 4) | b; i++; } return i; } -const char[?] HEXALPHABET @private = "0123456789abcdef"; -const char[?] HEXREVERSE @private = +const char[*] HEXALPHABET @private = "0123456789abcdef"; +const char[*] HEXREVERSE @private = x`ffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffff diff --git a/lib/std/encoding/json.c3 b/lib/std/encoding/json.c3 index b5129808d..265641c47 100644 --- a/lib/std/encoding/json.c3 +++ b/lib/std/encoding/json.c3 @@ -6,26 +6,19 @@ import std::io; import std::ascii; import std::collections::object; -fault JsonParsingError -{ - EOF, - UNEXPECTED_CHARACTER, - INVALID_ESCAPE_SEQUENCE, - DUPLICATE_MEMBERS, - INVALID_NUMBER, -} +fault UNEXPECTED_CHARACTER, INVALID_ESCAPE_SEQUENCE, DUPLICATE_MEMBERS, INVALID_NUMBER; -fn Object*! parse_string(Allocator allocator, String s) +fn Object*? parse_string(Allocator allocator, String s) { return parse(allocator, (ByteReader){}.init(s)); } -fn Object*! tparse_string(String s) +fn Object*? tparse_string(String s) { return parse(tmem(), (ByteReader){}.init(s)); } -fn Object*! parse(Allocator allocator, InStream s) +fn Object*? parse(Allocator allocator, InStream s) { @stack_mem(512; Allocator smem) { @@ -37,7 +30,7 @@ fn Object*! parse(Allocator allocator, InStream s) }; } -fn Object*! tparse(InStream s) +fn Object*? tparse(InStream s) { return parse(tmem(), s); } @@ -78,7 +71,7 @@ struct JsonContext @local } -fn Object*! parse_from_token(JsonContext* context, JsonTokenType token) @local +fn Object*? parse_from_token(JsonContext* context, JsonTokenType token) @local { switch (token) { @@ -88,21 +81,21 @@ fn Object*! parse_from_token(JsonContext* context, JsonTokenType token) @local case COMMA: case RBRACE: case RBRACKET: - case COLON: return JsonParsingError.UNEXPECTED_CHARACTER?; + case COLON: return UNEXPECTED_CHARACTER?; case STRING: return object::new_string(context.last_string.str_view(), context.allocator); case NUMBER: return object::new_float(context.last_number, context.allocator); case TRUE: return object::new_bool(true); case FALSE: return object::new_bool(false); case NULL: return object::new_null(); - case EOF: return JsonParsingError.EOF?; + case EOF: return io::EOF?; } } -fn Object*! parse_any(JsonContext* context) @local +fn Object*? parse_any(JsonContext* context) @local { return parse_from_token(context, advance(context)); } -fn JsonTokenType! lex_number(JsonContext *context, char c) @local +fn JsonTokenType? lex_number(JsonContext *context, char c) @local { @stack_mem(256; Allocator mem) { @@ -137,7 +130,7 @@ fn JsonTokenType! lex_number(JsonContext *context, char c) @local t.append(c); c = read_next(context)!; } - if (!c.is_digit()) return JsonParsingError.INVALID_NUMBER?; + if (!c.is_digit()) return INVALID_NUMBER?; while (c.is_digit()) { t.append(c); @@ -145,13 +138,13 @@ fn JsonTokenType! lex_number(JsonContext *context, char c) @local } } pushback(context, c); - double! d = t.str_view().to_double() ?? JsonParsingError.INVALID_NUMBER?; + double? d = t.str_view().to_double() ?? INVALID_NUMBER?; context.last_number = d!; return NUMBER; }; } -fn Object*! parse_map(JsonContext* context) @local +fn Object*? parse_map(JsonContext* context) @local { Object* map = object::new_obj(context.allocator); defer catch map.free(); @@ -162,9 +155,9 @@ fn Object*! parse_map(JsonContext* context) @local DString temp_key = dstring::new_with_capacity(mem, 32); while (token != JsonTokenType.RBRACE) { - if (token != JsonTokenType.STRING) return JsonParsingError.UNEXPECTED_CHARACTER?; + if (token != JsonTokenType.STRING) return UNEXPECTED_CHARACTER?; DString string = context.last_string; - if (map.has_key(string.str_view())) return JsonParsingError.DUPLICATE_MEMBERS?; + if (map.has_key(string.str_view())) return DUPLICATE_MEMBERS?; // Copy the key to our temp holder, since our // last_string may be used in parse_any temp_key.clear(); @@ -178,13 +171,13 @@ fn Object*! parse_map(JsonContext* context) @local token = advance(context)!; continue; } - if (token != JsonTokenType.RBRACE) return JsonParsingError.UNEXPECTED_CHARACTER?; + if (token != JsonTokenType.RBRACE) return UNEXPECTED_CHARACTER?; } return map; }; } -fn Object*! parse_array(JsonContext* context) @local +fn Object*? parse_array(JsonContext* context) @local { Object* list = object::new_obj(context.allocator); defer catch list.free(); @@ -199,7 +192,7 @@ fn Object*! parse_array(JsonContext* context) @local token = advance(context)!; continue; } - if (token != JsonTokenType.RBRACKET) return JsonParsingError.UNEXPECTED_CHARACTER?; + if (token != JsonTokenType.RBRACKET) return UNEXPECTED_CHARACTER?; } return list; } @@ -214,7 +207,7 @@ fn void pushback(JsonContext* context, char c) @local } } -fn char! read_next(JsonContext* context) @local +fn char? read_next(JsonContext* context) @local { if (context.reached_end) return '\0'; if (context.pushed_back) @@ -222,10 +215,10 @@ fn char! read_next(JsonContext* context) @local context.pushed_back = false; return context.current; } - char! c = context.stream.read_byte(); + char? c = context.stream.read_byte(); if (catch err = c) { - if (err == IoError.EOF) + if (err == io::EOF) { context.reached_end = true; return '\0'; @@ -239,7 +232,7 @@ fn char! read_next(JsonContext* context) @local return c; } -fn JsonTokenType! advance(JsonContext* context) @local +fn JsonTokenType? advance(JsonContext* context) @local { char c; // Skip whitespace @@ -287,7 +280,7 @@ fn JsonTokenType! advance(JsonContext* context) @local switch (c) { case '\0': - return IoError.EOF?; + return io::EOF?; case '{': return LBRACE; case '}': @@ -315,25 +308,25 @@ fn JsonTokenType! advance(JsonContext* context) @local match(context, "ull")!; return NULL; default: - return JsonParsingError.UNEXPECTED_CHARACTER?; + return UNEXPECTED_CHARACTER?; } } -fn void! match(JsonContext* context, String str) @local +fn void? match(JsonContext* context, String str) @local { foreach (c : str) { char l = read_next(context)!; - if (l != c) return JsonParsingError.UNEXPECTED_CHARACTER?; + if (l != c) return UNEXPECTED_CHARACTER?; } } -fn void! parse_expected(JsonContext* context, JsonTokenType token) @local +fn void? parse_expected(JsonContext* context, JsonTokenType token) @local { - if (advance(context)! != token) return JsonParsingError.UNEXPECTED_CHARACTER?; + if (advance(context)! != token) return UNEXPECTED_CHARACTER?; } -fn JsonTokenType! lex_string(JsonContext* context) +fn JsonTokenType? lex_string(JsonContext* context) { context.last_string.clear(); while LOOP: (true) @@ -342,9 +335,9 @@ fn JsonTokenType! lex_string(JsonContext* context) switch (c) { case '\0': - return JsonParsingError.EOF?; + return io::EOF?; case 1..31: - return JsonParsingError.UNEXPECTED_CHARACTER?; + return UNEXPECTED_CHARACTER?; case '"': break LOOP; case '\\': @@ -357,9 +350,9 @@ fn JsonTokenType! lex_string(JsonContext* context) switch (c) { case '\0': - return JsonParsingError.EOF?; + return io::EOF?; case 1..31: - return JsonParsingError.UNEXPECTED_CHARACTER?; + return UNEXPECTED_CHARACTER?; case '"': case '\\': case '/': @@ -379,13 +372,13 @@ fn JsonTokenType! lex_string(JsonContext* context) for (int i = 0; i < 4; i++) { c = read_next(context)!; - if (!c.is_xdigit()) return JsonParsingError.INVALID_ESCAPE_SEQUENCE?; + if (!c.is_xdigit()) return INVALID_ESCAPE_SEQUENCE?; val = val << 4 + (c > '9' ? (c | 32) - 'a' + 10 : c - '0'); } context.last_string.append_char32(val); continue; default: - return JsonParsingError.INVALID_ESCAPE_SEQUENCE?; + return INVALID_ESCAPE_SEQUENCE?; } context.last_string.append(c); } diff --git a/lib/std/experimental/FrameScheduler.c3 b/lib/std/experimental/FrameScheduler.c3 index c8bb7b1bf..06d497d00 100644 --- a/lib/std/experimental/FrameScheduler.c3 +++ b/lib/std/experimental/FrameScheduler.c3 @@ -71,12 +71,12 @@ fn void FrameScheduler.queue_event(&self, Event event) @atomic_store(self.pending, true); }; } -fn Event! FrameScheduler.pop_event(&self) +fn Event? FrameScheduler.pop_event(&self) { while (true) { if (try event = self.events.pop()) return event; - if (!@atomic_load(self.pending)) return IteratorResult.NO_MORE_ELEMENT?; + if (!@atomic_load(self.pending)) return NO_MORE_ELEMENT?; self.mtx.@in_lock() { self.events.add_all(&self.pending_events); @@ -88,7 +88,7 @@ fn Event! FrameScheduler.pop_event(&self) self.events.push(self.delayed_events.pop()!!); } @atomic_store(self.pending, self.delayed_events.len() > 0); - if (!self.events.len()) return IteratorResult.NO_MORE_ELEMENT?; + if (!self.events.len()) return NO_MORE_ELEMENT?; }; } } diff --git a/lib/std/io/bits.c3 b/lib/std/io/bits.c3 index 653869979..dd4c9c81e 100644 --- a/lib/std/io/bits.c3 +++ b/lib/std/io/bits.c3 @@ -21,7 +21,7 @@ fn void BitReader.clear(&self) @inline @require nbits <= 8 @require self.len + nbits <= uint.sizeof * 8 *> -fn char! BitReader.read_bits(&self, uint nbits) +fn char? BitReader.read_bits(&self, uint nbits) { uint bits = self.bits; if (self.len < nbits) @@ -54,7 +54,7 @@ fn void BitWriter.init(&self, OutStream byte_writer) *self = { .writer = byte_writer }; } -fn void! BitWriter.flush(&self) +fn void? BitWriter.flush(&self) { if (self.len == 0) return; @@ -70,7 +70,7 @@ fn void! BitWriter.flush(&self) <* @require nbits <= 32 *> -fn void! BitWriter.write_bits(&self, uint bits, uint nbits) +fn void? BitWriter.write_bits(&self, uint bits, uint nbits) { if (nbits == 0) return; while (self.len + nbits > WRITER_BITS) diff --git a/lib/std/io/file.c3 b/lib/std/io/file.c3 index e27626f77..8ada06d3d 100644 --- a/lib/std/io/file.c3 +++ b/lib/std/io/file.c3 @@ -9,12 +9,12 @@ struct File (InStream, OutStream) module std::io::file; import libc, std::io::path, std::io::os; -fn File! open(String filename, String mode) +fn File? open(String filename, String mode) { return from_handle(os::native_fopen(filename, mode)); } -fn File! open_path(Path path, String mode) +fn File? open_path(Path path, String mode) { return from_handle(os::native_fopen(path.str_view(), mode)); } @@ -39,12 +39,12 @@ fn bool is_dir(String path) return os::native_is_dir(path); } -fn usz! get_size(String path) +fn usz? get_size(String path) { return os::native_file_size(path); } -fn void! delete(String filename) +fn void? delete(String filename) { return os::native_remove(filename) @inline; } @@ -53,7 +53,7 @@ fn void! delete(String filename) <* @require self.file != null *> -fn void! File.reopen(&self, String filename, String mode) +fn void? File.reopen(&self, String filename, String mode) { self.file = os::native_freopen(self.file, filename, mode)!; } @@ -61,7 +61,7 @@ fn void! File.reopen(&self, String filename, String mode) <* @require self.file != null *> -fn usz! File.seek(&self, isz offset, Seek seek_mode = Seek.SET) @dynamic +fn usz? File.seek(&self, isz offset, Seek seek_mode = Seek.SET) @dynamic { os::native_fseek(self.file, offset, seek_mode)!; return os::native_ftell(self.file); @@ -73,7 +73,7 @@ Implement later <* @require self.file == null *> -fn void! File.memopen(File* file, char[] data, String mode) +fn void? File.memopen(File* file, char[] data, String mode) { @pool() { @@ -87,7 +87,7 @@ fn void! File.memopen(File* file, char[] data, String mode) <* @require self.file != null *> -fn void! File.write_byte(&self, char c) @dynamic +fn void? File.write_byte(&self, char c) @dynamic { return os::native_fputc(c, self.file); } @@ -95,15 +95,15 @@ fn void! File.write_byte(&self, char c) @dynamic <* @param [&inout] self *> -fn void! File.close(&self) @inline @dynamic +fn void? File.close(&self) @inline @dynamic { if (self.file && libc::fclose(self.file)) { switch (libc::errno()) { case errno::ECONNRESET: - case errno::EBADF: return IoError.FILE_NOT_VALID?; - case errno::EINTR: return IoError.INTERRUPTED?; + case errno::EBADF: return io::FILE_NOT_VALID?; + case errno::EINTR: return io::INTERRUPTED?; case errno::EDQUOT: case errno::EFAULT: case errno::EAGAIN: @@ -111,8 +111,8 @@ fn void! File.close(&self) @inline @dynamic case errno::ENETDOWN: case errno::ENETUNREACH: case errno::ENOSPC: - case errno::EIO: return IoError.INCOMPLETE_WRITE?; - default: return IoError.UNKNOWN_ERROR?; + case errno::EIO: return io::INCOMPLETE_WRITE?; + default: return io::UNKNOWN_ERROR?; } } self.file = null; @@ -129,7 +129,7 @@ fn bool File.eof(&self) @inline <* @param [in] buffer *> -fn usz! File.read(&self, char[] buffer) @dynamic +fn usz? File.read(&self, char[] buffer) @dynamic { return os::native_fread(self.file, buffer); } @@ -138,7 +138,7 @@ fn usz! File.read(&self, char[] buffer) @dynamic @param [out] buffer @require self.file != null : `File must be initialized` *> -fn usz! File.write(&self, char[] buffer) @dynamic +fn usz? File.write(&self, char[] buffer) @dynamic { return os::native_fwrite(self.file, buffer); } @@ -153,26 +153,26 @@ fn bool File.isatty(self) @if(env::LIBC) return libc::isatty(self.fd()) > 0; } -fn char! File.read_byte(&self) @dynamic +fn char? File.read_byte(&self) @dynamic { int c = libc::fgetc(self.file); - if (c == -1) return IoError.EOF?; + if (c == -1) return io::EOF?; return (char)c; } <* - Load up to buffer.len characters. Returns IoError.OVERFLOW if the file is longer + Load up to buffer.len characters. Returns io::OVERFLOW if the file is longer than the buffer. @param filename : "The path to the file to read" @param [in] buffer : "The buffer to read to" *> -fn char[]! load_buffer(String filename, char[] buffer) +fn char[]? load_buffer(String filename, char[] buffer) { File file = open(filename, "rb")!; defer (void)file.close(); usz len = file.seek(0, END)!; - if (len > buffer.len) return IoError.OVERFLOW?; + if (len > buffer.len) return io::OVERFLOW?; file.seek(0, SET)!; usz read = 0; while (read < len) @@ -183,9 +183,9 @@ fn char[]! load_buffer(String filename, char[] buffer) } -fn char[]! load(Allocator allocator, String filename) => load_new(filename, allocator); +fn char[]? load(Allocator allocator, String filename) => load_new(filename, allocator); -fn char[]! load_new(String filename, Allocator allocator = allocator::heap()) +fn char[]? load_new(String filename, Allocator allocator = allocator::heap()) { File file = open(filename, "rb")!; defer (void)file.close(); @@ -201,16 +201,16 @@ fn char[]! load_new(String filename, Allocator allocator = allocator::heap()) return data[:len]; } -fn char[]! load_path_new(Path path, Allocator allocator = allocator::heap()) => load_new(path.str_view(), allocator); +fn char[]? load_path_new(Path path, Allocator allocator = allocator::heap()) => load_new(path.str_view(), allocator); -fn char[]! load_temp(String filename) +fn char[]? load_temp(String filename) { return load_new(filename, allocator::temp()); } -fn char[]! load_path_temp(Path path) => load_temp(path.str_view()); +fn char[]? load_path_temp(Path path) => load_temp(path.str_view()); -fn void! save(String filename, char[] data) +fn void? save(String filename, char[] data) { File file = open(filename, "wb")!; defer (void)file.close(); @@ -224,7 +224,7 @@ fn void! save(String filename, char[] data) <* @require self.file != null : `File must be initialized` *> -fn void! File.flush(&self) @dynamic +fn void? File.flush(&self) @dynamic { libc::fflush(self.file); } diff --git a/lib/std/io/formatter.c3 b/lib/std/io/formatter.c3 index 052a0d9c9..876c51b8f 100644 --- a/lib/std/io/formatter.c3 +++ b/lib/std/io/formatter.c3 @@ -7,19 +7,13 @@ const int PRINTF_NTOA_BUFFER_SIZE = 256; interface Printable { fn String to_constant_string() @optional; - fn usz! to_format(Formatter* formatter) @optional; + fn usz? to_format(Formatter* formatter) @optional; } -fault PrintFault -{ - BUFFER_EXCEEDED, - INTERNAL_BUFFER_EXCEEDED, - INVALID_FORMAT, - NOT_ENOUGH_ARGUMENTS, - INVALID_ARGUMENT, -} +fault BUFFER_EXCEEDED, INTERNAL_BUFFER_EXCEEDED, INVALID_FORMAT, NOT_ENOUGH_ARGUMENTS, + INVALID_ARGUMENT; -def OutputFn = fn void!(void* buffer, char c); +def OutputFn = fn void?(void* buffer, char c); def FloatType = double; @@ -35,7 +29,7 @@ macro bool is_struct_with_default_print($Type) @require @typekind(value) == STRUCT : `This macro is only valid on macros` *> -macro usz! struct_to_format(value, Formatter* f, bool $force_dump) +macro usz? struct_to_format(value, Formatter* f, bool $force_dump) { var $Type = $typeof(value); usz total = f.print("{ ")!; @@ -56,12 +50,12 @@ macro usz! struct_to_format(value, Formatter* f, bool $force_dump) return total + f.print(" }"); } -fn usz! ReflectedParam.to_format(&self, Formatter* f) @dynamic +fn usz? ReflectedParam.to_format(&self, Formatter* f) @dynamic { return f.printf("[Parameter '%s']", self.name); } -fn usz! Formatter.printf(&self, String format, args...) +fn usz? Formatter.printf(&self, String format, args...) { return self.vprintf(format, args) @inline; } @@ -96,7 +90,7 @@ fn void Formatter.init(&self, OutputFn out_fn, void* data = null) *self = { .data = data, .out_fn = out_fn}; } -fn usz! Formatter.out(&self, char c) @private +fn usz? Formatter.out(&self, char c) @private { if (catch err = self.out_fn(self.data, c)) { @@ -107,7 +101,7 @@ fn usz! Formatter.out(&self, char c) @private return 1; } -fn usz! Formatter.print_with_function(&self, Printable arg) +fn usz? Formatter.print_with_function(&self, Printable arg) { if (&arg.to_format) { @@ -137,14 +131,14 @@ fn usz! Formatter.print_with_function(&self, Printable arg) if (!arg) return self.out_substr("(null)"); return self.out_substr(arg.to_constant_string()); } - return SearchResult.MISSING?; + return NOT_FOUND?; } -fn usz! Formatter.out_unknown(&self, String category, any arg) @private +fn usz? Formatter.out_unknown(&self, String category, any arg) @private { return self.out_substr("[") + self.out_substr(category) + self.out_substr(" type:") + self.ntoa((iptr)arg.type, false, 16) + self.out_substr(", addr:") + self.ntoa((iptr)arg.ptr, false, 16) + self.out_substr("]"); } -fn usz! Formatter.out_str(&self, any arg) @private +fn usz? Formatter.out_str(&self, any arg) @private { switch (arg.type.kindof) { @@ -153,7 +147,6 @@ fn usz! Formatter.out_str(&self, any arg) @private case VOID: return self.out_substr("void"); case ANYFAULT: - case FAULT: return self.out_substr((*(anyfault*)arg.ptr).nameof); case INTERFACE: case ANY: @@ -187,9 +180,9 @@ fn usz! Formatter.out_str(&self, any arg) @private return self.out_substr(*(bool*)arg.ptr ? "true" : "false"); default: } - usz! n = self.print_with_function((Printable)arg); + usz? n = self.print_with_function((Printable)arg); if (try n) return n; - if (@catch(n) != SearchResult.MISSING) n!; + if (@catch(n) != NOT_FOUND) n!; switch (arg.type.kindof) { case ENUM: @@ -226,7 +219,7 @@ fn usz! Formatter.out_str(&self, any arg) @private any deref = any_make(*pointer, inner); n = self.print_with_function((Printable)deref); if (try n) return n; - if (@catch(n) != SearchResult.MISSING) n!; + if (@catch(n) != NOT_FOUND) n!; } PrintFlags flags = self.flags; uint width = self.width; @@ -238,7 +231,7 @@ fn usz! Formatter.out_str(&self, any arg) @private self.width = 0; return self.out_substr("0x")! + self.ntoa_any(arg, 16); case ARRAY: - // this is SomeType[?] so grab the "SomeType" + // this is SomeType[*] so grab the "SomeType" PrintFlags flags = self.flags; uint width = self.width; defer @@ -272,7 +265,7 @@ fn usz! Formatter.out_str(&self, any arg) @private } self.flags = {}; self.width = 0; - // this is SomeType[?] so grab the "SomeType" + // this is SomeType[*] so grab the "SomeType" typeid inner = arg.type.inner; usz size = inner.sizeof; usz vlen = arg.type.len; @@ -325,28 +318,28 @@ fn usz! Formatter.out_str(&self, any arg) @private -fn void! out_null_fn(void* data @unused, char c @unused) @private +fn void? out_null_fn(void* data @unused, char c @unused) @private { } -macro usz! @report_fault(Formatter* f, $fault) +macro usz? @report_fault(Formatter* f, $fault) { (void)f.out_substr($fault); - return PrintFault.INVALID_FORMAT?; + return INVALID_FORMAT?; } -macro usz! @wrap_bad(Formatter* f, #action) +macro usz? @wrap_bad(Formatter* f, #action) { - usz! len = #action; + usz? len = #action; if (catch err = len) { switch (err) { - case PrintFault.BUFFER_EXCEEDED: - case PrintFault.INTERNAL_BUFFER_EXCEEDED: + case BUFFER_EXCEEDED: + case INTERNAL_BUFFER_EXCEEDED: return f.first_err(err)?; default: - err = f.first_err(PrintFault.INVALID_ARGUMENT); + err = f.first_err(INVALID_ARGUMENT); f.out_substr("")!; return err?; } @@ -354,7 +347,7 @@ macro usz! @wrap_bad(Formatter* f, #action) return len; } -fn usz! Formatter.vprintf(&self, String format, any[] anys) +fn usz? Formatter.vprintf(&self, String format, any[] anys) { self.first_fault = {}; if (!self.out_fn) @@ -400,7 +393,7 @@ fn usz! Formatter.vprintf(&self, String format, any[] anys) c = format[i]; } // evaluate width field - int! w = printf_parse_format_field(anys.ptr, anys.len, &variant_index, format.ptr, format.len, &i); + int? w = printf_parse_format_field(anys.ptr, anys.len, &variant_index, format.ptr, format.len, &i); if (catch w) return @report_fault(self, "%ERR"); c = format[i]; if (w < 0) @@ -415,7 +408,7 @@ fn usz! Formatter.vprintf(&self, String format, any[] anys) { self.flags.precision = true; if (++i >= format_len) return @report_fault(self, ""); - int! prec = printf_parse_format_field(anys.ptr, anys.len, &variant_index, format.ptr, format.len, &i); + int? prec = printf_parse_format_field(anys.ptr, anys.len, &variant_index, format.ptr, format.len, &i); if (catch prec) return @report_fault(self, ""); self.prec = prec < 0 ? 0 : prec; c = format[i]; @@ -425,7 +418,7 @@ fn usz! Formatter.vprintf(&self, String format, any[] anys) uint base = 0; if (variant_index >= anys.len) { - self.first_err(PrintFault.NOT_ENOUGH_ARGUMENTS); + self.first_err(NOT_ENOUGH_ARGUMENTS); total_len += self.out_substr("")!; continue; } @@ -532,7 +525,7 @@ fn usz! Formatter.vprintf(&self, String format, any[] anys) self.flags.hash = true; base = 16; default: - self.first_err(PrintFault.INVALID_FORMAT); + self.first_err(INVALID_FORMAT); total_len += self.out_substr("")!; continue; } @@ -556,7 +549,7 @@ fn usz! Formatter.vprintf(&self, String format, any[] anys) } -fn usz! Formatter.print(&self, String str) +fn usz? Formatter.print(&self, String str) { if (!self.out_fn) { diff --git a/lib/std/io/formatter_private.c3 b/lib/std/io/formatter_private.c3 index 608437740..399124b87 100644 --- a/lib/std/io/formatter_private.c3 +++ b/lib/std/io/formatter_private.c3 @@ -4,12 +4,9 @@ import std::math; const char[16] XDIGITS_H = "0123456789ABCDEF"; const char[16] XDIGITS_L = "0123456789abcdef"; -fault FormattingFault -{ - BAD_FORMAT -} +fault BAD_FORMAT; -fn usz! print_hex_chars(Formatter* f, char[] out, bool uppercase) @inline +fn usz? print_hex_chars(Formatter* f, char[] out, bool uppercase) @inline { char past_10 = (uppercase ? 'A' : 'a') - 10; usz len = 0; @@ -32,13 +29,13 @@ macro Formatter.first_err(&self, anyfault f) return f; } -fn usz! Formatter.adjust(&self, usz len) @local +fn usz? Formatter.adjust(&self, usz len) @local { if (!self.flags.left) return 0; return self.pad(' ', self.width, len); } -fn uint128! int_from_any(any arg, bool *is_neg) @private +fn uint128? int_from_any(any arg, bool *is_neg) @private { switch (arg.type.kindof) { @@ -88,11 +85,11 @@ fn uint128! int_from_any(any arg, bool *is_neg) @private double d = *(double*)arg; return (uint128)((*is_neg = d < 0) ? -d : d); default: - return FormattingFault.BAD_FORMAT?; + return BAD_FORMAT?; } } -fn FloatType! float_from_any(any arg) @private +fn FloatType? float_from_any(any arg) @private { $if env::F128_SUPPORT: if (arg.type == float128.typeid) return (FloatType)*((float128*)arg.ptr); @@ -130,7 +127,7 @@ fn FloatType! float_from_any(any arg) @private case double: return (FloatType)*(double*)arg; default: - return FormattingFault.BAD_FORMAT?; + return BAD_FORMAT?; } } @@ -158,7 +155,7 @@ fn uint simple_atoi(char* buf, usz maxlen, usz* len_ptr) @inline @private return i; } -fn usz! Formatter.out_substr(&self, String str) @private +fn usz? Formatter.out_substr(&self, String str) @private { usz l = conv::utf8_codepoints(str); uint prec = self.prec; @@ -177,7 +174,7 @@ fn usz! Formatter.out_substr(&self, String str) @private return index; } -fn usz! Formatter.pad(&self, char c, isz width, isz len) @inline +fn usz? Formatter.pad(&self, char c, isz width, isz len) @inline { isz delta = width - len; for (isz i = 0; i < delta; i++) self.out(c)!; @@ -191,7 +188,7 @@ fn char* fmt_u(uint128 x, char* s) return s; } -fn usz! Formatter.out_chars(&self, char[] s) +fn usz? Formatter.out_chars(&self, char[] s) { foreach (c : s) self.out(c)!; return s.len; @@ -205,12 +202,12 @@ enum FloatFormatting HEX } -fn usz! Formatter.etoa(&self, double y) => self.floatformat(EXPONENTIAL, y); -fn usz! Formatter.ftoa(&self, double y) => self.floatformat(FLOAT, y); -fn usz! Formatter.gtoa(&self, double y) => self.floatformat(ADAPTIVE, y); -fn usz! Formatter.atoa(&self, double y) => self.floatformat(HEX, y); +fn usz? Formatter.etoa(&self, double y) => self.floatformat(EXPONENTIAL, y); +fn usz? Formatter.ftoa(&self, double y) => self.floatformat(FLOAT, y); +fn usz? Formatter.gtoa(&self, double y) => self.floatformat(ADAPTIVE, y); +fn usz? Formatter.atoa(&self, double y) => self.floatformat(HEX, y); -fn usz! Formatter.floatformat(&self, FloatFormatting formatting, double y) @private +fn usz? Formatter.floatformat(&self, FloatFormatting formatting, double y) @private { // This code is heavily based on musl's printf code const BUF_SIZE = (math::DOUBLE_MANT_DIG + 28) / 29 + 1 @@ -285,7 +282,7 @@ fn usz! Formatter.floatformat(&self, FloatFormatting formatting, double y) @priv } while (y); isz outlen = s - buf; isz explen = ebuf - estr; - if (p > int.max - 2 - explen - pl) return PrintFault.INTERNAL_BUFFER_EXCEEDED?; + if (p > int.max - 2 - explen - pl) return INTERNAL_BUFFER_EXCEEDED?; usz len; usz l = p && outlen - 2 < p ? p + 2 + explen @@ -453,12 +450,12 @@ fn usz! Formatter.floatformat(&self, FloatFormatting formatting, double y) @priv } } } - if (p > int.max - 1 - (isz)(p || self.flags.hash)) return PrintFault.INTERNAL_BUFFER_EXCEEDED?; + if (p > int.max - 1 - (isz)(p || self.flags.hash)) return INTERNAL_BUFFER_EXCEEDED?; int l = (int)(1 + p + (isz)(p || self.flags.hash)); char* estr @noinit; if (formatting == FLOAT) { - if (e > int.max - l) return PrintFault.INTERNAL_BUFFER_EXCEEDED?; + if (e > int.max - l) return INTERNAL_BUFFER_EXCEEDED?; if (e > 0) l += e; } else @@ -467,10 +464,10 @@ fn usz! Formatter.floatformat(&self, FloatFormatting formatting, double y) @priv while (ebuf - estr < 2) (--estr)[0] = '0'; *--estr = (e < 0 ? '-' : '+'); *--estr = self.flags.uppercase ? 'E' : 'e'; - if (ebuf - estr > (isz)int.max - l) return PrintFault.INTERNAL_BUFFER_EXCEEDED?; + if (ebuf - estr > (isz)int.max - l) return INTERNAL_BUFFER_EXCEEDED?; l += (int)(ebuf - estr); } - if (l > int.max - pl) return PrintFault.INTERNAL_BUFFER_EXCEEDED?; + if (l > int.max - pl) return INTERNAL_BUFFER_EXCEEDED?; usz len; if (!self.flags.left && !self.flags.zeropad) len += self.pad(' ', self.width, pl + l)!; if (is_neg || self.flags.plus) len += self.out(is_neg ? '-' : '+')!; @@ -528,7 +525,7 @@ fn usz! Formatter.floatformat(&self, FloatFormatting formatting, double y) @priv return len; } -fn usz! Formatter.ntoa(&self, uint128 value, bool negative, uint base) @private +fn usz? Formatter.ntoa(&self, uint128 value, bool negative, uint base) @private { char[PRINTF_NTOA_BUFFER_SIZE] buf @noinit; usz len; @@ -542,7 +539,7 @@ fn usz! Formatter.ntoa(&self, uint128 value, bool negative, uint base) @private char past_10 = (self.flags.uppercase ? 'A' : 'a') - 10; do { - if (len >= PRINTF_NTOA_BUFFER_SIZE) return PrintFault.INTERNAL_BUFFER_EXCEEDED?; + if (len >= PRINTF_NTOA_BUFFER_SIZE) return INTERNAL_BUFFER_EXCEEDED?; char digit = (char)(value % base); buf[len++] = digit + (digit < 10 ? '0' : past_10); value /= base; @@ -552,7 +549,7 @@ fn usz! Formatter.ntoa(&self, uint128 value, bool negative, uint base) @private return self.ntoa_format((String)buf[:PRINTF_NTOA_BUFFER_SIZE], len, negative, base); } -fn usz! Formatter.ntoa_format(&self, String buf, usz len, bool negative, uint base) @private +fn usz? Formatter.ntoa_format(&self, String buf, usz len, bool negative, uint base) @private { // pad leading zeros if (!self.flags.left) @@ -560,12 +557,12 @@ fn usz! Formatter.ntoa_format(&self, String buf, usz len, bool negative, uint ba if (self.width && self.flags.zeropad && (negative || self.flags.plus || self.flags.space)) self.width--; while (len < self.prec) { - if (len >= buf.len) return PrintFault.INTERNAL_BUFFER_EXCEEDED?; + if (len >= buf.len) return INTERNAL_BUFFER_EXCEEDED?; buf[len++] = '0'; } while (self.flags.zeropad && len < self.width) { - if (len >= buf.len) return PrintFault.INTERNAL_BUFFER_EXCEEDED?; + if (len >= buf.len) return INTERNAL_BUFFER_EXCEEDED?; buf[len++] = '0'; } } @@ -580,7 +577,7 @@ fn usz! Formatter.ntoa_format(&self, String buf, usz len, bool negative, uint ba } if (base != 10) { - if (len + 1 >= buf.len) return PrintFault.INTERNAL_BUFFER_EXCEEDED?; + if (len + 1 >= buf.len) return INTERNAL_BUFFER_EXCEEDED?; switch (base) { case 16: @@ -599,13 +596,13 @@ fn usz! Formatter.ntoa_format(&self, String buf, usz len, bool negative, uint ba switch (true) { case negative: - if (len >= buf.len) return PrintFault.INTERNAL_BUFFER_EXCEEDED?; + if (len >= buf.len) return INTERNAL_BUFFER_EXCEEDED?; buf[len++] = '-'; case self.flags.plus: - if (len >= buf.len) return PrintFault.INTERNAL_BUFFER_EXCEEDED?; + if (len >= buf.len) return INTERNAL_BUFFER_EXCEEDED?; buf[len++] = '+'; case self.flags.space: - if (len >= buf.len) return PrintFault.INTERNAL_BUFFER_EXCEEDED?; + if (len >= buf.len) return INTERNAL_BUFFER_EXCEEDED?; buf[len++] = ' '; } if (len) self.out_reverse(buf[:len])!; @@ -613,13 +610,13 @@ fn usz! Formatter.ntoa_format(&self, String buf, usz len, bool negative, uint ba } -fn usz! Formatter.ntoa_any(&self, any arg, uint base) @private +fn usz? Formatter.ntoa_any(&self, any arg, uint base) @private { bool is_neg; return self.ntoa(int_from_any(arg, &is_neg)!!, is_neg, base) @inline; } -fn usz! Formatter.out_char(&self, any arg) @private +fn usz? Formatter.out_char(&self, any arg) @private { if (!arg.type.kindof.is_int()) { @@ -653,7 +650,7 @@ fn usz! Formatter.out_char(&self, any arg) @private } -fn usz! Formatter.out_reverse(&self, char[] buf) @private +fn usz? Formatter.out_reverse(&self, char[] buf) @private { usz n; usz buffer_start_idx = self.idx; @@ -672,7 +669,7 @@ fn usz! Formatter.out_reverse(&self, char[] buf) @private } -fn int! printf_parse_format_field( +fn int? printf_parse_format_field( any* args_ptr, usz args_len, usz* args_index_ptr, char* format_ptr, usz format_len, usz* index_ptr) @inline @private { @@ -680,10 +677,10 @@ fn int! printf_parse_format_field( if (c.is_digit()) return simple_atoi(format_ptr, format_len, index_ptr); if (c != '*') return 0; usz len = ++(*index_ptr); - if (len >= format_len) return FormattingFault.BAD_FORMAT?; - if (*args_index_ptr >= args_len) return FormattingFault.BAD_FORMAT?; + if (len >= format_len) return BAD_FORMAT?; + if (*args_index_ptr >= args_len) return BAD_FORMAT?; any val = args_ptr[(*args_index_ptr)++]; - if (!val.type.kindof.is_int()) return FormattingFault.BAD_FORMAT?; - uint! intval = types::any_to_int(val, int); - return intval ?? FormattingFault.BAD_FORMAT?; + if (!val.type.kindof.is_int()) return BAD_FORMAT?; + uint? intval = types::any_to_int(val, int); + return intval ?? BAD_FORMAT?; } diff --git a/lib/std/io/io.c3 b/lib/std/io/io.c3 index 5c77232b1..9454c5341 100644 --- a/lib/std/io/io.c3 +++ b/lib/std/io/io.c3 @@ -11,8 +11,7 @@ enum Seek END } -fault IoError -{ +fault ALREADY_EXISTS, BUSY, CANNOT_READ_DIR, @@ -41,8 +40,7 @@ fault IoError UNEXPECTED_EOF, UNKNOWN_ERROR, UNSUPPORTED_OPERATION, - WOULD_BLOCK, -} + WOULD_BLOCK; <* @@ -55,7 +53,7 @@ fault IoError @param [inout] allocator : `the allocator to use.` @return `The string containing the data read.` *> -macro String! readline(Allocator allocator, stream = io::stdin()) +macro String? readline(Allocator allocator, stream = io::stdin()) { bool $is_stream = @typeis(stream, InStream); $if $is_stream: @@ -73,13 +71,13 @@ macro String! readline(Allocator allocator, stream = io::stdin()) while (1) { $if $is_stream: - char! c = func((void*)stream); + char? c = func((void*)stream); $else - char! c = stream.read_byte(); + char? c = stream.read_byte(); $endif if (catch err = c) { - if (err == IoError.EOF) break; + if (err == io::EOF) break; return err?; } if (c == '\r') continue; @@ -98,7 +96,7 @@ macro String! readline(Allocator allocator, stream = io::stdin()) @require @is_instream(stream) : `The stream must implement InStream.` @return `The temporary string containing the data read.` *> -macro String! treadline(stream = io::stdin()) +macro String? treadline(stream = io::stdin()) { return readline(tmem(), stream) @inline; } @@ -111,7 +109,7 @@ macro String! treadline(stream = io::stdin()) @require @is_outstream(out) : `The output must implement OutStream.` @return `the number of bytes printed.` *> -macro usz! fprint(out, x) +macro usz? fprint(out, x) { var $Type = $typeof(x); $switch $Type: @@ -141,7 +139,7 @@ macro usz! fprint(out, x) @param [in] format : `The printf-style format string` @return `the number of characters printed` *> -fn usz! fprintf(OutStream out, String format, args...) +fn usz? fprintf(OutStream out, String format, args...) { Formatter formatter; formatter.init(&out_putstream_fn, &out); @@ -156,7 +154,7 @@ fn usz! fprintf(OutStream out, String format, args...) @param [in] format : `The printf-style format string` @return `the number of characters printed` *> -fn usz! fprintfn(OutStream out, String format, args...) @maydiscard +fn usz? fprintfn(OutStream out, String format, args...) @maydiscard { Formatter formatter; formatter.init(&out_putstream_fn, &out); @@ -169,7 +167,7 @@ fn usz! fprintfn(OutStream out, String format, args...) @maydiscard <* @require @is_outstream(out) : "The output must implement OutStream" *> -macro usz! fprintn(out, x = "") +macro usz? fprintn(out, x = "") { usz len = fprint(out, x)!; out.write_byte('\n')!; @@ -219,13 +217,13 @@ macro void eprintn(x) } -fn void! out_putstream_fn(void* data, char c) @private +fn void? out_putstream_fn(void* data, char c) @private { OutStream* stream = data; return (*stream).write_byte(c); } -fn void! out_putchar_fn(void* data @unused, char c) @private +fn void? out_putchar_fn(void* data @unused, char c) @private { $if env::TESTING: // HACK: this is used for the purpose of unit test output hijacking @@ -251,7 +249,7 @@ fn void! out_putchar_fn(void* data @unused, char c) @private @param [in] format : `The printf-style format string` @return `the number of characters printed` *> -fn usz! printf(String format, args...) @maydiscard +fn usz? printf(String format, args...) @maydiscard { Formatter formatter; formatter.init(&out_putchar_fn); @@ -265,11 +263,11 @@ fn usz! printf(String format, args...) @maydiscard @param [in] format : `The printf-style format string` @return `the number of characters printed` *> -fn usz! printfn(String format, args...) @maydiscard +fn usz? printfn(String format, args...) @maydiscard { Formatter formatter; formatter.init(&out_putchar_fn); - usz! len = formatter.vprintf(format, args); + usz? len = formatter.vprintf(format, args); out_putchar_fn(null, '\n')!; io::stdout().flush()!; return len + 1; @@ -282,7 +280,7 @@ fn usz! printfn(String format, args...) @maydiscard @param [in] format : `The printf-style format string` @return `the number of characters printed` *> -fn usz! eprintf(String format, args...) @maydiscard +fn usz? eprintf(String format, args...) @maydiscard { Formatter formatter; OutStream stream = stderr(); @@ -298,12 +296,12 @@ fn usz! eprintf(String format, args...) @maydiscard @param [in] format : `The printf-style format string` @return `the number of characters printed` *> -fn usz! eprintfn(String format, args...) @maydiscard +fn usz? eprintfn(String format, args...) @maydiscard { Formatter formatter; OutStream stream = stderr(); formatter.init(&out_putstream_fn, &stream); - usz! len = formatter.vprintf(format, args); + usz? len = formatter.vprintf(format, args); stderr().write_byte('\n')!; stderr().flush()!; return len + 1; @@ -317,7 +315,7 @@ fn usz! eprintfn(String format, args...) @maydiscard @param [in] format : `The printf-style format string` @return `a slice formed from the "buffer" with the resulting length.` *> -fn char[]! bprintf(char[] buffer, String format, args...) @maydiscard +fn char[]? bprintf(char[] buffer, String format, args...) @maydiscard { Formatter formatter; BufferData data = { .buffer = buffer }; @@ -327,10 +325,10 @@ fn char[]! bprintf(char[] buffer, String format, args...) @maydiscard } // Used to print to a buffer. -fn void! out_buffer_fn(void *data, char c) @private +fn void? out_buffer_fn(void *data, char c) @private { BufferData *buffer_data = data; - if (buffer_data.written >= buffer_data.buffer.len) return PrintFault.BUFFER_EXCEEDED?; + if (buffer_data.written >= buffer_data.buffer.len) return BUFFER_EXCEEDED?; buffer_data.buffer[buffer_data.written++] = c; } diff --git a/lib/std/io/os/chdir.c3 b/lib/std/io/os/chdir.c3 index 77c82fc0a..d64252539 100644 --- a/lib/std/io/os/chdir.c3 +++ b/lib/std/io/os/chdir.c3 @@ -1,7 +1,7 @@ module std::io::os; import std::io::path, libc, std::os; -macro void! native_chdir(Path path) +macro void? native_chdir(Path path) { $switch: $case env::POSIX: @@ -9,12 +9,12 @@ macro void! native_chdir(Path path) { switch (libc::errno()) { - case errno::EACCES: return IoError.NO_PERMISSION?; - case errno::ENAMETOOLONG: return IoError.NAME_TOO_LONG?; - case errno::ENOTDIR: return IoError.FILE_NOT_DIR?; - case errno::ENOENT: return IoError.FILE_NOT_FOUND?; - case errno::ELOOP: return IoError.SYMLINK_FAILED?; - default: return IoError.GENERAL_ERROR?; + case errno::EACCES: return io::NO_PERMISSION?; + case errno::ENAMETOOLONG: return io::NAME_TOO_LONG?; + case errno::ENOTDIR: return io::FILE_NOT_DIR?; + case errno::ENOENT: return io::FILE_NOT_FOUND?; + case errno::ELOOP: return io::SYMLINK_FAILED?; + default: return io::GENERAL_ERROR?; } } $case env::WIN32: @@ -23,8 +23,8 @@ macro void! native_chdir(Path path) // TODO improve with better error handling. if (win32::setCurrentDirectoryW(path.str_view().to_temp_utf16()!!)) return; }; - return IoError.GENERAL_ERROR?; + return io::GENERAL_ERROR?; $default: - return IoError.UNSUPPORTED_OPERATION?; + return io::UNSUPPORTED_OPERATION?; $endswitch } diff --git a/lib/std/io/os/file_libc.c3 b/lib/std/io/os/file_libc.c3 index 72a428317..663c0e5d5 100644 --- a/lib/std/io/os/file_libc.c3 +++ b/lib/std/io/os/file_libc.c3 @@ -5,7 +5,7 @@ import libc; @require mode.len > 0 @require filename.len > 0 *> -fn void*! native_fopen(String filename, String mode) @inline => @pool() +fn void*? native_fopen(String filename, String mode) @inline => @pool() { $if env::WIN32: void* file = libc::_wfopen(filename.to_temp_wstring(), mode.to_temp_wstring())!; @@ -15,7 +15,7 @@ fn void*! native_fopen(String filename, String mode) @inline => @pool() return file ?: file_open_errno()?; } -fn void! native_remove(String filename) => @pool() +fn void? native_remove(String filename) => @pool() { $if env::WIN32: CInt result = libc::_wremove(filename.to_temp_wstring())!; @@ -27,10 +27,10 @@ fn void! native_remove(String filename) => @pool() switch (libc::errno()) { case errno::ENOENT: - return IoError.FILE_NOT_FOUND?; + return io::FILE_NOT_FOUND?; case errno::EACCES: default: - return IoError.FILE_CANNOT_DELETE?; + return io::FILE_CANNOT_DELETE?; } } } @@ -39,7 +39,7 @@ fn void! native_remove(String filename) => @pool() @require mode.len > 0 @require filename.len > 0 *> -fn void*! native_freopen(void* file, String filename, String mode) @inline => @pool() +fn void*? native_freopen(void* file, String filename, String mode) @inline => @pool() { $if env::WIN32: file = libc::_wfreopen(filename.to_temp_wstring(), mode.to_temp_wstring(), file)!; @@ -49,29 +49,29 @@ fn void*! native_freopen(void* file, String filename, String mode) @inline => @p return file ?: file_open_errno()?; } -fn void! native_fseek(void* file, isz offset, Seek seek_mode) @inline +fn void? native_fseek(void* file, isz offset, Seek seek_mode) @inline { if (libc::fseek(file, (SeekIndex)offset, seek_mode.ordinal)) return file_seek_errno()?; } -fn usz! native_ftell(CFile file) @inline +fn usz? native_ftell(CFile file) @inline { long index = libc::ftell(file); return index >= 0 ? (usz)index : file_seek_errno()?; } -fn usz! native_fwrite(CFile file, char[] buffer) @inline +fn usz? native_fwrite(CFile file, char[] buffer) @inline { return libc::fwrite(buffer.ptr, 1, buffer.len, file); } -fn void! native_fputc(CInt c, CFile stream) @inline +fn void? native_fputc(CInt c, CFile stream) @inline { - if (libc::fputc(c, stream) == libc::EOF) return IoError.EOF?; + if (libc::fputc(c, stream) == libc::EOF) return io::EOF?; } -fn usz! native_fread(CFile file, char[] buffer) @inline +fn usz? native_fread(CFile file, char[] buffer) @inline { return libc::fread(buffer.ptr, 1, buffer.len, file); } @@ -80,27 +80,27 @@ macro anyfault file_open_errno() @local { switch (libc::errno()) { - case errno::EACCES: return IoError.NO_PERMISSION; - case errno::EDQUOT: return IoError.OUT_OF_SPACE; - case errno::EBADF: return IoError.FILE_NOT_VALID; - case errno::EEXIST: return IoError.ALREADY_EXISTS; - case errno::EINTR: return IoError.INTERRUPTED; - case errno::EFAULT: return IoError.GENERAL_ERROR; - case errno::EISDIR: return IoError.FILE_IS_DIR; - case errno::ELOOP: return IoError.SYMLINK_FAILED; - case errno::EMFILE: return IoError.TOO_MANY_DESCRIPTORS; - case errno::ENAMETOOLONG: return IoError.NAME_TOO_LONG; - case errno::ENFILE: return IoError.OUT_OF_SPACE; - case errno::ENOTDIR: return IoError.FILE_NOT_DIR; - case errno::ENOENT: return IoError.FILE_NOT_FOUND; - case errno::ENOSPC: return IoError.OUT_OF_SPACE; - case errno::ENXIO: return IoError.FILE_NOT_FOUND; - case errno::EOVERFLOW: return IoError.OVERFLOW; - case errno::EROFS: return IoError.READ_ONLY; - case errno::EOPNOTSUPP: return IoError.UNSUPPORTED_OPERATION; - case errno::EIO: return IoError.INCOMPLETE_WRITE; - case errno::EWOULDBLOCK: return IoError.WOULD_BLOCK; - default: return IoError.UNKNOWN_ERROR; + case errno::EACCES: return io::NO_PERMISSION; + case errno::EDQUOT: return io::OUT_OF_SPACE; + case errno::EBADF: return io::FILE_NOT_VALID; + case errno::EEXIST: return io::ALREADY_EXISTS; + case errno::EINTR: return io::INTERRUPTED; + case errno::EFAULT: return io::GENERAL_ERROR; + case errno::EISDIR: return io::FILE_IS_DIR; + case errno::ELOOP: return io::SYMLINK_FAILED; + case errno::EMFILE: return io::TOO_MANY_DESCRIPTORS; + case errno::ENAMETOOLONG: return io::NAME_TOO_LONG; + case errno::ENFILE: return io::OUT_OF_SPACE; + case errno::ENOTDIR: return io::FILE_NOT_DIR; + case errno::ENOENT: return io::FILE_NOT_FOUND; + case errno::ENOSPC: return io::OUT_OF_SPACE; + case errno::ENXIO: return io::FILE_NOT_FOUND; + case errno::EOVERFLOW: return io::OVERFLOW; + case errno::EROFS: return io::READ_ONLY; + case errno::EOPNOTSUPP: return io::UNSUPPORTED_OPERATION; + case errno::EIO: return io::INCOMPLETE_WRITE; + case errno::EWOULDBLOCK: return io::WOULD_BLOCK; + default: return io::UNKNOWN_ERROR; } } @@ -108,18 +108,18 @@ macro anyfault file_seek_errno() @local { switch (libc::errno()) { - case errno::ESPIPE: return IoError.FILE_IS_PIPE; - case errno::EPIPE: return IoError.FILE_IS_PIPE; - case errno::EOVERFLOW: return IoError.OVERFLOW; - case errno::ENXIO: return IoError.FILE_NOT_FOUND; - case errno::ENOSPC: return IoError.OUT_OF_SPACE; - case errno::EIO: return IoError.INCOMPLETE_WRITE; - case errno::EINVAL: return IoError.INVALID_POSITION; - case errno::EINTR: return IoError.INTERRUPTED; - case errno::EFBIG: return IoError.OUT_OF_SPACE; - case errno::EBADF: return IoError.FILE_NOT_VALID; - case errno::EAGAIN: return IoError.WOULD_BLOCK; - default: return IoError.UNKNOWN_ERROR; + case errno::ESPIPE: return io::FILE_IS_PIPE; + case errno::EPIPE: return io::FILE_IS_PIPE; + case errno::EOVERFLOW: return io::OVERFLOW; + case errno::ENXIO: return io::FILE_NOT_FOUND; + case errno::ENOSPC: return io::OUT_OF_SPACE; + case errno::EIO: return io::INCOMPLETE_WRITE; + case errno::EINVAL: return io::INVALID_POSITION; + case errno::EINTR: return io::INTERRUPTED; + case errno::EFBIG: return io::OUT_OF_SPACE; + case errno::EBADF: return io::FILE_NOT_VALID; + case errno::EAGAIN: return io::WOULD_BLOCK; + default: return io::UNKNOWN_ERROR; } } diff --git a/lib/std/io/os/file_nolibc.c3 b/lib/std/io/os/file_nolibc.c3 index 7c23afa03..1d5d1232f 100644 --- a/lib/std/io/os/file_nolibc.c3 +++ b/lib/std/io/os/file_nolibc.c3 @@ -1,15 +1,15 @@ module std::io::os @if(env::NO_LIBC); import libc; -def FopenFn = fn void*!(String, String); -def FreopenFn = fn void*!(void*, String, String); -def FcloseFn = fn void!(void*); -def FseekFn = fn void!(void*, isz, Seek); -def FtellFn = fn usz!(void*); -def FwriteFn = fn usz!(void*, char[] buffer); -def FreadFn = fn usz!(void*, char[] buffer); -def RemoveFn = fn void!(String); -def FputcFn = fn void!(int, void*); +def FopenFn = fn void*?(String, String); +def FreopenFn = fn void*?(void*, String, String); +def FcloseFn = fn void?(void*); +def FseekFn = fn void?(void*, isz, Seek); +def FtellFn = fn usz?(void*); +def FwriteFn = fn usz?(void*, char[] buffer); +def FreadFn = fn usz?(void*, char[] buffer); +def RemoveFn = fn void?(String); +def FputcFn = fn void?(int, void*); FopenFn native_fopen_fn @weak @if(!$defined(native_fopen_fn)); FcloseFn native_fclose_fn @weak @if(!$defined(native_fclose_fn)); @@ -25,10 +25,10 @@ FputcFn native_fputc_fn @weak @if(!$defined(native_fputc_fn)); @require mode.len > 0 @require filename.len > 0 *> -fn void*! native_fopen(String filename, String mode) @inline +fn void*? native_fopen(String filename, String mode) @inline { if (native_fopen_fn) return native_fopen_fn(filename, mode); - return IoError.UNSUPPORTED_OPERATION?; + return io::UNSUPPORTED_OPERATION?; } <* @@ -36,48 +36,48 @@ fn void*! native_fopen(String filename, String mode) @inline @require filename.len > 0 *> -fn void! native_remove(String filename) @inline +fn void? native_remove(String filename) @inline { if (native_remove_fn) return native_remove_fn(filename); - return IoError.UNSUPPORTED_OPERATION?; + return io::UNSUPPORTED_OPERATION?; } <* @require mode.len > 0 @require filename.len > 0 *> -fn void*! native_freopen(void* file, String filename, String mode) @inline +fn void*? native_freopen(void* file, String filename, String mode) @inline { if (native_freopen_fn) return native_freopen_fn(file, filename, mode); - return IoError.UNSUPPORTED_OPERATION?; + return io::UNSUPPORTED_OPERATION?; } -fn void! native_fseek(void* file, isz offset, Seek seek_mode) @inline +fn void? native_fseek(void* file, isz offset, Seek seek_mode) @inline { if (native_fseek_fn) return native_fseek_fn(file, offset, seek_mode); - return IoError.UNSUPPORTED_OPERATION?; + return io::UNSUPPORTED_OPERATION?; } -fn usz! native_ftell(CFile file) @inline +fn usz? native_ftell(CFile file) @inline { if (native_ftell_fn) return native_ftell_fn(file); - return IoError.UNSUPPORTED_OPERATION?; + return io::UNSUPPORTED_OPERATION?; } -fn usz! native_fwrite(CFile file, char[] buffer) @inline +fn usz? native_fwrite(CFile file, char[] buffer) @inline { if (native_fwrite_fn) return native_fwrite_fn(file, buffer); - return IoError.UNSUPPORTED_OPERATION?; + return io::UNSUPPORTED_OPERATION?; } -fn usz! native_fread(CFile file, char[] buffer) @inline +fn usz? native_fread(CFile file, char[] buffer) @inline { if (native_fread_fn) return native_fread_fn(file, buffer); - return IoError.UNSUPPORTED_OPERATION?; + return io::UNSUPPORTED_OPERATION?; } -fn void! native_fputc(CInt c, CFile stream) @inline +fn void? native_fputc(CInt c, CFile stream) @inline { if (native_fputc_fn) return native_fputc_fn(c, stream); - return IoError.UNSUPPORTED_OPERATION?; + return io::UNSUPPORTED_OPERATION?; } diff --git a/lib/std/io/os/fileinfo.c3 b/lib/std/io/os/fileinfo.c3 index e546b0b45..751f3415d 100644 --- a/lib/std/io/os/fileinfo.c3 +++ b/lib/std/io/os/fileinfo.c3 @@ -1,7 +1,7 @@ module std::io::os; import libc, std::os, std::io; -fn void! native_stat(Stat* stat, String path) @if(env::DARWIN || env::LINUX || env::BSD_FAMILY) => @pool() +fn void? native_stat(Stat* stat, String path) @if(env::DARWIN || env::LINUX || env::BSD_FAMILY) => @pool() { $if env::DARWIN || env::LINUX || env::BSD_FAMILY: int res = libc::stat(path.zstr_tcopy(), stat); @@ -14,30 +14,30 @@ fn void! native_stat(Stat* stat, String path) @if(env::DARWIN || env::LINUX || e switch (libc::errno()) { case errno::EBADF: - return IoError.FILE_NOT_VALID?; + return io::FILE_NOT_VALID?; case errno::EFAULT: unreachable("Invalid stat"); case errno::EIO: - return IoError.GENERAL_ERROR?; + return io::GENERAL_ERROR?; case errno::EACCES: - return IoError.NO_PERMISSION?; + return io::NO_PERMISSION?; case errno::ELOOP: - return IoError.NO_PERMISSION?; + return io::NO_PERMISSION?; case errno::ENAMETOOLONG: - return IoError.NAME_TOO_LONG?; + return io::NAME_TOO_LONG?; case errno::ENOENT: - return IoError.FILE_NOT_FOUND?; + return io::FILE_NOT_FOUND?; case errno::ENOTDIR: - return IoError.FILE_NOT_DIR?; + return io::FILE_NOT_DIR?; case errno::EOVERFLOW: - return IoError.GENERAL_ERROR?; + return io::GENERAL_ERROR?; default: - return IoError.UNKNOWN_ERROR?; + return io::UNKNOWN_ERROR?; } } } -fn usz! native_file_size(String path) @if(env::WIN32) => @pool() +fn usz? native_file_size(String path) @if(env::WIN32) => @pool() { Win32_FILE_ATTRIBUTE_DATA data; win32::getFileAttributesExW(path.to_temp_wstring()!, Win32_GET_FILEEX_INFO_LEVELS.STANDARD, &data); @@ -47,14 +47,14 @@ fn usz! native_file_size(String path) @if(env::WIN32) => @pool() return (usz)size.quadPart; } -fn usz! native_file_size(String path) @if(!env::WIN32 && !env::DARWIN) +fn usz? native_file_size(String path) @if(!env::WIN32 && !env::DARWIN) { File f = file::open(path, "r")!; defer (void)f.close(); return f.seek(0, Seek.END)!; } -fn usz! native_file_size(String path) @if(env::DARWIN) +fn usz? native_file_size(String path) @if(env::DARWIN) { Stat stat; native_stat(&stat, path)!; @@ -97,7 +97,7 @@ fn bool native_is_file(String path) Stat stat; return @ok(native_stat(&stat, path)) && libc_S_ISTYPE(stat.st_mode, libc::S_IFREG); $default: - File! f = file::open(path, "r"); + File? f = file::open(path, "r"); defer (void)f.close(); return @ok(f); $endswitch diff --git a/lib/std/io/os/getcwd.c3 b/lib/std/io/os/getcwd.c3 index dbc66ea1d..c4ab658d2 100644 --- a/lib/std/io/os/getcwd.c3 +++ b/lib/std/io/os/getcwd.c3 @@ -1,7 +1,7 @@ module std::io::os; import libc, std::os; -macro String! getcwd(Allocator allocator = allocator::heap()) +macro String? getcwd(Allocator allocator = allocator::heap()) { $switch: $case env::WIN32: @@ -12,7 +12,7 @@ macro String! getcwd(Allocator allocator = allocator::heap()) defer if (free) libc::free(res); if (!res) { - if (libc::errno() != errno::ERANGE) return IoError.GENERAL_ERROR?; + if (libc::errno() != errno::ERANGE) return io::GENERAL_ERROR?; res = win32::_wgetcwd(null, 0); free = true; } @@ -27,7 +27,7 @@ macro String! getcwd(Allocator allocator = allocator::heap()) if (!res) { // Improve error - if (libc::errno() != errno::ERANGE) return IoError.GENERAL_ERROR?; + if (libc::errno() != errno::ERANGE) return io::GENERAL_ERROR?; res = posix::getcwd(null, 0); free = true; } @@ -35,7 +35,7 @@ macro String! getcwd(Allocator allocator = allocator::heap()) return res.copy(allocator); $default: - return IoError.UNSUPPORTED_OPERATION?; + return io::UNSUPPORTED_OPERATION?; $endswitch } diff --git a/lib/std/io/os/ls.c3 b/lib/std/io/os/ls.c3 index a6ca6b5a1..9b290bd15 100644 --- a/lib/std/io/os/ls.c3 +++ b/lib/std/io/os/ls.c3 @@ -1,13 +1,13 @@ module std::io::os @if(env::POSIX); import std::io, std::os; -fn PathList! native_ls(Path dir, bool no_dirs, bool no_symlinks, String mask, Allocator allocator) +fn PathList? native_ls(Path dir, bool no_dirs, bool no_symlinks, String mask, Allocator allocator) { PathList list; list.init(allocator); DIRPtr directory = posix::opendir(dir.str_view() ? dir.as_zstr() : (ZString)"."); defer if (directory) posix::closedir(directory); - if (!directory) return (path::is_dir(dir) ? IoError.CANNOT_READ_DIR : IoError.FILE_NOT_DIR)?; + if (!directory) return (path::is_dir(dir) ? io::CANNOT_READ_DIR : io::FILE_NOT_DIR)?; Posix_dirent* entry; while ((entry = posix::readdir(directory))) { @@ -24,7 +24,7 @@ fn PathList! native_ls(Path dir, bool no_dirs, bool no_symlinks, String mask, Al module std::io::os @if(env::WIN32); import std::time, std::os, std::io; -fn PathList! native_ls(Path dir, bool no_dirs, bool no_symlinks, String mask, Allocator allocator) +fn PathList? native_ls(Path dir, bool no_dirs, bool no_symlinks, String mask, Allocator allocator) { PathList list; list.init(allocator); @@ -34,7 +34,7 @@ fn PathList! native_ls(Path dir, bool no_dirs, bool no_symlinks, String mask, Al WString result = dir.str_view().tconcat(`\*`).to_temp_wstring()!!; Win32_WIN32_FIND_DATAW find_data; Win32_HANDLE find = win32::findFirstFileW(result, &find_data); - if (find == win32::INVALID_HANDLE_VALUE) return IoError.CANNOT_READ_DIR?; + if (find == win32::INVALID_HANDLE_VALUE) return io::CANNOT_READ_DIR?; defer win32::findClose(find); do { diff --git a/lib/std/io/os/mkdir.c3 b/lib/std/io/os/mkdir.c3 index e329f4593..717d065bd 100644 --- a/lib/std/io/os/mkdir.c3 +++ b/lib/std/io/os/mkdir.c3 @@ -5,7 +5,7 @@ import std::os::win32; import std::os::posix; -macro bool! native_mkdir(Path path, MkdirPermissions permissions) +macro bool? native_mkdir(Path path, MkdirPermissions permissions) { $switch: $case env::POSIX: @@ -15,15 +15,15 @@ macro bool! native_mkdir(Path path, MkdirPermissions permissions) case errno::EACCES: case errno::EPERM: case errno::EROFS: - case errno::EFAULT: return IoError.NO_PERMISSION?; - case errno::ENAMETOOLONG: return IoError.NAME_TOO_LONG?; + case errno::EFAULT: return io::NO_PERMISSION?; + case errno::ENAMETOOLONG: return io::NAME_TOO_LONG?; case errno::EDQUOT: - case errno::ENOSPC: return IoError.OUT_OF_SPACE?; + case errno::ENOSPC: return io::OUT_OF_SPACE?; case errno::EISDIR: case errno::EEXIST: return false; - case errno::ELOOP: return IoError.SYMLINK_FAILED?; - case errno::ENOTDIR: return IoError.FILE_NOT_FOUND?; - default: return IoError.GENERAL_ERROR?; + case errno::ELOOP: return io::SYMLINK_FAILED?; + case errno::ENOTDIR: return io::FILE_NOT_FOUND?; + default: return io::GENERAL_ERROR?; } $case env::WIN32: @pool() @@ -33,18 +33,18 @@ macro bool! native_mkdir(Path path, MkdirPermissions permissions) switch (win32::getLastError()) { case win32::ERROR_ACCESS_DENIED: - return IoError.NO_PERMISSION?; + return io::NO_PERMISSION?; case win32::ERROR_DISK_FULL: - return IoError.OUT_OF_SPACE?; + return io::OUT_OF_SPACE?; case win32::ERROR_ALREADY_EXISTS: return false; case win32::ERROR_PATH_NOT_FOUND: - return IoError.FILE_NOT_FOUND?; + return io::FILE_NOT_FOUND?; default: - return IoError.GENERAL_ERROR?; + return io::GENERAL_ERROR?; } }; $default: - return IoError.UNSUPPORTED_OPERATION?; + return io::UNSUPPORTED_OPERATION?; $endswitch } \ No newline at end of file diff --git a/lib/std/io/os/rmdir.c3 b/lib/std/io/os/rmdir.c3 index a4645e39f..cf367bf75 100644 --- a/lib/std/io/os/rmdir.c3 +++ b/lib/std/io/os/rmdir.c3 @@ -4,24 +4,24 @@ import std::io::path; import std::os::win32; import std::os::posix; -macro bool! native_rmdir(Path path) +macro bool? native_rmdir(Path path) { $switch: $case env::POSIX: if (!posix::rmdir(path.as_zstr())) return true; switch (libc::errno()) { - case errno::EBUSY: return IoError.BUSY?; + case errno::EBUSY: return io::BUSY?; case errno::EACCES: case errno::EPERM: case errno::EROFS: - case errno::EFAULT: return IoError.NO_PERMISSION?; - case errno::ENAMETOOLONG: return IoError.NAME_TOO_LONG?; + case errno::EFAULT: return io::NO_PERMISSION?; + case errno::ENAMETOOLONG: return io::NAME_TOO_LONG?; case errno::ENOTDIR: case errno::ENOENT: return false; - case errno::ENOTEMPTY: return IoError.DIR_NOT_EMPTY?; - case errno::ELOOP: return IoError.SYMLINK_FAILED?; - default: return IoError.GENERAL_ERROR?; + case errno::ENOTEMPTY: return io::DIR_NOT_EMPTY?; + case errno::ELOOP: return io::SYMLINK_FAILED?; + default: return io::GENERAL_ERROR?; } $case env::WIN32: @pool() @@ -30,19 +30,19 @@ macro bool! native_rmdir(Path path) switch (win32::getLastError()) { case win32::ERROR_ACCESS_DENIED: - return IoError.NO_PERMISSION?; + return io::NO_PERMISSION?; case win32::ERROR_CURRENT_DIRECTORY: - return IoError.BUSY?; + return io::BUSY?; case win32::ERROR_DIR_NOT_EMPTY: - return IoError.DIR_NOT_EMPTY?; + return io::DIR_NOT_EMPTY?; case win32::ERROR_DIRECTORY: case win32::ERROR_PATH_NOT_FOUND: return false; default: - return IoError.GENERAL_ERROR?; + return io::GENERAL_ERROR?; } }; $default: - return IoError.UNSUPPORTED_OPERATION?; + return io::UNSUPPORTED_OPERATION?; $endswitch } diff --git a/lib/std/io/os/rmtree.c3 b/lib/std/io/os/rmtree.c3 index 210fdf917..fac177f0f 100644 --- a/lib/std/io/os/rmtree.c3 +++ b/lib/std/io/os/rmtree.c3 @@ -4,11 +4,11 @@ import std::io, std::os, libc; <* @require dir.str_view().len > 0 *> -fn void! native_rmtree(Path dir) +fn void? native_rmtree(Path dir) { DIRPtr directory = posix::opendir(dir.as_zstr()); defer if (directory) posix::closedir(directory); - if (!directory) return path::is_dir(dir) ? IoError.CANNOT_READ_DIR? : IoError.FILE_NOT_DIR?; + if (!directory) return path::is_dir(dir) ? io::CANNOT_READ_DIR? : io::FILE_NOT_DIR?; Posix_dirent* entry; while ((entry = posix::readdir(directory))) { @@ -25,7 +25,7 @@ fn void! native_rmtree(Path dir) if (libc::remove(new_path.as_zstr())) { // TODO improve - return IoError.GENERAL_ERROR?; + return io::GENERAL_ERROR?; } }; } @@ -35,13 +35,13 @@ fn void! native_rmtree(Path dir) module std::io::os @if(env::WIN32); import std::io, std::time, std::os; -fn void! native_rmtree(Path path) +fn void? native_rmtree(Path path) { Win32_WIN32_FIND_DATAW find_data; String s = path.str_view().tconcat("\\*"); Win32_HANDLE find = win32::findFirstFileW(s.to_temp_utf16(), &find_data)!; - if (find == win32::INVALID_HANDLE_VALUE) return IoError.CANNOT_READ_DIR?; + if (find == win32::INVALID_HANDLE_VALUE) return io::CANNOT_READ_DIR?; defer win32::findClose(find); do { diff --git a/lib/std/io/os/temp_directory.c3 b/lib/std/io/os/temp_directory.c3 index d1f82c9ae..da53da537 100644 --- a/lib/std/io/os/temp_directory.c3 +++ b/lib/std/io/os/temp_directory.c3 @@ -1,7 +1,7 @@ module std::io::os @if(env::LIBC); import std::io::path, std::os; -fn Path! native_temp_directory(Allocator allocator) @if(!env::WIN32) +fn Path? native_temp_directory(Allocator allocator) @if(!env::WIN32) { foreach (String env : { "TMPDIR", "TMP", "TEMP", "TEMPDIR" }) { @@ -11,19 +11,19 @@ fn Path! native_temp_directory(Allocator allocator) @if(!env::WIN32) return path::new(allocator, "/tmp"); } -fn Path! native_temp_directory(Allocator allocator) @if(env::WIN32) => @pool(allocator) +fn Path? native_temp_directory(Allocator allocator) @if(env::WIN32) => @pool(allocator) { Win32_DWORD len = win32::getTempPathW(0, null); - if (!len) return IoError.GENERAL_ERROR?; + if (!len) return io::GENERAL_ERROR?; Char16[] buff = mem::talloc_array(Char16, len + (usz)1); - if (!win32::getTempPathW(len, buff)) return IoError.GENERAL_ERROR?; + if (!win32::getTempPathW(len, buff)) return io::GENERAL_ERROR?; return path::new(allocator, string::tfrom_utf16(buff[:len])); } module std::io::os @if(env::NO_LIBC); import std::io::path; -macro Path! native_temp_directory(Allocator allocator = allocator::heap()) +macro Path? native_temp_directory(Allocator allocator = allocator::heap()) { - return IoError.UNSUPPORTED_OPERATION?; + return io::UNSUPPORTED_OPERATION?; } diff --git a/lib/std/io/path.c3 b/lib/std/io/path.c3 index 1a2310d1e..de2d41530 100644 --- a/lib/std/io/path.c3 +++ b/lib/std/io/path.c3 @@ -9,11 +9,7 @@ const char PREFERRED_SEPARATOR = env::WIN32 ? PREFERRED_SEPARATOR_WIN32 : PREFER def PathList = List { Path }; -fault PathResult -{ - INVALID_PATH, - NO_PARENT, -} +fault INVALID_PATH, NO_PARENT; def Path = PathImp; @@ -30,7 +26,7 @@ enum PathEnv POSIX } -fn Path! cwd(Allocator allocator) +fn Path? cwd(Allocator allocator) { @pool(allocator) { @@ -40,14 +36,14 @@ fn Path! cwd(Allocator allocator) fn bool is_dir(Path path) => os::native_is_dir(path.str_view()); fn bool is_file(Path path) => os::native_is_file(path.str_view()); -fn usz! file_size(Path path) => os::native_file_size(path.str_view()); +fn usz? file_size(Path path) => os::native_file_size(path.str_view()); fn bool exists(Path path) => os::native_file_or_dir_exists(path.str_view()); -fn Path! tcwd() => cwd(tmem()) @inline; +fn Path? tcwd() => cwd(tmem()) @inline; <* @require @is_pathlike(path) : "Expected a Path or String to chdir" *> -macro void! chdir(path) +macro void? chdir(path) { $if @typeis(path, String): @pool() @@ -59,9 +55,9 @@ macro void! chdir(path) $endif } -fn Path! temp_directory(Allocator allocator) => os::native_temp_directory(allocator); +fn Path? temp_directory(Allocator allocator) => os::native_temp_directory(allocator); -fn void! delete(Path path) => os::native_remove(path.str_view()) @inline; +fn void? delete(Path path) => os::native_remove(path.str_view()) @inline; macro bool @is_pathlike(#path) => @typeis(#path, String) || @typeis(#path, Path); @@ -73,12 +69,12 @@ macro bool is_separator(char c, PathEnv path_env = DEFAULT_ENV) macro bool is_posix_separator(char c) => c == '/'; macro bool is_win32_separator(char c) => c == '/' || c == '\\'; -fn PathList! ls(Allocator allocator, Path dir, bool no_dirs = false, bool no_symlinks = false, String mask = "") +fn PathList? ls(Allocator allocator, Path dir, bool no_dirs = false, bool no_symlinks = false, String mask = "") { $if $defined(os::native_ls): return os::native_ls(dir, no_dirs, no_symlinks, mask, allocator); $else - return IoError.UNSUPPORTED_OPERATION?; + return io::UNSUPPORTED_OPERATION?; $endif } @@ -97,7 +93,7 @@ enum MkdirPermissions @param recursive : `If directories in between should be created if they're missing, defaults to false` @param permissions : `The permissions to set on the directory` *> -macro bool! mkdir(Path path, bool recursive = false, MkdirPermissions permissions = NORMAL) +macro bool? mkdir(Path path, bool recursive = false, MkdirPermissions permissions = NORMAL) { $if @typeis(path, String): @pool() { return _mkdir(temp(path), recursive, permissions); }; @@ -113,9 +109,9 @@ macro bool! mkdir(Path path, bool recursive = false, MkdirPermissions permission @param path : `The path to delete` @require @is_pathlike(path) : "Expected a Path or String to chdir" @return `true if there was a directory to delete, false otherwise` - @return! PathResult.INVALID_PATH : `if the path was invalid` + @return! INVALID_PATH : `if the path was invalid` *> -macro bool! rmdir(path) +macro bool? rmdir(path) { $if @typeis(path, String): @pool() { return _rmdir(temp(path)); }; @@ -127,22 +123,22 @@ macro bool! rmdir(path) <* Like [rmdir] but deletes a directory even if it contains items. *> -fn void! rmtree(Path path) +fn void? rmtree(Path path) { - if (!path.path_string.len) return PathResult.INVALID_PATH?; + if (!path.path_string.len) return INVALID_PATH?; $if $defined(os::native_rmtree): return os::native_rmtree(path); $else - return IoError.UNSUPPORTED_OPERATION?; + return io::UNSUPPORTED_OPERATION?; $endif } <* Creates a new path. - @return! PathResult.INVALID_PATH : `if the path was invalid` + @return! INVALID_PATH : `if the path was invalid` *> -fn Path! new(Allocator allocator, String path, PathEnv path_env = DEFAULT_ENV) +fn Path? new(Allocator allocator, String path, PathEnv path_env = DEFAULT_ENV) { return { normalize(path.copy(allocator), path_env), path_env, allocator }; } @@ -150,24 +146,24 @@ fn Path! new(Allocator allocator, String path, PathEnv path_env = DEFAULT_ENV) <* Creates a new path using the temp allocator. - @return! PathResult.INVALID_PATH : `if the path was invalid` + @return! INVALID_PATH : `if the path was invalid` *> -fn Path! temp(String path, PathEnv path_env = DEFAULT_ENV) +fn Path? temp(String path, PathEnv path_env = DEFAULT_ENV) { return new(tmem(), path, path_env); } -fn Path! from_win32_wstring(Allocator allocator, WString path) => @pool(allocator) +fn Path? from_win32_wstring(Allocator allocator, WString path) => @pool(allocator) { return path::new(allocator, string::tfrom_wstring(path)!); } -fn Path! for_windows(Allocator allocator, String path) +fn Path? for_windows(Allocator allocator, String path) { return new(allocator, path, WIN32); } -fn Path! for_posix(Allocator allocator, String path) +fn Path? for_posix(Allocator allocator, String path) { return new(allocator, path, POSIX); } @@ -182,7 +178,7 @@ fn bool Path.equals(self, Path p2) @param [in] filename *> -fn Path! Path.append(self, Allocator allocator, String filename) +fn Path? Path.append(self, Allocator allocator, String filename) { if (!self.path_string.len) return new(allocator, filename, self.env)!; assert(!is_separator(self.path_string[^1], self.env)); @@ -197,12 +193,12 @@ fn Path! Path.append(self, Allocator allocator, String filename) }; } -fn Path! Path.tappend(self, String filename) => self.append(tmem(), filename); +fn Path? Path.tappend(self, String filename) => self.append(tmem(), filename); -fn usz! start_of_base_name(String str, PathEnv path_env) @local +fn usz? start_of_base_name(String str, PathEnv path_env) @local { if (!str.len) return 0; - usz! start_slash = str.rindex_of_char('/'); + usz? start_slash = str.rindex_of_char('/'); if (path_env != PathEnv.WIN32) return start_slash + 1 ?? 0; if (try index = str.rindex_of_char('\\')) { @@ -213,7 +209,7 @@ fn usz! start_of_base_name(String str, PathEnv path_env) @local // Find the \ before "foo" usz last_index = 2 + str[2..].index_of_char('\\')!; // If they don't match, we're done - if (last_index > index) return PathResult.INVALID_PATH?; + if (last_index > index) return INVALID_PATH?; if (last_index != index) return index + 1; // Otherwise just default to the volume length. } @@ -221,12 +217,12 @@ fn usz! start_of_base_name(String str, PathEnv path_env) @local } -fn bool! String.is_absolute_path(self) => @pool() +fn bool? String.is_absolute_path(self) => @pool() { return temp(self).is_absolute(); } -fn bool! Path.is_absolute(self) +fn bool? Path.is_absolute(self) { String path_str = self.str_view(); if (!path_str.len) return false; @@ -236,7 +232,7 @@ fn bool! Path.is_absolute(self) } -fn Path! String.to_absolute_path(self, Allocator allocator) => @pool(allocator) +fn Path? String.to_absolute_path(self, Allocator allocator) => @pool(allocator) { return temp(self).absolute(allocator); } @@ -244,10 +240,10 @@ fn Path! String.to_absolute_path(self, Allocator allocator) => @pool(allocator) <* @require self.env == DEFAULT_ENV : "This method is only available on native paths" *> -fn Path! Path.absolute(self, Allocator allocator) +fn Path? Path.absolute(self, Allocator allocator) { String path_str = self.str_view(); - if (!path_str.len) return PathResult.INVALID_PATH?; + if (!path_str.len) return INVALID_PATH?; if (self.is_absolute()!) return new(allocator, path_str, self.env); if (path_str == ".") { @@ -263,7 +259,7 @@ fn Path! Path.absolute(self, Allocator allocator) const usz BUFFER_LEN = 4096; WString buffer = (WString)mem::talloc_array(Char16, BUFFER_LEN); buffer = win32::_wfullpath(buffer, path_str.to_temp_wstring()!, BUFFER_LEN); - if (!buffer) return PathResult.INVALID_PATH?; + if (!buffer) return INVALID_PATH?; return { string::from_wstring(allocator, buffer), WIN32, allocator }; }; $else @@ -272,12 +268,12 @@ fn Path! Path.absolute(self, Allocator allocator) $endif } -fn String! String.file_basename(self, Allocator allocator) => @pool(allocator) +fn String? String.file_basename(self, Allocator allocator) => @pool(allocator) { return temp(self).basename().copy(allocator); } -fn String! String.file_tbasename(self) => self.file_basename(tmem()); +fn String? String.file_tbasename(self) => self.file_basename(tmem()); fn String Path.basename(self) { @@ -287,9 +283,9 @@ fn String Path.basename(self) return path_str[basename_start..]; } -fn String! String.path_tdirname(self) => self.path_dirname(tmem()); +fn String? String.path_tdirname(self) => self.path_dirname(tmem()); -fn String! String.path_dirname(self, Allocator allocator) => @pool(allocator) +fn String? String.path_dirname(self, Allocator allocator) => @pool(allocator) { return temp(self).dirname().copy(allocator); } @@ -328,13 +324,12 @@ fn bool Path.has_extension(self, String extension) return basename[^extension.len..] == extension; } -fn String! Path.extension(self) +fn String? Path.extension(self) { String basename = self.basename(); usz index = basename.rindex_of(".")!; - // Plain ".foo" does not have an - if (index == 0) return SearchResult.MISSING?; - if (index == basename.len) return ""; + // Plain ".foo" does not have an extension + if (index == 0 || index == basename.len) return ""; return basename[index + 1..]; } @@ -345,17 +340,17 @@ fn String Path.volume_name(self) return self.path_string[:len]; } -fn Path! String.to_path(self, Allocator allocator) +fn Path? String.to_path(self, Allocator allocator) { return new(allocator, self); } -fn Path! String.to_tpath(self) +fn Path? String.to_tpath(self) { return new(tmem(), self); } -fn usz! volume_name_len(String path, PathEnv path_env) @local +fn usz? volume_name_len(String path, PathEnv path_env) @local { usz len = path.len; if (len < 2 || path_env != PathEnv.WIN32) return 0; @@ -379,10 +374,10 @@ fn usz! volume_name_len(String path, PathEnv path_env) @local base_found = i; continue; } - if (is_reserved_win32_path_char(c)) return PathResult.INVALID_PATH?; + if (is_reserved_win32_path_char(c)) return INVALID_PATH?; } if (base_found > 0 && base_found + 1 < len) return len; - return PathResult.INVALID_PATH?; + return INVALID_PATH?; case 'A'..'Z': case 'a'..'z': return path[1] == ':' ? 2 : 0; @@ -396,11 +391,11 @@ fn usz! volume_name_len(String path, PathEnv path_env) @local of the path itself. @return `The parent of the path as a non-allocated path` - @return! PathResult.NO_PARENT : `if this path does not have a parent` + @return! NO_PARENT : `if this path does not have a parent` *> -fn Path! Path.parent(self) +fn Path? Path.parent(self) { - if (self.path_string.len == 1 && is_separator(self.path_string[0], self.env)) return PathResult.NO_PARENT?; + if (self.path_string.len == 1 && is_separator(self.path_string[0], self.env)) return NO_PARENT?; foreach_r(i, c : self.path_string) { if (is_separator(c, self.env)) @@ -408,10 +403,10 @@ fn Path! Path.parent(self) return { self.path_string[:i], self.env, null }; } } - return PathResult.NO_PARENT?; + return NO_PARENT?; } -fn String! normalize(String path_str, PathEnv path_env = DEFAULT_ENV) +fn String? normalize(String path_str, PathEnv path_env = DEFAULT_ENV) { if (!path_str.len) return path_str; usz path_start = volume_name_len(path_str, path_env)!; @@ -450,7 +445,7 @@ fn String! normalize(String path_str, PathEnv path_env = DEFAULT_ENV) // The rest are names of the path elements, so check that the // characters are valid. - if (is_reserved_path_char(c, path_env)) return PathResult.INVALID_PATH?; + if (is_reserved_path_char(c, path_env)) return INVALID_PATH?; // If we have '.' after a separator if (c == '.' && previous_was_separator) @@ -483,7 +478,7 @@ fn String! normalize(String path_str, PathEnv path_env = DEFAULT_ENV) continue; case 2: // This is an error: /a/../.. - if (len == path_start && has_root) return PathResult.INVALID_PATH?; + if (len == path_start && has_root) return INVALID_PATH?; // If this .. at the start, or after ../? If so, we just copy .. if (len == path_start || @@ -557,14 +552,14 @@ fn String Path.root_directory(self) return path_str; } -def PathWalker = fn bool! (Path, bool is_dir, void*); +def PathWalker = fn bool? (Path, bool is_dir, void*); <* Walk the path recursively. PathWalker is run on every file and directory found. Return true to abort the walk. @require self.env == DEFAULT_ENV : "This method is only available on native paths" *> -fn bool! Path.walk(self, PathWalker w, void* data) +fn bool? Path.walk(self, PathWalker w, void* data) { const PATH_MAX = 512; @stack_mem(PATH_MAX; Allocator allocator) @@ -583,14 +578,14 @@ fn bool! Path.walk(self, PathWalker w, void* data) return false; } -def TraverseCallback = fn bool! (Path, bool is_dir, any data); +def TraverseCallback = fn bool? (Path, bool is_dir, any data); <* Walk the path recursively. TraverseCallback is run for every file and directory found. Return true to abort the walk. @require path.env == DEFAULT_ENV : "This method is only available on native paths" *> -fn bool! traverse(Path path, TraverseCallback callback, any data) +fn bool? traverse(Path path, TraverseCallback callback, any data) { const PATH_MAX = 512; @stack_mem(PATH_MAX; Allocator allocator) @@ -631,7 +626,7 @@ fn void Path.free(self) allocator::free(self.allocator, self.path_string.ptr); } -fn usz! Path.to_format(&self, Formatter* formatter) @dynamic +fn usz? Path.to_format(&self, Formatter* formatter) @dynamic { return formatter.print(self.str_view()); } @@ -665,23 +660,23 @@ macro bool is_reserved_path_char(char c, PathEnv path_env = DEFAULT_ENV) ? RESERVED_PATH_CHAR_WIN32[c] : RESERVED_PATH_CHAR_POSIX[c]; } -fn bool! _mkdir(Path path, bool recursive = false, MkdirPermissions permissions = NORMAL) @private +fn bool? _mkdir(Path path, bool recursive = false, MkdirPermissions permissions = NORMAL) @private { - if (!path.path_string.len) return PathResult.INVALID_PATH?; + if (!path.path_string.len) return INVALID_PATH?; if (is_dir(path)) return false; - if (exists(path)) return IoError.FILE_NOT_DIR?; + if (exists(path)) return io::FILE_NOT_DIR?; if (recursive) { if (try parent = path.parent()) mkdir(parent, true, permissions)!; } - if (!is_dir(path.parent()) ?? false) return IoError.CANNOT_READ_DIR?; + if (!is_dir(path.parent()) ?? false) return io::CANNOT_READ_DIR?; return os::native_mkdir(path, permissions); } -fn bool! _rmdir(Path path) @private +fn bool? _rmdir(Path path) @private { - if (!path.path_string.len) return PathResult.INVALID_PATH?; + if (!path.path_string.len) return INVALID_PATH?; return os::native_rmdir(path); } diff --git a/lib/std/io/stream.c3 b/lib/std/io/stream.c3 index c62373066..2bcc743c0 100644 --- a/lib/std/io/stream.c3 +++ b/lib/std/io/stream.c3 @@ -3,28 +3,28 @@ import std::math; interface InStream { - fn void! close() @optional; - fn usz! seek(isz offset, Seek seek) @optional; + fn void? close() @optional; + fn usz? seek(isz offset, Seek seek) @optional; fn usz len() @optional; - fn usz! available() @optional; - fn usz! read(char[] buffer); - fn char! read_byte(); - fn usz! write_to(OutStream out) @optional; - fn void! pushback_byte() @optional; + fn usz? available() @optional; + fn usz? read(char[] buffer); + fn char? read_byte(); + fn usz? write_to(OutStream out) @optional; + fn void? pushback_byte() @optional; } interface OutStream { - fn void! destroy() @optional; - fn void! close() @optional; - fn void! flush() @optional; - fn usz! write(char[] bytes); - fn void! write_byte(char c); - fn usz! read_to(InStream in) @optional; + fn void? destroy() @optional; + fn void? close() @optional; + fn void? flush() @optional; + fn usz? write(char[] bytes); + fn void? write_byte(char c); + fn usz? read_to(InStream in) @optional; } -fn usz! available(InStream s) +fn usz? available(InStream s) { if (&s.available) return s.available(); if (&s.seek) @@ -51,7 +51,7 @@ macro bool @is_outstream(#expr) @param [&out] ref @require @is_instream(stream) *> -macro usz! read_any(stream, any ref) +macro usz? read_any(stream, any ref) { return read_all(stream, ((char*)ref)[:ref.type.sizeof]); } @@ -61,7 +61,7 @@ macro usz! read_any(stream, any ref) @require @is_outstream(stream) @ensure return == ref.type.sizeof *> -macro usz! write_any(stream, any ref) +macro usz? write_any(stream, any ref) { return write_all(stream, ((char*)ref)[:ref.type.sizeof]); } @@ -69,18 +69,18 @@ macro usz! write_any(stream, any ref) <* @require @is_instream(stream) *> -macro usz! read_all(stream, char[] buffer) +macro usz? read_all(stream, char[] buffer) { if (buffer.len == 0) return 0; usz n = stream.read(buffer)!; - if (n != buffer.len) return IoError.UNEXPECTED_EOF?; + if (n != buffer.len) return UNEXPECTED_EOF?; return n; } <* @require @is_instream(stream) *> -macro char[]! read_fully(Allocator allocator, stream) +macro char[]? read_fully(Allocator allocator, stream) { usz len = available(stream)!; char* data = allocator::malloc_try(allocator, len)!; @@ -96,23 +96,23 @@ macro char[]! read_fully(Allocator allocator, stream) <* @require @is_outstream(stream) *> -macro usz! write_all(stream, char[] buffer) +macro usz? write_all(stream, char[] buffer) { if (buffer.len == 0) return 0; usz n = stream.write(buffer)!; - if (n != buffer.len) return IoError.INCOMPLETE_WRITE?; + if (n != buffer.len) return INCOMPLETE_WRITE?; return n; } -macro usz! read_using_read_byte(s, char[] buffer) +macro usz? read_using_read_byte(s, char[] buffer) { usz len = 0; foreach (&cptr : buffer) { - char! c = s.read_byte(); + char? c = s.read_byte(); if (catch err = c) { - if (err == IoError.EOF) return len; + if (err == io::EOF) return len; return err?; } *cptr = c; @@ -121,35 +121,35 @@ macro usz! read_using_read_byte(s, char[] buffer) return len; } -macro void! write_byte_using_write(s, char c) +macro void? write_byte_using_write(s, char c) { char[1] buff = { c }; s.write(&buff)!; } -macro char! read_byte_using_read(s) +macro char? read_byte_using_read(s) { char[1] buffer; usz read = s.read(&buffer)!; - if (read != 1) return IoError.EOF?; + if (read != 1) return io::EOF?; return buffer[0]; } -def ReadByteFn = fn char!(); +def ReadByteFn = fn char?(); -macro usz! write_using_write_byte(s, char[] bytes) +macro usz? write_using_write_byte(s, char[] bytes) { foreach (c : bytes) s.write_byte(self, c)!; return bytes.len; } -macro void! pushback_using_seek(s) +macro void? pushback_using_seek(s) { s.seek(-1, CURSOR)!; } -fn usz! copy_to(InStream in, OutStream dst, char[] buffer = {}) +fn usz? copy_to(InStream in, OutStream dst, char[] buffer = {}) { if (buffer.len) return copy_through_buffer(in, dst, buffer); if (&in.write_to) return in.write_to(dst); @@ -165,31 +165,31 @@ fn usz! copy_to(InStream in, OutStream dst, char[] buffer = {}) $endswitch } -macro usz! copy_through_buffer(InStream in, OutStream dst, char[] buffer) @local +macro usz? copy_through_buffer(InStream in, OutStream dst, char[] buffer) @local { usz total_copied; while (true) { - usz! len = in.read(buffer); + usz? len = in.read(buffer); if (catch err = len) { - if (err == IoError.EOF) return total_copied; + if (err == io::EOF) return total_copied; return err?; } if (!len) return total_copied; usz written = dst.write(buffer[:len])!; total_copied += len; - if (written != len) return IoError.INCOMPLETE_WRITE?; + if (written != len) return INCOMPLETE_WRITE?; } } -const char[?] MAX_VARS @private = { [2] = 3, [4] = 5, [8] = 10 }; +const char[*] MAX_VARS @private = { [2] = 3, [4] = 5, [8] = 10 }; <* @require @is_instream(stream) @require @typekind(x_ptr) == POINTER && $typeof(x_ptr).inner.kindof.is_int() *> -macro usz! read_varint(stream, x_ptr) +macro usz? read_varint(stream, x_ptr) { var $Type = $typefrom($typeof(x_ptr).inner); const MAX = MAX_VARS[$Type.sizeof]; @@ -198,10 +198,10 @@ macro usz! read_varint(stream, x_ptr) usz n; for (usz i = 0; i < MAX; i++) { - char! c = stream.read_byte(); + char? c = stream.read_byte(); if (catch err = c) { - if (err == IoError.EOF) return IoError.UNEXPECTED_EOF?; + if (err == io::EOF) return io::UNEXPECTED_EOF?; return err?; } n++; @@ -218,13 +218,13 @@ macro usz! read_varint(stream, x_ptr) x |= (c & 0x7F) << shift; shift += 7; } - return MathError.OVERFLOW?; + return math::OVERFLOW?; } <* @require @is_outstream(stream) @require @typekind(x).is_int() *> -macro usz! write_varint(stream, x) +macro usz? write_varint(stream, x) { var $Type = $typeof(x); const MAX = MAX_VARS[$Type.sizeof]; @@ -243,7 +243,7 @@ macro usz! write_varint(stream, x) <* @require @is_instream(stream) *> -macro ushort! read_be_ushort(stream) +macro ushort? read_be_ushort(stream) { char hi_byte = stream.read_byte()!; char lo_byte = stream.read_byte()!; @@ -253,7 +253,7 @@ macro ushort! read_be_ushort(stream) <* @require @is_instream(stream) *> -macro short! read_be_short(stream) +macro short? read_be_short(stream) { return read_be_ushort(stream); } @@ -261,7 +261,7 @@ macro short! read_be_short(stream) <* @require @is_outstream(stream) *> -macro void! write_be_short(stream, ushort s) +macro void? write_be_short(stream, ushort s) { stream.write_byte((char)(s >> 8))!; stream.write_byte((char)s)!; @@ -270,7 +270,7 @@ macro void! write_be_short(stream, ushort s) <* @require @is_instream(stream) *> -macro uint! read_be_uint(stream) +macro uint? read_be_uint(stream) { uint val = stream.read_byte()! << 24; val += stream.read_byte()! << 16; @@ -281,7 +281,7 @@ macro uint! read_be_uint(stream) <* @require @is_instream(stream) *> -macro int! read_be_int(stream) +macro int? read_be_int(stream) { return read_be_uint(stream); } @@ -289,7 +289,7 @@ macro int! read_be_int(stream) <* @require @is_outstream(stream) *> -macro void! write_be_int(stream, uint s) +macro void? write_be_int(stream, uint s) { stream.write_byte((char)(s >> 24))!; stream.write_byte((char)(s >> 16))!; @@ -300,7 +300,7 @@ macro void! write_be_int(stream, uint s) <* @require @is_instream(stream) *> -macro ulong! read_be_ulong(stream) +macro ulong? read_be_ulong(stream) { ulong val = (ulong)stream.read_byte()! << 56; val += (ulong)stream.read_byte()! << 48; @@ -315,7 +315,7 @@ macro ulong! read_be_ulong(stream) <* @require @is_instream(stream) *> -macro long! read_be_long(stream) +macro long? read_be_long(stream) { return read_be_ulong(stream); } @@ -323,7 +323,7 @@ macro long! read_be_long(stream) <* @require @is_outstream(stream) *> -macro void! write_be_long(stream, ulong s) +macro void? write_be_long(stream, ulong s) { stream.write_byte((char)(s >> 56))!; stream.write_byte((char)(s >> 48))!; @@ -338,7 +338,7 @@ macro void! write_be_long(stream, ulong s) <* @require @is_instream(stream) *> -macro uint128! read_be_uint128(stream) +macro uint128? read_be_uint128(stream) { uint128 val = (uint128)stream.read_byte()! << 120; val += (uint128)stream.read_byte()! << 112; @@ -361,7 +361,7 @@ macro uint128! read_be_uint128(stream) <* @require @is_instream(stream) *> -macro int128! read_be_int128(stream) +macro int128? read_be_int128(stream) { return read_be_uint128(stream); } @@ -369,7 +369,7 @@ macro int128! read_be_int128(stream) <* @require @is_outstream(stream) *> -macro void! write_be_int128(stream, uint128 s) +macro void? write_be_int128(stream, uint128 s) { stream.write_byte((char)(s >> 120))!; stream.write_byte((char)(s >> 112))!; @@ -393,7 +393,7 @@ macro void! write_be_int128(stream, uint128 s) @require @is_outstream(stream) @require data.len < 256 : "Data exceeded 255" *> -macro usz! write_tiny_bytearray(stream, char[] data) +macro usz? write_tiny_bytearray(stream, char[] data) { stream.write_byte((char)data.len)!; return stream.write(data) + 1; @@ -402,7 +402,7 @@ macro usz! write_tiny_bytearray(stream, char[] data) <* @require @is_instream(stream) *> -macro char[]! read_tiny_bytearray(stream, Allocator allocator) +macro char[]? read_tiny_bytearray(stream, Allocator allocator) { int len = stream.read_byte()!; if (!len) return {}; @@ -415,7 +415,7 @@ macro char[]! read_tiny_bytearray(stream, Allocator allocator) @require @is_outstream(stream) @require data.len < 0x1000 : "Data exceeded 65535" *> -macro usz! write_short_bytearray(stream, char[] data) +macro usz? write_short_bytearray(stream, char[] data) { io::write_be_short(stream, (ushort)data.len)!; return stream.write(data) + 2; @@ -424,7 +424,7 @@ macro usz! write_short_bytearray(stream, char[] data) <* @require @is_instream(stream) *> -macro char[]! read_short_bytearray(stream, Allocator allocator) +macro char[]? read_short_bytearray(stream, Allocator allocator) { int len = io::read_be_ushort(stream)!; if (!len) return {}; diff --git a/lib/std/io/stream/buffer.c3 b/lib/std/io/stream/buffer.c3 index dae6902c2..5e3dd80e7 100644 --- a/lib/std/io/stream/buffer.c3 +++ b/lib/std/io/stream/buffer.c3 @@ -24,12 +24,12 @@ fn String ReadBuffer.str_view(&self) @inline return (String)self.bytes[self.read_idx:self.write_idx - self.read_idx]; } -fn void! ReadBuffer.close(&self) @dynamic +fn void? ReadBuffer.close(&self) @dynamic { if (&self.wrapped_stream.close) self.wrapped_stream.close()!; } -fn usz! ReadBuffer.read(&self, char[] bytes) @dynamic +fn usz? ReadBuffer.read(&self, char[] bytes) @dynamic { if (self.read_idx == self.write_idx) { @@ -46,16 +46,16 @@ fn usz! ReadBuffer.read(&self, char[] bytes) @dynamic return n; } -fn char! ReadBuffer.read_byte(&self) @dynamic +fn char? ReadBuffer.read_byte(&self) @dynamic { if (self.read_idx == self.write_idx) self.refill()!; - if (self.read_idx == self.write_idx) return IoError.EOF?; + if (self.read_idx == self.write_idx) return io::EOF?; char c = self.bytes[self.read_idx]; self.read_idx++; return c; } -fn void! ReadBuffer.refill(&self) @local @inline +fn void? ReadBuffer.refill(&self) @local @inline { self.read_idx = 0; self.write_idx = self.wrapped_stream.read(self.bytes)!; @@ -85,18 +85,18 @@ fn String WriteBuffer.str_view(&self) @inline return (String)self.bytes[:self.index]; } -fn void! WriteBuffer.close(&self) @dynamic +fn void? WriteBuffer.close(&self) @dynamic { if (&self.wrapped_stream.close) return self.wrapped_stream.close(); } -fn void! WriteBuffer.flush(&self) @dynamic +fn void? WriteBuffer.flush(&self) @dynamic { self.write_pending()!; if (&self.wrapped_stream.flush) self.wrapped_stream.flush()!; } -fn usz! WriteBuffer.write(&self, char[] bytes) @dynamic +fn usz? WriteBuffer.write(&self, char[] bytes) @dynamic { usz n = self.bytes.len - self.index; if (bytes.len < n) @@ -118,7 +118,7 @@ fn usz! WriteBuffer.write(&self, char[] bytes) @dynamic return bytes.len; } -fn void! WriteBuffer.write_byte(&self, char c) @dynamic +fn void? WriteBuffer.write_byte(&self, char c) @dynamic { usz n = self.bytes.len - self.index; if (n == 0) @@ -129,8 +129,8 @@ fn void! WriteBuffer.write_byte(&self, char c) @dynamic self.index += 1; } -fn void! WriteBuffer.write_pending(&self) @local +fn void? WriteBuffer.write_pending(&self) @local { self.index -= self.wrapped_stream.write(self.bytes[:self.index])!; - if (self.index != 0) return IoError.INCOMPLETE_WRITE?; + if (self.index != 0) return INCOMPLETE_WRITE?; } diff --git a/lib/std/io/stream/bytebuffer.c3 b/lib/std/io/stream/bytebuffer.c3 index b2241f8da..3e4c9b6e8 100644 --- a/lib/std/io/stream/bytebuffer.c3 +++ b/lib/std/io/stream/bytebuffer.c3 @@ -45,7 +45,7 @@ fn void ByteBuffer.free(&self) *self = {}; } -fn usz! ByteBuffer.write(&self, char[] bytes) @dynamic +fn usz? ByteBuffer.write(&self, char[] bytes) @dynamic { usz cap = self.bytes.len - self.write_idx; if (cap < bytes.len) self.grow(bytes.len); @@ -54,7 +54,7 @@ fn usz! ByteBuffer.write(&self, char[] bytes) @dynamic return bytes.len; } -fn void! ByteBuffer.write_byte(&self, char c) @dynamic +fn void? ByteBuffer.write_byte(&self, char c) @dynamic { usz cap = self.bytes.len - self.write_idx; if (cap == 0) self.grow(1); @@ -62,13 +62,13 @@ fn void! ByteBuffer.write_byte(&self, char c) @dynamic self.write_idx++; } -fn usz! ByteBuffer.read(&self, char[] bytes) @dynamic +fn usz? ByteBuffer.read(&self, char[] bytes) @dynamic { usz readable = self.write_idx - self.read_idx; if (readable == 0) { self.has_last = false; - return IoError.EOF?; + return io::EOF?; } usz n = min(readable, bytes.len); bytes[:n] = self.bytes[self.read_idx:n]; @@ -78,13 +78,13 @@ fn usz! ByteBuffer.read(&self, char[] bytes) @dynamic return n; } -fn char! ByteBuffer.read_byte(&self) @dynamic +fn char? ByteBuffer.read_byte(&self) @dynamic { usz readable = self.write_idx - self.read_idx; if (readable == 0) { self.has_last = false; - return IoError.EOF?; + return io::EOF?; } char c = self.bytes[self.read_idx]; self.read_idx++; @@ -96,34 +96,34 @@ fn char! ByteBuffer.read_byte(&self) @dynamic <* Only the last byte of a successful read can be pushed back. *> -fn void! ByteBuffer.pushback_byte(&self) @dynamic +fn void? ByteBuffer.pushback_byte(&self) @dynamic { - if (!self.has_last) return IoError.EOF?; + if (!self.has_last) return io::EOF?; assert(self.read_idx > 0); self.read_idx--; self.has_last = false; } -fn usz! ByteBuffer.seek(&self, isz offset, Seek seek) @dynamic +fn usz? ByteBuffer.seek(&self, isz offset, Seek seek) @dynamic { switch (seek) { case SET: - if (offset < 0 || offset > self.write_idx) return IoError.INVALID_POSITION?; + if (offset < 0 || offset > self.write_idx) return INVALID_POSITION?; self.read_idx = offset; return offset; case CURSOR: if ((offset < 0 && self.read_idx < -offset) || - (offset > 0 && self.read_idx + offset > self.write_idx)) return IoError.INVALID_POSITION?; + (offset > 0 && self.read_idx + offset > self.write_idx)) return INVALID_POSITION?; self.read_idx += offset; case END: - if (offset < 0 || offset > self.write_idx) return IoError.INVALID_POSITION?; + if (offset < 0 || offset > self.write_idx) return INVALID_POSITION?; self.read_idx = self.write_idx - offset; } return self.read_idx; } -fn usz! ByteBuffer.available(&self) @inline @dynamic +fn usz? ByteBuffer.available(&self) @inline @dynamic { return self.write_idx - self.read_idx; } diff --git a/lib/std/io/stream/bytereader.c3 b/lib/std/io/stream/bytereader.c3 index ea2ae3c79..f0e3736e2 100644 --- a/lib/std/io/stream/bytereader.c3 +++ b/lib/std/io/stream/bytereader.c3 @@ -17,9 +17,9 @@ fn ByteReader* ByteReader.init(&self, char[] bytes) return self; } -fn usz! ByteReader.read(&self, char[] bytes) @dynamic +fn usz? ByteReader.read(&self, char[] bytes) @dynamic { - if (self.index >= self.bytes.len) return IoError.EOF?; + if (self.index >= self.bytes.len) return io::EOF?; usz len = min(self.bytes.len - self.index, bytes.len); if (len == 0) return 0; mem::copy(bytes.ptr, &self.bytes[self.index], len); @@ -27,19 +27,19 @@ fn usz! ByteReader.read(&self, char[] bytes) @dynamic return len; } -fn char! ByteReader.read_byte(&self) @dynamic +fn char? ByteReader.read_byte(&self) @dynamic { - if (self.index >= self.bytes.len) return IoError.EOF?; + if (self.index >= self.bytes.len) return io::EOF?; return self.bytes[self.index++]; } -fn void! ByteReader.pushback_byte(&self) @dynamic +fn void? ByteReader.pushback_byte(&self) @dynamic { - if (!self.index) return IoError.INVALID_PUSHBACK?; + if (!self.index) return INVALID_PUSHBACK?; self.index--; } -fn usz! ByteReader.seek(&self, isz offset, Seek seek) @dynamic +fn usz? ByteReader.seek(&self, isz offset, Seek seek) @dynamic { isz new_index; switch (seek) @@ -48,12 +48,12 @@ fn usz! ByteReader.seek(&self, isz offset, Seek seek) @dynamic case CURSOR: new_index = self.index + offset; case END: new_index = self.bytes.len + offset; } - if (new_index < 0) return IoError.INVALID_POSITION?; + if (new_index < 0) return INVALID_POSITION?; self.index = new_index; return new_index; } -fn usz! ByteReader.write_to(&self, OutStream writer) @dynamic +fn usz? ByteReader.write_to(&self, OutStream writer) @dynamic { if (self.index >= self.bytes.len) return 0; usz written = writer.write(self.bytes[self.index..])!; @@ -62,7 +62,7 @@ fn usz! ByteReader.write_to(&self, OutStream writer) @dynamic return written; } -fn usz! ByteReader.available(&self) @inline @dynamic +fn usz? ByteReader.available(&self) @inline @dynamic { return max(0, self.bytes.len - self.index); } \ No newline at end of file diff --git a/lib/std/io/stream/bytewriter.c3 b/lib/std/io/stream/bytewriter.c3 index afe020b74..a6a4c73a7 100644 --- a/lib/std/io/stream/bytewriter.c3 +++ b/lib/std/io/stream/bytewriter.c3 @@ -36,7 +36,7 @@ fn ByteWriter* ByteWriter.init_with_buffer(&self, char[] data) return self; } -fn void! ByteWriter.destroy(&self) @dynamic +fn void? ByteWriter.destroy(&self) @dynamic { if (!self.allocator) return; if (void* ptr = self.bytes.ptr) allocator::free(self.allocator, ptr); @@ -48,17 +48,17 @@ fn String ByteWriter.str_view(&self) @inline return (String)self.bytes[:self.index]; } -fn void! ByteWriter.ensure_capacity(&self, usz len) @inline +fn void? ByteWriter.ensure_capacity(&self, usz len) @inline { if (self.bytes.len > len) return; - if (!self.allocator) return IoError.OUT_OF_SPACE?; + if (!self.allocator) return OUT_OF_SPACE?; if (len < 16) len = 16; usz new_capacity = math::next_power_of_2(len); char* new_ptr = allocator::realloc_try(self.allocator, self.bytes.ptr, new_capacity)!; self.bytes = new_ptr[:new_capacity]; } -fn usz! ByteWriter.write(&self, char[] bytes) @dynamic +fn usz? ByteWriter.write(&self, char[] bytes) @dynamic { self.ensure_capacity(self.index + bytes.len)!; mem::copy(&self.bytes[self.index], bytes.ptr, bytes.len); @@ -66,7 +66,7 @@ fn usz! ByteWriter.write(&self, char[] bytes) @dynamic return bytes.len; } -fn void! ByteWriter.write_byte(&self, char c) @dynamic +fn void? ByteWriter.write_byte(&self, char c) @dynamic { self.ensure_capacity(self.index + 1)!; self.bytes[self.index++] = c; @@ -76,7 +76,7 @@ fn void! ByteWriter.write_byte(&self, char c) @dynamic @param [&inout] self @param reader *> -fn usz! ByteWriter.read_from(&self, InStream reader) @dynamic +fn usz? ByteWriter.read_from(&self, InStream reader) @dynamic { usz start_index = self.index; if (&reader.available) diff --git a/lib/std/io/stream/limitreader.c3 b/lib/std/io/stream/limitreader.c3 index f853f7651..2c1de2c79 100644 --- a/lib/std/io/stream/limitreader.c3 +++ b/lib/std/io/stream/limitreader.c3 @@ -16,29 +16,29 @@ fn LimitReader* LimitReader.init(&self, InStream wrapped_stream, usz limit) return self; } -fn void! LimitReader.close(&self) @dynamic +fn void? LimitReader.close(&self) @dynamic { if (&self.wrapped_stream.close) return self.wrapped_stream.close(); } -fn usz! LimitReader.read(&self, char[] bytes) @dynamic +fn usz? LimitReader.read(&self, char[] bytes) @dynamic { - if (self.limit == 0) return IoError.EOF?; + if (self.limit == 0) return io::EOF?; usz m = min(bytes.len, self.limit); usz n = self.wrapped_stream.read(bytes[:m])!; self.limit -= n; return n; } -fn char! LimitReader.read_byte(&self) @dynamic +fn char? LimitReader.read_byte(&self) @dynamic { - if (self.limit == 0) return IoError.EOF?; + if (self.limit == 0) return io::EOF?; defer try self.limit--; return self.wrapped_stream.read_byte(); } -fn usz! LimitReader.available(&self) @inline @dynamic +fn usz? LimitReader.available(&self) @inline @dynamic { return self.limit; } \ No newline at end of file diff --git a/lib/std/io/stream/multireader.c3 b/lib/std/io/stream/multireader.c3 index 1fab083e2..3aaf5b855 100644 --- a/lib/std/io/stream/multireader.c3 +++ b/lib/std/io/stream/multireader.c3 @@ -2,7 +2,7 @@ module std::io; /* MultiReader implements the InStream interface and provides a logical * concatenation of the provided readers. They are read sequentially. If all the - * data has been read, IoError.EOF is returned. + * data has been read, io::EOF is returned. */ struct MultiReader (InStream) { @@ -43,24 +43,24 @@ fn void MultiReader.free(&self) *self = {}; } -fn usz! MultiReader.read(&self, char[] bytes) @dynamic +fn usz? MultiReader.read(&self, char[] bytes) @dynamic { InStream r = self.readers[self.index]; - usz! n = r.read(bytes); + usz? n = r.read(bytes); if (catch err = n) { - if (err != IoError.EOF) return err?; + if (err != io::EOF) return err?; self.index++; if (self.index >= self.readers.len) { - return IoError.EOF?; + return io::EOF?; } return self.read(bytes); } return n; } -fn char! MultiReader.read_byte(&self) @dynamic +fn char? MultiReader.read_byte(&self) @dynamic { char[1] data; self.read(data[..])!; diff --git a/lib/std/io/stream/multiwriter.c3 b/lib/std/io/stream/multiwriter.c3 index da850c294..793f4a26d 100644 --- a/lib/std/io/stream/multiwriter.c3 +++ b/lib/std/io/stream/multiwriter.c3 @@ -40,18 +40,18 @@ fn void MultiWriter.free(&self) *self = {}; } -fn usz! MultiWriter.write(&self, char[] bytes) @dynamic +fn usz? MultiWriter.write(&self, char[] bytes) @dynamic { usz n; foreach (w : self.writers) { n = w.write(bytes)!; - if (n != bytes.len) return IoError.INCOMPLETE_WRITE?; + if (n != bytes.len) return INCOMPLETE_WRITE?; } return bytes.len; } -fn void! MultiWriter.write_byte(&self, char c) @dynamic +fn void? MultiWriter.write_byte(&self, char c) @dynamic { char[1] data; data[0] = c; diff --git a/lib/std/io/stream/scanner.c3 b/lib/std/io/stream/scanner.c3 index 5396aabc6..d885bbe02 100644 --- a/lib/std/io/stream/scanner.c3 +++ b/lib/std/io/stream/scanner.c3 @@ -35,7 +35,7 @@ fn char[] Scanner.flush(&self) @dynamic return buf; } -fn void! Scanner.close(&self) @dynamic +fn void? Scanner.close(&self) @dynamic { if (&self.wrapped_stream.close) return self.wrapped_stream.close(); } @@ -45,7 +45,7 @@ fn void! Scanner.close(&self) @dynamic @require pattern.len > 0 : "Non-empty pattern required." @require self.buf.len > pattern.len : "Pattern too large." *> -fn char[]! Scanner.scan(&self, String pattern = "\n") +fn char[]? Scanner.scan(&self, String pattern = "\n") { if (self.read_idx == 0) { @@ -65,7 +65,7 @@ fn char[]! Scanner.scan(&self, String pattern = "\n") { // Split pattern not found with maximized search, abort. // Split pattern not found and already read as much as possible. - return SearchResult.MISSING?; + return NOT_FOUND?; } // Split pattern not found: maximize the search and try one more time. self.buf[:n] = buf[..]; @@ -82,23 +82,23 @@ fn char[]! Scanner.scan(&self, String pattern = "\n") return self.buf[:n + i]; } -macro usz! Scanner.find(&self, buf, pattern) @private +macro usz? Scanner.find(&self, buf, pattern) @private { return ((String)buf).index_of(pattern); } -macro usz! Scanner.refill(&self, buf) @private +macro usz? Scanner.refill(&self, buf) @private { - usz! n = self.wrapped_stream.read(buf); + usz? n = self.wrapped_stream.read(buf); if (catch err = n) { - if (err == IoError.EOF) return SearchResult.MISSING?; + if (err == io::EOF) return NOT_FOUND?; return err?; } return n; } -fn usz! Scanner.read(&self, char[] bytes) @dynamic +fn usz? Scanner.read(&self, char[] bytes) @dynamic { usz n; if (self.pattern_idx < self.read_idx) @@ -112,7 +112,7 @@ fn usz! Scanner.read(&self, char[] bytes) @dynamic return n; } -fn char! Scanner.read_byte(&self) @dynamic +fn char? Scanner.read_byte(&self) @dynamic { if (self.pattern_idx < self.read_idx) { diff --git a/lib/std/io/stream/teereader.c3 b/lib/std/io/stream/teereader.c3 index 4d88f163b..89165f0aa 100644 --- a/lib/std/io/stream/teereader.c3 +++ b/lib/std/io/stream/teereader.c3 @@ -25,16 +25,16 @@ fn TeeReader* TeeReader.init(&self, InStream r, OutStream w) return self; } -fn usz! TeeReader.read(&self, char[] bytes) @dynamic +fn usz? TeeReader.read(&self, char[] bytes) @dynamic { usz nr, nw; nr = self.r.read(bytes)!; nw = self.w.write(bytes[:nr])!; - if (nr != nw) return IoError.GENERAL_ERROR?; + if (nr != nw) return GENERAL_ERROR?; return nr; } -fn char! TeeReader.read_byte(&self) @dynamic +fn char? TeeReader.read_byte(&self) @dynamic { char[1] data; self.read(data[..])!; diff --git a/lib/std/math/bigint.c3 b/lib/std/math/bigint.c3 index a75936d28..65f9a26e2 100644 --- a/lib/std/math/bigint.c3 +++ b/lib/std/math/bigint.c3 @@ -83,7 +83,7 @@ fn BigInt* BigInt.init_with_array(&self, uint[] values) return self; } -fn BigInt*! BigInt.init_string_radix(&self, String value, int radix) +fn BigInt*? BigInt.init_string_radix(&self, String value, int radix) { isz len = value.len; isz limit = value[0] == '-' ? 1 : 0; @@ -102,9 +102,9 @@ fn BigInt*! BigInt.init_string_radix(&self, String value, int radix) case 'a'..'z': pos_val -= 'a' - 10; default: - return NumberConversion.MALFORMED_INTEGER?; + return string::MALFORMED_INTEGER?; } - if (pos_val >= radix) return NumberConversion.MALFORMED_INTEGER?; + if (pos_val >= radix) return string::MALFORMED_INTEGER?; if (limit == 1) pos_val = -pos_val; self.add_this(multiplier.mult(from_int(pos_val))); if (i - 1 >= limit) @@ -115,9 +115,9 @@ fn BigInt*! BigInt.init_string_radix(&self, String value, int radix) switch { case limit && !self.is_negative(): - return NumberConversion.INTEGER_OVERFLOW?; + return string::INTEGER_OVERFLOW?; case !limit && self.is_negative(): - return NumberConversion.INTEGER_OVERFLOW?; + return string::INTEGER_OVERFLOW?; } return self; } @@ -506,7 +506,7 @@ fn BigInt BigInt.abs(&self) return self.is_negative() ? self.unary_minus() : *self; } -fn usz! BigInt.to_format(&self, Formatter* format) @dynamic +fn usz? BigInt.to_format(&self, Formatter* format) @dynamic { @stack_mem(4100; Allocator mem) { @@ -526,7 +526,7 @@ fn String BigInt.to_string_with_radix(&self, int radix, Allocator allocator) { if (self.is_zero()) return "0".copy(allocator); - const char[?] CHARS = "ABCDEFGHIJKLMNOPQRSTUVWXYZ"; + const char[*] CHARS = "ABCDEFGHIJKLMNOPQRSTUVWXYZ"; @stack_mem(4100; Allocator mem) { BigInt a = *self; diff --git a/lib/std/math/math.c3 b/lib/std/math/math.c3 index 3aa8b439b..686d98e23 100644 --- a/lib/std/math/math.c3 +++ b/lib/std/math/math.c3 @@ -80,15 +80,7 @@ enum RoundingMode : int TOWARD_NEG_INFINITY } -fault MathError -{ - OVERFLOW, -} - -fault MatrixError -{ - MATRIX_INVERSE_DOESNT_EXIST, -} +fault OVERFLOW, MATRIX_INVERSE_DOESNT_EXIST; def Complexf = Complex{float}; def Complex = Complex{double}; @@ -629,7 +621,7 @@ macro normalize(x) @private @return "a vector of the same type as then/else" *> -macro select(bool[] mask, then_value, else_value) +macro select(bool[<*>] mask, then_value, else_value) { return $$select(mask, then_value, else_value); } @@ -647,35 +639,35 @@ macro float float.round(float x) => $$round(x); macro float float.roundeven(float x) => $$roundeven(x); macro float float.trunc(float x) => $$trunc(x); -macro float float[].sum(float[] x, float start = 0.0) => $$reduce_fadd(x, start); -macro float float[].product(float[] x, float start = 1.0) => $$reduce_fmul(x, start); -macro float float[].max(float[] x) => $$reduce_max(x); -macro float float[].min(float[] x) => $$reduce_min(x); -macro float[] float[].ceil(float[] x) => $$ceil(x); -macro float[] float[].clamp(float[] x, float[] lower, float[] upper) => $$max(lower, $$min(x, upper)); -macro float[] float[].copysign(float[] mag, float[] sgn) => $$copysign(mag, sgn); -macro float[] float[].fma(float[] a, float[] b, float[] c) => $$fma(a, b, c); -macro float[] float[].floor(float[] x) => $$floor(x); -macro float[] float[].nearbyint(float[] x) => $$nearbyint(x); -macro float[] float[].pow(float[] x, exp) => pow(x, exp); -macro float[] float[].rint(float[] x) => $$rint(x); -macro float[] float[].round(float[] x) => $$round(x); -macro float[] float[].roundeven(float[] x) => $$roundeven(x); -macro float[] float[].trunc(float[] x) => $$trunc(x); -macro float float[].dot(float[] x, float[] y) => (x * y).sum(); -macro float float[].length(float[] x) => $$sqrt(x.dot(x)); -macro float float[].distance(float[] x, float[] y) => (x - y).length(); -macro float[] float[].normalize(float[] x) => normalize(x); -macro float[] float[].lerp(float[] x, float[] y, float amount) => lerp(x, y, amount); -macro float[] float[].reflect(float[] x, float[] y) => reflect(x, y); -macro bool float[].equals(float[] x, float[] y) => equals_vec(x, y); +macro float float[<*>].sum(float[<*>] x, float start = 0.0) => $$reduce_fadd(x, start); +macro float float[<*>].product(float[<*>] x, float start = 1.0) => $$reduce_fmul(x, start); +macro float float[<*>].max(float[<*>] x) => $$reduce_max(x); +macro float float[<*>].min(float[<*>] x) => $$reduce_min(x); +macro float[<*>] float[<*>].ceil(float[<*>] x) => $$ceil(x); +macro float[<*>] float[<*>].clamp(float[<*>] x, float[<*>] lower, float[<*>] upper) => $$max(lower, $$min(x, upper)); +macro float[<*>] float[<*>].copysign(float[<*>] mag, float[<*>] sgn) => $$copysign(mag, sgn); +macro float[<*>] float[<*>].fma(float[<*>] a, float[<*>] b, float[<*>] c) => $$fma(a, b, c); +macro float[<*>] float[<*>].floor(float[<*>] x) => $$floor(x); +macro float[<*>] float[<*>].nearbyint(float[<*>] x) => $$nearbyint(x); +macro float[<*>] float[<*>].pow(float[<*>] x, exp) => pow(x, exp); +macro float[<*>] float[<*>].rint(float[<*>] x) => $$rint(x); +macro float[<*>] float[<*>].round(float[<*>] x) => $$round(x); +macro float[<*>] float[<*>].roundeven(float[<*>] x) => $$roundeven(x); +macro float[<*>] float[<*>].trunc(float[<*>] x) => $$trunc(x); +macro float float[<*>].dot(float[<*>] x, float[<*>] y) => (x * y).sum(); +macro float float[<*>].length(float[<*>] x) => $$sqrt(x.dot(x)); +macro float float[<*>].distance(float[<*>] x, float[<*>] y) => (x - y).length(); +macro float[<*>] float[<*>].normalize(float[<*>] x) => normalize(x); +macro float[<*>] float[<*>].lerp(float[<*>] x, float[<*>] y, float amount) => lerp(x, y, amount); +macro float[<*>] float[<*>].reflect(float[<*>] x, float[<*>] y) => reflect(x, y); +macro bool float[<*>].equals(float[<*>] x, float[<*>] y) => equals_vec(x, y); -macro bool[] float[].comp_lt(float[] x, float[] y) => $$veccomplt(x, y); -macro bool[] float[].comp_le(float[] x, float[] y) => $$veccomple(x, y); -macro bool[] float[].comp_eq(float[] x, float[] y) => $$veccompeq(x, y); -macro bool[] float[].comp_gt(float[] x, float[] y) => $$veccompgt(x, y); -macro bool[] float[].comp_ge(float[] x, float[] y) => $$veccompge(x, y); -macro bool[] float[].comp_ne(float[] x, float[] y) => $$veccompne(x, y); +macro bool[<*>] float[<*>].comp_lt(float[<*>] x, float[<*>] y) => $$veccomplt(x, y); +macro bool[<*>] float[<*>].comp_le(float[<*>] x, float[<*>] y) => $$veccomple(x, y); +macro bool[<*>] float[<*>].comp_eq(float[<*>] x, float[<*>] y) => $$veccompeq(x, y); +macro bool[<*>] float[<*>].comp_gt(float[<*>] x, float[<*>] y) => $$veccompgt(x, y); +macro bool[<*>] float[<*>].comp_ge(float[<*>] x, float[<*>] y) => $$veccompge(x, y); +macro bool[<*>] float[<*>].comp_ne(float[<*>] x, float[<*>] y) => $$veccompne(x, y); macro double double.ceil(double x) => $$ceil(x); macro double double.clamp(double x, double lower, double upper) => $$max(lower, $$min(x, upper)); @@ -690,289 +682,289 @@ macro double double.round(double x) => $$round(x); macro double double.roundeven(double x) => $$roundeven(x); macro double double.trunc(double x) => $$trunc(x); -macro double double[].sum(double[] x, double start = 0.0) => $$reduce_fadd(x, start); -macro double double[].product(double[] x, double start = 1.0) => $$reduce_fmul(x, start); -macro double double[].max(double[] x) => $$reduce_fmax(x); -macro double double[].min(double[] x) => $$reduce_fmin(x); -macro double[] double[].ceil(double[] x) => $$ceil(x); -macro double[] double[].clamp(double[] x, double[] lower, double[] upper) => $$max(lower, $$min(x, upper)); -macro double[] double[].copysign(double[] mag, double[] sgn) => $$copysign(mag, sgn); -macro double[] double[].floor(double[] x) => $$floor(x); -macro double[] double[].fma(double[] a, double[] b, double[] c) => $$fma(a, b, c); -macro double[] double[].nearbyint(double[] x) => $$nearbyint(x); -macro double[] double[].pow(double[] x, exp) => pow(x, exp); -macro double[] double[].rint(double[] x) => $$rint(x); -macro double[] double[].round(double[] x) => $$round(x); -macro double[] double[].roundeven(double[] x) => $$roundeven(x); -macro double[] double[].trunc(double[] x) => $$trunc(x); -macro double double[].dot(double[] x, double[] y) => (x * y).sum(); -macro double double[].length(double[] x) => $$sqrt(x.dot(x)); -macro double double[].distance(double[] x, double[] y) => (x - y).length(); -macro double[] double[].normalize(double[] x) => normalize(x); -macro double[] double[].reflect(double[] x, double[] y) => reflect(x, y); -macro double[] double[].lerp(double[] x, double[] y, double amount) => lerp(x, y, amount); -macro bool double[].equals(double[] x, double[] y) => equals_vec(x, y); +macro double double[<*>].sum(double[<*>] x, double start = 0.0) => $$reduce_fadd(x, start); +macro double double[<*>].product(double[<*>] x, double start = 1.0) => $$reduce_fmul(x, start); +macro double double[<*>].max(double[<*>] x) => $$reduce_fmax(x); +macro double double[<*>].min(double[<*>] x) => $$reduce_fmin(x); +macro double[<*>] double[<*>].ceil(double[<*>] x) => $$ceil(x); +macro double[<*>] double[<*>].clamp(double[<*>] x, double[<*>] lower, double[<*>] upper) => $$max(lower, $$min(x, upper)); +macro double[<*>] double[<*>].copysign(double[<*>] mag, double[<*>] sgn) => $$copysign(mag, sgn); +macro double[<*>] double[<*>].floor(double[<*>] x) => $$floor(x); +macro double[<*>] double[<*>].fma(double[<*>] a, double[<*>] b, double[<*>] c) => $$fma(a, b, c); +macro double[<*>] double[<*>].nearbyint(double[<*>] x) => $$nearbyint(x); +macro double[<*>] double[<*>].pow(double[<*>] x, exp) => pow(x, exp); +macro double[<*>] double[<*>].rint(double[<*>] x) => $$rint(x); +macro double[<*>] double[<*>].round(double[<*>] x) => $$round(x); +macro double[<*>] double[<*>].roundeven(double[<*>] x) => $$roundeven(x); +macro double[<*>] double[<*>].trunc(double[<*>] x) => $$trunc(x); +macro double double[<*>].dot(double[<*>] x, double[<*>] y) => (x * y).sum(); +macro double double[<*>].length(double[<*>] x) => $$sqrt(x.dot(x)); +macro double double[<*>].distance(double[<*>] x, double[<*>] y) => (x - y).length(); +macro double[<*>] double[<*>].normalize(double[<*>] x) => normalize(x); +macro double[<*>] double[<*>].reflect(double[<*>] x, double[<*>] y) => reflect(x, y); +macro double[<*>] double[<*>].lerp(double[<*>] x, double[<*>] y, double amount) => lerp(x, y, amount); +macro bool double[<*>].equals(double[<*>] x, double[<*>] y) => equals_vec(x, y); -macro bool[] double[].comp_lt(double[] x, double[] y) => $$veccomplt(x, y); -macro bool[] double[].comp_le(double[] x, double[] y) => $$veccomple(x, y); -macro bool[] double[].comp_eq(double[] x, double[] y) => $$veccompeq(x, y); -macro bool[] double[].comp_gt(double[] x, double[] y) => $$veccompgt(x, y); -macro bool[] double[].comp_ge(double[] x, double[] y) => $$veccompge(x, y); -macro bool[] double[].comp_ne(double[] x, double[] y) => $$veccompne(x, y); +macro bool[<*>] double[<*>].comp_lt(double[<*>] x, double[<*>] y) => $$veccomplt(x, y); +macro bool[<*>] double[<*>].comp_le(double[<*>] x, double[<*>] y) => $$veccomple(x, y); +macro bool[<*>] double[<*>].comp_eq(double[<*>] x, double[<*>] y) => $$veccompeq(x, y); +macro bool[<*>] double[<*>].comp_gt(double[<*>] x, double[<*>] y) => $$veccompgt(x, y); +macro bool[<*>] double[<*>].comp_ge(double[<*>] x, double[<*>] y) => $$veccompge(x, y); +macro bool[<*>] double[<*>].comp_ne(double[<*>] x, double[<*>] y) => $$veccompne(x, y); -macro bool[] ichar[].comp_lt(ichar[] x, ichar[] y) => $$veccomplt(x, y); -macro bool[] ichar[].comp_le(ichar[] x, ichar[] y) => $$veccomple(x, y); -macro bool[] ichar[].comp_eq(ichar[] x, ichar[] y) => $$veccompeq(x, y); -macro bool[] ichar[].comp_gt(ichar[] x, ichar[] y) => $$veccompgt(x, y); -macro bool[] ichar[].comp_ge(ichar[] x, ichar[] y) => $$veccompge(x, y); -macro bool[] ichar[].comp_ne(ichar[] x, ichar[] y) => $$veccompne(x, y); +macro bool[<*>] ichar[<*>].comp_lt(ichar[<*>] x, ichar[<*>] y) => $$veccomplt(x, y); +macro bool[<*>] ichar[<*>].comp_le(ichar[<*>] x, ichar[<*>] y) => $$veccomple(x, y); +macro bool[<*>] ichar[<*>].comp_eq(ichar[<*>] x, ichar[<*>] y) => $$veccompeq(x, y); +macro bool[<*>] ichar[<*>].comp_gt(ichar[<*>] x, ichar[<*>] y) => $$veccompgt(x, y); +macro bool[<*>] ichar[<*>].comp_ge(ichar[<*>] x, ichar[<*>] y) => $$veccompge(x, y); +macro bool[<*>] ichar[<*>].comp_ne(ichar[<*>] x, ichar[<*>] y) => $$veccompne(x, y); -macro ichar ichar[].sum(ichar[] x) => $$reduce_add(x); -macro ichar ichar[].product(ichar[] x) => $$reduce_mul(x); -macro ichar ichar[].and(ichar[] x) => $$reduce_and(x); -macro ichar ichar[].or(ichar[] x) => $$reduce_or(x); -macro ichar ichar[].xor(ichar[] x) => $$reduce_xor(x); -macro ichar ichar[].max(ichar[] x) => $$reduce_max(x); -macro ichar ichar[].min(ichar[] x) => $$reduce_min(x); -macro ichar ichar[].dot(ichar[] x, ichar[] y) => (x * y).sum(); +macro ichar ichar[<*>].sum(ichar[<*>] x) => $$reduce_add(x); +macro ichar ichar[<*>].product(ichar[<*>] x) => $$reduce_mul(x); +macro ichar ichar[<*>].and(ichar[<*>] x) => $$reduce_and(x); +macro ichar ichar[<*>].or(ichar[<*>] x) => $$reduce_or(x); +macro ichar ichar[<*>].xor(ichar[<*>] x) => $$reduce_xor(x); +macro ichar ichar[<*>].max(ichar[<*>] x) => $$reduce_max(x); +macro ichar ichar[<*>].min(ichar[<*>] x) => $$reduce_min(x); +macro ichar ichar[<*>].dot(ichar[<*>] x, ichar[<*>] y) => (x * y).sum(); -macro bool[] short[].comp_lt(short[] x, short[] y) => $$veccomplt(x, y); -macro bool[] short[].comp_le(short[] x, short[] y) => $$veccomple(x, y); -macro bool[] short[].comp_eq(short[] x, short[] y) => $$veccompeq(x, y); -macro bool[] short[].comp_gt(short[] x, short[] y) => $$veccompgt(x, y); -macro bool[] short[].comp_ge(short[] x, short[] y) => $$veccompge(x, y); -macro bool[] short[].comp_ne(short[] x, short[] y) => $$veccompne(x, y); +macro bool[<*>] short[<*>].comp_lt(short[<*>] x, short[<*>] y) => $$veccomplt(x, y); +macro bool[<*>] short[<*>].comp_le(short[<*>] x, short[<*>] y) => $$veccomple(x, y); +macro bool[<*>] short[<*>].comp_eq(short[<*>] x, short[<*>] y) => $$veccompeq(x, y); +macro bool[<*>] short[<*>].comp_gt(short[<*>] x, short[<*>] y) => $$veccompgt(x, y); +macro bool[<*>] short[<*>].comp_ge(short[<*>] x, short[<*>] y) => $$veccompge(x, y); +macro bool[<*>] short[<*>].comp_ne(short[<*>] x, short[<*>] y) => $$veccompne(x, y); -macro short short[].sum(short[] x) => $$reduce_add(x); -macro short short[].product(short[] x) => $$reduce_mul(x); -macro short short[].and(short[] x) => $$reduce_and(x); -macro short short[].or(short[] x) => $$reduce_or(x); -macro short short[].xor(short[] x) => $$reduce_xor(x); -macro short short[].max(short[] x) => $$reduce_max(x); -macro short short[].min(short[] x) => $$reduce_min(x); -macro short short[].dot(short[] x, short[] y) => (x * y).sum(); +macro short short[<*>].sum(short[<*>] x) => $$reduce_add(x); +macro short short[<*>].product(short[<*>] x) => $$reduce_mul(x); +macro short short[<*>].and(short[<*>] x) => $$reduce_and(x); +macro short short[<*>].or(short[<*>] x) => $$reduce_or(x); +macro short short[<*>].xor(short[<*>] x) => $$reduce_xor(x); +macro short short[<*>].max(short[<*>] x) => $$reduce_max(x); +macro short short[<*>].min(short[<*>] x) => $$reduce_min(x); +macro short short[<*>].dot(short[<*>] x, short[<*>] y) => (x * y).sum(); -macro bool[] int[].comp_lt(int[] x, int[] y) => $$veccomplt(x, y); -macro bool[] int[].comp_le(int[] x, int[] y) => $$veccomple(x, y); -macro bool[] int[].comp_eq(int[] x, int[] y) => $$veccompeq(x, y); -macro bool[] int[].comp_gt(int[] x, int[] y) => $$veccompgt(x, y); -macro bool[] int[].comp_ge(int[] x, int[] y) => $$veccompge(x, y); -macro bool[] int[].comp_ne(int[] x, int[] y) => $$veccompne(x, y); +macro bool[<*>] int[<*>].comp_lt(int[<*>] x, int[<*>] y) => $$veccomplt(x, y); +macro bool[<*>] int[<*>].comp_le(int[<*>] x, int[<*>] y) => $$veccomple(x, y); +macro bool[<*>] int[<*>].comp_eq(int[<*>] x, int[<*>] y) => $$veccompeq(x, y); +macro bool[<*>] int[<*>].comp_gt(int[<*>] x, int[<*>] y) => $$veccompgt(x, y); +macro bool[<*>] int[<*>].comp_ge(int[<*>] x, int[<*>] y) => $$veccompge(x, y); +macro bool[<*>] int[<*>].comp_ne(int[<*>] x, int[<*>] y) => $$veccompne(x, y); -macro int int[].sum(int[] x) => $$reduce_add(x); -macro int int[].product(int[] x) => $$reduce_mul(x); -macro int int[].and(int[] x) => $$reduce_and(x); -macro int int[].or(int[] x) => $$reduce_or(x); -macro int int[].xor(int[] x) => $$reduce_xor(x); -macro int int[].max(int[] x) => $$reduce_max(x); -macro int int[].min(int[] x) => $$reduce_min(x); -macro int int[].dot(int[] x, int[] y) => (x * y).sum(); +macro int int[<*>].sum(int[<*>] x) => $$reduce_add(x); +macro int int[<*>].product(int[<*>] x) => $$reduce_mul(x); +macro int int[<*>].and(int[<*>] x) => $$reduce_and(x); +macro int int[<*>].or(int[<*>] x) => $$reduce_or(x); +macro int int[<*>].xor(int[<*>] x) => $$reduce_xor(x); +macro int int[<*>].max(int[<*>] x) => $$reduce_max(x); +macro int int[<*>].min(int[<*>] x) => $$reduce_min(x); +macro int int[<*>].dot(int[<*>] x, int[<*>] y) => (x * y).sum(); -macro bool[] long[].comp_lt(long[] x, long[] y) => $$veccomplt(x, y); -macro bool[] long[].comp_le(long[] x, long[] y) => $$veccomple(x, y); -macro bool[] long[].comp_eq(long[] x, long[] y) => $$veccompeq(x, y); -macro bool[] long[].comp_gt(long[] x, long[] y) => $$veccompgt(x, y); -macro bool[] long[].comp_ge(long[] x, long[] y) => $$veccompge(x, y); -macro bool[] long[].comp_ne(long[] x, long[] y) => $$veccompne(x, y); -macro long long[].sum(long[] x) => $$reduce_add(x); -macro long long[].product(long[] x) => $$reduce_mul(x); -macro long long[].and(long[] x) => $$reduce_and(x); -macro long long[].or(long[] x) => $$reduce_or(x); -macro long long[].xor(long[] x) => $$reduce_xor(x); -macro long long[].max(long[] x) => $$reduce_max(x); -macro long long[].min(long[] x) => $$reduce_min(x); -macro long long[].dot(long[] x, long[] y) => (x * y).sum(); +macro bool[<*>] long[<*>].comp_lt(long[<*>] x, long[<*>] y) => $$veccomplt(x, y); +macro bool[<*>] long[<*>].comp_le(long[<*>] x, long[<*>] y) => $$veccomple(x, y); +macro bool[<*>] long[<*>].comp_eq(long[<*>] x, long[<*>] y) => $$veccompeq(x, y); +macro bool[<*>] long[<*>].comp_gt(long[<*>] x, long[<*>] y) => $$veccompgt(x, y); +macro bool[<*>] long[<*>].comp_ge(long[<*>] x, long[<*>] y) => $$veccompge(x, y); +macro bool[<*>] long[<*>].comp_ne(long[<*>] x, long[<*>] y) => $$veccompne(x, y); +macro long long[<*>].sum(long[<*>] x) => $$reduce_add(x); +macro long long[<*>].product(long[<*>] x) => $$reduce_mul(x); +macro long long[<*>].and(long[<*>] x) => $$reduce_and(x); +macro long long[<*>].or(long[<*>] x) => $$reduce_or(x); +macro long long[<*>].xor(long[<*>] x) => $$reduce_xor(x); +macro long long[<*>].max(long[<*>] x) => $$reduce_max(x); +macro long long[<*>].min(long[<*>] x) => $$reduce_min(x); +macro long long[<*>].dot(long[<*>] x, long[<*>] y) => (x * y).sum(); -macro bool[] int128[].comp_lt(int128[] x, int128[] y) => $$veccomplt(x, y); -macro bool[] int128[].comp_le(int128[] x, int128[] y) => $$veccomple(x, y); -macro bool[] int128[].comp_eq(int128[] x, int128[] y) => $$veccompeq(x, y); -macro bool[] int128[].comp_gt(int128[] x, int128[] y) => $$veccompgt(x, y); -macro bool[] int128[].comp_ge(int128[] x, int128[] y) => $$veccompge(x, y); -macro bool[] int128[].comp_ne(int128[] x, int128[] y) => $$veccompne(x, y); -macro int128 int128[].sum(int128[] x) => $$reduce_add(x); -macro int128 int128[].product(int128[] x) => $$reduce_mul(x); -macro int128 int128[].and(int128[] x) => $$reduce_and(x); -macro int128 int128[].or(int128[] x) => $$reduce_or(x); -macro int128 int128[].xor(int128[] x) => $$reduce_xor(x); -macro int128 int128[].max(int128[] x) => $$reduce_max(x); -macro int128 int128[].min(int128[] x) => $$reduce_min(x); -macro int128 int128[].dot(int128[] x, int128[] y) => (x * y).sum(); +macro bool[<*>] int128[<*>].comp_lt(int128[<*>] x, int128[<*>] y) => $$veccomplt(x, y); +macro bool[<*>] int128[<*>].comp_le(int128[<*>] x, int128[<*>] y) => $$veccomple(x, y); +macro bool[<*>] int128[<*>].comp_eq(int128[<*>] x, int128[<*>] y) => $$veccompeq(x, y); +macro bool[<*>] int128[<*>].comp_gt(int128[<*>] x, int128[<*>] y) => $$veccompgt(x, y); +macro bool[<*>] int128[<*>].comp_ge(int128[<*>] x, int128[<*>] y) => $$veccompge(x, y); +macro bool[<*>] int128[<*>].comp_ne(int128[<*>] x, int128[<*>] y) => $$veccompne(x, y); +macro int128 int128[<*>].sum(int128[<*>] x) => $$reduce_add(x); +macro int128 int128[<*>].product(int128[<*>] x) => $$reduce_mul(x); +macro int128 int128[<*>].and(int128[<*>] x) => $$reduce_and(x); +macro int128 int128[<*>].or(int128[<*>] x) => $$reduce_or(x); +macro int128 int128[<*>].xor(int128[<*>] x) => $$reduce_xor(x); +macro int128 int128[<*>].max(int128[<*>] x) => $$reduce_max(x); +macro int128 int128[<*>].min(int128[<*>] x) => $$reduce_min(x); +macro int128 int128[<*>].dot(int128[<*>] x, int128[<*>] y) => (x * y).sum(); -macro bool[] bool[].comp_lt(bool[] x, bool[] y) => $$veccomplt(x, y); -macro bool[] bool[].comp_le(bool[] x, bool[] y) => $$veccomple(x, y); -macro bool[] bool[].comp_eq(bool[] x, bool[] y) => $$veccompeq(x, y); -macro bool[] bool[].comp_gt(bool[] x, bool[] y) => $$veccompgt(x, y); -macro bool[] bool[].comp_ge(bool[] x, bool[] y) => $$veccompge(x, y); -macro bool[] bool[].comp_ne(bool[] x, bool[] y) => $$veccompne(x, y); +macro bool[<*>] bool[<*>].comp_lt(bool[<*>] x, bool[<*>] y) => $$veccomplt(x, y); +macro bool[<*>] bool[<*>].comp_le(bool[<*>] x, bool[<*>] y) => $$veccomple(x, y); +macro bool[<*>] bool[<*>].comp_eq(bool[<*>] x, bool[<*>] y) => $$veccompeq(x, y); +macro bool[<*>] bool[<*>].comp_gt(bool[<*>] x, bool[<*>] y) => $$veccompgt(x, y); +macro bool[<*>] bool[<*>].comp_ge(bool[<*>] x, bool[<*>] y) => $$veccompge(x, y); +macro bool[<*>] bool[<*>].comp_ne(bool[<*>] x, bool[<*>] y) => $$veccompne(x, y); -macro bool bool[].sum(bool[] x) => $$reduce_add(x); -macro bool bool[].product(bool[] x) => $$reduce_mul(x); -macro bool bool[].and(bool[] x) => $$reduce_and(x); -macro bool bool[].or(bool[] x) => $$reduce_or(x); -macro bool bool[].xor(bool[] x) => $$reduce_xor(x); -macro bool bool[].max(bool[] x) => $$reduce_max(x); -macro bool bool[].min(bool[] x) => $$reduce_min(x); +macro bool bool[<*>].sum(bool[<*>] x) => $$reduce_add(x); +macro bool bool[<*>].product(bool[<*>] x) => $$reduce_mul(x); +macro bool bool[<*>].and(bool[<*>] x) => $$reduce_and(x); +macro bool bool[<*>].or(bool[<*>] x) => $$reduce_or(x); +macro bool bool[<*>].xor(bool[<*>] x) => $$reduce_xor(x); +macro bool bool[<*>].max(bool[<*>] x) => $$reduce_max(x); +macro bool bool[<*>].min(bool[<*>] x) => $$reduce_min(x); -macro bool[] char[].comp_lt(char[] x, char[] y) => $$veccomplt(x, y); -macro bool[] char[].comp_le(char[] x, char[] y) => $$veccomple(x, y); -macro bool[] char[].comp_eq(char[] x, char[] y) => $$veccompeq(x, y); -macro bool[] char[].comp_gt(char[] x, char[] y) => $$veccompgt(x, y); -macro bool[] char[].comp_ge(char[] x, char[] y) => $$veccompge(x, y); -macro bool[] char[].comp_ne(char[] x, char[] y) => $$veccompne(x, y); +macro bool[<*>] char[<*>].comp_lt(char[<*>] x, char[<*>] y) => $$veccomplt(x, y); +macro bool[<*>] char[<*>].comp_le(char[<*>] x, char[<*>] y) => $$veccomple(x, y); +macro bool[<*>] char[<*>].comp_eq(char[<*>] x, char[<*>] y) => $$veccompeq(x, y); +macro bool[<*>] char[<*>].comp_gt(char[<*>] x, char[<*>] y) => $$veccompgt(x, y); +macro bool[<*>] char[<*>].comp_ge(char[<*>] x, char[<*>] y) => $$veccompge(x, y); +macro bool[<*>] char[<*>].comp_ne(char[<*>] x, char[<*>] y) => $$veccompne(x, y); -macro char char[].sum(char[] x) => $$reduce_add(x); -macro char char[].product(char[] x) => $$reduce_mul(x); -macro char char[].and(char[] x) => $$reduce_and(x); -macro char char[].or(char[] x) => $$reduce_or(x); -macro char char[].xor(char[] x) => $$reduce_xor(x); -macro char char[].max(char[] x) => $$reduce_max(x); -macro char char[].min(char[] x) => $$reduce_min(x); -macro char char[].dot(char[] x, char[] y) => (x * y).sum(); +macro char char[<*>].sum(char[<*>] x) => $$reduce_add(x); +macro char char[<*>].product(char[<*>] x) => $$reduce_mul(x); +macro char char[<*>].and(char[<*>] x) => $$reduce_and(x); +macro char char[<*>].or(char[<*>] x) => $$reduce_or(x); +macro char char[<*>].xor(char[<*>] x) => $$reduce_xor(x); +macro char char[<*>].max(char[<*>] x) => $$reduce_max(x); +macro char char[<*>].min(char[<*>] x) => $$reduce_min(x); +macro char char[<*>].dot(char[<*>] x, char[<*>] y) => (x * y).sum(); -macro bool[] ushort[].comp_lt(ushort[] x, ushort[] y) => $$veccomplt(x, y); -macro bool[] ushort[].comp_le(ushort[] x, ushort[] y) => $$veccomple(x, y); -macro bool[] ushort[].comp_eq(ushort[] x, ushort[] y) => $$veccompeq(x, y); -macro bool[] ushort[].comp_gt(ushort[] x, ushort[] y) => $$veccompgt(x, y); -macro bool[] ushort[].comp_ge(ushort[] x, ushort[] y) => $$veccompge(x, y); -macro bool[] ushort[].comp_ne(ushort[] x, ushort[] y) => $$veccompne(x, y); +macro bool[<*>] ushort[<*>].comp_lt(ushort[<*>] x, ushort[<*>] y) => $$veccomplt(x, y); +macro bool[<*>] ushort[<*>].comp_le(ushort[<*>] x, ushort[<*>] y) => $$veccomple(x, y); +macro bool[<*>] ushort[<*>].comp_eq(ushort[<*>] x, ushort[<*>] y) => $$veccompeq(x, y); +macro bool[<*>] ushort[<*>].comp_gt(ushort[<*>] x, ushort[<*>] y) => $$veccompgt(x, y); +macro bool[<*>] ushort[<*>].comp_ge(ushort[<*>] x, ushort[<*>] y) => $$veccompge(x, y); +macro bool[<*>] ushort[<*>].comp_ne(ushort[<*>] x, ushort[<*>] y) => $$veccompne(x, y); -macro ushort ushort[].sum(ushort[] x) => $$reduce_add(x); -macro ushort ushort[].product(ushort[] x) => $$reduce_mul(x); -macro ushort ushort[].and(ushort[] x) => $$reduce_and(x); -macro ushort ushort[].or(ushort[] x) => $$reduce_or(x); -macro ushort ushort[].xor(ushort[] x) => $$reduce_xor(x); -macro ushort ushort[].max(ushort[] x) => $$reduce_max(x); -macro ushort ushort[].min(ushort[] x) => $$reduce_min(x); -macro ushort ushort[].dot(ushort[] x, ushort[] y) => (x * y).sum(); +macro ushort ushort[<*>].sum(ushort[<*>] x) => $$reduce_add(x); +macro ushort ushort[<*>].product(ushort[<*>] x) => $$reduce_mul(x); +macro ushort ushort[<*>].and(ushort[<*>] x) => $$reduce_and(x); +macro ushort ushort[<*>].or(ushort[<*>] x) => $$reduce_or(x); +macro ushort ushort[<*>].xor(ushort[<*>] x) => $$reduce_xor(x); +macro ushort ushort[<*>].max(ushort[<*>] x) => $$reduce_max(x); +macro ushort ushort[<*>].min(ushort[<*>] x) => $$reduce_min(x); +macro ushort ushort[<*>].dot(ushort[<*>] x, ushort[<*>] y) => (x * y).sum(); -macro bool[] uint[].comp_lt(uint[] x, uint[] y) => $$veccomplt(x, y); -macro bool[] uint[].comp_le(uint[] x, uint[] y) => $$veccomple(x, y); -macro bool[] uint[].comp_eq(uint[] x, uint[] y) => $$veccompeq(x, y); -macro bool[] uint[].comp_gt(uint[] x, uint[] y) => $$veccompgt(x, y); -macro bool[] uint[].comp_ge(uint[] x, uint[] y) => $$veccompge(x, y); -macro bool[] uint[].comp_ne(uint[] x, uint[] y) => $$veccompne(x, y); +macro bool[<*>] uint[<*>].comp_lt(uint[<*>] x, uint[<*>] y) => $$veccomplt(x, y); +macro bool[<*>] uint[<*>].comp_le(uint[<*>] x, uint[<*>] y) => $$veccomple(x, y); +macro bool[<*>] uint[<*>].comp_eq(uint[<*>] x, uint[<*>] y) => $$veccompeq(x, y); +macro bool[<*>] uint[<*>].comp_gt(uint[<*>] x, uint[<*>] y) => $$veccompgt(x, y); +macro bool[<*>] uint[<*>].comp_ge(uint[<*>] x, uint[<*>] y) => $$veccompge(x, y); +macro bool[<*>] uint[<*>].comp_ne(uint[<*>] x, uint[<*>] y) => $$veccompne(x, y); -macro uint uint[].sum(uint[] x) => $$reduce_add(x); -macro uint uint[].product(uint[] x) => $$reduce_mul(x); -macro uint uint[].and(uint[] x) => $$reduce_and(x); -macro uint uint[].or(uint[] x) => $$reduce_or(x); -macro uint uint[].xor(uint[] x) => $$reduce_xor(x); -macro uint uint[].max(uint[] x) => $$reduce_max(x); -macro uint uint[].min(uint[] x) => $$reduce_min(x); -macro uint uint[].dot(uint[] x, uint[] y) => (x * y).sum(); +macro uint uint[<*>].sum(uint[<*>] x) => $$reduce_add(x); +macro uint uint[<*>].product(uint[<*>] x) => $$reduce_mul(x); +macro uint uint[<*>].and(uint[<*>] x) => $$reduce_and(x); +macro uint uint[<*>].or(uint[<*>] x) => $$reduce_or(x); +macro uint uint[<*>].xor(uint[<*>] x) => $$reduce_xor(x); +macro uint uint[<*>].max(uint[<*>] x) => $$reduce_max(x); +macro uint uint[<*>].min(uint[<*>] x) => $$reduce_min(x); +macro uint uint[<*>].dot(uint[<*>] x, uint[<*>] y) => (x * y).sum(); -macro bool[] ulong[].comp_lt(ulong[] x, ulong[] y) => $$veccomplt(x, y); -macro bool[] ulong[].comp_le(ulong[] x, ulong[] y) => $$veccomple(x, y); -macro bool[] ulong[].comp_eq(ulong[] x, ulong[] y) => $$veccompeq(x, y); -macro bool[] ulong[].comp_gt(ulong[] x, ulong[] y) => $$veccompgt(x, y); -macro bool[] ulong[].comp_ge(ulong[] x, ulong[] y) => $$veccompge(x, y); -macro bool[] ulong[].comp_ne(ulong[] x, ulong[] y) => $$veccompne(x, y); +macro bool[<*>] ulong[<*>].comp_lt(ulong[<*>] x, ulong[<*>] y) => $$veccomplt(x, y); +macro bool[<*>] ulong[<*>].comp_le(ulong[<*>] x, ulong[<*>] y) => $$veccomple(x, y); +macro bool[<*>] ulong[<*>].comp_eq(ulong[<*>] x, ulong[<*>] y) => $$veccompeq(x, y); +macro bool[<*>] ulong[<*>].comp_gt(ulong[<*>] x, ulong[<*>] y) => $$veccompgt(x, y); +macro bool[<*>] ulong[<*>].comp_ge(ulong[<*>] x, ulong[<*>] y) => $$veccompge(x, y); +macro bool[<*>] ulong[<*>].comp_ne(ulong[<*>] x, ulong[<*>] y) => $$veccompne(x, y); -macro ulong ulong[].sum(ulong[] x) => $$reduce_add(x); -macro ulong ulong[].product(ulong[] x) => $$reduce_mul(x); -macro ulong ulong[].and(ulong[] x) => $$reduce_and(x); -macro ulong ulong[].or(ulong[] x) => $$reduce_or(x); -macro ulong ulong[].xor(ulong[] x) => $$reduce_xor(x); -macro ulong ulong[].max(ulong[] x) => $$reduce_max(x); -macro ulong ulong[].min(ulong[] x) => $$reduce_min(x); -macro ulong ulong[].dot(ulong[] x, ulong[] y) => (x * y).sum(); +macro ulong ulong[<*>].sum(ulong[<*>] x) => $$reduce_add(x); +macro ulong ulong[<*>].product(ulong[<*>] x) => $$reduce_mul(x); +macro ulong ulong[<*>].and(ulong[<*>] x) => $$reduce_and(x); +macro ulong ulong[<*>].or(ulong[<*>] x) => $$reduce_or(x); +macro ulong ulong[<*>].xor(ulong[<*>] x) => $$reduce_xor(x); +macro ulong ulong[<*>].max(ulong[<*>] x) => $$reduce_max(x); +macro ulong ulong[<*>].min(ulong[<*>] x) => $$reduce_min(x); +macro ulong ulong[<*>].dot(ulong[<*>] x, ulong[<*>] y) => (x * y).sum(); -macro bool[] uint128[].comp_lt(uint128[] x, uint128[] y) => $$veccomplt(x, y); -macro bool[] uint128[].comp_le(uint128[] x, uint128[] y) => $$veccomple(x, y); -macro bool[] uint128[].comp_eq(uint128[] x, uint128[] y) => $$veccompeq(x, y); -macro bool[] uint128[].comp_gt(uint128[] x, uint128[] y) => $$veccompgt(x, y); -macro bool[] uint128[].comp_ge(uint128[] x, uint128[] y) => $$veccompge(x, y); -macro bool[] uint128[].comp_ne(uint128[] x, uint128[] y) => $$veccompne(x, y); +macro bool[<*>] uint128[<*>].comp_lt(uint128[<*>] x, uint128[<*>] y) => $$veccomplt(x, y); +macro bool[<*>] uint128[<*>].comp_le(uint128[<*>] x, uint128[<*>] y) => $$veccomple(x, y); +macro bool[<*>] uint128[<*>].comp_eq(uint128[<*>] x, uint128[<*>] y) => $$veccompeq(x, y); +macro bool[<*>] uint128[<*>].comp_gt(uint128[<*>] x, uint128[<*>] y) => $$veccompgt(x, y); +macro bool[<*>] uint128[<*>].comp_ge(uint128[<*>] x, uint128[<*>] y) => $$veccompge(x, y); +macro bool[<*>] uint128[<*>].comp_ne(uint128[<*>] x, uint128[<*>] y) => $$veccompne(x, y); -macro uint128 uint128[].sum(uint128[] x) => $$reduce_add(x); -macro uint128 uint128[].product(uint128[] x) => $$reduce_mul(x); -macro uint128 uint128[].and(uint128[] x) => $$reduce_and(x); -macro uint128 uint128[].or(uint128[] x) => $$reduce_or(x); -macro uint128 uint128[].xor(uint128[] x) => $$reduce_xor(x); -macro uint128 uint128[].max(uint128[] x) => $$reduce_max(x); -macro uint128 uint128[].min(uint128[] x) => $$reduce_min(x); -macro uint128 uint128[].dot(uint128[] x, uint128[] y) => (x * y).sum(); +macro uint128 uint128[<*>].sum(uint128[<*>] x) => $$reduce_add(x); +macro uint128 uint128[<*>].product(uint128[<*>] x) => $$reduce_mul(x); +macro uint128 uint128[<*>].and(uint128[<*>] x) => $$reduce_and(x); +macro uint128 uint128[<*>].or(uint128[<*>] x) => $$reduce_or(x); +macro uint128 uint128[<*>].xor(uint128[<*>] x) => $$reduce_xor(x); +macro uint128 uint128[<*>].max(uint128[<*>] x) => $$reduce_max(x); +macro uint128 uint128[<*>].min(uint128[<*>] x) => $$reduce_min(x); +macro uint128 uint128[<*>].dot(uint128[<*>] x, uint128[<*>] y) => (x * y).sum(); macro char char.sat_add(char x, char y) => $$sat_add(x, y); macro char char.sat_sub(char x, char y) => $$sat_sub(x, y); macro char char.sat_mul(char x, char y) => $$sat_mul(x, y); macro char char.sat_shl(char x, char y) => $$sat_shl(x, y); -macro char! char.overflow_add(char x, char y) => overflow_add_helper(x, y); -macro char! char.overflow_sub(char x, char y) => overflow_sub_helper(x, y); -macro char! char.overflow_mul(char x, char y) => overflow_mul_helper(x, y); +macro char? char.overflow_add(char x, char y) => overflow_add_helper(x, y); +macro char? char.overflow_sub(char x, char y) => overflow_sub_helper(x, y); +macro char? char.overflow_mul(char x, char y) => overflow_mul_helper(x, y); macro ichar ichar.sat_add(ichar x, ichar y) => $$sat_add(x, y); macro ichar ichar.sat_sub(ichar x, ichar y) => $$sat_sub(x, y); macro ichar ichar.sat_mul(ichar x, ichar y) => $$sat_mul(x, y); macro ichar ichar.sat_shl(ichar x, ichar y) => $$sat_shl(x, y); -macro ichar! ichar.overflow_add(ichar x, ichar y) => overflow_add_helper(x, y); -macro ichar! ichar.overflow_sub(ichar x, ichar y) => overflow_sub_helper(x, y); -macro ichar! ichar.overflow_mul(ichar x, ichar y) => overflow_mul_helper(x, y); +macro ichar? ichar.overflow_add(ichar x, ichar y) => overflow_add_helper(x, y); +macro ichar? ichar.overflow_sub(ichar x, ichar y) => overflow_sub_helper(x, y); +macro ichar? ichar.overflow_mul(ichar x, ichar y) => overflow_mul_helper(x, y); macro ushort ushort.sat_add(ushort x, ushort y) => $$sat_add(x, y); macro ushort ushort.sat_sub(ushort x, ushort y) => $$sat_sub(x, y); macro ushort ushort.sat_mul(ushort x, ushort y) => $$sat_mul(x, y); macro ushort ushort.sat_shl(ushort x, ushort y) => $$sat_shl(x, y); -macro ushort! ushort.overflow_add(ushort x, ushort y) => overflow_add_helper(x, y); -macro ushort! ushort.overflow_sub(ushort x, ushort y) => overflow_sub_helper(x, y); -macro ushort! ushort.overflow_mul(ushort x, ushort y) => overflow_mul_helper(x, y); +macro ushort? ushort.overflow_add(ushort x, ushort y) => overflow_add_helper(x, y); +macro ushort? ushort.overflow_sub(ushort x, ushort y) => overflow_sub_helper(x, y); +macro ushort? ushort.overflow_mul(ushort x, ushort y) => overflow_mul_helper(x, y); macro short short.sat_add(short x, short y) => $$sat_add(x, y); macro short short.sat_sub(short x, short y) => $$sat_sub(x, y); macro short short.sat_mul(short x, short y) => $$sat_mul(x, y); macro short short.sat_shl(short x, short y) => $$sat_shl(x, y); -macro short! short.overflow_add(short x, short y) => overflow_add_helper(x, y); -macro short! short.overflow_sub(short x, short y) => overflow_sub_helper(x, y); -macro short! short.overflow_mul(short x, short y) => overflow_mul_helper(x, y); +macro short? short.overflow_add(short x, short y) => overflow_add_helper(x, y); +macro short? short.overflow_sub(short x, short y) => overflow_sub_helper(x, y); +macro short? short.overflow_mul(short x, short y) => overflow_mul_helper(x, y); macro uint uint.sat_add(uint x, uint y) => $$sat_add(x, y); macro uint uint.sat_sub(uint x, uint y) => $$sat_sub(x, y); macro uint uint.sat_mul(uint x, uint y) => $$sat_mul(x, y); macro uint uint.sat_shl(uint x, uint y) => $$sat_shl(x, y); -macro uint! uint.overflow_add(uint x, uint y) => overflow_add_helper(x, y); -macro uint! uint.overflow_sub(uint x, uint y) => overflow_sub_helper(x, y); -macro uint! uint.overflow_mul(uint x, uint y) => overflow_mul_helper(x, y); +macro uint? uint.overflow_add(uint x, uint y) => overflow_add_helper(x, y); +macro uint? uint.overflow_sub(uint x, uint y) => overflow_sub_helper(x, y); +macro uint? uint.overflow_mul(uint x, uint y) => overflow_mul_helper(x, y); macro int int.sat_add(int x, int y) => $$sat_add(x, y); macro int int.sat_sub(int x, int y) => $$sat_sub(x, y); macro int int.sat_mul(int x, int y) => $$sat_mul(x, y); macro int int.sat_shl(int x, int y) => $$sat_shl(x, y); -macro int! int.overflow_add(int x, int y) => overflow_add_helper(x, y); -macro int! int.overflow_sub(int x, int y) => overflow_sub_helper(x, y); -macro int! int.overflow_mul(int x, int y) => overflow_mul_helper(x, y); +macro int? int.overflow_add(int x, int y) => overflow_add_helper(x, y); +macro int? int.overflow_sub(int x, int y) => overflow_sub_helper(x, y); +macro int? int.overflow_mul(int x, int y) => overflow_mul_helper(x, y); macro ulong ulong.sat_add(ulong x, ulong y) => $$sat_add(x, y); macro ulong ulong.sat_sub(ulong x, ulong y) => $$sat_sub(x, y); macro ulong ulong.sat_mul(ulong x, ulong y) => $$sat_mul(x, y); macro ulong ulong.sat_shl(ulong x, ulong y) => $$sat_shl(x, y); -macro ulong! ulong.overflow_add(ulong x, ulong y) => overflow_add_helper(x, y); -macro ulong! ulong.overflow_sub(ulong x, ulong y) => overflow_sub_helper(x, y); -macro ulong! ulong.overflow_mul(ulong x, ulong y) => overflow_mul_helper(x, y); +macro ulong? ulong.overflow_add(ulong x, ulong y) => overflow_add_helper(x, y); +macro ulong? ulong.overflow_sub(ulong x, ulong y) => overflow_sub_helper(x, y); +macro ulong? ulong.overflow_mul(ulong x, ulong y) => overflow_mul_helper(x, y); macro long long.sat_add(long x, long y) => $$sat_add(x, y); macro long long.sat_sub(long x, long y) => $$sat_sub(x, y); macro long long.sat_mul(long x, long y) => $$sat_mul(x, y); macro long long.sat_shl(long x, long y) => $$sat_shl(x, y); -macro long! long.overflow_add(long x, long y) => overflow_add_helper(x, y); -macro long! long.overflow_sub(long x, long y) => overflow_sub_helper(x, y); -macro long! long.overflow_mul(long x, long y) => overflow_mul_helper(x, y); +macro long? long.overflow_add(long x, long y) => overflow_add_helper(x, y); +macro long? long.overflow_sub(long x, long y) => overflow_sub_helper(x, y); +macro long? long.overflow_mul(long x, long y) => overflow_mul_helper(x, y); macro uint128 uint128.sat_add(uint128 x, uint128 y) => $$sat_add(x, y); macro uint128 uint128.sat_sub(uint128 x, uint128 y) => $$sat_sub(x, y); macro uint128 uint128.sat_mul(uint128 x, uint128 y) => $$sat_mul(x, y); macro uint128 uint128.sat_shl(uint128 x, uint128 y) => $$sat_shl(x, y); -macro uint128! uint128.overflow_add(uint128 x, uint128 y) => overflow_add_helper(x, y); -macro uint128! uint128.overflow_sub(uint128 x, uint128 y) => overflow_sub_helper(x, y); -macro uint128! uint128.overflow_mul(uint128 x, uint128 y) => overflow_mul_helper(x, y); +macro uint128? uint128.overflow_add(uint128 x, uint128 y) => overflow_add_helper(x, y); +macro uint128? uint128.overflow_sub(uint128 x, uint128 y) => overflow_sub_helper(x, y); +macro uint128? uint128.overflow_mul(uint128 x, uint128 y) => overflow_mul_helper(x, y); macro int128 int128.sat_add(int128 x, int128 y) => $$sat_add(x, y); macro int128 int128.sat_sub(int128 x, int128 y) => $$sat_sub(x, y); macro int128 int128.sat_mul(int128 x, int128 y) => $$sat_mul(x, y); macro int128 int128.sat_shl(int128 x, int128 y) => $$sat_shl(x, y); -macro int128! int128.overflow_add(int128 x, int128 y) => overflow_add_helper(x, y); -macro int128! int128.overflow_sub(int128 x, int128 y) => overflow_sub_helper(x, y); -macro int128! int128.overflow_mul(int128 x, int128 y) => overflow_mul_helper(x, y); +macro int128? int128.overflow_add(int128 x, int128 y) => overflow_add_helper(x, y); +macro int128? int128.overflow_sub(int128 x, int128 y) => overflow_sub_helper(x, y); +macro int128? int128.overflow_mul(int128 x, int128 y) => overflow_mul_helper(x, y); <* @require values::@is_int(x) : `The input must be an integer` *> @@ -1137,21 +1129,21 @@ fn float _frexpf(float x, int* e) macro overflow_add_helper(x, y) @local { $typeof(x) res @noinit; - if ($$overflow_add(x, y, &res)) return MathError.OVERFLOW?; + if ($$overflow_add(x, y, &res)) return OVERFLOW?; return res; } macro overflow_sub_helper(x, y) @local { $typeof(x) res @noinit; - if ($$overflow_sub(x, y, &res)) return MathError.OVERFLOW?; + if ($$overflow_sub(x, y, &res)) return OVERFLOW?; return res; } macro overflow_mul_helper(x, y) @local { $typeof(x) res @noinit; - if ($$overflow_mul(x, y, &res)) return MathError.OVERFLOW?; + if ($$overflow_mul(x, y, &res)) return OVERFLOW?; return res; } @@ -1178,49 +1170,49 @@ macro bool @is_same_vector_or_scalar(#vector_value, #vector_or_scalar) @private @require @is_same_vector_or_scalar(self, mul) : `mul must be a vector of the same type as self, or be an integer scalar` @require @is_same_vector_or_scalar(self, div) : `div must be a vector of the same type as self, or be an integer scalar` *> -macro char[] char[].muldiv(self, mul, div) => mul_div_helper(self, mul, div); +macro char[<*>] char[<*>].muldiv(self, mul, div) => mul_div_helper(self, mul, div); <* @require @is_same_vector_or_scalar(self, mul) : `mul must be a vector of the same type as self, or be an integer scalar` @require @is_same_vector_or_scalar(self, div) : `div must be a vector of the same type as self, or be an integer scalar` *> -macro ichar[] ichar[].muldiv(self, mul, div) => mul_div_helper(self, mul, div); +macro ichar[<*>] ichar[<*>].muldiv(self, mul, div) => mul_div_helper(self, mul, div); <* @require @is_same_vector_or_scalar(self, mul) : `mul must be a vector of the same type as self, or be an integer scalar` @require @is_same_vector_or_scalar(self, div) : `div must be a vector of the same type as self, or be an integer scalar` *> -macro short[] short[].muldiv(self, mul, div) => mul_div_helper(self, mul, div); +macro short[<*>] short[<*>].muldiv(self, mul, div) => mul_div_helper(self, mul, div); <* @require @is_same_vector_or_scalar(self, mul) : `mul must be a vector of the same type as self, or be an integer scalar` @require @is_same_vector_or_scalar(self, div) : `div must be a vector of the same type as self, or be an integer scalar` *> -macro ushort[] ushort[].muldiv(self, mul, div) => mul_div_helper(self, mul, div); +macro ushort[<*>] ushort[<*>].muldiv(self, mul, div) => mul_div_helper(self, mul, div); <* @require @is_same_vector_or_scalar(self, mul) : `mul must be a vector of the same type as self, or be an integer scalar` @require @is_same_vector_or_scalar(self, div) `div must be a vector of the same type as self, or be an integer scalar` *> -macro int[] int[].muldiv(self, mul, div) => mul_div_helper(self, mul, div); +macro int[<*>] int[<*>].muldiv(self, mul, div) => mul_div_helper(self, mul, div); <* @require @is_same_vector_or_scalar(self, mul) `mul must be a vector of the same type as self, or be an integer scalar` @require @is_same_vector_or_scalar(self, div) `div must be a vector of the same type as self, or be an integer scalar` *> -macro uint[] uint[].muldiv(self, mul, div) => mul_div_helper(self, mul, div); +macro uint[<*>] uint[<*>].muldiv(self, mul, div) => mul_div_helper(self, mul, div); <* @require @is_same_vector_or_scalar(self, mul) `mul must be a vector of the same type as self, or be an integer scalar` @require @is_same_vector_or_scalar(self, div) `div must be a vector of the same type as self, or be an integer scalar` *> -macro long[] long[].muldiv(self, mul, div) => mul_div_helper(self, mul, div); +macro long[<*>] long[<*>].muldiv(self, mul, div) => mul_div_helper(self, mul, div); <* @require @is_same_vector_or_scalar(self, mul) `mul must be a vector of the same type as self, or be an integer scalar` @require @is_same_vector_or_scalar(self, div) `div must be a vector of the same type as self, or be an integer scalar` *> -macro ulong[] ulong[].muldiv(self, mul, div) => mul_div_helper(self, mul, div); +macro ulong[<*>] ulong[<*>].muldiv(self, mul, div) => mul_div_helper(self, mul, div); <* @require types::is_int($typeof(a)) `The input must be an integer` diff --git a/lib/std/math/math_matrix.c3 b/lib/std/math/math_matrix.c3 index afd060aff..393108cd7 100644 --- a/lib/std/math/math_matrix.c3 +++ b/lib/std/math/math_matrix.c3 @@ -275,26 +275,26 @@ fn Matrix4x4 Matrix4x4.adjoint(&self) } -fn Matrix2x2! Matrix2x2.inverse(&self) +fn Matrix2x2? Matrix2x2.inverse(&self) { Real det = self.determinant(); - if (det == 0) return MatrixError.MATRIX_INVERSE_DOESNT_EXIST?; + if (det == 0) return math::MATRIX_INVERSE_DOESNT_EXIST?; Matrix2x2 adj = self.adjoint(); return adj.component_mul(1 / det).transpose(); } -fn Matrix3x3! Matrix3x3.inverse(&self) +fn Matrix3x3? Matrix3x3.inverse(&self) { Real det = self.determinant(); - if (det == 0) return MatrixError.MATRIX_INVERSE_DOESNT_EXIST?; + if (det == 0) return math::MATRIX_INVERSE_DOESNT_EXIST?; Matrix3x3 adj = self.adjoint(); return adj.component_mul(1 / det).transpose(); } -fn Matrix4x4! Matrix4x4.inverse(&self) +fn Matrix4x4? Matrix4x4.inverse(&self) { Real det = self.determinant(); - if (det == 0) return MatrixError.MATRIX_INVERSE_DOESNT_EXIST?; + if (det == 0) return math::MATRIX_INVERSE_DOESNT_EXIST?; Matrix4x4 adj = self.adjoint(); return adj.component_mul(1 / det).transpose(); } diff --git a/lib/std/math/math_nolibc/__tan.c3 b/lib/std/math/math_nolibc/__tan.c3 index 44bb8adfd..83da7ed19 100644 --- a/lib/std/math/math_nolibc/__tan.c3 +++ b/lib/std/math/math_nolibc/__tan.c3 @@ -11,7 +11,7 @@ module std::math::nolibc @if(env::NO_LIBC || $feature(C3_MATH)); * ==================================================== */ -const double[?] TAN_T = { +const double[*] TAN_T = { 3.33333333333334091986e-01, /* 3FD55555, 55555563 */ 1.33333333333201242699e-01, /* 3FC11111, 1110FE7A */ 5.39682539762260521377e-02, /* 3FABA1BA, 1BB341FE */ diff --git a/lib/std/math/math_nolibc/__tandf.c3 b/lib/std/math/math_nolibc/__tandf.c3 index 8719ba32f..c6083f094 100644 --- a/lib/std/math/math_nolibc/__tandf.c3 +++ b/lib/std/math/math_nolibc/__tandf.c3 @@ -16,7 +16,7 @@ module std::math::nolibc @if(env::NO_LIBC || $feature(C3_MATH)); */ // |tan(x)/x - t(x)| < 2**-25.5 (~[-2e-08, 2e-08]). -const double[?] TANDF = { +const double[*] TANDF = { 0x15554d3418c99f.0p-54, /* 0.333331395030791399758 */ 0x1112fd38999f72.0p-55, /* 0.133392002712976742718 */ 0x1b54c91d865afe.0p-57, /* 0.0533812378445670393523 */ diff --git a/lib/std/math/math_nolibc/atan.c3 b/lib/std/math/math_nolibc/atan.c3 index b2db3713c..a307b2495 100644 --- a/lib/std/math/math_nolibc/atan.c3 +++ b/lib/std/math/math_nolibc/atan.c3 @@ -12,21 +12,21 @@ module std::math::nolibc @if(env::NO_LIBC || $feature(C3_MATH)); * ==================================================== */ -const double[?] ATANHI @private = { +const double[*] ATANHI @private = { 4.63647609000806093515e-01, /* atan(0.5)hi 0x3FDDAC67, 0x0561BB4F */ 7.85398163397448278999e-01, /* atan(1.0)hi 0x3FE921FB, 0x54442D18 */ 9.82793723247329054082e-01, /* atan(1.5)hi 0x3FEF730B, 0xD281F69B */ 1.57079632679489655800e+00, /* atan(inf)hi 0x3FF921FB, 0x54442D18 */ }; -const double[?] ATANLO @private = { +const double[*] ATANLO @private = { 2.26987774529616870924e-17, /* atan(0.5)lo 0x3C7A2B7F, 0x222F65E2 */ 3.06161699786838301793e-17, /* atan(1.0)lo 0x3C81A626, 0x33145C07 */ 1.39033110312309984516e-17, /* atan(1.5)lo 0x3C700788, 0x7AF0CBBD */ 6.12323399573676603587e-17, /* atan(inf)lo 0x3C91A626, 0x33145C07 */ }; -const double[?] AT @private = { +const double[*] AT @private = { 3.33333333333329318027e-01, /* 0x3FD55555, 0x5555550D */ -1.99999999998764832476e-01, /* 0xBFC99999, 0x9998EBC4 */ 1.42857142725034663711e-01, /* 0x3FC24924, 0x920083FF */ @@ -116,21 +116,21 @@ fn double _atan(double x) @weak @extern("atan") @nostrip * ==================================================== */ -const float[?] ATANHIF @private = { +const float[*] ATANHIF @private = { 4.6364760399e-01, /* atan(0.5)hi 0x3eed6338 */ 7.8539812565e-01, /* atan(1.0)hi 0x3f490fda */ 9.8279368877e-01, /* atan(1.5)hi 0x3f7b985e */ 1.5707962513e+00, /* atan(inf)hi 0x3fc90fda */ }; -const float[?] ATANLOF @private = { +const float[*] ATANLOF @private = { 5.0121582440e-09, /* atan(0.5)lo 0x31ac3769 */ 3.7748947079e-08, /* atan(1.0)lo 0x33222168 */ 3.4473217170e-08, /* atan(1.5)lo 0x33140fb4 */ 7.5497894159e-08, /* atan(inf)lo 0x33a22168 */ }; -const float[?] ATF @private = { +const float[*] ATF @private = { 3.3333328366e-01, -1.9999158382e-01, 1.4253635705e-01, diff --git a/lib/std/math/math_nolibc/rempi.c3 b/lib/std/math/math_nolibc/rempi.c3 index 36ec31241..035eb3ced 100644 --- a/lib/std/math/math_nolibc/rempi.c3 +++ b/lib/std/math/math_nolibc/rempi.c3 @@ -94,9 +94,9 @@ fn int __rem_pio2f(float x, double *y) * ==================================================== */ -const int[?] INIT_JK = {3,4,4,6}; /* initial value for jk */ +const int[*] INIT_JK = {3,4,4,6}; /* initial value for jk */ -const int[?] IPIO2 = { +const int[*] IPIO2 = { 0xA2F983, 0x6E4E44, 0x1529FC, 0x2757D1, 0xF534DD, 0xC0DB62, 0x95993C, 0x439041, 0xFE5163, 0xABDEBB, 0xC561B7, 0x246E3A, 0x424DD2, 0xE00649, 0x2EEA09, 0xD1921C, 0xFE1DEB, 0x1CB129, @@ -109,7 +109,7 @@ const int[?] IPIO2 = { 0x91615E, 0xE61B08, 0x659985, 0x5F14A0, 0x68408D, 0xFFD880, 0x4D7327, 0x310606, 0x1556CA, 0x73A8C9, 0x60E27B, 0xC08C6B, }; -const double[?] PIO2 = { +const double[*] PIO2 = { 1.57079625129699707031e+00, /* 0x3FF921FB, 0x40000000 */ 7.54978941586159635335e-08, /* 0x3E74442D, 0x00000000 */ 5.39030252995776476554e-15, /* 0x3CF84698, 0x80000000 */ diff --git a/lib/std/math/uuid.c3 b/lib/std/math/uuid.c3 index f5648bc27..b7cc28b0b 100644 --- a/lib/std/math/uuid.c3 +++ b/lib/std/math/uuid.c3 @@ -25,7 +25,7 @@ fn Uuid generate_from_random(Random random) return uuid; } -fn usz! Uuid.to_format(&self, Formatter* formatter) @dynamic +fn usz? Uuid.to_format(&self, Formatter* formatter) @dynamic { return formatter.printf("%02x%02x%02x%02x-%02x%02x-%02x%02x-%02x%02x-%02x%02x%02x%02x%02x%02x", (*self)[0], (*self)[1], (*self)[2], (*self)[3], diff --git a/lib/std/net/http.c3 b/lib/std/net/http.c3 index fd178afe6..5e90a16bc 100644 --- a/lib/std/net/http.c3 +++ b/lib/std/net/http.c3 @@ -55,7 +55,7 @@ struct HttpInternal @private void* data; } -fn String! parse_url(String url, String* port, String* resource) @private +fn String? parse_url(String url, String* port, String* resource) @private { if (url[:7] != "http://") return NetError.INVALID_URL?; url = url[7..]; @@ -85,7 +85,7 @@ fn String! parse_url(String url, String* port, String* resource) @private return address; } -fn Socket! http_internal_connect(String address, uint port) @private +fn Socket? http_internal_connect(String address, uint port) @private { return tcp::connect_async(address, port)!; } @@ -108,7 +108,7 @@ fn HttpInternal* http_internal_create(usz request_data_size, Allocator allocator return internal; } -fn Http*! http_get(String url, Allocator allocator = allocator::temp()) +fn Http*? http_get(String url, Allocator allocator = allocator::temp()) { $if env::WIN32: int[1024] wsa_data; @@ -139,7 +139,7 @@ $endif return internal; } -fn Http*! http_post(String url, Allocator allocator = allocator::temp()) +fn Http*? http_post(String url, Allocator allocator = allocator::temp()) { $if env::OS_TYPE == OsType::WIN32: int[1024] wsa_data; diff --git a/lib/std/net/inetaddr.c3 b/lib/std/net/inetaddr.c3 index 1f82bb2ad..f2cf5bce0 100644 --- a/lib/std/net/inetaddr.c3 +++ b/lib/std/net/inetaddr.c3 @@ -45,7 +45,7 @@ struct InetAddress (Printable) } -fn usz! InetAddress.to_format(InetAddress* addr, Formatter* formatter) @dynamic +fn usz? InetAddress.to_format(InetAddress* addr, Formatter* formatter) @dynamic { if (addr.is_ipv6) { @@ -66,14 +66,14 @@ fn String InetAddress.to_tstring(&self) return string::format(tmem(), "%s", *self); } -fn InetAddress! ipv6_from_str(String s) +fn InetAddress? ipv6_from_str(String s) { uint sections = 0; - if (s.len < 2) return NetError.INVALID_IP_STRING?; + if (s.len < 2) return INVALID_IP_STRING?; foreach (c : s) if (c == ':') sections++; int zero_segment_len = s[0] == ':' || s[^1] == ':' ? 9 - sections : 8 - sections; if (zero_segment_len == 7 && s.len == 2) return { .is_ipv6 = true }; - if (zero_segment_len > 7) return NetError.INVALID_IP_STRING?; + if (zero_segment_len > 7) return INVALID_IP_STRING?; usz index = 0; bool last_was_colon, found_zero; int current = -1; @@ -89,7 +89,7 @@ fn InetAddress! ipv6_from_str(String s) last_was_colon = true; continue; } - if (current < 0 || current > 65535) return NetError.INVALID_IP_STRING?; + if (current < 0 || current > 65535) return INVALID_IP_STRING?; addr.ipv6arr[index++].val = (ushort)current; current = -1; last_was_colon = true; @@ -97,9 +97,9 @@ fn InetAddress! ipv6_from_str(String s) } assert(current == -1); // Check that this is the first :: - if (found_zero) return NetError.INVALID_IP_STRING?; + if (found_zero) return INVALID_IP_STRING?; // Also check that the zeroed section is at least 2 - if (zero_segment_len < 2) return NetError.INVALID_IP_STRING?; + if (zero_segment_len < 2) return INVALID_IP_STRING?; // Skip (will be zero by default index += zero_segment_len; found_zero = true; @@ -107,7 +107,7 @@ fn InetAddress! ipv6_from_str(String s) continue; } last_was_colon = false; - if (index > 7 || !c.is_xdigit()) return NetError.INVALID_IP_STRING?; + if (index > 7 || !c.is_xdigit()) return INVALID_IP_STRING?; if (current < 0) current = 0; current = current * 16 + (c <= '9' ? c - '0' : (c | 32) - 'a' + 10); } @@ -115,12 +115,12 @@ fn InetAddress! ipv6_from_str(String s) if (index == 8 && current == -1) return addr; // Ends with number - if (index != 7 || current < 0 || current > 65535) return NetError.INVALID_IP_STRING?; + if (index != 7 || current < 0 || current > 65535) return INVALID_IP_STRING?; addr.ipv6arr[7].val = (ushort)current; return addr; } -fn InetAddress! ipv4_from_str(String s) +fn InetAddress? ipv4_from_str(String s) { InetAddress addr; int element; @@ -129,20 +129,20 @@ fn InetAddress! ipv4_from_str(String s) { if (c == '.') { - if (current < 0) return NetError.INVALID_IP_STRING?; - if (current > 255) return NetError.INVALID_IP_STRING?; + if (current < 0) return INVALID_IP_STRING?; + if (current > 255) return INVALID_IP_STRING?; switch (element) { case 0: addr.ipv4.a = (char)current; case 1: addr.ipv4.b = (char)current; case 2: addr.ipv4.c = (char)current; - default: return NetError.INVALID_IP_STRING?; + default: return INVALID_IP_STRING?; } current = -1; element++; continue; } - if (element > 3 || c < '0' || c > '9') return NetError.INVALID_IP_STRING?; + if (element > 3 || c < '0' || c > '9') return INVALID_IP_STRING?; if (current < 0) { current = c - '0'; @@ -150,7 +150,7 @@ fn InetAddress! ipv4_from_str(String s) } current = current * 10 + c - '0'; } - if (element != 3 || current < 0 || current > 255) return NetError.INVALID_IP_STRING?; + if (element != 3 || current < 0 || current > 255) return INVALID_IP_STRING?; addr.ipv4.d = (char)current; return addr; } @@ -252,13 +252,13 @@ fn bool InetAddress.is_multicast_link_local(InetAddress* addr) return addr.ipv4.a == 224 && addr.ipv4.b == 0 && addr.ipv4.c == 0; } -fn AddrInfo*! addrinfo(String host, uint port, AIFamily ai_family, AISockType ai_socktype) @if(os::SUPPORTS_INET) => @pool() +fn AddrInfo*? addrinfo(String host, uint port, AIFamily ai_family, AISockType ai_socktype) @if(os::SUPPORTS_INET) => @pool() { ZString zhost = host.zstr_tcopy(); DString str = dstring::temp_with_capacity(32); str.appendf("%d", port); AddrInfo hints = { .ai_family = ai_family, .ai_socktype = ai_socktype }; AddrInfo* ai; - if (os::getaddrinfo(zhost, str.zstr_view(), &hints, &ai)) return NetError.ADDRINFO_FAILED?; + if (os::getaddrinfo(zhost, str.zstr_view(), &hints, &ai)) return ADDRINFO_FAILED?; return ai; } diff --git a/lib/std/net/net.c3 b/lib/std/net/net.c3 index 7a5f600d5..c65f216ac 100644 --- a/lib/std/net/net.c3 +++ b/lib/std/net/net.c3 @@ -1,8 +1,7 @@ module std::net; import std::io; -fault NetError -{ +fault INVALID_URL, URL_TOO_LONG, INVALID_SOCKET, @@ -27,10 +26,9 @@ fault NetError ALREADY_CONNECTED, NETWORK_UNREACHABLE, OPERATION_NOT_SUPPORTED_ON_SOCKET, - CONNECTION_RESET, -} + CONNECTION_RESET; -fn uint! ipv4toint(String s) +fn uint? ipv4toint(String s) { uint out; int element; @@ -39,13 +37,13 @@ fn uint! ipv4toint(String s) { if (c == '.') { - if (current < 0) return NetError.INVALID_IP_STRING?; + if (current < 0) return INVALID_IP_STRING?; out = out << 8 + current; current = -1; element++; continue; } - if (element > 3 || c < '0' || c > '9') return NetError.INVALID_IP_STRING?; + if (element > 3 || c < '0' || c > '9') return INVALID_IP_STRING?; if (current < 0) { current = c - '0'; @@ -53,12 +51,12 @@ fn uint! ipv4toint(String s) } current = current * 10 + c - '0'; } - if (element != 3 || current < 0) return NetError.INVALID_IP_STRING?; + if (element != 3 || current < 0) return INVALID_IP_STRING?; out = out << 8 + current; return out; } -fn String! int_to_ipv4(uint val, Allocator allocator) +fn String? int_to_ipv4(uint val, Allocator allocator) { char[3 * 4 + 3 + 1] buffer; String res = (String)io::bprintf(&buffer, "%d.%d.%d.%d", val >> 24, (val >> 16) & 0xFF, (val >> 8) & 0xFF, val & 0xFF)!; diff --git a/lib/std/net/os/posix.c3 b/lib/std/net/os/posix.c3 index 499537d62..00258aa3c 100644 --- a/lib/std/net/os/posix.c3 +++ b/lib/std/net/os/posix.c3 @@ -34,20 +34,20 @@ fn anyfault convert_error(Errno error) { switch (error) { - case errno::EACCES: return IoError.NO_PERMISSION; - case errno::EADDRINUSE: return NetError.ADDRESS_IN_USE; - case errno::EALREADY: return NetError.CONNECTION_ALREADY_IN_PROGRESS; - case errno::EBADF: return NetError.BAD_SOCKET_DESCRIPTOR; - case errno::ECONNREFUSED: return NetError.CONNECTION_REFUSED; - case errno::ECONNRESET: return NetError.CONNECTION_RESET; - case errno::EISCONN: return NetError.ALREADY_CONNECTED; - case errno::ENETUNREACH: return NetError.NETWORK_UNREACHABLE; - case errno::ENOTSOCK: return NetError.NOT_A_SOCKET; - case errno::EINTR: return IoError.INTERRUPTED; - case errno::EWOULDBLOCK: return IoError.WOULD_BLOCK; - case errno::EOPNOTSUPP: return NetError.OPERATION_NOT_SUPPORTED_ON_SOCKET; - case errno::ETIMEDOUT: return NetError.CONNECTION_TIMED_OUT; - default: return IoError.GENERAL_ERROR; + case errno::EACCES: return io::NO_PERMISSION; + case errno::EADDRINUSE: return net::ADDRESS_IN_USE; + case errno::EALREADY: return net::CONNECTION_ALREADY_IN_PROGRESS; + case errno::EBADF: return net::BAD_SOCKET_DESCRIPTOR; + case errno::ECONNREFUSED: return net::CONNECTION_REFUSED; + case errno::ECONNRESET: return net::CONNECTION_RESET; + case errno::EISCONN: return net::ALREADY_CONNECTED; + case errno::ENETUNREACH: return net::NETWORK_UNREACHABLE; + case errno::ENOTSOCK: return net::NOT_A_SOCKET; + case errno::EINTR: return io::INTERRUPTED; + case errno::EWOULDBLOCK: return io::WOULD_BLOCK; + case errno::EOPNOTSUPP: return net::OPERATION_NOT_SUPPORTED_ON_SOCKET; + case errno::ETIMEDOUT: return net::CONNECTION_TIMED_OUT; + default: return io::GENERAL_ERROR; } } @@ -61,16 +61,16 @@ macro bool NativeSocket.is_valid(self) return (iptr)self >= 0; } -macro void! NativeSocket.close(self) +macro void? NativeSocket.close(self) { if (libc::close(self)) { - if (libc::errno() == errno::EBADF) return NetError.INVALID_SOCKET?; - return NetError.GENERAL_ERROR?; + if (libc::errno() == errno::EBADF) return net::INVALID_SOCKET?; + return net::GENERAL_ERROR?; } } -macro void! NativeSocket.set_non_blocking(self, bool non_blocking) +macro void? NativeSocket.set_non_blocking(self, bool non_blocking) { int flags = fcntl(self, F_GETFL, 0); if (non_blocking) @@ -85,8 +85,8 @@ macro void! NativeSocket.set_non_blocking(self, bool non_blocking) } if (fcntl(self, F_SETFL, flags) == -1) { - if (libc::errno() == errno::EBADF) return NetError.INVALID_SOCKET?; - return NetError.GENERAL_ERROR?; + if (libc::errno() == errno::EBADF) return net::INVALID_SOCKET?; + return net::GENERAL_ERROR?; } } diff --git a/lib/std/net/os/win32.c3 b/lib/std/net/os/win32.c3 index 062be2825..e1a23afd3 100644 --- a/lib/std/net/os/win32.c3 +++ b/lib/std/net/os/win32.c3 @@ -27,7 +27,7 @@ macro bool NativeSocket.is_valid(self) return self != (NativeSocket)(uptr)-1; } -fn void! NativeSocket.set_non_blocking(self, bool non_blocking) +fn void? NativeSocket.set_non_blocking(self, bool non_blocking) { if (ioctlsocket(self, win32::FIONBIO, &&(CULong)non_blocking)) { @@ -35,7 +35,7 @@ fn void! NativeSocket.set_non_blocking(self, bool non_blocking) } } -macro void! NativeSocket.close(self) +macro void? NativeSocket.close(self) { WSAError error = closesocket(self); if (error) return convert_error(error)?; @@ -65,24 +65,24 @@ fn anyfault convert_error(WSAError error) { switch (error) { - case wsa::NOTINITIALISED: return NetError.SOCKETS_NOT_INITIALIZED; - case wsa::ENETDOWN: return NetError.NETWORK_UNREACHABLE; - case wsa::INVALID_HANDLE: return NetError.BAD_SOCKET_DESCRIPTOR; - case wsa::EACCESS: return IoError.NO_PERMISSION; - case wsa::EINPROGRESS: return NetError.STILL_PROCESSING_CALLBACK; - case wsa::EADDRINUSE: return NetError.ADDRESS_IN_USE; - case wsa::EALREADY: return NetError.CONNECTION_ALREADY_IN_PROGRESS; - case wsa::EBADF: return NetError.BAD_SOCKET_DESCRIPTOR; - case wsa::EINTR: return IoError.INTERRUPTED; - case wsa::EWOULDBLOCK: return IoError.WOULD_BLOCK; - case wsa::ECONNREFUSED: return NetError.CONNECTION_REFUSED; - case wsa::EISCONN: return NetError.ALREADY_CONNECTED; - case wsa::ENETUNREACH: return NetError.NETWORK_UNREACHABLE; - case wsa::ENOTSOCK: return NetError.NOT_A_SOCKET; - case wsa::EOPNOTSUPP: return NetError.OPERATION_NOT_SUPPORTED_ON_SOCKET; - case wsa::ETIMEDOUT: return NetError.CONNECTION_TIMED_OUT; - case wsa::ECONNRESET: return NetError.CONNECTION_RESET; - default: return IoError.GENERAL_ERROR; + case wsa::NOTINITIALISED: return net::SOCKETS_NOT_INITIALIZED; + case wsa::ENETDOWN: return net::NETWORK_UNREACHABLE; + case wsa::INVALID_HANDLE: return net::BAD_SOCKET_DESCRIPTOR; + case wsa::EACCESS: return io::NO_PERMISSION; + case wsa::EINPROGRESS: return net::STILL_PROCESSING_CALLBACK; + case wsa::EADDRINUSE: return net::ADDRESS_IN_USE; + case wsa::EALREADY: return net::CONNECTION_ALREADY_IN_PROGRESS; + case wsa::EBADF: return net::BAD_SOCKET_DESCRIPTOR; + case wsa::EINTR: return io::INTERRUPTED; + case wsa::EWOULDBLOCK: return io::WOULD_BLOCK; + case wsa::ECONNREFUSED: return net::CONNECTION_REFUSED; + case wsa::EISCONN: return net::ALREADY_CONNECTED; + case wsa::ENETUNREACH: return net::NETWORK_UNREACHABLE; + case wsa::ENOTSOCK: return net::NOT_A_SOCKET; + case wsa::EOPNOTSUPP: return net::OPERATION_NOT_SUPPORTED_ON_SOCKET; + case wsa::ETIMEDOUT: return net::CONNECTION_TIMED_OUT; + case wsa::ECONNRESET: return net::CONNECTION_RESET; + default: return io::GENERAL_ERROR; } } diff --git a/lib/std/net/socket.c3 b/lib/std/net/socket.c3 index 639436f47..8425bfde6 100644 --- a/lib/std/net/socket.c3 +++ b/lib/std/net/socket.c3 @@ -56,7 +56,7 @@ struct Poll @param [inout] polls @param timeout : "duration to poll (clamped to CInt.max ms), or POLL_FOREVER." *> -fn ulong! poll(Poll[] polls, Duration timeout) +fn ulong? poll(Poll[] polls, Duration timeout) { return poll_ms(polls, timeout == POLL_FOREVER ? -1 : timeout.to_ms()) @inline; } @@ -65,7 +65,7 @@ fn ulong! poll(Poll[] polls, Duration timeout) @param [inout] polls @param timeout_ms : "duration to poll in ms or -1. Clamped to CInt.max" *> -fn ulong! poll_ms(Poll[] polls, long timeout_ms) +fn ulong? poll_ms(Poll[] polls, long timeout_ms) { if (timeout_ms > CInt.max) timeout_ms = CInt.max; $if env::WIN32: @@ -94,34 +94,34 @@ enum SocketOption : char (CInt value) DONTROUTE = os::SO_DONTROUTE, } -fn bool! Socket.get_broadcast(&self) => self.get_option(BROADCAST); -fn bool! Socket.get_keepalive(&self) => self.get_option(KEEPALIVE); -fn bool! Socket.get_reuseaddr(&self) => self.get_option(REUSEADDR); -fn bool! Socket.get_dontroute(&self) => self.get_option(DONTROUTE); -fn bool! Socket.get_oobinline(&self) => self.get_option(OOBINLINE); +fn bool? Socket.get_broadcast(&self) => self.get_option(BROADCAST); +fn bool? Socket.get_keepalive(&self) => self.get_option(KEEPALIVE); +fn bool? Socket.get_reuseaddr(&self) => self.get_option(REUSEADDR); +fn bool? Socket.get_dontroute(&self) => self.get_option(DONTROUTE); +fn bool? Socket.get_oobinline(&self) => self.get_option(OOBINLINE); -fn void! Socket.set_broadcast(&self, bool value) => self.set_option(BROADCAST, value); -fn void! Socket.set_keepalive(&self, bool value) => self.set_option(KEEPALIVE, value); -fn void! Socket.set_reuseaddr(&self, bool value) => self.set_option(REUSEADDR, value); -fn void! Socket.set_dontroute(&self, bool value) => self.set_option(DONTROUTE, value); -fn void! Socket.set_oobinline(&self, bool value) => self.set_option(OOBINLINE, value); +fn void? Socket.set_broadcast(&self, bool value) => self.set_option(BROADCAST, value); +fn void? Socket.set_keepalive(&self, bool value) => self.set_option(KEEPALIVE, value); +fn void? Socket.set_reuseaddr(&self, bool value) => self.set_option(REUSEADDR, value); +fn void? Socket.set_dontroute(&self, bool value) => self.set_option(DONTROUTE, value); +fn void? Socket.set_oobinline(&self, bool value) => self.set_option(OOBINLINE, value); -fn void! Socket.set_option(&self, SocketOption option, bool value) +fn void? Socket.set_option(&self, SocketOption option, bool value) { CInt flag = (CInt)value; int errcode = os::setsockopt(self.sock, os::SOL_SOCKET, option.value, &flag, CInt.sizeof); - if (errcode != 0) return NetError.SOCKOPT_FAILED?; + if (errcode != 0) return SOCKOPT_FAILED?; } -fn bool! Socket.get_option(&self, SocketOption option) +fn bool? Socket.get_option(&self, SocketOption option) { CInt flag; int errcode = os::setsockopt(self.sock, os::SOL_SOCKET, option.value, &flag, CInt.sizeof); - if (errcode != 0) return NetError.SOCKOPT_FAILED?; + if (errcode != 0) return SOCKOPT_FAILED?; return (bool)flag; } -fn usz! Socket.read(&self, char[] bytes) @dynamic +fn usz? Socket.read(&self, char[] bytes) @dynamic { $if env::WIN32: isz n = libc::recv(self.sock, bytes.ptr, (int)bytes.len, 0); @@ -132,9 +132,9 @@ $endif return (usz)n; } -fn char! Socket.read_byte(&self) @dynamic => io::read_byte_using_read(self); +fn char? Socket.read_byte(&self) @dynamic => io::read_byte_using_read(self); -fn usz! Socket.write(&self, char[] bytes) @dynamic +fn usz? Socket.write(&self, char[] bytes) @dynamic { $if env::WIN32: isz n = libc::send(self.sock, bytes.ptr, (int)bytes.len, 0); @@ -145,18 +145,18 @@ $endif return (usz)n; } -fn void! Socket.write_byte(&self, char byte) @dynamic => io::write_byte_using_write(self, byte); +fn void? Socket.write_byte(&self, char byte) @dynamic => io::write_byte_using_write(self, byte); -fn void! Socket.destroy(&self) @dynamic +fn void? Socket.destroy(&self) @dynamic { self.close()!; } -fn void! Socket.close(&self) @inline @dynamic +fn void? Socket.close(&self) @inline @dynamic { self.sock.close()!; } -fn usz! Socket.peek(&self, char[] bytes) @dynamic +fn usz? Socket.peek(&self, char[] bytes) @dynamic { $if env::WIN32: isz n = libc::recv(self.sock, bytes.ptr, (int)bytes.len, os::MSG_PEEK); @@ -174,7 +174,7 @@ enum SocketShutdownHow : (inline CInt native_value) BOTH = @select(env::WIN32, libc::SD_BOTH, libc::SHUT_RDWR), } -fn void! Socket.shutdown(&self, SocketShutdownHow how) +fn void? Socket.shutdown(&self, SocketShutdownHow how) { if (libc::shutdown(self.sock, how) < 0) { diff --git a/lib/std/net/socket_private.c3 b/lib/std/net/socket_private.c3 index 1833b1d2d..5f7656a1d 100644 --- a/lib/std/net/socket_private.c3 +++ b/lib/std/net/socket_private.c3 @@ -7,7 +7,7 @@ macro apply_sockoptions(sockfd, options) @private foreach (o : options) sock.set_option(o, true)!; } -fn Socket! connect_from_addrinfo(AddrInfo* addrinfo, SocketOption[] options) @private +fn Socket? connect_from_addrinfo(AddrInfo* addrinfo, SocketOption[] options) @private { @loop_over_ai(addrinfo; NativeSocket sockfd, AddrInfo* ai) { @@ -35,7 +35,7 @@ fn bool last_error_is_delayed_connect() $endswitch } -fn Socket! connect_with_timeout_from_addrinfo(AddrInfo* addrinfo, SocketOption[] options, Duration timeout) @private +fn Socket? connect_with_timeout_from_addrinfo(AddrInfo* addrinfo, SocketOption[] options, Duration timeout) @private { Clock c = 0; @loop_over_ai(addrinfo; NativeSocket sockfd, AddrInfo* ai) @@ -57,7 +57,7 @@ fn Socket! connect_with_timeout_from_addrinfo(AddrInfo* addrinfo, SocketOption[] Duration to_remove = c.to_now().to_duration(); if (to_remove >= timeout_left) { - return NetError.CONNECTION_TIMED_OUT?; + return CONNECTION_TIMED_OUT?; } timeout_left -= to_remove; } @@ -68,7 +68,7 @@ fn Socket! connect_with_timeout_from_addrinfo(AddrInfo* addrinfo, SocketOption[] Poll poll_request = { sockfd, SUBSCRIBE_ANY_WRITE, 0 }; if (!poll((&poll_request)[:1], timeout_left)!) { - return NetError.CONNECTION_TIMED_OUT?; + return CONNECTION_TIMED_OUT?; } if (poll_request.revents & POLL_EVENT_WRITE) { @@ -80,7 +80,7 @@ fn Socket! connect_with_timeout_from_addrinfo(AddrInfo* addrinfo, SocketOption[] return os::socket_error()?; } -fn Socket! connect_async_from_addrinfo(AddrInfo* addrinfo, SocketOption[] options) @private +fn Socket? connect_async_from_addrinfo(AddrInfo* addrinfo, SocketOption[] options) @private { @loop_over_ai(addrinfo; NativeSocket sockfd, AddrInfo* ai) { diff --git a/lib/std/net/tcp.c3 b/lib/std/net/tcp.c3 index 716584076..e2428f322 100644 --- a/lib/std/net/tcp.c3 +++ b/lib/std/net/tcp.c3 @@ -5,7 +5,7 @@ import std::time, libc; distinct TcpSocket = inline Socket; distinct TcpServerSocket = inline Socket; -fn TcpSocket! connect(String host, uint port, Duration timeout = 0, SocketOption... options, IpProtocol ip_protocol = UNSPECIFIED) +fn TcpSocket? connect(String host, uint port, Duration timeout = 0, SocketOption... options, IpProtocol ip_protocol = UNSPECIFIED) { AddrInfo* ai = net::addrinfo(host, port, ip_protocol.ai_family, os::SOCK_STREAM)!; defer os::freeaddrinfo(ai); @@ -16,40 +16,40 @@ fn TcpSocket! connect(String host, uint port, Duration timeout = 0, SocketOption return connect_to(ai, ...options); } -fn TcpSocket! connect_async(String host, uint port, SocketOption... options, IpProtocol ip_protocol = UNSPECIFIED) +fn TcpSocket? connect_async(String host, uint port, SocketOption... options, IpProtocol ip_protocol = UNSPECIFIED) { AddrInfo* ai = net::addrinfo(host, port, ip_protocol.ai_family, os::SOCK_STREAM)!; defer os::freeaddrinfo(ai); return connect_async_to(ai, ...options); } -fn TcpSocket! connect_to(AddrInfo* ai, SocketOption... options) +fn TcpSocket? connect_to(AddrInfo* ai, SocketOption... options) { return (TcpSocket)net::connect_from_addrinfo(ai, options); } -fn TcpSocket! connect_async_to(AddrInfo* ai, SocketOption... options) +fn TcpSocket? connect_async_to(AddrInfo* ai, SocketOption... options) { return (TcpSocket)net::connect_async_from_addrinfo(ai, options); } -fn TcpServerSocket! listen(String host, uint port, uint backlog, SocketOption... options, IpProtocol ip_protocol = UNSPECIFIED) +fn TcpServerSocket? listen(String host, uint port, uint backlog, SocketOption... options, IpProtocol ip_protocol = UNSPECIFIED) { AddrInfo* ai = net::addrinfo(host, port, ip_protocol.ai_family, os::SOCK_STREAM)!; defer os::freeaddrinfo(ai); return listen_to(ai, backlog, ...options); } -fn TcpSocket! accept(TcpServerSocket* server_socket) +fn TcpSocket? accept(TcpServerSocket* server_socket) { TcpSocket socket; socket.ai_addrlen = socket.ai_addr_storage.len; socket.sock = os::accept(server_socket.sock, (SockAddrPtr)&socket.ai_addr_storage, &socket.ai_addrlen); - if (!socket.sock.is_valid()) return NetError.ACCEPT_FAILED?; + if (!socket.sock.is_valid()) return net::ACCEPT_FAILED?; return socket; } -fn TcpServerSocket! listen_to(AddrInfo* ai, uint backlog, SocketOption... options) +fn TcpServerSocket? listen_to(AddrInfo* ai, uint backlog, SocketOption... options) { net::@loop_over_ai(ai; NativeSocket sockfd, AddrInfo* ai_candidate) { diff --git a/lib/std/net/udp.c3 b/lib/std/net/udp.c3 index 3ecace47d..93586144d 100644 --- a/lib/std/net/udp.c3 +++ b/lib/std/net/udp.c3 @@ -3,26 +3,26 @@ import std::net @public; distinct UdpSocket = inline Socket; -fn UdpSocket! connect(String host, uint port, SocketOption... options, IpProtocol ip_protocol = UNSPECIFIED) +fn UdpSocket? connect(String host, uint port, SocketOption... options, IpProtocol ip_protocol = UNSPECIFIED) { AddrInfo* ai = net::addrinfo(host, port, ip_protocol.ai_family, os::SOCK_DGRAM)!; defer os::freeaddrinfo(ai); return connect_to(ai, ...options); } -fn UdpSocket! connect_to(AddrInfo* ai, SocketOption... options) +fn UdpSocket? connect_to(AddrInfo* ai, SocketOption... options) { return (UdpSocket)net::connect_from_addrinfo(ai, options); } -fn UdpSocket! connect_async(String host, uint port, SocketOption... options, IpProtocol ip_protocol = UNSPECIFIED) +fn UdpSocket? connect_async(String host, uint port, SocketOption... options, IpProtocol ip_protocol = UNSPECIFIED) { AddrInfo* ai = net::addrinfo(host, port, ip_protocol.ai_family, os::SOCK_DGRAM)!; defer os::freeaddrinfo(ai); return connect_async_to(ai, ...options); } -fn UdpSocket! connect_async_to(AddrInfo* ai, SocketOption... options) +fn UdpSocket? connect_async_to(AddrInfo* ai, SocketOption... options) { return (UdpSocket)net::connect_async_from_addrinfo(ai, options); } diff --git a/lib/std/net/url.c3 b/lib/std/net/url.c3 index f6da84fab..3d8befb14 100644 --- a/lib/std/net/url.c3 +++ b/lib/std/net/url.c3 @@ -2,16 +2,14 @@ module std::net::url; import std::io, std::collections::map, std::collections::list; -fault UrlParsingResult -{ +fault EMPTY, INVALID_SCHEME, INVALID_USER, INVALID_PASSWORD, INVALID_HOST, INVALID_PATH, - INVALID_FRAGMENT, -} + INVALID_FRAGMENT; <* Represents the actual (decoded) Url. @@ -49,7 +47,7 @@ struct Url(Printable) @require url_string.len > 0 : "the url_string must be len 1 or more" @return "the parsed Url" *> -fn Url! tparse(String url_string) => parse(tmem(), url_string); +fn Url? tparse(String url_string) => parse(tmem(), url_string); <* Parse a URL string into a Url struct. @@ -58,25 +56,25 @@ fn Url! tparse(String url_string) => parse(tmem(), url_string); @require url_string.len > 0 : "the url_string must be len 1 or more" @return "the parsed Url" *> -fn Url! parse(Allocator allocator, String url_string) +fn Url? parse(Allocator allocator, String url_string) { url_string = url_string.trim(); - if (!url_string) return UrlParsingResult.EMPTY?; + if (!url_string) return EMPTY?; Url url = { .allocator = allocator }; // Parse scheme if (try pos = url_string.index_of("://")) { - if (!pos) return UrlParsingResult.INVALID_SCHEME?; + if (!pos) return INVALID_SCHEME?; url.scheme = url_string[:pos].copy(allocator); url_string = url_string[url.scheme.len + 3 ..]; } else if (try pos = url_string.index_of(":")) { // Handle schemes without authority like 'mailto:' - if (!pos) return UrlParsingResult.INVALID_SCHEME?; + if (!pos) return INVALID_SCHEME?; url.scheme = url_string[:pos].copy(allocator); - url.path = decode(allocator, url_string[pos + 1 ..], PATH) ?? UrlParsingResult.INVALID_PATH?!; + url.path = decode(allocator, url_string[pos + 1 ..], PATH) ?? INVALID_PATH?!; return url; } @@ -95,11 +93,11 @@ fn Url! parse(Allocator allocator, String url_string) { String[] userpass = userinfo.tsplit(":", 2); username = userpass[0]; - if (!username.len) return UrlParsingResult.INVALID_USER?; + if (!username.len) return INVALID_USER?; url.host = - url.username = decode(allocator, username, HOST) ?? UrlParsingResult.INVALID_USER?!; - if (userpass.len) url.password = decode(allocator, userpass[1], USERPASS) ?? UrlParsingResult.INVALID_PASSWORD?!; + url.username = decode(allocator, username, HOST) ?? INVALID_USER?!; + if (userpass.len) url.password = decode(allocator, userpass[1], USERPASS) ?? INVALID_PASSWORD?!; }; authority = authority[userinfo.len + 1 ..]; } @@ -131,23 +129,23 @@ fn Url! parse(Allocator allocator, String url_string) } }; } - url.host = decode(allocator, host, HOST) ?? UrlParsingResult.INVALID_HOST?!; + url.host = decode(allocator, host, HOST) ?? INVALID_HOST?!; url_string = url_string[authority_end ..]; } // Parse path - usz! query_index = url_string.index_of_char('?'); - usz! fragment_index = url_string.index_of_char('#'); + usz? query_index = url_string.index_of_char('?'); + usz? fragment_index = url_string.index_of_char('#'); if (@ok(query_index) || @ok(fragment_index)) { usz path_end = min(query_index ?? url_string.len, fragment_index ?? url_string.len); - url.path = decode(allocator, url_string[:path_end], PATH) ?? UrlParsingResult.INVALID_PATH?!; + url.path = decode(allocator, url_string[:path_end], PATH) ?? INVALID_PATH?!; url_string = url_string[path_end ..]; } else { - url.path = decode(allocator, url_string, PATH) ?? UrlParsingResult.INVALID_PATH?!; + url.path = decode(allocator, url_string, PATH) ?? INVALID_PATH?!; url_string = ""; } @@ -165,12 +163,12 @@ fn Url! parse(Allocator allocator, String url_string) // Parse fragment if (url_string.starts_with("#")) { - url.fragment = decode(allocator, url_string[1..], FRAGMENT) ?? UrlParsingResult.INVALID_FRAGMENT?!; + url.fragment = decode(allocator, url_string[1..], FRAGMENT) ?? INVALID_FRAGMENT?!; } return url; } -fn usz! Url.to_format(&self, Formatter* f) @dynamic +fn usz? Url.to_format(&self, Formatter* f) @dynamic { usz len; // Add scheme if it exists @@ -310,7 +308,7 @@ fn UrlQueryValues* UrlQueryValues.add(&self, String key, String value) -fn usz! UrlQueryValues.to_format(&self, Formatter* f) @dynamic +fn usz? UrlQueryValues.to_format(&self, Formatter* f) @dynamic { usz len; usz i; @@ -319,7 +317,7 @@ fn usz! UrlQueryValues.to_format(&self, Formatter* f) @dynamic @stack_mem(128; Allocator mem) { String encoded_key = encode(mem, key, QUERY); - UrlQueryValueList! values = self.map.get(key); + UrlQueryValueList? values = self.map.get(key); if (catch values) continue; foreach (value : values) { diff --git a/lib/std/net/url_encoding.c3 b/lib/std/net/url_encoding.c3 index 38ce4eeea..48ef50f57 100644 --- a/lib/std/net/url_encoding.c3 +++ b/lib/std/net/url_encoding.c3 @@ -15,10 +15,7 @@ enum UrlEncodingMode : char (String allowed) FRAGMENT = "$&+,/:;=?@!()*", // section 4.1 } -fault UrlDecodingError -{ - INVALID_HEX -} +fault INVALID_HEX; <* Returns true if char c should be encoded according to RFC 3986. @@ -108,9 +105,9 @@ fn String tencode(String s, UrlEncodingMode mode) => encode(tmem(), s, mode); <* Calculate the length of the percent-decoded string. - @return! UrlDecodingError.INVALID_HEX + @return! INVALID_HEX *> -fn usz! decode_len(String s, UrlEncodingMode mode) @inline +fn usz? decode_len(String s, UrlEncodingMode mode) @inline { usz n; foreach (i, c: s) @@ -118,7 +115,7 @@ fn usz! decode_len(String s, UrlEncodingMode mode) @inline if (c != '%') continue; if (i + 2 >= s.len || !s[i+1].is_xdigit() || !s[i+2].is_xdigit()) { - return UrlDecodingError.INVALID_HEX?; + return INVALID_HEX?; } n++; } @@ -134,7 +131,7 @@ fn usz! decode_len(String s, UrlEncodingMode mode) @inline @param [inout] allocator @return "Percent-decoded String" *> -fn String! decode(Allocator allocator, String s, UrlEncodingMode mode) => @pool(allocator) +fn String? decode(Allocator allocator, String s, UrlEncodingMode mode) => @pool(allocator) { usz n = decode_len(s, mode)!; DString builder = dstring::temp_with_capacity(n); @@ -170,4 +167,4 @@ fn String! decode(Allocator allocator, String s, UrlEncodingMode mode) => @pool @param mode : "Url encoding mode" @return "Percent-decoded String" *> -fn String! tdecode(String s, UrlEncodingMode mode) => decode(tmem(), s, mode); +fn String? tdecode(String s, UrlEncodingMode mode) => decode(tmem(), s, mode); diff --git a/lib/std/os/backtrace.c3 b/lib/std/os/backtrace.c3 index dc99dec12..6ad6f8ece 100644 --- a/lib/std/os/backtrace.c3 +++ b/lib/std/os/backtrace.c3 @@ -1,14 +1,7 @@ module std::os::backtrace; import std::collections::list, std::os, std::io; -fault BacktraceFault -{ - SEGMENT_NOT_FOUND, - EXECUTABLE_PATH_NOT_FOUND, - IMAGE_NOT_FOUND, - NO_BACKTRACE_SYMBOLS, - RESOLUTION_FAILED, -} +fault SEGMENT_NOT_FOUND, EXECUTABLE_PATH_NOT_FOUND, IMAGE_NOT_FOUND, NO_BACKTRACE_SYMBOLS, RESOLUTION_FAILED; const Backtrace BACKTRACE_UNKNOWN = { 0, "", "", "", 0, null, false }; @@ -34,7 +27,7 @@ fn bool Backtrace.is_unknown(&self) return !self.object_file.len; } -fn usz! Backtrace.to_format(&self, Formatter* formatter) @dynamic +fn usz? Backtrace.to_format(&self, Formatter* formatter) @dynamic { String inline_suffix = self.is_inline ? " [inline]" : ""; if (self.has_file()) @@ -97,7 +90,7 @@ def symbolize_backtrace = linux::symbolize_backtrace @if(env::LINUX); def symbolize_backtrace = win32::symbolize_backtrace @if(env::WIN32); def symbolize_backtrace = darwin::symbolize_backtrace @if(env::DARWIN); -fn BacktraceList! symbolize_backtrace(Allocator allocator, void*[] backtrace) @if(!env::NATIVE_STACKTRACE) +fn BacktraceList? symbolize_backtrace(Allocator allocator, void*[] backtrace) @if(!env::NATIVE_STACKTRACE) { return {}; } \ No newline at end of file diff --git a/lib/std/os/env.c3 b/lib/std/os/env.c3 index 7d8b15a03..2726bf924 100644 --- a/lib/std/os/env.c3 +++ b/lib/std/os/env.c3 @@ -7,22 +7,22 @@ import std::io::path, libc, std::os; <* @param [in] name @require name.len > 0 - @return! SearchResult.MISSING + @return! NOT_FOUND *> -fn String! get_var(Allocator allocator, String name) => @pool(allocator) +fn String? get_var(Allocator allocator, String name) => @pool(allocator) { $switch: $case env::LIBC && !env::WIN32: ZString val = libc::getenv(name.zstr_tcopy()); - return val ? val.copy(allocator) : SearchResult.MISSING?; + return val ? val.copy(allocator) : NOT_FOUND?; $case env::WIN32: // https://learn.microsoft.com/en-us/windows/win32/api/winbase/nf-winbase-getenvironmentvariable const usz BUFSIZE = 1024; WString buff = (WString)tcalloc(BUFSIZE * 2 + 2); WString wstr = name.to_temp_wstring()!; usz len = win32::getEnvironmentVariableW(wstr, buff, BUFSIZE); - if (len == 0) return SearchResult.MISSING?; + if (len == 0) return NOT_FOUND?; if (len > BUFSIZE) { buff = (WString)tmalloc(len * 2 + 2); @@ -34,7 +34,7 @@ fn String! get_var(Allocator allocator, String name) => @pool(allocator) $endswitch } -fn String! tget_var(String name) +fn String? tget_var(String name) { return get_var(tmem(), name); } @@ -66,7 +66,7 @@ fn bool set_var(String name, String value, bool overwrite = true) => @pool() <* Returns the current user's home directory. *> -fn String! get_home_dir(Allocator using = allocator::heap()) +fn String? get_home_dir(Allocator using = allocator::heap()) { String home; $if !env::WIN32: @@ -81,7 +81,7 @@ fn String! get_home_dir(Allocator using = allocator::heap()) <* Returns the current user's config directory. *> -fn Path! get_config_dir(Allocator allocator) => @pool(allocator) +fn Path? get_config_dir(Allocator allocator) => @pool(allocator) { $if env::WIN32: return path::new(allocator, tget_var("AppData")); @@ -115,11 +115,11 @@ fn bool clear_var(String name) => @pool() $endswitch } -fn String! executable_path(Allocator allocator) +fn String? executable_path(Allocator allocator) { $if env::DARWIN: return darwin::executable_path(allocator); $else - return SearchResult.MISSING?; + return NOT_FOUND?; $endif } diff --git a/lib/std/os/linux/linux.c3 b/lib/std/os/linux/linux.c3 index 3c530ef01..811fdf6b3 100644 --- a/lib/std/os/linux/linux.c3 +++ b/lib/std/os/linux/linux.c3 @@ -89,23 +89,23 @@ struct Linux_Dl_info void* dli_saddr; /* Address of nearest symbol */ } -fn ulong! elf_module_image_base(String path) @local +fn ulong? elf_module_image_base(String path) @local { File file = file::open(path, "rb")!; defer (void)file.close(); char[4] buffer; io::read_all(&file, &buffer)!; - if (buffer != { 0x7f, 'E', 'L', 'F'}) return BacktraceFault.IMAGE_NOT_FOUND?; + if (buffer != { 0x7f, 'E', 'L', 'F'}) return backtrace::IMAGE_NOT_FOUND?; bool is_64 = file.read_byte()! == 2; bool is_little_endian = file.read_byte()! == 1; // Actually, not supported. - if (!is_little_endian) return BacktraceFault.IMAGE_NOT_FOUND?; + if (!is_little_endian) return backtrace::IMAGE_NOT_FOUND?; file.seek(0)!; if (is_64) { Elf64_Ehdr file_header; io::read_any(&file, &file_header)!; - if (file_header.e_ehsize != Elf64_Ehdr.sizeof) return BacktraceFault.IMAGE_NOT_FOUND?; + if (file_header.e_ehsize != Elf64_Ehdr.sizeof) return backtrace::IMAGE_NOT_FOUND?; for (isz i = 0; i < file_header.e_phnum; i++) { Elf64_Phdr header; @@ -117,7 +117,7 @@ fn ulong! elf_module_image_base(String path) @local } Elf32_Ehdr file_header; io::read_any(&file, &file_header)!; - if (file_header.e_ehsize != Elf32_Ehdr.sizeof) return BacktraceFault.IMAGE_NOT_FOUND?; + if (file_header.e_ehsize != Elf32_Ehdr.sizeof) return backtrace::IMAGE_NOT_FOUND?; for (isz i = 0; i < file_header.e_phnum; i++) { Elf32_Phdr header; @@ -128,7 +128,7 @@ fn ulong! elf_module_image_base(String path) @local return 0; } -fn void! backtrace_add_from_exec(Allocator allocator, BacktraceList* list, void* addr) @local +fn void? backtrace_add_from_exec(Allocator allocator, BacktraceList* list, void* addr) @local { char[] buf = mem::talloc_array(char, 1024); @@ -138,7 +138,7 @@ fn void! backtrace_add_from_exec(Allocator allocator, BacktraceList* list, void* return backtrace_add_addr2line(allocator, list, addr, addr2line, obj_name, "???"); } -fn void! backtrace_add_from_dlinfo(Allocator allocator, BacktraceList* list, void* addr, Linux_Dl_info* info) @local +fn void? backtrace_add_from_dlinfo(Allocator allocator, BacktraceList* list, void* addr, Linux_Dl_info* info) @local { char[] buf = mem::talloc_array(char, 1024); @@ -149,10 +149,10 @@ fn void! backtrace_add_from_dlinfo(Allocator allocator, BacktraceList* list, voi return backtrace_add_addr2line(allocator, list, addr, addr2line, info.dli_fname.str_view(), sname); } -fn Backtrace! backtrace_line_parse(Allocator allocator, String string, String obj_name, String func_name, bool is_inlined) +fn Backtrace? backtrace_line_parse(Allocator allocator, String string, String obj_name, String func_name, bool is_inlined) { String[] parts = string.trim().tsplit(" at "); - if (parts.len != 2) return SearchResult.MISSING?; + if (parts.len != 2) return NOT_FOUND?; uint line = 0; String source = ""; @@ -171,14 +171,14 @@ fn Backtrace! backtrace_line_parse(Allocator allocator, String string, String ob .is_inline = is_inlined }; } -fn void! backtrace_add_addr2line(Allocator allocator, BacktraceList* list, void* addr, String addr2line, String obj_name, String func_name) @local +fn void? backtrace_add_addr2line(Allocator allocator, BacktraceList* list, void* addr, String addr2line, String obj_name, String func_name) @local { String[] inline_parts = addr2line.tsplit("(inlined by)"); usz last = inline_parts.len - 1; foreach (i, part : inline_parts) { bool is_inline = i != last; - Backtrace! trace = backtrace_line_parse(allocator, part, obj_name, func_name, is_inline); + Backtrace? trace = backtrace_line_parse(allocator, part, obj_name, func_name, is_inline); if (catch trace) { list.push({ @@ -196,7 +196,7 @@ fn void! backtrace_add_addr2line(Allocator allocator, BacktraceList* list, void* } } -fn void! backtrace_add_element(Allocator allocator, BacktraceList *list, void* addr) @local +fn void? backtrace_add_element(Allocator allocator, BacktraceList *list, void* addr) @local { if (!addr) { @@ -215,7 +215,7 @@ fn void! backtrace_add_element(Allocator allocator, BacktraceList *list, void* a }; } -fn BacktraceList! symbolize_backtrace(Allocator allocator, void*[] backtrace) +fn BacktraceList? symbolize_backtrace(Allocator allocator, void*[] backtrace) { BacktraceList list; list.init(allocator, backtrace.len); diff --git a/lib/std/os/macos/darwin.c3 b/lib/std/os/macos/darwin.c3 index f4805855f..8d1b1b383 100644 --- a/lib/std/os/macos/darwin.c3 +++ b/lib/std/os/macos/darwin.c3 @@ -68,19 +68,19 @@ struct Darwin_segment_command_64 } -fn String! executable_path(Allocator allocator) +fn String? executable_path(Allocator allocator) { char[4096] path; uint len = path.len; - if (darwin_NSGetExecutablePath(&path, &len) < 0) return SearchResult.MISSING?; + if (darwin_NSGetExecutablePath(&path, &len) < 0) return NOT_FOUND?; return ((ZString)&path).copy(allocator); } -fn uptr! load_address() @local +fn uptr? load_address() @local { Darwin_segment_command_64* cmd = darwin::getsegbyname("__TEXT"); - if (!cmd) return BacktraceFault.SEGMENT_NOT_FOUND?; - String path = env::executable_path(tmem()) ?? BacktraceFault.EXECUTABLE_PATH_NOT_FOUND?!; + if (!cmd) return backtrace::SEGMENT_NOT_FOUND?; + String path = env::executable_path(tmem()) ?? backtrace::EXECUTABLE_PATH_NOT_FOUND?!; uint dyld_count = darwin::_dyld_image_count(); for (uint i = 0; i < dyld_count; i++) { @@ -89,11 +89,11 @@ fn uptr! load_address() @local if (image_name.str_view() != path) continue; return cmd.vmaddr + darwin::_dyld_get_image_vmaddr_slide(i); } - return BacktraceFault.IMAGE_NOT_FOUND?; + return backtrace::IMAGE_NOT_FOUND?; } -fn Backtrace! backtrace_load_element(String execpath, void* buffer, void* load_address, Allocator allocator = allocator::heap()) @local +fn Backtrace? backtrace_load_element(String execpath, void* buffer, void* load_address, Allocator allocator = allocator::heap()) @local { @pool(allocator) { @@ -132,7 +132,7 @@ fn Backtrace! backtrace_load_element(String execpath, void* buffer, void* load_a }; } -fn BacktraceList! symbolize_backtrace(Allocator allocator, void*[] backtrace) +fn BacktraceList? symbolize_backtrace(Allocator allocator, void*[] backtrace) { void *load_addr = (void *)load_address()!; BacktraceList list; diff --git a/lib/std/os/macos/objc.c3 b/lib/std/os/macos/objc.c3 index 48e2aa0a0..e8a5e692f 100644 --- a/lib/std/os/macos/objc.c3 +++ b/lib/std/os/macos/objc.c3 @@ -7,11 +7,7 @@ distinct ObjcSelector = void*; def ObjcId = void*; def SendVoid = fn void*(void*, ObjcSelector); -fault ObjcFailure -{ - CLASS_NOT_FOUND, - UNKNOWN_EVENT -} +fault CLASS_NOT_FOUND, UNKNOWN_EVENT; macro ZString ObjcClass.name(ObjcClass cls) => class_getName(cls); macro ObjcClass ObjcClass.superclass(ObjcClass cls) => class_getSuperclass(cls); @@ -24,10 +20,10 @@ macro bool ObjcClass.equals(ObjcClass a, ObjcClass b) => a == b; fn ObjcId alloc(ObjcClass cls) => objc::msg_send(cls, SendVoid, "alloc"); fn void release(ObjcId id) => objc::msg_send(id, SendVoid, "release"); -macro ObjcClass! class_by_name(ZString c) +macro ObjcClass? class_by_name(ZString c) { ObjcClass cls = objc::lookUpClass(c); - return cls ?: ObjcFailure.CLASS_NOT_FOUND?; + return cls ?: CLASS_NOT_FOUND?; } macro ObjcClass[] class_get_list(Allocator allocator = allocator::heap()) @@ -138,7 +134,7 @@ enum EventType : (long val) CHANGE_MODE = 38, } -fn EventType! event_type_from(int val) +fn EventType? event_type_from(int val) { switch(val) { @@ -176,7 +172,7 @@ fn EventType! event_type_from(int val) case EventType.PRESSURE.val: return PRESSURE; case EventType.DIRECT_TOUCH.val: return DIRECT_TOUCH; case EventType.CHANGE_MODE.val: return CHANGE_MODE; - default: return ObjcFailure.UNKNOWN_EVENT?; + default: return UNKNOWN_EVENT?; } } diff --git a/lib/std/os/posix/files.c3 b/lib/std/os/posix/files.c3 index ae87913bf..c809a4cda 100644 --- a/lib/std/os/posix/files.c3 +++ b/lib/std/os/posix/files.c3 @@ -22,7 +22,7 @@ struct Posix_dirent char[255+1] name @if(env::FREEBSD || env::OPENBSD); char[511+1] name @if(env::NETBSD); char[1024] name @if(env::DARWIN); - char[?] name @if(!env::DARWIN && !env::BSD_FAMILY); + char[*] name @if(!env::DARWIN && !env::BSD_FAMILY); } extern fn int rmdir(ZString); diff --git a/lib/std/os/subprocess.c3 b/lib/std/os/subprocess.c3 index 159a9af0f..a8368569e 100644 --- a/lib/std/os/subprocess.c3 +++ b/lib/std/os/subprocess.c3 @@ -3,8 +3,7 @@ import std::io, libc, std::os; // This code is based on https://github.com/sheredom/subprocess.h -fault SubProcessResult -{ +fault FAILED_TO_CREATE_PIPE, FAILED_TO_OPEN_STDIN, FAILED_TO_OPEN_STDOUT, @@ -13,8 +12,7 @@ fault SubProcessResult FAILED_TO_INITIALIZE_ACTIONS, PROCESS_JOIN_FAILED, PROCESS_TERMINATION_FAILED, - READ_FAILED, -} + READ_FAILED; struct SubProcess { @@ -49,7 +47,7 @@ bitstruct SubProcessOptions : int bool search_user_path; } -fn void! create_named_pipe_helper(void** rd, void **wr) @local @if(env::WIN32) +fn void? create_named_pipe_helper(void** rd, void **wr) @local @if(env::WIN32) { Win32_SECURITY_ATTRIBUTES sa_attr = { Win32_SECURITY_ATTRIBUTES.sizeof, null, 1 }; @@ -64,11 +62,11 @@ fn void! create_named_pipe_helper(void** rd, void **wr) @local @if(env::WIN32) win32::PIPE_ACCESS_INBOUND | win32::FILE_FLAG_OVERLAPPED, win32::PIPE_TYPE_BYTE | win32::PIPE_WAIT, 1, 4096, 4096, 0, &sa_attr); - if (win32::INVALID_HANDLE_VALUE == *rd) return SubProcessResult.FAILED_TO_CREATE_PIPE?; + if (win32::INVALID_HANDLE_VALUE == *rd) return FAILED_TO_CREATE_PIPE?; *wr = win32::createFileA( str, win32::GENERIC_WRITE, 0, &sa_attr, win32::OPEN_EXISTING, win32::FILE_ATTRIBUTE_NORMAL, null); - if (win32::INVALID_HANDLE_VALUE == *wr) return SubProcessResult.FAILED_TO_CREATE_PIPE?; + if (win32::INVALID_HANDLE_VALUE == *wr) return FAILED_TO_CREATE_PIPE?; }; } @@ -115,7 +113,7 @@ fn WString convert_command_line_win32(String[] command_line) @inline @if(env::WI <* @require !environment || !options.inherit_environment *> -fn SubProcess! create(String[] command_line, SubProcessOptions options = {}, String[] environment = {}) @if(env::WIN32) +fn SubProcess? create(String[] command_line, SubProcessOptions options = {}, String[] environment = {}) @if(env::WIN32) { void* rd, wr; Win32_DWORD flags = win32::CREATE_UNICODE_ENVIRONMENT; @@ -126,9 +124,9 @@ fn SubProcess! create(String[] command_line, SubProcessOptions options = {}, Str .dwFlags = win32::STARTF_USESTDHANDLES }; if (options.no_window) flags |= win32::CREATE_NO_WINDOW; - if (!win32::createPipe(&rd, &wr, &sa_attr, 0)) return SubProcessResult.FAILED_TO_CREATE_PIPE?; + if (!win32::createPipe(&rd, &wr, &sa_attr, 0)) return FAILED_TO_CREATE_PIPE?; // TODO defer catch - if (!win32::setHandleInformation(wr, win32::HANDLE_FLAG_INHERIT, 0)) return SubProcessResult.FAILED_TO_CREATE_PIPE?; + if (!win32::setHandleInformation(wr, win32::HANDLE_FLAG_INHERIT, 0)) return FAILED_TO_CREATE_PIPE?; CFile stdin; CFile stdout; @@ -155,7 +153,7 @@ fn SubProcess! create(String[] command_line, SubProcessOptions options = {}, Str if (fd != -1) { stdin = win32::_fdopen(fd, "wb"); - if (!stdin) return SubProcessResult.FAILED_TO_OPEN_STDIN?; + if (!stdin) return FAILED_TO_OPEN_STDIN?; } start_info.hStdInput = rd; if (options.read_async) @@ -164,14 +162,14 @@ fn SubProcess! create(String[] command_line, SubProcessOptions options = {}, Str } else { - if (!win32::createPipe(&rd, &wr, &sa_attr, 0)) return SubProcessResult.FAILED_TO_CREATE_PIPE?; + if (!win32::createPipe(&rd, &wr, &sa_attr, 0)) return FAILED_TO_CREATE_PIPE?; } - if (!win32::setHandleInformation(rd, win32::HANDLE_FLAG_INHERIT, 0)) return SubProcessResult.FAILED_TO_CREATE_PIPE?; + if (!win32::setHandleInformation(rd, win32::HANDLE_FLAG_INHERIT, 0)) return FAILED_TO_CREATE_PIPE?; fd = win32::_open_osfhandle((iptr)rd, 0); if (fd != -1) { stdout = win32::_fdopen(fd, "rb"); - if (!stdout) return SubProcessResult.FAILED_TO_OPEN_STDOUT?; + if (!stdout) return FAILED_TO_OPEN_STDOUT?; } start_info.hStdOutput = wr; @@ -190,15 +188,15 @@ fn SubProcess! create(String[] command_line, SubProcessOptions options = {}, Str } else { - if (!win32::createPipe(&rd, &wr, &sa_attr, 0)) return SubProcessResult.FAILED_TO_CREATE_PIPE?; + if (!win32::createPipe(&rd, &wr, &sa_attr, 0)) return FAILED_TO_CREATE_PIPE?; } - if (!win32::setHandleInformation(rd, win32::HANDLE_FLAG_INHERIT, 0)) return SubProcessResult.FAILED_TO_CREATE_PIPE?; + if (!win32::setHandleInformation(rd, win32::HANDLE_FLAG_INHERIT, 0)) return FAILED_TO_CREATE_PIPE?; fd = win32::_open_osfhandle((iptr)rd, 0); if (fd != -1) { stderr = win32::_fdopen(fd, "rb"); - if (!stderr) return SubProcessResult.FAILED_TO_OPEN_STDERR?; + if (!stderr) return FAILED_TO_OPEN_STDERR?; } start_info.hStdError = wr; }; @@ -219,7 +217,7 @@ fn SubProcess! create(String[] command_line, SubProcessOptions options = {}, Str used_environment, // environment null, // use parent dir &start_info, // startup info ptr - &process_info)) return SubProcessResult.FAILED_TO_START_PROCESS?; + &process_info)) return FAILED_TO_START_PROCESS?; }; // We don't need the handle of the primary thread in the called process. win32::closeHandle(process_info.hThread); @@ -266,7 +264,7 @@ fn ZString* tcopy_env(String[] environment) @local @inline @if(env::POSIX) return copy; } -fn String! execute_stdout_to_buffer(char[] buffer, String[] command_line, SubProcessOptions options = {}, String[] environment = {}) +fn String? execute_stdout_to_buffer(char[] buffer, String[] command_line, SubProcessOptions options = {}, String[] environment = {}) { SubProcess process = process::create(command_line, options, environment)!; process.join()!; @@ -277,31 +275,31 @@ fn String! execute_stdout_to_buffer(char[] buffer, String[] command_line, SubPro <* @require !environment || !options.inherit_environment *> -fn SubProcess! create(String[] command_line, SubProcessOptions options = {}, String[] environment = {}) @if(env::POSIX) +fn SubProcess? create(String[] command_line, SubProcessOptions options = {}, String[] environment = {}) @if(env::POSIX) { CInt[2] stdinfd; CInt[2] stdoutfd; CInt[2] stderrfd; - if (posix::pipe(&stdinfd)) return SubProcessResult.FAILED_TO_OPEN_STDIN?; - if (posix::pipe(&stdoutfd)) return SubProcessResult.FAILED_TO_OPEN_STDOUT?; - if (!options.combined_stdout_stderr && posix::pipe(&stderrfd)) return SubProcessResult.FAILED_TO_OPEN_STDERR?; + if (posix::pipe(&stdinfd)) return FAILED_TO_OPEN_STDIN?; + if (posix::pipe(&stdoutfd)) return FAILED_TO_OPEN_STDOUT?; + if (!options.combined_stdout_stderr && posix::pipe(&stderrfd)) return FAILED_TO_OPEN_STDERR?; Posix_spawn_file_actions_t actions; - if (posix::spawn_file_actions_init(&actions)) return SubProcessResult.FAILED_TO_INITIALIZE_ACTIONS?; + if (posix::spawn_file_actions_init(&actions)) return FAILED_TO_INITIALIZE_ACTIONS?; defer posix::spawn_file_actions_destroy(&actions); - if (posix::spawn_file_actions_addclose(&actions, stdinfd[1])) return SubProcessResult.FAILED_TO_OPEN_STDIN?; - if (posix::spawn_file_actions_adddup2(&actions, stdinfd[0], libc::STDIN_FD)) return SubProcessResult.FAILED_TO_OPEN_STDIN?; - if (posix::spawn_file_actions_addclose(&actions, stdoutfd[0])) return SubProcessResult.FAILED_TO_OPEN_STDOUT?; - if (posix::spawn_file_actions_adddup2(&actions, stdoutfd[1], libc::STDOUT_FD)) return SubProcessResult.FAILED_TO_OPEN_STDOUT?; + if (posix::spawn_file_actions_addclose(&actions, stdinfd[1])) return FAILED_TO_OPEN_STDIN?; + if (posix::spawn_file_actions_adddup2(&actions, stdinfd[0], libc::STDIN_FD)) return FAILED_TO_OPEN_STDIN?; + if (posix::spawn_file_actions_addclose(&actions, stdoutfd[0])) return FAILED_TO_OPEN_STDOUT?; + if (posix::spawn_file_actions_adddup2(&actions, stdoutfd[1], libc::STDOUT_FD)) return FAILED_TO_OPEN_STDOUT?; if (options.combined_stdout_stderr) { - if (posix::spawn_file_actions_adddup2(&actions, libc::STDOUT_FD, libc::STDERR_FD)) return SubProcessResult.FAILED_TO_OPEN_STDERR?; + if (posix::spawn_file_actions_adddup2(&actions, libc::STDOUT_FD, libc::STDERR_FD)) return FAILED_TO_OPEN_STDERR?; } else { - if (posix::spawn_file_actions_addclose(&actions, stderrfd[0])) return SubProcessResult.FAILED_TO_OPEN_STDERR?; - if (posix::spawn_file_actions_adddup2(&actions, stderrfd[1], libc::STDERR_FD)) return SubProcessResult.FAILED_TO_OPEN_STDERR?; + if (posix::spawn_file_actions_addclose(&actions, stderrfd[0])) return FAILED_TO_OPEN_STDERR?; + if (posix::spawn_file_actions_adddup2(&actions, stderrfd[1], libc::STDERR_FD)) return FAILED_TO_OPEN_STDERR?; } Pid_t child; @pool() @@ -310,11 +308,11 @@ fn SubProcess! create(String[] command_line, SubProcessOptions options = {}, Str ZString* used_environment = options.inherit_environment ? posix::environ : tcopy_env(environment); if (options.search_user_path) { - if (posix::spawnp(&child, command_line_copy[0], &actions, null, command_line_copy, used_environment)) return SubProcessResult.FAILED_TO_START_PROCESS?; + if (posix::spawnp(&child, command_line_copy[0], &actions, null, command_line_copy, used_environment)) return FAILED_TO_START_PROCESS?; } else { - if (posix::spawnp(&child, command_line_copy[0], &actions, null, command_line_copy, used_environment)) return SubProcessResult.FAILED_TO_START_PROCESS?; + if (posix::spawnp(&child, command_line_copy[0], &actions, null, command_line_copy, used_environment)) return FAILED_TO_START_PROCESS?; } }; libc::close(stdinfd[0]); @@ -341,7 +339,7 @@ fn SubProcess! create(String[] command_line, SubProcessOptions options = {}, Str }; } -fn CInt! SubProcess.join(&self) @if(env::POSIX) +fn CInt? SubProcess.join(&self) @if(env::POSIX) { if (self.stdin_file) { @@ -349,7 +347,7 @@ fn CInt! SubProcess.join(&self) @if(env::POSIX) self.stdin_file = null; } CInt status; - if (self.child && self.child != posix::waitpid(self.child, &status, 0)) return SubProcessResult.PROCESS_JOIN_FAILED?; + if (self.child && self.child != posix::waitpid(self.child, &status, 0)) return PROCESS_JOIN_FAILED?; self.child = 0; self.is_alive = false; @@ -367,7 +365,7 @@ fn File SubProcess.stderr(&self) return file::from_handle(self.stderr_file); } -fn CInt! SubProcess.join(&self) @if(env::WIN32) +fn CInt? SubProcess.join(&self) @if(env::WIN32) { if (self.stdin_file) { @@ -381,7 +379,7 @@ fn CInt! SubProcess.join(&self) @if(env::WIN32) } win32::waitForSingleObject(self.hProcess, win32::INFINITE); Win32_DWORD return_code @noinit; - if (!win32::getExitCodeProcess(self.hProcess, &return_code)) return SubProcessResult.PROCESS_JOIN_FAILED?; + if (!win32::getExitCodeProcess(self.hProcess, &return_code)) return PROCESS_JOIN_FAILED?; self.is_alive = false; return return_code; } @@ -405,19 +403,19 @@ fn bool SubProcess.destroy(&self) return true; } -fn void! SubProcess.terminate(&self) +fn void? SubProcess.terminate(&self) { $if env::WIN32: - if (!win32::terminateProcess(self.hProcess, 99)) return SubProcessResult.PROCESS_TERMINATION_FAILED?; + if (!win32::terminateProcess(self.hProcess, 99)) return PROCESS_TERMINATION_FAILED?; $else - if (posix::kill(self.child, 9)) return SubProcessResult.PROCESS_TERMINATION_FAILED?; + if (posix::kill(self.child, 9)) return PROCESS_TERMINATION_FAILED?; $endif } <* @require size <= Win32_DWORD.max *> -fn usz! read_from_file_win32(CFile file, Win32_HANDLE event_handle, char* buffer, usz size) @if(env::WIN32) @local +fn usz? read_from_file_win32(CFile file, Win32_HANDLE event_handle, char* buffer, usz size) @if(env::WIN32) @local { CInt fd = libc::fileno(file); Win32_DWORD bytes_read = 0; @@ -436,21 +434,21 @@ fn usz! read_from_file_win32(CFile file, Win32_HANDLE event_handle, char* buffer case win32::ERROR_HANDLE_EOF: break; default: - return SubProcessResult.READ_FAILED?; + return READ_FAILED?; } } } } return bytes_read; } -fn usz! read_from_file_posix(CFile file, char* buffer, usz size) @if(env::POSIX) @local +fn usz? read_from_file_posix(CFile file, char* buffer, usz size) @if(env::POSIX) @local { isz bytes_read = libc::read(libc::fileno(file), buffer, size); - if (bytes_read < 0) return SubProcessResult.READ_FAILED?; + if (bytes_read < 0) return READ_FAILED?; return bytes_read; } -fn usz! SubProcess.read_stdout(&self, char* buffer, usz size) +fn usz? SubProcess.read_stdout(&self, char* buffer, usz size) { $if env::WIN32: return read_from_file_win32(self.stdout_file, self.hEventOutput, buffer, size); @@ -459,7 +457,7 @@ fn usz! SubProcess.read_stdout(&self, char* buffer, usz size) $endif } -fn usz! SubProcess.read_stderr(&self, char* buffer, usz size) +fn usz? SubProcess.read_stderr(&self, char* buffer, usz size) { $if env::WIN32: return read_from_file_win32(self.stderr_file, self.hEventError, buffer, size); @@ -468,7 +466,7 @@ fn usz! SubProcess.read_stderr(&self, char* buffer, usz size) $endif } -fn bool! SubProcess.is_running(&self) +fn bool? SubProcess.is_running(&self) { if (!self.is_alive) return false; $if env::WIN32: diff --git a/lib/std/os/win32/process.c3 b/lib/std/os/win32/process.c3 index 05fe742ea..77831e10f 100644 --- a/lib/std/os/win32/process.c3 +++ b/lib/std/os/win32/process.c3 @@ -108,7 +108,7 @@ extern fn Win32_BOOL symGetModuleInfo64(Win32_HANDLE hProcess, Win32_DWORD64 qwA extern fn Win32_HANDLE getModuleHandleA(Win32_LPCSTR lpModuleName) @extern("GetModuleHandleA"); extern fn Win32_HANDLE getModuleHandleW(Win32_LPCWSTR lpModuleName) @extern("GetModuleHandleW"); -fn Win32_DWORD! load_modules() +fn Win32_DWORD? load_modules() { Win32_HANDLE process = getCurrentProcess(); Win32_DWORD needed; @@ -119,9 +119,9 @@ fn Win32_DWORD! load_modules() Win32_HMODULE[1024] mod_buffer; if (!enumProcessModules(process, &mod_buffer, mod_buffer.len, &needed)) { - return BacktraceFault.RESOLUTION_FAILED?; + return backtrace::RESOLUTION_FAILED?; } - if (needed > mod_buffer.len) return BacktraceFault.RESOLUTION_FAILED?; + if (needed > mod_buffer.len) return backtrace::RESOLUTION_FAILED?; Win32_HMODULE[] modules = mod_buffer[:needed]; void* base = null; foreach (mod : modules) @@ -129,7 +129,7 @@ fn Win32_DWORD! load_modules() Win32_MODULEINFO info; if (!getModuleInformation(process, mod, &info, $sizeof(info))) { - return BacktraceFault.RESOLUTION_FAILED?; + return backtrace::RESOLUTION_FAILED?; } if (!base) base = info.lpBaseOfDll; Win32_DWORD load_size = info.sizeOfImage; @@ -141,7 +141,7 @@ fn Win32_DWORD! load_modules() if (len2 < 1) continue; Win32_DWORD64 base_addr = symLoadModuleEx(process, null, (Win32_PCSTR)&char_buf, (Win32_PCSTR)&module_name, (Win32_DWORD64)info.lpBaseOfDll, load_size, null, 0); } - if (!base) return BacktraceFault.IMAGE_NOT_FOUND?; + if (!base) return backtrace::IMAGE_NOT_FOUND?; Win32_IMAGE_NT_HEADERS* h = imageNtHeader(base); return h.fileHeader.machine; } @@ -154,7 +154,7 @@ struct Symbol Win32_DWORD64 displacement; -fn BacktraceList! symbolize_backtrace(Allocator allocator, void*[] backtrace) +fn BacktraceList? symbolize_backtrace(Allocator allocator, void*[] backtrace) { BacktraceList list; list.init(allocator, backtrace.len); @@ -168,7 +168,7 @@ fn BacktraceList! symbolize_backtrace(Allocator allocator, void*[] backtrace) return list; } -fn Backtrace! resolve_backtrace(Allocator allocator, void* addr, Win32_HANDLE process) +fn Backtrace? resolve_backtrace(Allocator allocator, void* addr, Win32_HANDLE process) { Symbol symbol; //Win32_DWORD image_type = load_modules()!; @@ -176,13 +176,13 @@ fn Backtrace! resolve_backtrace(Allocator allocator, void* addr, Win32_HANDLE pr symbol.maxNameLen = 255; if (!symFromAddr(process, (Win32_DWORD64)addr - 1, &displacement, &symbol)) { - return BacktraceFault.NO_BACKTRACE_SYMBOLS?; + return backtrace::NO_BACKTRACE_SYMBOLS?; } Win32_IMAGEHLP_MODULE64 module_info; module_info.sizeOfStruct = Win32_IMAGEHLP_MODULE64.sizeof; if (!symGetModuleInfo64(process, (Win32_DWORD64)addr - 1, &module_info)) { - return BacktraceFault.NO_BACKTRACE_SYMBOLS?; + return backtrace::NO_BACKTRACE_SYMBOLS?; } ZString module_name = (ZString)&module_info.imageName; char[256] name; diff --git a/lib/std/sort/quicksort.c3 b/lib/std/sort/quicksort.c3 index f3ffe885c..cec881403 100644 --- a/lib/std/sort/quicksort.c3 +++ b/lib/std/sort/quicksort.c3 @@ -85,7 +85,7 @@ fn void qsort(Type list, isz low, isz high, CmpFn cmp, Context context) @require low <= k : "kth smalles element is smaller than lower bounds" @require k <= high : "kth smalles element is larger than upper bounds" *> -fn ElementType! qselect(Type list, isz low, isz high, isz k, CmpFn cmp, Context context) +fn ElementType? qselect(Type list, isz low, isz high, isz k, CmpFn cmp, Context context) { if (low >= 0 && high >= 0 && low < high) { @@ -108,7 +108,7 @@ fn ElementType! qselect(Type list, isz low, isz high, isz k, CmpFn cmp, Context } } } - return SearchResult.MISSING?; + return NOT_FOUND?; } macro @partition(Type list, isz l, isz h, CmpFn cmp, Context context) diff --git a/lib/std/text/i18n.c3 b/lib/std/text/i18n.c3 index a3dbd50fc..9d121a6de 100644 --- a/lib/std/text/i18n.c3 +++ b/lib/std/text/i18n.c3 @@ -8,7 +8,7 @@ const Language EN = "en"; def TranslationMap = HashMap{String, String}; fn uint Language.hash(self) => fnv32a::encode((char[])self); HashMap{Language, TranslationMap*} language_map @private; -TranslationMap! current_map; +TranslationMap? current_map; macro String @localized(String string) @builtin { diff --git a/lib/std/threads/buffered_channel.c3 b/lib/std/threads/buffered_channel.c3 index 2d53c1f4d..57ba3cc21 100644 --- a/lib/std/threads/buffered_channel.c3 +++ b/lib/std/threads/buffered_channel.c3 @@ -18,10 +18,10 @@ struct BufferedChannelImpl @private usz read_waiting; ConditionVariable read_cond; - Type[?] buf; + Type[*] buf; } -fn void! BufferedChannel.init(&self, Allocator allocator, usz size = 1) +fn void? BufferedChannel.init(&self, Allocator allocator, usz size = 1) { BufferedChannelImpl* channel = allocator::new_with_padding(allocator, BufferedChannelImpl, Type.sizeof * size)!; defer catch allocator::free(allocator, channel); @@ -44,7 +44,7 @@ fn void! BufferedChannel.init(&self, Allocator allocator, usz size = 1) *self = (BufferedChannel)channel; } -fn void! BufferedChannel.destroy(&self) +fn void? BufferedChannel.destroy(&self) { BufferedChannelImpl* channel = (BufferedChannelImpl*)(*self); @@ -58,7 +58,7 @@ fn void! BufferedChannel.destroy(&self) if (err) return err?; } -fn void! BufferedChannel.push(self, Type val) +fn void? BufferedChannel.push(self, Type val) { BufferedChannelImpl* channel = (BufferedChannelImpl*)self; @@ -74,7 +74,7 @@ fn void! BufferedChannel.push(self, Type val) } // check if channel is closed - if (channel.closed) return ThreadFault.CHANNEL_CLOSED?; + if (channel.closed) return thread::CHANNEL_CLOSED?; // save value to buf channel.buf[channel.sendx] = val; @@ -98,7 +98,7 @@ fn void! BufferedChannel.push(self, Type val) channel.mu.unlock()!; } -fn Type! BufferedChannel.pop(self) +fn Type? BufferedChannel.pop(self) { BufferedChannelImpl* channel = (BufferedChannelImpl*)self; @@ -116,7 +116,7 @@ fn Type! BufferedChannel.pop(self) // check if chan is closed and empty if (channel.closed && channel.elems == 0) { - return ThreadFault.CHANNEL_CLOSED?; + return thread::CHANNEL_CLOSED?; } // read from buf @@ -143,7 +143,7 @@ fn Type! BufferedChannel.pop(self) return ret; } -fn void! BufferedChannel.close(self) +fn void? BufferedChannel.close(self) { BufferedChannelImpl* channel = (BufferedChannelImpl*)self; diff --git a/lib/std/threads/event/event_thread.c3 b/lib/std/threads/event/event_thread.c3 index cccccac3f..7031b09ae 100644 --- a/lib/std/threads/event/event_thread.c3 +++ b/lib/std/threads/event/event_thread.c3 @@ -73,7 +73,7 @@ fn int run_thread(void* arg) @local thread.state = KILLED; continue; } - EventThreadTask! task = thread.queue.wait_for_task(); + EventThreadTask? task = thread.queue.wait_for_task(); if (catch task) { pool.notify_user_shutdown(thread); diff --git a/lib/std/threads/fixed_pool.c3 b/lib/std/threads/fixed_pool.c3 index 08471513a..9a3254e36 100644 --- a/lib/std/threads/fixed_pool.c3 +++ b/lib/std/threads/fixed_pool.c3 @@ -1,13 +1,11 @@ +module std::thread; +fault THREAD_QUEUE_FULL; + module std::thread::threadpool @if (env::POSIX || env::WIN32); import std::thread; // Please do not use this one in production. -fault ThreadPoolResult -{ - QUEUE_FULL -} - def ThreadPoolFn = fn void(any[] args); struct FixedThreadPool @@ -36,7 +34,7 @@ struct QueueItem @private @require threads > 0 && threads < 0x1000 : `Threads should be greater than 0 and less than 0x1000` @require queue_size < 0x10000 : `Queue size must be less than 65536` *> -fn void! FixedThreadPool.init(&self, usz threads, usz queue_size = 0) +fn void? FixedThreadPool.init(&self, usz threads, usz queue_size = 0) { if (queue_size == 0) queue_size = threads * 32; defer catch @ok(self.destroy()); @@ -61,7 +59,7 @@ fn void! FixedThreadPool.init(&self, usz threads, usz queue_size = 0) Stop all the threads and cleanup the pool. Any pending work will be dropped. *> -fn void! FixedThreadPool.destroy(&self) +fn void? FixedThreadPool.destroy(&self) { return self.@shutdown(stop_now); } @@ -70,12 +68,12 @@ fn void! FixedThreadPool.destroy(&self) Stop all the threads and cleanup the pool. Any pending work will be processed. *> -fn void! FixedThreadPool.stop_and_destroy(&self) +fn void? FixedThreadPool.stop_and_destroy(&self) { return self.@shutdown(stop); } -macro void! FixedThreadPool.@shutdown(&self, #stop) @private +macro void? FixedThreadPool.@shutdown(&self, #stop) @private { if (self.initialized) { @@ -109,11 +107,11 @@ macro void! FixedThreadPool.@shutdown(&self, #stop) @private Push a new job to the pool. return Excuse if the queue is full, in which case the job is ignored. *> -fn void! FixedThreadPool.push(&self, ThreadPoolFn func, args...) +fn void? FixedThreadPool.push(&self, ThreadPoolFn func, args...) { self.mu.lock()!; defer self.mu.unlock()!!; - if (self.qindex == self.queue.len) return ThreadPoolResult.QUEUE_FULL?; + if (self.qindex == self.queue.len) return thread::THREAD_QUEUE_FULL?; any[] data; if (args.len) { diff --git a/lib/std/threads/os/thread_posix.c3 b/lib/std/threads/os/thread_posix.c3 index 034498058..a4274935c 100644 --- a/lib/std/threads/os/thread_posix.c3 +++ b/lib/std/threads/os/thread_posix.c3 @@ -22,22 +22,23 @@ def NativeOnceFlag = Pthread_once_t; @require !self.is_initialized() : "Mutex is already initialized" @ensure self.is_initialized() *> -fn void! NativeMutex.init(&self, MutexType type) +fn void? NativeMutex.init(&self, MutexType type) { Pthread_mutexattr_t attr; - if (posix::pthread_mutexattr_init(&attr)) return ThreadFault.INIT_FAILED?; + if (posix::pthread_mutexattr_init(&attr)) return thread::INIT_FAILED?; defer posix::pthread_mutexattr_destroy(&attr); + // TODO: make a fine grained error instead if (type & thread::MUTEX_RECURSIVE) { - if (posix::pthread_mutexattr_settype(&attr, posix::PTHREAD_MUTEX_RECURSIVE)) return ThreadFault.INIT_FAILED?; + if (posix::pthread_mutexattr_settype(&attr, posix::PTHREAD_MUTEX_RECURSIVE)) return thread::INIT_FAILED?; } else { $if env::COMPILER_SAFE_MODE: - if (posix::pthread_mutexattr_settype(&attr, posix::PTHREAD_MUTEX_ERRORCHECK)) return ThreadFault.INIT_FAILED?; + if (posix::pthread_mutexattr_settype(&attr, posix::PTHREAD_MUTEX_ERRORCHECK)) return thread::INIT_FAILED?; $endif } - if (posix::pthread_mutex_init(&self.mutex, &attr)) return ThreadFault.INIT_FAILED?; + if (posix::pthread_mutex_init(&self.mutex, &attr)) return thread::INIT_FAILED?; self.initialized = true; } @@ -50,24 +51,24 @@ fn bool NativeMutex.is_initialized(&self) @require self.is_initialized() : "Mutex was not initialized" @ensure !self.is_initialized() *> -fn void! NativeMutex.destroy(&self) +fn void? NativeMutex.destroy(&self) { - if (posix::pthread_mutex_destroy(&self.mutex)) return ThreadFault.DESTROY_FAILED?; + if (posix::pthread_mutex_destroy(&self.mutex)) return thread::DESTROY_FAILED?; *self = {}; } <* @require self.is_initialized() : "Mutex was not initialized" *> -fn void! NativeMutex.lock(&self) +fn void? NativeMutex.lock(&self) { - if (posix::pthread_mutex_lock(&self.mutex)) return ThreadFault.LOCK_FAILED?; + if (posix::pthread_mutex_lock(&self.mutex)) return thread::LOCK_FAILED?; } <* @require self.is_initialized() : "Mutex was not initialized" *> -fn void! NativeMutex.lock_timeout(&self, ulong ms) +fn void? NativeMutex.lock_timeout(&self, ulong ms) { /* Try to acquire the lock and, if we fail, sleep for 5ms. */ Errno result; @@ -75,7 +76,7 @@ fn void! NativeMutex.lock_timeout(&self, ulong ms) { if (!ms) break; ulong sleep = min(5, ms); - if (!libc::nanosleep(&&time::ms(ms).to_timespec(), null)) return ThreadFault.LOCK_FAILED?; + if (!libc::nanosleep(&&time::ms(ms).to_timespec(), null)) return thread::LOCK_FAILED?; ms -= sleep; } switch (result) @@ -84,9 +85,9 @@ fn void! NativeMutex.lock_timeout(&self, ulong ms) return; case errno::EBUSY: case errno::ETIMEDOUT: - return ThreadFault.LOCK_TIMEOUT?; + return thread::LOCK_TIMEOUT?; default: - return ThreadFault.LOCK_FAILED?; + return thread::LOCK_FAILED?; } } @@ -101,57 +102,57 @@ fn bool NativeMutex.try_lock(&self) <* @require self.is_initialized() : "Mutex was not initialized" *> -fn void! NativeMutex.unlock(&self) +fn void? NativeMutex.unlock(&self) { - if (posix::pthread_mutex_unlock(&self.mutex)) return ThreadFault.UNLOCK_FAILED?; + if (posix::pthread_mutex_unlock(&self.mutex)) return thread::UNLOCK_FAILED?; } -fn void! NativeConditionVariable.init(&cond) +fn void? NativeConditionVariable.init(&cond) { - if (posix::pthread_cond_init(cond, null)) return ThreadFault.INIT_FAILED?; + if (posix::pthread_cond_init(cond, null)) return thread::INIT_FAILED?; } -fn void! NativeConditionVariable.destroy(&cond) +fn void? NativeConditionVariable.destroy(&cond) { - if (posix::pthread_cond_destroy(cond)) return ThreadFault.DESTROY_FAILED?; + if (posix::pthread_cond_destroy(cond)) return thread::DESTROY_FAILED?; } -fn void! NativeConditionVariable.signal(&cond) +fn void? NativeConditionVariable.signal(&cond) { - if (posix::pthread_cond_signal(cond)) return ThreadFault.SIGNAL_FAILED?; + if (posix::pthread_cond_signal(cond)) return thread::SIGNAL_FAILED?; } -fn void! NativeConditionVariable.broadcast(&cond) +fn void? NativeConditionVariable.broadcast(&cond) { - if (posix::pthread_cond_broadcast(cond)) return ThreadFault.SIGNAL_FAILED?; + if (posix::pthread_cond_broadcast(cond)) return thread::SIGNAL_FAILED?; } <* @require mtx.is_initialized() *> -fn void! NativeConditionVariable.wait(&cond, NativeMutex* mtx) +fn void? NativeConditionVariable.wait(&cond, NativeMutex* mtx) { - if (posix::pthread_cond_wait(cond, &mtx.mutex)) return ThreadFault.WAIT_FAILED?; + if (posix::pthread_cond_wait(cond, &mtx.mutex)) return thread::WAIT_FAILED?; } <* @require mtx.is_initialized() *> -fn void! NativeConditionVariable.wait_timeout(&cond, NativeMutex* mtx, ulong ms) +fn void? NativeConditionVariable.wait_timeout(&cond, NativeMutex* mtx, ulong ms) { TimeSpec now; - if (libc::timespec_get(&now, libc::TIME_UTC) != libc::TIME_UTC) return ThreadFault.WAIT_FAILED?; + if (libc::timespec_get(&now, libc::TIME_UTC) != libc::TIME_UTC) return thread::WAIT_FAILED?; now.ns += (CLong)((ms % 1000) * 1000_000); now.s += (Time_t)(ms / 1000 + now.ns / 1000_000_000); now.ns = now.ns % 1000_000_000; switch (posix::pthread_cond_timedwait(cond, &mtx.mutex, &now)) { case errno::ETIMEDOUT: - return ThreadFault.WAIT_TIMEOUT?; + return thread::WAIT_TIMEOUT?; case errno::OK: return; default: - return ThreadFault.WAIT_FAILED?; + return thread::WAIT_FAILED?; } } @@ -164,19 +165,19 @@ fn void* callback(void* arg) @private return (void*)(iptr)thread.thread_fn(thread.arg); } -fn void! NativeThread.create(&thread, ThreadFn thread_fn, void* arg) +fn void? NativeThread.create(&thread, ThreadFn thread_fn, void* arg) { thread.thread_fn = thread_fn; thread.arg = arg; if (posix::pthread_create(&thread.pthread, null, &callback, thread) != 0) { - return ThreadFault.INIT_FAILED?; + return thread::INIT_FAILED?; } } -fn void! NativeThread.detach(thread) +fn void? NativeThread.detach(thread) { - if (posix::pthread_detach(thread.pthread)) return ThreadFault.DETACH_FAILED?; + if (posix::pthread_detach(thread.pthread)) return thread::DETACH_FAILED?; } fn void native_thread_exit(int result) @@ -194,10 +195,10 @@ fn bool NativeThread.equals(thread, NativeThread other) return (bool)posix::pthread_equal(thread.pthread, other.pthread); } -fn int! NativeThread.join(thread) +fn int? NativeThread.join(thread) { void *pres; - if (posix::pthread_join(thread.pthread, &pres)) return ThreadFault.JOIN_FAILED?; + if (posix::pthread_join(thread.pthread, &pres)) return thread::JOIN_FAILED?; return (int)(iptr)pres; } @@ -211,9 +212,9 @@ fn void native_thread_yield() posix::sched_yield(); } -fn void! native_sleep_nano(NanoDuration nano) +fn void? native_sleep_nano(NanoDuration nano) { if (nano <= 0) return; - if (libc::nanosleep(&&nano.to_timespec(), null)) return ThreadFault.INTERRUPTED?; + if (libc::nanosleep(&&nano.to_timespec(), null)) return thread::INTERRUPTED?; } diff --git a/lib/std/threads/os/thread_win32.c3 b/lib/std/threads/os/thread_win32.c3 index 08645f684..34f8565c5 100644 --- a/lib/std/threads/os/thread_win32.c3 +++ b/lib/std/threads/os/thread_win32.c3 @@ -38,7 +38,7 @@ struct NativeConditionVariable Win32_CRITICAL_SECTION waiters_count_lock; } -fn void! NativeMutex.init(&mtx, MutexType type) +fn void? NativeMutex.init(&mtx, MutexType type) { mtx.locks = 0; mtx.recursive = (bool)(type & thread::MUTEX_RECURSIVE); @@ -48,10 +48,10 @@ fn void! NativeMutex.init(&mtx, MutexType type) win32::initializeCriticalSection(&(mtx.critical_section)); return; } - if (!(mtx.handle = win32::createMutex(null, 0, null))) return ThreadFault.INIT_FAILED?; + if (!(mtx.handle = win32::createMutex(null, 0, null))) return thread::INIT_FAILED?; } -fn void! NativeMutex.destroy(&mtx) +fn void? NativeMutex.destroy(&mtx) { mtx.locks = 0; if (!mtx.timed) @@ -59,10 +59,10 @@ fn void! NativeMutex.destroy(&mtx) win32::deleteCriticalSection(&mtx.critical_section); return; } - if (!win32::closeHandle(mtx.handle)) return ThreadFault.DESTROY_FAILED?; + if (!win32::closeHandle(mtx.handle)) return thread::DESTROY_FAILED?; } -fn void! NativeMutex.lock(&mtx) +fn void? NativeMutex.lock(&mtx) { if (!mtx.timed) { @@ -76,13 +76,13 @@ fn void! NativeMutex.lock(&mtx) break; case win32::WAIT_ABANDONED: default: - return ThreadFault.LOCK_FAILED?; + return thread::LOCK_FAILED?; } } if (!mtx.recursive && mtx.locks) { - return ThreadFault.LOCK_FAILED?; + return thread::LOCK_FAILED?; } mtx.locks++; } @@ -91,7 +91,7 @@ fn void! NativeMutex.lock(&mtx) <* @require mtx.timed : "Only available for timed locks" *> -fn void! NativeMutex.lock_timeout(&mtx, ulong ms) +fn void? NativeMutex.lock_timeout(&mtx, ulong ms) { if (ms > uint.max) ms = uint.max; switch (win32::waitForSingleObject(mtx.handle, (uint)ms)) @@ -99,14 +99,14 @@ fn void! NativeMutex.lock_timeout(&mtx, ulong ms) case win32::WAIT_OBJECT_0: break; case win32::WAIT_TIMEOUT: - return ThreadFault.LOCK_TIMEOUT?; + return thread::LOCK_TIMEOUT?; case win32::WAIT_ABANDONED: default: - return ThreadFault.LOCK_FAILED?; + return thread::LOCK_FAILED?; } if (!mtx.recursive && mtx.locks) { - return ThreadFault.LOCK_FAILED?; + return thread::LOCK_FAILED?; } mtx.locks++; } @@ -137,22 +137,22 @@ fn bool NativeMutex.try_lock(&mtx) return true; } -fn void! NativeMutex.unlock(&mtx) +fn void? NativeMutex.unlock(&mtx) { - if (!mtx.locks) return ThreadFault.UNLOCK_FAILED?; + if (!mtx.locks) return thread::UNLOCK_FAILED?; mtx.locks--; if (!mtx.timed) { win32::leaveCriticalSection(&mtx.critical_section); return; } - if (!win32::releaseMutex(mtx.handle)) return ThreadFault.UNLOCK_FAILED?; + if (!win32::releaseMutex(mtx.handle)) return thread::UNLOCK_FAILED?; } const int CONDITION_EVENT_ONE = 0; const int CONDITION_EVENT_ALL = 1; -fn void! NativeConditionVariable.init(&cond) +fn void? NativeConditionVariable.init(&cond) { cond.waiters_count = 0; win32::initializeCriticalSection(&cond.waiters_count_lock); @@ -160,41 +160,41 @@ fn void! NativeConditionVariable.init(&cond) if (!cond.event_one) { cond.event_all = (Win32_HANDLE)0; - return ThreadFault.INIT_FAILED?; + return thread::INIT_FAILED?; } cond.event_all = win32::createEventA(null, 1, 0, null); if (!cond.event_all) { win32::closeHandle(cond.event_one); cond.event_one = (Win32_HANDLE)0; - return ThreadFault.INIT_FAILED?; + return thread::INIT_FAILED?; } } -fn void! NativeConditionVariable.destroy(&cond) @maydiscard +fn void? NativeConditionVariable.destroy(&cond) @maydiscard { if (cond.event_one) win32::closeHandle(cond.event_one); if (cond.event_all) win32::closeHandle(cond.event_all); win32::deleteCriticalSection(&cond.waiters_count_lock); } -fn void! NativeConditionVariable.signal(&cond) +fn void? NativeConditionVariable.signal(&cond) { win32::enterCriticalSection(&cond.waiters_count_lock); bool have_waiters = cond.waiters_count > 0; win32::leaveCriticalSection(&cond.waiters_count_lock); - if (have_waiters && !win32::setEvent(cond.event_one)) return ThreadFault.SIGNAL_FAILED?; + if (have_waiters && !win32::setEvent(cond.event_one)) return thread::SIGNAL_FAILED?; } -fn void! NativeConditionVariable.broadcast(&cond) +fn void? NativeConditionVariable.broadcast(&cond) { win32::enterCriticalSection(&cond.waiters_count_lock); bool have_waiters = cond.waiters_count > 0; win32::leaveCriticalSection(&cond.waiters_count_lock); - if (have_waiters && !win32::setEvent(cond.event_all)) return ThreadFault.SIGNAL_FAILED?; + if (have_waiters && !win32::setEvent(cond.event_all)) return thread::SIGNAL_FAILED?; } -fn void! timedwait(NativeConditionVariable* cond, NativeMutex* mtx, uint timeout) @private +fn void? timedwait(NativeConditionVariable* cond, NativeMutex* mtx, uint timeout) @private { win32::enterCriticalSection(&cond.waiters_count_lock); cond.waiters_count++; @@ -207,10 +207,10 @@ fn void! timedwait(NativeConditionVariable* cond, NativeMutex* mtx, uint timeout { case win32::WAIT_TIMEOUT: mtx.lock()!; - return ThreadFault.WAIT_TIMEOUT?; + return thread::WAIT_TIMEOUT?; case win32::WAIT_FAILED: mtx.lock()!; - return ThreadFault.WAIT_FAILED?; + return thread::WAIT_FAILED?; default: break; } @@ -226,32 +226,32 @@ fn void! timedwait(NativeConditionVariable* cond, NativeMutex* mtx, uint timeout if (!win32::resetEvent(cond.event_all)) { mtx.lock()!; - return ThreadFault.WAIT_FAILED?; + return thread::WAIT_FAILED?; } } mtx.lock()!; } -fn void! NativeConditionVariable.wait(&cond, NativeMutex* mtx) @inline +fn void? NativeConditionVariable.wait(&cond, NativeMutex* mtx) @inline { return timedwait(cond, mtx, win32::INFINITE) @inline; } -fn void! NativeConditionVariable.wait_timeout(&cond, NativeMutex* mtx, ulong ms) @inline +fn void? NativeConditionVariable.wait_timeout(&cond, NativeMutex* mtx, ulong ms) @inline { if (ms > uint.max) ms = uint.max; return timedwait(cond, mtx, (uint)ms) @inline; } -fn void! NativeThread.create(&thread, ThreadFn func, void* args) +fn void? NativeThread.create(&thread, ThreadFn func, void* args) { - if (!(*thread = (NativeThread)win32::createThread(null, 0, func, args, 0, null))) return ThreadFault.INIT_FAILED?; + if (!(*thread = (NativeThread)win32::createThread(null, 0, func, args, 0, null))) return thread::INIT_FAILED?; } -fn void! NativeThread.detach(thread) @inline +fn void? NativeThread.detach(thread) @inline { - if (!win32::closeHandle(thread)) return ThreadFault.DETACH_FAILED?; + if (!win32::closeHandle(thread)) return thread::DETACH_FAILED?; } @@ -293,11 +293,11 @@ fn void NativeOnceFlag.call_once(&flag, OnceFn func) } } -fn int! NativeThread.join(thread) +fn int? NativeThread.join(thread) { uint res; - if (win32::waitForSingleObject(thread, win32::INFINITE) == win32::WAIT_FAILED) return ThreadFault.JOIN_FAILED?; - if (!win32::getExitCodeThread(thread, &res)) return ThreadFault.JOIN_FAILED?; + if (win32::waitForSingleObject(thread, win32::INFINITE) == win32::WAIT_FAILED) return thread::JOIN_FAILED?; + if (!win32::getExitCodeThread(thread, &res)) return thread::JOIN_FAILED?; defer win32::closeHandle(thread); return res; } @@ -312,10 +312,10 @@ fn bool NativeThread.equals(thread, NativeThread other) return win32::getThreadId(thread) == win32::getThreadId(other); } -fn void! native_sleep_nano(NanoDuration ns) +fn void? native_sleep_nano(NanoDuration ns) { long ms = ns.to_ms(); if (ms <= 0) return; if (ms > Win32_DWORD.max) ms = Win32_DWORD.max; - if (win32::sleepEx((Win32_DWORD)ms, (Win32_BOOL)true) == win32::WAIT_IO_COMPLETION) return ThreadFault.INTERRUPTED?; + if (win32::sleepEx((Win32_DWORD)ms, (Win32_BOOL)true) == win32::WAIT_IO_COMPLETION) return thread::INTERRUPTED?; } diff --git a/lib/std/threads/pool.c3 b/lib/std/threads/pool.c3 index fc9eb204f..0fc2a55b2 100644 --- a/lib/std/threads/pool.c3 +++ b/lib/std/threads/pool.c3 @@ -26,7 +26,7 @@ struct QueueItem @private <* @require !self.initialized : "ThreadPool must not be already initialized" *> -fn void! ThreadPool.init(&self) +fn void? ThreadPool.init(&self) { defer catch @ok(self.destroy()); *self = { .num_threads = SIZE, .initialized = true }; @@ -44,7 +44,7 @@ fn void! ThreadPool.init(&self) Stop all the threads and cleanup the pool. Any pending work will be dropped. *> -fn void! ThreadPool.destroy(&self) +fn void? ThreadPool.destroy(&self) { return self.@shutdown(stop_now); } @@ -53,12 +53,12 @@ fn void! ThreadPool.destroy(&self) Stop all the threads and cleanup the pool. Any pending work will be processed. *> -fn void! ThreadPool.stop_and_destroy(&self) +fn void? ThreadPool.stop_and_destroy(&self) { return self.@shutdown(stop); } -macro void! ThreadPool.@shutdown(&self, #stop) @private +macro void? ThreadPool.@shutdown(&self, #stop) @private { if (self.initialized) { @@ -86,7 +86,7 @@ macro void! ThreadPool.@shutdown(&self, #stop) @private Push a new job to the pool. Returns whether the queue is full, in which case the job is ignored. *> -fn void! ThreadPool.push(&self, ThreadFn func, void* arg) +fn void? ThreadPool.push(&self, ThreadFn func, void* arg) { while (true) { diff --git a/lib/std/threads/thread.c3 b/lib/std/threads/thread.c3 index 2cb2424d1..b5b7447c4 100644 --- a/lib/std/threads/thread.c3 +++ b/lib/std/threads/thread.c3 @@ -19,8 +19,7 @@ def OnceFn = fn void(); def ThreadFn = fn int(void* arg); -fault ThreadFault -{ +fault INIT_FAILED, DESTROY_FAILED, LOCK_FAILED, @@ -32,19 +31,18 @@ fault ThreadFault DETACH_FAILED, JOIN_FAILED, INTERRUPTED, - CHANNEL_CLOSED, -} + CHANNEL_CLOSED; -macro void! Mutex.init(&mutex) => NativeMutex.init((NativeMutex*)mutex, MUTEX_PLAIN); -macro void! TimedMutex.init(&mutex) => NativeMutex.init((NativeMutex*)mutex, MUTEX_TIMED); -macro void! RecursiveMutex.init(&mutex) => NativeMutex.init((NativeMutex*)mutex, MUTEX_RECURSIVE); -macro void! TimedRecursiveMutex.init(&mutex) => NativeMutex.init((NativeMutex*)mutex, MUTEX_TIMED | MUTEX_RECURSIVE); -macro void! Mutex.destroy(&mutex) => NativeMutex.destroy((NativeMutex*)mutex); -macro void! Mutex.lock(&mutex) => NativeMutex.lock((NativeMutex*)mutex); -macro void! TimedMutex.lock_timeout(&mutex, ulong ms) => NativeMutex.lock_timeout((NativeMutex*)mutex, ms); -macro void! TimedRecursiveMutex.lock_timeout(&mutex, ulong ms) => NativeMutex.lock_timeout((NativeMutex*)mutex, ms); +macro void? Mutex.init(&mutex) => NativeMutex.init((NativeMutex*)mutex, MUTEX_PLAIN); +macro void? TimedMutex.init(&mutex) => NativeMutex.init((NativeMutex*)mutex, MUTEX_TIMED); +macro void? RecursiveMutex.init(&mutex) => NativeMutex.init((NativeMutex*)mutex, MUTEX_RECURSIVE); +macro void? TimedRecursiveMutex.init(&mutex) => NativeMutex.init((NativeMutex*)mutex, MUTEX_TIMED | MUTEX_RECURSIVE); +macro void? Mutex.destroy(&mutex) => NativeMutex.destroy((NativeMutex*)mutex); +macro void? Mutex.lock(&mutex) => NativeMutex.lock((NativeMutex*)mutex); +macro void? TimedMutex.lock_timeout(&mutex, ulong ms) => NativeMutex.lock_timeout((NativeMutex*)mutex, ms); +macro void? TimedRecursiveMutex.lock_timeout(&mutex, ulong ms) => NativeMutex.lock_timeout((NativeMutex*)mutex, ms); macro bool Mutex.try_lock(&mutex) => NativeMutex.try_lock((NativeMutex*)mutex); -macro void! Mutex.unlock(&mutex) => NativeMutex.unlock((NativeMutex*)mutex); +macro void? Mutex.unlock(&mutex) => NativeMutex.unlock((NativeMutex*)mutex); macro void Mutex.@in_lock(&mutex; @body) { (void)mutex.lock(); @@ -52,22 +50,22 @@ macro void Mutex.@in_lock(&mutex; @body) @body(); } -macro void! ConditionVariable.init(&cond) => NativeConditionVariable.init((NativeConditionVariable*)cond); -macro void! ConditionVariable.destroy(&cond) => NativeConditionVariable.destroy((NativeConditionVariable*)cond); -macro void! ConditionVariable.signal(&cond) => NativeConditionVariable.signal((NativeConditionVariable*)cond); -macro void! ConditionVariable.broadcast(&cond) => NativeConditionVariable.broadcast((NativeConditionVariable*)cond); -macro void! ConditionVariable.wait(&cond, Mutex* mutex) +macro void? ConditionVariable.init(&cond) => NativeConditionVariable.init((NativeConditionVariable*)cond); +macro void? ConditionVariable.destroy(&cond) => NativeConditionVariable.destroy((NativeConditionVariable*)cond); +macro void? ConditionVariable.signal(&cond) => NativeConditionVariable.signal((NativeConditionVariable*)cond); +macro void? ConditionVariable.broadcast(&cond) => NativeConditionVariable.broadcast((NativeConditionVariable*)cond); +macro void? ConditionVariable.wait(&cond, Mutex* mutex) { return NativeConditionVariable.wait((NativeConditionVariable*)cond, (NativeMutex*)mutex); } -macro void! ConditionVariable.wait_timeout(&cond, Mutex* mutex, ulong ms) +macro void? ConditionVariable.wait_timeout(&cond, Mutex* mutex, ulong ms) { return NativeConditionVariable.wait_timeout((NativeConditionVariable*)cond, (NativeMutex*)mutex, ms); } -macro void! Thread.create(&thread, ThreadFn thread_fn, void* arg) => NativeThread.create(thread, thread_fn, arg); -macro void! Thread.detach(thread) => NativeThread.detach(thread); -macro int! Thread.join(thread) => NativeThread.join(thread); +macro void? Thread.create(&thread, ThreadFn thread_fn, void* arg) => NativeThread.create(thread, thread_fn, arg); +macro void? Thread.detach(thread) => NativeThread.detach(thread); +macro int? Thread.join(thread) => NativeThread.join(thread); macro bool Thread.equals(thread, Thread other) => NativeThread.equals(thread, other); macro void OnceFlag.call(&flag, OnceFn func) => NativeOnceFlag.call_once((NativeOnceFlag*)flag, func); @@ -75,6 +73,6 @@ macro void OnceFlag.call(&flag, OnceFn func) => NativeOnceFlag.call_once((Native macro void yield() => os::native_thread_yield(); macro Thread current() => (Thread)os::native_thread_current(); macro void exit(int result) => os::native_thread_exit(result); -macro void! sleep(Duration d) @maydiscard => os::native_sleep_nano(d.to_nano()); -macro void! sleep_ms(ulong ms) @maydiscard => sleep(time::ms(ms)); -macro void! sleep_ns(NanoDuration ns) @maydiscard => os::native_sleep_nano(ns); +macro void? sleep(Duration d) @maydiscard => os::native_sleep_nano(d.to_nano()); +macro void? sleep_ms(ulong ms) @maydiscard => sleep(time::ms(ms)); +macro void? sleep_ns(NanoDuration ns) @maydiscard => os::native_sleep_nano(ns); diff --git a/lib/std/threads/unbuffered_channel.c3 b/lib/std/threads/unbuffered_channel.c3 index a17bf748d..90ce3f770 100644 --- a/lib/std/threads/unbuffered_channel.c3 +++ b/lib/std/threads/unbuffered_channel.c3 @@ -1,4 +1,4 @@ -module std::thread::channel{Type}; +module std::thread::channel {Type}; distinct UnbufferedChannel = void*; @@ -18,7 +18,7 @@ struct UnbufferedChannelImpl @private ConditionVariable read_cond; } -fn void! UnbufferedChannel.init(&self, Allocator allocator) +fn void? UnbufferedChannel.init(&self, Allocator allocator) { UnbufferedChannelImpl* channel = allocator::alloc(allocator, UnbufferedChannelImpl); defer catch (void)allocator::free(allocator, channel); @@ -40,7 +40,7 @@ fn void! UnbufferedChannel.init(&self, Allocator allocator) *self = (UnbufferedChannel)channel; } -fn void! UnbufferedChannel.destroy(&self) +fn void? UnbufferedChannel.destroy(&self) { UnbufferedChannelImpl* channel = (UnbufferedChannelImpl*)(*self); @@ -56,7 +56,7 @@ fn void! UnbufferedChannel.destroy(&self) *self = null; } -fn void! UnbufferedChannel.push(self, Type val) +fn void? UnbufferedChannel.push(self, Type val) { UnbufferedChannelImpl* channel = (UnbufferedChannelImpl*)self; @@ -67,7 +67,7 @@ fn void! UnbufferedChannel.push(self, Type val) if (channel.closed) { - return ThreadFault.CHANNEL_CLOSED?; + return thread::CHANNEL_CLOSED?; } // store value in the buffer @@ -84,13 +84,13 @@ fn void! UnbufferedChannel.push(self, Type val) // wait until reader takes value from buffer channel.send_cond.wait(&channel.mu)!; - if (channel.closed) return ThreadFault.CHANNEL_CLOSED?; + if (channel.closed) return thread::CHANNEL_CLOSED?; channel.mu.unlock()!; channel.send_mu.unlock()!; } -fn Type! UnbufferedChannel.pop(self) +fn Type? UnbufferedChannel.pop(self) { UnbufferedChannelImpl* channel = (UnbufferedChannelImpl*)self; @@ -107,7 +107,7 @@ fn Type! UnbufferedChannel.pop(self) channel.read_waiting--; } - if (channel.closed) return ThreadFault.CHANNEL_CLOSED?; + if (channel.closed) return thread::CHANNEL_CLOSED?; // take value from buffer Type ret = channel.buf; @@ -122,7 +122,7 @@ fn Type! UnbufferedChannel.pop(self) return ret; } -fn void! UnbufferedChannel.close(self) +fn void? UnbufferedChannel.close(self) { UnbufferedChannelImpl* channel = (UnbufferedChannelImpl*)self; diff --git a/lib/std/time/time.c3 b/lib/std/time/time.c3 index a15218212..b7c4de95b 100644 --- a/lib/std/time/time.c3 +++ b/lib/std/time/time.c3 @@ -109,7 +109,7 @@ fn Duration NanoDuration.to_duration(nd) => (Duration)nd / 1_000; fn NanoDuration Duration.to_nano(td) => (NanoDuration)td * 1_000; fn long Duration.to_ms(td) => (long)td / 1_000; -fn usz! NanoDuration.to_format(&self, Formatter* formatter) @dynamic +fn usz? NanoDuration.to_format(&self, Formatter* formatter) @dynamic { NanoDuration nd = *self; if (nd == 0) diff --git a/releasenotes.md b/releasenotes.md index 0ef9b90b2..a0fa88b1d 100644 --- a/releasenotes.md +++ b/releasenotes.md @@ -24,6 +24,10 @@ - Empty `$switch` requires trailing ":" `$switch` -> `$switch:` - Change `@return!` syntax to require ":" after faults. - Remove `if (catch foo) { case ... }` syntax. +- Remove `[?]` syntax. +- Change `int!` to `int?` syntax. +- New `fault` declarations. +- Enum associated values can reference the calling enum. ### Fixes - Fix address sanitizer to work on MachO targets (e.g. MacOS). diff --git a/resources/examples/base64.c3 b/resources/examples/base64.c3 index c3681f38e..d91e6b0aa 100644 --- a/resources/examples/base64.c3 +++ b/resources/examples/base64.c3 @@ -1,11 +1,10 @@ module base64; + +fault INVALID_CHARACTER; + // Based on the C2 version. -fault DecodingError -{ - INVALID_CHARACTER -} const char[64] LUT_ENC = { 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', @@ -76,7 +75,7 @@ fn void encode(char[] in, char *out) } -fn int! decode(String in, char* out, int* invalid_char_index = null) +fn int? decode(String in, char* out, int* invalid_char_index = null) { int j = 0; @@ -89,7 +88,7 @@ fn int! decode(String in, char* out, int* invalid_char_index = null) if (c == ERR) { if (invalid_char_index) *invalid_char_index = i; - return DecodingError.INVALID_CHARACTER?; + return INVALID_CHARACTER?; } @@ -127,7 +126,7 @@ fn void main() encode(helloworld[0..12], &buffer); printf("Result: %s\n", &buffer); char *to_decode = "aGVsbG8gd29ybGRcMA=="; - char[?] result = b64"aGVsbG8gd29ybGRcMA=="; + char[*] result = b64"aGVsbG8gd29ybGRcMA=="; decode((String)to_decode[0..19], &buffer)!!; printf("Result: %s\n", &buffer); printf("Result direct: %.*s\n", 13, &result); diff --git a/resources/examples/brainfk.c3 b/resources/examples/brainfk.c3 index 6f3f89fd3..da5901dd1 100644 --- a/resources/examples/brainfk.c3 +++ b/resources/examples/brainfk.c3 @@ -4,18 +4,15 @@ import std::io; const BF_MEM = 30000; char[BF_MEM] memory; -fault InterpretError -{ - INTEPRET_FAILED -} +fault INTEPRET_FAILED; -fn void! print_error_type_at(usz pos, String err) +fn void? print_error_type_at(usz pos, String err) { io::printfn("Error at %s: %s", pos, err); - return InterpretError.INTEPRET_FAILED?; + return INTEPRET_FAILED?; } -fn void! brainf(String program) +fn void? brainf(String program) { usz sp = 0; usz mem = 0; diff --git a/resources/examples/contextfree/boolerr.c3 b/resources/examples/contextfree/boolerr.c3 index eefc8223b..9fbef88e6 100644 --- a/resources/examples/contextfree/boolerr.c3 +++ b/resources/examples/contextfree/boolerr.c3 @@ -4,15 +4,8 @@ import libc; import std::io; import std::collections::maybe; -fault TitleResult -{ - TITLE_MISSING -} - -fault ReadError -{ - BAD_READ, -} +fault TITLE_MISSING; +fault BAD_READ; struct Doc { @@ -30,14 +23,14 @@ struct Summary bool ok; } -fn void! Summary.print(Summary* s, OutStream out) +fn void? Summary.print(Summary* s, OutStream out) { io::fprintf(out, "Summary({ .title = %s, .ok = %s})", s.title.get() ?? "missing", s.ok)!; } -fn Doc! read_doc(String url) +fn Doc? read_doc(String url) { - if (url.contains("fail")) return ReadError.BAD_READ?; + if (url.contains("fail")) return BAD_READ?; if (url.contains("head-missing")) return { }; if (url.contains("title-missing")) return { .head = maybe::value{Head}({}) }; if (url.contains("title-empty")) return { .head = maybe::value{Head}({ .title = maybe::value{String}("")}) }; @@ -57,14 +50,14 @@ fn Summary read_and_build_summary(String url) return build_summary(read_doc(url)) ?? {}; } -fn bool! is_title_non_empty(Doc doc) +fn bool? is_title_non_empty(Doc doc) { - String! title = doc.head.get().title.get(); - if (catch title) return TitleResult.TITLE_MISSING?; + String? title = doc.head.get().title.get(); + if (catch title) return TITLE_MISSING?; return title.len > 0; } -fn bool! read_whether_title_non_empty(String url) +fn bool? read_whether_title_non_empty(String url) { return is_title_non_empty(read_doc(url)); } @@ -90,7 +83,7 @@ fn void main() summary.print(out)!!; io::fprintn(out, "")!!; io::fprintf(out, " Title: %s\n", summary.title.get() ?? "")!!; - bool! has_title = read_whether_title_non_empty(url); + bool? has_title = read_whether_title_non_empty(url); // This looks a bit less than elegant, but as you see it's mostly due to having to // use printf here. io::fprintf(out, " Has title: %s vs %s\n", bool_to_string(has_title) ?? (@catch(has_title)).nameof, has_title ?? false)!!; diff --git a/resources/examples/contextfree/cleanup.c3 b/resources/examples/contextfree/cleanup.c3 index b7aaf2702..bc0f6b804 100644 --- a/resources/examples/contextfree/cleanup.c3 +++ b/resources/examples/contextfree/cleanup.c3 @@ -6,12 +6,9 @@ struct Resource String name; } -fault Error -{ - WELCOME_TO_YOUR_DOOM -} +fault WELCOME_TO_YOUR_DOOM; -fn Resource! resource_init(String name) +fn Resource? resource_init(String name) { io::printfn("open %s", name); return { name }; @@ -19,7 +16,7 @@ fn Resource! resource_init(String name) fn void Resource.deinit(Resource this) => io::printfn("close %s", this.name); -macro void! @open_with(String name; @body(Resource resource)) +macro void? @open_with(String name; @body(Resource resource)) { Resource resource = resource_init(name)!; defer @@ -30,7 +27,7 @@ macro void! @open_with(String name; @body(Resource resource)) @body(resource); } -fn Resource! prep_out(String out_name, String[] prep_names) +fn Resource? prep_out(String out_name, String[] prep_names) { Resource writer = resource_init(out_name)!; // Rethrow the optional result defer catch writer.deinit(); @@ -39,7 +36,7 @@ fn Resource! prep_out(String out_name, String[] prep_names) @open_with(name; Resource reader) { io::printfn("use %s", reader.name); - // if (true) return Error.WELCOME_TO_YOUR_DOOM?; + // if (true) return WELCOME_TO_YOUR_DOOM?; }!; } return writer; diff --git a/resources/examples/contextfree/guess_number.c3 b/resources/examples/contextfree/guess_number.c3 index ecd623526..ffbcd9d24 100644 --- a/resources/examples/contextfree/guess_number.c3 +++ b/resources/examples/contextfree/guess_number.c3 @@ -11,27 +11,23 @@ struct Game int high; } -fault InputResult -{ - NOT_AN_INT, - FAILED_TO_READ, -} +fault NOT_AN_INT, FAILED_TO_READ; int err_count = 0; -fn int! ask_guess(int high) +fn int? ask_guess(int high) { io::printf("Guess a number between 1 and %d: ", high); - String text = io::treadline() ?? InputResult.FAILED_TO_READ?!; - return text.to_int() ?? InputResult.NOT_AN_INT?; + String text = io::treadline() ?? FAILED_TO_READ?!; + return text.to_int() ?? NOT_AN_INT?; } -fn int! ask_guess_multi(int high) +fn int? ask_guess_multi(int high) { while (true) { - int! result = ask_guess(high); - if (@catch(result) == InputResult.NOT_AN_INT) + int? result = ask_guess(high); + if (@catch(result) == NOT_AN_INT) { io::printn("I didn't understand that."); err_count++; @@ -41,7 +37,7 @@ fn int! ask_guess_multi(int high) } } -fn void! Game.play(Game *game) +fn void? Game.play(Game *game) { while (!game.done) { diff --git a/resources/examples/dynlib-test/add.c3 b/resources/examples/dynlib-test/add.c3 index 4f98223f6..1ba0d12a9 100644 --- a/resources/examples/dynlib-test/add.c3 +++ b/resources/examples/dynlib-test/add.c3 @@ -4,7 +4,7 @@ struct Foo(Printable) int a; } -fn usz! Foo.to_format(&self, Formatter* f) @dynamic +fn usz? Foo.to_format(&self, Formatter* f) @dynamic { return f.printf("Foo[%d]", self.a); } diff --git a/resources/examples/map.c3 b/resources/examples/map.c3 index 2118aeb11..cc3ac485f 100644 --- a/resources/examples/map.c3 +++ b/resources/examples/map.c3 @@ -1,10 +1,8 @@ module std::container::map{Key, Type}; import std::core::builtin; import std::io; -fault MapResult -{ - KEY_NOT_FOUND -} + +fault KEY_NOT_FOUND; struct Entry { @@ -33,22 +31,22 @@ fn void Map.init(Map *map, uint capacity = 128) map.mod = capacity - 1; } -fn Type! Map.valueForKey(Map *map, Key key) +fn Type? Map.valueForKey(Map *map, Key key) { - if (!map.map) return MapResult.KEY_NOT_FOUND?; + if (!map.map) return KEY_NOT_FOUND?; uint hash = key.hash(); usz pos = hash & map.mod; Entry* entry = &map.map[pos]; - if (!entry) return MapResult.KEY_NOT_FOUND?; + if (!entry) return KEY_NOT_FOUND?; while (entry) { if (entry.hash == hash && entry.key == key) return entry.value; entry = entry.next; } - return MapResult.KEY_NOT_FOUND?; + return KEY_NOT_FOUND?; } -fn Type! Map.set(Map *map, Key key, Type value) @maydiscard +fn Type? Map.set(Map *map, Key key, Type value) @maydiscard { if (!map.map) { @@ -67,7 +65,7 @@ fn Type! Map.set(Map *map, Key key, Type value) @maydiscard entry.value = value; entry.hash = hash; entry.key = key; - return MapResult.KEY_NOT_FOUND?; + return KEY_NOT_FOUND?; } if (entry.hash == hash && entry.key == key) { @@ -87,7 +85,7 @@ fn Type! Map.set(Map *map, Key key, Type value) @maydiscard new.next = null; new.used = true; entry.next = new; - return MapResult.KEY_NOT_FOUND?; + return KEY_NOT_FOUND?; } } diff --git a/resources/examples/nbodies.c3 b/resources/examples/nbodies.c3 index 4c914a227..c15455b7d 100644 --- a/resources/examples/nbodies.c3 +++ b/resources/examples/nbodies.c3 @@ -81,7 +81,7 @@ fn void offset_momentum(Planet[] bodies) bodies[0].vz = - pz / SOLAR_MASS; } -Planet[?] planet_bodies = { +Planet[*] planet_bodies = { { /* sun */ 0, 0, 0, 0, 0, 0, SOLAR_MASS }, diff --git a/resources/examples/plus_minus.c3 b/resources/examples/plus_minus.c3 index 61ffabb80..ff5269a55 100644 --- a/resources/examples/plus_minus.c3 +++ b/resources/examples/plus_minus.c3 @@ -2,10 +2,7 @@ module test; import std::io; import libc; -fault TokenResult -{ - NO_MORE_TOKENS -} +fault NO_MORE_TOKENS; // While we could have written this with libc @@ -36,7 +33,7 @@ fn void main(String[] args) val = add ? val + i : val - i; // Read an optional token. - String! op = read_next(&numbers); + String? op = read_next(&numbers); // If it's an error, then we're done. if (catch op) break; @@ -56,7 +53,7 @@ fn void main(String[] args) io::printfn("%d", val); } -fn String! read_next(String* remaining) +fn String? read_next(String* remaining) { while (remaining.len > 0 && (*remaining)[0] == ' ') { @@ -77,7 +74,7 @@ fn String! read_next(String* remaining) } // If it's a zero length token, return an optional result. - if (!len) return TokenResult.NO_MORE_TOKENS?; + if (!len) return NO_MORE_TOKENS?; // Otherwise create a slice from the pointer start and length. return (String)ptr_start[:len]; diff --git a/resources/examples/raylib/raylib_snake.c3 b/resources/examples/raylib/raylib_snake.c3 index 4d274b830..0fa6348cf 100644 --- a/resources/examples/raylib/raylib_snake.c3 +++ b/resources/examples/raylib/raylib_snake.c3 @@ -76,7 +76,7 @@ fn void init_game() counter_tail = 1; allow_move = false; - snake_direction = SnakeDirection.RIGHT; + snake_direction = RIGHT; offset.x = SCREEN_WIDTH % SQUARE_SIZE; offset.y = SCREEN_HEIGHT % SQUARE_SIZE; diff --git a/resources/examples/raylib/raylib_tetris.c3 b/resources/examples/raylib/raylib_tetris.c3 index 900a912aa..93bcd306a 100644 --- a/resources/examples/raylib/raylib_tetris.c3 +++ b/resources/examples/raylib/raylib_tetris.c3 @@ -257,7 +257,7 @@ fn void update_game() { for (int i = 1; i < GRID_HORIZONTAL_SIZE - 1; i++) { - if (grid[i][j] == GridSquare.FULL) + if (grid[i][j] == FULL) { game_over = true; } @@ -404,7 +404,7 @@ fn bool create_piece() { for (int j = 0; j < 4; j++) { - if (piece[i - (int)piece_position_x][j] == GridSquare.MOVING) grid[i][j] = MOVING; + if (piece[i - (int)piece_position_x][j] == MOVING) grid[i][j] = MOVING; } } @@ -474,7 +474,7 @@ fn void resolve_falling_movement(bool* detection_ref, bool* piece_active_ref) { for (int i = 1; i < GRID_HORIZONTAL_SIZE - 1; i++) { - if (grid[i][j] == GridSquare.MOVING) + if (grid[i][j] == MOVING) { grid[i][j] = FULL; *detection_ref = false; @@ -489,7 +489,7 @@ fn void resolve_falling_movement(bool* detection_ref, bool* piece_active_ref) { for (int i = 1; i < GRID_HORIZONTAL_SIZE - 1; i++) { - if (grid[i][j] == GridSquare.MOVING) + if (grid[i][j] == MOVING) { grid[i][j+1] = MOVING; grid[i][j] = EMPTY; @@ -513,10 +513,10 @@ fn bool resolve_lateral_movement() { for (int i = 1; i < GRID_HORIZONTAL_SIZE - 1; i++) { - if (grid[i][j] == GridSquare.MOVING) + if (grid[i][j] == MOVING) { // Check if we are touching the left wall or we have a full square at the left - if ((i-1 == 0) || (grid[i-1][j] == GridSquare.FULL)) collision = true; + if ((i-1 == 0) || (grid[i-1][j] == FULL)) collision = true; } } } diff --git a/resources/examples/retry.c3 b/resources/examples/retry.c3 index 8d29c05c1..0665cac88 100644 --- a/resources/examples/retry.c3 +++ b/resources/examples/retry.c3 @@ -1,15 +1,12 @@ module test; import libc; -fault TestErr -{ - NOPE -} +fault NOPE; -fn int! eventually_succeed() +fn int? eventually_succeed() { static int i = 0; - if (i++ < 3) return TestErr.NOPE?; + if (i++ < 3) return NOPE?; return i * 3; } @@ -19,7 +16,7 @@ macro @retry(#function, int retries = 3) anyfault e; do { - $Type! result = #function; + $Type? result = #function; if (catch err = result) { e = err; @@ -32,7 +29,7 @@ macro @retry(#function, int retries = 3) fn void main() { - int! result = @retry(eventually_succeed()); + int? result = @retry(eventually_succeed()); if (try result) { libc::printf("Got result: %d\n", result); diff --git a/resources/examples/staticlib-test/add.c3 b/resources/examples/staticlib-test/add.c3 index d00c61d02..05dbf86f6 100644 --- a/resources/examples/staticlib-test/add.c3 +++ b/resources/examples/staticlib-test/add.c3 @@ -5,7 +5,7 @@ struct Foo(Printable) int a; } -fn usz! Foo.to_format(&self, Formatter* f) @dynamic +fn usz? Foo.to_format(&self, Formatter* f) @dynamic { return f.printf("Foo[%d]", self.a); } diff --git a/resources/grammar/grammar.y b/resources/grammar/grammar.y index c1b289aaf..0ff48f06c 100644 --- a/resources/grammar/grammar.y +++ b/resources/grammar/grammar.y @@ -578,7 +578,7 @@ type optional_type : type - | type '!' + | type '?' ; local_decl_after_type diff --git a/resources/linux_stack.c3 b/resources/linux_stack.c3 index d76869691..61b30f43f 100644 --- a/resources/linux_stack.c3 +++ b/resources/linux_stack.c3 @@ -3,7 +3,7 @@ import std::io; import std::collections::map; import std::os; -fn void! test2() +fn void? test2() { builtin::print_backtrace("hello", 1); } diff --git a/src/compiler/abi/c_abi_x86.c b/src/compiler/abi/c_abi_x86.c index f6fa650f1..3f1b20a74 100644 --- a/src/compiler/abi/c_abi_x86.c +++ b/src/compiler/abi/c_abi_x86.c @@ -113,7 +113,6 @@ static bool x86_should_return_type_in_reg(Type *type) case TYPE_TYPEDEF: case TYPE_DISTINCT: case TYPE_ENUM: - case TYPE_FAULTTYPE: case TYPE_TYPEID: case TYPE_ANYFAULT: case TYPE_BITSTRUCT: diff --git a/src/compiler/ast.c b/src/compiler/ast.c index d7b84899b..22526e43f 100644 --- a/src/compiler/ast.c +++ b/src/compiler/ast.c @@ -64,9 +64,6 @@ Decl *decl_new_with_type(const char *name, SourceSpan loc, DeclKind decl_type) case DECL_STRUCT: kind = TYPE_STRUCT; break; - case DECL_FAULT: - kind = TYPE_FAULTTYPE; - break; case DECL_ENUM: kind = TYPE_ENUM; break; @@ -121,10 +118,9 @@ const char *decl_to_a_name(Decl *decl) case DECL_ENUM_CONSTANT: return "an enum value"; case DECL_ERASED: return "an erased declaration"; case DECL_FAULT: return "a fault"; - case DECL_FAULTVALUE: return "a fault value"; case DECL_FNTYPE: return "a function type"; case DECL_FUNC: return "a function"; - case DECL_GLOBALS: return "globals"; + case DECL_GROUP: return "group"; case DECL_IMPORT: return "an import"; case DECL_LABEL: return "a label"; case DECL_MACRO: return "a macro"; @@ -407,6 +403,7 @@ bool decl_needs_prefix(Decl *decl) case DECL_DEFINE: case DECL_FUNC: case DECL_MACRO: + case DECL_FAULT: return !decl->is_autoimport; default: return false; diff --git a/src/compiler/c_codegen.c b/src/compiler/c_codegen.c index 41d62eaba..faddcd8fb 100644 --- a/src/compiler/c_codegen.c +++ b/src/compiler/c_codegen.c @@ -110,7 +110,6 @@ static const char *c_type_name(GenContext *c, Type *type) case TYPE_STRUCT: case TYPE_UNION: case TYPE_BITSTRUCT: - case TYPE_FAULTTYPE: case TYPE_SLICE: case TYPE_ARRAY: case TYPE_FLEXIBLE_ARRAY: @@ -235,7 +234,6 @@ static bool c_emit_type_decl(GenContext *c, Type *type) return true; } case TYPE_BITSTRUCT: - case TYPE_FAULTTYPE: TODO break; case TYPE_SLICE: @@ -371,8 +369,8 @@ static void c_emit_const_expr(GenContext *c, CValue *value, Expr *expr) } PRINT("\";\n"); return; + case CONST_FAULT: case CONST_ENUM: - case CONST_ERR: case CONST_BYTES: break; case CONST_POINTER: diff --git a/src/compiler/codegen_internal.h b/src/compiler/codegen_internal.h index 5f8523000..01e36bfd4 100644 --- a/src/compiler/codegen_internal.h +++ b/src/compiler/codegen_internal.h @@ -46,7 +46,6 @@ static inline Type *type_lowering(Type *type) return type_any; case TYPE_ANYFAULT: case TYPE_TYPEID: - case TYPE_FAULTTYPE: return type_iptr->canonical; case TYPE_BITSTRUCT: type = type->decl->strukt.container_type->type; diff --git a/src/compiler/compiler_internal.h b/src/compiler/compiler_internal.h index cfe685714..be9f4d49c 100644 --- a/src/compiler/compiler_internal.h +++ b/src/compiler/compiler_internal.h @@ -156,6 +156,7 @@ typedef struct Expr *expr_ref; Decl *global_ref; Decl *enum_err_val; + Decl *fault; Type *typeid; ConstInitializer *initializer; ConstInitializer *slice_init; @@ -289,7 +290,7 @@ struct Type_ Decl *decl; // int, float, bool TypeBuiltin builtin; - // Type[], Type[?], Type[123] or Type[<123>] + // Type[], Type[*], Type[123] or Type[<123>] TypeArray array; // fn TypeR Type1(Type2, Type3, ...) TypeFunction function; @@ -1413,11 +1414,7 @@ typedef struct bool resolved; union { - struct - { - TypeInfo *type; - const char *ident; - }; + Expr *expr; Decl *decl; }; } AstDocFault; @@ -1605,6 +1602,7 @@ struct CompilationUnit_ Decl **enums; Decl **attributes; Decl **faulttypes; + Decl **faults; const char **links; Visibility default_visibility; Attr *if_attr; @@ -2514,7 +2512,6 @@ int type_kind_bitsize(TypeKind kind); INLINE bool type_kind_is_signed(TypeKind kind); INLINE bool type_kind_is_unsigned(TypeKind kind); INLINE bool type_kind_is_any_integer(TypeKind kind); -INLINE bool type_kind_is_enumlike(TypeKind kind); void advance(ParseContext *c); INLINE void advance_and_verify(ParseContext *context, TokenType token_type); @@ -2615,17 +2612,6 @@ INLINE bool type_is_wildcard(Type *type) return type == type_wildcard || type == type_wildcard_optional; } -INLINE bool type_is_fault_raw(Type *type) -{ - switch (type->type_kind) - { - case TYPE_FAULTTYPE: - case TYPE_ANYFAULT: - return true; - default: - return false; - } -} INLINE bool type_is_any_raw(Type *type) { switch (type->type_kind) @@ -2662,7 +2648,6 @@ INLINE bool type_may_implement_interface(Type *type) case TYPE_UNION: case TYPE_ENUM: case TYPE_DISTINCT: - case TYPE_FAULTTYPE: case TYPE_BITSTRUCT: return true; default: @@ -2760,7 +2745,6 @@ INLINE bool type_is_atomic(Type *type_flat) case ALL_SIGNED_INTS: case ALL_FLOATS: case TYPE_ENUM: - case TYPE_FAULTTYPE: case TYPE_ANYFAULT: case TYPE_TYPEID: case TYPE_BOOL: @@ -3092,7 +3076,7 @@ INLINE bool type_is_builtin(TypeKind kind) { return kind >= TYPE_VOID && kind <= INLINE bool type_kind_is_signed(TypeKind kind) { return kind >= TYPE_I8 && kind < TYPE_U8; } INLINE bool type_kind_is_unsigned(TypeKind kind) { return kind >= TYPE_U8 && kind <= TYPE_U128; } INLINE bool type_kind_is_any_integer(TypeKind kind) { return kind >= TYPE_I8 && kind <= TYPE_U128; } -INLINE bool type_kind_is_enumlike(TypeKind kind) { return kind == TYPE_ENUM || kind == TYPE_FAULTTYPE; } +INLINE bool type_kind_is_enum_or_fault(TypeKind kind) { return kind == TYPE_ENUM || kind == TYPE_ANYFAULT; } INLINE bool type_is_unsigned(Type *type) { return type->type_kind >= TYPE_U8 && type->type_kind <= TYPE_U128; } INLINE bool type_ok(Type *type) { return !type || type->type_kind != TYPE_POISONED; } INLINE bool type_info_ok(TypeInfo *type_info) { return !type_info || type_info->kind != TYPE_INFO_POISON; } @@ -3211,12 +3195,6 @@ INLINE bool decl_is_struct_type(Decl *decl) return (kind == DECL_UNION) | (kind == DECL_STRUCT); } -static inline bool decl_is_enum_kind(Decl *decl) -{ - DeclKind kind = decl->decl_kind; - return (kind == DECL_ENUM) | (kind == DECL_FAULT); -} - INLINE bool decl_is_user_defined_type(Decl *decl) { DeclKind kind = decl->decl_kind; @@ -3697,6 +3675,14 @@ INLINE void expr_rewrite_const_bool(Expr *expr, Type *type, bool b) expr->resolve_status = RESOLVE_DONE; } +INLINE void expr_rewrite_const_fault(Expr *expr, Decl *fault) +{ + expr->expr_kind = EXPR_CONST; + expr->type = type_anyfault; + expr->const_expr = (ExprConst) { .fault = fault, .const_kind = CONST_FAULT }; + expr->resolve_status = RESOLVE_DONE; +} + INLINE void expr_rewrite_const_null(Expr *expr, Type *type) { expr->expr_kind = EXPR_CONST; @@ -4016,7 +4002,7 @@ INLINE bool expr_is_const_enum(Expr *expr) INLINE bool expr_is_const_fault(Expr *expr) { ASSERT(expr->resolve_status == RESOLVE_DONE); - return expr->expr_kind == EXPR_CONST && expr->const_expr.const_kind == CONST_ERR; + return expr->expr_kind == EXPR_CONST && expr->const_expr.const_kind == CONST_FAULT; } INLINE bool expr_is_const_pointer(Expr *expr) diff --git a/src/compiler/context.c b/src/compiler/context.c index 104f2f23f..83aa8e4d5 100644 --- a/src/compiler/context.c +++ b/src/compiler/context.c @@ -161,18 +161,16 @@ void decl_register(Decl *decl) case DECL_CT_ECHO: case DECL_CT_EXEC: case DECL_ENUM_CONSTANT: - case DECL_FAULTVALUE: case DECL_IMPORT: case DECL_LABEL: case DECL_DECLARRAY: case DECL_BODYPARAM: case DECL_CT_INCLUDE: - case DECL_GLOBALS: + case DECL_GROUP: UNREACHABLE case DECL_ATTRIBUTE: case DECL_BITSTRUCT: case DECL_DISTINCT: - case DECL_FAULT: case DECL_ENUM: case DECL_STRUCT: case DECL_TYPEDEF: @@ -183,6 +181,7 @@ void decl_register(Decl *decl) case DECL_VAR: case DECL_FNTYPE: case DECL_INTERFACE: + case DECL_FAULT: global_context_add_decl(decl); break; } @@ -239,12 +238,16 @@ void unit_register_global_decl(CompilationUnit *unit, Decl *decl) case DECL_STRUCT: case DECL_UNION: case DECL_TYPEDEF: - case DECL_FAULT: case DECL_BITSTRUCT: ASSERT(decl->name); vec_add(unit->types, decl); decl_register(decl); break; + case DECL_FAULT: + ASSERT(decl->name); + vec_add(unit->faults, decl); + decl_register(decl); + break; case DECL_DEFINE: ASSERT(decl->name); vec_add(unit->generic_defines, decl); @@ -259,13 +262,12 @@ void unit_register_global_decl(CompilationUnit *unit, Decl *decl) vec_add(unit->attributes, decl); decl_register(decl); break; - case DECL_FAULTVALUE: case DECL_ENUM_CONSTANT: case DECL_IMPORT: case DECL_LABEL: case DECL_DECLARRAY: case DECL_BODYPARAM: - case DECL_GLOBALS: + case DECL_GROUP: case DECL_FNTYPE: UNREACHABLE case DECL_CT_EXEC: diff --git a/src/compiler/copying.c b/src/compiler/copying.c index f8f7112a0..a3fe45196 100644 --- a/src/compiler/copying.c +++ b/src/compiler/copying.c @@ -262,8 +262,10 @@ INLINE Expr *copy_const_expr(CopyStruct *c, Expr *expr) case CONST_REF: fixup_decl(c, &expr->const_expr.global_ref); break; + case CONST_FAULT: + fixup_decl(c, &expr->const_expr.fault); + break; case CONST_ENUM: - case CONST_ERR: fixup_decl(c, &expr->const_expr.enum_err_val); break; case CONST_BYTES: @@ -638,7 +640,7 @@ RETRY: } else { - MACRO_COPY_TYPE(ast->contract_fault.type); + MACRO_COPY_EXPR(ast->contract_fault.expr); } break; case AST_CONTRACT: @@ -999,7 +1001,7 @@ Decl *copy_decl(CopyStruct *c, Decl *decl) MACRO_COPY_DECL_LIST(copy->methods); break; case DECL_DECLARRAY: - case DECL_GLOBALS: + case DECL_GROUP: UNREACHABLE case DECL_BITSTRUCT: copy_decl_type(copy); @@ -1009,8 +1011,9 @@ Decl *copy_decl(CopyStruct *c, Decl *decl) MACRO_COPY_TYPE(copy->strukt.container_type); MACRO_COPY_DECL_LIST(copy->methods); break; - case DECL_ENUM: case DECL_FAULT: + break; + case DECL_ENUM: copy_decl_type(copy); MACRO_COPY_TYPE_LIST(copy->interfaces); MACRO_COPY_DECL_LIST(copy->methods); @@ -1055,9 +1058,6 @@ Decl *copy_decl(CopyStruct *c, Decl *decl) fixup_declid(c, ©->enum_constant.parent); MACRO_COPY_EXPR_LIST(copy->enum_constant.args); break; - case DECL_FAULTVALUE: - fixup_declid(c, ©->enum_constant.parent); - break; case DECL_TYPEDEF: copy_decl_type(copy); if (copy->typedef_decl.is_func) diff --git a/src/compiler/enums.h b/src/compiler/enums.h index b118ba036..9e3950ea0 100644 --- a/src/compiler/enums.h +++ b/src/compiler/enums.h @@ -382,7 +382,6 @@ typedef enum ACCESS_TYPEOFANYFAULT, ACCESS_ENUMNAME, ACCESS_FAULTNAME, - ACCESS_FAULTORDINAL, } BuiltinAccessKind; typedef enum @@ -579,7 +578,7 @@ typedef enum CONST_INTEGER, CONST_BOOL, CONST_ENUM, - CONST_ERR, + CONST_FAULT, CONST_BYTES, CONST_STRING, CONST_POINTER, @@ -620,7 +619,6 @@ typedef enum CONV_UNION, CONV_ANY, CONV_INTERFACE, - CONV_FAULT, CONV_ENUM, CONV_FUNC, CONV_TYPEID, @@ -658,10 +656,9 @@ typedef enum DECL_ENUM_CONSTANT, DECL_ERASED, DECL_FAULT, - DECL_FAULTVALUE, DECL_FNTYPE, DECL_FUNC, - DECL_GLOBALS, + DECL_GROUP, DECL_IMPORT, DECL_LABEL, DECL_MACRO, @@ -836,18 +833,17 @@ typedef enum INTROSPECT_TYPE_ANYFAULT = 6, INTROSPECT_TYPE_ANY = 7, INTROSPECT_TYPE_ENUM = 8, - INTROSPECT_TYPE_FAULT = 9, - INTROSPECT_TYPE_STRUCT = 10, - INTROSPECT_TYPE_UNION = 11, - INTROSPECT_TYPE_BITSTRUCT = 12, - INTROSPECT_TYPE_FUNC = 13, - INTROSPECT_TYPE_OPTIONAL = 14, - INTROSPECT_TYPE_ARRAY = 15, - INTROSPECT_TYPE_SLICE = 16, - INTROSPECT_TYPE_VECTOR = 17, - INTROSPECT_TYPE_DISTINCT = 18, - INTROSPECT_TYPE_POINTER = 19, - INTROSPECT_TYPE_INTERFACE = 20, + INTROSPECT_TYPE_STRUCT = 9, + INTROSPECT_TYPE_UNION = 10, + INTROSPECT_TYPE_BITSTRUCT = 11, + INTROSPECT_TYPE_FUNC = 12, + INTROSPECT_TYPE_OPTIONAL = 13, + INTROSPECT_TYPE_ARRAY = 14, + INTROSPECT_TYPE_SLICE = 15, + INTROSPECT_TYPE_VECTOR = 16, + INTROSPECT_TYPE_DISTINCT = 17, + INTROSPECT_TYPE_POINTER = 18, + INTROSPECT_TYPE_INTERFACE = 19, } IntrospectType; typedef enum @@ -1318,7 +1314,6 @@ typedef enum TYPE_STRUCT, TYPE_UNION, TYPE_BITSTRUCT, - TYPE_FAULTTYPE, TYPE_TYPEDEF, TYPE_UNTYPED_LIST, TYPE_SLICE, @@ -1590,9 +1585,9 @@ typedef enum // -- Decl helper macros #define NON_TYPE_DECLS DECL_IMPORT: case DECL_MACRO: \ case DECL_DECLARRAY: case DECL_ATTRIBUTE: case DECL_LABEL: \ - case DECL_DEFINE: case DECL_CT_ASSERT: case DECL_CT_EXEC: \ - case DECL_CT_ECHO: case DECL_CT_INCLUDE: case DECL_GLOBALS: \ - case DECL_BODYPARAM: case DECL_VAR: case DECL_ENUM_CONSTANT: case DECL_FAULTVALUE: \ + case DECL_DEFINE: case DECL_CT_ASSERT: case DECL_CT_EXEC: case DECL_FAULT: \ + case DECL_CT_ECHO: case DECL_CT_INCLUDE: case DECL_GROUP: \ + case DECL_BODYPARAM: case DECL_VAR: case DECL_ENUM_CONSTANT: \ case DECL_POISONED // -- Expr helper macros @@ -1635,7 +1630,7 @@ static_assert(EXPR_LAST < 128, "Too many expression types"); #define ALL_FLOATS TYPE_BF16: case TYPE_F16: case TYPE_F32: case TYPE_F64: case TYPE_F128 #define LOWERED_TYPES CT_TYPES: case TYPE_ENUM: case TYPE_TYPEDEF: case TYPE_TYPEID: \ - case TYPE_DISTINCT: case TYPE_ANYFAULT: case TYPE_FAULTTYPE: case TYPE_BITSTRUCT: \ + case TYPE_DISTINCT: case TYPE_ANYFAULT: case TYPE_BITSTRUCT: \ case TYPE_OPTIONAL: case TYPE_INTERFACE #define CT_TYPES TYPE_TYPEINFO: case TYPE_INFERRED_ARRAY: case TYPE_INFERRED_VECTOR: case TYPE_UNTYPED_LIST: \ diff --git a/src/compiler/expr.c b/src/compiler/expr.c index 018d515bb..c028a3694 100644 --- a/src/compiler/expr.c +++ b/src/compiler/expr.c @@ -139,7 +139,6 @@ bool expr_is_zero(Expr *expr) case CONST_BOOL: return !expr->const_expr.b; case CONST_ENUM: - case CONST_ERR: return !expr->const_expr.enum_err_val->enum_constant.ordinal; case CONST_BYTES: case CONST_STRING: @@ -151,6 +150,8 @@ bool expr_is_zero(Expr *expr) } return true; } + case CONST_FAULT: + return !expr->const_expr.fault; case CONST_POINTER: return !expr->const_expr.ptr; case CONST_TYPEID: @@ -366,8 +367,6 @@ bool expr_is_runtime_const(Expr *expr) { case ACCESS_ENUMNAME: case ACCESS_FAULTNAME: - case ACCESS_FAULTORDINAL: - break; case ACCESS_TYPEOFANYFAULT: case ACCESS_TYPEOFANY: break; @@ -643,7 +642,6 @@ void expr_rewrite_to_const_zero(Expr *expr, Type *type) expr_rewrite_const_bool(expr, type, false); return; case TYPE_POINTER: - case TYPE_FAULTTYPE: case TYPE_ANY: case TYPE_INTERFACE: case TYPE_ANYFAULT: @@ -688,7 +686,7 @@ Expr *expr_from_const_expr_at_index(Expr *expr, ArrayIndex index) ExprConst *expr_const = &expr->const_expr; switch (expr_const->const_kind) { - case CONST_ERR: + case CONST_FAULT: case CONST_FLOAT: case CONST_INTEGER: case CONST_BOOL: diff --git a/src/compiler/headers.c b/src/compiler/headers.c index 66131d926..8a1554d8e 100644 --- a/src/compiler/headers.c +++ b/src/compiler/headers.c @@ -175,7 +175,6 @@ static void header_print_type(HeaderContext *c, Type *type) header_print_type(c, type->decl->strukt.container_type->type); return; case TYPE_ANYFAULT: - case TYPE_FAULTTYPE: PRINTF("c3fault_t"); return; case TYPE_DISTINCT: @@ -507,7 +506,6 @@ RETRY: case ALL_INTS: case TYPE_ANYFAULT: case TYPE_TYPEID: - case TYPE_FAULTTYPE: case TYPE_SLICE: case TYPE_ANY: case TYPE_INTERFACE: @@ -652,9 +650,10 @@ static void header_gen_global_var(HeaderContext *c, Decl *decl, bool fn_globals, PRINTF("\"\n"); return; case CONST_ENUM: - case CONST_ERR: PRINTF("%s\n", decl_get_extname(init->const_expr.enum_err_val)); return; + case CONST_FAULT: + PRINTF("%s\n", decl_get_extname(init->const_expr.fault)); case CONST_SLICE: case CONST_TYPEID: case CONST_MEMBER: diff --git a/src/compiler/json_output.c b/src/compiler/json_output.c index 1375e00ce..7783ec828 100644 --- a/src/compiler/json_output.c +++ b/src/compiler/json_output.c @@ -92,10 +92,9 @@ static inline const char *decl_type_to_string(Decl *type) case DECL_ENUM: return "enum"; case DECL_ENUM_CONSTANT: return "enum_const"; case DECL_FAULT: return "fault"; - case DECL_FAULTVALUE: return "fault_val"; case DECL_FNTYPE: return "fntype"; case DECL_FUNC: return "function"; - case DECL_GLOBALS: return "global"; + case DECL_GROUP: return "globals"; case DECL_IMPORT: return "import"; case DECL_MACRO: return "macro"; case DECL_INTERFACE: return "interface"; @@ -160,11 +159,11 @@ void print_type(FILE *file, TypeInfo *type) break; case TYPE_INFO_INFERRED_ARRAY: print_type(file, type->array.base); - fputs("[?]", file); + fputs("[*]", file); break; case TYPE_INFO_INFERRED_VECTOR: print_type(file, type->array.base); - fputs("[]", file); + fputs("[<*>]", file); break; case TYPE_INFO_SLICE: print_type(file, type->array.base); diff --git a/src/compiler/llvm_codegen.c b/src/compiler/llvm_codegen.c index bbb89f98b..42f6a45e1 100644 --- a/src/compiler/llvm_codegen.c +++ b/src/compiler/llvm_codegen.c @@ -625,7 +625,7 @@ void llvm_emit_global_variable_init(GenContext *c, Decl *decl) if (init_expr && IS_OPTIONAL(init_expr) && init_expr->expr_kind == EXPR_OPTIONAL) { Expr *inner = init_expr->inner_expr; - ASSERT(expr_is_const(inner) && inner->const_expr.const_kind == CONST_ERR); + ASSERT(expr_is_const(inner) && inner->const_expr.const_kind == CONST_FAULT); BEValue value; llvm_emit_expr_global_value(c, &value, inner); optional_value = llvm_load_value_store(c, &value); @@ -999,7 +999,6 @@ static void llvm_emit_type_decls(GenContext *context, Decl *decl) case DECL_STRUCT: case DECL_UNION: case DECL_ENUM: - case DECL_FAULT: case DECL_BITSTRUCT: llvm_get_typeid(context, decl->type); break; @@ -1271,6 +1270,18 @@ void llvm_append_function_attributes(GenContext *c, Decl *decl) LLVMSetFunctionCallConv(function, llvm_call_convention_from_call(prototype->call_abi)); } +static LLVMValueRef llvm_create_fault(GenContext *c, Decl *decl) +{ + scratch_buffer_set_extern_decl_name(decl, true); + LLVMValueRef fault = llvm_add_global_raw(c, scratch_buffer_to_string(), c->chars_type, 0); + LLVMSetGlobalConstant(fault, 1); + scratch_buffer_append(".nameof"); + LLVMSetInitializer(fault, llvm_emit_string_const(c, decl->name, scratch_buffer_to_string())); + llvm_set_linkonce(c, fault); + decl->backend_ref = fault; + return fault; +} + LLVMValueRef llvm_get_ref(GenContext *c, Decl *decl) { ASSERT(!decl->is_value); @@ -1317,13 +1328,8 @@ LLVMValueRef llvm_get_ref(GenContext *c, Decl *decl) return backend_ref; case DECL_DEFINE: return llvm_get_ref(c, decl->define_decl.alias); - case DECL_FAULTVALUE: - if (!decl->backend_ref) - { - llvm_get_typeid(c, declptr(decl->enum_constant.parent)->type); - } - ASSERT(decl->backend_ref); - return decl->backend_ref; + case DECL_FAULT: + return llvm_create_fault(c, decl); case DECL_POISONED: case DECL_ATTRIBUTE: case DECL_BITSTRUCT: @@ -1331,7 +1337,6 @@ LLVMValueRef llvm_get_ref(GenContext *c, Decl *decl) case DECL_DISTINCT: case DECL_ENUM: case DECL_ENUM_CONSTANT: - case DECL_FAULT: case DECL_IMPORT: case DECL_LABEL: case DECL_MACRO: @@ -1343,7 +1348,7 @@ LLVMValueRef llvm_get_ref(GenContext *c, Decl *decl) case DECL_CT_ECHO: case DECL_CT_EXEC: case DECL_CT_INCLUDE: - case DECL_GLOBALS: + case DECL_GROUP: case DECL_INTERFACE: UNREACHABLE; } diff --git a/src/compiler/llvm_codegen_debug_info.c b/src/compiler/llvm_codegen_debug_info.c index 251d5da63..5f9cc2933 100644 --- a/src/compiler/llvm_codegen_debug_info.c +++ b/src/compiler/llvm_codegen_debug_info.c @@ -616,8 +616,6 @@ static inline LLVMMetadataRef llvm_get_debug_type_internal(GenContext *c, Type * return type->backend_debug_type = llvm_debug_pointer_type(c, type); case TYPE_ENUM: return type->backend_debug_type = llvm_debug_enum_type(c, type, scope); - case TYPE_FAULTTYPE: - return type->backend_debug_type = llvm_debug_enum_type(c, type, scope); case TYPE_FUNC_RAW: return type->backend_debug_type = llvm_debug_func_type(c, type); case TYPE_STRUCT: diff --git a/src/compiler/llvm_codegen_expr.c b/src/compiler/llvm_codegen_expr.c index c8f024f0a..e3f59757c 100644 --- a/src/compiler/llvm_codegen_expr.c +++ b/src/compiler/llvm_codegen_expr.c @@ -3476,7 +3476,6 @@ static void llvm_emit_array_comp(GenContext *c, BEValue *be_value, BEValue *lhs, case TYPE_INTERFACE: case TYPE_ANY: case TYPE_ANYFAULT: - case TYPE_FAULTTYPE: case TYPE_TYPEID: MEMCMP: llvm_value_addr(c, lhs); @@ -4744,9 +4743,9 @@ static void llvm_emit_const_expr(GenContext *c, BEValue *be_value, Expr *expr) case CONST_TYPEID: llvm_emit_typeid(c, be_value, expr->const_expr.typeid); return; - case CONST_ERR: + case CONST_FAULT: { - Decl *decl = expr->const_expr.enum_err_val; + Decl *decl = expr->const_expr.fault; ASSERT(decl); LLVMValueRef value = LLVMBuildPtrToInt(c->builder, llvm_get_ref(c, decl), llvm_get_type(c, type_anyfault), ""); llvm_value_set(be_value, value, type_anyfault); @@ -6577,36 +6576,11 @@ static inline void llvm_emit_builtin_access(GenContext *c, BEValue *be_value, Ex llvm_value_fold_optional(c, be_value); switch (expr->builtin_access_expr.kind) { - case ACCESS_FAULTORDINAL: - { - LLVMBasicBlockRef current_block = llvm_get_current_block_if_in_use(c); - if (!current_block) - { - llvm_value_set(be_value, llvm_get_zero(c, type_usz), type_usz); - return; - } - ASSERT(type_flatten(inner->type)->type_kind == TYPE_FAULTTYPE); - llvm_value_rvalue(c, be_value); - LLVMBasicBlockRef exit_block = llvm_basic_block_new(c, "faultordinal_exit"); - LLVMBasicBlockRef ok_block = llvm_basic_block_new(c, "faultordinal_found"); - BEValue check; - llvm_emit_int_comp_zero(c, &check, be_value, BINARYOP_EQ); - llvm_emit_cond_br(c, &check, exit_block, ok_block); - llvm_emit_block(c, ok_block); - LLVMValueRef fault_data = LLVMBuildIntToPtr(c->builder, be_value->value, - c->ptr_type, ""); - LLVMValueRef ptr = LLVMBuildStructGEP2(c->builder, c->fault_type, fault_data, 2, ""); - LLVMValueRef ordinal = llvm_load_abi_alignment(c, type_usz, ptr, ""); - llvm_emit_br(c, exit_block); - llvm_emit_block(c, exit_block); - llvm_new_phi(c, be_value, "faultname", type_usz, llvm_const_int(c, type_usz, 0), current_block, ordinal, ok_block); - return; - } case ACCESS_FAULTNAME: { Type *inner_type = type_no_optional(inner->type)->canonical; (void)inner_type; - ASSERT(inner_type->type_kind == TYPE_FAULTTYPE || inner_type->type_kind == TYPE_ANYFAULT); + ASSERT(inner_type->type_kind == TYPE_ANYFAULT); llvm_value_rvalue(c, be_value); LLVMValueRef val = llvm_emit_alloca_aligned(c, type_chars, "faultname_zero"); BEValue zero; @@ -6621,13 +6595,11 @@ static inline void llvm_emit_builtin_access(GenContext *c, BEValue *be_value, Ex llvm_store_zero(c, &zero); llvm_emit_br(c, exit_block); llvm_emit_block(c, ok_block); - LLVMValueRef fault_data = LLVMBuildIntToPtr(c->builder, be_value->value, - c->ptr_type, ""); - LLVMValueRef ptr = LLVMBuildStructGEP2(c->builder, c->fault_type, fault_data, 1, ""); + LLVMValueRef fault_data = LLVMBuildIntToPtr(c->builder, be_value->value, c->ptr_type, ""); llvm_emit_br(c, exit_block); llvm_emit_block(c, exit_block); LLVMValueRef phi = LLVMBuildPhi(c->builder, c->ptr_type, "faultname"); - llvm_set_phi(phi, zero.value, zero_block, ptr, ok_block); + llvm_set_phi(phi, zero.value, zero_block, fault_data, ok_block); llvm_value_set_address_abi_aligned(be_value, phi, type_chars); return; } diff --git a/src/compiler/llvm_codegen_module.c b/src/compiler/llvm_codegen_module.c index f0d6faa55..ec266db8e 100644 --- a/src/compiler/llvm_codegen_module.c +++ b/src/compiler/llvm_codegen_module.c @@ -86,7 +86,6 @@ void gencontext_begin_module(GenContext *c) switch (type->type_kind) { case TYPE_ENUM: - case TYPE_FAULTTYPE: { FOREACH(Decl *, value, type->decl->enums.values) { diff --git a/src/compiler/llvm_codegen_type.c b/src/compiler/llvm_codegen_type.c index 8950815d9..78f4779ab 100644 --- a/src/compiler/llvm_codegen_type.c +++ b/src/compiler/llvm_codegen_type.c @@ -78,8 +78,6 @@ static inline LLVMTypeRef llvm_type_from_decl(GenContext *c, Decl *decl) } case DECL_ENUM: return llvm_get_type(c, decl->type); - case DECL_FAULT: - return llvm_get_type(c, type_iptr); } UNREACHABLE } @@ -118,7 +116,6 @@ static void param_expand(GenContext *context, LLVMTypeRef** params_ref, Type *ty } case TYPE_ENUM: case TYPE_ANYFAULT: - case TYPE_FAULTTYPE: param_expand(context, params_ref, type_lowering(type)); return; case TYPE_UNION: @@ -598,43 +595,6 @@ static LLVMValueRef llvm_get_introspection_for_struct_union(GenContext *c, Type vec_size(decls), NULL, false); } -static LLVMValueRef llvm_get_introspection_for_fault(GenContext *c, Type *type) -{ - void *builder = c->builder; - c->builder = c->global_builder; - - Decl *decl = type->decl; - Decl **fault_vals = decl->enums.values; - unsigned elements = vec_size(fault_vals); - LLVMValueRef ref = llvm_generate_temp_introspection_global(c, type); - for (unsigned i = 0; i < elements; i++) - { - scratch_buffer_set_extern_decl_name(decl, true); - scratch_buffer_append_char('$'); - Decl *val = fault_vals[i]; - scratch_buffer_append(val->name); - LLVMValueRef global_name = LLVMAddGlobal(c->module, c->fault_type, scratch_buffer_to_string()); - LLVMSetAlignment(global_name, LLVMPreferredAlignmentOfGlobal(c->target_data, global_name)); - LLVMSetGlobalConstant(global_name, 1); - - LLVMValueRef vals[3] = { LLVMBuildPtrToInt(c->builder, ref, c->typeid_type, ""), - llvm_emit_string_const(c, val->name, ".fault"), - llvm_const_int(c, type_usz, val->enum_constant.ordinal + 1 )}; - - LLVMSetInitializer(global_name, llvm_get_struct_named(c->fault_type, vals, 3)); - llvm_set_linkonce(c, global_name); - val->backend_ref = LLVMBuildPtrToInt(c->builder, global_name, c->typeid_type, ""); - } - LLVMValueRef* values = elements ? MALLOC(sizeof(LLVMValueRef) * elements) : NULL; - for (unsigned i = 0; i < elements; i++) - { - assert(values); - values[i] = fault_vals[i]->backend_ref; - } - c->builder = builder; - return llvm_generate_introspection_global(c, ref, type, INTROSPECT_TYPE_FAULT, NULL, elements, NULL, false); -} - LLVMValueRef llvm_get_typeid(GenContext *c, Type *type) { @@ -662,8 +622,6 @@ LLVMValueRef llvm_get_typeid(GenContext *c, Type *type) return llvm_generate_introspection_global(c, NULL, type, INTROSPECT_TYPE_DISTINCT, type->decl->distinct->type, 0, NULL, false); case TYPE_ENUM: return llvm_get_introspection_for_enum(c, type); - case TYPE_FAULTTYPE: - return llvm_get_introspection_for_fault(c, type); case TYPE_STRUCT: case TYPE_UNION: return llvm_get_introspection_for_struct_union(c, type); diff --git a/src/compiler/llvm_codegen_value.c b/src/compiler/llvm_codegen_value.c index 7d1dcb674..821647d72 100644 --- a/src/compiler/llvm_codegen_value.c +++ b/src/compiler/llvm_codegen_value.c @@ -44,6 +44,10 @@ void llvm_value_set(BEValue *value, LLVMValueRef llvm_value, Type *type) void llvm_value_set_address(BEValue *value, LLVMValueRef llvm_value, Type *type, AlignSize alignment) { + if (alignment == 0) + { + puts("TODO"); + } ASSERT(alignment > 0); value->value = llvm_value; value->alignment = alignment; diff --git a/src/compiler/number.c b/src/compiler/number.c index 91934b5a1..fa4b7cff3 100644 --- a/src/compiler/number.c +++ b/src/compiler/number.c @@ -135,6 +135,9 @@ bool expr_const_compare(const ExprConst *left, const ExprConst *right, BinaryOp case CONST_INTEGER: ASSERT(right->const_kind != CONST_ENUM); return int_comp(left->ixx, right->ixx, op); + case CONST_FAULT: + ASSERT(right->const_kind == CONST_FAULT); + return decl_flatten(right->fault) == decl_flatten(left->fault); case CONST_REF: ASSERT(right->const_kind == CONST_POINTER || right->const_kind == CONST_REF); if (right->const_kind == CONST_POINTER) return false; @@ -163,7 +166,6 @@ bool expr_const_compare(const ExprConst *left, const ExprConst *right, BinaryOp case CONST_TYPEID: is_eq = left->typeid == right->typeid; goto RETURN; - case CONST_ERR: case CONST_ENUM: { Decl *left_decl = left->enum_err_val; @@ -274,7 +276,7 @@ bool expr_const_will_overflow(const ExprConst *expr, TypeKind kind) Int i = { .i = { .low = expr->enum_err_val->var.index }, .type = type_flatten(expr->enum_err_val->type)->type_kind }; return !int_fits(i, kind); } - case CONST_ERR: + case CONST_FAULT: case CONST_BYTES: case CONST_STRING: case CONST_POINTER: @@ -310,8 +312,9 @@ const char *expr_const_to_error_string(const ExprConst *expr) return ""; case CONST_REF: return expr->global_ref->name; + case CONST_FAULT: + return expr->fault->name; case CONST_ENUM: - case CONST_ERR: return expr->enum_err_val->name; case CONST_TYPEID: return type_to_error_string(expr->typeid); diff --git a/src/compiler/parse_expr.c b/src/compiler/parse_expr.c index 7457292c4..c6f8b218f 100644 --- a/src/compiler/parse_expr.c +++ b/src/compiler/parse_expr.c @@ -1903,7 +1903,7 @@ Expr *parse_type_expression_with_path(ParseContext *c, Path *path) advance_and_verify(c, TOKEN_TYPE_IDENT); RANGE_EXTEND_PREV(type); ASSIGN_TYPE_OR_RET(type, parse_type_with_base(c, type), poisoned_expr); - type->optional = try_consume(c, TOKEN_BANG); + type->optional = try_consume(c, TOKEN_QUESTION); } else { diff --git a/src/compiler/parse_global.c b/src/compiler/parse_global.c index aa77badc1..ab1067406 100644 --- a/src/compiler/parse_global.c +++ b/src/compiler/parse_global.c @@ -514,7 +514,7 @@ static inline TypeInfo *parse_array_type_index(ParseContext *c, TypeInfo *type) ASSERT(type_info_ok(type)); advance_and_verify(c, TOKEN_LBRACKET); - if (try_consume(c, TOKEN_STAR) || try_consume(c, TOKEN_QUESTION)) + if (try_consume(c, TOKEN_STAR)) { CONSUME_OR_RET(TOKEN_RBRACKET, poisoned_type_info); TypeInfo *inferred_array = type_info_new(TYPE_INFO_INFERRED_ARRAY, type->span); @@ -575,7 +575,7 @@ static inline TypeInfo *parse_vector_type_index(ParseContext *c, TypeInfo *type) advance_and_verify(c, TOKEN_LVEC); TypeInfo *vector = type_info_new(TYPE_INFO_VECTOR, type->span); vector->array.base = type; - if (try_consume(c, TOKEN_STAR) || try_consume(c, TOKEN_QUESTION)) + if (try_consume(c, TOKEN_STAR)) { CONSUME_OR_RET(TOKEN_RVEC, poisoned_type_info); vector->kind = TYPE_INFO_INFERRED_VECTOR; @@ -697,14 +697,14 @@ INLINE bool parse_rethrow_bracket(ParseContext *c, SourceSpan start) case DISCARD_ERR: return false; case DISCARD_WILDCARD: - print_error_at(extend_span_with_token(start, c->prev_span), "When declaring an optional array, the '[?]' should appear before the '!', e.g 'Foo[?]!'."); + print_error_at(extend_span_with_token(start, c->prev_span), "When declaring an optional array, the '[*]' should appear before the '?', e.g 'Foo[*]?'."); return false; case DISCARD_SLICE: print_error_at(extend_span_with_token(start, c->prev_span), - "When declaring an optional slice the '[]' should appear before the '!', e.g 'Foo[]!'."); + "When declaring an optional slice the '[]' should appear before the '?', e.g 'Foo[]?'."); return false; case DISCARD_EXPR: - print_error_at(extend_span_with_token(start, c->prev_span), "When declaring an optional array, the '[...]' should appear before the '!', e.g 'Foo[4]!'."); + print_error_at(extend_span_with_token(start, c->prev_span), "When declaring an optional array, the '[...]' should appear before the '?', e.g 'Foo[4]?'."); return false; } UNREACHABLE @@ -716,12 +716,12 @@ INLINE bool parse_rethrow_bracket(ParseContext *c, SourceSpan start) case DISCARD_ERR: return false; case DISCARD_WILDCARD: - print_error_at(extend_span_with_token(start, c->span), "When declaring an optional vector, the '[]' should appear before the '!', e.g 'Foo[]!'."); + print_error_at(extend_span_with_token(start, c->span), "When declaring an optional vector, the '[<*>]' should appear before the '?', e.g 'Foo[<*>]?'."); return false; case DISCARD_SLICE: UNREACHABLE case DISCARD_EXPR: - print_error_at(extend_span_with_token(start, c->span), "When declaring an optional vector, the '[<...>]' should appear before the '!', e.g 'Foo[<4>]!'."); + print_error_at(extend_span_with_token(start, c->span), "When declaring an optional vector, the '[<...>]' should appear before the '?', e.g 'Foo[<4>]?'."); return false; } UNREACHABLE @@ -738,7 +738,7 @@ static inline TypeInfo *parse_optional_type_maybe_generic(ParseContext *c, bool { ASSIGN_TYPE_OR_RET(TypeInfo *info, parse_base_type(c), poisoned_type_info); ASSIGN_TYPE_OR_RET(info, parse_type_with_base_maybe_generic(c, info, allow_generic), poisoned_type_info); - if (try_consume(c, TOKEN_BANG)) + if (try_consume(c, TOKEN_QUESTION)) { if (!parse_rethrow_bracket(c, info->span)) return poisoned_type_info; ASSERT(!info->optional); @@ -1226,7 +1226,7 @@ static inline Decl *parse_global_declaration(ParseContext *c) if (decls) { decl = decl_calloc(); - decl->decl_kind = DECL_GLOBALS; + decl->decl_kind = DECL_GROUP; decl->decls = decls; return decl; } @@ -2237,56 +2237,44 @@ static inline Decl *parse_macro_declaration(ParseContext *c, AstId docs) return decl; } +static inline Decl *parse_fault(ParseContext *c) +{ + Decl *decl = decl_new(DECL_FAULT, symstr(c), c->span); + if (!consume_const_name(c, "fault")) return poisoned_decl; + if (!parse_attributes_for_global(c, decl)) return poisoned_decl; + return decl; +} /** - * fault_declaration ::= FAULT TYPE_IDENT opt_interfaces opt_attributes '{' faults ','? '}' + * fault_declaration ::= FAULT CONST_IDENT (',' CONST_IDENT)* ','? ';' */ static inline Decl *parse_fault_declaration(ParseContext *c) { advance_and_verify(c, TOKEN_FAULT); - Decl *decl = decl_new_with_type(symstr(c), c->span, DECL_FAULT); - if (!consume_type_name(c, "fault")) return poisoned_decl; - if (!parse_interface_impls(c, &decl->interfaces)) return poisoned_decl; - - if (!parse_attributes_for_global(c, decl)) return poisoned_decl; - - CONSUME_OR_RET(TOKEN_LBRACE, poisoned_decl); - - decl->enums.type_info = type_info_new_base(type_iptr->canonical, decl->span); - uint64_t ordinal = 0; - while (!try_consume(c, TOKEN_RBRACE)) + if (c->lexer.token_type == TOKEN_EOS) { - Decl *fault_const = decl_new(DECL_FAULTVALUE, symstr(c), c->span); - if (!consume_const_name(c, "fault value")) - { - return poisoned_decl; - } - const char *name = fault_const->name; - fault_const->enum_constant.parent = declid(decl); - fault_const->enum_constant.ordinal = ordinal; - ordinal++; - FOREACH(Decl *, other_constant, decl->enums.values) - { - if (other_constant->name == name) - { - PRINT_ERROR_AT(fault_const, "This fault value was declared twice."); - SEMA_NOTE(other_constant, "The previous declaration was here."); - return poisoned_decl; - } - } - vec_add(decl->enums.values, fault_const); - // Allow trailing ',' - if (!try_consume(c, TOKEN_COMMA)) - { - EXPECT_OR_RET(TOKEN_RBRACE, poisoned_decl); - } + ASSIGN_DECL_OR_RET(Decl *decl, parse_fault(c), poisoned_decl); + CONSUME_EOS_OR_RET(poisoned_decl); + return decl; } - if (ordinal == 0) + Decl **decls = NULL; + while (!try_consume(c, TOKEN_EOS)) { - print_error_at(c->prev_span, "Declaration of '%s' contains no values, at least one value is required.", decl->name); + ASSIGN_DECL_OR_RET(Decl *decl, parse_fault(c), poisoned_decl); + vec_add(decls, decl); + if (try_consume(c, TOKEN_COMMA)) continue; + CONSUME_OR_RET(TOKEN_EOS, poisoned_decl); + break; + } + if (!decls) + { + PRINT_ERROR_LAST("Expected the name of a fault here."); return poisoned_decl; } + Decl *decl = decl_calloc(); + decl->decl_kind = DECL_GROUP; + decl->decl_list = decls; return decl; } @@ -2726,17 +2714,7 @@ static inline bool parse_doc_optreturn(ParseContext *c, AstId *docs, AstId **doc while (1) { Ast *ret = ast_new_curr(c, AST_CONTRACT_FAULT); - ASSIGN_TYPE_OR_RET(ret->contract_fault.type, parse_base_type(c), false); - if (ret->contract_fault.type->kind != TYPE_INFO_IDENTIFIER) - { - RETURN_PRINT_ERROR_AT(false, ret->contract_fault.type, "Expected a fault type."); - } - if (try_consume(c, TOKEN_DOT)) - { - ret->contract_fault.ident = c->data.string; - TRY_CONSUME_OR_RET(TOKEN_CONST_IDENT, "Expected a fault value.", false); - } - RANGE_EXTEND_PREV(ret); + ASSIGN_EXPR_OR_RET(ret->contract_fault.expr, parse_expr(c), false); vec_add(returns, ret); if (!try_consume(c, TOKEN_COMMA)) break; } diff --git a/src/compiler/parser_internal.h b/src/compiler/parser_internal.h index 94f7f43b7..34c7541a5 100644 --- a/src/compiler/parser_internal.h +++ b/src/compiler/parser_internal.h @@ -65,7 +65,7 @@ Expr *parse_type_compound_literal_expr_after_type(ParseContext *c, TypeInfo *typ INLINE void add_decl_to_list(Decl ***list, Decl *decl) { - if (decl->decl_kind == DECL_GLOBALS) + if (decl->decl_kind == DECL_GROUP) { FOREACH(Decl *, d, decl->decls) vec_add(*list, d); return; diff --git a/src/compiler/sema_casts.c b/src/compiler/sema_casts.c index 65180724d..29b6ca6c4 100644 --- a/src/compiler/sema_casts.c +++ b/src/compiler/sema_casts.c @@ -204,7 +204,6 @@ void cast_promote_vararg(Expr *arg) if (arg_type->type_kind == TYPE_SLICE) { cast_no_check(arg, type_get_ptr(arg_type->array.base), IS_OPTIONAL(arg)); - return; } } @@ -226,10 +225,10 @@ Type *type_infer_len_from_actual_type(Type *to_infer, Type *actual_type) // if so we assume the original type if (!type_len_is_inferred(to_infer)) return to_infer; - // Handle int[?]! a = { ... } by stripping the optional. + // Handle int[*]? a = { ... } by stripping the optional. bool is_optional = type_is_optional(to_infer); - assert((is_optional || !type_is_optional(actual_type)) && "int[?] x = { may_fail } should have been caught."); + assert((is_optional || !type_is_optional(actual_type)) && "int[*] x = { may_fail } should have been caught."); // Strip the optional if (is_optional) to_infer = to_infer->optional; @@ -241,7 +240,7 @@ Type *type_infer_len_from_actual_type(Type *to_infer, Type *actual_type) if (!actual) return actual_type; // Grab the underlying indexed type, - // because we can only have [?] [] [] [<>] * here + // because we can only have [*] [] [<*>] [<>] * here Type *indexed = type_get_indexed_type(to_infer); // We should always have indexed types. @@ -251,7 +250,7 @@ Type *type_infer_len_from_actual_type(Type *to_infer, Type *actual_type) // In this case, infer it. if (type_len_is_inferred(indexed)) { - // if we have int[?][?] => the inner is int[?], we cast it here. + // if we have int[*][*] => the inner is int[*], we cast it here. indexed = type_infer_len_from_actual_type(indexed, actual); } @@ -259,10 +258,10 @@ Type *type_infer_len_from_actual_type(Type *to_infer, Type *actual_type) switch (to_infer->type_kind) { case TYPE_POINTER: - // The case of int[?]* x = ... + // The case of int[*]* x = ... return type_add_optional(type_get_ptr(indexed), is_optional); case TYPE_ARRAY: - // The case of int[?][2] x = ... + // The case of int[*][2] x = ... return type_add_optional(type_get_array(indexed, to_infer->array.len), is_optional); case TYPE_INFERRED_ARRAY: ASSERT(type_is_arraylike(type_flatten(actual_type))); @@ -273,7 +272,7 @@ Type *type_infer_len_from_actual_type(Type *to_infer, Type *actual_type) case TYPE_SLICE: return type_add_optional(type_get_slice(indexed), is_optional); case TYPE_VECTOR: - // The case of int[?]*[<2>] x = ... + // The case of int[*]*[<2>] x = ... return type_add_optional(type_get_vector(indexed, to_infer->array.len), is_optional); default: UNREACHABLE @@ -409,7 +408,6 @@ RETRY: case ACCESS_TYPEOFANY: case ACCESS_ENUMNAME: case ACCESS_FAULTNAME: - case ACCESS_FAULTORDINAL: // For the rest, just check size. goto CHECK_SIZE; } @@ -999,7 +997,6 @@ static bool rule_arr_to_vec(CastContext *cc, bool is_explicit, bool is_silent) case CONV_INT: case CONV_FLOAT: case CONV_POINTER: - case CONV_FAULT: case CONV_ENUM: case CONV_TYPEID: case CONV_ANYFAULT: @@ -1173,22 +1170,6 @@ static bool rule_explicit_ok(CastContext *cc, bool is_explicit, bool silent) } -static bool rule_anyfault_to_fault(CastContext *cc, bool is_explicit, bool is_silent) -{ - if (!is_explicit) - { - if (is_silent) return false; - return sema_cast_error(cc, rule_anyfault_to_fault(cc, true, true), false); - } - Expr *expr = cc->expr; - if (!expr_is_const_fault(expr)) return true; - if (type_flatten(cc->to) == expr->const_expr.enum_err_val->type) return true; - if (is_silent) return false; - RETURN_CAST_ERROR(expr, "This expression is known at compile time to be a fault of type %s, so it cannot be cast to %s.", - type_quoted_error_string(expr->const_expr.enum_err_val->type), - type_quoted_error_string(cc->to_type)); -} - static bool rule_int_to_float(CastContext *cc, bool is_explicit, bool is_silent) { if (is_explicit) return true; @@ -1516,7 +1497,6 @@ static void cast_ptr_to_any(Expr *expr, Type *type) expr->type = type; } static void cast_struct_to_inline(Expr *expr, Type *type) { expr_rewrite_addr_conversion(expr, type); } -static void cast_fault_to_anyfault(Expr *expr, Type *type) { expr->type = type; } static void cast_fault_to_ptr(Expr *expr, Type *type) { expr_rewrite_to_int_to_ptr(expr, type); } static void cast_typeid_to_int(Expr *expr, Type *type) { expr_rewrite_ext_trunc(expr, type, type_is_signed(type_flatten_to_int(type))); } static void cast_fault_to_int(Expr *expr, Type *type) { cast_typeid_to_int(expr, type); } @@ -1846,7 +1826,6 @@ static void cast_vec_to_vec(Expr *expr, Type *to_type) case TYPE_FUNC_PTR: case TYPE_TYPEID: case TYPE_ANYFAULT: - case TYPE_FAULTTYPE: expr_rewrite_to_int_to_ptr(expr, to_type); default: UNREACHABLE; @@ -1873,7 +1852,6 @@ static void cast_vec_to_vec(Expr *expr, Type *to_type) case TYPE_FUNC_PTR: case TYPE_TYPEID: case TYPE_ANYFAULT: - case TYPE_FAULTTYPE: expr_rewrite_rvalue(expr, to_type); return; default: @@ -2107,7 +2085,7 @@ static void cast_vecarr_to_slice(Expr *expr, Type *to_type) case CONST_INTEGER: case CONST_BOOL: case CONST_ENUM: - case CONST_ERR: + case CONST_FAULT: case CONST_POINTER: case CONST_TYPEID: case CONST_SLICE: @@ -2248,15 +2226,13 @@ static void cast_typeid_to_bool(Expr *expr, Type *to_type) { expr_rewrite_int_to #define AR2AR &cast_arr_to_arr #define ST2LN &cast_struct_to_inline #define AY2BO &cast_any_to_bool -#define AY2PT &cast_any_to_ptr +#define AY2PT &cast_any_to_ptr #define FA2IN &cast_fault_to_int -#define FA2PT &cast_fault_to_ptr -#define FA2AF &cast_fault_to_anyfault -#define TI2BO &cast_typeid_to_bool +#define FA2PT &cast_fault_to_ptr +#define TI2BO &cast_typeid_to_bool #define TI2IN &cast_typeid_to_int #define TI2PT &cast_typeid_to_ptr #define AF2BO &cast_anyfault_to_bool -#define AF2FA &cast_anyfault_to_fault #define SL2VA &cast_slice_to_vecarr #define VA2SL &cast_vecarr_to_slice #define XX2VO &cast_all_to_void @@ -2272,11 +2248,10 @@ static void cast_typeid_to_bool(Expr *expr, Type *to_type) { expr_rewrite_int_to #define RWIDE &rule_widen_narrow /* Widen / narrow conversion of int/float */ #define RINFL &rule_int_to_float /* Simple expressions, check sizes */ #define ROKOK &rule_all_ok /* Always works */ -#define RAFFA &rule_anyfault_to_fault /* Runtime check that it's valid, otherwise ok if explicit */ #define RINPT &rule_int_to_ptr /* Int -> ptr (explicit + size match) */ #define RPTIN &rule_ptr_to_int /* Ptr -> int (explicit + size match) */ #define RINBS &rule_int_to_bits /* Int -> bits (explicit + int + size match) */ -#define RARBS &rule_arr_to_bits /* Char[?] -> bits (explicit + base match) */ +#define RARBS &rule_arr_to_bits /* Char[*] -> bits (explicit + base match) */ #define RINEN &rule_int_to_enum /* Int -> enum (explicit, range check const) */ #define RPTPT &rule_ptr_to_ptr /* Ptr -> ptr (explicit or ptr match) */ #define RAPSL &rule_arrptr_to_slice /* Arrptr -> Slice (explicit flattens distinct, pointer match) */ @@ -2308,59 +2283,57 @@ static void cast_typeid_to_bool(Expr *expr, Type *to_type) { expr_rewrite_int_to #define RVPAN &rule_voidptr_to_any /* void* -> interface/any */ CastRule cast_rules[CONV_LAST + 1][CONV_LAST + 1] = { -// void, wildc, bool, int, float, ptr, slice, vec, bitst, distc, array, strct, union, any, infc, fault, enum, func, typid, afaul, voidp, arrpt, infer, ulist (to) - {_NA__, _NO__, _NO__, _NO__, _NO__, _NO__, _NO__, _NO__, _NO__, _NO__, _NO__, _NO__, _NO__, _NO__, _NO__, _NO__, _NO__, _NO__, _NO__, _NO__, _NO__, _NO__, _NO__, _NO__}, // VOID (from) - {ROKOK, _NA__, ROKOK, ROKOK, ROKOK, ROKOK, ROKOK, ROKOK, ROKOK, ROKOK, ROKOK, ROKOK, ROKOK, ROKOK, ROKOK, ROKOK, ROKOK, ROKOK, ROKOK, ROKOK, ROKOK, ROKOK, _NO__, _NO__}, // WILDCARD - {REXPL, _NO__, _NA__, REXPL, REXPL, _NO__, _NO__, REXVC, _NO__, RXXDI, _NO__, _NO__, _NO__, _NO__, _NO__, _NO__, _NO__, _NO__, _NO__, _NO__, _NO__, _NO__, _NO__, _NO__}, // BOOL - {REXPL, _NO__, REXPL, RWIDE, RINFL, RINPT, _NO__, REXVC, RINBS, RXXDI, _NO__, _NO__, _NO__, _NO__, _NO__, _NO__, RINEN, RINPT, _NO__, _NO__, RINPT, RINPT, _NO__, _NO__}, // INT - {REXPL, _NO__, REXPL, REXPL, RWIDE, _NO__, _NO__, REXVC, _NO__, RXXDI, _NO__, _NO__, _NO__, _NO__, _NO__, _NO__, _NO__, _NO__, _NO__, _NO__, _NO__, _NO__, _NO__, _NO__}, // FLOAT - {REXPL, _NO__, REXPL, RPTIN, _NO__, RPTPT, _NO__, REXVC, _NO__, RXXDI, _NO__, _NO__, _NO__, ROKOK, RPTIF, _NO__, _NO__, _NO__, _NO__, _NO__, ROKOK, RPTPT, RPTFE, _NO__}, // PTR - {REXPL, _NO__, REXPL, _NO__, _NO__, RSLPT, RSLSL, RSLVA, _NO__, RXXDI, RSLVA, _NO__, _NO__, _NO__, _NO__, _NO__, _NO__, _NO__, _NO__, _NO__, ROKOK, RSLPT, RSLFE, _NO__}, // SLICE - {REXPL, _NO__, _NO__, _NO__, _NO__, _NO__, RVASL, RVCVC, _NO__, RXXDI, RVCAR, _NO__, _NO__, _NO__, _NO__, _NO__, _NO__, _NO__, _NO__, _NO__, _NO__, _NO__, RVAFE, _NO__}, // VECTOR - {REXPL, _NO__, REXPL, RBSIN, _NO__, _NO__, _NO__, _NO__, _NO__, RXXDI, RBSAR, _NO__, _NO__, _NO__, _NO__, _NO__, _NO__, _NO__, _NO__, _NO__, _NO__, _NO__, _NO__, _NO__}, // BITSTRUCT - {REXPL, _NO__, RDIXX, RDIXX, RDIXX, RDIXX, RDIXX, RDIXX, RDIXX, RDIDI, RDIXX, RDIXX, RDIXX, RDIXX, RDIXX, RDIXX, RDIXX, RDIXX, RDIXX, RDIXX, RDIXX, RDIXX, RDIXX, _NO__}, // DISTINCT - {REXPL, _NO__, _NO__, _NO__, _NO__, _NO__, RVASL, RARVC, RARBS, RXXDI, RARAR, _NO__, _NO__, _NO__, _NO__, _NO__, _NO__, _NO__, _NO__, _NO__, _NO__, _NO__, RVAFE, _NO__}, // ARRAY - {REXPL, _NO__, RSTST, RSTST, RSTST, RSTST, RSTST, RSTST, RSTST, RSTDI, RSTST, RSTST, RSTST, RSTST, RSTST, RSTST, RSTST, RSTST, RSTST, RSTST, RSTST, RSTST, _NO__, _NO__}, // STRUCT - {REXPL, _NO__, _NO__, _NO__, _NO__, _NO__, _NO__, _NO__, _NO__, RXXDI, _NO__, _NO__, _NO__, _NO__, _NO__, _NO__, _NO__, _NO__, _NO__, _NO__, _NO__, _NO__, _NO__, _NO__}, // UNION - {REXPL, _NO__, REXPL, _NO__, _NO__, REXPL, _NO__, _NO__, _NO__, RXXDI, _NO__, _NO__, _NO__, _NA__, REXPL, _NO__, _NO__, _NO__, _NO__, _NO__, ROKOK, REXPL, _NO__, _NO__}, // ANY - {REXPL, _NO__, REXPL, _NO__, _NO__, REXPL, _NO__, _NO__, _NO__, RXXDI, _NO__, _NO__, _NO__, ROKOK, RIFIF, _NO__, _NO__, _NO__, _NO__, _NO__, ROKOK, REXPL, _NO__, _NO__}, // INTERFACE - {REXPL, _NO__, REXPL, RPTIN, _NO__, REXPL, _NO__, REXVC, _NO__, RXXDI, _NO__, _NO__, _NO__, _NO__, _NO__, _NO__, _NO__, _NO__, _NO__, ROKOK, REXPL, REXPL, _NO__, _NO__}, // FAULT - {REXPL, _NO__, RENXX, RENXX, RENXX, RENXX, RENXX, RENXX, RENXX, RENXX, RENXX, RENXX, RENXX, RENXX, RENXX, RENXX, RENXX, RENXX, RENXX, RENXX, RENXX, RENXX, RENXX, _NO__}, // ENUM - {REXPL, _NO__, REXPL, RPTIN, _NO__, _NO__, _NO__, REXVC, _NO__, RXXDI, _NO__, _NO__, _NO__, _NO__, _NO__, _NO__, _NO__, RPTPT, _NO__, _NO__, ROKOK, _NO__, _NO__, _NO__}, // FUNC - {REXPL, _NO__, REXPL, RPTIN, _NO__, REXPL, _NO__, REXVC, _NO__, RXXDI, _NO__, _NO__, _NO__, _NO__, _NO__, _NO__, _NO__, _NO__, _NA__, _NO__, REXPL, REXPL, _NO__, _NO__}, // TYPEID - {REXPL, _NO__, REXPL, RPTIN, _NO__, REXPL, _NO__, REXVC, _NO__, RXXDI, _NO__, _NO__, _NO__, _NO__, _NO__, RAFFA, _NO__, _NO__, _NO__, _NA__, REXPL, REXPL, _NO__, _NO__}, // ANYFAULT - {REXPL, _NO__, REXPL, RPTIN, _NO__, ROKOK, _NO__, REXVC, _NO__, RXXDI, _NO__, _NO__, _NO__, RVPAN, RVPAN, _NO__, _NO__, ROKOK, _NO__, _NO__, _NA__, ROKOK, _NO__, _NO__}, // VOIDPTR - {REXPL, _NO__, REXPL, RPTIN, _NO__, RPTPT, RAPSL, REXVC, _NO__, RXXDI, _NO__, _NO__, _NO__, ROKOK, ROKOK, _NO__, _NO__, _NO__, _NO__, _NO__, ROKOK, RPTPT, RPTFE, _NO__}, // ARRPTR - {_NO__, _NO__, _NO__, _NO__, _NO__, _NO__, _NO__, _NO__, _NO__, _NO__, _NO__, _NO__, _NO__, _NO__, _NO__, _NO__, _NO__, _NO__, _NO__, _NO__, _NO__, _NO__, _NO__, _NO__}, // INFERRED - {_NO__, _NO__, _NO__, _NO__, _NO__, _NO__, RULSL, RULAR, RULST, RXXDI, RULAR, RULST, _NO__, _NO__, _NO__, _NO__, _NO__, _NO__, _NO__, _NO__, _NO__, _NO__, RULFE, _NO__}, // UNTYPED_LIST +// void, wildc, bool, int, float, ptr, slice, vec, bitst, distc, array, strct, union, any, infc, enum, func, typid, afaul, voidp, arrpt, infer, ulist (to) + {_NA__, _NO__, _NO__, _NO__, _NO__, _NO__, _NO__, _NO__, _NO__, _NO__, _NO__, _NO__, _NO__, _NO__, _NO__, _NO__, _NO__, _NO__, _NO__, _NO__, _NO__, _NO__, _NO__}, // VOID (from) + {ROKOK, _NA__, ROKOK, ROKOK, ROKOK, ROKOK, ROKOK, ROKOK, ROKOK, ROKOK, ROKOK, ROKOK, ROKOK, ROKOK, ROKOK, ROKOK, ROKOK, ROKOK, ROKOK, ROKOK, ROKOK, _NO__, _NO__}, // WILDCARD + {REXPL, _NO__, _NA__, REXPL, REXPL, _NO__, _NO__, REXVC, _NO__, RXXDI, _NO__, _NO__, _NO__, _NO__, _NO__, _NO__, _NO__, _NO__, _NO__, _NO__, _NO__, _NO__, _NO__}, // BOOL + {REXPL, _NO__, REXPL, RWIDE, RINFL, RINPT, _NO__, REXVC, RINBS, RXXDI, _NO__, _NO__, _NO__, _NO__, _NO__, RINEN, RINPT, _NO__, _NO__, RINPT, RINPT, _NO__, _NO__}, // INT + {REXPL, _NO__, REXPL, REXPL, RWIDE, _NO__, _NO__, REXVC, _NO__, RXXDI, _NO__, _NO__, _NO__, _NO__, _NO__, _NO__, _NO__, _NO__, _NO__, _NO__, _NO__, _NO__, _NO__}, // FLOAT + {REXPL, _NO__, REXPL, RPTIN, _NO__, RPTPT, _NO__, REXVC, _NO__, RXXDI, _NO__, _NO__, _NO__, ROKOK, RPTIF, _NO__, _NO__, _NO__, _NO__, ROKOK, RPTPT, RPTFE, _NO__}, // PTR + {REXPL, _NO__, REXPL, _NO__, _NO__, RSLPT, RSLSL, RSLVA, _NO__, RXXDI, RSLVA, _NO__, _NO__, _NO__, _NO__, _NO__, _NO__, _NO__, _NO__, ROKOK, RSLPT, RSLFE, _NO__}, // SLICE + {REXPL, _NO__, _NO__, _NO__, _NO__, _NO__, RVASL, RVCVC, _NO__, RXXDI, RVCAR, _NO__, _NO__, _NO__, _NO__, _NO__, _NO__, _NO__, _NO__, _NO__, _NO__, RVAFE, _NO__}, // VECTOR + {REXPL, _NO__, REXPL, RBSIN, _NO__, _NO__, _NO__, _NO__, _NO__, RXXDI, RBSAR, _NO__, _NO__, _NO__, _NO__, _NO__, _NO__, _NO__, _NO__, _NO__, _NO__, _NO__, _NO__}, // BITSTRUCT + {REXPL, _NO__, RDIXX, RDIXX, RDIXX, RDIXX, RDIXX, RDIXX, RDIXX, RDIDI, RDIXX, RDIXX, RDIXX, RDIXX, RDIXX, RDIXX, RDIXX, RDIXX, RDIXX, RDIXX, RDIXX, RDIXX, _NO__}, // DISTINCT + {REXPL, _NO__, _NO__, _NO__, _NO__, _NO__, RVASL, RARVC, RARBS, RXXDI, RARAR, _NO__, _NO__, _NO__, _NO__, _NO__, _NO__, _NO__, _NO__, _NO__, _NO__, RVAFE, _NO__}, // ARRAY + {REXPL, _NO__, RSTST, RSTST, RSTST, RSTST, RSTST, RSTST, RSTST, RSTDI, RSTST, RSTST, RSTST, RSTST, RSTST, RSTST, RSTST, RSTST, RSTST, RSTST, RSTST, _NO__, _NO__}, // STRUCT + {REXPL, _NO__, _NO__, _NO__, _NO__, _NO__, _NO__, _NO__, _NO__, RXXDI, _NO__, _NO__, _NO__, _NO__, _NO__, _NO__, _NO__, _NO__, _NO__, _NO__, _NO__, _NO__, _NO__}, // UNION + {REXPL, _NO__, REXPL, _NO__, _NO__, REXPL, _NO__, _NO__, _NO__, RXXDI, _NO__, _NO__, _NO__, _NA__, REXPL, _NO__, _NO__, _NO__, _NO__, ROKOK, REXPL, _NO__, _NO__}, // ANY + {REXPL, _NO__, REXPL, _NO__, _NO__, REXPL, _NO__, _NO__, _NO__, RXXDI, _NO__, _NO__, _NO__, ROKOK, RIFIF, _NO__, _NO__, _NO__, _NO__, ROKOK, REXPL, _NO__, _NO__}, // INTERFACE + {REXPL, _NO__, RENXX, RENXX, RENXX, RENXX, RENXX, RENXX, RENXX, RENXX, RENXX, RENXX, RENXX, RENXX, RENXX, RENXX, RENXX, RENXX, RENXX, RENXX, RENXX, RENXX, _NO__}, // ENUM + {REXPL, _NO__, REXPL, RPTIN, _NO__, _NO__, _NO__, REXVC, _NO__, RXXDI, _NO__, _NO__, _NO__, _NO__, _NO__, _NO__, RPTPT, _NO__, _NO__, ROKOK, _NO__, _NO__, _NO__}, // FUNC + {REXPL, _NO__, REXPL, RPTIN, _NO__, REXPL, _NO__, REXVC, _NO__, RXXDI, _NO__, _NO__, _NO__, _NO__, _NO__, _NO__, _NO__, _NA__, _NO__, REXPL, REXPL, _NO__, _NO__}, // TYPEID + {REXPL, _NO__, REXPL, RPTIN, _NO__, REXPL, _NO__, REXVC, _NO__, RXXDI, _NO__, _NO__, _NO__, _NO__, _NO__, _NO__, _NO__, _NO__, _NA__, REXPL, REXPL, _NO__, _NO__}, // ANYFAULT + {REXPL, _NO__, REXPL, RPTIN, _NO__, ROKOK, _NO__, REXVC, _NO__, RXXDI, _NO__, _NO__, _NO__, RVPAN, RVPAN, _NO__, ROKOK, _NO__, _NO__, _NA__, ROKOK, _NO__, _NO__}, // VOIDPTR + {REXPL, _NO__, REXPL, RPTIN, _NO__, RPTPT, RAPSL, REXVC, _NO__, RXXDI, _NO__, _NO__, _NO__, ROKOK, ROKOK, _NO__, _NO__, _NO__, _NO__, ROKOK, RPTPT, RPTFE, _NO__}, // ARRPTR + {_NO__, _NO__, _NO__, _NO__, _NO__, _NO__, _NO__, _NO__, _NO__, _NO__, _NO__, _NO__, _NO__, _NO__, _NO__, _NO__, _NO__, _NO__, _NO__, _NO__, _NO__, _NO__, _NO__}, // INFERRED + {_NO__, _NO__, _NO__, _NO__, _NO__, _NO__, RULSL, RULAR, RULST, RXXDI, RULAR, RULST, _NO__, _NO__, _NO__, _NO__, _NO__, _NO__, _NO__, _NO__, _NO__, RULFE, _NO__}, // UNTYPED_LIST }; CastFunction cast_function[CONV_LAST + 1][CONV_LAST + 1] = { -//void, wildcd, bool, int, float, ptr, slice, vec, bitst, dist, array,struct,union, any, infc, fault, enum, func, typeid, anyfa, vptr, aptr, infer, ulist (to) - {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, // VOID (from) - {XX2XX, 0, XX2XX, XX2XX, XX2XX, XX2XX, XX2XX, XX2XX, XX2XX, 0, XX2XX, XX2XX, XX2XX, XX2XX, XX2XX, XX2XX, XX2XX, XX2XX, XX2XX, XX2XX, XX2XX, XX2XX, 0, 0 }, // WILDCARD - {XX2VO, 0, 0, BO2IN, BO2FP, 0, 0, EX2VC, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, // BOOL - {XX2VO, 0, IN2BO, IN2IN, IN2FP, IN2PT, 0, EX2VC, IA2BS, 0, 0, 0, 0, 0, 0, 0, 0, IN2PT, 0, 0, IN2PT, IN2PT, 0, 0 }, // INT - {XX2VO, 0, FP2BO, FP2IN, FP2FP, 0, 0, EX2VC, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, // FLOAT - {XX2VO, 0, PT2BO, PT2IN, 0, PT2PT, 0, EX2VC, 0, 0, 0, 0, 0, PT2AY, PT2AY, 0, 0, 0, 0, 0, PT2PT, PT2PT, PT2FE, 0 }, // PTR - {XX2VO, 0, SL2BO, 0, 0, SL2PT, SL2SL, SL2VA, 0, 0, SL2VA, 0, 0, 0, 0, 0, 0, 0, 0, 0, SL2PT, SL2PT, SL2FE, 0 }, // SLICE - {XX2VO, 0, 0, 0, 0, 0, VA2SL, VC2VC, 0, 0, VC2AR, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, VA2FE, 0 }, // VECTOR - {XX2VO, 0, BS2BO, BS2IA, 0, 0, 0, 0, 0, 0, BS2IA, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, // BITSTRUCT - { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, // DISTINCT - {XX2VO, 0, 0, 0, 0, 0, VA2SL, AR2VC, IA2BS, 0, AR2AR, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, VA2FE, 0 }, // ARRAY - {XX2VO, 0, ST2LN, ST2LN, ST2LN, ST2LN, ST2LN, ST2LN, ST2LN, 0, ST2LN, ST2LN, ST2LN, ST2LN, ST2LN, ST2LN, ST2LN, ST2LN, ST2LN, ST2LN, ST2LN, ST2LN, 0, 0 }, // STRUCT - {XX2VO, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, // UNION - {XX2VO, 0, AY2BO, 0, 0, AY2PT, 0, 0, 0, 0, 0, 0, 0, PT2PT, PT2PT, 0, 0, 0, 0, 0, AY2PT, AY2PT, 0, 0 }, // ANY - {XX2VO, 0, AY2BO, 0, 0, AY2PT, 0, 0, 0, 0, 0, 0, 0, PT2PT, PT2PT, 0, 0, 0, 0, 0, AY2PT, AY2PT, 0, 0 }, // INTERFACE - {XX2VO, 0, AF2BO, FA2IN, 0, FA2PT, 0, EX2VC, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, FA2AF, FA2PT, FA2PT, 0, 0 }, // FAULT - {XX2VO, 0, EN2XX, EN2XX, EN2XX, EN2XX, EN2XX, EN2XX, EN2XX, EN2XX, EN2XX, EN2XX, EN2XX, EN2XX, EN2XX, EN2XX, EN2XX, EN2XX, EN2XX, EN2XX, EN2XX, EN2XX, EN2XX, EN2XX }, // ENUM - {XX2VO, 0, PT2BO, PT2IN, 0, 0, 0, EX2VC, 0, 0, 0, 0, 0, 0, 0, 0, 0, PT2PT, 0, 0, PT2PT, 0, 0, 0 }, // FUNC - {XX2VO, 0, TI2BO, TI2IN, 0, TI2PT, 0, EX2VC, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, TI2PT, TI2PT, 0, 0 }, // TYPEID - {XX2VO, 0, AF2BO, FA2IN, 0, FA2IN, 0, EX2VC, 0, 0, 0, 0, 0, 0, 0, AF2FA, 0, 0, 0, 0, FA2IN, FA2IN, 0, 0 }, // ANYFAULT - {XX2VO, 0, PT2BO, PT2IN, 0, PT2PT, 0, EX2VC, 0, 0, 0, 0, 0, PT2AY, PT2AY, 0, 0, PT2PT, 0, 0, 0, PT2PT, 0, 0 }, // VOIDPTR - {XX2VO, 0, PT2BO, PT2IN, 0, PT2PT, AP2SL, EX2VC, 0, 0, 0, 0, 0, PT2AY, PT2AY, 0, 0, 0, 0, 0, PT2PT, PT2PT, PT2FE, 0 }, // ARRAYPTR - { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, // INFERRED - { 0, 0, 0, 0, 0, 0, UL2XX, UL2XX, UL2XX, 0, UL2XX, UL2XX, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, UL2XX, 0 }, // UNTYPED +//void, wildcd, bool, int, float, ptr, slice, vec, bitst, dist, array,struct,union, any, infc, enum, func, typeid, anyfa, vptr, aptr, infer, ulist (to) + {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, // VOID (from) + {XX2XX, 0, XX2XX, XX2XX, XX2XX, XX2XX, XX2XX, XX2XX, XX2XX, 0, XX2XX, XX2XX, XX2XX, XX2XX, XX2XX, XX2XX, XX2XX, XX2XX, XX2XX, XX2XX, XX2XX, 0, 0 }, // WILDCARD + {XX2VO, 0, 0, BO2IN, BO2FP, 0, 0, EX2VC, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, // BOOL + {XX2VO, 0, IN2BO, IN2IN, IN2FP, IN2PT, 0, EX2VC, IA2BS, 0, 0, 0, 0, 0, 0, 0, IN2PT, 0, 0, IN2PT, IN2PT, 0, 0 }, // INT + {XX2VO, 0, FP2BO, FP2IN, FP2FP, 0, 0, EX2VC, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, // FLOAT + {XX2VO, 0, PT2BO, PT2IN, 0, PT2PT, 0, EX2VC, 0, 0, 0, 0, 0, PT2AY, PT2AY, 0, 0, 0, 0, PT2PT, PT2PT, PT2FE, 0 }, // PTR + {XX2VO, 0, SL2BO, 0, 0, SL2PT, SL2SL, SL2VA, 0, 0, SL2VA, 0, 0, 0, 0, 0, 0, 0, 0, SL2PT, SL2PT, SL2FE, 0 }, // SLICE + {XX2VO, 0, 0, 0, 0, 0, VA2SL, VC2VC, 0, 0, VC2AR, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, VA2FE, 0 }, // VECTOR + {XX2VO, 0, BS2BO, BS2IA, 0, 0, 0, 0, 0, 0, BS2IA, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, // BITSTRUCT + { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, // DISTINCT + {XX2VO, 0, 0, 0, 0, 0, VA2SL, AR2VC, IA2BS, 0, AR2AR, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, VA2FE, 0 }, // ARRAY + {XX2VO, 0, ST2LN, ST2LN, ST2LN, ST2LN, ST2LN, ST2LN, ST2LN, 0, ST2LN, ST2LN, ST2LN, ST2LN, ST2LN, ST2LN, ST2LN, ST2LN, ST2LN, ST2LN, ST2LN, 0, 0 }, // STRUCT + {XX2VO, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, // UNION + {XX2VO, 0, AY2BO, 0, 0, AY2PT, 0, 0, 0, 0, 0, 0, 0, PT2PT, PT2PT, 0, 0, 0, 0, AY2PT, AY2PT, 0, 0 }, // ANY + {XX2VO, 0, AY2BO, 0, 0, AY2PT, 0, 0, 0, 0, 0, 0, 0, PT2PT, PT2PT, 0, 0, 0, 0, AY2PT, AY2PT, 0, 0 }, // INTERFACE + {XX2VO, 0, EN2XX, EN2XX, EN2XX, EN2XX, EN2XX, EN2XX, EN2XX, EN2XX, EN2XX, EN2XX, EN2XX, EN2XX, EN2XX, EN2XX, EN2XX, EN2XX, EN2XX, EN2XX, EN2XX, EN2XX, EN2XX }, // ENUM + {XX2VO, 0, PT2BO, PT2IN, 0, 0, 0, EX2VC, 0, 0, 0, 0, 0, 0, 0, 0, PT2PT, 0, 0, PT2PT, 0, 0, 0 }, // FUNC + {XX2VO, 0, TI2BO, TI2IN, 0, TI2PT, 0, EX2VC, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, TI2PT, TI2PT, 0, 0 }, // TYPEID + {XX2VO, 0, AF2BO, FA2IN, 0, FA2IN, 0, EX2VC, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, FA2IN, FA2IN, 0, 0 }, // ANYFAULT + {XX2VO, 0, PT2BO, PT2IN, 0, PT2PT, 0, EX2VC, 0, 0, 0, 0, 0, PT2AY, PT2AY, 0, PT2PT, 0, 0, 0, PT2PT, 0, 0 }, // VOIDPTR + {XX2VO, 0, PT2BO, PT2IN, 0, PT2PT, AP2SL, EX2VC, 0, 0, 0, 0, 0, PT2AY, PT2AY, 0, 0, 0, 0, PT2PT, PT2PT, PT2FE, 0 }, // ARRAYPTR + { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, // INFERRED + { 0, 0, 0, 0, 0, 0, UL2XX, UL2XX, UL2XX, 0, UL2XX, UL2XX, 0, 0, 0, 0, 0, 0, 0, 0, 0, UL2XX, 0 }, // UNTYPED }; static ConvGroup group_from_type[TYPE_LAST + 1] = { @@ -2392,7 +2365,6 @@ static ConvGroup group_from_type[TYPE_LAST + 1] = { [TYPE_STRUCT] = CONV_STRUCT, [TYPE_UNION] = CONV_UNION, [TYPE_BITSTRUCT] = CONV_BITSTRUCT, - [TYPE_FAULTTYPE] = CONV_FAULT, [TYPE_TYPEDEF] = CONV_NO, [TYPE_DISTINCT] = CONV_DISTINCT, [TYPE_ARRAY] = CONV_ARRAY, diff --git a/src/compiler/sema_const.c b/src/compiler/sema_const.c index 1dc4fb863..9d63b8197 100644 --- a/src/compiler/sema_const.c +++ b/src/compiler/sema_const.c @@ -27,7 +27,7 @@ ArrayIndex sema_len_from_const(Expr *expr) case CONST_INTEGER: case CONST_BOOL: case CONST_ENUM: - case CONST_ERR: + case CONST_FAULT: case CONST_TYPEID: case CONST_MEMBER: case CONST_REF: @@ -169,7 +169,7 @@ static bool sema_concat_bytes_and_other(SemaContext *context, Expr *expr, Expr * case CONST_FLOAT: case CONST_BOOL: case CONST_ENUM: - case CONST_ERR: + case CONST_FAULT: case CONST_POINTER: case CONST_TYPEID: case CONST_MEMBER: @@ -320,7 +320,7 @@ bool sema_expr_analyse_ct_concat(SemaContext *context, Expr *concat_expr, Expr * case CONST_INTEGER: case CONST_BOOL: case CONST_ENUM: - case CONST_ERR: + case CONST_FAULT: case CONST_TYPEID: case CONST_REF: case CONST_MEMBER: @@ -361,7 +361,7 @@ bool sema_expr_analyse_ct_concat(SemaContext *context, Expr *concat_expr, Expr * case CONST_INTEGER: case CONST_BOOL: case CONST_ENUM: - case CONST_ERR: + case CONST_FAULT: case CONST_POINTER: case CONST_TYPEID: case CONST_MEMBER: diff --git a/src/compiler/sema_decls.c b/src/compiler/sema_decls.c index cd7115fcb..e71bd5dc6 100755 --- a/src/compiler/sema_decls.c +++ b/src/compiler/sema_decls.c @@ -62,7 +62,6 @@ static Module *module_instantiate_generic(SemaContext *context, Module *module, static inline bool sema_analyse_enum_param(SemaContext *context, Decl *param); static inline bool sema_analyse_enum(SemaContext *context, Decl *decl, bool *erase_decl); -static inline bool sema_analyse_error(SemaContext *context, Decl *decl, bool *erase_decl); static bool sema_check_section(SemaContext *context, Attr *attr) { @@ -237,7 +236,7 @@ static inline bool sema_analyse_struct_member(SemaContext *context, Decl *parent { ASSERT(decl->var.kind == VARDECL_MEMBER); decl->resolve_status = RESOLVE_RUNNING; - // Inferred types are not strictly allowed, but we use the int[?] for the flexible array member. + // Inferred types are not strictly allowed, but we use the int[*] for the flexible array member. ASSERT(type_infoptrzero(decl->var.type_info)); TypeInfo *type_info = type_infoptr(decl->var.type_info); if (!sema_resolve_type_info(context, type_info, RESOLVE_TYPE_ALLOW_FLEXIBLE)) return decl_poison(decl); @@ -440,7 +439,6 @@ RETRY:; case TYPE_FUNC_PTR: case TYPE_POINTER: case TYPE_FUNC_RAW: - case TYPE_FAULTTYPE: case TYPE_SLICE: return compiler.platform.align_pointer.align / 8; case TYPE_ENUM: @@ -511,9 +509,9 @@ static bool sema_analyse_struct_members(SemaContext *context, Decl *decl) Type *member_type = type_flatten(member->type); // If this is a struct and it has a variable array ending, then it must also be the last struct. // So this is ok: - // struct Foo { int x; struct { int x; int[?] y; } } + // struct Foo { int x; struct { int x; int[*] y; } } // But not this: - // struct Bar { struct { int x; int[?] y; } int x; } + // struct Bar { struct { int x; int[*] y; } int x; } if (member_type->type_kind == TYPE_STRUCT && member_type->decl->has_variable_array) { if (i != member_count - 1) @@ -1021,7 +1019,6 @@ RETRY: case TYPE_STRUCT: case TYPE_UNION: case TYPE_BITSTRUCT: - case TYPE_FAULTTYPE: case TYPE_DISTINCT: case TYPE_VECTOR: case TYPE_INFERRED_VECTOR: @@ -1460,7 +1457,7 @@ static inline bool sema_analyse_enum_param(SemaContext *context, Decl *param) } sema_decl_stack_push(param); ASSERT(!param->var.init_expr); - return sema_set_abi_alignment(context, param->type, ¶m->alignment); + return true; } static inline bool sema_analyse_enum(SemaContext *context, Decl *decl, bool *erase_decl) @@ -1503,8 +1500,6 @@ static inline bool sema_analyse_enum(SemaContext *context, Decl *decl, bool *era break; } if (!sema_analyse_enum_param(context, value)) goto ERR; - - value->resolve_status = RESOLVE_DONE; } sema_decl_stack_restore(state); @@ -1573,6 +1568,31 @@ static inline bool sema_analyse_enum(SemaContext *context, Decl *decl, bool *era { RETURN_SEMA_ERROR(enum_value, "Expected %d associated value%s for this enum value.", associated_value_count, associated_value_count != 1 ? "s" : ""); } + } + decl->resolve_status = RESOLVE_DONE; + for (unsigned i = 0; i < associated_value_count; i++) + { + Decl *param = associated_values[i]; + if (!sema_set_abi_alignment(context, param->type, ¶m->alignment)) return false; + param->resolve_status = RESOLVE_DONE; + } + for (unsigned i = 0; i < enums; i++) + { + Decl *enum_value = enum_values[i]; + Expr **args = enum_value->enum_constant.args; + unsigned arg_count = vec_size(args); + if (arg_count > associated_value_count) + { + if (!associated_value_count) + { + RETURN_SEMA_ERROR(args[0], "There are no associated values defined for this enum. Did you perhaps want C style gap enums? In that case, try enums with inline associated values."); + } + RETURN_SEMA_ERROR(args[associated_value_count], "You're adding too many values, only %d associated value%s are defined for '%s'.", associated_value_count, associated_value_count != 1 ? "s" : "", decl->name); + } + if (arg_count < associated_value_count) + { + RETURN_SEMA_ERROR(enum_value, "Expected %d associated value%s for this enum value.", associated_value_count, associated_value_count != 1 ? "s" : ""); + } for (unsigned j = 0; j < arg_count; j++) { Expr *arg = args[j]; @@ -1591,29 +1611,13 @@ ERR: return false; } -static inline bool sema_analyse_error(SemaContext *context, Decl *decl, bool *erase_decl) +static inline bool sema_analyse_fault(SemaContext *context, Decl *decl, bool *erase_decl) { if (!sema_analyse_attributes(context, decl, decl->attributes, ATTR_FAULT, erase_decl)) return decl_poison(decl); if (*erase_decl) return true; - if (!sema_resolve_implemented_interfaces(context, decl, false)) return decl_poison(decl); - - bool success = true; - unsigned enums = vec_size(decl->enums.values); - - for (unsigned i = 0; i < enums; i++) - { - Decl *enum_value = decl->enums.values[i]; - enum_value->type = decl->type; - DEBUG_LOG("* Checking error value %s.", enum_value->name); - enum_value->enum_constant.ordinal = i; - DEBUG_LOG("* Ordinal: %d", i); - ASSERT(enum_value->resolve_status == RESOLVE_NOT_DONE); - ASSERT(enum_value->decl_kind == DECL_FAULTVALUE); - - // Start evaluating the constant - enum_value->resolve_status = RESOLVE_DONE; - } - return success; + decl->type = type_anyfault; + decl->alignment = type_abi_alignment(type_string); + return true; } static inline const char *method_name_by_decl(Decl *method_like) @@ -2078,7 +2082,6 @@ static inline Decl *sema_find_interface_for_method(SemaContext *context, Canonic case TYPE_STRUCT: case TYPE_UNION: case TYPE_DISTINCT: - case TYPE_FAULTTYPE: case TYPE_ENUM: break; case TYPE_TYPEDEF: @@ -2243,13 +2246,6 @@ static inline bool sema_analyse_method(SemaContext *context, Decl *decl) if (d) RETURN_SEMA_ERROR(decl, "%s already has a field with the same name.", type_quoted_error_string(par_type)); break; } - case TYPE_FAULTTYPE: - if (kw == kw_ordinal || kw == kw_nameof) - { - errname = "a fault"; - goto NOT_VALID_NAME; - } - break; case TYPE_ANYFAULT: if (kw == kw_type || kw == kw_nameof) { @@ -4298,8 +4294,8 @@ static bool sema_generate_parameterized_name_to_scratch(SemaContext *context, Mo { if (!sema_analyse_ct_expr(context, param)) return false; Type *type = param->type->canonical; - bool is_enum_like = type_kind_is_enumlike(type->type_kind); - if (!type_is_integer_or_bool_kind(type) && !is_enum_like) + bool is_enum_or_fault = type_kind_is_enum_or_fault(type->type_kind); + if (!type_is_integer_or_bool_kind(type) && !is_enum_or_fault) { SEMA_ERROR(param, "Only integer, bool, fault and enum values may be generic arguments."); return poisoned_decl; @@ -4339,7 +4335,7 @@ static bool sema_generate_parameterized_name_to_scratch(SemaContext *context, Mo else { Type *type = param->type->canonical; - bool is_enum_like = type_kind_is_enumlike(type->type_kind); + bool is_enum_or_fault = type_kind_is_enum_or_fault(type->type_kind); if (type == type_bool) { if (mangled) @@ -4351,12 +4347,19 @@ static bool sema_generate_parameterized_name_to_scratch(SemaContext *context, Mo scratch_buffer_append(param->const_expr.b ? "true" : "false"); } } - else if (is_enum_like) + else if (type->type_kind == TYPE_ENUM) { - Decl *enum_like = param->const_expr.enum_err_val; - type_mangle_introspect_name_to_buffer(enum_like->type->canonical); + Decl *enumm = param->const_expr.enum_err_val; + type_mangle_introspect_name_to_buffer(enumm->type->canonical); scratch_buffer_append(mangled ? "_" : ":"); - scratch_buffer_append(enum_like->name); + scratch_buffer_append(enumm->name); + } + else if (type->type_kind == TYPE_ANYFAULT) + { + Decl *fault = param->const_expr.fault; + type_mangle_introspect_name_to_buffer(fault->type->canonical); + scratch_buffer_append(mangled ? "_" : ":"); + scratch_buffer_append(fault->name); } else { @@ -4603,7 +4606,6 @@ RETRY: case TYPE_STRUCT: case TYPE_UNION: case TYPE_BITSTRUCT: - case TYPE_FAULTTYPE: return sema_analyse_decl(context, type->decl); case TYPE_POINTER: case TYPE_FUNC_PTR: @@ -4704,7 +4706,7 @@ bool sema_analyse_decl(SemaContext *context, Decl *decl) if (!sema_analyse_enum(context, decl, &erase_decl)) goto FAILED; break; case DECL_FAULT: - if (!sema_analyse_error(context, decl, &erase_decl)) goto FAILED; + if (!sema_analyse_fault(context, decl, &erase_decl)) goto FAILED; break; case DECL_DEFINE: if (!sema_analyse_define(context, decl, &erase_decl)) goto FAILED; @@ -4715,12 +4717,11 @@ bool sema_analyse_decl(SemaContext *context, Decl *decl) case DECL_LABEL: case DECL_CT_ASSERT: case DECL_CT_ECHO: - case DECL_FAULTVALUE: case DECL_DECLARRAY: case DECL_BODYPARAM: case DECL_CT_INCLUDE: case DECL_CT_EXEC: - case DECL_GLOBALS: + case DECL_GROUP: UNREACHABLE } if (erase_decl) diff --git a/src/compiler/sema_expr.c b/src/compiler/sema_expr.c index 773995406..0d8c68f33 100644 --- a/src/compiler/sema_expr.c +++ b/src/compiler/sema_expr.c @@ -215,7 +215,7 @@ static inline bool sema_constant_fold_ops(Expr *expr) case CONST_FLOAT: case CONST_BOOL: case CONST_ENUM: - case CONST_ERR: + case CONST_FAULT: case CONST_STRING: case CONST_POINTER: case CONST_TYPEID: @@ -799,21 +799,21 @@ static inline bool sema_cast_ident_rvalue(SemaContext *context, Expr *expr) case DECL_MACRO: SEMA_ERROR(expr, "Expected a macro followed by (...)."); return expr_poison(expr); - case DECL_FAULTVALUE: - SEMA_ERROR(expr, "Did you forget a '!' after '%s'?", decl->name); - return expr_poison(expr); case DECL_ENUM_CONSTANT: // This can't happen, inferred identifiers are folded to consts they are never identifiers. UNREACHABLE; case DECL_VAR: break; + case DECL_FAULT: + expr_rewrite_const_fault(expr, decl); + return true; case DECL_DISTINCT: case DECL_TYPEDEF: case DECL_DECLARRAY: case DECL_BODYPARAM: case DECL_CT_INCLUDE: case DECL_CT_EXEC: - case DECL_GLOBALS: + case DECL_GROUP: case DECL_ERASED: case DECL_IMPORT: case DECL_ATTRIBUTE: @@ -841,9 +841,6 @@ static inline bool sema_cast_ident_rvalue(SemaContext *context, Expr *expr) case DECL_ENUM: SEMA_ERROR(expr, "Expected enum name followed by '.' and an enum value."); return expr_poison(expr); - case DECL_FAULT: - SEMA_ERROR(expr, "Expected fault name followed by '.' and a fault value."); - return expr_poison(expr); } switch (decl->var.kind) { @@ -991,11 +988,11 @@ static inline bool sema_expr_analyse_enum_constant(SemaContext *context, Expr *e if (!sema_analyse_decl(context, decl)) return false; - ASSERT_SPAN(expr, enum_constant->resolve_status == RESOLVE_DONE); + ASSERT_SPAN(expr, enum_constant->resolve_status != RESOLVE_NOT_DONE); expr->type = decl->type; expr->expr_kind = EXPR_CONST; - expr->const_expr.const_kind = enum_constant->decl_kind == DECL_ENUM_CONSTANT ? CONST_ENUM : CONST_ERR; + expr->const_expr.const_kind = CONST_ENUM; expr->const_expr.enum_err_val = enum_constant; expr->resolve_status = RESOLVE_DONE; return true; @@ -1004,7 +1001,7 @@ static inline bool sema_expr_analyse_enum_constant(SemaContext *context, Expr *e static inline bool sema_identifier_find_possible_inferred(SemaContext *context, Type *to, Expr *expr) { - if (to->canonical->type_kind != TYPE_ENUM && to->canonical->type_kind != TYPE_FAULTTYPE) return false; + if (to->canonical->type_kind != TYPE_ENUM) return false; Decl *parent_decl = to->canonical->decl; if (!decl_ok(parent_decl)) { @@ -1014,7 +1011,6 @@ static inline bool sema_identifier_find_possible_inferred(SemaContext *context, switch (parent_decl->decl_kind) { case DECL_ENUM: - case DECL_FAULT: return sema_expr_analyse_enum_constant(context, expr, expr->unresolved_ident_expr.ident, parent_decl); case DECL_UNION: case DECL_STRUCT: @@ -1085,6 +1081,9 @@ static inline bool sema_expr_analyse_identifier(SemaContext *context, Type *to, case DECL_DEFINE: message = "Aliases from other modules must be prefixed with the module name."; break; + case DECL_FAULT: + message = "Faults from other modules must be prefixed with the module name."; + break; default: UNREACHABLE } @@ -1128,6 +1127,11 @@ static inline bool sema_expr_analyse_identifier(SemaContext *context, Type *to, break; } } + else if (decl->decl_kind == DECL_FAULT) + { + expr_rewrite_const_fault(expr, decl); + return true; + } expr_resolve_ident(expr, decl); return true; } @@ -2597,12 +2601,11 @@ INLINE bool sema_expr_analyse_from_ordinal(SemaContext *context, Expr *expr, Exp expr->expr_kind = EXPR_CONST; expr->const_expr = (ExprConst) { .enum_err_val = decl->enums.values[to_convert.i.low], - .const_kind = decl->decl_kind == DECL_FAULT ? CONST_ERR : CONST_ENUM + .const_kind = CONST_ENUM }; expr->type = decl->type; return true; } - if (decl->decl_kind == DECL_FAULT) RETURN_SEMA_ERROR(key, "For faults you can only use 'from_ordinal' with constant arguments.", decl->name); expr->expr_kind = EXPR_ENUM_FROM_ORD; expr->inner_expr = key; @@ -3683,7 +3686,7 @@ static inline bool sema_expr_analyse_slice(SemaContext *context, Expr *expr, Che case CONST_INTEGER: case CONST_BOOL: case CONST_ENUM: - case CONST_ERR: + case CONST_FAULT: case CONST_TYPEID: case CONST_REF: case CONST_MEMBER: @@ -3794,7 +3797,7 @@ static inline bool sema_expr_replace_with_enum_array(SemaContext *context, Expr ArraySize elements = vec_size(values); Expr **element_values = elements > 0 ? VECNEW(Expr*, elements) : NULL; Type *kind = enum_decl->type; - ConstKind const_kind = enum_decl->decl_kind == DECL_FAULT ? CONST_ERR : CONST_ENUM; + ConstKind const_kind = CONST_ENUM; for (ArraySize i = 0; i < elements; i++) { Decl *decl = values[i]; @@ -3937,20 +3940,6 @@ static inline bool sema_expr_analyse_type_access(SemaContext *context, Expr *exp return true; } break; - case DECL_FAULT: - unit_register_external_symbol(context, decl); - if (is_const) - { - if (!sema_expr_analyse_enum_constant(context, expr, name, decl)) - { - if (missing_ref) goto MISSING_REF; - if (decl_poison(decl)) return false; - SEMA_ERROR(expr, "'%s' has no error value '%s'.", decl->name, name); - return false; - } - return true; - } - break; case DECL_UNION: case DECL_STRUCT: case DECL_DISTINCT: @@ -4154,7 +4143,6 @@ static inline bool sema_create_const_len(Expr *expr, Type *type) len = type->array.len; break; case TYPE_ENUM: - case TYPE_FAULTTYPE: len = vec_size(type->decl->enums.values); break; case TYPE_INFERRED_ARRAY: @@ -4714,20 +4702,18 @@ static bool sema_type_property_is_valid_for_type(Type *original_type, TypeProper case TYPE_ARRAY: case TYPE_VECTOR: case TYPE_ENUM: - case TYPE_FAULTTYPE: return true; default: return false; } case TYPE_PROPERTY_FROM_ORDINAL: - return type_kind_is_enumlike(type->canonical->type_kind); + return type->canonical->type_kind == TYPE_ENUM; case TYPE_PROPERTY_MIN: case TYPE_PROPERTY_MAX: return type_is_float(type) || type_is_integer(type); case TYPE_PROPERTY_ELEMENTS: case TYPE_PROPERTY_NAMES: case TYPE_PROPERTY_VALUES: - return type_kind_is_enumlike(type->type_kind); case TYPE_PROPERTY_ASSOCIATED: return type->type_kind == TYPE_ENUM; case TYPE_PROPERTY_MEMBERSOF: @@ -4807,17 +4793,17 @@ static bool sema_expr_rewrite_to_type_property(SemaContext *context, Expr *expr, case TYPE_PROPERTY_MAX: return sema_create_const_max(expr, type, flat); case TYPE_PROPERTY_NAMES: - ASSERT_SPAN(expr, type_kind_is_enumlike(flat->type_kind)); + ASSERT_SPAN(expr, flat->type_kind == TYPE_ENUM); return sema_expr_replace_with_enum_name_array(context, expr, flat->decl); case TYPE_PROPERTY_ASSOCIATED: return sema_create_const_associated(context, expr, flat); case TYPE_PROPERTY_ELEMENTS: - ASSERT_SPAN(expr, type_kind_is_enumlike(flat->type_kind)); + ASSERT_SPAN(expr, flat->type_kind == TYPE_ENUM); if (!sema_analyse_decl(context, type->decl)) return false; expr_rewrite_const_int(expr, type_isz, vec_size(flat->decl->enums.values)); return true; case TYPE_PROPERTY_VALUES: - ASSERT_SPAN(expr, type_kind_is_enumlike(flat->type_kind)); + ASSERT_SPAN(expr, flat->type_kind == TYPE_ENUM); return sema_expr_replace_with_enum_array(context, expr, flat->decl); case TYPE_PROPERTY_NAN: ASSERT_SPAN(expr, type_is_float(flat)); @@ -5187,32 +5173,11 @@ CHECK_DEEPER: return true; } } - if (kw == kw_ordinal) + if (kw == kw_ordinal && flat_type->type_kind == TYPE_ENUM) { - if (flat_type->type_kind == TYPE_ENUM) - { - sema_expr_convert_enum_to_int(current_parent); - expr_replace(expr, current_parent); - return true; - } - if (flat_type->type_kind == TYPE_FAULTTYPE) - { - ASSERT_SPAN(expr, flat_type->decl->resolve_status == RESOLVE_DONE); - - if (sema_cast_const(current_parent)) - { - if (current_parent->const_expr.const_kind == CONST_POINTER) - { - ASSERT_SPAN(expr, !current_parent->const_expr.ptr); - expr_rewrite_const_int(expr, type_usz, 0); - return true; - } - expr_rewrite_const_int(expr, type_usz, current_parent->const_expr.enum_err_val->enum_constant.ordinal + 1); - return true; - } - expr_rewrite_to_builtin_access(expr, current_parent, ACCESS_FAULTORDINAL, type_usz); - return true; - } + sema_expr_convert_enum_to_int(current_parent); + expr_replace(expr, current_parent); + return true; } if (kw == kw_nameof) { @@ -5226,11 +5191,11 @@ CHECK_DEEPER: expr_rewrite_to_builtin_access(expr, current_parent, ACCESS_ENUMNAME, type_string); return true; } - if (type_is_fault_raw(flat_type)) + if (flat_type == type_anyfault) { if (sema_cast_const(current_parent)) { - expr_rewrite_const_string(expr, current_parent->const_expr.enum_err_val->name); + expr_rewrite_const_string(expr, current_parent->const_expr.fault->name); return true; } expr_rewrite_to_builtin_access(expr, current_parent, ACCESS_FAULTNAME, type_string); @@ -5274,11 +5239,13 @@ CHECK_DEEPER: Decl *member = sema_decl_stack_find_decl_member(context, decl, kw, METHODS_AND_FIELDS); if (!decl_ok(member)) return false; - if (member && decl_is_enum_kind(decl) && member->decl_kind == DECL_VAR && sema_cast_const(parent)) + if (member && decl->decl_kind == DECL_ENUM && member->decl_kind == DECL_VAR && sema_cast_const(parent)) { if (!sema_analyse_decl(context, decl)) return false; + Decl *ref = current_parent->const_expr.enum_err_val; + if (!sema_analyse_decl(context, ref)) return false; ASSERT_SPAN(expr, parent->const_expr.const_kind == CONST_ENUM); - Expr *copy_init = copy_expr_single(current_parent->const_expr.enum_err_val->enum_constant.args[member->var.index]); + Expr *copy_init = copy_expr_single(ref->enum_constant.args[member->var.index]); expr_replace(expr, copy_init); ASSERT_SPAN(expr, copy_init->resolve_status == RESOLVE_DONE); return true; @@ -5806,7 +5773,7 @@ static bool sema_expr_analyse_ct_subscript_set_value(SemaContext *context, Expr case CONST_INTEGER: case CONST_BOOL: case CONST_ENUM: - case CONST_ERR: + case CONST_FAULT: case CONST_POINTER: case CONST_TYPEID: case CONST_REF: @@ -8068,7 +8035,7 @@ static inline bool sema_expr_analyse_optional(SemaContext *context, Expr *expr, Type *type = inner->type->canonical; - if (!type_is_fault_raw(type)) + if (type != type_anyfault) { if (failed_ref) goto ON_FAILED; RETURN_SEMA_ERROR(inner, "You cannot use the '?' operator on expressions of type %s", @@ -8535,18 +8502,18 @@ static inline bool sema_expr_analyse_ct_nameof(SemaContext *context, Expr *expr) case DECL_CT_INCLUDE: case DECL_DECLARRAY: case DECL_ERASED: - case DECL_GLOBALS: + case DECL_GROUP: case DECL_IMPORT: case DECL_LABEL: case DECL_MACRO: case DECL_DEFINE: RETURN_SEMA_ERROR(main_var, "'%s' does not have an external name.", decl->name); + case DECL_FAULT: + goto RETURN_CT; case DECL_BITSTRUCT: case DECL_DISTINCT: case DECL_ENUM: case DECL_ENUM_CONSTANT: - case DECL_FAULT: - case DECL_FAULTVALUE: case DECL_FNTYPE: case DECL_FUNC: case DECL_INTERFACE: @@ -8823,18 +8790,11 @@ static inline bool sema_expr_analyse_embed(SemaContext *context, Expr *expr, boo if (!compiler.context.io_error_file_not_found) { Module *module = global_context_find_module(kw_std__io); - Decl *io_error = module ? module_find_symbol(module, kw_IoError) : NULL; + Decl *io_error = module ? module_find_symbol(module, kw_FILE_NOT_FOUND) : NULL; Decl *fault = poisoned_decl; if (io_error && io_error->decl_kind == DECL_FAULT) { - FOREACH(Decl *, f, io_error->enums.values) - { - if (f->name == kw_FILE_NOT_FOUND) - { - fault = f; - break; - } - } + fault = io_error; } compiler.context.io_error_file_not_found = fault; } @@ -8845,9 +8805,9 @@ static inline bool sema_expr_analyse_embed(SemaContext *context, Expr *expr, boo expr->expr_kind = EXPR_OPTIONAL; expr->inner_expr = filename; filename->expr_kind = EXPR_CONST; - filename->const_expr.const_kind = CONST_ERR; + filename->const_expr.const_kind = CONST_FAULT; expr->type = type_wildcard_optional; - filename->const_expr.enum_err_val = compiler.context.io_error_file_not_found; + filename->const_expr.fault = compiler.context.io_error_file_not_found; filename->resolve_status = RESOLVE_DONE; expr->resolve_status = RESOLVE_DONE; return true; @@ -9533,7 +9493,7 @@ static inline bool sema_expr_analyse_compound_literal(SemaContext *context, Expr Type *type = type_info->type; if (type_is_optional(type)) { - RETURN_SEMA_ERROR(type_info, "The type here should always be written as a plain type and not an optional, please remove the '!'."); + RETURN_SEMA_ERROR(type_info, "The type here should always be written as a plain type and not an optional, please remove the '?'."); } if (!sema_resolve_type_structure(context, type)) return false; if (!sema_expr_analyse_initializer_list(context, type, expr->expr_compound_literal.initializer)) return false; @@ -9772,10 +9732,11 @@ bool sema_analyse_expr_rhs(SemaContext *context, Type *to, Expr *expr, bool allo Type *to_canonical = to ? to->canonical : NULL; Type *rhs_type = expr->type; Type *rhs_type_canonical = rhs_type->canonical; - if (to && allow_optional && to_canonical != rhs_type_canonical && rhs_type_canonical->type_kind == TYPE_FAULTTYPE) + // Let's have a better error on `return io::FILE_NOT_FOUND;` when the return type is not anyfault. + if (to && allow_optional && to_canonical != rhs_type_canonical && rhs_type_canonical == type_anyfault) { Type *flat = type_flatten(to); - if (!type_is_fault_raw(flat) && sema_cast_const(expr)) + if (flat != type_anyfault && sema_cast_const(expr)) { if (no_match_ref) goto NO_MATCH_REF; print_error_after(expr->span, "You need to add a trailing '?' here to make this an optional."); diff --git a/src/compiler/sema_initializers.c b/src/compiler/sema_initializers.c index 91457bab1..21ea89ae9 100644 --- a/src/compiler/sema_initializers.c +++ b/src/compiler/sema_initializers.c @@ -325,7 +325,7 @@ static inline bool sema_expr_analyse_array_plain_initializer(SemaContext *contex Expr **elements = initializer->initializer_list; bool inferred_len = type_len_is_inferred(flattened); - // We have the case where "Foo = int[?]" + // We have the case where "Foo = int[*]" if (inferred_len && !type_len_is_inferred(assigned)) { ASSERT(assigned->type_kind == TYPE_TYPEDEF); diff --git a/src/compiler/sema_liveness.c b/src/compiler/sema_liveness.c index 000b2d6de..f8308c1b9 100644 --- a/src/compiler/sema_liveness.c +++ b/src/compiler/sema_liveness.c @@ -375,8 +375,10 @@ RETRY: case CONST_UNTYPED_LIST: case CONST_MEMBER: return; + case CONST_FAULT: + sema_trace_decl_liveness(expr->const_expr.fault); + return; case CONST_ENUM: - case CONST_ERR: sema_trace_decl_liveness(expr->const_expr.enum_err_val); return; case CONST_REF: @@ -600,7 +602,6 @@ RETRY: sema_trace_type_liveness(decl->distinct->type); FALLTHROUGH; case DECL_BITSTRUCT: - case DECL_FAULT: case DECL_STRUCT: case DECL_UNION: case DECL_INTERFACE: @@ -611,7 +612,7 @@ RETRY: return; case DECL_POISONED: case DECL_ATTRIBUTE: - case DECL_FAULTVALUE: + case DECL_FAULT: return; case DECL_CT_ASSERT: case DECL_CT_ECHO: @@ -621,7 +622,7 @@ RETRY: case DECL_LABEL: case DECL_MACRO: case DECL_BODYPARAM: - case DECL_GLOBALS: + case DECL_GROUP: UNREACHABLE case DECL_FNTYPE:; sema_trace_func_liveness(&decl->fntype_decl); diff --git a/src/compiler/sema_name_resolution.c b/src/compiler/sema_name_resolution.c index d9e412506..d62011aa9 100644 --- a/src/compiler/sema_name_resolution.c +++ b/src/compiler/sema_name_resolution.c @@ -95,7 +95,7 @@ static bool add_members_to_decl_stack(SemaContext *context, Decl *decl, FindMemb if (!type_is_user_defined(type)) break; decl = type->decl; } - if (decl_is_enum_kind(decl)) + if (decl->decl_kind == DECL_ENUM) { FOREACH(Decl *, member, decl->enums.parameters) sema_decl_stack_push(member); } @@ -922,7 +922,6 @@ bool sema_resolve_type_decl(SemaContext *context, Type *type) case TYPE_STRUCT: case TYPE_UNION: case TYPE_BITSTRUCT: - case TYPE_FAULTTYPE: return sema_analyse_decl(context, type->decl); case TYPE_ARRAY: case TYPE_FLEXIBLE_ARRAY: diff --git a/src/compiler/sema_passes.c b/src/compiler/sema_passes.c index fbb3028d2..7975c3c9d 100644 --- a/src/compiler/sema_passes.c +++ b/src/compiler/sema_passes.c @@ -200,8 +200,10 @@ static bool exec_arg_append_to_scratch(Expr *arg) case CONST_REF: scratch_buffer_append(arg->const_expr.global_ref->name); return true; + case CONST_FAULT: + scratch_buffer_append(arg->const_expr.fault->name); + return true; case CONST_ENUM: - case CONST_ERR: scratch_buffer_append(arg->const_expr.enum_err_val->name); return true; case CONST_TYPEID: @@ -734,7 +736,6 @@ void sema_analysis_pass_interface(Module *module) case DECL_STRUCT: case DECL_UNION: case DECL_ENUM: - case DECL_FAULT: case DECL_BITSTRUCT: break; default: diff --git a/src/compiler/sema_stmts.c b/src/compiler/sema_stmts.c index 397462de2..9f9541f51 100644 --- a/src/compiler/sema_stmts.c +++ b/src/compiler/sema_stmts.c @@ -114,8 +114,7 @@ static inline bool sema_analyse_assert_stmt(SemaContext *context, Ast *statement FOREACH(Expr *, e, statement->assert_stmt.args) { if (!sema_analyse_expr(context, e)) return false; - if (IS_OPTIONAL(e)) RETURN_SEMA_ERROR(e, "Optionals cannot be used as assert arguments, use '?" - "?', '!' or '!!' to fix this."); + if (IS_OPTIONAL(e)) RETURN_SEMA_ERROR(e, "Optionals cannot be used as assert arguments, use '?""?', '!' or '!!' to fix this."); if (type_is_void(e->type)) RETURN_SEMA_ERROR(e, "This expression is of type 'void', did you make a mistake?"); } } @@ -446,17 +445,13 @@ static inline bool sema_check_return_matches_opt_returns(SemaContext *context, E if (!sema_cast_const(inner)) return true; // Here we have a const optional return. - ASSERT(ret_expr->inner_expr->const_expr.const_kind == CONST_ERR); + ASSERT(ret_expr->inner_expr->const_expr.const_kind == CONST_FAULT); Decl *fault = ret_expr->inner_expr->const_expr.enum_err_val; // Check that we find it. FOREACH(Decl *, opt, context->call_env.opt_returns) { - if (opt->decl_kind == DECL_FAULT) - { - if (fault->type->decl == opt) return true; - continue; - } + assert(opt->decl_kind == DECL_FAULT); if (opt == fault) return true; } // No match @@ -853,7 +848,7 @@ static inline bool sema_analyse_try_unwrap(SemaContext *context, Expr *expr) if (!sema_resolve_type_info(context, var_type, RESOLVE_TYPE_DEFAULT)) return false; if (IS_OPTIONAL(var_type)) { - RETURN_SEMA_ERROR(var_type, "Only non-optional types may be used as types for 'try', please remove the '!'."); + RETURN_SEMA_ERROR(var_type, "Only non-optional types may be used as types for 'try', please remove the '?'."); } } @@ -2613,7 +2608,7 @@ static inline bool sema_analyse_ct_foreach_stmt(SemaContext *context, Ast *state case CONST_INTEGER: case CONST_BOOL: case CONST_ENUM: - case CONST_ERR: + case CONST_FAULT: case CONST_POINTER: case CONST_TYPEID: case CONST_REF: @@ -2825,8 +2820,10 @@ bool sema_analyse_ct_echo_stmt(SemaContext *context, Ast *statement) case CONST_REF: puts(message->const_expr.global_ref->name); break; + case CONST_FAULT: + puts(message->const_expr.fault->name); + break; case CONST_ENUM: - case CONST_ERR: puts(message->const_expr.enum_err_val->name); break; case CONST_STRING: @@ -3056,33 +3053,17 @@ static bool sema_analyse_optional_returns(SemaContext *context, Ast *directive) FOREACH(Ast *, ret, directive->contract_stmt.faults) { if (ret->contract_fault.resolved) continue; - TypeInfo *type_info = ret->contract_fault.type; - const char *ident = ret->contract_fault.ident; - if (type_info->kind != TYPE_INFO_IDENTIFIER) RETURN_SEMA_ERROR(type_info, "Expected a fault name here."); - if (!sema_resolve_type_info(context, type_info, RESOLVE_TYPE_DEFAULT)) return false; - Type *type = type_info->type; - if (type->type_kind != TYPE_FAULTTYPE) RETURN_SEMA_ERROR(type_info, "A fault type is required."); - if (!ident) + Expr *expr = ret->contract_fault.expr; + if (expr->expr_kind != EXPR_UNRESOLVED_IDENTIFIER && !expr->unresolved_ident_expr.is_const) { - ret->contract_fault.decl = type->decl; - ret->contract_fault.resolved = true; - goto NEXT; + RETURN_SEMA_ERROR(expr, "Expected a fault name here."); } - Decl *decl = type->decl; - Decl **enums = decl->enums.values; - FOREACH(Decl *, opt_value, enums) - { - if (opt_value->name == ident) - { - ret->contract_fault.decl = opt_value; - ret->contract_fault.resolved = true; - goto NEXT; - } - } - RETURN_SEMA_ERROR(ret, "No fault value '%s' found.", ident); -NEXT:; - Decl *d = ret->contract_fault.decl; - vec_add(context->call_env.opt_returns, d); + if (!sema_analyse_expr(context, expr)) return false; + if (!expr_is_const_fault(expr)) RETURN_SEMA_ERROR(expr, "A fault is required."); + Decl *decl = expr->const_expr.fault; + ret->contract_fault.decl = decl; + ret->contract_fault.resolved = true; + vec_add(context->call_env.opt_returns, decl); } return true; } diff --git a/src/compiler/sema_types.c b/src/compiler/sema_types.c index 5826abe13..0e837dd8a 100644 --- a/src/compiler/sema_types.c +++ b/src/compiler/sema_types.c @@ -216,7 +216,6 @@ static bool sema_resolve_type_identifier(SemaContext *context, TypeInfo *type_in case DECL_STRUCT: case DECL_BITSTRUCT: case DECL_UNION: - case DECL_FAULT: case DECL_ENUM: case DECL_INTERFACE: type_info->type = decl->type; @@ -259,12 +258,12 @@ static bool sema_resolve_type_identifier(SemaContext *context, TypeInfo *type_in FALLTHROUGH; case DECL_DEFINE: case DECL_FUNC: - case DECL_FAULTVALUE: case DECL_ENUM_CONSTANT: case DECL_IMPORT: case DECL_MACRO: case DECL_LABEL: case DECL_ATTRIBUTE: + case DECL_FAULT: SEMA_ERROR(type_info, "This is not a type."); return type_info_poison(type_info); case DECL_CT_ASSERT: @@ -273,7 +272,7 @@ static bool sema_resolve_type_identifier(SemaContext *context, TypeInfo *type_in case DECL_BODYPARAM: case DECL_CT_INCLUDE: case DECL_CT_EXEC: - case DECL_GLOBALS: + case DECL_GROUP: UNREACHABLE } UNREACHABLE diff --git a/src/compiler/semantic_analyser.c b/src/compiler/semantic_analyser.c index f073d66e5..e710fa7bc 100644 --- a/src/compiler/semantic_analyser.c +++ b/src/compiler/semantic_analyser.c @@ -223,7 +223,6 @@ static void register_generic_decls(CompilationUnit *unit, Decl **decls) switch (decl->decl_kind) { case DECL_ENUM_CONSTANT: - case DECL_FAULTVALUE: case DECL_DECLARRAY: case DECL_ERASED: case DECL_LABEL: @@ -239,16 +238,16 @@ static void register_generic_decls(CompilationUnit *unit, Decl **decls) case DECL_ATTRIBUTE: break; case DECL_BODYPARAM: - case DECL_GLOBALS: + case DECL_GROUP: UNREACHABLE case DECL_DEFINE: case DECL_DISTINCT: case DECL_ENUM: - case DECL_FAULT: case DECL_STRUCT: case DECL_TYPEDEF: case DECL_UNION: case DECL_VAR: + case DECL_FAULT: case DECL_BITSTRUCT: case DECL_INTERFACE: break; diff --git a/src/compiler/types.c b/src/compiler/types.c index 699cf7f01..7646590a3 100644 --- a/src/compiler/types.c +++ b/src/compiler/types.c @@ -116,7 +116,6 @@ void type_append_name_to_scratch(Type *type) case TYPE_POISONED: case TYPE_TYPEDEF: UNREACHABLE; - case TYPE_FAULTTYPE: case TYPE_ENUM: case TYPE_STRUCT: case TYPE_UNION: @@ -146,7 +145,7 @@ void type_append_name_to_scratch(Type *type) break; case TYPE_FLEXIBLE_ARRAY: type_append_name_to_scratch(type->array.base); - scratch_buffer_append("[?]"); + scratch_buffer_append("[*]"); break; case TYPE_VOID: case TYPE_BOOL: @@ -251,7 +250,6 @@ const char *type_to_error_string(Type *type) case TYPE_WILDCARD: return type->name; case TYPE_ENUM: - case TYPE_FAULTTYPE: case TYPE_TYPEDEF: case TYPE_STRUCT: case TYPE_UNION: @@ -278,7 +276,7 @@ const char *type_to_error_string(Type *type) type_append_func_to_scratch(type->function.prototype); return scratch_buffer_copy(); case TYPE_INFERRED_VECTOR: - return str_printf("%s[]", type_to_error_string(type->array.base)); + return str_printf("%s[<*>]", type_to_error_string(type->array.base)); case TYPE_VECTOR: return str_printf("%s[<%llu>]", type_to_error_string(type->array.base), (unsigned long long)type->array.len); case TYPE_TYPEINFO: @@ -288,13 +286,13 @@ const char *type_to_error_string(Type *type) case TYPE_POINTER: return str_printf("%s*", type_to_error_string(type->pointer)); case TYPE_OPTIONAL: - if (!type->optional) return "void!"; - return str_printf("%s!", type_to_error_string(type->optional)); + if (!type->optional) return "void?"; + return str_printf("%s?", type_to_error_string(type->optional)); case TYPE_ARRAY: return str_printf("%s[%llu]", type_to_error_string(type->array.base), (unsigned long long)type->array.len); case TYPE_INFERRED_ARRAY: case TYPE_FLEXIBLE_ARRAY: - return str_printf("%s[?]", type_to_error_string(type->array.base)); + return str_printf("%s[*]", type_to_error_string(type->array.base)); case TYPE_SLICE: return str_printf("%s[]", type_to_error_string(type->array.base)); } @@ -343,9 +341,6 @@ RETRY: case TYPE_TYPEDEF: type = type->canonical; goto RETRY; - case TYPE_FAULTTYPE: - type = type_iptr->canonical; - goto RETRY; case TYPE_ENUM: ASSERT(type->decl->enums.type_info->resolve_status == RESOLVE_DONE); type = type->decl->enums.type_info->type->canonical; @@ -452,7 +447,6 @@ bool type_is_abi_aggregate(Type *type) case TYPE_FUNC_RAW: case TYPE_VECTOR: case TYPE_ANYFAULT: - case TYPE_FAULTTYPE: return false; case TYPE_STRUCT: case TYPE_UNION: @@ -546,7 +540,6 @@ bool type_is_comparable(Type *type) case TYPE_ENUM: case TYPE_FUNC_PTR: case TYPE_FUNC_RAW: - case TYPE_FAULTTYPE: case TYPE_UNTYPED_LIST: case TYPE_TYPEINFO: case TYPE_VECTOR: @@ -639,7 +632,6 @@ void type_mangle_introspect_name_to_buffer(Type *type) case TYPE_STRUCT: case TYPE_UNION: case TYPE_BITSTRUCT: - case TYPE_FAULTTYPE: case TYPE_DISTINCT: case TYPE_INTERFACE: scratch_buffer_set_extern_decl_name(type->decl, false); @@ -731,7 +723,6 @@ AlignSize type_abi_alignment(Type *type) case TYPE_ANY: case TYPE_POINTER: case TYPE_TYPEID: - case TYPE_FAULTTYPE: return t.iptr.canonical->builtin.abi_alignment; case TYPE_ARRAY: case TYPE_INFERRED_ARRAY: @@ -841,7 +832,7 @@ static Type *type_generate_inferred_array(Type *arr_type, bool canonical) Type *arr = arr_type->type_cache[INFERRED_ARRAY_OFFSET]; if (arr == NULL) { - arr = type_new(TYPE_INFERRED_ARRAY, str_printf("%s[?]", arr_type->name)); + arr = type_new(TYPE_INFERRED_ARRAY, str_printf("%s[*]", arr_type->name)); arr->array.base = arr_type; arr_type->type_cache[INFERRED_ARRAY_OFFSET] = arr; if (arr_type == arr_type->canonical) @@ -867,7 +858,7 @@ static Type *type_generate_inferred_vector(Type *arr_type, bool canonical) Type *arr = arr_type->type_cache[INFERRED_VECTOR_OFFSET]; if (arr == NULL) { - arr = type_new(TYPE_INFERRED_VECTOR, str_printf("%s[]", arr_type->name)); + arr = type_new(TYPE_INFERRED_VECTOR, str_printf("%s[<*>]", arr_type->name)); arr->array.base = arr_type; arr_type->type_cache[INFERRED_VECTOR_OFFSET] = arr; if (arr_type == arr_type->canonical) @@ -893,7 +884,7 @@ static Type *type_generate_flexible_array(Type *arr_type, bool canonical) Type *arr = arr_type->type_cache[FLEXIBLE_ARRAY_OFFSET]; if (arr == NULL) { - arr = type_new(TYPE_FLEXIBLE_ARRAY, str_printf("%s[?]", arr_type->name)); + arr = type_new(TYPE_FLEXIBLE_ARRAY, str_printf("%s[*]", arr_type->name)); arr->array.base = arr_type; arr->array.len = 0; arr_type->type_cache[FLEXIBLE_ARRAY_OFFSET] = arr; @@ -1067,7 +1058,6 @@ bool type_is_user_defined(Type *type) case TYPE_FUNC_RAW: case TYPE_STRUCT: case TYPE_UNION: - case TYPE_FAULTTYPE: case TYPE_DISTINCT: case TYPE_BITSTRUCT: case TYPE_TYPEDEF: @@ -1172,7 +1162,6 @@ bool type_is_valid_for_vector(Type *type) case TYPE_POINTER: case TYPE_ENUM: case TYPE_TYPEID: - case TYPE_FAULTTYPE: case TYPE_ANYFAULT: return true; case TYPE_DISTINCT: @@ -1207,7 +1196,6 @@ bool type_is_valid_for_array(Type *type) case TYPE_STRUCT: case TYPE_UNION: case TYPE_BITSTRUCT: - case TYPE_FAULTTYPE: case ALL_INTS: case ALL_FLOATS: case TYPE_BOOL: @@ -1469,7 +1457,6 @@ bool type_is_scalar(Type *type) case TYPE_POINTER: case TYPE_FUNC_PTR: case TYPE_ENUM: - case TYPE_FAULTTYPE: case TYPE_ANYFAULT: return true; case TYPE_BITSTRUCT: @@ -1730,7 +1717,6 @@ bool type_may_have_method(Type *type) case TYPE_UNION: case TYPE_STRUCT: case TYPE_ENUM: - case TYPE_FAULTTYPE: case TYPE_BITSTRUCT: case ALL_FLOATS: case ALL_INTS: @@ -1773,7 +1759,6 @@ bool type_may_have_sub_elements(Type *type) case TYPE_UNION: case TYPE_STRUCT: case TYPE_ENUM: - case TYPE_FAULTTYPE: case TYPE_BITSTRUCT: case TYPE_INTERFACE: return true; @@ -2020,9 +2005,6 @@ RETRY_DISTINCT: // IMPROVE: should there be implicit conversion between one enum and the other in // some way? return NULL; - case TYPE_FAULTTYPE: - if (other->type_kind == TYPE_FAULTTYPE) return type_anyfault; - return NULL; case TYPE_ANYFAULT: return type_anyfault; case TYPE_FUNC_PTR: @@ -2129,8 +2111,6 @@ unsigned type_get_introspection_kind(TypeKind kind) return INTROSPECT_TYPE_UNION; case TYPE_BITSTRUCT: return INTROSPECT_TYPE_BITSTRUCT; - case TYPE_FAULTTYPE: - return INTROSPECT_TYPE_FAULT; case TYPE_FUNC_RAW: case TYPE_TYPEDEF: UNREACHABLE @@ -2184,7 +2164,6 @@ Module *type_base_module(Type *type) case TYPE_STRUCT: case TYPE_UNION: case TYPE_BITSTRUCT: - case TYPE_FAULTTYPE: case TYPE_DISTINCT: case TYPE_INTERFACE: return type->decl->unit ? type->decl->unit->module : NULL; diff --git a/test/src/test_suite_runner.c3 b/test/src/test_suite_runner.c3 index 80b0a7649..e6dc3b31e 100644 --- a/test/src/test_suite_runner.c3 +++ b/test/src/test_suite_runner.c3 @@ -28,7 +28,7 @@ fn void main(String[] args) defer (void)path::rmtree(test_dir); // Find the compiler - Path! path = start_cwd.tappend(args[1]); + Path? path = start_cwd.tappend(args[1]); if (catch path) arg_error_exit(appname, "Invalid compiler path: %s", args[1]); // Is it a valid file? if (!path::is_file(path)) @@ -68,7 +68,7 @@ fn void main(String[] args) if (only_skipped && args[3] != "-s" && args[3] != "--skipped") usage(appname); // Get the directory or file to test - Path! file = args[2].to_tpath(); + Path? file = args[2].to_tpath(); if (catch file) arg_error_exit(appname, "Invalid path: '%s'.", args[2]); // Now just run all tests recursively. @@ -129,14 +129,14 @@ fn void RunFile.add_line(&self, String line) } } -fn RunFile*! create_input_file(String filename) +fn RunFile*? create_input_file(String filename) { File file = file::open_path(test_dir.tappend(filename), "wb")!; RunFile *run_file = mem::tnew(RunFile, { .name = filename, .file = file, .is_output = false }); return run_file; } -fn RunFile*! create_output_file(String filename) +fn RunFile*? create_output_file(String filename) { RunFile *run_file = mem::tnew(RunFile, { .name = filename, .is_output = true }); return run_file; @@ -381,7 +381,7 @@ fn void test_file(Path file_path) default: error_exit("FAILED - Unexpected file name '%s', expected a file with a '.c3' or '.c3t' suffix.", file_path.str_view()); } - File! f = file::open_path(file_path, "rb"); + File? f = file::open_path(file_path, "rb"); if (catch f) { error_exit("FAILED - Failed to open '%s'.", file_path); @@ -461,7 +461,7 @@ fn void test_file(Path file_path) } File file_ll = file::open(file.name, "rb")!!; defer (void)file_ll.close(); - String! next = file.expected_lines.pop_first(); + String? next = file.expected_lines.pop_first(); while (try line = io::treadline(&file_ll) && try value = next) { line = line.trim(); @@ -493,7 +493,7 @@ fn void test_file(Path file_path) success_count++; } -fn void! test_path(Path file_path) +fn void? test_path(Path file_path) { (void)path::chdir(start_cwd); foreach (file : path::ls(tmem(), file_path)!!) diff --git a/test/test_suite/abi/small_struct_x64.c3t b/test/test_suite/abi/small_struct_x64.c3t index 8bf57d9fe..d3b49062a 100644 --- a/test/test_suite/abi/small_struct_x64.c3t +++ b/test/test_suite/abi/small_struct_x64.c3t @@ -23,9 +23,8 @@ fn Foo getFoo(Foo f) %.introspect = type { i8, i64, ptr, i64, i64, i64, [0 x i64] } %Foo = type { i8, i8, i8 } -@"$ct.test.Foo" = linkonce global %.introspect { i8 10, i64 0, ptr null, i64 3, i64 0, i64 3, [0 x i64] zeroinitializer }, align 8 +@"$ct.test.Foo" = linkonce global %.introspect { i8 9, i64 0, ptr null, i64 3, i64 0, i64 3, [0 x i64] zeroinitializer }, align 8 -; Function Attrs: define i32 @test.testing() #0 { entry: %y = alloca %Foo, align 1 diff --git a/test/test_suite/any/any_in_any.c3t b/test/test_suite/any/any_in_any.c3t index 56e828ea1..2aeab2852 100644 --- a/test/test_suite/any/any_in_any.c3t +++ b/test/test_suite/any/any_in_any.c3t @@ -11,8 +11,8 @@ fn void main() %any = type { ptr, i64 } @"$ct.any$" = linkonce global %.introspect { i8 7, i64 0, ptr null, i64 16, i64 0, i64 0, [0 x i64] zeroinitializer }, align 8 -@"$ct.p$any$" = linkonce global %.introspect { i8 19, i64 0, ptr null, i64 8, i64 ptrtoint (ptr @"$ct.any$" to i64), i64 0, [0 x i64] zeroinitializer }, align 8 -@"$ct.p$p$any$" = linkonce global %.introspect { i8 19, i64 0, ptr null, i64 8, i64 ptrtoint (ptr @"$ct.p$any$" to i64), i64 0, [0 x i64] zeroinitializer }, align 8 +@"$ct.p$any$" = linkonce global %.introspect { i8 18, i64 0, ptr null, i64 8, i64 ptrtoint (ptr @"$ct.any$" to i64), i64 0, [0 x i64] zeroinitializer }, align 8 +@"$ct.p$p$any$" = linkonce global %.introspect { i8 18, i64 0, ptr null, i64 8, i64 ptrtoint (ptr @"$ct.p$any$" to i64), i64 0, [0 x i64] zeroinitializer }, align 8 define void @foo.main() #0 { entry: diff --git a/test/test_suite/any/variant_test.c3t b/test/test_suite/any/variant_test.c3t index cbb329af0..26397da0b 100644 --- a/test/test_suite/any/variant_test.c3t +++ b/test/test_suite/any/variant_test.c3t @@ -68,7 +68,7 @@ fn void main() @"$ct.int" = linkonce global %.introspect { i8 2, i64 0, ptr null, i64 4, i64 0, i64 0, [0 x i64] zeroinitializer }, align 8 @"$ct.double" = linkonce global %.introspect { i8 4, i64 0, ptr null, i64 8, i64 0, i64 0, [0 x i64] zeroinitializer }, align 8 @"$ct.any$" = linkonce global %.introspect { i8 7, i64 0, ptr null, i64 16, i64 0, i64 0, [0 x i64] zeroinitializer }, align 8 -@"$ct.p$int" = linkonce global %.introspect { i8 19, i64 0, ptr null, i64 8, i64 ptrtoint (ptr @"$ct.int" to i64), i64 0, [0 x i64] zeroinitializer }, align 8 +@"$ct.p$int" = linkonce global %.introspect { i8 18, i64 0, ptr null, i64 8, i64 ptrtoint (ptr @"$ct.int" to i64), i64 0, [0 x i64] zeroinitializer }, align 8 @"$ct.bool" = linkonce global %.introspect { i8 1, i64 0, ptr null, i64 1, i64 0, i64 0, [0 x i64] zeroinitializer }, align 8 define void @foo.test(i64 %0, ptr %1) #0 { diff --git a/test/test_suite/arrays/complex_array_const.c3t b/test/test_suite/arrays/complex_array_const.c3t index fcd12f014..a789f773f 100644 --- a/test/test_suite/arrays/complex_array_const.c3t +++ b/test/test_suite/arrays/complex_array_const.c3t @@ -15,7 +15,7 @@ Connection[3] link @private /* #expect: test.ll -@"$ct.test.Connection" = linkonce global %.introspect { i8 10, i64 0, ptr null, i64 24, i64 0, i64 3, [0 x i64] zeroinitializer }, align 8 +@"$ct.test.Connection" = linkonce global %.introspect { i8 9, i64 0, ptr null, i64 24, i64 0, i64 3, [0 x i64] zeroinitializer }, align 8 @.str = private unnamed_addr constant [6 x i8] c"link1\00", align 1 @.str.1 = private unnamed_addr constant [6 x i8] c"link2\00", align 1 @.str.2 = private unnamed_addr constant [6 x i8] c"link3\00", align 1 diff --git a/test/test_suite/arrays/complex_inferred_array.c3t b/test/test_suite/arrays/complex_inferred_array.c3t index da584132b..6f282cfc4 100644 --- a/test/test_suite/arrays/complex_inferred_array.c3t +++ b/test/test_suite/arrays/complex_inferred_array.c3t @@ -3,8 +3,8 @@ module test; fn void main() { - int[?][?][2][?]! y = { {{{1}, {2}}, { {3}, {4}}}}; - int[?][?][2][?] x = { {{{1}, {2}}, { {3}, {4}}}}; + int[*][*][2][*]? y = { {{{1}, {2}}, { {3}, {4}}}}; + int[*][*][2][*] x = { {{{1}, {2}}, { {3}, {4}}}}; } /* #expect: test.ll diff --git a/test/test_suite/arrays/inferred_array_err.c3 b/test/test_suite/arrays/inferred_array_err.c3 index 6562be53d..0e7dabd0b 100644 --- a/test/test_suite/arrays/inferred_array_err.c3 +++ b/test/test_suite/arrays/inferred_array_err.c3 @@ -1,7 +1,7 @@ -fn int[?] hello() // #error: Inferred array types can only be used in declarations with initializers +fn int[*] hello() // #error: Inferred array types can only be used in declarations with initializers { return int[3] { 1, 2, 3}; } -int[?] c; // #error: Inferred array types can only be used in declarations with initializers +int[*] c; // #error: Inferred array types can only be used in declarations with initializers diff --git a/test/test_suite/arrays/inferred_array_err2.c3 b/test/test_suite/arrays/inferred_array_err2.c3 index d85269e4d..84c324fb3 100644 --- a/test/test_suite/arrays/inferred_array_err2.c3 +++ b/test/test_suite/arrays/inferred_array_err2.c3 @@ -1,5 +1,5 @@ fn void test() { int[3] z; - (int[?])(z); + (int[*])(z); } \ No newline at end of file diff --git a/test/test_suite/arrays/inferred_array_optional.c3t b/test/test_suite/arrays/inferred_array_optional.c3t index 0ad8a5f62..9a60d52d9 100644 --- a/test/test_suite/arrays/inferred_array_optional.c3t +++ b/test/test_suite/arrays/inferred_array_optional.c3t @@ -1,14 +1,14 @@ // #target: macos-x64 module test; -fn int! foo() => 1; +fn int? foo() => 1; fn int main() { - int[?]! x = { 1, 2 }; - int[?]! y = { foo(), foo() }; - int[]! x2 = { 1, 2 }; - int[]! y2 = { foo(), foo() }; + int[*]? x = { 1, 2 }; + int[*]? y = { foo(), foo() }; + int[<*>]? x2 = { 1, 2 }; + int[<*>]? y2 = { foo(), foo() }; return 1; } diff --git a/test/test_suite/arrays/inferred_subarray.c3 b/test/test_suite/arrays/inferred_subarray.c3 index c8258fa30..b1c9a7399 100644 --- a/test/test_suite/arrays/inferred_subarray.c3 +++ b/test/test_suite/arrays/inferred_subarray.c3 @@ -1,5 +1,5 @@ fn void main() { - int[?][?][] x = (int[2][1][]) { { { 1, 2 } } }; - int[?][?][?] y = (int[2][1][]) { { { 1, 2 } } }; + int[*][*][] x = (int[2][1][]) { { { 1, 2 } } }; + int[*][*][*] y = (int[2][1][]) { { { 1, 2 } } }; } diff --git a/test/test_suite/assert/unreachable_in_macro.c3t b/test/test_suite/assert/unreachable_in_macro.c3t index d4025c7bf..17bb5a1d4 100644 --- a/test/test_suite/assert/unreachable_in_macro.c3t +++ b/test/test_suite/assert/unreachable_in_macro.c3t @@ -11,15 +11,12 @@ fn int main() return 0; } -fault Bob -{ - ABC -} +fault ABC; macro test() { if (false) return; - return Bob.ABC?; + return ABC?; unreachable(); } @@ -38,7 +35,7 @@ entry: testblock: ; preds = %entry br label %if.exit if.exit: ; preds = %testblock - store i64 ptrtoint (ptr @"test.Bob$ABC" to i64), ptr %temp_err, align 8 + store i64 ptrtoint (ptr @test.ABC to i64), ptr %temp_err, align 8 br label %end_block end_block: ; preds = %if.exit %0 = load i64, ptr %temp_err, align 8 diff --git a/test/test_suite/attributes/user_defined_attributes.c3t b/test/test_suite/attributes/user_defined_attributes.c3t index e69aa7ae1..698ad461a 100644 --- a/test/test_suite/attributes/user_defined_attributes.c3t +++ b/test/test_suite/attributes/user_defined_attributes.c3t @@ -33,7 +33,7 @@ fn void main() @TestZero %Foo = type { i32, [1020 x i8], i32, [1020 x i8] } -@"$ct.test.Foo" = linkonce global %.introspect { i8 10, i64 0, ptr null, i64 2048, i64 0, i64 2, [0 x i64] zeroinitializer }, align 8 +@"$ct.test.Foo" = linkonce global %.introspect { i8 9, i64 0, ptr null, i64 2048, i64 0, i64 2, [0 x i64] zeroinitializer }, align 8 @test.f = local_unnamed_addr global %Foo zeroinitializer, align 1024 define weak void @test.testme2() #0 { diff --git a/test/test_suite/builtins/builtin_with_optional.c3 b/test/test_suite/builtins/builtin_with_optional.c3 index 037fa3b5a..d61fe6f3c 100644 --- a/test/test_suite/builtins/builtin_with_optional.c3 +++ b/test/test_suite/builtins/builtin_with_optional.c3 @@ -2,7 +2,7 @@ fn void main() { float x; x = $$fma(x, x, x); - float! y; + float? y; y = $$fma(x, x, y); - x = $$fma(x, x, y); // #error: 'float!' + x = $$fma(x, x, y); // #error: 'float?' } \ No newline at end of file diff --git a/test/test_suite/builtins/wide_strings.c3t b/test/test_suite/builtins/wide_strings.c3t index 8ad5bbb33..36336d7a5 100644 --- a/test/test_suite/builtins/wide_strings.c3t +++ b/test/test_suite/builtins/wide_strings.c3t @@ -1,15 +1,15 @@ // #target: macos-x64 -ushort[?] a = $$wstr16("WIDESTR"); -ushort[?] b = $$wstr16("Esc\r\n"); -ushort[?] c = $$wstr16(`lit +ushort[*] a = $$wstr16("WIDESTR"); +ushort[*] b = $$wstr16("Esc\r\n"); +ushort[*] c = $$wstr16(`lit str\ting`); -ushort[?] d = $$wstr16(`γειά`); -uint[?] e = $$wstr32("\u03B3ειά"); -ushort[?] f = $$wstr16(""); -uint[?] g = $$wstr32(""); -ushort[?] h = $$wstr16(``); -uint[?] i = $$wstr32(``); -uint[?] j = $$wstr32("-"); +ushort[*] d = $$wstr16(`γειά`); +uint[*] e = $$wstr32("\u03B3ειά"); +ushort[*] f = $$wstr16(""); +uint[*] g = $$wstr32(""); +ushort[*] h = $$wstr16(``); +uint[*] i = $$wstr32(``); +uint[*] j = $$wstr32("-"); /* #expect: wide_strings.ll diff --git a/test/test_suite/builtins/wide_strings_fail_on_bad_escape_codepoints.c3 b/test/test_suite/builtins/wide_strings_fail_on_bad_escape_codepoints.c3 index 4d3a623d8..ab41310a4 100644 --- a/test/test_suite/builtins/wide_strings_fail_on_bad_escape_codepoints.c3 +++ b/test/test_suite/builtins/wide_strings_fail_on_bad_escape_codepoints.c3 @@ -1,2 +1,2 @@ -ushort[?] a = $$wstr16("γειά ok \U0001F600"); // #error: Invalid codepoint in string: a 16-bit wide-string cannot accommodate codepoints over U+FFFF. -ushort[?] b = $$wstr16("\U00121F60"); // #error: Invalid codepoint in string: a 16-bit wide-string cannot accommodate codepoints over U+FFFF. +ushort[*] a = $$wstr16("γειά ok \U0001F600"); // #error: Invalid codepoint in string: a 16-bit wide-string cannot accommodate codepoints over U+FFFF. +ushort[*] b = $$wstr16("\U00121F60"); // #error: Invalid codepoint in string: a 16-bit wide-string cannot accommodate codepoints over U+FFFF. diff --git a/test/test_suite/builtins/wide_strings_fail_on_wrong_type_assignments.c3 b/test/test_suite/builtins/wide_strings_fail_on_wrong_type_assignments.c3 index 204a49b55..398eb1add 100644 --- a/test/test_suite/builtins/wide_strings_fail_on_wrong_type_assignments.c3 +++ b/test/test_suite/builtins/wide_strings_fail_on_wrong_type_assignments.c3 @@ -1,2 +1,2 @@ -char[?] a = $$wstr16(`short str`); // #error: It is not possible to cast 'ushort[10]' to 'char[?]'. -uint[?] b = $$wstr16("str"); // #error: It is not possible to cast 'ushort[4]' to 'uint[?]'. +char[*] a = $$wstr16(`short str`); // #error: It is not possible to cast 'ushort[10]' to 'char[*]'. +uint[*] b = $$wstr16("str"); // #error: It is not possible to cast 'ushort[4]' to 'uint[*]'. diff --git a/test/test_suite/cast/cast_string_to_infered_array.c3 b/test/test_suite/cast/cast_string_to_infered_array.c3 index 3a89fdcc8..0e5824fff 100644 --- a/test/test_suite/cast/cast_string_to_infered_array.c3 +++ b/test/test_suite/cast/cast_string_to_infered_array.c3 @@ -1,6 +1,6 @@ import std; fn void main() { - char[?]* x = "abc"; // #error: You cannot cast 'String' to 'char[?]*' + char[*]* x = "abc"; // #error: You cannot cast 'String' to 'char[*]*' io::printn($typeof(x).nameof); } \ No newline at end of file diff --git a/test/test_suite/cast/cast_to_failable.c3 b/test/test_suite/cast/cast_to_failable.c3 index 0625d48c4..1f5350d6b 100644 --- a/test/test_suite/cast/cast_to_failable.c3 +++ b/test/test_suite/cast/cast_to_failable.c3 @@ -1,14 +1,11 @@ -fault MyErr -{ - FOO -} +fault FOO; fn void test() { - int! x; - double! y; - int! d = ($typeof(MyErr.FOO?))(x); // #error: Casting to an optional - int! df = ($typeof(y))(x); // #error: Casting to an optional type is not allowed - double! df2 = ($typeof(y!!))(x); + int? x; + double? y; + int? d = ($typeof(FOO?))(x); // #error: Casting to an optional + int? df = ($typeof(y))(x); // #error: Casting to an optional type is not allowed + double? df2 = ($typeof(y!!))(x); } diff --git a/test/test_suite/cast/implicit_infer_len_cast.c3t b/test/test_suite/cast/implicit_infer_len_cast.c3t index 69ea02de2..39eee4cc6 100644 --- a/test/test_suite/cast/implicit_infer_len_cast.c3t +++ b/test/test_suite/cast/implicit_infer_len_cast.c3t @@ -1,19 +1,19 @@ // #target: macos-x64 module test; -macro int test(int[?][?]* y) +macro int test(int[*][*]* y) { $typeof(*y) z = *y; return z[1][1]; } fn void main() { - int[2][?] x = { { 2, 3}, { 5, 6 }}; - int[<2>][?] y = { { 1, 3 }}; - int[][?] z = y; + int[2][*] x = { { 2, 3}, { 5, 6 }}; + int[<2>][*] y = { { 1, 3 }}; + int[<*>][*] z = y; int[<2>][1] w = z; int[<2>][] aa = { { 1, 3 }}; - int[][?] bb = { { 1, 3 } }; + int[][*] bb = { { 1, 3 } }; test(&x); } /* #expect: test.ll diff --git a/test/test_suite/cast/top_down_casts.c3t b/test/test_suite/cast/top_down_casts.c3t index 80bbf9ce4..915569293 100644 --- a/test/test_suite/cast/top_down_casts.c3t +++ b/test/test_suite/cast/top_down_casts.c3t @@ -11,7 +11,7 @@ fn void test() z = (long)x >> y; z = (long)~x; z = (long)-x; - int! w; + int? w; z = w ?? 1; } diff --git a/test/test_suite/clang/2002-01_02.c3t b/test/test_suite/clang/2002-01_02.c3t index 50d88fe44..af1fc4528 100644 --- a/test/test_suite/clang/2002-01_02.c3t +++ b/test/test_suite/clang/2002-01_02.c3t @@ -125,11 +125,11 @@ double afoo = 17; double abar = 12.0; float axx = 12.0f; -char*[?] procnames = { +char*[*] procnames = { "EXIT" }; -void *[?] data = { &afoo, &abar, &axx }; +void *[*] data = { &afoo, &abar, &axx }; /* #expect: test.ll diff --git a/test/test_suite/clang/2002-07.c3t b/test/test_suite/clang/2002-07.c3t index abb40af09..44dfa20d5 100644 --- a/test/test_suite/clang/2002-07.c3t +++ b/test/test_suite/clang/2002-07.c3t @@ -299,11 +299,12 @@ fn int strcmp(char *s1, char *s2) { %Quad = type { i32, %SubStruct, ptr, i8, i32 } %SubStruct = type { i16, i16 } %PBVTest = type { double, double, i32 } -@"$ct.foo.List" = linkonce global %.introspect { i8 10, i64 0, ptr null, i64 16, i64 0, i64 2, [0 x i64] zeroinitializer }, align 8 -@"$ct.foo.PBVTest" = linkonce global %.introspect { i8 10, i64 0, ptr null, i64 24, i64 0, i64 3, [0 x i64] zeroinitializer }, align 8 -@"$ct.foo.FunStructTest" = linkonce global %.introspect { i8 10, i64 0, ptr null, i64 64, i64 0, i64 3, [0 x i64] zeroinitializer }, align 8 -@"$ct.foo.SubStruct" = linkonce global %.introspect { i8 10, i64 0, ptr null, i64 4, i64 0, i64 2, [0 x i64] zeroinitializer }, align 8 -@"$ct.foo.Quad" = linkonce global %.introspect { i8 10, i64 0, ptr null, i64 24, i64 0, i64 5, [0 x i64] zeroinitializer }, align 8 + +@"$ct.foo.List" = linkonce global %.introspect { i8 9, i64 0, ptr null, i64 16, i64 0, i64 2, [0 x i64] zeroinitializer }, align 8 +@"$ct.foo.PBVTest" = linkonce global %.introspect { i8 9, i64 0, ptr null, i64 24, i64 0, i64 3, [0 x i64] zeroinitializer }, align 8 +@"$ct.foo.FunStructTest" = linkonce global %.introspect { i8 9, i64 0, ptr null, i64 64, i64 0, i64 3, [0 x i64] zeroinitializer }, align 8 +@"$ct.foo.SubStruct" = linkonce global %.introspect { i8 9, i64 0, ptr null, i64 4, i64 0, i64 2, [0 x i64] zeroinitializer }, align 8 +@"$ct.foo.Quad" = linkonce global %.introspect { i8 9, i64 0, ptr null, i64 24, i64 0, i64 5, [0 x i64] zeroinitializer }, align 8 @foo.data = local_unnamed_addr global ptr null, align 8 @foo.listNode3 = global %List { i32 4, ptr null }, align 8 @foo.listNode2 = global %List { i32 3, ptr @foo.listNode3 }, align 8 @@ -344,17 +345,20 @@ entry: %l = alloca ptr, align 8 store ptr %0, ptr %l, align 8 br label %loop.cond + loop.cond: ; preds = %loop.body, %entry %2 = load ptr, ptr %l, align 8 %3 = load ptr, ptr %2, align 8 %i2b = icmp ne ptr %3, null br i1 %i2b, label %loop.body, label %loop.exit + loop.body: ; preds = %loop.cond %4 = load ptr, ptr %l, align 8 %5 = load ptr, ptr %4, align 8 %ptradd = getelementptr inbounds i8, ptr %5, i64 8 store ptr %ptradd, ptr %l, align 8 br label %loop.cond + loop.exit: ; preds = %loop.cond %6 = load ptr, ptr %l, align 8 %7 = call ptr @malloc(i32 16) @@ -374,14 +378,18 @@ define ptr @foo.findData(ptr %0, i32 %1) #0 { entry: %i2nb = icmp eq ptr %0, null br i1 %i2nb, label %if.then, label %if.exit + if.then: ; preds = %entry ret ptr null + if.exit: ; preds = %entry %2 = load i32, ptr %0, align 8 %eq = icmp eq i32 %2, %1 br i1 %eq, label %if.then1, label %if.exit2 + if.then1: ; preds = %if.exit ret ptr %0 + if.exit2: ; preds = %if.exit %ptradd = getelementptr inbounds i8, ptr %0, i64 8 %3 = load ptr, ptr %ptradd, align 8 @@ -406,25 +414,31 @@ entry: %1 = call ptr @foo.findData(ptr %0, i32 75) %i2b = icmp ne ptr %1, null br i1 %i2b, label %if.then, label %if.exit + if.then: ; preds = %entry call void @foundIt() br label %if.exit + if.exit: ; preds = %if.then, %entry %2 = load ptr, ptr %myList, align 8 %3 = call ptr @foo.findData(ptr %2, i32 42) %i2b1 = icmp ne ptr %3, null br i1 %i2b1, label %if.then2, label %if.exit3 + if.then2: ; preds = %if.exit call void @foundIt() br label %if.exit3 + if.exit3: ; preds = %if.then2, %if.exit %4 = load ptr, ptr %myList, align 8 %5 = call ptr @foo.findData(ptr %4, i32 700) %i2b4 = icmp ne ptr %5, null br i1 %i2b4, label %if.then5, label %if.exit6 + if.then5: ; preds = %if.exit3 call void @foundIt() br label %if.exit6 + if.exit6: ; preds = %if.then5, %if.exit3 ret void } @@ -436,11 +450,13 @@ entry: %5 = load double, ptr %1, align 8 %lt = fcmp olt double %4, %5 br i1 %lt, label %or.phi, label %or.rhs + or.rhs: ; preds = %entry %6 = load float, ptr %2, align 4 %7 = load float, ptr %3, align 4 %lt1 = fcmp olt float %6, %7 br label %or.phi + or.phi: ; preds = %or.rhs, %entry %val = phi i1 [ true, %entry ], [ %lt1, %or.rhs ] %zext = zext i1 %val to i32 @@ -456,11 +472,13 @@ entry: %ptrxi = ptrtoint ptr %0 to i64 store i64 %ptrxi, ptr %dstp, align 8 br label %loop.cond + loop.cond: ; preds = %loop.body, %entry %3 = load i64, ptr %dstp, align 8 %smod = srem i64 %3, 4 %neq = icmp ne i64 %smod, 0 br i1 %neq, label %loop.body, label %loop.exit + loop.body: ; preds = %loop.cond %4 = load i64, ptr %dstp, align 8 %intptr = inttoptr i64 %4 to ptr @@ -473,6 +491,7 @@ loop.body: ; preds = %loop.cond %sub = sub i32 %6, 1 store i32 %sub, ptr %len, align 4 br label %loop.cond + loop.exit: ; preds = %loop.cond ret ptr %0 } @@ -485,12 +504,14 @@ entry: %1 = load i32, ptr @foo.remaining, align 4 %gt = icmp sgt i32 %0, %1 br i1 %gt, label %if.then, label %if.exit + if.then: ; preds = %entry %2 = call ptr @malloc(i32 32768) store ptr %2, ptr @foo.temp, align 8 store i32 32768, ptr @foo.remaining, align 4 %3 = load ptr, ptr @foo.temp, align 8 ret ptr %3 + if.exit: ; preds = %entry ret ptr null } @@ -535,11 +556,14 @@ entry: %0 = load ptr, ptr @foo.ext, align 8 %i2b = icmp ne ptr %0, null br i1 %i2b, label %cond.lhs, label %cond.rhs + cond.lhs: ; preds = %entry %1 = load ptr, ptr @foo.ext, align 8 br label %cond.phi + cond.rhs: ; preds = %entry br label %cond.phi + cond.phi: ; preds = %cond.rhs, %cond.lhs %val = phi ptr [ %1, %cond.lhs ], [ @.str, %cond.rhs ] %2 = call i32 @fp(i32 12, ptr %val) @@ -594,11 +618,13 @@ entry: %r = alloca %Quad, align 8 %i2b = icmp ne i32 %1, 0 br i1 %i2b, label %if.then, label %if.exit + if.then: ; preds = %entry %ptradd = getelementptr inbounds i8, ptr %r, i64 4 %ptradd1 = getelementptr inbounds i8, ptr %0, i64 4 call void @llvm.memcpy.p0.p0.i32(ptr align 4 %ptradd, ptr align 4 %ptradd1, i32 4, i1 false) br label %if.exit + if.exit: ; preds = %if.then, %entry %ptradd2 = getelementptr inbounds i8, ptr %0, i64 8 %ptradd3 = getelementptr inbounds i8, ptr %r, i64 4 @@ -629,9 +655,11 @@ entry: %r = alloca %Quad, align 8 %i2b = icmp ne i32 %1, 0 br i1 %i2b, label %if.then, label %if.exit + if.then: ; preds = %entry call void @llvm.memcpy.p0.p0.i32(ptr align 8 %r, ptr align 8 %0, i32 24, i1 false) br label %if.exit + if.exit: ; preds = %if.then, %entry %ptradd = getelementptr inbounds i8, ptr %0, i64 20 %ptradd1 = getelementptr inbounds i8, ptr %0, i64 16 @@ -660,9 +688,11 @@ entry: %fpfpext = fpext float %0 to double %gt = fcmp ogt double %fpfpext, 1.234500e+01 br i1 %gt, label %if.then, label %if.exit + if.then: ; preds = %entry store i32 4, ptr %result, align 4 br label %if.exit + if.exit: ; preds = %if.then, %entry %1 = load i32, ptr %result, align 4 ret i32 %1 @@ -720,15 +750,18 @@ entry: store i32 %0, ptr %i, align 4 store i32 %1, ptr %j, align 4 br label %loop.cond + loop.cond: ; preds = %loop.body, %entry %2 = load i32, ptr %i, align 4 %neq = icmp ne i32 %2, 20 br i1 %neq, label %loop.body, label %loop.exit + loop.body: ; preds = %loop.cond %3 = load i32, ptr %i, align 4 %add = add i32 %3, 2 store i32 %add, ptr %i, align 4 br label %loop.cond + loop.exit: ; preds = %loop.cond %4 = load i32, ptr %j, align 4 %5 = load i32, ptr %i, align 4 @@ -753,10 +786,12 @@ entry: store i32 0, ptr %result, align 4 store i32 0, ptr %i, align 4 br label %loop.cond + loop.cond: ; preds = %loop.body, %entry %2 = load i32, ptr %i, align 4 %lt = icmp slt i32 %2, %1 br i1 %lt, label %loop.body, label %loop.exit + loop.body: ; preds = %loop.cond %3 = load i32, ptr %result, align 4 %4 = load i32, ptr %i, align 4 @@ -769,6 +804,7 @@ loop.body: ; preds = %loop.cond %add1 = add i32 %6, 1 store i32 %add1, ptr %i, align 4 br label %loop.cond + loop.exit: ; preds = %loop.cond %7 = load i32, ptr %result, align 4 ret i32 %7 @@ -794,10 +830,12 @@ entry: store i32 0, ptr %i, align 4 store i32 0, ptr %i, align 4 br label %loop.cond + loop.cond: ; preds = %loop.body, %entry %0 = load i32, ptr %i, align 4 %lt = icmp slt i32 %0, 100 br i1 %lt, label %loop.body, label %loop.exit + loop.body: ; preds = %loop.cond %1 = load i32, ptr %i, align 4 %sext = sext i32 %1 to i64 @@ -809,6 +847,7 @@ loop.body: ; preds = %loop.cond %add = add i32 %3, 1 store i32 %add, ptr %i, align 4 br label %loop.cond + loop.exit: ; preds = %loop.cond %4 = load i32, ptr %a, align 4 %sext1 = sext i32 %4 to i64 @@ -829,10 +868,12 @@ entry: %3 = call i32 @externFunc(i64 -1, ptr null, i16 signext %trunc, i8 zeroext 2) store i32 0, ptr %i, align 4 br label %loop.cond + loop.cond: ; preds = %loop.body, %entry %4 = load i32, ptr %i, align 4 %gt = icmp ugt i32 10, %4 br i1 %gt, label %loop.body, label %loop.exit + loop.body: ; preds = %loop.cond %ptradd = getelementptr inbounds i8, ptr %1, i64 24 %5 = load ptr, ptr %ptradd, align 8 @@ -841,6 +882,7 @@ loop.body: ; preds = %loop.cond %add = add i32 %7, 1 store i32 %add, ptr %i, align 4 br label %loop.cond + loop.exit: ; preds = %loop.cond ret i32 0 } @@ -875,6 +917,7 @@ entry: store ptr %0, ptr %s1, align 8 store ptr %1, ptr %s2, align 8 br label %loop.cond + loop.cond: ; preds = %loop.body, %entry %2 = load ptr, ptr %s1, align 8 %ptradd_any = getelementptr i8, ptr %2, i8 1 @@ -886,13 +929,15 @@ loop.cond: ; preds = %loop.body, %entry store i8 %4, ptr %2, align 1 %i2b = icmp ne i8 %4, 0 br i1 %i2b, label %loop.body, label %loop.exit + loop.body: ; preds = %loop.cond br label %loop.cond + loop.exit: ; preds = %loop.cond ret void } -; Function Attrs: +; Function Attrs: nounwind uwtable define void @foo.strcat(ptr %0, ptr %1) #0 { entry: %s1 = alloca ptr, align 8 @@ -900,6 +945,7 @@ entry: store ptr %0, ptr %s1, align 8 store ptr %1, ptr %s2, align 8 br label %loop.cond + loop.cond: ; preds = %loop.body, %entry %2 = load ptr, ptr %s1, align 8 %ptradd_any = getelementptr i8, ptr %2, i8 1 @@ -907,13 +953,16 @@ loop.cond: ; preds = %loop.body, %entry %3 = load i8, ptr %2, align 1 %i2b = icmp ne i8 %3, 0 br i1 %i2b, label %loop.body, label %loop.exit + loop.body: ; preds = %loop.cond br label %loop.cond + loop.exit: ; preds = %loop.cond %4 = load ptr, ptr %s1, align 8 %ptradd_any1 = getelementptr i8, ptr %4, i8 -1 store ptr %ptradd_any1, ptr %s1, align 8 br label %loop.cond2 + loop.cond2: ; preds = %loop.body6, %loop.exit %5 = load ptr, ptr %s1, align 8 %ptradd_any3 = getelementptr i8, ptr %5, i8 1 @@ -925,13 +974,15 @@ loop.cond2: ; preds = %loop.body6, %loop.e store i8 %7, ptr %5, align 1 %i2b5 = icmp ne i8 %7, 0 br i1 %i2b5, label %loop.body6, label %loop.exit7 + loop.body6: ; preds = %loop.cond2 br label %loop.cond2 + loop.exit7: ; preds = %loop.cond2 ret void } -; Function Attrs: +; Function Attrs: nounwind uwtable define i32 @foo.strcmp(ptr %0, ptr %1) #0 { entry: %s1 = alloca ptr, align 8 @@ -939,6 +990,7 @@ entry: store ptr %0, ptr %s1, align 8 store ptr %1, ptr %s2, align 8 br label %loop.cond + loop.cond: ; preds = %loop.body, %entry %2 = load ptr, ptr %s1, align 8 %ptradd_any = getelementptr i8, ptr %2, i8 1 @@ -950,32 +1002,40 @@ loop.cond: ; preds = %loop.body, %entry %5 = load i8, ptr %4, align 1 %eq = icmp eq i8 %3, %5 br i1 %eq, label %loop.body, label %loop.exit + loop.body: ; preds = %loop.cond br label %loop.cond + loop.exit: ; preds = %loop.cond %6 = load ptr, ptr %s1, align 8 %7 = load i8, ptr %6, align 1 %zext = zext i8 %7 to i32 %eq2 = icmp eq i32 0, %zext br i1 %eq2, label %if.then, label %if.else6 + if.then: ; preds = %loop.exit %8 = load ptr, ptr %s2, align 8 %9 = load i8, ptr %8, align 1 %zext3 = zext i8 %9 to i32 %eq4 = icmp eq i32 0, %zext3 br i1 %eq4, label %if.then5, label %if.else + if.then5: ; preds = %if.then ret i32 0 + if.else: ; preds = %if.then ret i32 -1 + if.else6: ; preds = %loop.exit %10 = load ptr, ptr %s2, align 8 %11 = load i8, ptr %10, align 1 %zext7 = zext i8 %11 to i32 %eq8 = icmp eq i32 0, %zext7 br i1 %eq8, label %if.then9, label %if.else10 + if.then9: ; preds = %if.else6 ret i32 1 + if.else10: ; preds = %if.else6 %12 = load ptr, ptr %s1, align 8 %ptradd_any11 = getelementptr i8, ptr %12, i8 -1 diff --git a/test/test_suite/comments/simple_comments.c3 b/test/test_suite/comments/simple_comments.c3 index ded9afc18..7a6a9bec1 100644 --- a/test/test_suite/comments/simple_comments.c3 +++ b/test/test_suite/comments/simple_comments.c3 @@ -12,4 +12,4 @@ fn void test() return; } -/* /* nested /* comments! */ !! */ goes here */ +/* /* nested /* comments? */ !! */ goes here */ diff --git a/test/test_suite/compile_time/comptime_array_folding.c3t b/test/test_suite/compile_time/comptime_array_folding.c3t index 1a7198140..3a87d0cda 100644 --- a/test/test_suite/compile_time/comptime_array_folding.c3t +++ b/test/test_suite/compile_time/comptime_array_folding.c3t @@ -3,7 +3,7 @@ module test; import std; def @TaggedAttr(value) = { - @tag("foo", (ValueHere[?]){ value }) + @tag("foo", (ValueHere[*]){ value }) }; const FOO_STR = "foo"; diff --git a/test/test_suite/compile_time/concat_append.c3t b/test/test_suite/compile_time/concat_append.c3t index 2b2b92d3f..ccd583762 100644 --- a/test/test_suite/compile_time/concat_append.c3t +++ b/test/test_suite/compile_time/concat_append.c3t @@ -3,7 +3,7 @@ module test; macro foo() { var c = "hello" +++ " world"; - String[?] a = (String[1]) { "hello" } +++ (String[1]) { " world" }; + String[*] a = (String[1]) { "hello" } +++ (String[1]) { " world" }; int[2] $a = { 1, 2 }; $a = $a +++ 100; int z = $typeof($a).len; diff --git a/test/test_suite/compile_time/concat_append_extended_and_edit.c3t b/test/test_suite/compile_time/concat_append_extended_and_edit.c3t index c2ded4d53..9be8cbd8f 100644 --- a/test/test_suite/compile_time/concat_append_extended_and_edit.c3t +++ b/test/test_suite/compile_time/concat_append_extended_and_edit.c3t @@ -6,7 +6,7 @@ struct Abc (Printable) { int a; } -fn usz! Abc.to_format(&self, Formatter* f) @dynamic => f.printf("{%s}", self.a); +fn usz? Abc.to_format(&self, Formatter* f) @dynamic => f.printf("{%s}", self.a); fn void main2() { diff --git a/test/test_suite/compile_time/ct_cast_example.c3t b/test/test_suite/compile_time/ct_cast_example.c3t index 6d346fefc..94a51fe5d 100644 --- a/test/test_suite/compile_time/ct_cast_example.c3t +++ b/test/test_suite/compile_time/ct_cast_example.c3t @@ -6,7 +6,7 @@ fn void main() { var $x = { 1, 2 }; $x = $x +++ 333; - io::printn((int[?])$x); + io::printn((int[*])$x); } /* #expect: test.ll diff --git a/test/test_suite/compile_time/ct_subscript_inc.c3t b/test/test_suite/compile_time/ct_subscript_inc.c3t index df8114c2f..2de048a23 100644 --- a/test/test_suite/compile_time/ct_subscript_inc.c3t +++ b/test/test_suite/compile_time/ct_subscript_inc.c3t @@ -19,16 +19,16 @@ fn void main() io::printn($d); var $e = { 1, 2, 3 }; - io::printn((int[?])$e); + io::printn((int[*])$e); io::printn($e[1]++); - io::printn((int[?])$e); + io::printn((int[*])$e); - int[?] $f = { 1, 2, 3 }; + int[*] $f = { 1, 2, 3 }; io::printn($f); io::printn($f[1]++); io::printn($f); - int[?] $g = { 1, 2, 3 }; + int[*] $g = { 1, 2, 3 }; io::printn($g); io::printn(--$g[1]); io::printn(--$g[0]); @@ -51,9 +51,9 @@ fn void main() @.str.8 = private unnamed_addr constant [3 x i8] c"%c\00", align 1 @.str.9 = private unnamed_addr constant [5 x i8] c"Acdc\00", align 1 @.__const = private unnamed_addr constant [3 x i32] [i32 1, i32 2, i32 3], align 4 -@"$ct.std.io.File" = linkonce global %.introspect { i8 10, i64 0, ptr null, i64 8, i64 0, i64 1, [0 x i64] zeroinitializer }, align 8 +@"$ct.std.io.File" = linkonce global %.introspect { i8 9, i64 0, ptr null, i64 8, i64 0, i64 1, [0 x i64] zeroinitializer }, align 8 @.str.10 = private unnamed_addr constant [3 x i8] c"%s\00", align 1 -@"$ct.a3$int" = linkonce global %.introspect { i8 15, i64 0, ptr null, i64 12, i64 ptrtoint (ptr @"$ct.int" to i64), i64 3, [0 x i64] zeroinitializer }, align 8 +@"$ct.a3$int" = linkonce global %.introspect { i8 14, i64 0, ptr null, i64 12, i64 ptrtoint (ptr @"$ct.int" to i64), i64 3, [0 x i64] zeroinitializer }, align 8 @"$ct.int" = linkonce global %.introspect { i8 2, i64 0, ptr null, i64 4, i64 0, i64 0, [0 x i64] zeroinitializer }, align 8 @.str.11 = private unnamed_addr constant [3 x i8] c"%s\00", align 1 @.__const.12 = private unnamed_addr constant [3 x i32] [i32 1, i32 3, i32 3], align 4 diff --git a/test/test_suite/compile_time/more_untyped_conversions.c3t b/test/test_suite/compile_time/more_untyped_conversions.c3t index 41c4cf772..01fa92f3d 100644 --- a/test/test_suite/compile_time/more_untyped_conversions.c3t +++ b/test/test_suite/compile_time/more_untyped_conversions.c3t @@ -10,7 +10,7 @@ fn int main() var $c = { 1, { 3, 4 }}; var $d = { 1, 2 }; Foo f = $c; - int[?] y = $d; + int[*] y = $d; return 0; } diff --git a/test/test_suite/compile_time/stringify2.c3t b/test/test_suite/compile_time/stringify2.c3t index f4d2db3ab..ed8968e55 100644 --- a/test/test_suite/compile_time/stringify2.c3t +++ b/test/test_suite/compile_time/stringify2.c3t @@ -5,7 +5,7 @@ import std::io; fn void main() { var $s1 = $stringify(1 + 2); - char[?] s2 = $stringify($s1); + char[*] s2 = $stringify($s1); char[] s3 = $s1; io::printfn("$s1 == %s", $s1); diff --git a/test/test_suite/compile_time/untyped_conversions.c3t b/test/test_suite/compile_time/untyped_conversions.c3t index 050787316..2c8863014 100644 --- a/test/test_suite/compile_time/untyped_conversions.c3t +++ b/test/test_suite/compile_time/untyped_conversions.c3t @@ -29,20 +29,20 @@ fn void main() %"int[]" = type { ptr, i64 } %any = type { ptr, i64 } -@"$ct.test.Foo" = linkonce global %.introspect { i8 10, i64 0, ptr null, i64 8, i64 0, i64 2, [0 x i64] zeroinitializer }, align 8 +@"$ct.test.Foo" = linkonce global %.introspect { i8 9, i64 0, ptr null, i64 8, i64 0, i64 2, [0 x i64] zeroinitializer }, align 8 @.str = private unnamed_addr constant [9 x i8] c"%s %s %s\00", align 1 -@"$ct.a2$int" = linkonce global %.introspect { i8 15, i64 0, ptr null, i64 8, i64 ptrtoint (ptr @"$ct.int" to i64), i64 2, [0 x i64] zeroinitializer }, align 8 +@"$ct.a2$int" = linkonce global %.introspect { i8 14, i64 0, ptr null, i64 8, i64 ptrtoint (ptr @"$ct.int" to i64), i64 2, [0 x i64] zeroinitializer }, align 8 @"$ct.int" = linkonce global %.introspect { i8 2, i64 0, ptr null, i64 4, i64 0, i64 0, [0 x i64] zeroinitializer }, align 8 -@"$ct.sa$int" = linkonce global %.introspect { i8 16, i64 0, ptr null, i64 16, i64 ptrtoint (ptr @"$ct.int" to i64), i64 0, [0 x i64] zeroinitializer }, align 8 -@"$ct.v2$int" = linkonce global %.introspect { i8 17, i64 0, ptr null, i64 8, i64 ptrtoint (ptr @"$ct.int" to i64), i64 2, [0 x i64] zeroinitializer }, align 8 +@"$ct.sa$int" = linkonce global %.introspect { i8 15, i64 0, ptr null, i64 16, i64 ptrtoint (ptr @"$ct.int" to i64), i64 0, [0 x i64] zeroinitializer }, align 8 +@"$ct.v2$int" = linkonce global %.introspect { i8 16, i64 0, ptr null, i64 8, i64 ptrtoint (ptr @"$ct.int" to i64), i64 2, [0 x i64] zeroinitializer }, align 8 @.__const = private unnamed_addr constant [1 x %Foo] [%Foo { i32 1, i32 2 }], align 4 @.__const.1 = private unnamed_addr constant %Foo { i32 1, i32 2 }, align 4 @.__const.2 = private unnamed_addr constant [1 x [2 x i32]] [[2 x i32] [i32 1, i32 2]], align 4 @.__const.3 = private unnamed_addr constant [1 x [2 x double]] [[2 x double] [double 1.000000e+00, double 2.000000e+00]], align 16 @.str.4 = private unnamed_addr constant [15 x i8] c"%s %s {%s, %s}\00", align 1 -@"$ct.a1$a2$int" = linkonce global %.introspect { i8 15, i64 0, ptr null, i64 8, i64 ptrtoint (ptr @"$ct.a2$int" to i64), i64 1, [0 x i64] zeroinitializer }, align 8 -@"$ct.a1$a2$double" = linkonce global %.introspect { i8 15, i64 0, ptr null, i64 16, i64 ptrtoint (ptr @"$ct.a2$double" to i64), i64 1, [0 x i64] zeroinitializer }, align 8 -@"$ct.a2$double" = linkonce global %.introspect { i8 15, i64 0, ptr null, i64 16, i64 ptrtoint (ptr @"$ct.double" to i64), i64 2, [0 x i64] zeroinitializer }, align 8 +@"$ct.a1$a2$int" = linkonce global %.introspect { i8 14, i64 0, ptr null, i64 8, i64 ptrtoint (ptr @"$ct.a2$int" to i64), i64 1, [0 x i64] zeroinitializer }, align 8 +@"$ct.a1$a2$double" = linkonce global %.introspect { i8 14, i64 0, ptr null, i64 16, i64 ptrtoint (ptr @"$ct.a2$double" to i64), i64 1, [0 x i64] zeroinitializer }, align 8 +@"$ct.a2$double" = linkonce global %.introspect { i8 14, i64 0, ptr null, i64 16, i64 ptrtoint (ptr @"$ct.double" to i64), i64 2, [0 x i64] zeroinitializer }, align 8 @"$ct.double" = linkonce global %.introspect { i8 4, i64 0, ptr null, i64 8, i64 0, i64 0, [0 x i64] zeroinitializer }, align 8 @.__const.5 = private unnamed_addr constant [2 x i32] [i32 1, i32 2], align 4 @.__const.6 = private unnamed_addr constant [2 x i32] [i32 3, i32 4], align 4 diff --git a/test/test_suite/compile_time/untyped_with_inferred.c3 b/test/test_suite/compile_time/untyped_with_inferred.c3 index 5c4ff88ed..a9715e18d 100644 --- a/test/test_suite/compile_time/untyped_with_inferred.c3 +++ b/test/test_suite/compile_time/untyped_with_inferred.c3 @@ -2,5 +2,5 @@ fn void main() { var $x = { 1, 1.0 }; - double[?] z = $x; + double[*] z = $x; } diff --git a/test/test_suite/compile_time_introspection/defined2.c3 b/test/test_suite/compile_time_introspection/defined2.c3 index 36ac00559..5c4e249d3 100644 --- a/test/test_suite/compile_time_introspection/defined2.c3 +++ b/test/test_suite/compile_time_introspection/defined2.c3 @@ -2,7 +2,7 @@ fn void main() { int[<2>] ab = { 11, 22 }; $assert !$defined(&1); - int! a; + int? a; $assert $defined(a!!); $assert !$defined(ab!!); $assert $defined(a!); diff --git a/test/test_suite/compile_time_introspection/defined_err.c3 b/test/test_suite/compile_time_introspection/defined_err.c3 index 20b48c75f..a3d8e1c46 100644 --- a/test/test_suite/compile_time_introspection/defined_err.c3 +++ b/test/test_suite/compile_time_introspection/defined_err.c3 @@ -19,7 +19,7 @@ fn void test3() $assert $defined(Foo[1]); $assert $defined(Foo*); $assert $defined(Foo[]); - $assert $defined(Foo[?]); + $assert $defined(Foo[*]); bool x = $defined(Foo[y]); // #error: 'y' could not be found, did you spell it right? } diff --git a/test/test_suite/compile_time_introspection/paramsof.c3t b/test/test_suite/compile_time_introspection/paramsof.c3t index f45018999..2c4f0b4bd 100644 --- a/test/test_suite/compile_time_introspection/paramsof.c3t +++ b/test/test_suite/compile_time_introspection/paramsof.c3t @@ -6,7 +6,7 @@ fn void testme(int a, double b) fn void main() { - ReflectedParam[?] z = $typeof(testme).paramsof; + ReflectedParam[*] z = $typeof(testme).paramsof; foreach (r : z) { io::printn(r); @@ -29,9 +29,9 @@ fn void main() @.str.1 = private unnamed_addr constant [2 x i8] c"b\00", align 1 @"$ct.double" = linkonce global %.introspect { i8 4, i64 0, ptr null, i64 8, i64 0, i64 0, [0 x i64] zeroinitializer }, align 8 @.__const = private unnamed_addr constant [2 x %ReflectedParam] [%ReflectedParam { %"char[]" { ptr @.str, i64 1 }, i64 ptrtoint (ptr @"$ct.int" to i64) }, %ReflectedParam { %"char[]" { ptr @.str.1, i64 1 }, i64 ptrtoint (ptr @"$ct.double" to i64) }], align 16 -@"$ct.std.io.File" = linkonce global %.introspect { i8 10, i64 0, ptr null, i64 8, i64 0, i64 1, [0 x i64] zeroinitializer }, align 8 +@"$ct.std.io.File" = linkonce global %.introspect { i8 9, i64 0, ptr null, i64 8, i64 0, i64 1, [0 x i64] zeroinitializer }, align 8 @.str.2 = private unnamed_addr constant [3 x i8] c"%s\00", align 1 -@"$ct.ReflectedParam" = linkonce global %.introspect { i8 10, i64 0, ptr null, i64 24, i64 0, i64 2, [0 x i64] zeroinitializer }, align 8 +@"$ct.ReflectedParam" = linkonce global %.introspect { i8 9, i64 0, ptr null, i64 24, i64 0, i64 2, [0 x i64] zeroinitializer }, align 8 @.str.3 = private unnamed_addr constant [2 x i8] c"a\00", align 1 @.str.4 = private unnamed_addr constant [4 x i8] c"int\00", align 1 @.str.5 = private unnamed_addr constant [2 x i8] c"b\00", align 1 diff --git a/test/test_suite/compile_time_introspection/parentof.c3t b/test/test_suite/compile_time_introspection/parentof.c3t index 659b6b266..2a993cdd4 100644 --- a/test/test_suite/compile_time_introspection/parentof.c3t +++ b/test/test_suite/compile_time_introspection/parentof.c3t @@ -20,8 +20,8 @@ fn void main() /* #expect: foo.ll -@"$ct.foo.Foo" = linkonce global %.introspect { i8 10, i64 0, ptr null, i64 4, i64 0, i64 1, [0 x i64] zeroinitializer }, align 8 -@"$ct.foo.Bar" = linkonce global %.introspect { i8 10, i64 ptrtoint (ptr @"$ct.foo.Foo" to i64), ptr null, i64 4, i64 0, i64 1, [0 x i64] zeroinitializer }, align 8 +@"$ct.foo.Foo" = linkonce global %.introspect { i8 9, i64 0, ptr null, i64 4, i64 0, i64 1, [0 x i64] zeroinitializer }, align 8 +@"$ct.foo.Bar" = linkonce global %.introspect { i8 9, i64 ptrtoint (ptr @"$ct.foo.Foo" to i64), ptr null, i64 4, i64 0, i64 1, [0 x i64] zeroinitializer }, align 8 @"$ct.void" = linkonce global %.introspect { i8 0, i64 0, ptr null, i64 1, i64 0, i64 0, [0 x i64] zeroinitializer }, align 8 ; Function Attrs: diff --git a/test/test_suite/compile_time_introspection/qnameof.c3t b/test/test_suite/compile_time_introspection/qnameof.c3t index cf63a6bbb..d78669117 100644 --- a/test/test_suite/compile_time_introspection/qnameof.c3t +++ b/test/test_suite/compile_time_introspection/qnameof.c3t @@ -22,7 +22,7 @@ fn void main() /* #expect: qnametest.ll -@"$ct.qnametest.Blob" = linkonce global %.introspect { i8 10, i64 0, ptr null, i64 8, i64 0, i64 2, [0 x i64] zeroinitializer }, align 8 +@"$ct.qnametest.Blob" = linkonce global %.introspect { i8 9, i64 0, ptr null, i64 8, i64 0, i64 2, [0 x i64] zeroinitializer }, align 8 @qnametest.x = local_unnamed_addr global i32 0, align 4 @.str = private unnamed_addr constant [12 x i8] c"printf: %s\0A\00", align 1 @.str.1 = private unnamed_addr constant [7 x i8] c"printf\00", align 1 diff --git a/test/test_suite/concurrency/atomic_load_store_debug.c3t b/test/test_suite/concurrency/atomic_load_store_debug.c3t index 8fd02ddb9..8c29a1a82 100644 --- a/test/test_suite/concurrency/atomic_load_store_debug.c3t +++ b/test/test_suite/concurrency/atomic_load_store_debug.c3t @@ -23,7 +23,7 @@ fn void main() %.introspect = type { i8, i64, ptr, i64, i64, i64, [0 x i64] } %any = type { ptr, i64 } -@"$ct.test.Ghh" = linkonce global %.introspect { i8 10, i64 0, ptr null, i64 12, i64 0, i64 3, [0 x i64] zeroinitializer }, align 8 +@"$ct.test.Ghh" = linkonce global %.introspect { i8 9, i64 0, ptr null, i64 12, i64 0, i64 3, [0 x i64] zeroinitializer }, align 8 @.str = private unnamed_addr constant [3 x i8] c"%d\00", align 1 @"$ct.int" = linkonce global %.introspect { i8 2, i64 0, ptr null, i64 4, i64 0, i64 0, [0 x i64] zeroinitializer }, align 8 diff --git a/test/test_suite/constants/byte_literal_fail_base64.c3 b/test/test_suite/constants/byte_literal_fail_base64.c3 index 01ddc731f..ce3837ea6 100644 --- a/test/test_suite/constants/byte_literal_fail_base64.c3 +++ b/test/test_suite/constants/byte_literal_fail_base64.c3 @@ -1 +1 @@ -char[?] foo64 = b64"SGVsbG8g!V29ybGQ="; // #error: '!' is not a valid base64 character \ No newline at end of file +char[*] foo64 = b64"SGVsbG8g!V29ybGQ="; // #error: '!' is not a valid base64 character \ No newline at end of file diff --git a/test/test_suite/constants/byte_literal_fail_base64_2.c3 b/test/test_suite/constants/byte_literal_fail_base64_2.c3 index 862f66448..443883c14 100644 --- a/test/test_suite/constants/byte_literal_fail_base64_2.c3 +++ b/test/test_suite/constants/byte_literal_fail_base64_2.c3 @@ -1 +1 @@ -char[?] foo64 = b64"SGVsbG8gV29y=bGQ="; // #error: 'b' can't be placed after an ending '=' \ No newline at end of file +char[*] foo64 = b64"SGVsbG8gV29y=bGQ="; // #error: 'b' can't be placed after an ending '=' \ No newline at end of file diff --git a/test/test_suite/constants/byte_literal_fail_base64_4.c3 b/test/test_suite/constants/byte_literal_fail_base64_4.c3 index 2295dab35..ab8705d22 100644 --- a/test/test_suite/constants/byte_literal_fail_base64_4.c3 +++ b/test/test_suite/constants/byte_literal_fail_base64_4.c3 @@ -1 +1 @@ -char[?] foo64 = b64"SGVsbG8gV29ybGQ==="; // #error: There cannot be more than \ No newline at end of file +char[*] foo64 = b64"SGVsbG8gV29ybGQ==="; // #error: There cannot be more than \ No newline at end of file diff --git a/test/test_suite/constants/byte_literal_fail_hex.c3 b/test/test_suite/constants/byte_literal_fail_hex.c3 index c2312828a..115e3d4ba 100644 --- a/test/test_suite/constants/byte_literal_fail_hex.c3 +++ b/test/test_suite/constants/byte_literal_fail_hex.c3 @@ -1 +1 @@ -char[?] foo64 = x"abc def ^"; // #error: '^' isn't a valid hexadecimal digit, all digits should be a-z, A-Z and 0-9. +char[*] foo64 = x"abc def ^"; // #error: '^' isn't a valid hexadecimal digit, all digits should be a-z, A-Z and 0-9. diff --git a/test/test_suite/constants/byte_literals.c3t b/test/test_suite/constants/byte_literals.c3t index 30b8943df..9b6e90840 100644 --- a/test/test_suite/constants/byte_literals.c3t +++ b/test/test_suite/constants/byte_literals.c3t @@ -1,8 +1,8 @@ -char[?] foob = x"a0"; -char[?] fooz = x"00aabbccddeeff"; -char[?] fooy = x'dead beef'; -char[?] foow = x"4549234d e d"; -char[?] foo64 = b64"SGVsbG8gV29ybGQ="; +char[*] foob = x"a0"; +char[*] fooz = x"00aabbccddeeff"; +char[*] fooy = x'dead beef'; +char[*] foow = x"4549234d e d"; +char[*] foo64 = b64"SGVsbG8gV29ybGQ="; /* #expect: byte_literals.ll diff --git a/test/test_suite/constants/empty_byte_literal.c3 b/test/test_suite/constants/empty_byte_literal.c3 index 6e558ec45..f2de965cf 100644 --- a/test/test_suite/constants/empty_byte_literal.c3 +++ b/test/test_suite/constants/empty_byte_literal.c3 @@ -3,6 +3,6 @@ import std; fn void main() { char[] cd = {}; - char[?] b = x""; // #error: must be at least 1 byte + char[*] b = x""; // #error: must be at least 1 byte io::printfn("%d", b.len); } \ No newline at end of file diff --git a/test/test_suite/debug_symbols/defer_macro.c3t b/test/test_suite/debug_symbols/defer_macro.c3t index c39078338..58c0cb3d1 100644 --- a/test/test_suite/debug_symbols/defer_macro.c3t +++ b/test/test_suite/debug_symbols/defer_macro.c3t @@ -7,7 +7,7 @@ import std::io; fn void foo(int x) { - int! a = x; + int? a = x; while (try a) { a = 2; @@ -444,7 +444,7 @@ cache_hit: ; preds = %if.exit missing_function: ; preds = %16 %18 = load ptr, ptr @std.core.builtin.panic, align 8, !dbg !166 - call void %18(ptr @.panic_msg, i64 44, ptr @.file, i64 16, ptr @.func, i64 6, i32 68) + call void %18(ptr @.panic_msg, i64 44, ptr @.file, i64 16, ptr @.func unreachable, !dbg !166 match: ; preds = %16 @@ -741,7 +741,7 @@ no_match: ; preds = %compare !132 = !DILocation !133 = distinct !DILexicalBlock(scope: !111, file: !7, line: 124, column: 8) !134 = !DILocation -!135 = distinct !DISubprogram(name: "_$main", linkageName: "main", scope: !7, file: !7, line: 15, type: !136, scopeLine: 15, flags: DIFlagPrototyped, spFlags: DISPFlagDefinition, unit: !6, retainedNodes: !21) +!135 = distinct !DISubprogram(name: "_$main", linkageName: "main", scope: !7, file: !7 !136 = !DISubroutineType(types: !137) !137 = !{!15, !15, !138} !138 = !DIDerivedType(tag: DW_TAG_pointer_type, name: "char**", baseType: !43, size: 64, align: 64, dwarfAddressSpace: 0) @@ -749,16 +749,16 @@ no_match: ; preds = %compare !140 = !DILocation(line: 15, column: 8, scope: !135) !141 = !DILocalVariable(name: ".anon", arg: 2, scope: !135, file: !7, line: 15, type: !138) !142 = !DILocalVariable(name: "list", scope: !143, file: !7, line: 45, type: !35, align: 8) -!143 = distinct !DISubprogram(name: "@main_to_int_main_args", linkageName: "@main_to_int_main_args", scope: !144, file: !144, line: 43, scopeLine: 43, spFlags: DISPFlagLocalToUnit | DISPFlagDefinition, unit: !6, retainedNodes: !21) +!143 = distinct !DISubprogram(name: "@main_to_int_main_args", linkageName: "@main_to_int_main_args", scope: !144, file: !144 !144 = !DIFile(filename: "main_stub.c3" !145 = !DILocation !146 = !DILocalVariable(name: "list", scope: !147, file: !7, line: 24, type: !35, align: 8) -!147 = distinct !DISubprogram(name: "args_to_strings", linkageName: "args_to_strings", scope: !144, file: !144, line: 22, scopeLine: 22, spFlags: DISPFlagLocalToUnit | DISPFlagDefinition, unit: !6, retainedNodes: !21) +!147 = distinct !DISubprogram(name: "args_to_strings", linkageName: "args_to_strings", scope: !144, file: !144 !148 = !DILocation !149 = !DILocation !150 = !DILocation !151 = !DILocation -!152 = distinct !DISubprogram(name: "alloc_array_try", linkageName: "alloc_array_try", scope: !153, file: !153, line: 284, scopeLine: 284, spFlags: DISPFlagLocalToUnit | DISPFlagDefinition, unit: !6) +!152 = distinct !DISubprogram(name: "alloc_array_try", linkageName: "alloc_array_try" !153 = !DIFile(filename: "mem_allocator.c3" !154 = !DILocation !155 = distinct !DISubprogram(name: "alloc_array", linkageName: "alloc_array", scope: !153 @@ -767,11 +767,11 @@ no_match: ; preds = %compare !158 = !DILocation !159 = !DILocation !160 = !DILocation -!161 = distinct !DISubprogram(name: "malloc_try", linkageName: "malloc_try", scope: !153, file: !153, line: 60, scopeLine: 60, spFlags: DISPFlagLocalToUnit | DISPFlagDefinition, unit: !6) +!161 = distinct !DISubprogram(name: "malloc_try", linkageName: "malloc_try", scope: !153, file: !153 !162 = !DILocation !163 = !DILocation !164 = !DILocation -!165 = distinct !DISubprogram(name: "[DEFAULT INIT]", linkageName: "[DEFAULT INIT]", scope: !153, file: !153, line: 28, scopeLine: 28, spFlags: DISPFlagLocalToUnit | DISPFlagDefinition, unit: !6) +!165 = distinct !DISubprogram(name: "[DEFAULT INIT]", linkageName: "[DEFAULT INIT]", scope: !153, file: !153 !166 = !DILocation !167 = !DILocation !168 = !DILocalVariable(name: "i", scope: !169, file: !7, line: 25, type: !15, align: 4) @@ -792,7 +792,7 @@ no_match: ; preds = %compare !183 = !DILocation !184 = !DILocation !185 = !DILocalVariable(name: "len", scope: !186, file: !7, line: 5, type: !46, align: 8) -!186 = distinct !DISubprogram(name: "_strlen", linkageName: "_strlen", scope: !144, file: !144, line: 3, scopeLine: 3, spFlags: DISPFlagLocalToUnit | DISPFlagDefinition, unit: !6, retainedNodes: !21) +!186 = distinct !DISubprogram(name: "_strlen", linkageName: "_strlen", scope: !144, file: !144 !187 = !DILocation !188 = !DILocation !189 = !DILocation diff --git a/test/test_suite/defer/defer_catch_direct_error.c3t b/test/test_suite/defer/defer_catch_direct_error.c3t index 98c0d06be..3fee956e0 100644 --- a/test/test_suite/defer/defer_catch_direct_error.c3t +++ b/test/test_suite/defer/defer_catch_direct_error.c3t @@ -1,7 +1,7 @@ // #target: macos-x64 module test; import std::io; -fn void! example_fn() +fn void? example_fn() { defer try { int a = 1; @@ -10,7 +10,7 @@ fn void! example_fn() defer (catch err) { anyfault f = err; } - return io::IoError.FILE_NOT_FOUND?; + return io::FILE_NOT_FOUND?; } /* #expect: test.ll @@ -20,10 +20,10 @@ entry: %reterr = alloca i64, align 8 %err = alloca i64, align 8 %f = alloca i64, align 8 - store i64 ptrtoint (ptr @"std.io.IoError$FILE_NOT_FOUND" to i64), ptr %reterr, align 8 + store i64 ptrtoint (ptr @std.io.FILE_NOT_FOUND to i64), ptr %reterr, align 8 %0 = load i64, ptr %reterr, align 8 store i64 %0, ptr %err, align 8 %1 = load i64, ptr %err, align 8 store i64 %1, ptr %f, align 8 - ret i64 ptrtoint (ptr @"std.io.IoError$FILE_NOT_FOUND" to i64) + ret i64 ptrtoint (ptr @std.io.FILE_NOT_FOUND to i64) } diff --git a/test/test_suite/defer/defer_catch_err.c3t b/test/test_suite/defer/defer_catch_err.c3t index d8befc30f..ff16f158d 100644 --- a/test/test_suite/defer/defer_catch_err.c3t +++ b/test/test_suite/defer/defer_catch_err.c3t @@ -2,9 +2,9 @@ module foo; import std::io; -fault Test { FOO } +fault FOO; -fn void! test2() +fn void? test2() { defer (catch err) {}; test()!; @@ -13,18 +13,18 @@ fn void! test2() macro run() { const ABC = 4; - int! x = SearchResult.MISSING?; + int? x = NOT_FOUND?; defer (catch err) io::printfn("Hello %s", err); - defer (catch err) { io::printfn("Bye %s", err); err = Test.FOO; } + defer (catch err) { io::printfn("Bye %s", err); err = FOO; } return x; } -fn int! test() +fn int? test() { - int! z = run(); + int? z = run(); const ABC = 4; - int! x = SearchResult.MISSING?; + int? x = NOT_FOUND?; defer (catch err) io::printfn("Hello %s", err); - defer (catch err) { io::printfn("Bye %s", err); err = Test.FOO; } + defer (catch err) { io::printfn("Bye %s", err); err = FOO; } return x; } @@ -85,7 +85,7 @@ entry: %err19 = alloca i64, align 8 %varargslots20 = alloca [1 x %any], align 16 %retparam21 = alloca i64, align 8 - store i64 ptrtoint (ptr @"std.core.builtin.SearchResult$MISSING" to i64), ptr %x.f, align 8 + store i64 ptrtoint (ptr @std.core.builtin.NOT_FOUND to i64), ptr %x.f, align 8 %optval = load i64, ptr %x.f, align 8 %not_err = icmp eq i64 %optval, 0 %1 = call i1 @llvm.expect.i1(i1 %not_err, i1 true) @@ -107,13 +107,13 @@ opt_block_cleanup: ; preds = %assign_optional %5 = insertvalue %any %4, i64 ptrtoint (ptr @"$ct.anyfault" to i64), 1 store %any %5, ptr %varargslots, align 16 %6 = call i64 @std.io.printfn(ptr %retparam, ptr @.str, i64 6, ptr %varargslots, i64 1) - store i64 ptrtoint (ptr @"foo.Test$FOO" to i64), ptr %err, align 8 + store i64 ptrtoint (ptr @foo.FOO to i64), ptr %err, align 8 %7 = load i64, ptr %z.f, align 8 store i64 %7, ptr %err3, align 8 %8 = insertvalue %any undef, ptr %err3, 0 %9 = insertvalue %any %8, i64 ptrtoint (ptr @"$ct.anyfault" to i64), 1 store %any %9, ptr %varargslots4, align 16 - %10 = call i64 @std.io.printfn(ptr %retparam5, ptr @.str.2, i64 8, ptr %varargslots4, i64 1) + %10 = call i64 @std.io.printfn(ptr %retparam5, ptr @.str.1, i64 8, ptr %varargslots4, i64 1) br label %after_assign expr_block.exit: ; preds = %after_check @@ -123,7 +123,7 @@ expr_block.exit: ; preds = %after_check br label %after_assign after_assign: ; preds = %expr_block.exit, %opt_block_cleanup - store i64 ptrtoint (ptr @"std.core.builtin.SearchResult$MISSING" to i64), ptr %x.f9, align 8 + store i64 ptrtoint (ptr @std.core.builtin.NOT_FOUND to i64), ptr %x.f9, align 8 %optval10 = load i64, ptr %x.f9, align 8 %not_err11 = icmp eq i64 %optval10, 0 %12 = call i1 @llvm.expect.i1(i1 %not_err11, i1 true) @@ -144,14 +144,14 @@ err_retblock: ; preds = %assign_optional12 %15 = insertvalue %any undef, ptr %err14, 0 %16 = insertvalue %any %15, i64 ptrtoint (ptr @"$ct.anyfault" to i64), 1 store %any %16, ptr %varargslots15, align 16 - %17 = call i64 @std.io.printfn(ptr %retparam16, ptr @.str.4, i64 6, ptr %varargslots15, i64 1) - store i64 ptrtoint (ptr @"foo.Test$FOO" to i64), ptr %err14, align 8 + %17 = call i64 @std.io.printfn(ptr %retparam16, ptr @.str.3, i64 6, ptr %varargslots15, i64 1) + store i64 ptrtoint (ptr @foo.FOO to i64), ptr %err14, align 8 %18 = load i64, ptr %reterr, align 8 store i64 %18, ptr %err19, align 8 %19 = insertvalue %any undef, ptr %err19, 0 %20 = insertvalue %any %19, i64 ptrtoint (ptr @"$ct.anyfault" to i64), 1 store %any %20, ptr %varargslots20, align 16 - %21 = call i64 @std.io.printfn(ptr %retparam21, ptr @.str.5, i64 8, ptr %varargslots20, i64 1) + %21 = call i64 @std.io.printfn(ptr %retparam21, ptr @.str.4, i64 8, ptr %varargslots20, i64 1) %22 = load i64, ptr %reterr, align 8 ret i64 %22 } \ No newline at end of file diff --git a/test/test_suite/defer/defer_catch_mix.c3t b/test/test_suite/defer/defer_catch_mix.c3t index 20402f275..745b6d0f9 100644 --- a/test/test_suite/defer/defer_catch_mix.c3t +++ b/test/test_suite/defer/defer_catch_mix.c3t @@ -2,9 +2,9 @@ module test; import std::io; -fn char[]! fileReader(String filename, char[] buffer) +fn char[]? fileReader(String filename, char[] buffer) { - io::File! file = io::file::open(filename, "r"); + io::File? file = io::file::open(filename, "r"); defer (catch foo) io::printn("something on fail with the file"); defer io::printn("always close the file"); @@ -14,7 +14,7 @@ fn char[]! fileReader(String filename, char[] buffer) fn void main() { - char[] !buffer = mem::new_array(char, 12); + char[]? buffer = mem::new_array(char, 12); buffer = fileReader("not_found.txt", buffer); return; } @@ -60,32 +60,40 @@ entry: %not_err = icmp eq i64 %5, 0 %6 = call i1 @llvm.expect.i1(i1 %not_err, i1 true) br i1 %6, label %after_check, label %assign_optional + assign_optional: ; preds = %entry store i64 %5, ptr %file.f, align 8 br label %after_assign + after_check: ; preds = %entry call void @llvm.memcpy.p0.p0.i32(ptr align 8 %file, ptr align 8 %retparam, i32 8, i1 false) store i64 0, ptr %file.f, align 8 br label %after_assign + after_assign: ; preds = %after_check, %assign_optional %optval = load i64, ptr %file.f, align 8 %not_err1 = icmp eq i64 %optval, 0 %7 = call i1 @llvm.expect.i1(i1 %not_err1, i1 true) br i1 %7, label %after_check3, label %assign_optional2 + assign_optional2: ; preds = %after_assign store i64 %optval, ptr %error_var, align 8 br label %guard_block + after_check3: ; preds = %after_assign %8 = load [2 x i64], ptr %buffer, align 8 %9 = call i64 @std.io.File.read(ptr %retparam4, ptr %file, [2 x i64] %8) %not_err5 = icmp eq i64 %9, 0 %10 = call i1 @llvm.expect.i1(i1 %not_err5, i1 true) br i1 %10, label %after_check7, label %assign_optional6 + assign_optional6: ; preds = %after_check3 store i64 %9, ptr %error_var, align 8 br label %guard_block + after_check7: ; preds = %after_check3 br label %noerr_block52 + guard_block: ; preds = %assign_optional6, %assign_optional2 %11 = call ptr @std.io.stdout() store %"char[]" { ptr @.str.1, i64 21 }, ptr %taddr11, align 8 @@ -94,13 +102,17 @@ guard_block: ; preds = %assign_optional6, % %not_err12 = icmp eq i64 %13, 0 %14 = call i1 @llvm.expect.i1(i1 %not_err12, i1 true) br i1 %14, label %after_check14, label %assign_optional13 + assign_optional13: ; preds = %guard_block store i64 %13, ptr %error_var8, align 8 br label %guard_block15 + after_check14: ; preds = %guard_block br label %noerr_block + guard_block15: ; preds = %assign_optional13 br label %voiderr + noerr_block: ; preds = %after_check14 %15 = load i64, ptr %retparam10, align 8 store i64 %15, ptr %len, align 8 @@ -108,29 +120,38 @@ noerr_block: ; preds = %after_check14 %not_err17 = icmp eq i64 %16, 0 %17 = call i1 @llvm.expect.i1(i1 %not_err17, i1 true) br i1 %17, label %after_check19, label %assign_optional18 + assign_optional18: ; preds = %noerr_block store i64 %16, ptr %error_var16, align 8 br label %guard_block20 + after_check19: ; preds = %noerr_block br label %noerr_block21 + guard_block20: ; preds = %assign_optional18 br label %voiderr + noerr_block21: ; preds = %after_check19 %18 = call i64 @std.io.File.flush(ptr %11) %not_err23 = icmp eq i64 %18, 0 %19 = call i1 @llvm.expect.i1(i1 %not_err23, i1 true) br i1 %19, label %after_check25, label %assign_optional24 + assign_optional24: ; preds = %noerr_block21 store i64 %18, ptr %error_var22, align 8 br label %guard_block26 + after_check25: ; preds = %noerr_block21 br label %noerr_block27 + guard_block26: ; preds = %assign_optional24 br label %voiderr + noerr_block27: ; preds = %after_check25 %20 = load i64, ptr %len, align 8 %add = add i64 %20, 1 br label %voiderr + voiderr: ; preds = %noerr_block27, %guard_block26, %guard_block20, %guard_block15 %21 = load i64, ptr %error_var, align 8 store i64 %21, ptr %foo, align 8 @@ -141,13 +162,17 @@ voiderr: ; preds = %noerr_block27, %gua %not_err33 = icmp eq i64 %24, 0 %25 = call i1 @llvm.expect.i1(i1 %not_err33, i1 true) br i1 %25, label %after_check35, label %assign_optional34 + assign_optional34: ; preds = %voiderr store i64 %24, ptr %error_var29, align 8 br label %guard_block36 + after_check35: ; preds = %voiderr br label %noerr_block37 + guard_block36: ; preds = %assign_optional34 br label %voiderr51 + noerr_block37: ; preds = %after_check35 %26 = load i64, ptr %retparam31, align 8 store i64 %26, ptr %len28, align 8 @@ -155,32 +180,42 @@ noerr_block37: ; preds = %after_check35 %not_err39 = icmp eq i64 %27, 0 %28 = call i1 @llvm.expect.i1(i1 %not_err39, i1 true) br i1 %28, label %after_check41, label %assign_optional40 + assign_optional40: ; preds = %noerr_block37 store i64 %27, ptr %error_var38, align 8 br label %guard_block42 + after_check41: ; preds = %noerr_block37 br label %noerr_block43 + guard_block42: ; preds = %assign_optional40 br label %voiderr51 + noerr_block43: ; preds = %after_check41 %29 = call i64 @std.io.File.flush(ptr %22) %not_err45 = icmp eq i64 %29, 0 %30 = call i1 @llvm.expect.i1(i1 %not_err45, i1 true) br i1 %30, label %after_check47, label %assign_optional46 + assign_optional46: ; preds = %noerr_block43 store i64 %29, ptr %error_var44, align 8 br label %guard_block48 + after_check47: ; preds = %noerr_block43 br label %noerr_block49 + guard_block48: ; preds = %assign_optional46 br label %voiderr51 + noerr_block49: ; preds = %after_check47 %31 = load i64, ptr %len28, align 8 %add50 = add i64 %31, 1 br label %voiderr51 + voiderr51: ; preds = %noerr_block49, %guard_block48, %guard_block42, %guard_block36 %32 = load i64, ptr %error_var, align 8 ret i64 %32 + noerr_block52: ; preds = %after_check7 %33 = load %"char[]", ptr %buffer, align 8 %34 = call ptr @std.io.stdout() @@ -190,13 +225,17 @@ noerr_block52: ; preds = %after_check7 %not_err58 = icmp eq i64 %36, 0 %37 = call i1 @llvm.expect.i1(i1 %not_err58, i1 true) br i1 %37, label %after_check60, label %assign_optional59 + assign_optional59: ; preds = %noerr_block52 store i64 %36, ptr %error_var54, align 8 br label %guard_block61 + after_check60: ; preds = %noerr_block52 br label %noerr_block62 + guard_block61: ; preds = %assign_optional59 br label %voiderr76 + noerr_block62: ; preds = %after_check60 %38 = load i64, ptr %retparam56, align 8 store i64 %38, ptr %len53, align 8 @@ -204,33 +243,43 @@ noerr_block62: ; preds = %after_check60 %not_err64 = icmp eq i64 %39, 0 %40 = call i1 @llvm.expect.i1(i1 %not_err64, i1 true) br i1 %40, label %after_check66, label %assign_optional65 + assign_optional65: ; preds = %noerr_block62 store i64 %39, ptr %error_var63, align 8 br label %guard_block67 + after_check66: ; preds = %noerr_block62 br label %noerr_block68 + guard_block67: ; preds = %assign_optional65 br label %voiderr76 + noerr_block68: ; preds = %after_check66 %41 = call i64 @std.io.File.flush(ptr %34) %not_err70 = icmp eq i64 %41, 0 %42 = call i1 @llvm.expect.i1(i1 %not_err70, i1 true) br i1 %42, label %after_check72, label %assign_optional71 + assign_optional71: ; preds = %noerr_block68 store i64 %41, ptr %error_var69, align 8 br label %guard_block73 + after_check72: ; preds = %noerr_block68 br label %noerr_block74 + guard_block73: ; preds = %assign_optional71 br label %voiderr76 + noerr_block74: ; preds = %after_check72 %43 = load i64, ptr %len53, align 8 %add75 = add i64 %43, 1 br label %voiderr76 + voiderr76: ; preds = %noerr_block74, %guard_block73, %guard_block67, %guard_block61 store %"char[]" %33, ptr %0, align 8 ret i64 0 } + ; Function Attrs: nounwind uwtable(sync) define void @test.main() #0 { entry: @@ -259,6 +308,7 @@ entry: call void @llvm.memcpy.p0.p0.i32(ptr align 8 %allocator1, ptr align 8 %allocator, i32 16, i1 false) call void @llvm.memcpy.p0.p0.i32(ptr align 8 %allocator2, ptr align 8 %allocator1, i32 16, i1 false) br label %if.exit + if.exit: ; preds = %entry %ptradd = getelementptr inbounds i8, ptr %allocator2, i64 8 %0 = load i64, ptr %ptradd, align 8 @@ -266,6 +316,7 @@ if.exit: ; preds = %entry %type = load ptr, ptr %.cachedtype, align 8 %2 = icmp eq ptr %1, %type br i1 %2, label %cache_hit, label %cache_miss + cache_miss: ; preds = %if.exit %ptradd3 = getelementptr inbounds i8, ptr %1, i64 16 %3 = load ptr, ptr %ptradd3, align 8 @@ -273,13 +324,16 @@ cache_miss: ; preds = %if.exit store ptr %4, ptr %.inlinecache, align 8 store ptr %1, ptr %.cachedtype, align 8 br label %5 + cache_hit: ; preds = %if.exit %cache_hit_fn = load ptr, ptr %.inlinecache, align 8 br label %5 + 5: ; preds = %cache_hit, %cache_miss %fn_phi = phi ptr [ %cache_hit_fn, %cache_hit ], [ %4, %cache_miss ] %6 = icmp eq ptr %fn_phi, null br i1 %6, label %missing_function, label %match + missing_function: ; preds = %5 store %"char[]" { ptr @.panic_msg, i64 44 }, ptr %taddr, align 8 %7 = load [2 x i64], ptr %taddr, align 8 @@ -288,17 +342,20 @@ missing_function: ; preds = %5 store %"char[]" { ptr @.func, i64 4 }, ptr %taddr5, align 8 %9 = load [2 x i64], ptr %taddr5, align 8 %10 = load ptr, ptr @std.core.builtin.panic, align 8 - call void %10([2 x i64] %7, [2 x i64] %8, [2 x i64] %9, i32 80) + call void %10([2 x i64] %7, [2 x i64] %8, [2 x i64] %9 unreachable + match: ; preds = %5 %11 = load ptr, ptr %allocator2, align 8 %12 = call i64 %fn_phi(ptr %retparam, ptr %11, i64 12, i32 1, i64 0) %not_err = icmp eq i64 %12, 0 %13 = call i1 @llvm.expect.i1(i1 %not_err, i1 true) br i1 %13, label %after_check, label %assign_optional + assign_optional: ; preds = %match store i64 %12, ptr %error_var, align 8 br label %panic_block + after_check: ; preds = %match %14 = load ptr, ptr %retparam, align 8 store ptr %14, ptr %taddr6, align 8 @@ -306,6 +363,7 @@ after_check: ; preds = %match %16 = insertvalue %"char[]" undef, ptr %15, 0 %17 = insertvalue %"char[]" %16, i64 12, 1 br label %noerr_block + panic_block: ; preds = %assign_optional %18 = insertvalue %any undef, ptr %error_var, 0 %19 = insertvalue %any %18, i64 ptrtoint (ptr @"$ct.anyfault" to i64), 1 @@ -320,8 +378,9 @@ panic_block: ; preds = %assign_optional %"$$temp" = insertvalue %"any[]" %23, i64 1, 1 store %"any[]" %"$$temp", ptr %taddr10, align 8 %24 = load [2 x i64], ptr %taddr10, align 8 - call void @std.core.builtin.panicf([2 x i64] %20, [2 x i64] %21, [2 x i64] %22, i32 244, [2 x i64] %24) + call void @std.core.builtin.panicf([2 x i64] %20, [2 x i64] %21, [2 x i64] %22 unreachable + noerr_block: ; preds = %after_check store %"char[]" %17, ptr %buffer, align 8 store i64 0, ptr %buffer.f, align 8 @@ -329,9 +388,11 @@ noerr_block: ; preds = %after_check %not_err11 = icmp eq i64 %optval, 0 %25 = call i1 @llvm.expect.i1(i1 %not_err11, i1 true) br i1 %25, label %after_check13, label %assign_optional12 + assign_optional12: ; preds = %noerr_block store i64 %optval, ptr %buffer.f, align 8 br label %after_assign + after_check13: ; preds = %noerr_block store %"char[]" { ptr @.str.5, i64 13 }, ptr %taddr15, align 8 %26 = load [2 x i64], ptr %taddr15, align 8 @@ -340,13 +401,16 @@ after_check13: ; preds = %noerr_block %not_err16 = icmp eq i64 %28, 0 %29 = call i1 @llvm.expect.i1(i1 %not_err16, i1 true) br i1 %29, label %after_check18, label %assign_optional17 + assign_optional17: ; preds = %after_check13 store i64 %28, ptr %buffer.f, align 8 br label %after_assign + after_check18: ; preds = %after_check13 call void @llvm.memcpy.p0.p0.i32(ptr align 8 %buffer, ptr align 8 %retparam14, i32 16, i1 false) store i64 0, ptr %buffer.f, align 8 br label %after_assign + after_assign: ; preds = %after_check18, %assign_optional17, %assign_optional12 ret void } diff --git a/test/test_suite/defer/defer_catch_try.c3t b/test/test_suite/defer/defer_catch_try.c3t index ff4c3e1ab..54bfbd64a 100644 --- a/test/test_suite/defer/defer_catch_try.c3t +++ b/test/test_suite/defer/defer_catch_try.c3t @@ -2,19 +2,17 @@ module test; extern fn void printf(char*, ...); -fault Abc -{ - FOO -} -fn int! abc(int x) +fault FOO; + +fn int? abc(int x) { printf("Enter abc\n"); defer catch printf("Abc catch %d\n", x); defer try printf("Abc try %d\n", x); defer printf("Abc normal %d\n", x); - return x > 0 ? Abc.FOO? : 0; + return x > 0 ? FOO? : 0; } -fn int! bcd(int x) +fn int? bcd(int x) { printf("Enter bcd\n"); for (int i = 0; i < 10; i++) @@ -25,7 +23,7 @@ fn int! bcd(int x) defer printf("Bcd %d normal %d\n", i, x); if (i == 1) continue; printf("bcd check\n"); - if (i == 2) return x > 0 ? Abc.FOO? : 0; + if (i == 2) return x > 0 ? FOO? : 0; } return 0; } @@ -50,7 +48,7 @@ entry: br i1 %gt, label %cond.lhs, label %cond.rhs cond.lhs: ; preds = %entry - store i64 ptrtoint (ptr @"test.Abc$FOO" to i64), ptr %reterr, align 8 + store i64 ptrtoint (ptr @test.FOO to i64), ptr %reterr, align 8 br label %err_retblock cond.rhs: ; preds = %entry @@ -107,7 +105,7 @@ if.then2: ; preds = %if.exit br i1 %gt, label %cond.lhs, label %cond.rhs cond.lhs: ; preds = %if.then2 - store i64 ptrtoint (ptr @"test.Abc$FOO" to i64), ptr %reterr, align 8 + store i64 ptrtoint (ptr @test.FOO to i64), ptr %reterr, align 8 br label %err_retblock cond.rhs: ; preds = %if.then2 diff --git a/test/test_suite/defer/defer_with_catch.c3t b/test/test_suite/defer/defer_with_catch.c3t index 88ed0c416..b02d97c31 100644 --- a/test/test_suite/defer/defer_with_catch.c3t +++ b/test/test_suite/defer/defer_with_catch.c3t @@ -1,7 +1,7 @@ // #target: macos-x64 module test; -fn void! test() {} +fn void? test() {} fn void main() { int a; diff --git a/test/test_suite/defer/defer_with_rethrow.c3 b/test/test_suite/defer/defer_with_rethrow.c3 index ace071375..e43e89472 100644 --- a/test/test_suite/defer/defer_with_rethrow.c3 +++ b/test/test_suite/defer/defer_with_rethrow.c3 @@ -1,8 +1,8 @@ -fn int! foo() +fn int? foo() { return 1; } -fn int! bar() +fn int? bar() { defer { foo()!!; diff --git a/test/test_suite/defer/defer_with_return.c3 b/test/test_suite/defer/defer_with_return.c3 index 4c0c6f06c..b46e0e391 100644 --- a/test/test_suite/defer/defer_with_return.c3 +++ b/test/test_suite/defer/defer_with_return.c3 @@ -1,4 +1,4 @@ -fn int! bar() +fn int? bar() { defer return 3; // #error: Return is not allowed inside of a defer return 1; diff --git a/test/test_suite/defer/defer_with_unwrapped.c3t b/test/test_suite/defer/defer_with_unwrapped.c3t index 365c86a9a..4b8f80da2 100644 --- a/test/test_suite/defer/defer_with_unwrapped.c3t +++ b/test/test_suite/defer/defer_with_unwrapped.c3t @@ -6,7 +6,7 @@ fn int main() { defer { - int! x = 1; + int? x = 1; if (catch err = x) unreachable(); int y = x; } diff --git a/test/test_suite/define/forbidden_defines.c3 b/test/test_suite/define/forbidden_defines.c3 index 82c82f2df..67607c812 100644 --- a/test/test_suite/define/forbidden_defines.c3 +++ b/test/test_suite/define/forbidden_defines.c3 @@ -1,3 +1,3 @@ -def Abc = int[?]; // #error: Inferred array types can only +def Abc = int[*]; // #error: Inferred array types can only def Bcd = anyfault; def Efd = any; diff --git a/test/test_suite/distinct/distinct_invalid.c3 b/test/test_suite/distinct/distinct_invalid.c3 index 0e5759dfb..7086142ea 100644 --- a/test/test_suite/distinct/distinct_invalid.c3 +++ b/test/test_suite/distinct/distinct_invalid.c3 @@ -1,7 +1,4 @@ -fault Error -{ - ABC -} +fault ABC; distinct Foo1 = Error; diff --git a/test/test_suite/dynamic/any_cast.c3 b/test/test_suite/dynamic/any_cast.c3 index 85727eac8..dc093e30b 100644 --- a/test/test_suite/dynamic/any_cast.c3 +++ b/test/test_suite/dynamic/any_cast.c3 @@ -6,14 +6,14 @@ interface Abc : Def interface Def {} -fn void! test() +fn void? test() { any x; Abc d = x; // #error: cannot implicitly be converted to 'Abc' } -fn void! test2() +fn void? test2() { Abc x; any d = x; diff --git a/test/test_suite/dynamic/dynamic_mismatch.c3 b/test/test_suite/dynamic/dynamic_mismatch.c3 index b259a872a..119d553c3 100644 --- a/test/test_suite/dynamic/dynamic_mismatch.c3 +++ b/test/test_suite/dynamic/dynamic_mismatch.c3 @@ -6,7 +6,7 @@ interface TestProto struct Foo (TestProto) { int a; } -fn int! Foo.test(Foo* f) @dynamic { return 1; } // #error: The prototype method has a return type 'int' +fn int? Foo.test(Foo* f) @dynamic { return 1; } // #error: The prototype method has a return type 'int' struct Foo1 (TestProto) { int a; } diff --git a/test/test_suite/dynamic/dynamic_tracing.c3t b/test/test_suite/dynamic/dynamic_tracing.c3t index eb6cb6b86..780e5eb6e 100644 --- a/test/test_suite/dynamic/dynamic_tracing.c3t +++ b/test/test_suite/dynamic/dynamic_tracing.c3t @@ -58,9 +58,9 @@ fn void main() { /* #expect: test.ll -@"$ct.test.Aa" = linkonce global %.introspect { i8 10, i64 0, ptr null, i64 4, i64 0, i64 1, [0 x i64] zeroinitializer }, align 8 -@"$ct.test.Ba" = linkonce global %.introspect { i8 10, i64 0, ptr null, i64 4, i64 0, i64 1, [0 x i64] zeroinitializer }, align 8 -@"$ct.test.Ca" = linkonce global %.introspect { i8 10, i64 0, ptr null, i64 4, i64 0, i64 1, [0 x i64] zeroinitializer }, align 8 +@"$ct.test.Aa" = linkonce global %.introspect { i8 9, i64 0, ptr null, i64 4, i64 0, i64 1, [0 x i64] zeroinitializer }, align 8 +@"$ct.test.Ba" = linkonce global %.introspect { i8 9, i64 0, ptr null, i64 4, i64 0, i64 1, [0 x i64] zeroinitializer }, align 8 +@"$ct.test.Ca" = linkonce global %.introspect { i8 9, i64 0, ptr null, i64 4, i64 0, i64 1, [0 x i64] zeroinitializer }, align 8 @"$sel.foo" = linkonce_odr constant [4 x i8] c"foo\00", align 1 @"$c3_dynamic" = internal global [3 x { ptr, ptr, i64 }] [{ ptr, ptr, i64 } { ptr @test.Aa.foo, ptr @"$sel.foo", i64 ptrtoint (ptr @"$ct.test.Aa" to i64) }, { ptr, ptr, i64 } { ptr @test.Ba.foo, ptr @"$sel.foo", i64 ptrtoint (ptr @"$ct.test.Ba" to i64) }, { ptr, ptr, i64 } { ptr @test.Ca.foo, ptr @"$sel.foo", i64 ptrtoint (ptr @"$ct.test.Ca" to i64) }], section "__DATA,__c3_dynamic", no_sanitize_address, align 8 @llvm.global_ctors = appending global [1 x { i32, ptr, ptr }] [{ i32, ptr, ptr } { i32 1, ptr @.c3_dynamic_retain, ptr null }], no_sanitize_address diff --git a/test/test_suite/dynamic/inherit_linux.c3t b/test/test_suite/dynamic/inherit_linux.c3t index 3ce011da0..c14d0f753 100644 --- a/test/test_suite/dynamic/inherit_linux.c3t +++ b/test/test_suite/dynamic/inherit_linux.c3t @@ -45,7 +45,7 @@ $.dyn_search = comdat any $"$ct.inherit.Test" = comdat any $"$sel.tesT" = comdat any $"$sel.hello" = comdat any -@"$ct.inherit.Test" = linkonce global %.introspect { i8 10, i64 0, ptr null, i64 8, i64 0, i64 1, [0 x i64] zeroinitializer }, comdat, align 8 +@"$ct.inherit.Test" = linkonce global %.introspect { i8 9, i64 0, ptr null, i64 8, i64 0, i64 1, [0 x i64] zeroinitializer }, comdat, align 8 @"$sel.tesT" = linkonce_odr constant [5 x i8] c"tesT\00", comdat, align 1 @.panic_msg = internal constant [42 x i8] c"No method 'tesT' could be found on target\00", align 1 @.func = internal constant [5 x i8] c"main\00", align 1 diff --git a/test/test_suite/dynamic/inherit_macos.c3t b/test/test_suite/dynamic/inherit_macos.c3t index 792f9b960..eb7c608d7 100644 --- a/test/test_suite/dynamic/inherit_macos.c3t +++ b/test/test_suite/dynamic/inherit_macos.c3t @@ -42,7 +42,7 @@ fn void main() %.introspect = type { i8, i64, ptr, i64, i64, i64, [0 x i64] } %any = type { ptr, i64 } -@"$ct.inherit.Test" = linkonce global %.introspect { i8 10, i64 0, ptr null, i64 8, i64 0, i64 1, [0 x i64] zeroinitializer }, align 8 +@"$ct.inherit.Test" = linkonce global %.introspect { i8 9, i64 0, ptr null, i64 8, i64 0, i64 1, [0 x i64] zeroinitializer }, align 8 @"$sel.tesT" = linkonce_odr constant [5 x i8] c"tesT\00", align 1 @.panic_msg = internal constant [42 x i8] c"No method 'tesT' could be found on target\00", align 1 @.func = internal constant [5 x i8] c"main\00", align 1 diff --git a/test/test_suite/dynamic/overlapping_function_linux.c3t b/test/test_suite/dynamic/overlapping_function_linux.c3t index 05c63b4df..851028955 100644 --- a/test/test_suite/dynamic/overlapping_function_linux.c3t +++ b/test/test_suite/dynamic/overlapping_function_linux.c3t @@ -35,7 +35,8 @@ fn void main() %.introspect = type { i8, i64, ptr, i64, i64, i64, [0 x i64] } %any = type { ptr, i64 } -@"$ct.overlap.Test" = linkonce global %.introspect { i8 10, i64 0, ptr null, i64 8, i64 0, i64 1, [0 x i64] zeroinitializer }, comdat, align 8 + +@"$ct.overlap.Test" = linkonce global %.introspect { i8 9, i64 0, ptr null, i64 8, i64 0, i64 1, [0 x i64] zeroinitializer }, comdat, align 8 @"$sel.tesT" = linkonce_odr constant [5 x i8] c"tesT\00", comdat, align 1 @.panic_msg = internal constant [42 x i8] c"No method 'tesT' could be found on target\00", align 1 @.file = internal constant [30 x i8] c"overlapping_function_linux.c3\00", align 1 diff --git a/test/test_suite/dynamic/overlapping_function_macos.c3t b/test/test_suite/dynamic/overlapping_function_macos.c3t index 4d9d33473..51117b75b 100644 --- a/test/test_suite/dynamic/overlapping_function_macos.c3t +++ b/test/test_suite/dynamic/overlapping_function_macos.c3t @@ -35,7 +35,7 @@ fn void main() %.introspect = type { i8, i64, ptr, i64, i64, i64, [0 x i64] } %any = type { ptr, i64 } -@"$ct.overlap.Test" = linkonce global %.introspect { i8 10, i64 0, ptr null, i64 8, i64 0, i64 1, [0 x i64] zeroinitializer }, align 8 +@"$ct.overlap.Test" = linkonce global %.introspect { i8 9, i64 0, ptr null, i64 8, i64 0, i64 1, [0 x i64] zeroinitializer }, align 8 @"$sel.tesT" = linkonce_odr constant [5 x i8] c"tesT\00", align 1 @.panic_msg = internal constant [42 x i8] c"No method 'tesT' could be found on target\00", align 1 @.file = internal constant [30 x i8] c"overlapping_function_macos.c3\00", align 1 diff --git a/test/test_suite/embed/embed_basic.c3t b/test/test_suite/embed/embed_basic.c3t index c8a182f0a..253054915 100644 --- a/test/test_suite/embed/embed_basic.c3t +++ b/test/test_suite/embed/embed_basic.c3t @@ -3,19 +3,19 @@ module testing; fn void main() { - char[?] data = $embed("embed_basic.c3"); + char[*] data = $embed("embed_basic.c3"); char* data2 = $embed("embed_basic.c3"); char[] data3 = $embed("embed_basic.c3"); char* data4 = $embed("fiek") ?? null; - char*! data5 = $embed("fiek"); + char*? data5 = $embed("fiek"); } /* #expect: testing.ll -@.bytes = private unnamed_addr constant [234 x i8] c"module testing;\0A\0Afn void main()\0A{\0A\09char[?] data = $embed(\22embed_basic.c3\22);\0A\09char* data2 = $embed(\22embed_basic.c3\22);\0A\09char[] data3 = $embed(\22embed_basic.c3\22);\0A\09char* data4 = $embed(\22fiek\22) ?? null;\0A\09char*! data5 = $embed(\22fiek\22);\0A}\0A\0A\00", align 1 -@.bytes.1 = private unnamed_addr constant [234 x i8] c"module testing;\0A\0Afn void main()\0A{\0A\09char[?] data = $embed(\22embed_basic.c3\22);\0A\09char* data2 = $embed(\22embed_basic.c3\22);\0A\09char[] data3 = $embed(\22embed_basic.c3\22);\0A\09char* data4 = $embed(\22fiek\22) ?? null;\0A\09char*! data5 = $embed(\22fiek\22);\0A}\0A\0A\00", align 1 -@.bytes.2 = private unnamed_addr constant [234 x i8] c"module testing;\0A\0Afn void main()\0A{\0A\09char[?] data = $embed(\22embed_basic.c3\22);\0A\09char* data2 = $embed(\22embed_basic.c3\22);\0A\09char[] data3 = $embed(\22embed_basic.c3\22);\0A\09char* data4 = $embed(\22fiek\22) ?? null;\0A\09char*! data5 = $embed(\22fiek\22);\0A}\0A\0A\00", align 1 +@.bytes = private unnamed_addr constant [234 x i8] c"module testing;\0A\0Afn void main()\0A{\0A\09char[*] data = $embed(\22embed_basic.c3\22);\0A\09char* data2 = $embed(\22embed_basic.c3\22);\0A\09char[] data3 = $embed(\22embed_basic.c3\22);\0A\09char* data4 = $embed(\22fiek\22) ?? null;\0A\09char*? data5 = $embed(\22fiek\22);\0A}\0A\0A\00", align 1 +@.bytes.1 = private unnamed_addr constant [234 x i8] c"module testing;\0A\0Afn void main()\0A{\0A\09char[*] data = $embed(\22embed_basic.c3\22);\0A\09char* data2 = $embed(\22embed_basic.c3\22);\0A\09char[] data3 = $embed(\22embed_basic.c3\22);\0A\09char* data4 = $embed(\22fiek\22) ?? null;\0A\09char*? data5 = $embed(\22fiek\22);\0A}\0A\0A\00", align 1 +@.bytes.2 = private unnamed_addr constant [234 x i8] c"module testing;\0A\0Afn void main()\0A{\0A\09char[*] data = $embed(\22embed_basic.c3\22);\0A\09char* data2 = $embed(\22embed_basic.c3\22);\0A\09char[] data3 = $embed(\22embed_basic.c3\22);\0A\09char* data4 = $embed(\22fiek\22) ?? null;\0A\09char*? data5 = $embed(\22fiek\22);\0A}\0A\0A\00", align 1 define void @testing.main() #0 { entry: @@ -29,6 +29,6 @@ entry: store ptr @.bytes.1, ptr %data2, align 8 store %"char[]" { ptr @.bytes.2 store ptr null, ptr %data4, align 8 - store i64 ptrtoint (ptr @"std.io.IoError$FILE_NOT_FOUND" to i64), ptr %data5.f, align 8 + store i64 ptrtoint (ptr @std.io.FILE_NOT_FOUND to i64), ptr %data5.f, align 8 ret void } \ No newline at end of file diff --git a/test/test_suite/enumerations/enum_associated_values_other.c3t b/test/test_suite/enumerations/enum_associated_values_other.c3t index 02fe8fe60..6edd29cf7 100644 --- a/test/test_suite/enumerations/enum_associated_values_other.c3t +++ b/test/test_suite/enumerations/enum_associated_values_other.c3t @@ -26,7 +26,8 @@ enum Foo : int (String val) %.introspect = type { i8, i64, ptr, i64, i64, i64, [0 x i64] } %"char[]" = type { ptr, i64 } -@"$ct.abc.Abc" = linkonce global %.introspect { i8 10, i64 0, ptr null, i64 4, i64 0, i64 1, [0 x i64] zeroinitializer }, align 8 + +@"$ct.abc.Abc" = linkonce global %.introspect { i8 9, i64 0, ptr null, i64 4, i64 0, i64 1, [0 x i64] zeroinitializer }, align 8 @.enum.ABC = internal constant [4 x i8] c"ABC\00", align 1 @.enum.DEF = internal constant [4 x i8] c"DEF\00", align 1 @"$ct.int" = linkonce global %.introspect { i8 2, i64 0, ptr null, i64 4, i64 0, i64 0, [0 x i64] zeroinitializer }, align 8 diff --git a/test/test_suite/enumerations/enum_cast.c3t b/test/test_suite/enumerations/enum_cast.c3t index ff076c2f5..30d626ab3 100644 --- a/test/test_suite/enumerations/enum_cast.c3t +++ b/test/test_suite/enumerations/enum_cast.c3t @@ -27,8 +27,8 @@ fn void test() bool hello = (bool)MyEnum.FOO.ordinal; var $d = (float)MyEnum.FOO.ordinal; var $hello = (bool)MyEnum.FOO.ordinal; - MyEnum! xf = MyEnum.BAR; - float! e = (float)x.ordinal; + MyEnum? xf = MyEnum.BAR; + float? e = (float)x.ordinal; e = (float)xf.ordinal; } diff --git a/test/test_suite/enumerations/enum_recursive.c3 b/test/test_suite/enumerations/enum_recursive.c3 new file mode 100644 index 000000000..a7dfcf129 --- /dev/null +++ b/test/test_suite/enumerations/enum_recursive.c3 @@ -0,0 +1,17 @@ +module test; + +enum Bar : (Foo x) +{ + ABC = BAR +} + +enum Foo : (Bar b, Foo a) +{ + FOO = { ABC, BAR }, + BAR = { ABC, BAR } +} + +fn void main() +{ + Foo x = BAR; +} \ No newline at end of file diff --git a/test/test_suite/errors/anyfault_void.c3t b/test/test_suite/errors/anyfault_void.c3t index 0925f1b23..2293cd8d8 100644 --- a/test/test_suite/errors/anyfault_void.c3t +++ b/test/test_suite/errors/anyfault_void.c3t @@ -1,14 +1,11 @@ -fault MyError +fault FOO, BAR; + +fn void? errorThing() { - FOO, - BAR -} -fn void! errorThing() -{ - return MyError.BAR?; + return BAR?; } -fn void! errorThing2() +fn void? errorThing2() { return; } @@ -18,8 +15,8 @@ fn void main() { anyfault z = @catch(errorThing()); printf("Z; %llx\n", (iptr)(z)); - printf("BAR: %llx\n", (iptr)(MyError.BAR)); - printf("FOO: %llx\n", (iptr)(MyError.FOO)); + printf("BAR: %llx\n", (iptr)(BAR)); + printf("FOO: %llx\n", (iptr)(FOO)); z = @catch(errorThing2()); printf("Z2: %llx\n", (iptr)(z)); } @@ -28,7 +25,7 @@ fn void main() define i64 @anyfault_void.errorThing() #0 { entry: - ret i64 ptrtoint (ptr @"anyfault_void.MyError$BAR" to i64) + ret i64 ptrtoint (ptr @anyfault_void.BAR to i64) } define i64 @anyfault_void.errorThing2() #0 { @@ -47,62 +44,76 @@ entry: %blockret1 = alloca i64, align 8 %f2 = alloca i64, align 8 br label %testblock + testblock: ; preds = %entry %0 = call i64 @anyfault_void.errorThing() %not_err = icmp eq i64 %0, 0 %1 = call i1 @llvm.expect.i1(i1 %not_err, i1 true) br i1 %1, label %after_check, label %assign_optional + assign_optional: ; preds = %testblock store i64 %0, ptr %f, align 8 br label %end_block + after_check: ; preds = %testblock store i64 0, ptr %f, align 8 br label %end_block + end_block: ; preds = %after_check, %assign_optional %2 = load i64, ptr %f, align 8 %i2b = icmp ne i64 %2, 0 br i1 %i2b, label %if.then, label %if.exit + if.then: ; preds = %end_block %3 = load i64, ptr %f, align 8 store i64 %3, ptr %blockret, align 8 br label %expr_block.exit + if.exit: ; preds = %end_block store i64 0, ptr %blockret, align 8 br label %expr_block.exit + expr_block.exit: ; preds = %if.exit, %if.then %4 = load i64, ptr %blockret, align 8 store i64 %4, ptr %z, align 8 %5 = load i64, ptr %z, align 8 call void (ptr, ...) @printf(ptr @.str, i64 %5) - call void (ptr, ...) @printf(ptr @.str.2, i64 ptrtoint (ptr @"anyfault_void.MyError$BAR" to i64)) - call void (ptr, ...) @printf(ptr @.str.3, i64 ptrtoint (ptr @"anyfault_void.MyError$FOO" to i64)) + call void (ptr, ...) @printf(ptr @.str.1, i64 ptrtoint (ptr @anyfault_void.BAR to i64)) + call void (ptr, ...) @printf(ptr @.str.2, i64 ptrtoint (ptr @anyfault_void.FOO to i64)) br label %testblock3 + testblock3: ; preds = %expr_block.exit %6 = call i64 @anyfault_void.errorThing2() %not_err4 = icmp eq i64 %6, 0 %7 = call i1 @llvm.expect.i1(i1 %not_err4, i1 true) br i1 %7, label %after_check6, label %assign_optional5 + assign_optional5: ; preds = %testblock3 store i64 %6, ptr %f2, align 8 br label %end_block7 + after_check6: ; preds = %testblock3 store i64 0, ptr %f2, align 8 br label %end_block7 + end_block7: ; preds = %after_check6, %assign_optional5 %8 = load i64, ptr %f2, align 8 %i2b8 = icmp ne i64 %8, 0 br i1 %i2b8, label %if.then9, label %if.exit10 + if.then9: ; preds = %end_block7 %9 = load i64, ptr %f2, align 8 store i64 %9, ptr %blockret1, align 8 br label %expr_block.exit11 + if.exit10: ; preds = %end_block7 store i64 0, ptr %blockret1, align 8 br label %expr_block.exit11 + expr_block.exit11: ; preds = %if.exit10, %if.then9 %10 = load i64, ptr %blockret1, align 8 store i64 %10, ptr %z, align 8 %11 = load i64, ptr %z, align 8 - call void (ptr, ...) @printf(ptr @.str.4, i64 %11) + call void (ptr, ...) @printf(ptr @.str.3, i64 %11) ret void } \ No newline at end of file diff --git a/test/test_suite/errors/bitshift_failable.c3 b/test/test_suite/errors/bitshift_failable.c3 index 61ab084c9..ad5304faa 100644 --- a/test/test_suite/errors/bitshift_failable.c3 +++ b/test/test_suite/errors/bitshift_failable.c3 @@ -1,5 +1,5 @@ fn void test() { - int! x = 0; - int! z = x << 100; // #error: the bitsize of 'int' + int? x = 0; + int? z = x << 100; // #error: the bitsize of 'int' } \ No newline at end of file diff --git a/test/test_suite/errors/else_checks.c3t b/test/test_suite/errors/else_checks.c3t index 26a4e405d..3bf75d75f 100644 --- a/test/test_suite/errors/else_checks.c3t +++ b/test/test_suite/errors/else_checks.c3t @@ -1,6 +1,6 @@ // #target: macos-x64 -extern fn int! testError(); +extern fn int? testError(); fn void test() { diff --git a/test/test_suite/errors/else_struct.c3t b/test/test_suite/errors/else_struct.c3t index b12f4513d..e9f6dac85 100644 --- a/test/test_suite/errors/else_struct.c3t +++ b/test/test_suite/errors/else_struct.c3t @@ -7,8 +7,8 @@ struct Foo fn void test() { - int! a = 0; - Foo! b = {}; + int? a = 0; + Foo? b = {}; Foo c; int e = a ?? 1; diff --git a/test/test_suite/errors/empty_fault.c3 b/test/test_suite/errors/empty_fault.c3 index 855ecfbb5..08a98a186 100644 --- a/test/test_suite/errors/empty_fault.c3 +++ b/test/test_suite/errors/empty_fault.c3 @@ -1,4 +1,2 @@ module test; -fault Foo -{ -} // #error: no values \ No newline at end of file +fault; // #error: Expected diff --git a/test/test_suite/errors/error_decl_ok.c3 b/test/test_suite/errors/error_decl_ok.c3 index a17338068..f24be2c26 100644 --- a/test/test_suite/errors/error_decl_ok.c3 +++ b/test/test_suite/errors/error_decl_ok.c3 @@ -1,19 +1,9 @@ module errors; -fault TheError -{ - A -} +fault A; -fault TheError2 -{ - A, - B -} +fault A2, B2; -fault TheError3 -{ - C, D -} +fault C, D; diff --git a/test/test_suite/errors/error_else.c3t b/test/test_suite/errors/error_else.c3t index c818323fd..77b8dba67 100644 --- a/test/test_suite/errors/error_else.c3t +++ b/test/test_suite/errors/error_else.c3t @@ -1,22 +1,19 @@ module foo; -fault Baz -{ - TEST -} +fault TEST; module bar; import foo; -fn int! abc() +fn int? abc() { - return Baz.TEST?; + return foo::TEST?; } module baz; import foo; -fn int! abc() +fn int? abc() { - return Baz.TEST?; + return foo::TEST?; } diff --git a/test/test_suite/errors/error_introspect.c3t b/test/test_suite/errors/error_introspect.c3t deleted file mode 100644 index 9dd2e1bf6..000000000 --- a/test/test_suite/errors/error_introspect.c3t +++ /dev/null @@ -1,72 +0,0 @@ -// #target: macos-x64 -module foo; -import std::io; - -fault Foo -{ - BAR, - BAZ -} - -fn void main() -{ - String[] x = Foo.names; - io::printfn("Foo.names: %s", x); - io::printfn("Foo.values: %s", Foo.values); - io::printfn("Foo.elements: %s", Foo.elements); -} - -/* #expect: foo.ll - -@"foo.Foo$BAR" = linkonce constant %.fault { i64 ptrtoint (ptr @"$ct.foo.Foo" to i64), %"char[]" { ptr @.fault, i64 3 }, i64 1 }, align 8 -@.fault = internal constant [4 x i8] c"BAR\00", align 1 -@"foo.Foo$BAZ" = linkonce constant %.fault { i64 ptrtoint (ptr @"$ct.foo.Foo" to i64), %"char[]" { ptr @.fault.1, i64 3 }, i64 2 }, align 8 -@.fault.1 = internal constant [4 x i8] c"BAZ\00", align 1 -@"$ct.foo.Foo" = linkonce global %.introspect { i8 9, i64 0, ptr null, i64 8, i64 0, i64 2, [0 x i64] zeroinitializer }, align 8 -@.str = private unnamed_addr constant [4 x i8] c"BAR\00", align 1 -@.str.2 = private unnamed_addr constant [4 x i8] c"BAZ\00", align 1 -@.__const = private unnamed_addr constant [2 x %"char[]"] [%"char[]" { ptr @.str, i64 3 }, %"char[]" { ptr @.str.2, i64 3 }], align 16 -@.str.3 = private unnamed_addr constant [14 x i8] c"Foo.names: %s\00", align 1 -@"$ct.sa$String" = linkonce global %.introspect { i8 16, i64 0, ptr null, i64 16, i64 ptrtoint (ptr @"$ct.String" to i64), i64 0, [0 x i64] zeroinitializer }, align 8 -@"$ct.String" = linkonce global %.introspect { i8 18, i64 ptrtoint (ptr @"$ct.sa$char" to i64), ptr null, i64 16, i64 ptrtoint (ptr @"$ct.sa$char" to i64), i64 0, [0 x i64] zeroinitializer }, align 8 -@"$ct.sa$char" = linkonce global %.introspect { i8 16, i64 0, ptr null, i64 16, i64 ptrtoint (ptr @"$ct.char" to i64), i64 0, [0 x i64] zeroinitializer }, align 8 -@"$ct.char" = linkonce global %.introspect { i8 3, i64 0, ptr null, i64 1, i64 0, i64 0, [0 x i64] zeroinitializer }, align 8 -@.str.4 = private unnamed_addr constant [15 x i8] c"Foo.values: %s\00", align 1 -@.__const.5 = private unnamed_addr constant [2 x i64] [i64 ptrtoint (ptr @"foo.Foo$BAR" to i64), i64 ptrtoint (ptr @"foo.Foo$BAZ" to i64)], align 16 -@"$ct.a2$foo.Foo" = linkonce global %.introspect { i8 15, i64 0, ptr null, i64 16, i64 ptrtoint (ptr @"$ct.foo.Foo" to i64), i64 2, [0 x i64] zeroinitializer }, align 8 -@.str.6 = private unnamed_addr constant [17 x i8] c"Foo.elements: %s\00", align 1 -@"$ct.long" = linkonce global %.introspect { i8 2, i64 0, ptr null, i64 8, i64 0, i64 0, [0 x i64] zeroinitializer }, align 8 - -; Function Attrs: -define void @foo.main() #0 { -entry: - %x = alloca %"char[][]", align 8 - %literal = alloca [2 x %"char[]"], align 16 - %varargslots = alloca [1 x %any], align 16 - %retparam = alloca i64, align 8 - %varargslots1 = alloca [1 x %any], align 16 - %literal2 = alloca [2 x i64], align 16 - %retparam3 = alloca i64, align 8 - %varargslots4 = alloca [1 x %any], align 16 - %taddr = alloca i64, align 8 - %retparam5 = alloca i64, align 8 - call void @llvm.memcpy.p0.p0.i32(ptr align 8 %literal, ptr align 16 @.__const, i32 32, i1 false) - %0 = insertvalue %"char[][]" undef, ptr %literal, 0 - %1 = insertvalue %"char[][]" %0, i64 2, 1 - store %"char[][]" %1, ptr %x, align 8 - %2 = insertvalue %any undef, ptr %x, 0 - %3 = insertvalue %any %2, i64 ptrtoint (ptr @"$ct.sa$String" to i64), 1 - store %any %3, ptr %varargslots, align 16 - %4 = call i64 @std.io.printfn(ptr %retparam, ptr @.str.3, i64 13, ptr %varargslots, i64 1) - call void @llvm.memcpy.p0.p0.i32(ptr align 8 %literal2, ptr align 16 @.__const.5, i32 16, i1 false) - %5 = insertvalue %any undef, ptr %literal2, 0 - %6 = insertvalue %any %5, i64 ptrtoint (ptr @"$ct.a2$foo.Foo" to i64), 1 - store %any %6, ptr %varargslots1, align 16 - %7 = call i64 @std.io.printfn(ptr %retparam3, ptr @.str.4, i64 14, ptr %varargslots1, i64 1) - store i64 2, ptr %taddr, align 8 - %8 = insertvalue %any undef, ptr %taddr, 0 - %9 = insertvalue %any %8, i64 ptrtoint (ptr @"$ct.long" to i64), 1 - store %any %9, ptr %varargslots4, align 16 - %10 = call i64 @std.io.printfn(ptr %retparam5, ptr @.str.6, i64 16, ptr %varargslots4, i64 1) - ret void -} diff --git a/test/test_suite/errors/error_regression_2.c3t b/test/test_suite/errors/error_regression_2.c3t index 12649f621..df2f3ab7c 100644 --- a/test/test_suite/errors/error_regression_2.c3t +++ b/test/test_suite/errors/error_regression_2.c3t @@ -40,27 +40,23 @@ fn bool contains(char[] haystack, char[] needle) macro dupe(value) { $typeof(&value) temp = malloc($sizeof(value)); - if (!temp) return ReadError.OUT_OF_MEMORY?; + if (!temp) return OUT_OF_MEMORY?; *temp = value; return temp; } -fault ReadError -{ - BAD_READ, - OUT_OF_MEMORY -} +fault BAD_READ, OUT_OF_MEMORY; -fn Doc! readDoc(char[] url) +fn Doc? readDoc(char[] url) { - if (contains(url, "fail")) return ReadError.BAD_READ?; + if (contains(url, "fail")) return BAD_READ?; if (contains(url, "head-missing")) return { .head = null }; if (contains(url, "title-missing")) return { dupe((Head) { .title = null })! }; if (contains(url, "title-empty")) return { dupe((Head) { .title = dupe((char[])"")! })! }; // Not particularly elegant due to missing string functions. isz len = libc::snprintf(null, 0, "Title of %.*s", (int)url.len, url.ptr); char* str = malloc(len + 1); - if (!str) return ReadError.OUT_OF_MEMORY?; + if (!str) return OUT_OF_MEMORY?; libc::snprintf(str, len + 1, "Title of %.*s", (int)url.len, url.ptr); return { dupe((Head) { .title = dupe(str[..len - 1])! })! }; } @@ -89,21 +85,18 @@ fn Summary readAndBuildSummary(char[] url) } -fault TitleResult -{ - TITLE_MISSING -} +fault TITLE_MISSING; -fn bool! isTitleNonEmpty(Doc doc) +fn bool? isTitleNonEmpty(Doc doc) { - if (!doc.head) return TitleResult.TITLE_MISSING?; + if (!doc.head) return TITLE_MISSING?; char[]* head = doc.head.title; - if (!head) return TitleResult.TITLE_MISSING?; + if (!head) return TITLE_MISSING?; return (*head).len > 0; } -fn bool! readWhetherTitleNonEmpty(char[] url) +fn bool? readWhetherTitleNonEmpty(char[] url) { return isTitleNonEmpty(readDoc(url)); } @@ -116,11 +109,11 @@ fn char* nameFromError(anyfault e) { switch (e) { - case TitleResult.TITLE_MISSING: + case TITLE_MISSING: return "no title"; - case ReadError.BAD_READ: + case BAD_READ: return "bad read"; - case ReadError.OUT_OF_MEMORY: + case OUT_OF_MEMORY: return "out of memory"; default: return "unknown error"; @@ -141,7 +134,7 @@ fn void main() libc::printf("\n"); char[] title_sure = summary.title ? *summary.title : ""; libc::printf(" Title: %.*s\n", (int)title_sure.len, title_sure.ptr); - bool! has_title = readWhetherTitleNonEmpty(url); + bool? has_title = readWhetherTitleNonEmpty(url); // This looks a bit less than elegant, but as you see it's mostly due to having to // use printf here. libc::printf(" Has title: %s vs %s\n", bool_to_string(has_title) ?? nameFromError(@catch(has_title)), (has_title ?? false) ? (char*)"true" : (char*)"false"); @@ -166,7 +159,7 @@ cond.rhs: ; preds = %entry br label %cond.phi cond.phi: ; preds = %cond.rhs, %cond.lhs - %val = phi %"char[]" [ %4, %cond.lhs ], [ { ptr @.str.28, i64 7 }, %cond.rhs ] + %val = phi %"char[]" [ %4, %cond.lhs ], [ { ptr @.str.26, i64 7 }, %cond.rhs ] store %"char[]" %val, ptr %title, align 8 %ptradd = getelementptr inbounds i8, ptr %title, i64 8 %5 = load i64, ptr %ptradd, align 8 @@ -174,9 +167,9 @@ cond.phi: ; preds = %cond.rhs, %cond.lhs %ptradd1 = getelementptr inbounds i8, ptr %0, i64 8 %6 = load i8, ptr %ptradd1, align 8 %7 = trunc i8 %6 to i1 - %ternary = select i1 %7, ptr @.str.30, ptr @.str.31 + %ternary = select i1 %7, ptr @.str.28, ptr @.str.29 %8 = load ptr, ptr %title, align 8 - %9 = call i32 (ptr, ptr, ...) @fprintf(ptr %1, ptr @.str.29, i32 %trunc, ptr %8, ptr %ternary) + %9 = call i32 (ptr, ptr, ...) @fprintf(ptr %1, ptr @.str.27, i32 %trunc, ptr %8, ptr %ternary) ret void } @@ -297,13 +290,13 @@ entry: br i1 %4, label %if.then, label %if.exit if.then: ; preds = %entry - ret i64 ptrtoint (ptr @"test.ReadError$BAD_READ" to i64) + ret i64 ptrtoint (ptr @test.BAD_READ to i64) if.exit: ; preds = %entry %lo2 = load ptr, ptr %url, align 8 %ptradd3 = getelementptr inbounds i8, ptr %url, i64 8 %hi4 = load i64, ptr %ptradd3, align 8 - %5 = call i8 @test.contains(ptr %lo2, i64 %hi4, ptr @.str.3, i64 12) + %5 = call i8 @test.contains(ptr %lo2, i64 %hi4, ptr @.str.1, i64 12) %6 = trunc i8 %5 to i1 br i1 %6, label %if.then5, label %if.exit6 @@ -316,12 +309,12 @@ if.exit6: ; preds = %if.exit %lo7 = load ptr, ptr %url, align 8 %ptradd8 = getelementptr inbounds i8, ptr %url, i64 8 %hi9 = load i64, ptr %ptradd8, align 8 - %7 = call i8 @test.contains(ptr %lo7, i64 %hi9, ptr @.str.4, i64 13) + %7 = call i8 @test.contains(ptr %lo7, i64 %hi9, ptr @.str.2, i64 13) %8 = trunc i8 %7 to i1 br i1 %8, label %if.then10, label %if.exit16 if.then10: ; preds = %if.exit6 - call void @llvm.memcpy.p0.p0.i32(ptr align 8 %literal13, ptr align 8 @.__const.5, i32 8, i1 false) + call void @llvm.memcpy.p0.p0.i32(ptr align 8 %literal13, ptr align 8 @.__const.3, i32 8, i1 false) call void @llvm.memcpy.p0.p0.i32(ptr align 8 %value, ptr align 8 %literal13, i32 8, i1 false) %9 = call ptr @std.core.mem.malloc(i64 8) #3 store ptr %9, ptr %temp, align 8 @@ -330,7 +323,7 @@ if.then10: ; preds = %if.exit6 br i1 %i2nb, label %if.then14, label %if.exit15 if.then14: ; preds = %if.then10 - store i64 ptrtoint (ptr @"test.ReadError$OUT_OF_MEMORY" to i64), ptr %error_var, align 8 + store i64 ptrtoint (ptr @test.OUT_OF_MEMORY to i64), ptr %error_var, align 8 br label %guard_block if.exit15: ; preds = %if.then10 @@ -352,7 +345,7 @@ if.exit16: ; preds = %if.exit6 %lo17 = load ptr, ptr %url, align 8 %ptradd18 = getelementptr inbounds i8, ptr %url, i64 8 %hi19 = load i64, ptr %ptradd18, align 8 - %14 = call i8 @test.contains(ptr %lo17, i64 %hi19, ptr @.str.6, i64 11) + %14 = call i8 @test.contains(ptr %lo17, i64 %hi19, ptr @.str.4, i64 11) %15 = trunc i8 %14 to i1 br i1 %15, label %if.then20, label %if.exit40 @@ -366,7 +359,7 @@ if.then20: ; preds = %if.exit16 br i1 %i2nb28, label %if.then29, label %if.exit30 if.then29: ; preds = %if.then20 - store i64 ptrtoint (ptr @"test.ReadError$OUT_OF_MEMORY" to i64), ptr %error_var25, align 8 + store i64 ptrtoint (ptr @test.OUT_OF_MEMORY to i64), ptr %error_var25, align 8 br label %guard_block31 if.exit30: ; preds = %if.then20 @@ -389,7 +382,7 @@ noerr_block32: ; preds = %if.exit30 br i1 %i2nb35, label %if.then36, label %if.exit37 if.then36: ; preds = %noerr_block32 - store i64 ptrtoint (ptr @"test.ReadError$OUT_OF_MEMORY" to i64), ptr %error_var23, align 8 + store i64 ptrtoint (ptr @test.OUT_OF_MEMORY to i64), ptr %error_var23, align 8 br label %guard_block38 if.exit37: ; preds = %noerr_block32 @@ -412,7 +405,7 @@ if.exit40: ; preds = %if.exit16 %26 = load i64, ptr %ptradd41, align 8 %trunc = trunc i64 %26 to i32 %27 = load ptr, ptr %url, align 8 - %28 = call i32 (ptr, i64, ptr, ...) @snprintf(ptr null, i64 0, ptr @.str.7, i32 %trunc, ptr %27) + %28 = call i32 (ptr, i64, ptr, ...) @snprintf(ptr null, i64 0, ptr @.str.5, i32 %trunc, ptr %27) %sext = sext i32 %28 to i64 store i64 %sext, ptr %len, align 8 %29 = load i64, ptr %len, align 8 @@ -424,7 +417,7 @@ if.exit40: ; preds = %if.exit16 br i1 %i2nb42, label %if.then43, label %if.exit44 if.then43: ; preds = %if.exit40 - ret i64 ptrtoint (ptr @"test.ReadError$OUT_OF_MEMORY" to i64) + ret i64 ptrtoint (ptr @test.OUT_OF_MEMORY to i64) if.exit44: ; preds = %if.exit40 %32 = load i64, ptr %len, align 8 @@ -434,7 +427,7 @@ if.exit44: ; preds = %if.exit40 %trunc47 = trunc i64 %33 to i32 %34 = load ptr, ptr %str, align 8 %35 = load ptr, ptr %url, align 8 - %36 = call i32 (ptr, i64, ptr, ...) @snprintf(ptr %34, i64 %add45, ptr @.str.8, i32 %trunc47, ptr %35) + %36 = call i32 (ptr, i64, ptr, ...) @snprintf(ptr %34, i64 %add45, ptr @.str.6, i32 %trunc47, ptr %35) store ptr null, ptr %literal51, align 8 %37 = load ptr, ptr %str, align 8 %38 = load i64, ptr %len, align 8 @@ -451,7 +444,7 @@ if.exit44: ; preds = %if.exit40 br i1 %i2nb55, label %if.then56, label %if.exit57 if.then56: ; preds = %if.exit44 - store i64 ptrtoint (ptr @"test.ReadError$OUT_OF_MEMORY" to i64), ptr %error_var52, align 8 + store i64 ptrtoint (ptr @test.OUT_OF_MEMORY to i64), ptr %error_var52, align 8 br label %guard_block58 if.exit57: ; preds = %if.exit44 @@ -474,7 +467,7 @@ noerr_block59: ; preds = %if.exit57 br i1 %i2nb62, label %if.then63, label %if.exit64 if.then63: ; preds = %noerr_block59 - store i64 ptrtoint (ptr @"test.ReadError$OUT_OF_MEMORY" to i64), ptr %error_var50, align 8 + store i64 ptrtoint (ptr @test.OUT_OF_MEMORY to i64), ptr %error_var50, align 8 br label %guard_block65 if.exit64: ; preds = %noerr_block59 @@ -548,7 +541,7 @@ after_check: ; preds = %entry br label %phi_block else_block: ; preds = %entry - call void @llvm.memcpy.p0.p0.i32(ptr align 8 %literal, ptr align 8 @.__const.9, i32 16, i1 false) + call void @llvm.memcpy.p0.p0.i32(ptr align 8 %literal, ptr align 8 @.__const.7, i32 16, i1 false) br label %phi_block phi_block: ; preds = %else_block, %after_check @@ -569,7 +562,7 @@ entry: br i1 %i2nb, label %if.then, label %if.exit if.then: ; preds = %entry - ret i64 ptrtoint (ptr @"test.TitleResult$TITLE_MISSING" to i64) + ret i64 ptrtoint (ptr @test.TITLE_MISSING to i64) if.exit: ; preds = %entry %3 = load ptr, ptr %doc, align 8 @@ -580,7 +573,7 @@ if.exit: ; preds = %entry br i1 %i2nb1, label %if.then2, label %if.exit3 if.then2: ; preds = %if.exit - ret i64 ptrtoint (ptr @"test.TitleResult$TITLE_MISSING" to i64) + ret i64 ptrtoint (ptr @test.TITLE_MISSING to i64) if.exit3: ; preds = %if.exit %6 = load ptr, ptr %head, align 8 @@ -639,7 +632,7 @@ err_retblock: ; preds = %assign_optional4, % define ptr @test.bool_to_string(i8 zeroext %0) #0 { entry: %1 = trunc i8 %0 to i1 - %ternary = select i1 %1, ptr @.str.10, ptr @.str.11 + %ternary = select i1 %1, ptr @.str.8, ptr @.str.9 ret ptr %ternary } @@ -652,31 +645,31 @@ entry: switch.entry: ; preds = %entry %1 = load i64, ptr %switch, align 8 - %eq = icmp eq i64 ptrtoint (ptr @"test.TitleResult$TITLE_MISSING" to i64), %1 + %eq = icmp eq i64 ptrtoint (ptr @test.TITLE_MISSING to i64), %1 br i1 %eq, label %switch.case, label %next_if switch.case: ; preds = %switch.entry - ret ptr @.str.12 + ret ptr @.str.10 next_if: ; preds = %switch.entry - %eq1 = icmp eq i64 ptrtoint (ptr @"test.ReadError$BAD_READ" to i64), %1 + %eq1 = icmp eq i64 ptrtoint (ptr @test.BAD_READ to i64), %1 br i1 %eq1, label %switch.case2, label %next_if3 switch.case2: ; preds = %next_if - ret ptr @.str.13 + ret ptr @.str.11 next_if3: ; preds = %next_if - %eq4 = icmp eq i64 ptrtoint (ptr @"test.ReadError$OUT_OF_MEMORY" to i64), %1 + %eq4 = icmp eq i64 ptrtoint (ptr @test.OUT_OF_MEMORY to i64), %1 br i1 %eq4, label %switch.case5, label %next_if6 switch.case5: ; preds = %next_if3 - ret ptr @.str.14 + ret ptr @.str.12 next_if6: ; preds = %next_if3 br label %switch.default switch.default: ; preds = %next_if6 - ret ptr @.str.15 + ret ptr @.str.13 } ; Function Attrs: @@ -710,17 +703,17 @@ loop.body: ; preds = %loop.cond %4 = load i64, ptr %ptradd, align 8 %trunc = trunc i64 %4 to i32 %5 = load ptr, ptr %url, align 8 - %6 = call i32 (ptr, ...) @printf(ptr @.str.21, i32 %trunc, ptr %5) + %6 = call i32 (ptr, ...) @printf(ptr @.str.19, i32 %trunc, ptr %5) %lo = load ptr, ptr %url, align 8 %ptradd1 = getelementptr inbounds i8, ptr %url, i64 8 %hi = load i64, ptr %ptradd1, align 8 %7 = call { ptr, i8 } @test.readAndBuildSummary(ptr %lo, i64 %hi) store { ptr, i8 } %7, ptr %result, align 8 call void @llvm.memcpy.p0.p0.i32(ptr align 8 %summary, ptr align 8 %result, i32 16, i1 false) - %8 = call i32 (ptr, ...) @printf(ptr @.str.22) + %8 = call i32 (ptr, ...) @printf(ptr @.str.20) %9 = load ptr, ptr @__stdoutp, align 8 call void @test.Summary.print(ptr %summary, ptr %9) - %10 = call i32 (ptr, ...) @printf(ptr @.str.23) + %10 = call i32 (ptr, ...) @printf(ptr @.str.21) %11 = load ptr, ptr %summary, align 8 %i2b = icmp ne ptr %11, null br i1 %i2b, label %cond.lhs, label %cond.rhs @@ -740,7 +733,7 @@ cond.phi: ; preds = %cond.rhs, %cond.lhs %14 = load i64, ptr %ptradd2, align 8 %trunc3 = trunc i64 %14 to i32 %15 = load ptr, ptr %title_sure, align 8 - %16 = call i32 (ptr, ...) @printf(ptr @.str.24, i32 %trunc3, ptr %15) + %16 = call i32 (ptr, ...) @printf(ptr @.str.22, i32 %trunc3, ptr %15) %lo4 = load ptr, ptr %url, align 8 %ptradd5 = getelementptr inbounds i8, ptr %url, i64 8 %hi6 = load i64, ptr %ptradd5, align 8 @@ -823,8 +816,8 @@ else_block18: ; preds = %phi_block phi_block19: ; preds = %else_block18, %after_check17 %val20 = phi i1 [ %30, %after_check17 ], [ false, %else_block18 ] - %ternary = select i1 %val20, ptr @.str.26, ptr @.str.27 - %31 = call i32 (ptr, ...) @printf(ptr @.str.25, ptr %val14, ptr %ternary) + %ternary = select i1 %val20, ptr @.str.24, ptr @.str.25 + %31 = call i32 (ptr, ...) @printf(ptr @.str.23, ptr %val14, ptr %ternary) %32 = load i64, ptr %.anon, align 8 %addnuw = add nuw i64 %32, 1 store i64 %addnuw, ptr %.anon, align 8 diff --git a/test/test_suite/errors/error_semantic_fails.c3 b/test/test_suite/errors/error_semantic_fails.c3 index bfafa510f..2352298e4 100644 --- a/test/test_suite/errors/error_semantic_fails.c3 +++ b/test/test_suite/errors/error_semantic_fails.c3 @@ -1,5 +1,5 @@ -fault Repeater -{ +fault + A, - A // #error: This fault value was declared twice. -} + A // #error: would shadow a previous declaration +; diff --git a/test/test_suite/errors/error_throw.c3 b/test/test_suite/errors/error_throw.c3 index e540cb29f..d80e1ec50 100644 --- a/test/test_suite/errors/error_throw.c3 +++ b/test/test_suite/errors/error_throw.c3 @@ -1,12 +1,9 @@ module foo; -fault Blurg -{ - Z -} +fault Z; fn void main() { - int! i = Blurg.Z?; - int! j = Blurg.Z?; + int? i = Z?; + int? j = Z?; } \ No newline at end of file diff --git a/test/test_suite/errors/error_union.c3 b/test/test_suite/errors/error_union.c3 index 9996b2c2a..d9af8ef5e 100644 --- a/test/test_suite/errors/error_union.c3 +++ b/test/test_suite/errors/error_union.c3 @@ -1,9 +1,6 @@ module foo; -fault Blurg -{ - X, Y, Z -} +fault X, Y, Z; fn void main() { diff --git a/test/test_suite/errors/failable_catch.c3t b/test/test_suite/errors/failable_catch.c3t index b8b827ad3..fab5d84bb 100644 --- a/test/test_suite/errors/failable_catch.c3t +++ b/test/test_suite/errors/failable_catch.c3t @@ -1,24 +1,21 @@ // #target: macos-x64 -fault MyErr -{ - TEST -} +fault TEST; macro foo(int x) { if (x) return x; - return MyErr.TEST?; + return TEST?; } extern fn void printf(char*, ...); fn int main() { - int! a = foo(1); + int? a = foo(1); - int! b = foo((a + 3) ?? 2); - int! c = foo(0); + int? b = foo((a + 3) ?? 2); + int? c = foo(0); (void)printf("a = %d\n", a); (void)printf("b = %d\n", b); (void)printf("c = %d\n", c); @@ -78,7 +75,7 @@ if.then2: ; preds = %phi_block br label %expr_block.exit3 if.exit: ; preds = %phi_block - store i64 ptrtoint (ptr @"failable_catch.MyErr$TEST" to i64), ptr %b.f, align 8 + store i64 ptrtoint (ptr @failable_catch.TEST to i64), ptr %b.f, align 8 br label %after_assign4 expr_block.exit3: ; preds = %if.then2 @@ -91,7 +88,7 @@ after_assign4: ; preds = %expr_block.exit3, % br label %if.exit6 if.exit6: ; preds = %after_assign4 - store i64 ptrtoint (ptr @"failable_catch.MyErr$TEST" to i64), ptr %c.f, align 8 + store i64 ptrtoint (ptr @failable_catch.TEST to i64), ptr %c.f, align 8 br label %after_assign7 after_assign7: ; preds = %if.exit6 diff --git a/test/test_suite/errors/fault_conv.c3t b/test/test_suite/errors/fault_conv.c3t index e900b0aec..f4a424cd9 100644 --- a/test/test_suite/errors/fault_conv.c3t +++ b/test/test_suite/errors/fault_conv.c3t @@ -2,16 +2,11 @@ module test; import std::io; -fault HadError -{ - BAD_STUFF, - WORSE_STUFF, - THE_WORST_STUFF -} +fault BAD_STUFF, WORSE_STUFF, THE_WORST_STUFF; fn int exitcode(anyfault error) { - switch ((HadError)error) + switch (error) { case BAD_STUFF: return 64; case WORSE_STUFF: return 65; @@ -20,11 +15,11 @@ fn int exitcode(anyfault error) } } -fn void! canFail() +fn void? canFail() { if (34 + 35 == 69) { - return HadError.BAD_STUFF?; + return BAD_STUFF?; } } @@ -49,21 +44,21 @@ entry: switch.entry: ; preds = %entry %1 = load i64, ptr %switch, align 8 - %eq = icmp eq i64 ptrtoint (ptr @"test.HadError$BAD_STUFF" to i64), %1 + %eq = icmp eq i64 ptrtoint (ptr @test.BAD_STUFF to i64), %1 br i1 %eq, label %switch.case, label %next_if switch.case: ; preds = %switch.entry ret i32 64 next_if: ; preds = %switch.entry - %eq1 = icmp eq i64 ptrtoint (ptr @"test.HadError$WORSE_STUFF" to i64), %1 + %eq1 = icmp eq i64 ptrtoint (ptr @test.WORSE_STUFF to i64), %1 br i1 %eq1, label %switch.case2, label %next_if3 switch.case2: ; preds = %next_if ret i32 65 next_if3: ; preds = %next_if - %eq4 = icmp eq i64 ptrtoint (ptr @"test.HadError$THE_WORST_STUFF" to i64), %1 + %eq4 = icmp eq i64 ptrtoint (ptr @test.THE_WORST_STUFF to i64), %1 br i1 %eq4, label %switch.case5, label %next_if6 switch.case5: ; preds = %next_if3 @@ -81,7 +76,7 @@ entry: br label %if.then if.then: ; preds = %entry - ret i64 ptrtoint (ptr @"test.HadError$BAD_STUFF" to i64) + ret i64 ptrtoint (ptr @test.BAD_STUFF to i64) } define i32 @test.main(ptr %0, i64 %1) #0 { diff --git a/test/test_suite/errors/general_error_regression.c3t b/test/test_suite/errors/general_error_regression.c3t index 521baacaf..a8b10fed6 100644 --- a/test/test_suite/errors/general_error_regression.c3t +++ b/test/test_suite/errors/general_error_regression.c3t @@ -2,22 +2,14 @@ module foo; import std::io; import libc; -fault Foo -{ +fault X, Y, Z, W, - W1 + W1; - -} - -fault Foob -{ - X1, - Y2 -} +fault X1, Y2; distinct Bar = int; @@ -27,11 +19,6 @@ enum MyEnum B } -fn void Foo.hello(Foo *f) -{ - io::printn("Hello from Foo"); -} - fn void Bar.hello(Bar *b) { io::printn("Hello from Bar"); @@ -43,102 +30,34 @@ fn void MyEnum.hello(MyEnum *myenum) } fn void main() { - Foo f = Foo.X; - Foo ef = Foo.Y; + anyfault f = X; + anyfault ef = Y; anyfault x = f; ulong z = (ulong)(x); libc::printf("1: %p\n", z); x = ef; z = (ulong)(x); libc::printf("2: %p\n", z); - x = Foo.W; + x = W; z = (ulong)(x); libc::printf("21: %p\n", z); - x = Foo.W1; + x = W1; z = (ulong)(x); libc::printf("22: %p\n", z); - x = Foob.X1; + x = X1; z = (ulong)(x); libc::printf("3: %p\n", z); - x = Foob.Y2; + x = Y2; z = (ulong)(x); libc::printf("4: %p\n", z); Bar b; MyEnum a = MyEnum.A; - f.hello(); b.hello(); a.hello(); } /* #expect: foo.ll -define void @foo.Foo.hello(ptr %0) #0 { -entry: - %len = alloca i64, align 8 - %error_var = alloca i64, align 8 - %retparam = alloca i64, align 8 - %error_var2 = alloca i64, align 8 - %error_var8 = alloca i64, align 8 - %1 = call ptr @std.io.stdout() - %2 = call i64 @std.io.File.write(ptr %retparam, ptr %1, ptr @.str.12, i64 14) - %not_err = icmp eq i64 %2, 0 - %3 = call i1 @llvm.expect.i1(i1 %not_err, i1 true) - br i1 %3, label %after_check, label %assign_optional - -assign_optional: ; preds = %entry - store i64 %2, ptr %error_var, align 8 - br label %guard_block - -after_check: ; preds = %entry - br label %noerr_block - -guard_block: ; preds = %assign_optional - br label %voiderr - -noerr_block: ; preds = %after_check - %4 = load i64, ptr %retparam, align 8 - store i64 %4, ptr %len, align 8 - %5 = call i64 @std.io.File.write_byte(ptr %1, i8 zeroext 10) - %not_err3 = icmp eq i64 %5, 0 - %6 = call i1 @llvm.expect.i1(i1 %not_err3, i1 true) - br i1 %6, label %after_check5, label %assign_optional4 - -assign_optional4: ; preds = %noerr_block - store i64 %5, ptr %error_var2, align 8 - br label %guard_block6 - -after_check5: ; preds = %noerr_block - br label %noerr_block7 - -guard_block6: ; preds = %assign_optional4 - br label %voiderr - -noerr_block7: ; preds = %after_check5 - %7 = call i64 @std.io.File.flush(ptr %1) - %not_err9 = icmp eq i64 %7, 0 - %8 = call i1 @llvm.expect.i1(i1 %not_err9, i1 true) - br i1 %8, label %after_check11, label %assign_optional10 - -assign_optional10: ; preds = %noerr_block7 - store i64 %7, ptr %error_var8, align 8 - br label %guard_block12 - -after_check11: ; preds = %noerr_block7 - br label %noerr_block13 - -guard_block12: ; preds = %assign_optional10 - br label %voiderr - -noerr_block13: ; preds = %after_check11 - %9 = load i64, ptr %len, align 8 - %add = add i64 %9, 1 - br label %voiderr - -voiderr: ; preds = %noerr_block13, %guard_block12, %guard_block6, %guard_block - ret void -} - - define void @foo.Bar.hello(ptr %0) #0 { entry: %len = alloca i64, align 8 @@ -147,7 +66,7 @@ entry: %error_var2 = alloca i64, align 8 %error_var8 = alloca i64, align 8 %1 = call ptr @std.io.stdout() - %2 = call i64 @std.io.File.write(ptr %retparam, ptr %1, ptr @.str.13, i64 14) + %2 = call i64 @std.io.File.write(ptr %retparam, ptr %1, ptr @.str.6, i64 14) %not_err = icmp eq i64 %2, 0 %3 = call i1 @llvm.expect.i1(i1 %not_err, i1 true) br i1 %3, label %after_check, label %assign_optional @@ -214,7 +133,7 @@ entry: %error_var2 = alloca i64, align 8 %error_var8 = alloca i64, align 8 %1 = call ptr @std.io.stdout() - %2 = call i64 @std.io.File.write(ptr %retparam, ptr %1, ptr @.str.14, i64 17) + %2 = call i64 @std.io.File.write(ptr %retparam, ptr %1, ptr @.str.7, i64 17) %not_err = icmp eq i64 %2, 0 %3 = call i1 @llvm.expect.i1(i1 %not_err, i1 true) br i1 %3, label %after_check, label %assign_optional @@ -281,8 +200,8 @@ entry: %z = alloca i64, align 8 %b = alloca i32, align 4 %a = alloca i32, align 4 - store i64 ptrtoint (ptr @"foo.Foo$X" to i64), ptr %f, align 8 - store i64 ptrtoint (ptr @"foo.Foo$Y" to i64), ptr %ef, align 8 + store i64 ptrtoint (ptr @foo.X to i64), ptr %f, align 8 + store i64 ptrtoint (ptr @foo.Y to i64), ptr %ef, align 8 %0 = load i64, ptr %f, align 8 store i64 %0, ptr %x, align 8 %1 = load i64, ptr %x, align 8 @@ -294,30 +213,29 @@ entry: %5 = load i64, ptr %x, align 8 store i64 %5, ptr %z, align 8 %6 = load i64, ptr %z, align 8 - %7 = call i32 (ptr, ...) @printf(ptr @.str.7, i64 %6) - store i64 ptrtoint (ptr @"foo.Foo$W" to i64), ptr %x, align 8 + %7 = call i32 (ptr, ...) @printf(ptr @.str.1, i64 %6) + store i64 ptrtoint (ptr @foo.W to i64), ptr %x, align 8 %8 = load i64, ptr %x, align 8 store i64 %8, ptr %z, align 8 %9 = load i64, ptr %z, align 8 - %10 = call i32 (ptr, ...) @printf(ptr @.str.8, i64 %9) - store i64 ptrtoint (ptr @"foo.Foo$W1" to i64), ptr %x, align 8 + %10 = call i32 (ptr, ...) @printf(ptr @.str.2, i64 %9) + store i64 ptrtoint (ptr @foo.W1 to i64), ptr %x, align 8 %11 = load i64, ptr %x, align 8 store i64 %11, ptr %z, align 8 %12 = load i64, ptr %z, align 8 - %13 = call i32 (ptr, ...) @printf(ptr @.str.9, i64 %12) - store i64 ptrtoint (ptr @"foo.Foob$X1" to i64), ptr %x, align 8 + %13 = call i32 (ptr, ...) @printf(ptr @.str.3, i64 %12) + store i64 ptrtoint (ptr @foo.X1 to i64), ptr %x, align 8 %14 = load i64, ptr %x, align 8 store i64 %14, ptr %z, align 8 %15 = load i64, ptr %z, align 8 - %16 = call i32 (ptr, ...) @printf(ptr @.str.10, i64 %15) - store i64 ptrtoint (ptr @"foo.Foob$Y2" to i64), ptr %x, align 8 + %16 = call i32 (ptr, ...) @printf(ptr @.str.4, i64 %15) + store i64 ptrtoint (ptr @foo.Y2 to i64), ptr %x, align 8 %17 = load i64, ptr %x, align 8 store i64 %17, ptr %z, align 8 %18 = load i64, ptr %z, align 8 - %19 = call i32 (ptr, ...) @printf(ptr @.str.11, i64 %18) + %19 = call i32 (ptr, ...) @printf(ptr @.str.5, i64 %18) store i32 0, ptr %b, align 4 store i32 0, ptr %a, align 4 - call void @foo.Foo.hello(ptr %f) call void @foo.Bar.hello(ptr %b) call void @foo.MyEnum.hello(ptr %a) ret void diff --git a/test/test_suite/errors/illegal_use_of_optional.c3 b/test/test_suite/errors/illegal_use_of_optional.c3 index 6d33a20ee..5d29642f2 100644 --- a/test/test_suite/errors/illegal_use_of_optional.c3 +++ b/test/test_suite/errors/illegal_use_of_optional.c3 @@ -1,12 +1,12 @@ fn void syntaxErrors() { - int! i = 0; - while (i + 1) {} // #error: optional, but was 'int!' - if (i + 1) {} // #error: optional, but was 'int!' - for (int x = i;;) {} // #error: 'int!' to 'int' - for (int x = 0; x < i + 1;) {} // #error: optional, but was 'bool!'. + int? i = 0; + while (i + 1) {} // #error: optional, but was 'int?' + if (i + 1) {} // #error: optional, but was 'int?' + for (int x = i;;) {} // #error: 'int?' to 'int' + for (int x = 0; x < i + 1;) {} // #error: optional, but was 'bool?'. for (int x = 0; x < 10; x += i + 1) {} // #error: Cannot assign an optional value to a non-optional - switch (i + 1) // #error: optional, but was 'int!' + switch (i + 1) // #error: optional, but was 'int?' { default: i + 1; diff --git a/test/test_suite/errors/invalid_cast_ct.c3 b/test/test_suite/errors/invalid_cast_ct.c3 deleted file mode 100644 index 55c14ebb2..000000000 --- a/test/test_suite/errors/invalid_cast_ct.c3 +++ /dev/null @@ -1,16 +0,0 @@ -module exitcodes; -import std::io; - -fault HadError -{ - BAD_STUFF, - WORSE_STUFF, - THE_WORST_STUFF -} - -fn int main(String[] args) -{ - HadError err = HadError.BAD_STUFF; - SearchResult res = (SearchResult)(anyfault)HadError.BAD_STUFF; // #error: This expression is known at compile time - return 0; -} diff --git a/test/test_suite/errors/macro_err.c3t b/test/test_suite/errors/macro_err.c3t index 23e6ff617..66dff7876 100644 --- a/test/test_suite/errors/macro_err.c3t +++ b/test/test_suite/errors/macro_err.c3t @@ -1,7 +1,7 @@ // #target: macos-x64 module test; import libc; -fn int! abc() +fn int? abc() { return 1; } diff --git a/test/test_suite/errors/macro_err2.c3t b/test/test_suite/errors/macro_err2.c3t index da045fa3f..adfa40347 100644 --- a/test/test_suite/errors/macro_err2.c3t +++ b/test/test_suite/errors/macro_err2.c3t @@ -1,11 +1,11 @@ // #target: macos-x64 module test; import libc; -fault Tester { FOO } +fault FOO; -fn int! abc() +fn int? abc() { - return Tester.FOO?; + return FOO?; } macro test() { @@ -23,7 +23,7 @@ fn void main() define i64 @test.abc(ptr %0) #0 { entry: - ret i64 ptrtoint (ptr @"test.Tester$FOO" to i64) + ret i64 ptrtoint (ptr @test.FOO to i64) } define void @test.main() #0 { diff --git a/test/test_suite/errors/macro_err3.c3t b/test/test_suite/errors/macro_err3.c3t index 3cff92b0e..db3245ee5 100644 --- a/test/test_suite/errors/macro_err3.c3t +++ b/test/test_suite/errors/macro_err3.c3t @@ -1,13 +1,13 @@ // #target: macos-x64 module test; import libc; -fault Tester { FOO } +fault FOO; macro test() { defer libc::printf("Test2\n"); - return Tester.FOO?; + return FOO?; } fn void main() diff --git a/test/test_suite/errors/missing_bang.c3 b/test/test_suite/errors/missing_bang.c3 index 93d41fa64..5342b4aaf 100644 --- a/test/test_suite/errors/missing_bang.c3 +++ b/test/test_suite/errors/missing_bang.c3 @@ -1,7 +1,7 @@ -fault Bob { FOO } +fault FOO; -fn int! test() +fn int? test() { - return Bob.FOO; // #error: You need to add a trailing + return FOO; // #error: You need to add a trailing } \ No newline at end of file diff --git a/test/test_suite/errors/more_optional_discard.c3 b/test/test_suite/errors/more_optional_discard.c3 index c2472cb1d..410a62c17 100644 --- a/test/test_suite/errors/more_optional_discard.c3 +++ b/test/test_suite/errors/more_optional_discard.c3 @@ -1,15 +1,15 @@ module abc; macro int mtest1(int a) @nodiscard { return 0; } -macro int! mtest2(int a) { return 0; } +macro int? mtest2(int a) { return 0; } fn int ftest1(int a) @nodiscard { return 0; } -fn int! ftest2(int a) { return 0; } +fn int? ftest2(int a) { return 0; } fn void main() { mtest1(3); // #error: The called macro is marked `@nodiscard` - mtest2(3); // #error: The macro returns 'int!', which is an optional + mtest2(3); // #error: The macro returns 'int?', which is an optional ftest1(3); // #error: The called function is marked `@nodiscard` - ftest2(3); // #error: The function returns 'int!' + ftest2(3); // #error: The function returns 'int?' } \ No newline at end of file diff --git a/test/test_suite/errors/more_optional_tests.c3 b/test/test_suite/errors/more_optional_tests.c3 index 226c57303..507634733 100644 --- a/test/test_suite/errors/more_optional_tests.c3 +++ b/test/test_suite/errors/more_optional_tests.c3 @@ -1,13 +1,13 @@ module foo; -fault Foo { ABC } +fault ABC; fn void test() { - int x = Foo.ABC? ?? 123; + int x = ABC? ?? 123; } fn void test2() { - int! y = Foo.ABC? ?? Foo.ABC?; + int? y = ABC? ?? ABC?; } \ No newline at end of file diff --git a/test/test_suite/errors/multiple_catch.c3t b/test/test_suite/errors/multiple_catch.c3t index 2be69c69d..c690aa2f8 100644 --- a/test/test_suite/errors/multiple_catch.c3t +++ b/test/test_suite/errors/multiple_catch.c3t @@ -3,22 +3,18 @@ module demo1; import std::io; -fault CheckError -{ - ABC, - DEF -} +fault ABC, DEF; -fn int! hello(int a) +fn int? hello(int a) { io::printn("hello"); - return a < 0 ? CheckError.ABC? : a; + return a < 0 ? ABC? : a; } -fn void! bye() +fn void? bye() { io::printn("bye"); - return CheckError.DEF?; + return DEF?; } fn void main() { @@ -101,7 +97,7 @@ if.then: ; preds = %end_block %5 = insertvalue %any undef, ptr %err, 0 %6 = insertvalue %any %5, i64 ptrtoint (ptr @"$ct.anyfault" to i64), 1 store %any %6, ptr %varargslots, align 16 - %7 = call i64 @std.io.printfn(ptr %retparam5, ptr @.str.3, i64 8, ptr %varargslots, i64 1) + %7 = call i64 @std.io.printfn(ptr %retparam5, ptr @.str.2, i64 8, ptr %varargslots, i64 1) br label %if.exit if.exit: ; preds = %if.then, %end_block @@ -143,7 +139,7 @@ if.then20: ; preds = %end_block18 %13 = insertvalue %any undef, ptr %err8, 0 %14 = insertvalue %any %13, i64 ptrtoint (ptr @"$ct.anyfault" to i64), 1 store %any %14, ptr %varargslots21, align 16 - %15 = call i64 @std.io.printfn(ptr %retparam22, ptr @.str.4, i64 8, ptr %varargslots21, i64 1) + %15 = call i64 @std.io.printfn(ptr %retparam22, ptr @.str.3, i64 8, ptr %varargslots21, i64 1) br label %if.exit25 if.exit25: ; preds = %if.then20, %end_block18 @@ -183,7 +179,7 @@ end_block35: ; preds = %after_check34, %ass if.then37: ; preds = %end_block35 %21 = call ptr @std.io.stdout() - %22 = call i64 @std.io.File.write(ptr %retparam39, ptr %21, ptr @.str.5, i64 4) + %22 = call i64 @std.io.File.write(ptr %retparam39, ptr %21, ptr @.str.4, i64 4) %not_err40 = icmp eq i64 %22, 0 %23 = call i1 @llvm.expect.i1(i1 %not_err40, i1 true) br i1 %23, label %after_check42, label %assign_optional41 @@ -279,7 +275,7 @@ if.then68: ; preds = %end_block66 %35 = insertvalue %any undef, ptr %err56, 0 %36 = insertvalue %any %35, i64 ptrtoint (ptr @"$ct.anyfault" to i64), 1 store %any %36, ptr %varargslots69, align 16 - %37 = call i64 @std.io.printfn(ptr %retparam70, ptr @.str.6, i64 8, ptr %varargslots69, i64 1) + %37 = call i64 @std.io.printfn(ptr %retparam70, ptr @.str.5, i64 8, ptr %varargslots69, i64 1) br label %if.exit73 if.exit73: ; preds = %if.then68, %end_block66 diff --git a/test/test_suite/errors/no_common.c3 b/test/test_suite/errors/no_common.c3 index 2c26ee9f2..c3c8603b5 100644 --- a/test/test_suite/errors/no_common.c3 +++ b/test/test_suite/errors/no_common.c3 @@ -1,4 +1,4 @@ -fn int! abc() +fn int? abc() { return 1; } diff --git a/test/test_suite/errors/optional_chained_init.c3t b/test/test_suite/errors/optional_chained_init.c3t index beec02d17..dbd8b855e 100644 --- a/test/test_suite/errors/optional_chained_init.c3t +++ b/test/test_suite/errors/optional_chained_init.c3t @@ -2,12 +2,12 @@ module test; import std::io; -fault Test { FOO } +fault FOO; fn void test1() { - int! a = 1; - int! b = a = Test.FOO?; + int? a = 1; + int? b = a = FOO?; if (catch err = a) io::printfn("A err was: %s", err); if (catch err = b) io::printfn("B err was: %s", err); (void)io::printfn("A was: %s", a); @@ -16,9 +16,9 @@ fn void test1() fn void test2() { - int! x = Test.FOO?; - int! a = 1; - int! b = a = x; + int? x = FOO?; + int? a = 1; + int? b = a = x; if (catch err = a) io::printfn("A err was: %s", err); if (catch err = b) io::printfn("B err was: %s", err); (void)io::printfn("A was: %s", a); @@ -28,9 +28,9 @@ fn void test2() fn void test3() { - int! x = 23; - int! a = 1; - int! b = a = x; + int? x = 23; + int? a = 1; + int? b = a = x; if (catch err = a) io::printfn("A err was: %s", err); if (catch err = b) io::printfn("B err was: %s", err); (void)io::printfn("A was: %s", a); @@ -64,8 +64,8 @@ entry: %retparam28 = alloca i64, align 8 store i32 1, ptr %a, align 4 store i64 0, ptr %a.f, align 8 - store i64 ptrtoint (ptr @"test.Test$FOO" to i64), ptr %a.f, align 8 - store i64 ptrtoint (ptr @"test.Test$FOO" to i64), ptr %b.f, align 8 + store i64 ptrtoint (ptr @test.FOO to i64), ptr %a.f, align 8 + store i64 ptrtoint (ptr @test.FOO to i64), ptr %b.f, align 8 br label %after_assign after_assign: ; preds = %entry @@ -179,7 +179,7 @@ entry: %retparam26 = alloca i64, align 8 %varargslots29 = alloca [1 x %any], align 16 %retparam33 = alloca i64, align 8 - store i64 ptrtoint (ptr @"test.Test$FOO" to i64), ptr %x.f, align 8 + store i64 ptrtoint (ptr @test.FOO to i64), ptr %x.f, align 8 store i32 1, ptr %a, align 4 store i64 0, ptr %a.f, align 8 %optval = load i64, ptr %x.f, align 8 diff --git a/test/test_suite/errors/optional_contracts.c3 b/test/test_suite/errors/optional_contracts.c3 index 7540d47b2..00cef7e58 100644 --- a/test/test_suite/errors/optional_contracts.c3 +++ b/test/test_suite/errors/optional_contracts.c3 @@ -1,32 +1,27 @@ -fault Abc -{ +fault ABC, DEF, - ZED -} + ZED; -fault Foo -{ - XYZ -} +fault XYZ; <* hello world - @return! Foo, Abc.ABC + @return! XYZ, ABC *> -fn void! abc(int a, int b, int z) +fn void? abc(int a, int b, int z) { - return Abc.ZED?; // #error: This value does not match declared optional returns + return ZED?; // #error: This value does not match declared optional returns } <* hello world - @return! Foo, Abc.ABC + @return! XYZ, ABC *> -macro void! @abc(int a, int b, int z) +macro void? @abc(int a, int b, int z) { - return Abc.ZED?; // #error: This value does not match declared optional returns + return ZED?; // #error: This value does not match declared optional returns } fn void main() diff --git a/test/test_suite/errors/optional_designated.c3 b/test/test_suite/errors/optional_designated.c3 index e141767e6..65185ae13 100644 --- a/test/test_suite/errors/optional_designated.c3 +++ b/test/test_suite/errors/optional_designated.c3 @@ -7,4 +7,4 @@ fn void main() (Bar) { .f = (Foo) { foo() } }; // #error: not be discarded } -fn int! foo() => 1; \ No newline at end of file +fn int? foo() => 1; \ No newline at end of file diff --git a/test/test_suite/errors/optional_discarded_func.c3 b/test/test_suite/errors/optional_discarded_func.c3 index 871ba7ecb..f7689fba5 100644 --- a/test/test_suite/errors/optional_discarded_func.c3 +++ b/test/test_suite/errors/optional_discarded_func.c3 @@ -1,17 +1,17 @@ fn int abc(int x) { return 1; } -fn int! def2(int y) @maydiscard { return 1; } -fn int! def3(int z) { return 1; } +fn int? def2(int y) @maydiscard { return 1; } +fn int? def3(int z) { return 1; } fn void test1() { - int! x; + int? x; abc(x); // #error: The result of this call is optional due to its argumen } fn void test2() { - int! x; + int? x; int y; abc(y); abc(x) + 4; // #error: An optional value may not be discarded @@ -19,7 +19,7 @@ fn void test2() fn void test3() { - int! x; + int? x; int y; def2(1); def2(x); // #error: The result of this call is optional due to its argumen @@ -27,7 +27,7 @@ fn void test3() fn void test4() { - int! x; + int? x; int y; def2(1); def2(x) + 4; // #error: An optional value may not be discarded @@ -35,16 +35,16 @@ fn void test4() fn void test5() { - int! x; + int? x; int y; - def3(y); // #error: The function returns 'int!' + def3(y); // #error: The function returns 'int?' } fn void test6() { - int! x; + int? x; int y; - def3(x); // #error: The function returns 'int!' + def3(x); // #error: The function returns 'int?' } fn void test7() diff --git a/test/test_suite/errors/optional_discarded_macro.c3 b/test/test_suite/errors/optional_discarded_macro.c3 index 4dcc61e50..f33c588b0 100644 --- a/test/test_suite/errors/optional_discarded_macro.c3 +++ b/test/test_suite/errors/optional_discarded_macro.c3 @@ -1,17 +1,17 @@ macro int abc(int x) { return 1; } -macro int! def2(int y) @maydiscard { return 1; } -macro int! def3(int z) { return 1; } +macro int? def2(int y) @maydiscard { return 1; } +macro int? def3(int z) { return 1; } fn void test1() { - int! x; + int? x; abc(x); // #error: The result of this call is optional due to its argumen } fn void test2() { - int! x; + int? x; int y; abc(y); abc(x) + 4; // #error: An optional value may not be discarded @@ -19,7 +19,7 @@ fn void test2() fn void test3() { - int! x; + int? x; int y; def2(1); def2(x); // #error: The result of this call is optional due to its argumen @@ -27,7 +27,7 @@ fn void test3() fn void test4() { - int! x; + int? x; int y; def2(1); def2(x) + 4; // #error: An optional value may not be discarded @@ -35,16 +35,16 @@ fn void test4() fn void test5() { - int! x; + int? x; int y; - def3(y); // #error: The macro returns 'int!' + def3(y); // #error: The macro returns 'int?' } fn void test6() { - int! x; + int? x; int y; - def3(x); // #error: The macro returns 'int!' + def3(x); // #error: The macro returns 'int?' } fn void test7() diff --git a/test/test_suite/errors/optional_expr_list.c3t b/test/test_suite/errors/optional_expr_list.c3t index d531e5907..8413051c7 100644 --- a/test/test_suite/errors/optional_expr_list.c3t +++ b/test/test_suite/errors/optional_expr_list.c3t @@ -3,7 +3,7 @@ module test; fn void main() { - int! n; + int? n; for (n += 1, 1 + 1; false;); } diff --git a/test/test_suite/errors/optional_inits.c3t b/test/test_suite/errors/optional_inits.c3t index 54ac32e9c..727649808 100644 --- a/test/test_suite/errors/optional_inits.c3t +++ b/test/test_suite/errors/optional_inits.c3t @@ -2,26 +2,22 @@ module test; import std::io; -fault Foo -{ - MY_VAL1, - MY_VAL2, -} +fault MY_VAL1, MY_VAL2; struct Bar { int x; } -fn void! test1() @maydiscard +fn void? test1() @maydiscard { - Bar! x = Foo.MY_VAL1?; + Bar? x = MY_VAL1?; Bar y = x!; } -fn void! test2() @maydiscard +fn void? test2() @maydiscard { - Bar! x = {}; + Bar? x = {}; Bar y = x!; } @@ -39,7 +35,7 @@ entry: %x.f = alloca i64, align 8 %y = alloca %Bar, align 4 %error_var = alloca i64, align 8 - store i64 ptrtoint (ptr @"test.Foo$MY_VAL1" to i64), ptr %x.f, align 8 + store i64 ptrtoint (ptr @test.MY_VAL1 to i64), ptr %x.f, align 8 %optval = load i64, ptr %x.f, align 8 %not_err = icmp eq i64 %optval, 0 %0 = call i1 @llvm.expect.i1(i1 %not_err, i1 true) diff --git a/test/test_suite/errors/optional_sizeof.c3 b/test/test_suite/errors/optional_sizeof.c3 index e8455b594..68ebba02b 100644 --- a/test/test_suite/errors/optional_sizeof.c3 +++ b/test/test_suite/errors/optional_sizeof.c3 @@ -1,4 +1,4 @@ -fn int! abc() +fn int? abc() { return 1; } @@ -27,7 +27,7 @@ fn void c() $sizeof(test2() ?? 1); } -fn void! d() +fn void? d() { $typeof(test2()!) g; // #error: This expression lacks a concrete type } @@ -37,7 +37,7 @@ macro e() var g = test2()!; // #error: No type can be inferred from the optional result } -fn void! h() +fn void? h() { e(); } diff --git a/test/test_suite/errors/optional_taddr_and_access.c3t b/test/test_suite/errors/optional_taddr_and_access.c3t index 95bfbbd2f..24fc647bd 100644 --- a/test/test_suite/errors/optional_taddr_and_access.c3t +++ b/test/test_suite/errors/optional_taddr_and_access.c3t @@ -6,19 +6,16 @@ struct Foo int x, y; } -fault MyErr -{ - FOO -} +fault FOO; extern fn int printf(char *c, ...); fn void main() { - int! z = 2; - Foo*! w = &&(Foo){ z, 0 }; + int? z = 2; + Foo*? w = &&(Foo){ z, 0 }; (void)printf("%d\n", w.x); - z = MyErr.FOO?; + z = FOO?; w = &&(Foo){ z, 0 }; (void)printf("Not visible: %d\n", w.x); } @@ -27,11 +24,10 @@ fn void main() %Foo = type { i32, i32 } -@"$ct.test.Foo" = linkonce global %.introspect { i8 10, i64 0, ptr null, i64 8, i64 0, i64 2, [0 x i64] zeroinitializer }, align 8 -@"test.MyErr$FOO" = linkonce constant %.fault { i64 ptrtoint (ptr @"$ct.test.MyErr" to i64), %"char[]" { ptr @.fault, i64 3 }, i64 1 }, align 8 -@.fault = internal constant [4 x i8] c"FOO\00", align 1 -@"$ct.test.MyErr" = linkonce global %.introspect { i8 9, i64 0, ptr null, i64 8, i64 0, i64 1, [0 x i64] zeroinitializer }, align 8 +@"$ct.test.Foo" = linkonce global %.introspect { i8 9, i64 0, ptr null, i64 8, i64 0, i64 2, [0 x i64] zeroinitializer }, align 8 @.str = private unnamed_addr constant [4 x i8] c"%d\0A\00", align 1 +@test.FOO = linkonce constant %"char[]" { ptr @test.FOO.nameof, i64 3 }, align 8 +@test.FOO.nameof = internal constant [4 x i8] c"FOO\00", align 1 @.str.1 = private unnamed_addr constant [17 x i8] c"Not visible: %d\0A\00", align 1 ; Function Attrs: @@ -79,7 +75,7 @@ after_check3: ; preds = %after_assign br label %voiderr voiderr: ; preds = %after_check3, %after_assign - store i64 ptrtoint (ptr @"test.MyErr$FOO" to i64), ptr %z.f, align 8 + store i64 ptrtoint (ptr @test.FOO to i64), ptr %z.f, align 8 br label %after_check4 after_check4: ; preds = %voiderr diff --git a/test/test_suite/errors/optional_untyped_list.c3 b/test/test_suite/errors/optional_untyped_list.c3 index c4c2f9581..7b53e4b54 100644 --- a/test/test_suite/errors/optional_untyped_list.c3 +++ b/test/test_suite/errors/optional_untyped_list.c3 @@ -4,27 +4,24 @@ struct Foo int x, y; } -fault MyErr -{ - FOO -} +fault FOO; extern fn int printf(char *c, ...); fn void foo() { int z = 2; - Foo*! w = &&{ z, 0 }; // #error: An untyped list can only have constant elements + Foo*? w = &&{ z, 0 }; // #error: An untyped list can only have constant elements } fn void foo2() { - int! z = 2; - Foo*! w = &&{ z, 0 }; // #error: An untyped list can only have constant elements + int? z = 2; + Foo*? w = &&{ z, 0 }; // #error: An untyped list can only have constant elements } fn void test() { - int! z = 2; - Foo*! w = &&Foo!{ z, 0 }; // #error: please remove the '!' + int? z = 2; + Foo*? w = &&(Foo?){ z, 0 }; // #error: please remove the '?' } \ No newline at end of file diff --git a/test/test_suite/errors/optional_with_optional.c3t b/test/test_suite/errors/optional_with_optional.c3t index 94e32b413..187db6110 100644 --- a/test/test_suite/errors/optional_with_optional.c3t +++ b/test/test_suite/errors/optional_with_optional.c3t @@ -2,31 +2,31 @@ module test; import std::io; -fault Foo { ABC, DEF } +fault ABC, DEF; fn void main() { io::printfn("1:%d", get_a(1) ?? get_b(4) ?? -1); io::printfn("2:%d", get_a(2) ?? get_b(4) ?? -1); io::printfn("3:%d", get_a(1) ?? get_b(5) ?? -1); - io::printfn("4:%s", @catch(Foo.ABC? ?? Foo.DEF?)); - io::printfn("5:%s", Foo.ABC? ?? 3); - io::printfn("6:%s", @catch((3 > 2 ? Foo.ABC? : 4) ?? Foo.DEF?)); - io::printfn("7:%s", @catch((3 < 2 ? Foo.ABC? : 4) ?? Foo.DEF?)); - long x = Foo.DEF? ?? 3; + io::printfn("4:%s", @catch(ABC? ?? DEF?)); + io::printfn("5:%s", ABC? ?? 3); + io::printfn("6:%s", @catch((3 > 2 ? ABC? : 4) ?? DEF?)); + io::printfn("7:%s", @catch((3 < 2 ? ABC? : 4) ?? DEF?)); + long x = DEF? ?? 3; io::printfn("8:%s", x); - int! xy = Foo.ABC? ?? Foo.DEF?; + int? xy = ABC? ?? DEF?; } -fn int! get_a(int x) +fn int? get_a(int x) { - if (x % 2) return Foo.ABC?; + if (x % 2) return ABC?; return x * 2; } -fn int! get_b(int x) +fn int? get_b(int x) { - if (x % 2 == 0) return Foo.ABC?; + if (x % 2 == 0) return ABC?; return x * 2; } @@ -134,7 +134,7 @@ phi_block21: ; preds = %phi_block19, %after %15 = insertvalue %any undef, ptr %taddr23, 0 %16 = insertvalue %any %15, i64 ptrtoint (ptr @"$ct.int" to i64), 1 store %any %16, ptr %varargslots10, align 16 - %17 = call i64 @std.io.printfn(ptr %retparam24, ptr @.str.2, i64 4, ptr %varargslots10, i64 1) + %17 = call i64 @std.io.printfn(ptr %retparam24, ptr @.str.1, i64 4, ptr %varargslots10, i64 1) %18 = call i64 @test.get_a(ptr %retparam28, i32 1) %not_err29 = icmp eq i64 %18, 0 %19 = call i1 @llvm.expect.i1(i1 %not_err29, i1 true) @@ -167,11 +167,11 @@ phi_block38: ; preds = %phi_block36, %after %24 = insertvalue %any undef, ptr %taddr40, 0 %25 = insertvalue %any %24, i64 ptrtoint (ptr @"$ct.int" to i64), 1 store %any %25, ptr %varargslots27, align 16 - %26 = call i64 @std.io.printfn(ptr %retparam41, ptr @.str.3, i64 4, ptr %varargslots27, i64 1) + %26 = call i64 @std.io.printfn(ptr %retparam41, ptr @.str.2, i64 4, ptr %varargslots27, i64 1) br label %testblock testblock: ; preds = %phi_block38 - store i64 ptrtoint (ptr @"test.Foo$DEF" to i64), ptr %f, align 8 + store i64 ptrtoint (ptr @test.DEF to i64), ptr %f, align 8 br label %end_block end_block: ; preds = %testblock @@ -192,16 +192,16 @@ expr_block.exit: ; preds = %if.exit, %if.then %29 = insertvalue %any undef, ptr %blockret, 0 %30 = insertvalue %any %29, i64 ptrtoint (ptr @"$ct.anyfault" to i64), 1 store %any %30, ptr %varargslots44, align 16 - %31 = call i64 @std.io.printfn(ptr %retparam45, ptr @.str.4, i64 4, ptr %varargslots44, i64 1) + %31 = call i64 @std.io.printfn(ptr %retparam45, ptr @.str.3, i64 4, ptr %varargslots44, i64 1) store i32 3, ptr %taddr49, align 4 %32 = insertvalue %any undef, ptr %taddr49, 0 %33 = insertvalue %any %32, i64 ptrtoint (ptr @"$ct.int" to i64), 1 store %any %33, ptr %varargslots48, align 16 - %34 = call i64 @std.io.printfn(ptr %retparam50, ptr @.str.5, i64 4, ptr %varargslots48, i64 1) + %34 = call i64 @std.io.printfn(ptr %retparam50, ptr @.str.4, i64 4, ptr %varargslots48, i64 1) br label %testblock56 testblock56: ; preds = %expr_block.exit - store i64 ptrtoint (ptr @"test.Foo$DEF" to i64), ptr %f55, align 8 + store i64 ptrtoint (ptr @test.DEF to i64), ptr %f55, align 8 br label %end_block57 end_block57: ; preds = %testblock56 @@ -222,7 +222,7 @@ expr_block.exit61: ; preds = %if.exit60, %if.then %37 = insertvalue %any undef, ptr %blockret54, 0 %38 = insertvalue %any %37, i64 ptrtoint (ptr @"$ct.anyfault" to i64), 1 store %any %38, ptr %varargslots53, align 16 - %39 = call i64 @std.io.printfn(ptr %retparam62, ptr @.str.6, i64 4, ptr %varargslots53, i64 1) + %39 = call i64 @std.io.printfn(ptr %retparam62, ptr @.str.5, i64 4, ptr %varargslots53, i64 1) br label %testblock68 testblock68: ; preds = %expr_block.exit61 @@ -250,13 +250,13 @@ expr_block.exit75: ; preds = %if.exit74, %if.then %42 = insertvalue %any undef, ptr %blockret66, 0 %43 = insertvalue %any %42, i64 ptrtoint (ptr @"$ct.anyfault" to i64), 1 store %any %43, ptr %varargslots65, align 16 - %44 = call i64 @std.io.printfn(ptr %retparam76, ptr @.str.7, i64 4, ptr %varargslots65, i64 1) + %44 = call i64 @std.io.printfn(ptr %retparam76, ptr @.str.6, i64 4, ptr %varargslots65, i64 1) store i64 3, ptr %x, align 8 %45 = insertvalue %any undef, ptr %x, 0 %46 = insertvalue %any %45, i64 ptrtoint (ptr @"$ct.long" to i64), 1 store %any %46, ptr %varargslots79, align 16 - %47 = call i64 @std.io.printfn(ptr %retparam80, ptr @.str.8, i64 4, ptr %varargslots79, i64 1) - store i64 ptrtoint (ptr @"test.Foo$DEF" to i64), ptr %xy.f, align 8 + %47 = call i64 @std.io.printfn(ptr %retparam80, ptr @.str.7, i64 4, ptr %varargslots79, i64 1) + store i64 ptrtoint (ptr @test.DEF to i64), ptr %xy.f, align 8 ret void } @@ -269,7 +269,7 @@ entry: br i1 %i2b, label %if.then, label %if.exit if.then: ; preds = %entry - ret i64 ptrtoint (ptr @"test.Foo$ABC" to i64) + ret i64 ptrtoint (ptr @test.ABC to i64) if.exit: ; preds = %entry %mul = mul i32 %1, 2 @@ -286,7 +286,7 @@ entry: br i1 %eq, label %if.then, label %if.exit if.then: ; preds = %entry - ret i64 ptrtoint (ptr @"test.Foo$ABC" to i64) + ret i64 ptrtoint (ptr @test.ABC to i64) if.exit: ; preds = %entry %mul = mul i32 %1, 2 diff --git a/test/test_suite/errors/or_and_rethrow.c3t b/test/test_suite/errors/or_and_rethrow.c3t index cdfad2bb4..37d5de2b1 100644 --- a/test/test_suite/errors/or_and_rethrow.c3t +++ b/test/test_suite/errors/or_and_rethrow.c3t @@ -2,16 +2,16 @@ module foo; import std::io; -fault Foo { ABC } +fault ABC; fn void blurb() { io::printn("Blurb");} -macro int! tester() +macro int? tester() { defer blurb(); - return Foo.ABC?; + return ABC?; } -fn void! test(int x) +fn void? test(int x) { io::printfn("test(%d)", x); if (x || (tester()!)) io::printn("Ok1"); @@ -20,7 +20,7 @@ fn void! test(int x) io::printn("Test ok"); } -fn void! test2(int x) +fn void? test2(int x) { io::printfn("test2(%d)", x); if (x && (tester()!)) io::printn("Ok1"); @@ -67,7 +67,7 @@ entry: br i1 %i2b, label %or.phi, label %or.rhs or.rhs: ; preds = %entry - store i64 ptrtoint (ptr @"foo.Foo$ABC" to i64), ptr %error_var, align 8 + store i64 ptrtoint (ptr @foo.ABC to i64), ptr %error_var, align 8 br label %opt_block_cleanup opt_block_cleanup: ; preds = %or.rhs @@ -197,7 +197,7 @@ noerr_block39: ; preds = %after_check37 br label %voiderr41 voiderr41: ; preds = %noerr_block39, %guard_block38, %guard_block32, %guard_block26 - store i64 ptrtoint (ptr @"foo.Foo$ABC" to i64), ptr %error_var42, align 8 + store i64 ptrtoint (ptr @foo.ABC to i64), ptr %error_var42, align 8 br label %opt_block_cleanup44 opt_block_cleanup44: ; preds = %voiderr41 @@ -233,7 +233,7 @@ entry: br i1 %i2b, label %and.rhs, label %and.phi and.rhs: ; preds = %entry - store i64 ptrtoint (ptr @"foo.Foo$ABC" to i64), ptr %error_var, align 8 + store i64 ptrtoint (ptr @foo.ABC to i64), ptr %error_var, align 8 br label %opt_block_cleanup opt_block_cleanup: ; preds = %and.rhs @@ -304,7 +304,7 @@ noerr_block17: ; preds = %after_check15 br label %voiderr voiderr: ; preds = %noerr_block17, %guard_block16, %guard_block10, %guard_block5 - store i64 ptrtoint (ptr @"foo.Foo$ABC" to i64), ptr %error_var18, align 8 + store i64 ptrtoint (ptr @foo.ABC to i64), ptr %error_var18, align 8 br label %opt_block_cleanup20 opt_block_cleanup20: ; preds = %voiderr diff --git a/test/test_suite/errors/or_err_bool.c3t b/test/test_suite/errors/or_err_bool.c3t index 4a0b48e15..eba50e3d6 100644 --- a/test/test_suite/errors/or_err_bool.c3t +++ b/test/test_suite/errors/or_err_bool.c3t @@ -4,7 +4,7 @@ module test; fn void tester() { - bool! x = false; + bool? x = false; x ?? true; } diff --git a/test/test_suite/errors/or_err_infer.c3t b/test/test_suite/errors/or_err_infer.c3t index cda307534..6314c1705 100644 --- a/test/test_suite/errors/or_err_infer.c3t +++ b/test/test_suite/errors/or_err_infer.c3t @@ -8,7 +8,7 @@ enum Foo fn int main() { int a; - Foo! x = ABC; + Foo? x = ABC; Foo f = x ?? DEF; return 0; } diff --git a/test/test_suite/errors/printing_errors.c3t b/test/test_suite/errors/printing_errors.c3t index 4472a92c2..a91a50353 100644 --- a/test/test_suite/errors/printing_errors.c3t +++ b/test/test_suite/errors/printing_errors.c3t @@ -2,15 +2,11 @@ module test; import std::io; -fault Cde -{ - HELLO, - WORLD, -} +fault HELLO, WORLD; fn void main() { - anyfault x = Cde.WORLD; - io::printf("%s %s\n", Cde.HELLO.nameof, x.nameof); + anyfault x = WORLD; + io::printf("%s %s\n", HELLO.nameof, x.nameof); } /* #expect: test.ll @@ -22,8 +18,8 @@ entry: %taddr = alloca %"char[]", align 8 %faultname_zero = alloca %"char[]", align 8 %retparam = alloca i64, align 8 - store i64 ptrtoint (ptr @"test.Cde$WORLD" to i64), ptr %x, align 8 - store %"char[]" { ptr @.str.2, i64 5 }, ptr %taddr, align 8 + store i64 ptrtoint (ptr @test.WORLD to i64), ptr %x, align 8 + store %"char[]" { ptr @.str.1, i64 5 }, ptr %taddr, align 8 %0 = insertvalue %any undef, ptr %taddr, 0 %1 = insertvalue %any %0, i64 ptrtoint (ptr @"$ct.String" to i64), 1 store %any %1, ptr %varargslots, align 16 @@ -37,16 +33,15 @@ faultname_no: ; preds = %entry faultname_ok: ; preds = %entry %3 = inttoptr i64 %2 to ptr - %4 = getelementptr inbounds br label %faultname_exit faultname_exit: ; preds = %faultname_ok, %faultname_no - %faultname = phi ptr [ %faultname_zero, %faultname_no ], [ %4, %faultname_ok ] - %5 = insertvalue %any undef, ptr %faultname, 0 - %6 = insertvalue %any %5, i64 ptrtoint (ptr @"$ct.String" to i64), 1 + %faultname = phi ptr [ %faultname_zero, %faultname_no ], [ %3, %faultname_ok ] + %4 = insertvalue %any undef, ptr %faultname, 0 + %5 = insertvalue %any %4, i64 ptrtoint (ptr @"$ct.String" to i64), 1 %ptradd = getelementptr inbounds i8, ptr %varargslots, i64 16 - store %any %6, ptr %ptradd, align 16 - %7 = call i64 @std.io.printf(ptr %retparam, ptr @.str, i64 6, ptr %varargslots, i64 2) + store %any %5, ptr %ptradd, align 16 + %6 = call i64 @std.io.printf(ptr %retparam, ptr @.str, i64 6, ptr %varargslots, i64 2) ret void } diff --git a/test/test_suite/errors/rethrow.c3t b/test/test_suite/errors/rethrow.c3t index c94875567..32c9cbb90 100644 --- a/test/test_suite/errors/rethrow.c3t +++ b/test/test_suite/errors/rethrow.c3t @@ -1,8 +1,8 @@ // #target: macos-x64 -fn void! test() +fn void? test() { - int! i; + int? i; i!; } diff --git a/test/test_suite/errors/rethrow_mingw.c3t b/test/test_suite/errors/rethrow_mingw.c3t index 9713916ee..dfc24c683 100644 --- a/test/test_suite/errors/rethrow_mingw.c3t +++ b/test/test_suite/errors/rethrow_mingw.c3t @@ -2,9 +2,9 @@ module rethrow; -fn void! test() +fn void? test() { - int! i; + int? i; i!; } diff --git a/test/test_suite/errors/rethrow_no_err.c3 b/test/test_suite/errors/rethrow_no_err.c3 index 0a86ff526..9244ddf8c 100644 --- a/test/test_suite/errors/rethrow_no_err.c3 +++ b/test/test_suite/errors/rethrow_no_err.c3 @@ -4,14 +4,14 @@ fn void test() test()!; // #error: No optional to rethrow before '!' in the expression, please remove '!' int i = 0; if (i!) return; // #error: No optional to rethrow before '!' in the expression, please remove '!' - int! j = 0; + int? j = 0; if (j!) return; // #error: This expression implicitly returns with an optional result, but the function if ((j!)!) return; // #error: This expression implicitly returns with an optional result, but the function } -fn void! test2() +fn void? test2() { - int! j = 0; + int? j = 0; if (j!) return; if ((j!)!) return; // #error: No optional to rethrow before '!' in the expression, please remove '!' } \ No newline at end of file diff --git a/test/test_suite/errors/simple_static_failable.c3t b/test/test_suite/errors/simple_static_failable.c3t index d284b40cb..313b0ba21 100644 --- a/test/test_suite/errors/simple_static_failable.c3t +++ b/test/test_suite/errors/simple_static_failable.c3t @@ -2,15 +2,12 @@ module foo; -fault Blurg -{ - Y -} +fault Y; fn void main() { - static int! x = 120; - int! i = Blurg.Y?; + static int? x = 120; + int? i = Y?; } /* #expect: foo.ll @@ -19,6 +16,6 @@ define void @foo.main() #0 { entry: %i = alloca i32, align 4 %i.f = alloca i64, align 8 - store i64 ptrtoint (ptr @"foo.Blurg$Y" to i64), ptr %i.f, align 8 + store i64 ptrtoint (ptr @foo.Y to i64), ptr %i.f, align 8 ret void } \ No newline at end of file diff --git a/test/test_suite/errors/ternary_void_fault.c3t b/test/test_suite/errors/ternary_void_fault.c3t index d8a279213..2e1ada61c 100644 --- a/test/test_suite/errors/ternary_void_fault.c3t +++ b/test/test_suite/errors/ternary_void_fault.c3t @@ -1,6 +1,6 @@ // #target: macos-x64 module test; -fn void! x() {} +fn void? x() {} fn void main() { int a; diff --git a/test/test_suite/errors/try_assign.c3t b/test/test_suite/errors/try_assign.c3t index eafbee252..fba1f22ab 100644 --- a/test/test_suite/errors/try_assign.c3t +++ b/test/test_suite/errors/try_assign.c3t @@ -1,13 +1,13 @@ // #target: macos-x64 -extern fn int! err(); -fault FooErr { QBERT } +extern fn int? err(); +fault QBERT; extern fn int printf(char* fmt, ...); fn void main() { - int! z = 234; - int! w; + int? z = 234; + int? w; if (try x = z && try gh = w) { printf("Success %d && %d!\n", x, gh); diff --git a/test/test_suite/errors/try_catch_if.c3t b/test/test_suite/errors/try_catch_if.c3t index 10479e060..86b8b0cb0 100644 --- a/test/test_suite/errors/try_catch_if.c3t +++ b/test/test_suite/errors/try_catch_if.c3t @@ -7,19 +7,17 @@ fn int hello(int x) extern fn int printf(char *c, ...); -fn int! tester() +fn int? tester() { printf("In tester\n"); return 222; } -fault Foo -{ - A -} +fault A; + fn void test1() { - int! a = 123; + int? a = 123; if (catch err = a, tester()) { printf("Err\n"); diff --git a/test/test_suite/errors/try_catch_unwrapping_while_if.c3 b/test/test_suite/errors/try_catch_unwrapping_while_if.c3 index 2153a110f..20fb8909c 100644 --- a/test/test_suite/errors/try_catch_unwrapping_while_if.c3 +++ b/test/test_suite/errors/try_catch_unwrapping_while_if.c3 @@ -1,26 +1,24 @@ extern fn int printf(char* fmt, ...); -extern fn int! err(); -fault FooErr -{ - X -} +extern fn int? err(); +fault X; + fn void test1() { - int! z = 234; + int? z = 234; if (try z) { int y = z; z = 12; - z = FooErr.X?; // #error: The variable is unwrapped in this context + z = X?; // #error: The variable is unwrapped in this context } } fn void test4() { - int! z = 234; - int! w = 123; + int? z = 234; + int? w = 123; if (try z && try w && 1) { int y = z; @@ -30,8 +28,8 @@ fn void test4() fn void test5() { - int! z = 234; - int! w = 123; + int? z = 234; + int? w = 123; if (try z && try w) { int y = z; @@ -39,8 +37,8 @@ fn void test5() } fn void test5b() { - int! z = 234; - int! w = 123; + int? z = 234; + int? w = 123; if (try z && try z) // #error: This variable is already unwrapped, so you cannot use 'try' on it again, please remove the 'try'. { int y = z; @@ -49,8 +47,8 @@ fn void test5b() fn void test6() { - int! z = 234; - int! w = 123; + int? z = 234; + int? w = 123; while (try z) { int y = z; @@ -60,8 +58,8 @@ fn void test6() fn void test7() { - int! z = 234; - int! w = 123; + int? z = 234; + int? w = 123; if (catch z) { } @@ -73,8 +71,8 @@ fn void test7() fn void test8() { - int! z = 234; - int! w = 123; + int? z = 234; + int? w = 123; if (catch z) { } @@ -85,8 +83,8 @@ fn void test8() } fn void test9() { - int! z = 234; - int! w = 123; + int? z = 234; + int? w = 123; if (catch e = z) { } diff --git a/test/test_suite/errors/try_expr.c3t b/test/test_suite/errors/try_expr.c3t index 9ca8de6f2..e1338cef8 100644 --- a/test/test_suite/errors/try_expr.c3t +++ b/test/test_suite/errors/try_expr.c3t @@ -15,7 +15,7 @@ fn void main() } } -fn void! foo() {} +fn void? foo() {} /* #expect: foo.ll diff --git a/test/test_suite/errors/try_unwrap_using_assert.c3 b/test/test_suite/errors/try_unwrap_using_assert.c3 index 3d6738861..107b72b21 100644 --- a/test/test_suite/errors/try_unwrap_using_assert.c3 +++ b/test/test_suite/errors/try_unwrap_using_assert.c3 @@ -1,10 +1,10 @@ module test; -extern fn int! maybe(); +extern fn int? maybe(); fn int tester(int n) { - int! num = maybe(); + int? num = maybe(); assert(try num, "Hello"); // #error: An expression was expected int x = num; return num; diff --git a/test/test_suite/errors/try_with_assign_to_failable.c3 b/test/test_suite/errors/try_with_assign_to_failable.c3 index 57c054fcd..f3c9c57ab 100644 --- a/test/test_suite/errors/try_with_assign_to_failable.c3 +++ b/test/test_suite/errors/try_with_assign_to_failable.c3 @@ -1,6 +1,6 @@ fn void test() { - int! z; - int! w; + int? z; + int? w; try w = z; // #error: can only be used when unwrapping an optional } diff --git a/test/test_suite/errors/try_with_chained_unwrap.c3t b/test/test_suite/errors/try_with_chained_unwrap.c3t index 5a34b82b8..c38bf68e7 100644 --- a/test/test_suite/errors/try_with_chained_unwrap.c3t +++ b/test/test_suite/errors/try_with_chained_unwrap.c3t @@ -1,7 +1,7 @@ // #target: macos-x64 -extern fn char*! readLine(); -extern fn int! atoi(char*); +extern fn char*? readLine(); +extern fn int? atoi(char*); extern fn int printf(char* fmt, ...); diff --git a/test/test_suite/errors/try_with_chained_unwrap_errors.c3 b/test/test_suite/errors/try_with_chained_unwrap_errors.c3 index 29b71f47d..4265d5f53 100644 --- a/test/test_suite/errors/try_with_chained_unwrap_errors.c3 +++ b/test/test_suite/errors/try_with_chained_unwrap_errors.c3 @@ -1,12 +1,12 @@ fn void test() { - int! a; + int? a; int b; if (try int b = a) {} // #error: 'b' would shadow a previous declaration. } fn void test2() { - int! a; + int? a; if (try b = a) {} if (try test2 = a) {} } @@ -16,7 +16,7 @@ const int BAZ = 1; fn void test3() { - int! a; + int? a; int b; if (try BAZ = a) {} // #error: lower case } @@ -25,14 +25,14 @@ fn void test3() fn void test4() { - int! a; + int? a; if (try b = 1) {} // #error: remove 'try' } fn void test5() { - int! a; + int? a; int b; if (try a = a) {} // #error: if (try a) } @@ -40,24 +40,24 @@ fn void test5() fn void test6() { - int! a; + int? a; int b; - int*! x; + int*? x; if (try *x = a) {} // #error: variable name } fn void test7() { - int! a; + int? a; int b; - int*! x; + int*? x; if (try foo::z = a) {} // #error: The variable may not have a path. } fn void test8() { - int! a; + int? a; int e; if (e == 0, try c = a && try d = a && e > 0) {} if (try b = a && try c = a && e > 0) {} @@ -66,7 +66,7 @@ fn void test8() fn void test9() { - int! a = 11; + int? a = 11; if (try z = a) { int g = z++; @@ -79,13 +79,13 @@ fn void test9() fn void test10() { - int! a = 11; + int? a = 11; if (try a) { int g = a; } else { - int g = a; // #error: 'int!' to 'int' + int g = a; // #error: 'int?' to 'int' } } \ No newline at end of file diff --git a/test/test_suite/errors/try_with_unwrap.c3t b/test/test_suite/errors/try_with_unwrap.c3t index 46379c269..8bb30dc1e 100644 --- a/test/test_suite/errors/try_with_unwrap.c3t +++ b/test/test_suite/errors/try_with_unwrap.c3t @@ -1,15 +1,15 @@ // #target: macos-x64 -extern fn char*! readLine(); -extern fn int! atoi(char*); +extern fn char*? readLine(); +extern fn int? atoi(char*); extern fn int printf(char* fmt, ...); fn void main() { - char*! line = readLine(); + char*? line = readLine(); if (try line) { - int! val = atoi(line); + int? val = atoi(line); if (try val) { printf("You typed the number %d\n", val); diff --git a/test/test_suite/errors/try_with_unwrapper.c3t b/test/test_suite/errors/try_with_unwrapper.c3t index bdc5f79da..833d0b803 100644 --- a/test/test_suite/errors/try_with_unwrapper.c3t +++ b/test/test_suite/errors/try_with_unwrapper.c3t @@ -7,19 +7,17 @@ fn int hello(int x) extern fn int printf(char *c, ...); -fn int! tester() +fn int? tester() { printf("In tester\n"); return 222; } -fault Foo -{ - A -} +fault A; + fn void test1() { - int! a = 11; + int? a = 11; if (try int b = a && try int c = tester()) { printf("%d\n", hello(b)); @@ -33,7 +31,7 @@ fn void main() fn void test2() { - int! a; + int? a; if (try int b = a && hello(b)) { hello(b + 1); diff --git a/test/test_suite/errors/try_with_weird_stuff.c3 b/test/test_suite/errors/try_with_weird_stuff.c3 index 2cf0bdf0f..50ab9933d 100644 --- a/test/test_suite/errors/try_with_weird_stuff.c3 +++ b/test/test_suite/errors/try_with_weird_stuff.c3 @@ -1,16 +1,16 @@ fn void test1() { - int! a; + int? a; int b; - int*! x; + int*? x; if (try int 1 = a) {} // #error: A new variable was expected. } fn void test2() { - int! a; + int? a; int b; - int*! x; + int*? x; if (try foo::z = a, b += 1) {} // #error: The 'try' must be placed last, can you change it? } \ No newline at end of file diff --git a/test/test_suite/errors/type_optional_declaration_order.c3 b/test/test_suite/errors/type_optional_declaration_order.c3 index 1ea98e202..fa14f0bce 100644 --- a/test/test_suite/errors/type_optional_declaration_order.c3 +++ b/test/test_suite/errors/type_optional_declaration_order.c3 @@ -1,27 +1,27 @@ import std::io; -fn void! test1() +fn void? test1() { - CallbackResult![] result = 123; // #error: Foo[]! + CallbackResult?[] result = 123; // #error: Foo[]? } -fn void! test2() +fn void? test2() { - CallbackResult![?] result = 123; // #error: Foo[?]! + CallbackResult?[*] result = 123; // #error: Foo[*]? } -fn void! test3() +fn void? test3() { - CallbackResult![4 + 5] result = 123; // #error: Foo[4]! + CallbackResult?[4 + 5] result = 123; // #error: Foo[4]? } -fn void! test4() +fn void? test4() { - CallbackResult![] result = 123; // #error: Foo[]! + CallbackResult?[<*>] result = 123; // #error: Foo[<*>]? } -fn void! test5() +fn void? test5() { - CallbackResult![] result = 123; // #error: Foo[<4>]! + CallbackResult?[] result = 123; // #error: Foo[<4>]? } diff --git a/test/test_suite/expressions/addr_of_fails.c3 b/test/test_suite/expressions/addr_of_fails.c3 index f8c1fcbb3..b2c24e647 100644 --- a/test/test_suite/expressions/addr_of_fails.c3 +++ b/test/test_suite/expressions/addr_of_fails.c3 @@ -62,7 +62,7 @@ fn void test6() def Baz = Foo; distinct Bar = int; -fault Err { FOO } +fault FOO; union Un { int x; } enum MyEnum { BAR } @@ -70,9 +70,8 @@ fn void test7() { &Baz; // #error: It is not possible to take the address of a type. &Bar; // #error: It is not possible to take the address of a type. - &Err; // #error: It is not possible to take the address of a type. &Un; // #error: It is not possible to take the address of a type. - &Err.FOO; // #error: To take the address of a temporary value, use '&&' instead of '&' + &FOO; // #error: To take the address of a temporary value, use '&&' &MyEnum; // #error: It is not possible to take the address of a type. &MyEnum.BAR; // #error: To take the address of a temporary value, use '&&' instead of '&' } diff --git a/test/test_suite/expressions/arithmetics_sema_fail.c3 b/test/test_suite/expressions/arithmetics_sema_fail.c3 index 5612ed71e..19033a548 100644 --- a/test/test_suite/expressions/arithmetics_sema_fail.c3 +++ b/test/test_suite/expressions/arithmetics_sema_fail.c3 @@ -1,7 +1,7 @@ fn void test7() { - double x = 1.2 / 0; // This is ok! NaN + double x = 1.2 / 0; // This is ok? NaN } fn void test8() diff --git a/test/test_suite/expressions/assign_deref_opt.c3 b/test/test_suite/expressions/assign_deref_opt.c3 index 5f4584533..8ea166c52 100644 --- a/test/test_suite/expressions/assign_deref_opt.c3 +++ b/test/test_suite/expressions/assign_deref_opt.c3 @@ -2,8 +2,8 @@ module test; fn void main() { - int! a; - int*! b; + int? a; + int*? b; *b = a; // #error: You cannot assign to a dereferenced optional } diff --git a/test/test_suite/expressions/assign_optional.c3t b/test/test_suite/expressions/assign_optional.c3t index d61fcf34d..4a2de4837 100644 --- a/test/test_suite/expressions/assign_optional.c3t +++ b/test/test_suite/expressions/assign_optional.c3t @@ -3,10 +3,10 @@ module test; fn void main() { - anyfault x = SearchResult.MISSING; - int! a = x?; - int! b = a = x?; - int! c = b = a; + anyfault x = NOT_FOUND; + int? a = x?; + int? b = a = x?; + int? c = b = a; } /* #expect: test.ll @@ -20,7 +20,7 @@ entry: %b.f = alloca i64, align 8 %c = alloca i32, align 4 %c.f = alloca i64, align 8 - store i64 ptrtoint (ptr @"std.core.builtin.SearchResult$MISSING" to i64), ptr %x, align 8 + store i64 ptrtoint (ptr @std.core.builtin.NOT_FOUND to i64), ptr %x, align 8 %0 = load i64, ptr %x, align 8 store i64 %0, ptr %a.f, align 8 %1 = load i64, ptr %x, align 8 diff --git a/test/test_suite/expressions/casts/cast_failable.c3 b/test/test_suite/expressions/casts/cast_failable.c3 index fdfaa6954..bb8a1cb86 100644 --- a/test/test_suite/expressions/casts/cast_failable.c3 +++ b/test/test_suite/expressions/casts/cast_failable.c3 @@ -1,10 +1,7 @@ -fault MyErr -{ - FOO -} +fault FOO; fn void test() { - int! x = (int!)(MyErr.FOO?); // #error: Casting to an optional type is not - int! y = MyErr.FOO?; + int? x = (int?)(FOO?); // #error: Casting to an optional type is not + int? y = FOO?; } \ No newline at end of file diff --git a/test/test_suite/expressions/casts/struct_cast_and_distinct.c3 b/test/test_suite/expressions/casts/struct_cast_and_distinct.c3 index a4864337c..c18c228fc 100644 --- a/test/test_suite/expressions/casts/struct_cast_and_distinct.c3 +++ b/test/test_suite/expressions/casts/struct_cast_and_distinct.c3 @@ -4,20 +4,20 @@ distinct Foo = int; fn void test1() { - int[2][?] x = { { 2, 3}, { 5, 6 }}; + int[2][*] x = { { 2, 3}, { 5, 6 }}; Foo[2][2] y = x; // #error: explicit cast } fn void test2() { - int[2][?] x = { { 2, 3}, { 5, 6 }}; + int[2][*] x = { { 2, 3}, { 5, 6 }}; Foo[2][2] y = (Foo[2][2])x; } fn void test3() { - int[2][?] x = { { 2, 3}, { 5, 6 }}; + int[2][*] x = { { 2, 3}, { 5, 6 }}; Foo[2][2]* y = &x; // #error: explicit cast } @@ -27,6 +27,6 @@ struct Baz { int x; } fn void test4() { - Baz[2][?] x = { { { 2 } , { 3 } }, {{5}, {6} }}; - Bar[?][?] y = (Bar[2][2])x; + Baz[2][*] x = { { { 2 } , { 3 } }, {{5}, {6} }}; + Bar[*][*] y = (Bar[2][2])x; } diff --git a/test/test_suite/expressions/casts/void_casting.c3t b/test/test_suite/expressions/casts/void_casting.c3t index 8cdcff296..0680e36ca 100644 --- a/test/test_suite/expressions/casts/void_casting.c3t +++ b/test/test_suite/expressions/casts/void_casting.c3t @@ -1,17 +1,17 @@ // #target: macos-x64 module test; -fn void! foo() +fn void? foo() {} -fault Abc { AAA } +fault AAA; -macro int! bar() +macro int? bar() { - return Abc.AAA?; + return AAA?; } -fn int! baz() +fn int? baz() { return 2; } @@ -19,7 +19,7 @@ fn int! baz() fn int main() { int x; - int! y; + int? y; (void)x; (void)y; (void)foo(); diff --git a/test/test_suite/expressions/chained_ternary.c3t b/test/test_suite/expressions/chained_ternary.c3t index 28bf22952..99f1c1f9a 100644 --- a/test/test_suite/expressions/chained_ternary.c3t +++ b/test/test_suite/expressions/chained_ternary.c3t @@ -1,7 +1,7 @@ // #target: macos-x64 module test; -fault Test { FOO, BAR } +fault FOO, BAR; fn void test() { @@ -9,13 +9,13 @@ fn void test() void* b; void* c; a = !a ? a : !a ? b : c; - void*! x; - void*! y = !a ? x : b; + void*? x; + void*? y = !a ? x : b; y = !a ? b : x; y = !a ? x : x; - y = !a ? x : Test.FOO?; - y = !a ? Test.FOO? : x; - y = !a ? Test.FOO? : Test.BAR?; + y = !a ? x : FOO?; + y = !a ? FOO? : x; + y = !a ? FOO? : BAR?; } /* #expect: test.ll @@ -166,7 +166,7 @@ after_check40: ; preds = %cond.lhs36 br label %cond.phi42 cond.rhs41: ; preds = %after_assign34 - store i64 ptrtoint (ptr @"test.Test$FOO" to i64), ptr %y.f, align 8 + store i64 ptrtoint (ptr @test.FOO to i64), ptr %y.f, align 8 br label %after_assign43 cond.phi42: ; preds = %after_check40 @@ -180,7 +180,7 @@ after_assign43: ; preds = %cond.phi42, %cond.r br i1 %i2nb44, label %cond.lhs45, label %cond.rhs46 cond.lhs45: ; preds = %after_assign43 - store i64 ptrtoint (ptr @"test.Test$FOO" to i64), ptr %y.f, align 8 + store i64 ptrtoint (ptr @test.FOO to i64), ptr %y.f, align 8 br label %after_assign52 cond.rhs46: ; preds = %after_assign43 @@ -208,11 +208,11 @@ after_assign52: ; preds = %cond.phi51, %assign br i1 %i2nb53, label %cond.lhs54, label %cond.rhs55 cond.lhs54: ; preds = %after_assign52 - store i64 ptrtoint (ptr @"test.Test$FOO" to i64), ptr %y.f, align 8 + store i64 ptrtoint (ptr @test.FOO to i64), ptr %y.f, align 8 br label %after_assign57 cond.rhs55: ; preds = %after_assign52 - store i64 ptrtoint (ptr @"test.Test$BAR" to i64), ptr %y.f, align 8 + store i64 ptrtoint (ptr @test.BAR to i64), ptr %y.f, align 8 br label %after_assign57 after_assign57: ; preds = %cond.rhs55, %cond.lhs54 diff --git a/test/test_suite/expressions/incdec_overload.c3t b/test/test_suite/expressions/incdec_overload.c3t index 1ebc40b92..eee10250b 100644 --- a/test/test_suite/expressions/incdec_overload.c3t +++ b/test/test_suite/expressions/incdec_overload.c3t @@ -7,7 +7,7 @@ Abc m; fn void main() { m[3] = 100; - int! x = m[3]--; + int? x = m[3]--; assert(m[3]!! == 99); assert(x!! == 100); x = ++m[3]; diff --git a/test/test_suite/expressions/negate_int.c3 b/test/test_suite/expressions/negate_int.c3 index cf7c367d8..b35036fb1 100644 --- a/test/test_suite/expressions/negate_int.c3 +++ b/test/test_suite/expressions/negate_int.c3 @@ -1,41 +1,41 @@ fn void test1() { - short! a = 1; + short? a = 1; @ok(-a); - short b = -a; // #error: 'short!' to 'short'. + short b = -a; // #error: 'short?' to 'short'. } fn void test2() { - int! a = 1; + int? a = 1; @ok(-a); - int b = -a; // #error: 'int!' to 'int' + int b = -a; // #error: 'int?' to 'int' } fn void test3() { - long! a = 1; + long? a = 1; @ok(-a); - long b = -a; // #error: 'long!' to 'long' + long b = -a; // #error: 'long?' to 'long' } fn void test4() { - short! a = 1; + short? a = 1; @ok(~a); - short b = ~a; // #error: 'short!' to 'short' + short b = ~a; // #error: 'short?' to 'short' } fn void test5() { - int! a = 1; + int? a = 1; @ok(~a); - int b = ~a; // #error: 'int!' to 'int' + int b = ~a; // #error: 'int?' to 'int' } fn void test6() { - long! a = 1; + long? a = 1; @ok(~a); - long b = ~a; // #error: 'long!' to 'long' + long b = ~a; // #error: 'long?' to 'long' } diff --git a/test/test_suite/expressions/opt_in_conv.c3 b/test/test_suite/expressions/opt_in_conv.c3 index 6b1dce090..39169e8e4 100644 --- a/test/test_suite/expressions/opt_in_conv.c3 +++ b/test/test_suite/expressions/opt_in_conv.c3 @@ -4,6 +4,6 @@ fn void main() { String s = "Hello"; Char16* title = String.to_utf16(s, mem).ptr; // #error: It is not possible to cast from - int! a; + int? a; float b = (float)a; // #error: It is not possible to cast from } \ No newline at end of file diff --git a/test/test_suite/expressions/optional_and_error.c3 b/test/test_suite/expressions/optional_and_error.c3 index aa9ce69ed..30cea920a 100644 --- a/test/test_suite/expressions/optional_and_error.c3 +++ b/test/test_suite/expressions/optional_and_error.c3 @@ -7,7 +7,7 @@ fn void main() if (ok && !foo()) io::printfn("nok"); // #error: The expression may not be an optional } -fn bool! foo() +fn bool? foo() { return false; } \ No newline at end of file diff --git a/test/test_suite/expressions/optional_ternary.c3t b/test/test_suite/expressions/optional_ternary.c3t index f29a7876b..76746daeb 100644 --- a/test/test_suite/expressions/optional_ternary.c3t +++ b/test/test_suite/expressions/optional_ternary.c3t @@ -2,49 +2,46 @@ module test; -fault Foo +fault X; + +fn int? test(int i) { - X + return i ?: X?; } -fn int! test(int i) +fn int? test2(int i) { - return i ?: Foo.X?; -} - -fn int! test2(int i) -{ - return i ? Foo.X? : Foo.X?; + return i ? X? : X?; } -fn int! test3(int i) +fn int? test3(int i) { - return i ? 2 : Foo.X?; + return i ? 2 : X?; } -fn int! test4(int i) +fn int? test4(int i) { - int! y = i; - return (y!) ?: Foo.X?; + int? y = i; + return (y!) ?: X?; } -fn int! test5(int i) +fn int? test5(int i) { - int! y = i; - return (y!) ? Foo.X? : Foo.X?; + int? y = i; + return (y!) ? X? : X?; } -fn int! test6(int i) +fn int? test6(int i) { - int! y = i; - return (y!) ? 2 : Foo.X?; + int? y = i; + return (y!) ? 2 : X?; } -fn int! test7(int i) +fn int? test7(int i) { - int! y = i; - return (y!) ? Foo.X? : 2; + int? y = i; + return (y!) ? X? : 2; } fn void main() @@ -52,7 +49,7 @@ fn void main() test(1)!!; test7(0)!!; test6(1)!!; - int! i = test2(3); + int? i = test2(3); } /* expect: test.ll diff --git a/test/test_suite/expressions/plus_int.c3 b/test/test_suite/expressions/plus_int.c3 index 7ebebcf46..7074ac3dd 100644 --- a/test/test_suite/expressions/plus_int.c3 +++ b/test/test_suite/expressions/plus_int.c3 @@ -1,22 +1,22 @@ fn void test1() { - short! a = 1; + short? a = 1; @ok(+a); - short b = +a; // #error: 'short!' to 'short'. + short b = +a; // #error: 'short?' to 'short'. } fn void test2() { - int! a = 1; + int? a = 1; @ok(+a); - int b = +a; // #error: 'int!' to 'int' + int b = +a; // #error: 'int?' to 'int' } fn void test3() { - long! a = 1; + long? a = 1; @ok(+a); - long b = +a; // #error: 'long!' to 'long' + long b = +a; // #error: 'long?' to 'long' } diff --git a/test/test_suite/expressions/pointer_access.c3t b/test/test_suite/expressions/pointer_access.c3t index 27f3746cb..a6b457d15 100644 --- a/test/test_suite/expressions/pointer_access.c3t +++ b/test/test_suite/expressions/pointer_access.c3t @@ -42,10 +42,10 @@ fn void testSimple() %.anon = type { i32, i32 } %.anon.0 = type { double } -@"$ct.pointer_access.c" = linkonce global %.introspect { i8 10, i64 0, ptr null, i64 40, i64 0, i64 5, [0 x i64] zeroinitializer }, align 8 -@"$ct.pointer_access.$anon" = linkonce global %.introspect { i8 10, i64 0, ptr null, i64 8, i64 0, i64 2, [0 x i64] zeroinitializer }, align 8 -@"$ct.pointer_access.$anon.4" = linkonce global %.introspect { i8 11, i64 0, ptr null, i64 8, i64 0, i64 2, [0 x i64] zeroinitializer }, align 8 -@"$ct.pointer_access.ExtraSimple" = linkonce global %.introspect { i8 10, i64 0, ptr null, i64 72, i64 0, i64 6, [0 x i64] zeroinitializer }, align 8 +@"$ct.pointer_access.c" = linkonce global %.introspect { i8 9, i64 0, ptr null, i64 40, i64 0, i64 5, [0 x i64] zeroinitializer }, align 8 +@"$ct.pointer_access.$anon" = linkonce global %.introspect { i8 9, i64 0, ptr null, i64 8, i64 0, i64 2, [0 x i64] zeroinitializer }, align 8 +@"$ct.pointer_access.$anon.4" = linkonce global %.introspect { i8 10, i64 0, ptr null, i64 8, i64 0, i64 2, [0 x i64] zeroinitializer }, align 8 +@"$ct.pointer_access.ExtraSimple" = linkonce global %.introspect { i8 9, i64 0, ptr null, i64 72, i64 0, i64 6, [0 x i64] zeroinitializer }, align 8 @.str = private unnamed_addr constant [71 x i8] c"a = %d, c.e = %f, c.f = %f, c.j = %f, g = %d, o0 = %f, r = %d, s = %d\0A\00", align 1 define void @pointer_access.testSimple() #0 { diff --git a/test/test_suite/from_docs/examples_if_catch.c3t b/test/test_suite/from_docs/examples_if_catch.c3t index ea04fac82..92111cd61 100644 --- a/test/test_suite/from_docs/examples_if_catch.c3t +++ b/test/test_suite/from_docs/examples_if_catch.c3t @@ -3,23 +3,20 @@ module demo; import libc; import std::io; -fault MathError -{ - DIVISION_BY_ZERO -} +fault DIVISION_BY_ZERO; fn int foo() { return 123; } fn int bar() { return 0; } -fn double! divide(int a, int b) +fn double? divide(int a, int b) { - if (b == 0) return MathError.DIVISION_BY_ZERO?; + if (b == 0) return DIVISION_BY_ZERO?; return (double)(a) / (double)(b); } // Rethrowing an error uses "?" suffix -fn void! testMayError() +fn void? testMayError() { divide(foo(), bar())!; } @@ -27,12 +24,12 @@ fn void! testMayError() fn void main() { // ratio has an optional type. - double! ratio = divide(foo(), bar()); + double? ratio = divide(foo(), bar()); // Handle the error if (catch err = ratio) { - if (err == MathError.DIVISION_BY_ZERO) + if (err == DIVISION_BY_ZERO) { libc::printf("Division by zero\n"); return; @@ -55,7 +52,7 @@ entry: br i1 %eq, label %if.then, label %if.exit if.then: ; preds = %entry - ret i64 ptrtoint (ptr @"demo.MathError$DIVISION_BY_ZERO" to i64) + ret i64 ptrtoint (ptr @demo.DIVISION_BY_ZERO to i64) if.exit: ; preds = %entry %sifp = sitofp i32 %1 to double @@ -138,7 +135,7 @@ end_block: ; preds = %after_check3, %assi if.then: ; preds = %end_block %7 = load i64, ptr %err, align 8 - %eq = icmp eq i64 %7, ptrtoint (ptr @"demo.MathError$DIVISION_BY_ZERO" to i64) + %eq = icmp eq i64 %7, ptrtoint (ptr @demo.DIVISION_BY_ZERO to i64) br i1 %eq, label %if.then4, label %if.exit if.then4: ; preds = %if.then diff --git a/test/test_suite/functions/c_vararg_expansion.c3t b/test/test_suite/functions/c_vararg_expansion.c3t index 650a79681..6627c42a8 100644 --- a/test/test_suite/functions/c_vararg_expansion.c3t +++ b/test/test_suite/functions/c_vararg_expansion.c3t @@ -5,7 +5,7 @@ distinct Foo = float; fn void main() { Foo a = 12.3; - Foo! b = 33.5; + Foo? b = 33.5; (void)printf("%f %f %f", (float)a, a, b); } diff --git a/test/test_suite/functions/default_param_fail.c3 b/test/test_suite/functions/default_param_fail.c3 index aeac261a8..d64e1a040 100644 --- a/test/test_suite/functions/default_param_fail.c3 +++ b/test/test_suite/functions/default_param_fail.c3 @@ -1,11 +1,8 @@ int z; -fault MyError -{ - FOO, -} +fault FOO; fn void test(int a = z) {} -fn void test2(int b = MyError.FOO?) {} \ No newline at end of file +fn void test2(int b = FOO?) {} \ No newline at end of file diff --git a/test/test_suite/functions/failable_param.c3 b/test/test_suite/functions/failable_param.c3 index 40633fcaf..1fa23433b 100644 --- a/test/test_suite/functions/failable_param.c3 +++ b/test/test_suite/functions/failable_param.c3 @@ -1,3 +1,3 @@ module test; -fn void test4(void!); // #error: Parameters may not be optional. +fn void test4(void?); // #error: Parameters may not be optional. diff --git a/test/test_suite/functions/func_ptr_conversion_alias.c3t b/test/test_suite/functions/func_ptr_conversion_alias.c3t index f9434f330..ee37d2dd7 100644 --- a/test/test_suite/functions/func_ptr_conversion_alias.c3t +++ b/test/test_suite/functions/func_ptr_conversion_alias.c3t @@ -14,8 +14,8 @@ fn Callback**[][123]* tester() GetCallback x = &tester; -def GetCallbackOpt = fn Callback2!(); +def GetCallbackOpt = fn Callback2?(); -fn Callback2! tester2() => null; +fn Callback2? tester2() => null; GetCallbackOpt y = &tester2; \ No newline at end of file diff --git a/test/test_suite/functions/func_ptr_conversions_and_names.c3t b/test/test_suite/functions/func_ptr_conversions_and_names.c3t index 57cf0d55e..a62af5abc 100644 --- a/test/test_suite/functions/func_ptr_conversions_and_names.c3t +++ b/test/test_suite/functions/func_ptr_conversions_and_names.c3t @@ -8,8 +8,8 @@ def FuncSame = fn int(int z = 444); fn int test(int a) { return a; } fn int test2(int b = 3) { return b; } -fn int! test3(int b = 3) { return b; } -fn int! test4(int b = 3) { return b; } +fn int? test3(int b = 3) { return b; } +fn int? test4(int b = 3) { return b; } fn void main() { @@ -37,8 +37,8 @@ fn void main() @.str.2 = private unnamed_addr constant [3 x i8] c"%d\00", align 1 @.str.3 = private unnamed_addr constant [3 x i8] c"%s\00", align 1 @.str.4 = private unnamed_addr constant [12 x i8] c"fn int(int)\00", align 1 -@"$ct.String" = linkonce global %.introspect { i8 18, i64 ptrtoint (ptr @"$ct.sa$char" to i64), ptr null, i64 16, i64 ptrtoint (ptr @"$ct.sa$char" to i64), i64 0, [0 x i64] zeroinitializer }, align 8 -@"$ct.sa$char" = linkonce global %.introspect { i8 16, i64 0, ptr null, i64 16, i64 ptrtoint (ptr @"$ct.char" to i64), i64 0, [0 x i64] zeroinitializer }, align 8 +@"$ct.String" = linkonce global %.introspect { i8 17, i64 ptrtoint (ptr @"$ct.sa$char" to i64), ptr null, i64 16, i64 ptrtoint (ptr @"$ct.sa$char" to i64), i64 0, [0 x i64] zeroinitializer }, align 8 +@"$ct.sa$char" = linkonce global %.introspect { i8 15, i64 0, ptr null, i64 16, i64 ptrtoint (ptr @"$ct.char" to i64), i64 0, [0 x i64] zeroinitializer }, align 8 @"$ct.char" = linkonce global %.introspect { i8 3, i64 0, ptr null, i64 1, i64 0, i64 0, [0 x i64] zeroinitializer }, align 8 @.str.5 = private unnamed_addr constant [3 x i8] c"%s\00", align 1 @.str.6 = private unnamed_addr constant [12 x i8] c"fn int(int)\00", align 1 @@ -48,7 +48,7 @@ fn void main() @.str.10 = private unnamed_addr constant [12 x i8] c"fn int(int)\00", align 1 @.str.11 = private unnamed_addr constant [3 x i8] c"%s\00", align 1 @.str.12 = private unnamed_addr constant [13 x i8] c"fn int!(int)\00", align 1 -@"$ct.fn$int$int$" = linkonce global %.introspect { i8 13, i64 0, ptr null, i64 8, i64 0, i64 0, [0 x i64] zeroinitializer }, align 8 +@"$ct.fn$int$int$" = linkonce global %.introspect { i8 12, i64 0, ptr null, i64 8, i64 0, i64 0, [0 x i64] zeroinitializer }, align 8 define void @test.main() #0 { entry: diff --git a/test/test_suite/functions/function_alias_llvm_check.c3t b/test/test_suite/functions/function_alias_llvm_check.c3t index f20a6fbe3..7d8e1347a 100644 --- a/test/test_suite/functions/function_alias_llvm_check.c3t +++ b/test/test_suite/functions/function_alias_llvm_check.c3t @@ -12,7 +12,7 @@ struct Foo List{FnB} bFuncs; } -fn void! Foo.deinit(&self) +fn void? Foo.deinit(&self) { self.aFuncs.free(); self.bFuncs.free(); diff --git a/test/test_suite/functions/missing_return_lambda.c3 b/test/test_suite/functions/missing_return_lambda.c3 index b7ff6af10..2a3c8fa20 100644 --- a/test/test_suite/functions/missing_return_lambda.c3 +++ b/test/test_suite/functions/missing_return_lambda.c3 @@ -1,9 +1,9 @@ import std::io::path; -fn void! process_dir(String dir_name) +fn void? process_dir(String dir_name) { path::Path p = path::temp(dir_name)!; - path::PathWalker fnwalk = fn bool!(Path p, bool is_dir, void*) { // #error: issing return statement at the end + path::PathWalker fnwalk = fn bool?(Path p, bool is_dir, void*) { // #error: issing return statement at the end io::printfn("path is %s", p); }; } \ No newline at end of file diff --git a/test/test_suite/functions/pointer_escape.c3 b/test/test_suite/functions/pointer_escape.c3 index bdfc3144f..9b7eeac7c 100644 --- a/test/test_suite/functions/pointer_escape.c3 +++ b/test/test_suite/functions/pointer_escape.c3 @@ -1,4 +1,4 @@ -int[?] foo = {1,2,3}; +int[*] foo = {1,2,3}; fn int* bar(int index) { int* array = &foo; diff --git a/test/test_suite/functions/recursive_through_generic.c3 b/test/test_suite/functions/recursive_through_generic.c3 index fcd382dab..e1d975941 100644 --- a/test/test_suite/functions/recursive_through_generic.c3 +++ b/test/test_suite/functions/recursive_through_generic.c3 @@ -5,7 +5,7 @@ fn void main() { } -def FooFunc = fn void! (Bar); // #error: Recursive definition +def FooFunc = fn void? (Bar); // #error: Recursive definition def Foo = HashMap{String, FooFunc}; struct Bar diff --git a/test/test_suite/functions/test_regression.c3t b/test/test_suite/functions/test_regression.c3t index e51c2525d..0ac4c7bcd 100644 --- a/test/test_suite/functions/test_regression.c3t +++ b/test/test_suite/functions/test_regression.c3t @@ -201,11 +201,7 @@ fn Type getMult(Type a) } Type argh = 234; -fault MyErr -{ - X, - Y -} +fault X, Y; enum Hello : int { @@ -243,11 +239,11 @@ fn Type getValue(Blob blob) %List = type { i64, i64, %any, ptr } %Foo = type { i32, i32 } -@"$ct.test.Bobo" = linkonce global %.introspect { i8 10, i64 0, ptr null, i64 20, i64 0, i64 6, [0 x i64] zeroinitializer }, align 8 -@"$ct.test.Blob" = linkonce global %.introspect { i8 10, i64 0, ptr null, i64 8, i64 0, i64 2, [0 x i64] zeroinitializer }, align 8 -@"$ct.test.Foor" = linkonce global %.introspect { i8 11, i64 0, ptr null, i64 16, i64 0, i64 2, [0 x i64] zeroinitializer }, align 8 -@"$ct.test.Foo2" = linkonce global %.introspect { i8 10, i64 0, ptr null, i64 4, i64 0, i64 1, [0 x i64] zeroinitializer }, align 8 -@"$ct.test.Foo" = linkonce global %.introspect { i8 10, i64 0, ptr null, i64 8, i64 0, i64 2, [0 x i64] zeroinitializer }, align 8 +@"$ct.test.Bobo" = linkonce global %.introspect { i8 9, i64 0, ptr null, i64 20, i64 0, i64 6, [0 x i64] zeroinitializer }, align 8 +@"$ct.test.Blob" = linkonce global %.introspect { i8 9, i64 0, ptr null, i64 8, i64 0, i64 2, [0 x i64] zeroinitializer }, align 8 +@"$ct.test.Foor" = linkonce global %.introspect { i8 10, i64 0, ptr null, i64 16, i64 0, i64 2, [0 x i64] zeroinitializer }, align 8 +@"$ct.test.Foo2" = linkonce global %.introspect { i8 9, i64 0, ptr null, i64 4, i64 0, i64 1, [0 x i64] zeroinitializer }, align 8 +@"$ct.test.Foo" = linkonce global %.introspect { i8 9, i64 0, ptr null, i64 8, i64 0, i64 2, [0 x i64] zeroinitializer }, align 8 @"$ct.int" = linkonce global %.introspect { i8 2, i64 0, ptr null, i64 4, i64 0, i64 0, [0 x i64] zeroinitializer }, align 8 @"$ct.test.MyEnum" = linkonce global { i8, i64, ptr, i64, i64, i64, [3 x %"char[]"] } { i8 8, i64 0, ptr null, i64 4, i64 ptrtoint (ptr @"$ct.int" to i64), i64 3, [3 x %"char[]"] [%"char[]" { ptr @.enum.HELO, i64 4 }, %"char[]" { ptr @.enum.WORLD, i64 5 }, %"char[]" { ptr @.enum.BYE, i64 3 }] }, align 8 @test_static.x = internal unnamed_addr global i32 1, align 4 diff --git a/test/test_suite/functions/test_regression_mingw.c3t b/test/test_suite/functions/test_regression_mingw.c3t index 78cc40232..5dad9057b 100644 --- a/test/test_suite/functions/test_regression_mingw.c3t +++ b/test/test_suite/functions/test_regression_mingw.c3t @@ -203,11 +203,7 @@ fn Type getMult(Type a) } Type argh = 234; -fault MyErr -{ - X, - Y -} +fault X, Y; enum Hello : int { @@ -259,11 +255,11 @@ $"$ct.int" = comdat any $"$ct.test.MyEnum" = comdat any -@"$ct.test.Bobo" = linkonce global %.introspect { i8 10, i64 0, ptr null, i64 20, i64 0, i64 6, [0 x i64] zeroinitializer }, comdat, align 8 -@"$ct.test.Blob" = linkonce global %.introspect { i8 10, i64 0, ptr null, i64 8, i64 0, i64 2, [0 x i64] zeroinitializer }, comdat, align 8 -@"$ct.test.Foor" = linkonce global %.introspect { i8 11, i64 0, ptr null, i64 16, i64 0, i64 2, [0 x i64] zeroinitializer }, comdat, align 8 -@"$ct.test.Foo2" = linkonce global %.introspect { i8 10, i64 0, ptr null, i64 4, i64 0, i64 1, [0 x i64] zeroinitializer }, comdat, align 8 -@"$ct.test.Foo" = linkonce global %.introspect { i8 10, i64 0, ptr null, i64 8, i64 0, i64 2, [0 x i64] zeroinitializer }, comdat, align 8 +@"$ct.test.Bobo" = linkonce global %.introspect { i8 9, i64 0, ptr null, i64 20, i64 0, i64 6, [0 x i64] zeroinitializer }, comdat, align 8 +@"$ct.test.Blob" = linkonce global %.introspect { i8 9, i64 0, ptr null, i64 8, i64 0, i64 2, [0 x i64] zeroinitializer }, comdat, align 8 +@"$ct.test.Foor" = linkonce global %.introspect { i8 10, i64 0, ptr null, i64 16, i64 0, i64 2, [0 x i64] zeroinitializer }, comdat, align 8 +@"$ct.test.Foo2" = linkonce global %.introspect { i8 9, i64 0, ptr null, i64 4, i64 0, i64 1, [0 x i64] zeroinitializer }, comdat, align 8 +@"$ct.test.Foo" = linkonce global %.introspect { i8 9, i64 0, ptr null, i64 8, i64 0, i64 2, [0 x i64] zeroinitializer }, comdat, align 8 @.enum.HELO = internal constant [5 x i8] c"HELO\00", align 1 @.enum.WORLD = internal constant [6 x i8] c"WORLD\00", align 1 @.enum.BYE = internal constant [4 x i8] c"BYE\00", align 1 diff --git a/test/test_suite/generic/generic_lambda_complex.c3t b/test/test_suite/generic/generic_lambda_complex.c3t index 76a726278..8dd6726e8 100644 --- a/test/test_suite/generic/generic_lambda_complex.c3t +++ b/test/test_suite/generic/generic_lambda_complex.c3t @@ -7,13 +7,7 @@ import std::collections::list; def TextTagList = List{TextTag}; -fault TextError -{ - UNTERMINATED_TAG, - EMPTY_TAG, - MISSING_TAG, - UNSUPPORTED_TAG, -} +fault UNTERMINATED_TAG, EMPTY_TAG, MISSING_TAG, UNSUPPORTED_TAG; enum TextTagKind: char { @@ -44,21 +38,21 @@ struct TextTag @require self.tags.len == 0 "template already initialized" @require tag_start != tag_end *> -fn void! TextTemplate.init(&self, String template, String tag_start = "{{", String tag_end = "}}", Allocator using = allocator::heap()) +fn void? TextTemplate.init(&self, String template, String tag_start = "{{", String tag_end = "}}", Allocator using = allocator::heap()) { TextTagList tags; String tmpl = template; uptr data = (uptr)&self.data; while (true) { - usz! start = tmpl.index_of(tag_start); + usz? start = tmpl.index_of(tag_start); if (catch start) break; tmpl = tmpl[start + tag_start.len..]; - usz! end = tmpl.index_of(tag_end); - if (catch end) return TextError.UNTERMINATED_TAG?; + usz? end = tmpl.index_of(tag_end); + if (catch end) return UNTERMINATED_TAG?; String name = tmpl[:end].trim(); - if (name == "") return TextError.EMPTY_TAG?; + if (name == "") return EMPTY_TAG?; // Check that the tag exists in the data struct. TextTag tag @noinit; @@ -83,10 +77,10 @@ fn void! TextTemplate.init(&self, String template, String tag_start = "{{", Stri break; $endif $endswitch - //return TextError.UNSUPPORTED_TAG?; + //return UNSUPPORTED_TAG?; } $endforeach - return TextError.MISSING_TAG?; + return MISSING_TAG?; }; tmpl = tmpl[end + tag_end.len..]; @@ -98,13 +92,13 @@ fn void! TextTemplate.init(&self, String template, String tag_start = "{{", Stri *self = { .allocator = using, .template = template, .tags = tags.array_view() }; } -fn void! TextTemplate.free(&self) +fn void? TextTemplate.free(&self) { allocator::free(self.allocator, self.tags); *self = {}; } -fn usz! TextTemplate.write_to(&self, OutStream writer) +fn usz? TextTemplate.write_to(&self, OutStream writer) { usz n; usz pos; @@ -118,7 +112,7 @@ fn usz! TextTemplate.write_to(&self, OutStream writer) return n; } -fn usz! TextTag.write(&self, OutStream writer) +fn usz? TextTag.write(&self, OutStream writer) { switch (self.kind) { diff --git a/test/test_suite/generic/nested_typedef.c3t b/test/test_suite/generic/nested_typedef.c3t index 6b007b59c..14b60b8ae 100644 --- a/test/test_suite/generic/nested_typedef.c3t +++ b/test/test_suite/generic/nested_typedef.c3t @@ -24,7 +24,7 @@ fn void main() {} /* #expect: test.ll -@"$ct.test.Foo" = linkonce global %.introspect { i8 10, i64 0, ptr null, i64 4, i64 0, i64 1, [0 x i64] zeroinitializer }, align 8 -@"$ct.test.Foo2" = linkonce global %.introspect { i8 10, i64 0, ptr null, i64 4, i64 0, i64 1, [0 x i64] zeroinitializer }, align 8 +@"$ct.test.Foo" = linkonce global %.introspect { i8 9, i64 0, ptr null, i64 4, i64 0, i64 1, [0 x i64] zeroinitializer }, align 8 +@"$ct.test.Foo2" = linkonce global %.introspect { i8 9, i64 0, ptr null, i64 4, i64 0, i64 1, [0 x i64] zeroinitializer }, align 8 define i32 @test.test() #0 { define i32 @test.test2() #0 { diff --git a/test/test_suite/globals/global_init.c3 b/test/test_suite/globals/global_init.c3 index 7bffb33bd..eec62d316 100644 --- a/test/test_suite/globals/global_init.c3 +++ b/test/test_suite/globals/global_init.c3 @@ -7,7 +7,7 @@ int[2] a1 = { 1, 2 }; int[2] a2 = 30; // #error: 'int' to 'int[2]' -ichar[?] a; // #error: Inferred array types can only be used in declarations with initializers +ichar[*] a; // #error: Inferred array types can only be used in declarations with initializers ichar ca = 0; ichar cb = 1; diff --git a/test/test_suite/globals/init_with_err.c3t b/test/test_suite/globals/init_with_err.c3t index ca39f116c..823e02d6b 100644 --- a/test/test_suite/globals/init_with_err.c3t +++ b/test/test_suite/globals/init_with_err.c3t @@ -2,23 +2,22 @@ module test; import std::io; -fault Hello -{ - FOO -} -const String! ABC = Hello.FOO?; -String! abc = Hello.FOO?; -const String! DEF = ABC; -String! bcd = ABC; +fault FOO; +const String? ABC = FOO?; +String? abc = FOO?; +const String? DEF = ABC; +String? bcd = ABC; /* #expect: test.ll -@test.ABC.f = unnamed_addr global i64 ptrtoint (ptr @"test.Hello$FOO" to i64), align 8 -@test.abc.f = unnamed_addr global i64 ptrtoint (ptr @"test.Hello$FOO" to i64), align 8 -@test.DEF.f = unnamed_addr global i64 ptrtoint (ptr @"test.Hello$FOO" to i64), align 8 -@test.bcd.f = unnamed_addr global i64 ptrtoint (ptr @"test.Hello$FOO" to i64), align 8 +@test.ABC.f = unnamed_addr global i64 ptrtoint (ptr @test.FOO to i64), align 8 +@test.abc.f = unnamed_addr global i64 ptrtoint (ptr @test.FOO to i64), align 8 +@test.DEF.f = unnamed_addr global i64 ptrtoint (ptr @test.FOO to i64), align 8 +@test.bcd.f = unnamed_addr global i64 ptrtoint (ptr @test.FOO to i64), align 8 @test.ABC = local_unnamed_addr constant %"char[]" zeroinitializer, align 8 +@test.FOO = linkonce constant %"char[]" { ptr @test.FOO.nameof, i64 3 }, align 8 +@test.FOO.nameof = internal constant [4 x i8] c"FOO\00", align 1 @test.abc = local_unnamed_addr global %"char[]" zeroinitializer, align 8 @test.DEF = local_unnamed_addr constant %"char[]" zeroinitializer, align 8 @test.bcd = local_unnamed_addr global %"char[]" zeroinitializer, align 8 diff --git a/test/test_suite/initializer_lists/disallowed_lists.c3 b/test/test_suite/initializer_lists/disallowed_lists.c3 index 5ee323e37..6f2225099 100644 --- a/test/test_suite/initializer_lists/disallowed_lists.c3 +++ b/test/test_suite/initializer_lists/disallowed_lists.c3 @@ -2,7 +2,7 @@ fn void test() { char* hello = "123"; String a = { '1', '2', '3' }; - char[?] b = { '1', '2', '3' }; + char[*] b = { '1', '2', '3' }; char[3] c = { '1', '2', '3' }; char* d = { '1', '2', '3' }; // #error: Pointers cannot be initialized using an initializer list, instead you need to take the address of an array } \ No newline at end of file diff --git a/test/test_suite/initializer_lists/general_tests.c3t b/test/test_suite/initializer_lists/general_tests.c3t index 170afc755..1c72c3a3e 100644 --- a/test/test_suite/initializer_lists/general_tests.c3t +++ b/test/test_suite/initializer_lists/general_tests.c3t @@ -37,8 +37,8 @@ fn int test() %"int[]" = type { ptr, i64 } %"Bar[]" = type { ptr, i64 } -@"$ct.general_tests.Baz" = linkonce global %.introspect { i8 11, i64 0, ptr null, i64 8, i64 0, i64 2, [0 x i64] zeroinitializer }, align 8 -@"$ct.general_tests.Bar" = linkonce global %.introspect { i8 10, i64 0, ptr null, i64 8, i64 0, i64 2, [0 x i64] zeroinitializer }, align 8 +@"$ct.general_tests.Baz" = linkonce global %.introspect { i8 10, i64 0, ptr null, i64 8, i64 0, i64 2, [0 x i64] zeroinitializer }, align 8 +@"$ct.general_tests.Bar" = linkonce global %.introspect { i8 9, i64 0, ptr null, i64 8, i64 0, i64 2, [0 x i64] zeroinitializer }, align 8 @.__const = private unnamed_addr constant { i32, [4 x i8] } { i32 1, [4 x i8] undef }, align 8 @test.foo1 = internal unnamed_addr global i32 22, align 4 @.str = private unnamed_addr constant [7 x i8] c"Hello!\00", align 1 diff --git a/test/test_suite/initializer_lists/infer_with_init.c3t b/test/test_suite/initializer_lists/infer_with_init.c3t index 260dedb56..e777eeaf3 100644 --- a/test/test_suite/initializer_lists/infer_with_init.c3t +++ b/test/test_suite/initializer_lists/infer_with_init.c3t @@ -1,11 +1,11 @@ // #target: windows-x64 module test; -const int[?] X = (int[?]) { 1, 2, 3 }; -int[?] y = (int[?]) { 1, 2, 3 }; +const int[*] X = (int[*]) { 1, 2, 3 }; +int[*] y = (int[*]) { 1, 2, 3 }; fn void main() { - int x = $typeof((int[?]) { 1, 2, 3}).len; + int x = $typeof((int[*]) { 1, 2, 3}).len; int z = X.len; int w = y.len; } diff --git a/test/test_suite/initializer_lists/statics.c3t b/test/test_suite/initializer_lists/statics.c3t index 725e9f1c3..f7a634016 100644 --- a/test/test_suite/initializer_lists/statics.c3t +++ b/test/test_suite/initializer_lists/statics.c3t @@ -35,8 +35,8 @@ fn int main() %Bar = type { i32, i32 } %"Bar[]" = type { ptr, i64 } -@"$ct.statics.Baz" = linkonce global %.introspect { i8 11, i64 0, ptr null, i64 8, i64 0, i64 2, [0 x i64] zeroinitializer }, align 8 -@"$ct.statics.Bar" = linkonce global %.introspect { i8 10, i64 0, ptr null, i64 8, i64 0, i64 2, [0 x i64] zeroinitializer }, align 8 +@"$ct.statics.Baz" = linkonce global %.introspect { i8 10, i64 0, ptr null, i64 8, i64 0, i64 2, [0 x i64] zeroinitializer }, align 8 +@"$ct.statics.Bar" = linkonce global %.introspect { i8 9, i64 0, ptr null, i64 8, i64 0, i64 2, [0 x i64] zeroinitializer }, align 8 @.__const = private unnamed_addr constant [1 x %Bar] [%Bar { i32 1, i32 2 }], align 4 @.__const_slice = private unnamed_addr global [1 x %Bar] [%Bar { i32 1, i32 2 }], align 4 @test.c = internal unnamed_addr global %"Bar[]" { ptr @.__const_slice, i64 1 }, align 8 diff --git a/test/test_suite/initializer_lists/subarrays.c3t b/test/test_suite/initializer_lists/subarrays.c3t index b978cb441..807a4fcff 100644 --- a/test/test_suite/initializer_lists/subarrays.c3t +++ b/test/test_suite/initializer_lists/subarrays.c3t @@ -50,8 +50,8 @@ fn int main() %"int[]" = type { ptr, i64 } %Baz = type { double } -@"$ct.subarrays.Baz" = linkonce global %.introspect { i8 11, i64 0, ptr null, i64 8, i64 0, i64 2, [0 x i64] zeroinitializer }, align 8 -@"$ct.subarrays.Bar" = linkonce global %.introspect { i8 10, i64 0, ptr null, i64 8, i64 0, i64 2, [0 x i64] zeroinitializer }, align 8 +@"$ct.subarrays.Baz" = linkonce global %.introspect { i8 10, i64 0, ptr null, i64 8, i64 0, i64 2, [0 x i64] zeroinitializer }, align 8 +@"$ct.subarrays.Bar" = linkonce global %.introspect { i8 9, i64 0, ptr null, i64 8, i64 0, i64 2, [0 x i64] zeroinitializer }, align 8 @.__const_slice = private unnamed_addr global [2 x %Bar] [%Bar { i32 3, i32 4 }, %Bar { i32 8, i32 9 }], align 16 @subarrays.arrbar = local_unnamed_addr global %"Bar[]" { ptr @.__const_slice, i64 2 }, align 8 @.__const_slice.3 = private unnamed_addr global [2 x i32] [i32 1, i32 2], align 4 diff --git a/test/test_suite/initializer_lists/zero_inferred_array.c3 b/test/test_suite/initializer_lists/zero_inferred_array.c3 index 3be21cafb..4c41938f1 100644 --- a/test/test_suite/initializer_lists/zero_inferred_array.c3 +++ b/test/test_suite/initializer_lists/zero_inferred_array.c3 @@ -1,4 +1,4 @@ fn void test() { - int[?] a = {}; // #error: Zero length + int[*] a = {}; // #error: Zero length } \ No newline at end of file diff --git a/test/test_suite/literals/radix_numbers_errors.c3 b/test/test_suite/literals/radix_numbers_errors.c3 index a37970238..12c816c9b 100644 --- a/test/test_suite/literals/radix_numbers_errors.c3 +++ b/test/test_suite/literals/radix_numbers_errors.c3 @@ -12,6 +12,6 @@ 0xg // #error: '0x' starts a hexadecimal number, so the next character should be 0-9, a-f or A-F. -0x! // #error: '0x' starts a hexadecimal number, so the next character should be 0-9, a-f or A-F. +0x? // #error: '0x' starts a hexadecimal number, so the next character should be 0-9, a-f or A-F. 0b // #error: An expression starting with '0b' should be followed by binary digits diff --git a/test/test_suite/macros/implicit_return_opt.c3 b/test/test_suite/macros/implicit_return_opt.c3 index 91c5cb20e..dc802f592 100644 --- a/test/test_suite/macros/implicit_return_opt.c3 +++ b/test/test_suite/macros/implicit_return_opt.c3 @@ -14,6 +14,6 @@ macro run() { i++; if (i > 10) break; - if (i > 100) return IoError.EOF?; + if (i > 100) return io::EOF?; } } \ No newline at end of file diff --git a/test/test_suite/macros/macro_body_defer.c3t b/test/test_suite/macros/macro_body_defer.c3t index a3fae041b..ef0e96edc 100644 --- a/test/test_suite/macros/macro_body_defer.c3t +++ b/test/test_suite/macros/macro_body_defer.c3t @@ -2,7 +2,7 @@ module foo; extern fn void printf(char*,...); -fn int! foo() { return 1; } +fn int? foo() { return 1; } macro @foo_test(int i; @body()) { diff --git a/test/test_suite/macros/macro_chained_return_void_optional.c3t b/test/test_suite/macros/macro_chained_return_void_optional.c3t index b8724062d..e6edf61d9 100644 --- a/test/test_suite/macros/macro_chained_return_void_optional.c3t +++ b/test/test_suite/macros/macro_chained_return_void_optional.c3t @@ -1,7 +1,7 @@ module abi; -fn void! abc() {} -macro void! abc_macro() => abc(); +fn void? abc() {} +macro void? abc_macro() => abc(); fn void main() { diff --git a/test/test_suite/macros/macro_failable_return_rethrow.c3t b/test/test_suite/macros/macro_failable_return_rethrow.c3t index 9110112b2..c23622d08 100644 --- a/test/test_suite/macros/macro_failable_return_rethrow.c3t +++ b/test/test_suite/macros/macro_failable_return_rethrow.c3t @@ -1,10 +1,10 @@ // #target: macos-x64 module test; -fn int! xy() +fn int? xy() { return 1; } -macro int! foo() +macro int? foo() { xy()!; return 1; diff --git a/test/test_suite/macros/macro_vasplat.c3t b/test/test_suite/macros/macro_vasplat.c3t index 2151da33a..537b93d02 100644 --- a/test/test_suite/macros/macro_vasplat.c3t +++ b/test/test_suite/macros/macro_vasplat.c3t @@ -4,41 +4,41 @@ import std::io; macro @hello(...) { - int[?] a = { 1, $vasplat, 3 }; + int[*] a = { 1, $vasplat, 3 }; foreach (i, x : a) io::printfn("%d: %d", i, x); } macro @hello1(...) { - int[?] a = { 1, $vasplat }; + int[*] a = { 1, $vasplat }; foreach (i, x : a) io::printfn("x:%d: %d", i, x); } macro @hello2(...) { - int[?] a = { $vasplat, 888 }; + int[*] a = { $vasplat, 888 }; foreach (i, x : a) io::printfn("x:%d: %d", i, x); } macro @hello3(...) { - int[?] a = { $vasplat }; + int[*] a = { $vasplat }; foreach (i, x : a) io::printfn("x:%d: %d", i, x); } macro @hello4(...) { - int[?] a = { 5, $vasplat[2..4], 77 }; + int[*] a = { 5, $vasplat[2..4], 77 }; foreach (i, x : a) io::printfn("y:%d: %d", i, x); } macro @hello5(...) { - int[?] a = { 5, $vasplat[2..], 77 }; + int[*] a = { 5, $vasplat[2..], 77 }; foreach (i, x : a) io::printfn("y:%d: %d", i, x); - int[?] b = { 55, $vasplat[2..^2], 88 }; + int[*] b = { 55, $vasplat[2..^2], 88 }; foreach (i, x : b) io::printfn("z:%d: %d", i, x); - int[?] c = { 55, $vasplat[0:^2], 88 }; + int[*] c = { 55, $vasplat[0:^2], 88 }; foreach (i, x : c) io::printfn("zz:%d: %d", i, x); } diff --git a/test/test_suite/macros/unifying_implicit_void.c3t b/test/test_suite/macros/unifying_implicit_void.c3t index 4c815c827..7f09c91ae 100644 --- a/test/test_suite/macros/unifying_implicit_void.c3t +++ b/test/test_suite/macros/unifying_implicit_void.c3t @@ -11,7 +11,7 @@ fn void main() macro InStream.foo(&self) { - char! c = self.read_byte(); + char? c = self.read_byte(); if (catch err = c) { return err?; diff --git a/test/test_suite/macros/userland_bitcast.c3t b/test/test_suite/macros/userland_bitcast.c3t index 6f425e337..2b2c913fc 100644 --- a/test/test_suite/macros/userland_bitcast.c3t +++ b/test/test_suite/macros/userland_bitcast.c3t @@ -79,7 +79,7 @@ fn void main() %Foo = type { i16, i8, i8, i16, i16 } -@"$ct.userland_bitcast.Foo" = linkonce global %.introspect { i8 10, i64 0, ptr null, i64 8, i64 0, i64 5, [0 x i64] zeroinitializer }, align 8 +@"$ct.userland_bitcast.Foo" = linkonce global %.introspect { i8 9, i64 0, ptr null, i64 8, i64 0, i64 5, [0 x i64] zeroinitializer }, align 8 @.str = private unnamed_addr constant [16 x i8] c"%f => %d => %f\0A\00", align 1 @.str.1 = private unnamed_addr constant [18 x i8] c"%e => %llu => %e\0A\00", align 1 diff --git a/test/test_suite/methods/enum_distinct_err_methods.c3t b/test/test_suite/methods/enum_distinct_err_methods.c3t index d4ee7e08c..2a47d2a10 100644 --- a/test/test_suite/methods/enum_distinct_err_methods.c3t +++ b/test/test_suite/methods/enum_distinct_err_methods.c3t @@ -3,10 +3,7 @@ module foo; import std::io; -fault Foo -{ - X -} +fault X; distinct Bar = int; @@ -16,11 +13,6 @@ enum MyEnum B } -fn void Foo.hello(Foo *f) -{ - io::printn("Hello from Foo"); -} - fn void Bar.hello(Bar *b) { io::printn("Hello from Bar"); @@ -32,10 +24,8 @@ fn void MyEnum.hello(MyEnum *myenum) } fn int main() { - Foo f; Bar b; MyEnum a = MyEnum.A; - f.hello(); b.hello(); a.hello(); return 0; @@ -43,8 +33,7 @@ fn int main() /* #expect: foo.ll - -define void @foo.Foo.hello(ptr %0) #0 { +define void @foo.Bar.hello(ptr %0) #0 { entry: %len = alloca i64, align 8 %error_var = alloca i64, align 8 @@ -56,66 +45,17 @@ entry: %not_err = icmp eq i64 %2, 0 %3 = call i1 @llvm.expect.i1(i1 %not_err, i1 true) br i1 %3, label %after_check, label %assign_optional -assign_optional: ; preds = %entry - store i64 %2, ptr %error_var, align 8 - br label %guard_block -after_check: ; preds = %entry - br label %noerr_block -guard_block: ; preds = %assign_optional - br label %voiderr -noerr_block: ; preds = %after_check - %4 = load i64, ptr %retparam, align 8 - store i64 %4, ptr %len, align 8 - %5 = call i64 @std.io.File.write_byte(ptr %1, i8 zeroext 10) - %not_err3 = icmp eq i64 %5, 0 - %6 = call i1 @llvm.expect.i1(i1 %not_err3, i1 true) - br i1 %6, label %after_check5, label %assign_optional4 -assign_optional4: ; preds = %noerr_block - store i64 %5, ptr %error_var2, align 8 - br label %guard_block6 -after_check5: ; preds = %noerr_block - br label %noerr_block7 -guard_block6: ; preds = %assign_optional4 - br label %voiderr -noerr_block7: ; preds = %after_check5 - %7 = call i64 @std.io.File.flush(ptr %1) - %not_err9 = icmp eq i64 %7, 0 - %8 = call i1 @llvm.expect.i1(i1 %not_err9, i1 true) - br i1 %8, label %after_check11, label %assign_optional10 -assign_optional10: ; preds = %noerr_block7 - store i64 %7, ptr %error_var8, align 8 - br label %guard_block12 -after_check11: ; preds = %noerr_block7 - br label %noerr_block13 -guard_block12: ; preds = %assign_optional10 - br label %voiderr -noerr_block13: ; preds = %after_check11 - %9 = load i64, ptr %len, align 8 - %add = add i64 %9, 1 - br label %voiderr -voiderr: ; preds = %noerr_block13, %guard_block12, %guard_block6, %guard_block - ret void -} -define void @foo.Bar.hello(ptr %0) #0 { -entry: - %len = alloca i64, align 8 - %error_var = alloca i64, align 8 - %retparam = alloca i64, align 8 - %error_var2 = alloca i64, align 8 - %error_var8 = alloca i64, align 8 - %1 = call ptr @std.io.stdout() - %2 = call i64 @std.io.File.write(ptr %retparam, ptr %1, ptr @.str.1, i64 14) - %not_err = icmp eq i64 %2, 0 - %3 = call i1 @llvm.expect.i1(i1 %not_err, i1 true) - br i1 %3, label %after_check, label %assign_optional assign_optional: ; preds = %entry store i64 %2, ptr %error_var, align 8 br label %guard_block + after_check: ; preds = %entry br label %noerr_block + guard_block: ; preds = %assign_optional br label %voiderr + noerr_block: ; preds = %after_check %4 = load i64, ptr %retparam, align 8 store i64 %4, ptr %len, align 8 @@ -123,29 +63,38 @@ noerr_block: ; preds = %after_check %not_err3 = icmp eq i64 %5, 0 %6 = call i1 @llvm.expect.i1(i1 %not_err3, i1 true) br i1 %6, label %after_check5, label %assign_optional4 + assign_optional4: ; preds = %noerr_block store i64 %5, ptr %error_var2, align 8 br label %guard_block6 + after_check5: ; preds = %noerr_block br label %noerr_block7 + guard_block6: ; preds = %assign_optional4 br label %voiderr + noerr_block7: ; preds = %after_check5 %7 = call i64 @std.io.File.flush(ptr %1) %not_err9 = icmp eq i64 %7, 0 %8 = call i1 @llvm.expect.i1(i1 %not_err9, i1 true) br i1 %8, label %after_check11, label %assign_optional10 + assign_optional10: ; preds = %noerr_block7 store i64 %7, ptr %error_var8, align 8 br label %guard_block12 + after_check11: ; preds = %noerr_block7 br label %noerr_block13 + guard_block12: ; preds = %assign_optional10 br label %voiderr + noerr_block13: ; preds = %after_check11 %9 = load i64, ptr %len, align 8 %add = add i64 %9, 1 br label %voiderr + voiderr: ; preds = %noerr_block13, %guard_block12, %guard_block6, %guard_block ret void } @@ -158,17 +107,21 @@ entry: %error_var2 = alloca i64, align 8 %error_var8 = alloca i64, align 8 %1 = call ptr @std.io.stdout() - %2 = call i64 @std.io.File.write(ptr %retparam, ptr %1, ptr @.str.2, i64 17) + %2 = call i64 @std.io.File.write(ptr %retparam, ptr %1, ptr @.str.1, i64 17) %not_err = icmp eq i64 %2, 0 %3 = call i1 @llvm.expect.i1(i1 %not_err, i1 true) br i1 %3, label %after_check, label %assign_optional + assign_optional: ; preds = %entry store i64 %2, ptr %error_var, align 8 br label %guard_block + after_check: ; preds = %entry br label %noerr_block + guard_block: ; preds = %assign_optional br label %voiderr + noerr_block: ; preds = %after_check %4 = load i64, ptr %retparam, align 8 store i64 %4, ptr %len, align 8 @@ -176,42 +129,48 @@ noerr_block: ; preds = %after_check %not_err3 = icmp eq i64 %5, 0 %6 = call i1 @llvm.expect.i1(i1 %not_err3, i1 true) br i1 %6, label %after_check5, label %assign_optional4 + assign_optional4: ; preds = %noerr_block store i64 %5, ptr %error_var2, align 8 br label %guard_block6 + after_check5: ; preds = %noerr_block br label %noerr_block7 + guard_block6: ; preds = %assign_optional4 br label %voiderr + noerr_block7: ; preds = %after_check5 %7 = call i64 @std.io.File.flush(ptr %1) %not_err9 = icmp eq i64 %7, 0 %8 = call i1 @llvm.expect.i1(i1 %not_err9, i1 true) br i1 %8, label %after_check11, label %assign_optional10 + assign_optional10: ; preds = %noerr_block7 store i64 %7, ptr %error_var8, align 8 br label %guard_block12 + after_check11: ; preds = %noerr_block7 br label %noerr_block13 + guard_block12: ; preds = %assign_optional10 br label %voiderr + noerr_block13: ; preds = %after_check11 %9 = load i64, ptr %len, align 8 %add = add i64 %9, 1 br label %voiderr + voiderr: ; preds = %noerr_block13, %guard_block12, %guard_block6, %guard_block ret void } define i32 @main() #0 { entry: - %f = alloca i64, align 8 %b = alloca i32, align 4 %a = alloca i32, align 4 - store i64 0, ptr %f, align 8 store i32 0, ptr %b, align 4 store i32 0, ptr %a, align 4 - call void @foo.Foo.hello(ptr %f) call void @foo.Bar.hello(ptr %b) call void @foo.MyEnum.hello(ptr %a) ret i32 0 diff --git a/test/test_suite/pointers/const_ref.c3t b/test/test_suite/pointers/const_ref.c3t index 13d75b378..716318687 100644 --- a/test/test_suite/pointers/const_ref.c3t +++ b/test/test_suite/pointers/const_ref.c3t @@ -1,7 +1,7 @@ // #target: macos-x64 module test; -const int[?] X = (int[?]) { 1, 2, 3 }; -int[?] y = (int[?]) { 1, 2, 3 }; +const int[*] X = (int[*]) { 1, 2, 3 }; +int[*] y = (int[*]) { 1, 2, 3 }; fn int main() { diff --git a/test/test_suite/slices/array_to_const_err.c3 b/test/test_suite/slices/array_to_const_err.c3 index b02186039..349890be1 100644 --- a/test/test_suite/slices/array_to_const_err.c3 +++ b/test/test_suite/slices/array_to_const_err.c3 @@ -3,6 +3,6 @@ import std; fn void main() { - char[?] z = { 1, 2 }; + char[*] z = { 1, 2 }; char[] y = z; // #error: Conversions from arrays or vectors } diff --git a/test/test_suite/slices/slice_negative_len.c3 b/test/test_suite/slices/slice_negative_len.c3 index 30073685a..8e1baa8bf 100644 --- a/test/test_suite/slices/slice_negative_len.c3 +++ b/test/test_suite/slices/slice_negative_len.c3 @@ -68,7 +68,7 @@ fn void test10() struct Abc { int a; - char[?] z; + char[*] z; } fn void test105() diff --git a/test/test_suite/slices/slice_optional.c3t b/test/test_suite/slices/slice_optional.c3t index bc6545de6..cf3d4688a 100644 --- a/test/test_suite/slices/slice_optional.c3t +++ b/test/test_suite/slices/slice_optional.c3t @@ -1,8 +1,8 @@ // #target: macos-x64 module test; fn void main() { - int[]! a = {1, 2}; - int! b = a[0]; + int[]? a = {1, 2}; + int? b = a[0]; } /* #expect: test.ll diff --git a/test/test_suite/slices/slice_optional_index.c3t b/test/test_suite/slices/slice_optional_index.c3t index a1be9cd28..8a8e949bb 100644 --- a/test/test_suite/slices/slice_optional_index.c3t +++ b/test/test_suite/slices/slice_optional_index.c3t @@ -6,10 +6,10 @@ fn void test() int[] a = { 1, 2, 3 }; for (int i = 0; i < 3; i++) { - int! b = i == 0 ? SearchResult.MISSING? : i; - int[]! y = a[:b]; - int[]! w = a[b..]; - int! z = a[b]; + int? b = i == 0 ? NOT_FOUND? : i; + int[]? y = a[:b]; + int[]? w = a[b..]; + int? z = a[b]; } } @@ -30,7 +30,7 @@ loop.body: ; preds = %loop.cond br i1 %eq, label %cond.lhs, label %cond.rhs cond.lhs: ; preds = %loop.body - store i64 ptrtoint (ptr @"std.core.builtin.SearchResult$MISSING" to i64), ptr %b.f, align 8 + store i64 ptrtoint (ptr @std.core.builtin.NOT_FOUND to i64), ptr %b.f, align 8 br label %after_assign cond.rhs: ; preds = %loop.body diff --git a/test/test_suite/slices/slice_to_slice_assign.c3t b/test/test_suite/slices/slice_to_slice_assign.c3t index 69c642eb8..fe5c64225 100644 --- a/test/test_suite/slices/slice_to_slice_assign.c3t +++ b/test/test_suite/slices/slice_to_slice_assign.c3t @@ -4,7 +4,7 @@ import std::io; fn void main() { - int[?] z = { 1, 2, 3, 4, 5, 6, 7 }; + int[*] z = { 1, 2, 3, 4, 5, 6, 7 }; int[6] y; y[1..3] = z[3..5]; io::printfn("%s %s", y, z); diff --git a/test/test_suite/slices/slice_to_slice_vector_assign.c3t b/test/test_suite/slices/slice_to_slice_vector_assign.c3t index abedcf3e3..a1e46acae 100644 --- a/test/test_suite/slices/slice_to_slice_vector_assign.c3t +++ b/test/test_suite/slices/slice_to_slice_vector_assign.c3t @@ -4,7 +4,7 @@ import std::io; fn void main() { - int[] z = { 1, 2, 3, 4, 5, 6, 7 }; + int[<*>] z = { 1, 2, 3, 4, 5, 6, 7 }; int[<6>] y; y[1..3] = z[3..5]; io::printfn("%s %s", y, z); diff --git a/test/test_suite/slices/various_const_slicing.c3t b/test/test_suite/slices/various_const_slicing.c3t index 6828e0877..999005940 100644 --- a/test/test_suite/slices/various_const_slicing.c3t +++ b/test/test_suite/slices/various_const_slicing.c3t @@ -16,7 +16,7 @@ fn void test() } fn int main() { - int[?] $x = { 1, 2, 3, 4 }; + int[*] $x = { 1, 2, 3, 4 }; var $y = $x[1..3]; int[] y = { 1, 2 }; io::printn(y.ptr); diff --git a/test/test_suite/statements/custom_foreach_with_ref.c3t b/test/test_suite/statements/custom_foreach_with_ref.c3t index da74ede49..14880c684 100644 --- a/test/test_suite/statements/custom_foreach_with_ref.c3t +++ b/test/test_suite/statements/custom_foreach_with_ref.c3t @@ -85,7 +85,7 @@ fn void main() %Foo = type { [3 x i32] } -@"$ct.foo.Foo" = linkonce global %.introspect { i8 10, i64 0, ptr null, i64 12, i64 0, i64 1, [0 x i64] zeroinitializer }, align 8 +@"$ct.foo.Foo" = linkonce global %.introspect { i8 9, i64 0, ptr null, i64 12, i64 0, i64 1, [0 x i64] zeroinitializer }, align 8 @.str = private unnamed_addr constant [11 x i8] c"getFields\0A\00", align 1 @.__const = private unnamed_addr constant [5 x i32] [i32 3, i32 5, i32 2, i32 10, i32 111], align 16 @.str.1 = private unnamed_addr constant [11 x i8] c"Call made\0A\00", align 1 diff --git a/test/test_suite/statements/dead_statements.c3t b/test/test_suite/statements/dead_statements.c3t index 228f2a6af..bfdf2bd45 100644 --- a/test/test_suite/statements/dead_statements.c3t +++ b/test/test_suite/statements/dead_statements.c3t @@ -4,14 +4,14 @@ import std::io; import std::io::path; import std::collections::list; -fn void! load_corpus2(String code, String path) @local +fn void? load_corpus2(String code, String path) @local { for(;;) io::printfn("hi"); path::Path p = path::temp(path)!; // #warning: This code will never execute if (!path::exists(p)) { - return IoError.FILE_NOT_FOUND?; + return io::FILE_NOT_FOUND?; } } diff --git a/test/test_suite/statements/defer_if_try_copy.c3t b/test/test_suite/statements/defer_if_try_copy.c3t index 74c7dc7dd..8f1b106f9 100644 --- a/test/test_suite/statements/defer_if_try_copy.c3t +++ b/test/test_suite/statements/defer_if_try_copy.c3t @@ -3,10 +3,10 @@ module foo; import std; fn int main() { - int! cmd = 3; + int? cmd = 3; defer { - if (try cmd) { io::printfn("HO! %s", cmd); } + if (try cmd) { io::printfn("HO? %s", cmd); } } return 0; } diff --git a/test/test_suite/statements/for_with_optional.c3t b/test/test_suite/statements/for_with_optional.c3t index bf04c5aea..12684b438 100644 --- a/test/test_suite/statements/for_with_optional.c3t +++ b/test/test_suite/statements/for_with_optional.c3t @@ -1,15 +1,15 @@ // #target: macos-x64 module test; -fn void! test() +fn void? test() { - int! n; + int? n; for (n += 1; n! < 10; n += 1); } fn int main() { (void)test(); - int! n; + int? n; for (n += 1; n!! < 10; n += 1); return 0; } diff --git a/test/test_suite/statements/foreach_custom.c3t b/test/test_suite/statements/foreach_custom.c3t index 509742c4b..20fe1a3d9 100644 --- a/test/test_suite/statements/foreach_custom.c3t +++ b/test/test_suite/statements/foreach_custom.c3t @@ -18,7 +18,7 @@ macro usz Foo.@operator_len(&foo) @operator(len) fn void main() { - int[?] i = { 1, 3, 10 }; + int[*] i = { 1, 3, 10 }; Foo x = { &i }; foreach FOO: (int f : x) { printf("%d\n", f); diff --git a/test/test_suite/statements/foreach_custom_macro.c3t b/test/test_suite/statements/foreach_custom_macro.c3t index 553be040e..1f03574ea 100644 --- a/test/test_suite/statements/foreach_custom_macro.c3t +++ b/test/test_suite/statements/foreach_custom_macro.c3t @@ -17,7 +17,7 @@ macro usz Foo.@operator_len(&foo) @operator(len) fn void main() { - int[?] i = { 1, 3, 10 }; + int[*] i = { 1, 3, 10 }; Foo x = { &i }; foreach FOO: (int f : x) { printf("%d\n", f); @@ -35,7 +35,7 @@ extern fn int printf(char *fmt, ...); %Foo = type { %"int[]" } %"int[]" = type { ptr, i64 } -@"$ct.foo.Foo" = linkonce global %.introspect { i8 10, i64 0, ptr null, i64 16, i64 0, i64 1, [0 x i64] zeroinitializer }, align 8 +@"$ct.foo.Foo" = linkonce global %.introspect { i8 9, i64 0, ptr null, i64 16, i64 0, i64 1, [0 x i64] zeroinitializer }, align 8 @.__const = private unnamed_addr constant [3 x i32] [i32 1, i32 3, i32 10], align 4 @.str = private unnamed_addr constant [4 x i8] c"%d\0A\00", align 1 diff --git a/test/test_suite/statements/foreach_errors.c3 b/test/test_suite/statements/foreach_errors.c3 index 64531102b..669bc74ef 100644 --- a/test/test_suite/statements/foreach_errors.c3 +++ b/test/test_suite/statements/foreach_errors.c3 @@ -33,12 +33,12 @@ fn void test4() fn void test5() { - foreach (int! y : z) foo(); + foreach (int? y : z) foo(); } fn void test6() { - foreach (int! i, y : z) foo(); // #error: The index may not be an optional. + foreach (int? i, y : z) foo(); // #error: The index may not be an optional. } fn void test7() diff --git a/test/test_suite/statements/foreach_r_custom.c3t b/test/test_suite/statements/foreach_r_custom.c3t index 9cb61cb11..38ac06e01 100644 --- a/test/test_suite/statements/foreach_r_custom.c3t +++ b/test/test_suite/statements/foreach_r_custom.c3t @@ -18,7 +18,7 @@ macro usz Foo.@operator_len(&foo) @operator(len) fn void main() { - int[?] i = { 1, 3, 10 }; + int[*] i = { 1, 3, 10 }; Foo x = { &i }; foreach_r FOO: (int f : x) { printf("%d\n", f); diff --git a/test/test_suite/statements/foreach_r_custom_macro.c3t b/test/test_suite/statements/foreach_r_custom_macro.c3t index 2aee831c0..2239fa8cf 100644 --- a/test/test_suite/statements/foreach_r_custom_macro.c3t +++ b/test/test_suite/statements/foreach_r_custom_macro.c3t @@ -17,7 +17,7 @@ macro usz Foo.@operator_len(&foo) @operator(len) fn void main() { - int[?] i = { 1, 3, 10 }; + int[*] i = { 1, 3, 10 }; Foo x = { &i }; foreach_r FOO: (int f : x) { printf("%d\n", f); diff --git a/test/test_suite/statements/foreach_r_errors.c3 b/test/test_suite/statements/foreach_r_errors.c3 index df840104a..da0b00fa7 100644 --- a/test/test_suite/statements/foreach_r_errors.c3 +++ b/test/test_suite/statements/foreach_r_errors.c3 @@ -33,12 +33,12 @@ fn void test4() fn void test5() { - foreach_r (int! y : z) foo(); + foreach_r (int? y : z) foo(); } fn void test6() { - foreach_r (int! i, y : z) foo(); // #error: The index may not be an optional. + foreach_r (int? i, y : z) foo(); // #error: The index may not be an optional. } fn void test7() diff --git a/test/test_suite/statements/foreach_r_with_error.c3 b/test/test_suite/statements/foreach_r_with_error.c3 index dea64e90c..310651dad 100644 --- a/test/test_suite/statements/foreach_r_with_error.c3 +++ b/test/test_suite/statements/foreach_r_with_error.c3 @@ -2,7 +2,7 @@ module test; fn void test() { - int[3]! x; + int[3]? x; int g; foreach_r (z : x) // #error: The foreach iterable expression may not be { diff --git a/test/test_suite/statements/foreach_with_error.c3 b/test/test_suite/statements/foreach_with_error.c3 index 7edd14487..0ee448ad0 100644 --- a/test/test_suite/statements/foreach_with_error.c3 +++ b/test/test_suite/statements/foreach_with_error.c3 @@ -2,7 +2,7 @@ module test; fn void test() { - int[3]! x; + int[3]? x; int g; foreach (z : x) // #error: The foreach iterable expression { diff --git a/test/test_suite/statements/if_only_throw.c3t b/test/test_suite/statements/if_only_throw.c3t index de4517409..b755219c6 100644 --- a/test/test_suite/statements/if_only_throw.c3t +++ b/test/test_suite/statements/if_only_throw.c3t @@ -2,15 +2,14 @@ module foo; import std::io; -fault Foo { ABC } -fn void! test() +fault ABC; + +fn void? test() { - if ((Foo.ABC?!)) - { - } + if ((ABC?!)) + { } else - { - } + {} } fn void main() { @@ -22,7 +21,7 @@ fn void main() define i64 @foo.test() #0 { entry: %error_var = alloca i64, align 8 - store i64 ptrtoint (ptr @"foo.Foo$ABC" to i64), ptr %error_var, align 8 + store i64 ptrtoint (ptr @foo.ABC to i64), ptr %error_var, align 8 br label %guard_block guard_block: ; preds = %entry %0 = load i64, ptr %error_var, align 8 diff --git a/test/test_suite/statements/if_while_do_error.c3 b/test/test_suite/statements/if_while_do_error.c3 index 3658e1d8b..fec0a2eba 100644 --- a/test/test_suite/statements/if_while_do_error.c3 +++ b/test/test_suite/statements/if_while_do_error.c3 @@ -2,8 +2,8 @@ module test; fn void test1() { - bool! x = false; - if (x) // #error: optional, but was 'bool! + bool? x = false; + if (x) // #error: optional, but was 'bool? { x = 100; } @@ -11,8 +11,8 @@ fn void test1() fn void test2() { - bool! x = false; - while (x) // #error: optional, but was 'bool! + bool? x = false; + while (x) // #error: optional, but was 'bool? { x = false; } @@ -20,7 +20,7 @@ fn void test2() fn void test3() { - bool! x = false; + bool? x = false; double y = 1; do { @@ -30,5 +30,5 @@ fn void test3() { x = !x; } - while (x); // #error: 'bool!' cannot be implicitly converted to a regular boolean value + while (x); // #error: 'bool?' cannot be implicitly converted to a regular boolean value } \ No newline at end of file diff --git a/test/test_suite/statements/switch_errors.c3 b/test/test_suite/statements/switch_errors.c3 index b9b2415f9..ace0cd4bc 100644 --- a/test/test_suite/statements/switch_errors.c3 +++ b/test/test_suite/statements/switch_errors.c3 @@ -135,13 +135,10 @@ fn void test_missing_no_cases(Baz x) } } -fault MathError -{ - DIVISION_BY_ZERO -} +fault DIVISION_BY_ZERO; // Rethrowing an error uses "!!" suffix -fn void! testMayError() +fn void? testMayError() { } @@ -150,7 +147,7 @@ fn void main() // Handle the error switch (catch err = testMayError()) // #error: Catch unwrapping is only allowed { - case MathError.DIVISION_BY_ZERO: + case DIVISION_BY_ZERO: libc::printf("Division by zero\n"); return; default: diff --git a/test/test_suite/statements/various_switching.c3t b/test/test_suite/statements/various_switching.c3t index ad11436f3..8c398c6cd 100644 --- a/test/test_suite/statements/various_switching.c3t +++ b/test/test_suite/statements/various_switching.c3t @@ -3,19 +3,12 @@ module mymodule; extern fn void printf(char *, ...); -fault HelloErr -{ - FOO, -} -fault ByeErr -{ - BAR, - BAZ -} +fault FOO; +fault BAR, BAZ; fn void test() { - int! x = ByeErr.BAR?; + int? x = BAR?; typeid z = int.typeid; switch (z) @@ -70,7 +63,7 @@ entry: %zy = alloca i32, align 4 %switch17 = alloca i32, align 4 %switch27 = alloca i8, align 1 - store i64 ptrtoint (ptr @"mymodule.ByeErr$BAR" to i64), ptr %x.f, align 8 + store i64 ptrtoint (ptr @mymodule.BAR to i64), ptr %x.f, align 8 store i64 ptrtoint (ptr @"$ct.int" to i64), ptr %z, align 8 %0 = load i64, ptr %z, align 8 store i64 %0, ptr %switch, align 8 @@ -148,7 +141,7 @@ next_if16: ; preds = %result_block14 br label %switch.default switch.default: ; preds = %next_if16, %switch.case15 - call void (ptr, ...) @printf(ptr @.str.3) + call void (ptr, ...) @printf(ptr @.str.1) br label %switch.exit switch.exit: ; preds = %switch.default, %switch.case @@ -169,7 +162,7 @@ switch.entry18: ; preds = %switch.exit br i1 %eq19, label %switch.case20, label %next_if21 switch.case20: ; preds = %switch.entry18 - call void (ptr, ...) @printf(ptr @.str.4) + call void (ptr, ...) @printf(ptr @.str.2) br label %switch.exit26 next_if21: ; preds = %switch.entry18 @@ -178,14 +171,14 @@ next_if21: ; preds = %switch.entry18 br i1 %eq22, label %switch.case23, label %next_if24 switch.case23: ; preds = %next_if21 - call void (ptr, ...) @printf(ptr @.str.5) + call void (ptr, ...) @printf(ptr @.str.3) br label %switch.exit26 next_if24: ; preds = %next_if21 br label %switch.default25 switch.default25: ; preds = %next_if24 - call void (ptr, ...) @printf(ptr @.str.6) + call void (ptr, ...) @printf(ptr @.str.4) br label %switch.exit26 switch.exit26: ; preds = %switch.default25, %switch.case23, %switch.case20 @@ -201,7 +194,7 @@ switch.entry28: ; preds = %switch.exit26 br i1 %eq29, label %switch.case30, label %next_if31 switch.case30: ; preds = %switch.entry28 - call void (ptr, ...) @printf(ptr @.str.7) + call void (ptr, ...) @printf(ptr @.str.5) br label %switch.exit37 next_if31: ; preds = %switch.entry28 @@ -211,14 +204,14 @@ next_if31: ; preds = %switch.entry28 br i1 %eq33, label %switch.case34, label %next_if35 switch.case34: ; preds = %next_if31 - call void (ptr, ...) @printf(ptr @.str.8) + call void (ptr, ...) @printf(ptr @.str.6) br label %switch.exit37 next_if35: ; preds = %next_if31 br label %switch.default36 switch.default36: ; preds = %next_if35 - call void (ptr, ...) @printf(ptr @.str.9) + call void (ptr, ...) @printf(ptr @.str.7) br label %switch.exit37 switch.exit37: ; preds = %switch.default36, %switch.case34, %switch.case30 @@ -229,6 +222,6 @@ switch.exit37: ; preds = %switch.default36, % define void @mymodule.main() #0 { entry: call void @mymodule.test() - call void (ptr, ...) @printf(ptr @.str.10) + call void (ptr, ...) @printf(ptr @.str.8) ret void } diff --git a/test/test_suite/strings/string_to_array.c3t b/test/test_suite/strings/string_to_array.c3t index f29d45a93..bd239b114 100644 --- a/test/test_suite/strings/string_to_array.c3t +++ b/test/test_suite/strings/string_to_array.c3t @@ -2,12 +2,12 @@ module foo; char[2] g = "ab"; -char[?] h = "abc"; +char[*] h = "abc"; fn int main() { char[2] x = "ab"; - char[?] y = "abc"; + char[*] y = "abc"; return 0; } diff --git a/test/test_suite/struct/flex_array_comparison.c3 b/test/test_suite/struct/flex_array_comparison.c3 index d2f0c09be..ebb66a161 100644 --- a/test/test_suite/struct/flex_array_comparison.c3 +++ b/test/test_suite/struct/flex_array_comparison.c3 @@ -3,7 +3,7 @@ module test; struct Abc { int x; - int[?] y; + int[*] y; } diff --git a/test/test_suite/struct/flex_array_struct_err.c3 b/test/test_suite/struct/flex_array_struct_err.c3 index 8ec5ae6eb..59faccf3b 100644 --- a/test/test_suite/struct/flex_array_struct_err.c3 +++ b/test/test_suite/struct/flex_array_struct_err.c3 @@ -1,19 +1,19 @@ struct Foo { int x; - int[?] y; // #error: flexible array member must be the last element + int[*] y; // #error: flexible array member must be the last element int z; } struct Bar { - int[?] y; // #error: flexible array member cannot be the only element + int[*] y; // #error: flexible array member cannot be the only element } struct Baz { int y; - int[?] z; + int[*] z; } struct BazContainerOk diff --git a/test/test_suite/struct/flexible_array_resolve.c3 b/test/test_suite/struct/flexible_array_resolve.c3 index 1255468cf..cd0f5f91e 100644 --- a/test/test_suite/struct/flexible_array_resolve.c3 +++ b/test/test_suite/struct/flexible_array_resolve.c3 @@ -6,11 +6,11 @@ struct Abc struct Foo { int a; - int[?] x; + int[*] x; } struct Foo2 { int a; - int[?] x, y; // #error: must be the last element + int[*] x, y; // #error: must be the last element } diff --git a/test/test_suite/struct/nested_struct_init.c3t b/test/test_suite/struct/nested_struct_init.c3t index c67162466..074a22705 100644 --- a/test/test_suite/struct/nested_struct_init.c3t +++ b/test/test_suite/struct/nested_struct_init.c3t @@ -38,12 +38,12 @@ fn void main() %Matrix2x2_b = type { %.anon.1 } %.anon.1 = type { [4 x float] } -@"$ct.foo.$anon" = linkonce global %.introspect { i8 10, i64 0, ptr null, i64 16, i64 0, i64 4, [0 x i64] zeroinitializer }, align 8 -@"$ct.foo.$anon.3" = linkonce global %.introspect { i8 11, i64 0, ptr null, i64 16, i64 0, i64 2, [0 x i64] zeroinitializer }, align 8 -@"$ct.foo.Matrix2x2" = linkonce global %.introspect { i8 10, i64 0, ptr null, i64 16, i64 0, i64 1, [0 x i64] zeroinitializer }, align 8 -@"$ct.foo.$anon.6" = linkonce global %.introspect { i8 10, i64 0, ptr null, i64 16, i64 0, i64 4, [0 x i64] zeroinitializer }, align 8 -@"$ct.foo.$anon.7" = linkonce global %.introspect { i8 11, i64 0, ptr null, i64 16, i64 0, i64 2, [0 x i64] zeroinitializer }, align 8 -@"$ct.foo.Matrix2x2_b" = linkonce global %.introspect { i8 10, i64 0, ptr null, i64 16, i64 0, i64 1, [0 x i64] zeroinitializer }, align 8 +@"$ct.foo.$anon" = linkonce global %.introspect { i8 9, i64 0, ptr null, i64 16, i64 0, i64 4, [0 x i64] zeroinitializer }, align 8 +@"$ct.foo.$anon.3" = linkonce global %.introspect { i8 10, i64 0, ptr null, i64 16, i64 0, i64 2, [0 x i64] zeroinitializer }, align 8 +@"$ct.foo.Matrix2x2" = linkonce global %.introspect { i8 9, i64 0, ptr null, i64 16, i64 0, i64 1, [0 x i64] zeroinitializer }, align 8 +@"$ct.foo.$anon.6" = linkonce global %.introspect { i8 9, i64 0, ptr null, i64 16, i64 0, i64 4, [0 x i64] zeroinitializer }, align 8 +@"$ct.foo.$anon.7" = linkonce global %.introspect { i8 10, i64 0, ptr null, i64 16, i64 0, i64 2, [0 x i64] zeroinitializer }, align 8 +@"$ct.foo.Matrix2x2_b" = linkonce global %.introspect { i8 9, i64 0, ptr null, i64 16, i64 0, i64 1, [0 x i64] zeroinitializer }, align 8 @.__const = private unnamed_addr constant %Matrix2x2 { %.anon { %.anon.0 { float 1.000000e+00, float 2.000000e+00, float 3.000000e+00, float 4.000000e+00 } } }, align 4 @.__const.8 = private unnamed_addr constant %Matrix2x2_b { %.anon.1 { [4 x float] [float 1.000000e+00, float 2.000000e+00, float 3.000000e+00, float 4.000000e+00] } }, align 4 @.str = private unnamed_addr constant [13 x i8] c"%f %f %f %f\0A\00", align 1 diff --git a/test/test_suite/struct/struct_as_value.c3t b/test/test_suite/struct/struct_as_value.c3t index 58d5a0602..7bd97267a 100644 --- a/test/test_suite/struct/struct_as_value.c3t +++ b/test/test_suite/struct/struct_as_value.c3t @@ -16,7 +16,7 @@ fn Event test(int x) /* #expect: test.ll %Event = type { i32 } -@"$ct.test.Event" = linkonce global %.introspect { i8 10, i64 0, ptr null, i64 4, i64 0, i64 1, [0 x i64] zeroinitializer }, align 8 +@"$ct.test.Event" = linkonce global %.introspect { i8 9, i64 0, ptr null, i64 4, i64 0, i64 1, [0 x i64] zeroinitializer }, align 8 @.__const = private unnamed_addr constant %Event { i32 1 }, align 4 @.__const.1 = private unnamed_addr constant %Event { i32 2 }, align 4 diff --git a/test/test_suite/struct/struct_codegen.c3t b/test/test_suite/struct/struct_codegen.c3t index 966691695..bac07a6cd 100644 --- a/test/test_suite/struct/struct_codegen.c3t +++ b/test/test_suite/struct/struct_codegen.c3t @@ -16,7 +16,7 @@ fn void test1() %Point = type { i32, i32 } -@"$ct.test.Point" = linkonce global %.introspect { i8 10, i64 0, ptr null, i64 8, i64 0, i64 2, [0 x i64] zeroinitializer }, align 8 +@"$ct.test.Point" = linkonce global %.introspect { i8 9, i64 0, ptr null, i64 8, i64 0, i64 2, [0 x i64] zeroinitializer }, align 8 @.__const = private unnamed_addr constant %Point { i32 5, i32 6 }, align 4 define void @test.test1() #0 { diff --git a/test/test_suite/struct/struct_codegen_fam.c3t b/test/test_suite/struct/struct_codegen_fam.c3t index daaeb7c81..d7fda8dc5 100644 --- a/test/test_suite/struct/struct_codegen_fam.c3t +++ b/test/test_suite/struct/struct_codegen_fam.c3t @@ -8,7 +8,7 @@ struct Bar int y; } int ufe; - int[?] z; + int[*] z; } diff --git a/test/test_suite/struct/struct_const_construct_simple.c3t b/test/test_suite/struct/struct_const_construct_simple.c3t index 2a81d9db5..7b670605a 100644 --- a/test/test_suite/struct/struct_const_construct_simple.c3t +++ b/test/test_suite/struct/struct_const_construct_simple.c3t @@ -20,7 +20,7 @@ Foo foo8 @private = FOO7; /* #expect: structo.ll -@"$ct.structo.Foo" = linkonce global %.introspect { i8 10, i64 0, ptr null, i64 16, i64 0, i64 2, [0 x i64] zeroinitializer }, align 8 +@"$ct.structo.Foo" = linkonce global %.introspect { i8 9, i64 0, ptr null, i64 16, i64 0, i64 2, [0 x i64] zeroinitializer }, align 8 @structo.x = internal unnamed_addr global i64 16, align 8 @structo.foo1 = internal unnamed_addr global %Foo { i32 1, i64 2 }, align 8 @structo.foo2 = internal unnamed_addr global %Foo { i32 2, i64 0 }, align 8 diff --git a/test/test_suite/switch/bad_ranges.c3 b/test/test_suite/switch/bad_ranges.c3 index af839145d..91e6df832 100644 --- a/test/test_suite/switch/bad_ranges.c3 +++ b/test/test_suite/switch/bad_ranges.c3 @@ -1,6 +1,6 @@ module test; -fn void! test1() +fn void? test1() { double a; switch (a) @@ -10,7 +10,7 @@ fn void! test1() } } -fn void! test2() +fn void? test2() { int a; switch (a) diff --git a/test/test_suite/switch/failable_switch.c3 b/test/test_suite/switch/failable_switch.c3 index 52489999d..379c78687 100644 --- a/test/test_suite/switch/failable_switch.c3 +++ b/test/test_suite/switch/failable_switch.c3 @@ -1,14 +1,11 @@ -fault MyError -{ - FOO -} +fault FOO; fn void test() { int x = 0; switch (x) { - case MyError.FOO? : // #error: 'int!' to 'int' + case FOO? : // #error: 'int?' to 'int' x = x + 1; } } \ No newline at end of file diff --git a/test/test_suite/switch/switch_in_defer_macro.c3t b/test/test_suite/switch/switch_in_defer_macro.c3t index 038dde243..8ac5232b0 100644 --- a/test/test_suite/switch/switch_in_defer_macro.c3t +++ b/test/test_suite/switch/switch_in_defer_macro.c3t @@ -19,12 +19,7 @@ enum Kind : char IDENTIFIER, } -fault LexerError -{ - UNTERMINATED_STRING, - UNTERMINATED_RUNE, - UNTERMINATED_COMMENT, -} +fault UNTERMINATED_STRING, UNTERMINATED_RUNE, UNTERMINATED_COMMENT; def TokenTrie = Trie{Token, ushort}; @@ -51,7 +46,7 @@ struct Lexer } } -fn void! Lexer.init(&self, InStream reader, Ident ident, Allocator using = mem) +fn void? Lexer.init(&self, InStream reader, Ident ident, Allocator using = mem) { TokenTrie trie; ushort max_token; @@ -72,13 +67,13 @@ fn void! Lexer.init(&self, InStream reader, Ident ident, Allocator using = mem) *self = { .allocator = using, .reader = reader, .buf = buf[:max_token], .tokens = trie }; } -fn void! Lexer.free(&self) +fn void? Lexer.free(&self) { allocator::free(self.allocator, self.buf); *self = {}; } -fn Kind! Lexer.next(&self) +fn Kind? Lexer.next(&self) { if (self.peeked) { @@ -121,7 +116,7 @@ fn Kind! Lexer.next(&self) return UNKNOWN; } -fn Kind! Lexer.peek(&self) +fn Kind? Lexer.peek(&self) { if (!self.peeked) { @@ -131,7 +126,7 @@ fn Kind! Lexer.peek(&self) return self.kind; } -fn Token! Lexer.expect(&self, anyfault err, Token... tokens) +fn Token? Lexer.expect(&self, anyfault err, Token... tokens) { Kind kind = self.next()!; if (kind == TOKEN) @@ -144,7 +139,7 @@ fn Token! Lexer.expect(&self, anyfault err, Token... tokens) return err?; } -fn void! Lexer.skip_whitespace(&self) @private +fn void? Lexer.skip_whitespace(&self) @private { self.span = 0; while (true) @@ -167,7 +162,7 @@ fn void! Lexer.skip_whitespace(&self) @private } } -fn ulong! Lexer.parse_uint(&self) @private +fn ulong? Lexer.parse_uint(&self) @private { ulong x; char c = self.reader.read_byte()!; @@ -191,7 +186,7 @@ fn ulong! Lexer.parse_uint(&self) @private return self.parse_decimal()!; } -fn ulong! Lexer.parse_decimal(&self) @private +fn ulong? Lexer.parse_decimal(&self) @private { return @parse_uint(self, ulong; ulong x, char c, bool ok) { @@ -203,7 +198,7 @@ fn ulong! Lexer.parse_decimal(&self) @private }; } -fn ulong! Lexer.parse_hexadecimal(&self) @private +fn ulong? Lexer.parse_hexadecimal(&self) @private { return @parse_uint(self, ulong; ulong x, char c, bool ok) { @@ -220,7 +215,7 @@ fn ulong! Lexer.parse_hexadecimal(&self) @private }; } -fn ulong! Lexer.parse_binary(&self) @private +fn ulong? Lexer.parse_binary(&self) @private { return @parse_uint(self, ulong; ulong x, char c, bool ok) { @@ -232,7 +227,7 @@ fn ulong! Lexer.parse_binary(&self) @private }; } -fn ulong! Lexer.parse_octal(&self) @private +fn ulong? Lexer.parse_octal(&self) @private { return @parse_uint(self, ulong; ulong x, char c, bool ok) { @@ -250,10 +245,10 @@ macro @parse_uint(self, $Type; @body(x, c, ok)) @private uint column = self.column; while (true) { - char! c = self.reader.read_byte(); + char? c = self.reader.read_byte(); if (catch err = c) { - if (err == IoError.EOF) break; + if (err == io::EOF) break; return err?; } else @@ -263,7 +258,7 @@ macro @parse_uint(self, $Type; @body(x, c, ok)) @private $Type xx = x; bool ok; @body(x, c, ok); - if (xx > x) return NumberConversion.INTEGER_OVERFLOW?; + if (xx > x) return string::INTEGER_OVERFLOW?; if (!ok) { self.column--; @@ -276,7 +271,7 @@ macro @parse_uint(self, $Type; @body(x, c, ok)) @private return x; } -fn String! Lexer.parse_string(&self, char quote) @private +fn String? Lexer.parse_string(&self, char quote) @private { char c = self.read_char_for_string()!; if (c == quote) return ""; @@ -317,26 +312,26 @@ fn String! Lexer.parse_string(&self, char quote) @private } } -fn char! Lexer.parse_rune(&self) @private +fn char? Lexer.parse_rune(&self) @private { char x = self.reader.read_byte()!; char c = self.reader.read_byte()!; - if (c != '\'') return LexerError.UNTERMINATED_RUNE?; + if (c != '\'') return UNTERMINATED_RUNE?; return x; } -macro char! Lexer.read_char_for_string(&self) @private +macro char? Lexer.read_char_for_string(&self) @private { - char! c = self.reader.read_byte(); + char? c = self.reader.read_byte(); if (catch err = c) { - if (err == IoError.EOF) return LexerError.UNTERMINATED_STRING?; + if (err == io::EOF) return UNTERMINATED_STRING?; return err?; } return c; } -fn Token! Lexer.parse_token(&self) @private +fn Token? Lexer.parse_token(&self) @private { usz n = self.reader.read(self.buf)!; defer self.unread(n); @@ -345,7 +340,7 @@ fn Token! Lexer.parse_token(&self) @private return tok; } -fn void! Lexer.parse_comment(&self, String end) @private +fn void? Lexer.parse_comment(&self, String end) @private { // Find the end token and accumulate the data in between. DString acc; @@ -355,7 +350,7 @@ fn void! Lexer.parse_comment(&self, String end) @private { if (catch err = io::read_all(self.reader, buf)) { - if (err == IoError.UNEXPECTED_EOF || err == IoError.EOF) return LexerError.UNTERMINATED_COMMENT?; + if (err == io::UNEXPECTED_EOF || err == io::EOF) return UNTERMINATED_COMMENT?; return err?; } if (end == (String)buf) @@ -384,16 +379,16 @@ macro Lexer.unread(self, n) @private } } -fn String! Lexer.parse_ident(&self) @private +fn String? Lexer.parse_ident(&self) @private { DString str; str.init(self.allocator, 8); while (true) { - char! c = self.reader.read_byte(); + char? c = self.reader.read_byte(); if (catch err = c) { - if (err == IoError.EOF) return str.str_view(); + if (err == io::EOF) return str.str_view(); return err?; } if (!self.ident(str.len(), c)) return str.str_view(); @@ -433,7 +428,7 @@ struct UintTest ulong out; } -fn void! lex_uint() +fn void? lex_uint() { UintTest[] tcases = {}; foreach (tc : tcases) @@ -464,10 +459,7 @@ import trie::bitmap; def TrieNodeList = List{TrieNode}; def TriePath = List{Index} @private; -fault TrieError -{ - TRIE_FULL, -} +fault TRIE_FULL; struct Trie { @@ -491,7 +483,7 @@ fn void Trie.init(&self, usz initial_capacity = 8, Allocator using = allocator:: <* @require self.nodes.len() > 0 *> -fn Value! Trie.get(&self, char[] key) +fn Value? Trie.get(&self, char[] key) { return self.nodes[0].get(self, key); } @@ -499,17 +491,17 @@ fn Value! Trie.get(&self, char[] key) <* @require self.nodes.len() > 0 *> -fn Value! Trie.get_best(&self, char[] key) +fn Value? Trie.get_best(&self, char[] key) { TrieNode* root = &self.nodes[0]; - if (key.len == 0) return root.valid ? root.value : SearchResult.MISSING?; + if (key.len == 0) return root.valid ? root.value : NOT_FOUND?; return root.get_best(self, key, 0); } <* @require self.nodes.len() > 0 *> -fn void! Trie.set(&self, char[] key, Value value) +fn void? Trie.set(&self, char[] key, Value value) { self.nodes[0].set(self, key, value)!!; } @@ -517,7 +509,7 @@ fn void! Trie.set(&self, char[] key, Value value) <* @require self.nodes.len() > 0 *> -fn void! Trie.del(&self, char[] key) +fn void? Trie.del(&self, char[] key) { if (key.len == 0) { @@ -532,27 +524,27 @@ fn void! Trie.del(&self, char[] key) self.nodes[0].del(self, key, path)!; } -fn Value! TrieNode.get(&self, Trie *t, char[] key) @private +fn Value? TrieNode.get(&self, Trie *t, char[] key) @private { - if (key.len == 0) return self.valid ? self.value : SearchResult.MISSING?; + if (key.len == 0) return self.valid ? self.value : NOT_FOUND?; char c = key[0]; Index idx = self.children[c]; - if (idx == 0) return SearchResult.MISSING?; + if (idx == 0) return NOT_FOUND?; return t.nodes[idx].get(t, key[1..]); } -fn Value! TrieNode.get_best(&self, Trie *t, char[] key, Index result) @private +fn Value? TrieNode.get_best(&self, Trie *t, char[] key, Index result) @private { if (key.len == 0) { - if (result == 0) return SearchResult.MISSING?; + if (result == 0) return NOT_FOUND?; return t.nodes[result].value; } char c = key[0]; Index idx = self.children[c]; if (idx == 0) { - if (result == 0) return SearchResult.MISSING?; + if (result == 0) return NOT_FOUND?; return t.nodes[result].value; } TrieNode* next = &t.nodes[idx]; @@ -560,7 +552,7 @@ fn Value! TrieNode.get_best(&self, Trie *t, char[] key, Index result) @private return next.get_best(t, key[1..], result); } -fn void! TrieNode.set(&self, Trie *t, char[] key, Value value) @private +fn void? TrieNode.set(&self, Trie *t, char[] key, Value value) @private { if (key.len == 0) { @@ -574,7 +566,7 @@ fn void! TrieNode.set(&self, Trie *t, char[] key, Value value) @private { usz new_idx = t.nodes.len(); assert(new_idx != 0); - if (new_idx > Index.max) return TrieError.TRIE_FULL?; + if (new_idx > Index.max) return TRIE_FULL?; idx = (Index)new_idx; self.children[c] = idx; t.nodes.push((TrieNode){}); @@ -582,7 +574,7 @@ fn void! TrieNode.set(&self, Trie *t, char[] key, Value value) @private t.nodes[idx].set(t, key[1..], value)!; } -fn void! TrieNode.del(&self, Trie* t, char[] key, TriePath path) @private +fn void? TrieNode.del(&self, Trie* t, char[] key, TriePath path) @private { if (key.len > 0) { @@ -648,7 +640,7 @@ fn void test() { Trie t; t.init(); - String! v = t.get("a"); + String? v = t.get("a"); if (try v) unreachable("key 'a' should not exist"); if (catch t.set("a", "va")) unreachable("key 'a' not added"); String w = t.get("a")!!; @@ -666,7 +658,7 @@ fn void test() assert(ww == "hi"); t.del("a")!!; - String! x = t.get("a"); + String? x = t.get("a"); if (try x) unreachable("key 'a' should not exist"); } @@ -683,7 +675,7 @@ fn void test() %List = type { i64, i64, %any, ptr } %.anon = type { %"char[]" } -@"$ct.lexer_test.UintTest" = linkonce global %.introspect { i8 10, i64 0, ptr null, i64 24, i64 0, i64 2, [0 x i64] zeroinitializer }, align 8 +@"$ct.lexer_test.UintTest" = linkonce global %.introspect { i8 9, i64 0, ptr null, i64 24, i64 0, i64 2, [0 x i64] zeroinitializer }, align 8 @.enum.KEYWORD1 = internal constant [9 x i8] c"KEYWORD1\00", align 1 @.enum.KEYWORD2 = internal constant [9 x i8] c"KEYWORD2\00", align 1 @.enum.SINGLE = internal constant [7 x i8] c"SINGLE\00", align 1 @@ -700,7 +692,7 @@ fn void test() @.str.4 = private unnamed_addr constant [2 x i8] c"\0A\00", align 1 @.str.5 = private unnamed_addr constant [3 x i8] c"*/\00", align 1 @"lexer_test.Comment$end" = linkonce constant [2 x %"char[]"] [%"char[]" { ptr @.str.4, i64 1 }, %"char[]" { ptr @.str.5, i64 2 }], align 8 -@"$ct.std.io.ByteReader" = linkonce global %.introspect { i8 10, i64 0, ptr null, i64 24, i64 0, i64 2, [0 x i64] zeroinitializer }, align 8 +@"$ct.std.io.ByteReader" = linkonce global %.introspect { i8 9, i64 0, ptr null, i64 24, i64 0, i64 2, [0 x i64] zeroinitializer }, align 8 @std.core.mem.allocator.thread_allocator = extern_weak thread_local global %any, align 8 ; Function Attrs: @@ -737,7 +729,7 @@ or.phi: ; preds = %and.phi2, %and.phi ret i8 %6 } -; Function Attrs: +; Function Attrs: nounwind uwtable define i64 @lexer_test.lex_uint() #0 { entry: %tcases = alloca %"UintTest[]", align 8 diff --git a/test/test_suite/union/flexible_array_union.c3 b/test/test_suite/union/flexible_array_union.c3 index 1cb6e05a9..42bbe8276 100644 --- a/test/test_suite/union/flexible_array_union.c3 +++ b/test/test_suite/union/flexible_array_union.c3 @@ -1,5 +1,5 @@ union Zee { int z; - int[?] y; // #error: Flexible array members not allowed in unions. + int[*] y; // #error: Flexible array members not allowed in unions. } \ No newline at end of file diff --git a/test/test_suite/union/inferred_size_vector.c3 b/test/test_suite/union/inferred_size_vector.c3 index 2adce22bd..03a77a602 100644 --- a/test/test_suite/union/inferred_size_vector.c3 +++ b/test/test_suite/union/inferred_size_vector.c3 @@ -1,4 +1,4 @@ union Foo { - int[] x; // #error: Inferred vector types can only + int[<*>] x; // #error: Inferred vector types can only } diff --git a/test/test_suite/vector/swizzling.c3 b/test/test_suite/vector/swizzling.c3 index e7b4c72b4..56955e20b 100644 --- a/test/test_suite/vector/swizzling.c3 +++ b/test/test_suite/vector/swizzling.c3 @@ -1,6 +1,6 @@ // #target: macos-x64 -fn void! swizzle_test() +fn void? swizzle_test() { int[<4>] abc = { 1, 2, 3, 4 }; int[<3>] z = abc.rbx; // #error: Mixing diff --git a/test/test_suite/vector/vector_to_array_fail.c3 b/test/test_suite/vector/vector_to_array_fail.c3 index 25ff8fe9e..1635a9403 100644 --- a/test/test_suite/vector/vector_to_array_fail.c3 +++ b/test/test_suite/vector/vector_to_array_fail.c3 @@ -4,10 +4,10 @@ fn void main() { int[<2>] x = { 4, 7 }; int[2] y = x; - int[?] y1 = y; - int[?] y2 = x; - int[] z = x; - int[] w = y; + int[*] y1 = y; + int[*] y2 = x; + int[<*>] z = x; + int[<*>] w = y; double[<2>] ww = x; short[<2>] www = y; // #error: Implicitly casting 'int[2]' to 'short[<2>]' } \ No newline at end of file diff --git a/test/test_suite/visibility/export_property.c3t b/test/test_suite/visibility/export_property.c3t index 3aa969ce4..c9efe1f28 100644 --- a/test/test_suite/visibility/export_property.c3t +++ b/test/test_suite/visibility/export_property.c3t @@ -21,7 +21,7 @@ struct Test int fa : 1..6; } Abc y; - int[?] x; + int[*] x; } /* #expect: test.ll @@ -31,8 +31,8 @@ struct Test %Test = type { %.anon, i32, i32, [0 x i32] } %.anon = type { i32, i32 } -@"$ct.test.$anon" = linkonce global %.introspect { i8 10, i64 0, ptr null, i64 8, i64 0, i64 2, [0 x i64] zeroinitializer }, align 8 -@"$ct.test.Test" = linkonce global %.introspect { i8 10, i64 0, ptr null, i64 16, i64 0, i64 4, [0 x i64] zeroinitializer }, align 8 +@"$ct.test.$anon" = linkonce global %.introspect { i8 9, i64 0, ptr null, i64 8, i64 0, i64 2, [0 x i64] zeroinitializer }, align 8 +@"$ct.test.Test" = linkonce global %.introspect { i8 9, i64 0, ptr null, i64 16, i64 0, i64 4, [0 x i64] zeroinitializer }, align 8 @.enum.ABC = internal constant [4 x i8] c"ABC\00", align 1 @.enum.DEF = internal constant [4 x i8] c"DEF\00", align 1 @"$ct.int" = linkonce global %.introspect { i8 2, i64 0, ptr null, i64 4, i64 0, i64 0, [0 x i64] zeroinitializer }, align 8 diff --git a/test/unit/regression/castable_assignable.c3 b/test/unit/regression/castable_assignable.c3 index 9254778d4..73224337f 100644 --- a/test/unit/regression/castable_assignable.c3 +++ b/test/unit/regression/castable_assignable.c3 @@ -7,7 +7,7 @@ fn void assignable() assert(!$assignable("12", int)); assert($assignable("12", String)); assert($assignable("12", char*)); - assert($assignable("12", char[?])); + assert($assignable("12", char[*])); assert($assignable("12", char[2])); assert($assignable("12", char[3])); } diff --git a/test/unit/regression/catch_err.c3 b/test/unit/regression/catch_err.c3 index 171abf6f4..bbc9eaf4d 100644 --- a/test/unit/regression/catch_err.c3 +++ b/test/unit/regression/catch_err.c3 @@ -3,17 +3,17 @@ module catch_err @test; fn void test() { anyfault a; - int! z = fn int!(anyfault* a) { + int? z = fn int?(anyfault* a) { const ABC = 4; - int! x = SearchResult.MISSING?; + int? x = NOT_FOUND?; defer (catch err) *a = err; return x; }(&a); - assert(a == SearchResult.MISSING); + assert(a == NOT_FOUND); anyfault y; - z = fn int!(anyfault* y) { + z = fn int?(anyfault* y) { const ABC = 4; - int! x = 1; + int? x = 1; defer (catch err) *y = err; return x; }(&y); diff --git a/test/unit/regression/faults.c3 b/test/unit/regression/faults.c3 deleted file mode 100644 index e4201162f..000000000 --- a/test/unit/regression/faults.c3 +++ /dev/null @@ -1,21 +0,0 @@ -module faults @test; - -fault Foo -{ - ABC, - CDE -} - -fn void ordinals() -{ - Foo z = {}; - assert(z.ordinal == 0); - $assert Foo.ABC.ordinal == 1; - $assert Foo.CDE.ordinal == 2; - $assert (Foo){}.ordinal == 0; - Foo x = Foo.CDE; - assert(x.ordinal == 2); - x = Foo.ABC; - assert(x.ordinal == 1); -} - diff --git a/test/unit/regression/unwrapping.c3 b/test/unit/regression/unwrapping.c3 index f68fc5452..319caff00 100644 --- a/test/unit/regression/unwrapping.c3 +++ b/test/unit/regression/unwrapping.c3 @@ -1,6 +1,6 @@ module unwrapping; -fn bool! get_bool() +fn bool? get_bool() { return true; } diff --git a/test/unit/regression/vecpointer.c3 b/test/unit/regression/vecpointer.c3 index 1499dd525..736d9b3c7 100644 --- a/test/unit/regression/vecpointer.c3 +++ b/test/unit/regression/vecpointer.c3 @@ -30,6 +30,6 @@ fn void pointer_add_sub_diff() assert(w == { -1, 2 }); int*[<2>] zz = y - (y - yy); assert(zz[0] == &a[1] && zz[1] == &a[2]); - int[?]*[<2>] g = (int[2]*[<2>]) { null, null }; - int[?]*[] g2 = (int[2]*[<2>]) { null, null }; + int[*]*[<2>] g = (int[2]*[<2>]) { null, null }; + int[*]*[<*>] g2 = (int[2]*[<2>]) { null, null }; } \ No newline at end of file diff --git a/test/unit/regression/vector_conversion.c3 b/test/unit/regression/vector_conversion.c3 index 5f9589b0e..2f14e36a6 100644 --- a/test/unit/regression/vector_conversion.c3 +++ b/test/unit/regression/vector_conversion.c3 @@ -4,10 +4,10 @@ fn void vector_array_inferred() { int[<2>] x = { 4, 7 }; int[2] y = x; - int[?] y1 = y; - int[?] y2 = x; - int[] z = x; - int[] w = y; + int[*] y1 = y; + int[*] y2 = x; + int[<*>] z = x; + int[<*>] w = y; double[<2>] ww = x; assert((int[<2>])y == { 4, 7}); assert((int[<2>])y1 == { 4, 7 }); diff --git a/test/unit/regression/vector_method_reduce.c3 b/test/unit/regression/vector_method_reduce.c3 index a0f5a539d..e981466c1 100644 --- a/test/unit/regression/vector_method_reduce.c3 +++ b/test/unit/regression/vector_method_reduce.c3 @@ -3,7 +3,7 @@ import std::math; fn void vector_method_reduce() @test { float[<3>] x = { 1, 2.0, 4.0 }; - int[] y = { -23, 1, 4 }; + int[<*>] y = { -23, 1, 4 }; assert(y.sum() == -18); assert(y.product() == -92); assert(y.max() == 4); diff --git a/test/unit/regression/wstring.c3 b/test/unit/regression/wstring.c3 index ce0e74600..7e3dc9d54 100644 --- a/test/unit/regression/wstring.c3 +++ b/test/unit/regression/wstring.c3 @@ -23,6 +23,6 @@ fn void lengths() @test { test::eq($$wstr16("ABC").len, 4); test::eq($$wstr16("ABC", false).len, 3); - Char16[?] w = $$wstr16("ÅÄÖ"); - test::eq(w, (Char16[?]) { 'Å', 'Ä', 'Ö', 0 }); + Char16[*] w = $$wstr16("ÅÄÖ"); + test::eq(w, (Char16[*]) { 'Å', 'Ä', 'Ö', 0 }); } \ No newline at end of file diff --git a/test/unit/stdlib/compression/qoi.c3 b/test/unit/stdlib/compression/qoi.c3 index 0b6aca4e3..21c3f2bcb 100644 --- a/test/unit/stdlib/compression/qoi.c3 +++ b/test/unit/stdlib/compression/qoi.c3 @@ -4,7 +4,7 @@ import std::io::file; import std::compression::qoi; -const char[?] TEST_QOI_DATA = b64"cW9pZgAAAVQAAACpBABV/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/cl/Jv39/f392jXBJv39/f392TXBJv39/f392TXBJv39/f392TXBJv39/f392TXBJv39/f392TXBJv39/f392DXBJv39/f392TXBJv39/f392TXBJv39/f392TXBJv39/f392TXBJu81Jv39zzXAJv390jXBJu01wyb9/cg1xib9/dA1wibsNcQm/f3GNcgm0zXAJv33NcEm6zXHJv39wzXIJtQ1xCb99DXBJus1wibANcEm/f3BNcgm1TXHJv3yNcEm6jXCJsE1wSb9/cA1xibZNSbANcQm/fE1wSbpNcImwjXBJv39NcUm4DXCJv3xNcEm6DXCJsM1wSb9/TXEJuI1wib98DXBJuc1wibENcEm/fw1wyblNcIm/e41wibmNcImxTXBJv37NcMm5zXBJv3uNcIm5jXCJsU1wSb9+jXEJuc1wib97TXCJuU1wibGNcEm/fk1xCboNcIm/e01wSbmNcImxjXBJv35NcMm6DXCJv3uNcEm5jXBJsc1wSb9+DXDJuk1wib97jXBJuU1wibGNcIm/fg1wyboNcIm/e81wSblNcEmxzXBJv34NcMm6TXCJv3vNcEm5TXBJsc1wSb9+DXCJuk1wib98DXBJuQ1wibHNcEm/fc1wyboNcMm/fA1wSbkNcEmxzXCJv33NcMm5jXEJv3xNcEm5DXBJsc1wSb9+DXCJuY1xSb98TXBJuM1wibGNcIm/fc1wybmNcQm/fI1wSbjNcEmxjXCJv34NcIm5zXGJv3wNcEm4zXBJsU1wyb9+DXCJug1xib97jXCJuI1wibENcMm/fk1wibrNcQm/e01wibiNcImwjXDJv37NcIm7DXEJv3sNcEm4zXBJsE1xCb9wDUm+TXCJu41wyb96zXBJuM1wSY1xSbKNcUm6jXDJvc1wibvNcMm/eo1wSbjNccmyzXIJuY1xSb3NcIm7zXEJv3pNcEm4jXGJsw1yibLNcUm0DXGJvc1wibwNcMm/ek1wSbiNcQmzTXLJsk1xybDNcImxjXHJvc1wibxNcIm/ek1wSbhNcMmzzXDJsA1xSbGNcomwjXDJsQ1ySb2NcIm8TXCJv3pNcEm4TXCJs81wibCNcUmxDXLJsI1xSbCNcQmNcIm9zXDJvA1wib96DXCJuI1wSbONcMmwzXEJsM1xibANcImwjXGJsA1xCY1wyb4NcIm7zXDJv3oNcIm4jXBJs41wibENcQmwTXGJsE1wybCNccmNcMmNcMm+TXCJtA1wibZNcIm/ek1wSbjNcEmzjXBJsU1wybANcYmwzXCJsI11Cb5NcMmzTXDJtk1wyb96TXBJuM1wSbNNcImxTXMJsM1wybCNcImwDXNJvs1wibMNcMm2TXDJv3qNcEm4zXBJs01wibFNcsmxDXDJsE1wybBNcsm/DXDJsk1xCbZNcQm/eo1wSbjNcEmzDXCJsc1yCbGNcImwjXCJsM1yCb9wDXEJsY1xCbaNcQm/es1wSbjNcEmyzXDJsY1xibJNcImwTXDJsQ1wib9xjXQJto1xCb97DXBJuM1wSbKNcQmxjXCJs01wibANcMmxTXCJv3HNc4m2jXEJv3tNcEm4zXBJsk1xibENcImzjXCJsA1wybENcMm/cg1yybbNcQm/e41wSbjNcImxzXCJjXCJsQ1wibNNcMmNcMmxTXDJv3JNcgm3DXEJv3vNcEm5DXBJsQ1xCbANcwmzTXIJsY1wyb98DXEJtg1wCb91DXBJuQ1wyY1xibCNcomzjXIJsc1wib96DXBJsE1xSbWNcAm/dc1wSblNckmxTXIJs81xybINcImzTXBJv3VNcMmNcUm1TXAJv3ZNcEm5jXHJsg1wibTNcYmyTXDJss1wSb91TXLJtQ1wCb92zXBJug1wSblNcYmyTXDJsk1wyb91TXJJtM1wCb93jXBJv3UNcQmzDXEJsU1xCb91TXJJtI1wCb94DXBJv3UNcMmzjXGJjXGJv3WNccm0jXAJv3iNcEm/dU1wSbPNc4m/dc1xibQNcAm/eU1wSb96zXLJv3YNcQm0DXAJv3nNcIm/ew1xyb92zXBJtA1wCb96jXBJv3uNcIm/fE1wCb97DXBJv39/eU1wCb9/f39/dc1wCb9/f39/dg1wCb9/f39/dg1wCbxNcUm/f39/dw1wCbxNcgm/f39/dk1wCbxNcom/f39/dc1wCbyNcQmwjXBJv39/f3VNcAm9DXCJsQ1wSb9/f390jXBJvY1wSbENcIm/f39/dA1wSb4NcAmxTXCJv39/f3ONcEm+zUmxTXCJs01wCb9/f35NcEm/cc1wibJNcUm1QDeJv39/DXCJv3JNcImyDXGJtUA3ib9/fo1wSb9zDXCJsU1yCbWAN4m/f33NcIm/c41wibDNckm1wDeJsdv4Cb9/co1wib9zzXCJsE1ySbaAN4mxzLgJv39yDXCJv3RNc4m3ADeJscy4Cb9/cY1wib9xTXBJsk1zCbeAN4mxzLgJv39xDXCJv3ENcYmxjXKJuEAyP8AAAC7/wAAAOr/AAAA9g4JAAn/AAAA+sAJAMomxzLJ/icAAMIy0Sb9/cI1wib9xTXIJsU1xybkAMc+yP8AAAD5AMomxzLI/o0AACrDMtAm/f3BNcEm/cY1ySbFNcUm5gDGPsoAyibHMsj+UQAAKsgyyyb9/TXBJv3INcImwDXDJsU1wyboAMY+whI+xQDKJscyyCrJMssm/fs1wSb9yjXBJsE1xCbENcEm6gDGPsIADj7DDgDKJscyyCrJMssm/fg1wib9zDXBJsE1xCbzAMUJPsEJPsUAyybHMsgqwSgqwP41AADAKBwyzCb99jXCJv3ONcImwDXEJsM1Ju0AxQ4+yQDLJscyyCrBMtMm/fQ1wib90DXCJsA1xSY1wibtAMUOPsgzCQDKJscyyCrBMtMm/fI1wib9yDXEJsI1wiY1yibuAMUJPsQJEj7DAMkmxzLIKsEy0yb98DXCJuY1wibcNcUmwTXOJu8AzQ4+wwDJJscyyCrBMtMm/e41wibpNcEm2zXHJsE1xSY1xSbvAM0JPsMAySbHMsgqwTLTJv3sNcIm6zXCJto1wSbANcMmwTXEJjXEJvAA3ibHMsgqwTLTJv3qNcIm7jXCJtA1JsE1JsA1wibCNcImwjXBJsI1wibxAN4mxzLIKsEy0yb96DXCJvA1wybONcomwzXCJv3BAN4mxzLIHMEy0yb95jXCJvM1wibPNckmwzXCJv3BAN4mxzLgJvs1wSbiNcIm9jXCJs81yCbDNcIm/cEA3ibHMuAm+zXCJt81wibxNSbENcImxTXDJsI1xCbANcImwjXCJv3qMuAm/DXCJtw1wibxNcEmxTXBJsQ1xSbBNcMmwjXBJsM1wSb96jLgJvw1wibcNcIm8DXCJsU1wibCNccmwTXCJsI1wSbENSb9/f3RNcEm3DXDJu81wSbFNcImwjXCJsA1wSbCNcEmwjXCJv39/dc1wibfNcAm7jXBJsY1wSbCNcEmwTXCJsE1wSbBNcMm/f392DXBJv3TNcImxTXBJsI1wSbCNcEmwDXCJsI1wib9/f3YNcEm/dM1wibFNcImwTXBJsE1wSY1xCbCNcIm/f392DXCJv3TNcEmxTXCJsE1wSY1wyY1xCbDNcAm/f39wjUm1TXBJv01wCbQNcEmxDXDJsE1xibANcEmNcAm/f39yDXDJtI1wSb4NckmzDXCJsE1xSbBNcUmwDXBJv39/cw1xCbRNcIm9jXPJsg1wSbANccmwDXDJsE1wib9/f3lNcIm9TXTJsU1xyY1wibANcEmwzXBJv39/eY1wib1NcUmNcsmxTXGJsA1wibANcImwTXCJv3Zftwm/es1wib1NcImwTXNJsM1xibCNcEmwDXCJsA1wib92i7cJsx73Sb9NcEm9TXCJsA1xSbDNcImwzXFJsM1wSbANcgm/dou3CbMMN0m/TXBJvQ1wyY1xibDNcMmwzXCJsU1wSbBNcYm/dsu3CbMMN0m/DXCJvQ1wibANcEmNcImxDXCJsQ1wSbFNcEmwjXEJv3cLsr+AADQ/gAAjcAlLswmzDDI/gCNAMD+ACcAwjDNJvw1wib0NcImwDXBJjXCJsM1wibFNcImxDXBJsM1wSb93i7K/gAAJ8EQLswmzDDHOMUwzSb8NcIm9DXCJsA1wSbANcImwTXDJsY1wSbENcEm/eYuygbBEC7MJswwxjjIMMsm/DXCJvQ1wibANcEmwDXCJjXEJsg1wCbENcEm/eYuygbBJS7MJswwxTjENsA4wTDLJvw1wib0NcImwDXBJsA1yCbINcEmxTXAJv3mLskQBsEuzSbMMMU4wzDA/gBRADjBMMsm/DXCJvQ1wibANcImNccmyzXAJv3uLsn+AAAQ/gAAAcEGwBAuyibMMMU4wTYwwTjCMMsm/DXCJvQ1wibBNcomzDXAJv3uLsklPMCgjAbCLskmzDDFOMSkRDjCMMsm+zXCJvU1wibCNccmzzUm/e4uySU8wCUGxC7HJswwxTjJMMsm6TXAJs41wib1NcImwzXFJv39wy7IBsElBsUuxybMMMU4yTDLJug1wCbPNcIm9TXDJv39zi7IPMEYLsEGwi7HJswwyDjB/gA1ADjCMMsm5jXBJs81wib2NcMm/f3OLsg8wSUGEP4AAFEGwi7HJswwzDjBCjDLJuU1wybONcIm9zXDJss1JjXAJv36Lsg8wQbGLscmzDDGNjjANjA2OME2MMsm5TXCJs41wyb3NcQmyTXCJv37LsgGJTwGxi7HJswwxgo4wAo2OMIwzCb5NcIm+TXFJsQ1xCb9/C7KEAbEEC7IJswwxj44wG44wzDMJvg1wib7Nc8m/f0u3CbMMMYKOMU2MMwm+DXCJvw1zSb9/cAu3CbMMMY2OMQ2MM0m9zXCJv3ANcsm/f3tMMc4wzYwzib3NcIm/cM1xib9/e8w3Sb2NcIm/f39/f3XNcMm/f397f6NjY3BJv3iNcMm/f397Tj+JycnwSb93zXFJv39/dU4/lFRUT7DJtA+wib93zXEJv39/dQ4PsYmzzg+wTQm/d81wyb9/f3UPsgmzz7COCb94DXAJv39/dU+xjgmyDg0wDgmwjg+wibCOD7GJv39/f3tPsQmyD7FJsI+wjgmwT7IJs84ND7CJsU4NMA4Jv39/f3LPsImyT7GJsE0PsImwj7IJsE4PsI4JsY+xCbEPsMmxTg0hIg0OCb9/f39PsEmyj7GJsE+wjgmwj7COMA0PsEmwTQ+yCbBPsQmxD7DJsQ+xSb9/f38PsI4JsI4wSbBPsEQOD7BJsE+wTQmwz7BOD7EJsEQPsgmwT7DJsU+wTQ4JsM+xib9/f38PsomwRA+xSbAOD7BOCbDPsgmwRA+yCbBPsUmwz7CJsQ+whA+wSb9/f38PsomwTg+xSbAND7CNMA4JsA+xzgmwRA+wBAmyT7FJsI+wibEPsI4Jv39/f3BOD7IOCbCPsUmwDQ+xSbAPsUmxBA+wBAmyz7DJsI+wzgmwj7DOCb9/f390j7COCbAOD7FJsE4NMA4JsY0PsA0Jsk+xSbCOD7DJsI4PsM4Jv39/f3bPsE0OCbNOD7AOCbJPsQ4JsE+xibBPsQ4Jv39/f39wD7EJsI+xibBPsQ4Jv39/f39yj7GJsE+wzgm/f39/f3LODT+KysrPsA4JsM+wSb9/f39/f39/f3aAAAAAAAAAAE="; +const char[*] TEST_QOI_DATA = b64"cW9pZgAAAVQAAACpBABV/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/cl/Jv39/f392jXBJv39/f392TXBJv39/f392TXBJv39/f392TXBJv39/f392TXBJv39/f392TXBJv39/f392DXBJv39/f392TXBJv39/f392TXBJv39/f392TXBJv39/f392TXBJu81Jv39zzXAJv390jXBJu01wyb9/cg1xib9/dA1wibsNcQm/f3GNcgm0zXAJv33NcEm6zXHJv39wzXIJtQ1xCb99DXBJus1wibANcEm/f3BNcgm1TXHJv3yNcEm6jXCJsE1wSb9/cA1xibZNSbANcQm/fE1wSbpNcImwjXBJv39NcUm4DXCJv3xNcEm6DXCJsM1wSb9/TXEJuI1wib98DXBJuc1wibENcEm/fw1wyblNcIm/e41wibmNcImxTXBJv37NcMm5zXBJv3uNcIm5jXCJsU1wSb9+jXEJuc1wib97TXCJuU1wibGNcEm/fk1xCboNcIm/e01wSbmNcImxjXBJv35NcMm6DXCJv3uNcEm5jXBJsc1wSb9+DXDJuk1wib97jXBJuU1wibGNcIm/fg1wyboNcIm/e81wSblNcEmxzXBJv34NcMm6TXCJv3vNcEm5TXBJsc1wSb9+DXCJuk1wib98DXBJuQ1wibHNcEm/fc1wyboNcMm/fA1wSbkNcEmxzXCJv33NcMm5jXEJv3xNcEm5DXBJsc1wSb9+DXCJuY1xSb98TXBJuM1wibGNcIm/fc1wybmNcQm/fI1wSbjNcEmxjXCJv34NcIm5zXGJv3wNcEm4zXBJsU1wyb9+DXCJug1xib97jXCJuI1wibENcMm/fk1wibrNcQm/e01wibiNcImwjXDJv37NcIm7DXEJv3sNcEm4zXBJsE1xCb9wDUm+TXCJu41wyb96zXBJuM1wSY1xSbKNcUm6jXDJvc1wibvNcMm/eo1wSbjNccmyzXIJuY1xSb3NcIm7zXEJv3pNcEm4jXGJsw1yibLNcUm0DXGJvc1wibwNcMm/ek1wSbiNcQmzTXLJsk1xybDNcImxjXHJvc1wibxNcIm/ek1wSbhNcMmzzXDJsA1xSbGNcomwjXDJsQ1ySb2NcIm8TXCJv3pNcEm4TXCJs81wibCNcUmxDXLJsI1xSbCNcQmNcIm9zXDJvA1wib96DXCJuI1wSbONcMmwzXEJsM1xibANcImwjXGJsA1xCY1wyb4NcIm7zXDJv3oNcIm4jXBJs41wibENcQmwTXGJsE1wybCNccmNcMmNcMm+TXCJtA1wibZNcIm/ek1wSbjNcEmzjXBJsU1wybANcYmwzXCJsI11Cb5NcMmzTXDJtk1wyb96TXBJuM1wSbNNcImxTXMJsM1wybCNcImwDXNJvs1wibMNcMm2TXDJv3qNcEm4zXBJs01wibFNcsmxDXDJsE1wybBNcsm/DXDJsk1xCbZNcQm/eo1wSbjNcEmzDXCJsc1yCbGNcImwjXCJsM1yCb9wDXEJsY1xCbaNcQm/es1wSbjNcEmyzXDJsY1xibJNcImwTXDJsQ1wib9xjXQJto1xCb97DXBJuM1wSbKNcQmxjXCJs01wibANcMmxTXCJv3HNc4m2jXEJv3tNcEm4zXBJsk1xibENcImzjXCJsA1wybENcMm/cg1yybbNcQm/e41wSbjNcImxzXCJjXCJsQ1wibNNcMmNcMmxTXDJv3JNcgm3DXEJv3vNcEm5DXBJsQ1xCbANcwmzTXIJsY1wyb98DXEJtg1wCb91DXBJuQ1wyY1xibCNcomzjXIJsc1wib96DXBJsE1xSbWNcAm/dc1wSblNckmxTXIJs81xybINcImzTXBJv3VNcMmNcUm1TXAJv3ZNcEm5jXHJsg1wibTNcYmyTXDJss1wSb91TXLJtQ1wCb92zXBJug1wSblNcYmyTXDJsk1wyb91TXJJtM1wCb93jXBJv3UNcQmzDXEJsU1xCb91TXJJtI1wCb94DXBJv3UNcMmzjXGJjXGJv3WNccm0jXAJv3iNcEm/dU1wSbPNc4m/dc1xibQNcAm/eU1wSb96zXLJv3YNcQm0DXAJv3nNcIm/ew1xyb92zXBJtA1wCb96jXBJv3uNcIm/fE1wCb97DXBJv39/eU1wCb9/f39/dc1wCb9/f39/dg1wCb9/f39/dg1wCbxNcUm/f39/dw1wCbxNcgm/f39/dk1wCbxNcom/f39/dc1wCbyNcQmwjXBJv39/f3VNcAm9DXCJsQ1wSb9/f390jXBJvY1wSbENcIm/f39/dA1wSb4NcAmxTXCJv39/f3ONcEm+zUmxTXCJs01wCb9/f35NcEm/cc1wibJNcUm1QDeJv39/DXCJv3JNcImyDXGJtUA3ib9/fo1wSb9zDXCJsU1yCbWAN4m/f33NcIm/c41wibDNckm1wDeJsdv4Cb9/co1wib9zzXCJsE1ySbaAN4mxzLgJv39yDXCJv3RNc4m3ADeJscy4Cb9/cY1wib9xTXBJsk1zCbeAN4mxzLgJv39xDXCJv3ENcYmxjXKJuEAyP8AAAC7/wAAAOr/AAAA9g4JAAn/AAAA+sAJAMomxzLJ/icAAMIy0Sb9/cI1wib9xTXIJsU1xybkAMc+yP8AAAD5AMomxzLI/o0AACrDMtAm/f3BNcEm/cY1ySbFNcUm5gDGPsoAyibHMsj+UQAAKsgyyyb9/TXBJv3INcImwDXDJsU1wyboAMY+whI+xQDKJscyyCrJMssm/fs1wSb9yjXBJsE1xCbENcEm6gDGPsIADj7DDgDKJscyyCrJMssm/fg1wib9zDXBJsE1xCbzAMUJPsEJPsUAyybHMsgqwSgqwP41AADAKBwyzCb99jXCJv3ONcImwDXEJsM1Ju0AxQ4+yQDLJscyyCrBMtMm/fQ1wib90DXCJsA1xSY1wibtAMUOPsgzCQDKJscyyCrBMtMm/fI1wib9yDXEJsI1wiY1yibuAMUJPsQJEj7DAMkmxzLIKsEy0yb98DXCJuY1wibcNcUmwTXOJu8AzQ4+wwDJJscyyCrBMtMm/e41wibpNcEm2zXHJsE1xSY1xSbvAM0JPsMAySbHMsgqwTLTJv3sNcIm6zXCJto1wSbANcMmwTXEJjXEJvAA3ibHMsgqwTLTJv3qNcIm7jXCJtA1JsE1JsA1wibCNcImwjXBJsI1wibxAN4mxzLIKsEy0yb96DXCJvA1wybONcomwzXCJv3BAN4mxzLIHMEy0yb95jXCJvM1wibPNckmwzXCJv3BAN4mxzLgJvs1wSbiNcIm9jXCJs81yCbDNcIm/cEA3ibHMuAm+zXCJt81wibxNSbENcImxTXDJsI1xCbANcImwjXCJv3qMuAm/DXCJtw1wibxNcEmxTXBJsQ1xSbBNcMmwjXBJsM1wSb96jLgJvw1wibcNcIm8DXCJsU1wibCNccmwTXCJsI1wSbENSb9/f3RNcEm3DXDJu81wSbFNcImwjXCJsA1wSbCNcEmwjXCJv39/dc1wibfNcAm7jXBJsY1wSbCNcEmwTXCJsE1wSbBNcMm/f392DXBJv3TNcImxTXBJsI1wSbCNcEmwDXCJsI1wib9/f3YNcEm/dM1wibFNcImwTXBJsE1wSY1xCbCNcIm/f392DXCJv3TNcEmxTXCJsE1wSY1wyY1xCbDNcAm/f39wjUm1TXBJv01wCbQNcEmxDXDJsE1xibANcEmNcAm/f39yDXDJtI1wSb4NckmzDXCJsE1xSbBNcUmwDXBJv39/cw1xCbRNcIm9jXPJsg1wSbANccmwDXDJsE1wib9/f3lNcIm9TXTJsU1xyY1wibANcEmwzXBJv39/eY1wib1NcUmNcsmxTXGJsA1wibANcImwTXCJv3Zftwm/es1wib1NcImwTXNJsM1xibCNcEmwDXCJsA1wib92i7cJsx73Sb9NcEm9TXCJsA1xSbDNcImwzXFJsM1wSbANcgm/dou3CbMMN0m/TXBJvQ1wyY1xibDNcMmwzXCJsU1wSbBNcYm/dsu3CbMMN0m/DXCJvQ1wibANcEmNcImxDXCJsQ1wSbFNcEmwjXEJv3cLsr+AADQ/gAAjcAlLswmzDDI/gCNAMD+ACcAwjDNJvw1wib0NcImwDXBJjXCJsM1wibFNcImxDXBJsM1wSb93i7K/gAAJ8EQLswmzDDHOMUwzSb8NcIm9DXCJsA1wSbANcImwTXDJsY1wSbENcEm/eYuygbBEC7MJswwxjjIMMsm/DXCJvQ1wibANcEmwDXCJjXEJsg1wCbENcEm/eYuygbBJS7MJswwxTjENsA4wTDLJvw1wib0NcImwDXBJsA1yCbINcEmxTXAJv3mLskQBsEuzSbMMMU4wzDA/gBRADjBMMsm/DXCJvQ1wibANcImNccmyzXAJv3uLsn+AAAQ/gAAAcEGwBAuyibMMMU4wTYwwTjCMMsm/DXCJvQ1wibBNcomzDXAJv3uLsklPMCgjAbCLskmzDDFOMSkRDjCMMsm+zXCJvU1wibCNccmzzUm/e4uySU8wCUGxC7HJswwxTjJMMsm6TXAJs41wib1NcImwzXFJv39wy7IBsElBsUuxybMMMU4yTDLJug1wCbPNcIm9TXDJv39zi7IPMEYLsEGwi7HJswwyDjB/gA1ADjCMMsm5jXBJs81wib2NcMm/f3OLsg8wSUGEP4AAFEGwi7HJswwzDjBCjDLJuU1wybONcIm9zXDJss1JjXAJv36Lsg8wQbGLscmzDDGNjjANjA2OME2MMsm5TXCJs41wyb3NcQmyTXCJv37LsgGJTwGxi7HJswwxgo4wAo2OMIwzCb5NcIm+TXFJsQ1xCb9/C7KEAbEEC7IJswwxj44wG44wzDMJvg1wib7Nc8m/f0u3CbMMMYKOMU2MMwm+DXCJvw1zSb9/cAu3CbMMMY2OMQ2MM0m9zXCJv3ANcsm/f3tMMc4wzYwzib3NcIm/cM1xib9/e8w3Sb2NcIm/f39/f3XNcMm/f397f6NjY3BJv3iNcMm/f397Tj+JycnwSb93zXFJv39/dU4/lFRUT7DJtA+wib93zXEJv39/dQ4PsYmzzg+wTQm/d81wyb9/f3UPsgmzz7COCb94DXAJv39/dU+xjgmyDg0wDgmwjg+wibCOD7GJv39/f3tPsQmyD7FJsI+wjgmwT7IJs84ND7CJsU4NMA4Jv39/f3LPsImyT7GJsE0PsImwj7IJsE4PsI4JsY+xCbEPsMmxTg0hIg0OCb9/f39PsEmyj7GJsE+wjgmwj7COMA0PsEmwTQ+yCbBPsQmxD7DJsQ+xSb9/f38PsI4JsI4wSbBPsEQOD7BJsE+wTQmwz7BOD7EJsEQPsgmwT7DJsU+wTQ4JsM+xib9/f38PsomwRA+xSbAOD7BOCbDPsgmwRA+yCbBPsUmwz7CJsQ+whA+wSb9/f38PsomwTg+xSbAND7CNMA4JsA+xzgmwRA+wBAmyT7FJsI+wibEPsI4Jv39/f3BOD7IOCbCPsUmwDQ+xSbAPsUmxBA+wBAmyz7DJsI+wzgmwj7DOCb9/f390j7COCbAOD7FJsE4NMA4JsY0PsA0Jsk+xSbCOD7DJsI4PsM4Jv39/f3bPsE0OCbNOD7AOCbJPsQ4JsE+xibBPsQ4Jv39/f39wD7EJsI+xibBPsQ4Jv39/f39yj7GJsE+wzgm/f39/f3LODT+KysrPsA4JsM+wSb9/f39/f39/f3aAAAAAAAAAAE="; fn void test_qoi_all() diff --git a/test/unit/stdlib/conv_tests.c3 b/test/unit/stdlib/conv_tests.c3 index e422c4f6d..2bc8e9893 100644 --- a/test/unit/stdlib/conv_tests.c3 +++ b/test/unit/stdlib/conv_tests.c3 @@ -1,7 +1,7 @@ module conv_tests; import std::io; -fn void! comparison_helper_32_to_8(Char32 c32, String expected_output) +fn void? comparison_helper_32_to_8(Char32 c32, String expected_output) { char[8] out; usz len = conv::char32_to_utf8(c32, &out)!; @@ -12,7 +12,7 @@ fn void! comparison_helper_32_to_8(Char32 c32, String expected_output) } } -fn void! comparison_helper_8_to_32(String in, Char32 c32) +fn void? comparison_helper_8_to_32(String in, Char32 c32) { usz len = in.len; Char32 res = conv::utf8_to_char32(in.ptr, &len)!; diff --git a/test/unit/stdlib/core/array.c3 b/test/unit/stdlib/core/array.c3 index 2342209e0..75cf37053 100644 --- a/test/unit/stdlib/core/array.c3 +++ b/test/unit/stdlib/core/array.c3 @@ -6,7 +6,7 @@ fn void find() assert(array::index_of(a, 2)!! == 1); assert(array::index_of(a, 1)!! == 0); assert(array::index_of(a, 3)!! == 2); - assert(@catch(array::index_of(a, 4)) == SearchResult.MISSING); + assert(@catch(array::index_of(a, 4)) == NOT_FOUND); } fn void find_subarray() @@ -15,7 +15,7 @@ fn void find_subarray() assert(array::index_of(a, 2)!! == 1); assert(array::index_of(a, 1)!! == 0); assert(array::index_of(a, 3)!! == 2); - assert(@catch(array::index_of(a, 4)) == SearchResult.MISSING); + assert(@catch(array::index_of(a, 4)) == NOT_FOUND); } fn void concat() diff --git a/test/unit/stdlib/core/bitorder.c3 b/test/unit/stdlib/core/bitorder.c3 index 85fb9228b..e6eb805a1 100644 --- a/test/unit/stdlib/core/bitorder.c3 +++ b/test/unit/stdlib/core/bitorder.c3 @@ -2,7 +2,7 @@ module std::core::bitorder @test; fn void test_read() { - char[?] bytes = { 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08 }; + char[*] bytes = { 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08 }; assert(bitorder::read(bytes, UShortBE) == 0x0102); assert(bitorder::read(bytes, UShortLE) == 0x0201); @@ -28,7 +28,7 @@ fn void test_read() fn void test_write() { - char[?] bytes = { 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08 }; + char[*] bytes = { 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08 }; char[8] buf; ushort x1 = bitorder::read(bytes, UShortBE); diff --git a/test/unit/stdlib/core/builtintests.c3 b/test/unit/stdlib/core/builtintests.c3 index 17f1847f2..24e553be3 100644 --- a/test/unit/stdlib/core/builtintests.c3 +++ b/test/unit/stdlib/core/builtintests.c3 @@ -5,7 +5,7 @@ fn void test_anycast() int a; any b = &a; assert(anycast(b, int)!! == &a); - assert(@catch(anycast(b, double)) == CastResult.TYPE_MISMATCH); + assert(@catch(anycast(b, double)) == TYPE_MISMATCH); } fn void test_bitcast() @@ -25,7 +25,7 @@ fn void test_enum_by_name() { assert(enum_by_name(Tester, "ABC")!! == Tester.ABC); assert(enum_by_name(Tester, "DEF")!! == Tester.DEF); - assert(@catch(enum_by_name(Tester, "GHI")) == SearchResult.MISSING); + assert(@catch(enum_by_name(Tester, "GHI")) == NOT_FOUND); } fn void test_likely() diff --git a/test/unit/stdlib/core/formatter.c3 b/test/unit/stdlib/core/formatter.c3 index 6fd743c2e..edd4b66fd 100644 --- a/test/unit/stdlib/core/formatter.c3 +++ b/test/unit/stdlib/core/formatter.c3 @@ -3,7 +3,7 @@ module std::core::formatter_test; import std; struct Foo (Printable) { int a; } -fn usz! Foo.to_format(&self, Formatter *f) @dynamic +fn usz? Foo.to_format(&self, Formatter *f) @dynamic { return f.printf("Foo[%d]", self.a); } diff --git a/test/unit/stdlib/core/string.c3 b/test/unit/stdlib/core/string.c3 index 64795551d..87aba576a 100644 --- a/test/unit/stdlib/core/string.c3 +++ b/test/unit/stdlib/core/string.c3 @@ -155,7 +155,7 @@ fn void test_split_to_buffer() assert(strings[3] == "c"); assert(strings[4] == ""); String[4] c; - assert(@catch(test.split_to_buffer("|", &c)) == SplitResult.BUFFER_EXCEEDED); + assert(@catch(test.split_to_buffer("|", &c)) == string::BUFFER_EXCEEDED); strings = test.split(mem, "|", 2); assert(strings.len == 2); assert(strings[0] == "abc"); diff --git a/test/unit/stdlib/core/test_test.c3 b/test/unit/stdlib/core/test_test.c3 index afb584fe1..b0ce71052 100644 --- a/test/unit/stdlib/core/test_test.c3 +++ b/test/unit/stdlib/core/test_test.c3 @@ -270,52 +270,49 @@ fn void test_check_fails_no_info() test::@check(2 == 1); } -def TestIntFn = fn int! (int a, int b); -def TestFailFn = fn void! (bool to_fail); +def TestIntFn = fn int? (int a, int b); +def TestFailFn = fn void? (bool to_fail); -fault MyFault -{ - FOO, -} +fault FOO; fn void test_error() { - TestFailFn ffail_void = fn void!(bool to_fail) + TestFailFn ffail_void = fn void?(bool to_fail) { - if (to_fail) return IoError.FILE_NOT_FOUND?; + if (to_fail) return io::FILE_NOT_FOUND?; }; - TestIntFn ffail_int = fn int! (int a, int b) + TestIntFn ffail_int = fn int?(int a, int b) { - if (b == 0) return IoError.FILE_NOT_FOUND?; + if (b == 0) return io::FILE_NOT_FOUND?; return a / b; }; test::@setup(state.setup_fn, state.teardown_fn); - test::@error(ffail_void(true), IoError.FILE_NOT_FOUND); - test::@error(ffail_int(1, 0), IoError.FILE_NOT_FOUND); + test::@error(ffail_void(true), io::FILE_NOT_FOUND); + test::@error(ffail_int(1, 0), io::FILE_NOT_FOUND); } fn void test_error_not_raised() { - TestIntFn ffail_int = fn int! (int a, int b) { - if (b == 0) return IoError.FILE_NOT_FOUND?; + TestIntFn ffail_int = fn int?(int a, int b) { + if (b == 0) return io::FILE_NOT_FOUND?; return a / b; }; test::@setup(state.setup_fn, state.teardown_fn); state.expected_fail = true; - test::@error(ffail_int(1, 1), IoError.FILE_NOT_FOUND); + test::@error(ffail_int(1, 1), io::FILE_NOT_FOUND); } fn void test_error_wrong_error_expected() { - TestIntFn ffail_int = fn int! (int a, int b) { - if (b == 0) return IoError.BUSY?; + TestIntFn ffail_int = fn int?(int a, int b) { + if (b == 0) return io::BUSY?; return a / b; }; test::@setup(state.setup_fn, state.teardown_fn); state.expected_fail = true; - test::@error(ffail_int(1, 0), IoError.FILE_NOT_FOUND); + test::@error(ffail_int(1, 0), io::FILE_NOT_FOUND); } fn void test_std_out_hijack() diff --git a/test/unit/stdlib/crypto/rc4.c3 b/test/unit/stdlib/crypto/rc4.c3 index 5615f2bb8..1e8e96563 100644 --- a/test/unit/stdlib/crypto/rc4.c3 +++ b/test/unit/stdlib/crypto/rc4.c3 @@ -8,7 +8,7 @@ fn void rc_crypt() @test char[200] x; String text = "The quick brown fox jumps over the lazy dog."; rc.crypt(text, &x); - char[?] res = x'2ac2fecdd8fbb84638e3a4 + char[*] res = x'2ac2fecdd8fbb84638e3a4 820eb205cc8e29c28b9d5d 6b2ef974f311964971c90e 8b9ca16467ef2dc6fc3520'; diff --git a/test/unit/stdlib/encoding/base32.c3 b/test/unit/stdlib/encoding/base32.c3 index f850231a7..3ac927f9a 100644 --- a/test/unit/stdlib/encoding/base32.c3 +++ b/test/unit/stdlib/encoding/base32.c3 @@ -9,7 +9,7 @@ struct TestCase char[] enc; } -TestCase[?] std_tests = { +TestCase[*] std_tests = { { "", "" }, { "f", "MY======" }, { "fo", "MZXQ====" }, @@ -19,7 +19,7 @@ TestCase[?] std_tests = { { "foobar", "MZXW6YTBOI======" }, }; -TestCase[?] hex_tests = { +TestCase[*] hex_tests = { { "", "" }, { "f", "CO======" }, { "fo", "CPNG====" }, @@ -38,7 +38,7 @@ macro encode_tests(tests, alphabet, padding) base32::encode_buffer(t.dec, buf[:n], padding, alphabet); char[] want = t.enc; - usz! pad_idx = array::index_of(want, '='); + usz? pad_idx = array::index_of(want, '='); if (try pad_idx && !padding) { want = want[:pad_idx]; @@ -66,7 +66,7 @@ macro decode_tests(tests, alphabet, padding) foreach (t : tests) { char[] input = t.enc[..]; - usz! pad_idx = array::index_of(input, '='); + usz? pad_idx = array::index_of(input, '='); if (try pad_idx && !padding) { input = input[:pad_idx]; diff --git a/test/unit/stdlib/io/bytestream.c3 b/test/unit/stdlib/io/bytestream.c3 index d88f9db4d..ba981ca3e 100644 --- a/test/unit/stdlib/io/bytestream.c3 +++ b/test/unit/stdlib/io/bytestream.c3 @@ -59,7 +59,7 @@ struct TestReader (InStream) usz index; } -fn usz! TestReader.read(&self, char[] bytes) @dynamic +fn usz? TestReader.read(&self, char[] bytes) @dynamic { usz left = self.bytes.len - self.index; if (left == 0) return 0; @@ -69,4 +69,4 @@ fn usz! TestReader.read(&self, char[] bytes) @dynamic return n; } -fn char! TestReader.read_byte(&self) @dynamic => io::read_byte_using_read(self); +fn char? TestReader.read_byte(&self) @dynamic => io::read_byte_using_read(self); diff --git a/test/unit/stdlib/io/scanner.c3 b/test/unit/stdlib/io/scanner.c3 index 2d4202fd8..040113649 100644 --- a/test/unit/stdlib/io/scanner.c3 +++ b/test/unit/stdlib/io/scanner.c3 @@ -30,10 +30,10 @@ fn void scanner() defer results.free(); while (true) { - char[]! res = sc.scan(",,"); + char[]? res = sc.scan(",,"); if (catch err = res) { - if (err == SearchResult.MISSING) break; + if (err == NOT_FOUND) break; return err?!!; } String str = (String)res; diff --git a/test/unit/stdlib/net/url.c3 b/test/unit/stdlib/net/url.c3 index d35d43e5f..18c1a4f95 100644 --- a/test/unit/stdlib/net/url.c3 +++ b/test/unit/stdlib/net/url.c3 @@ -172,7 +172,7 @@ fn void test_parse_urn2() fn void test_parse_empty() { - assert(@catch(url::parse(mem, " ")) == UrlParsingResult.EMPTY); + assert(@catch(url::parse(mem, " ")) == url::EMPTY); } // Parser tests with escape sequences diff --git a/test/unit/stdlib/net/url_encoding.c3 b/test/unit/stdlib/net/url_encoding.c3 index 782c82383..78404d663 100644 --- a/test/unit/stdlib/net/url_encoding.c3 +++ b/test/unit/stdlib/net/url_encoding.c3 @@ -11,18 +11,18 @@ struct EncodeTest UrlEncodingMode mode; } -EncodeTest[?] decode_with_error_tests @local = { +EncodeTest[*] decode_with_error_tests @local = { { "", "", {}, QUERY, }, { "abc", "abc", {}, QUERY, }, { "1%41", "1A", {}, QUERY, }, { "1%41%42%43", "1ABC", {}, QUERY, }, { "%4a", "J", {}, QUERY, }, { "%6F", "o", {}, QUERY, }, - { "%", "", UrlDecodingError.INVALID_HEX, QUERY, }, - { "%a", "", UrlDecodingError.INVALID_HEX, QUERY, }, - { "%1", "", UrlDecodingError.INVALID_HEX, QUERY, }, - { "123%45%6", "", UrlDecodingError.INVALID_HEX, QUERY, }, - { "%zzzzz", "", UrlDecodingError.INVALID_HEX, QUERY, }, + { "%", "", url::INVALID_HEX, QUERY, }, + { "%a", "", url::INVALID_HEX, QUERY, }, + { "%1", "", url::INVALID_HEX, QUERY, }, + { "123%45%6", "", url::INVALID_HEX, QUERY, }, + { "%zzzzz", "", url::INVALID_HEX, QUERY, }, { "a+b", "a b", {}, QUERY, }, { "a%20b", "a b", {}, QUERY, }, }; @@ -31,7 +31,7 @@ fn void test_decoding_with_error() => @pool() { foreach (test: decode_with_error_tests) { - String! actual = url::tdecode(test.in, test.mode); + String? actual = url::tdecode(test.in, test.mode); if (catch excuse = actual) { assert(excuse == test.err, "unescape(%s, %s); " @@ -43,7 +43,7 @@ fn void test_decoding_with_error() => @pool() } } -EncodeTest[?] encode_tests @local = { +EncodeTest[*] encode_tests @local = { { "", "", {}, PATH, }, { "abc", "abc", {}, PATH, }, { "abc+def", "abc+def", {}, PATH, }, @@ -81,7 +81,7 @@ struct ShouldEncodeTest bool escape; } -ShouldEncodeTest[?] should_encode_tests = { +ShouldEncodeTest[*] should_encode_tests = { {'a', PATH, false}, {'a', USERPASS, false}, {'a', QUERY, false}, diff --git a/test/unit/stdlib/sort/insertionsort.c3 b/test/unit/stdlib/sort/insertionsort.c3 index 57dfe9d0d..09b840160 100644 --- a/test/unit/stdlib/sort/insertionsort.c3 +++ b/test/unit/stdlib/sort/insertionsort.c3 @@ -56,7 +56,7 @@ fn void insertionsort_with_value() fn void insertionsort_with_array() { - int[?] a = { 4, 8, 100, 1, 2 }; + int[*] a = { 4, 8, 100, 1, 2 }; sort::insertionsort(&a); assert(a == { 1, 2, 4, 8, 100 }); } diff --git a/test/unit/stdlib/sort/quicksort.c3 b/test/unit/stdlib/sort/quicksort.c3 index 8cecec30e..a9135c7f6 100644 --- a/test/unit/stdlib/sort/quicksort.c3 +++ b/test/unit/stdlib/sort/quicksort.c3 @@ -39,7 +39,7 @@ fn void quicksort_with_ref() fn void quicksort_with_array() { - int[?] a = { 4, 8, 100, 1, 2 }; + int[*] a = { 4, 8, 100, 1, 2 }; sort::quicksort(&a); assert(a == { 1, 2, 4, 8, 100 }); } diff --git a/test/unit/stdlib/string_to_float.c3 b/test/unit/stdlib/string_to_float.c3 index bf650a844..0631f4340 100644 --- a/test/unit/stdlib/string_to_float.c3 +++ b/test/unit/stdlib/string_to_float.c3 @@ -12,8 +12,8 @@ fn void test_float() @test assert(String.to_float("-23.545")!! == -23.545f); assert(String.to_float("1.5555555555555")!! == 1.5555555555555f); assert(String.to_float("1.5555555555556666")!! == 1.5555555555556666f); - test::@error("+".to_float(), NumberConversion.MALFORMED_FLOAT); - test::@error("-".to_float(), NumberConversion.MALFORMED_FLOAT); + test::@error("+".to_float(), string::MALFORMED_FLOAT); + test::@error("-".to_float(), string::MALFORMED_FLOAT); } fn void test_double() @test @@ -28,6 +28,6 @@ fn void test_double() @test assert(String.to_double("-23.545")!! == -23.545); assert(String.to_double("1.5555555555555")!! == 1.5555555555555); assert(String.to_double("1.5555555555556666")!! == 1.5555555555556666); - test::@error("+".to_double(), NumberConversion.MALFORMED_FLOAT); - test::@error("-".to_double(), NumberConversion.MALFORMED_FLOAT); + test::@error("+".to_double(), string::MALFORMED_FLOAT); + test::@error("-".to_double(), string::MALFORMED_FLOAT); } diff --git a/test/unit/stdlib/threads/channel.c3 b/test/unit/stdlib/threads/channel.c3 index bf7f8876c..38b6edb2d 100644 --- a/test/unit/stdlib/threads/channel.c3 +++ b/test/unit/stdlib/threads/channel.c3 @@ -78,7 +78,7 @@ fn void sending_to_closed_unbuffered_chan_is_forbidden() @test if (catch err = c.push(123)) { - assert(err == ThreadFault.CHANNEL_CLOSED); + assert(err == thread::CHANNEL_CLOSED); return; } assert(false); @@ -94,7 +94,7 @@ fn void sending_to_closed_buffered_chan_is_forbidden() @test if (catch err = c.push(123)) { - assert(err == ThreadFault.CHANNEL_CLOSED); + assert(err == thread::CHANNEL_CLOSED); return; } assert(false); @@ -110,7 +110,7 @@ fn void reading_from_empty_closed_unbuffered_chan_is_forbidden() @test if (catch err = c.pop()) { - assert(err == ThreadFault.CHANNEL_CLOSED); + assert(err == thread::CHANNEL_CLOSED); return; } assert(false); @@ -126,7 +126,7 @@ fn void reading_from_empty_closed_buffered_chan_is_forbidden() @test if (catch err = c.pop()) { - assert(err == ThreadFault.CHANNEL_CLOSED); + assert(err == thread::CHANNEL_CLOSED); return; } assert(false); @@ -151,10 +151,10 @@ fn void reading_from_non_empty_closed_buffered_chan_is_ok() @test got = c.pop()!!; assert(got == 3); - int! got_err = c.pop(); + int? got_err = c.pop(); if (catch err = got_err) { - assert(err == ThreadFault.CHANNEL_CLOSED); + assert(err == thread::CHANNEL_CLOSED); return; } @@ -177,10 +177,10 @@ fn void reading_from_empty_buffered_chan_aborted_by_close() @test return 0; }, (void*)c)!!; - int! res = c.pop(); + int? res = c.pop(); if (catch err = res) { - assert(err == ThreadFault.CHANNEL_CLOSED); + assert(err == thread::CHANNEL_CLOSED); return; } @@ -203,10 +203,10 @@ fn void reading_from_unbuffered_chan_aborted_by_close() @test return 0; }, (void*)c)!!; - int! res = c.pop(); + int? res = c.pop(); if (catch err = res) { - assert(err == ThreadFault.CHANNEL_CLOSED); + assert(err == thread::CHANNEL_CLOSED); return; } @@ -234,7 +234,7 @@ fn void sending_to_full_buffered_chan_aborted_by_close() @test anyfault err = @catch(c.push(1)); if (err) { - assert(err == ThreadFault.CHANNEL_CLOSED); + assert(err == thread::CHANNEL_CLOSED); return; } @@ -260,7 +260,7 @@ fn void sending_to_unbuffered_chan_aborted_by_close() @test anyfault err = @catch(c.push(1)); if (err) { - assert(err == ThreadFault.CHANNEL_CLOSED); + assert(err == thread::CHANNEL_CLOSED); return; } @@ -290,7 +290,7 @@ fn void multiple_actions_unbuffered() @test for (int i = 0; i <= 100; i++) { - int! res = c.pop(); + int? res = c.pop(); if (catch err = res) { assert(false); @@ -324,7 +324,7 @@ fn void multiple_actions_buffered() @test for (int i = 0; i <= 100; i++) { - int! res = c.pop(); + int? res = c.pop(); if (catch err = res) { assert(false); diff --git a/test/unit/stdlib/threads/mutex.c3 b/test/unit/stdlib/threads/mutex.c3 index 8e47b32ea..befe55872 100644 --- a/test/unit/stdlib/threads/mutex.c3 +++ b/test/unit/stdlib/threads/mutex.c3 @@ -30,7 +30,7 @@ fn void lock_with_double_unlock_test() @test assert(@catch(m.unlock())); } -fn void! own_mutex(Mutex* m) +fn void? own_mutex(Mutex* m) { m.lock()!; m.unlock()!; diff --git a/test/unit/stdlib/time/format.c3 b/test/unit/stdlib/time/format.c3 index 81f0b0357..236b94a4f 100644 --- a/test/unit/stdlib/time/format.c3 +++ b/test/unit/stdlib/time/format.c3 @@ -7,7 +7,7 @@ def FormatTestSpec = Triple{DateTime, DateTimeFormat, String}; fn void test_with_tz() { - FormatTzTestSpec[?] tests = { + FormatTzTestSpec[*] tests = { { datetime::from_date(1970, Month.JANUARY, 1, 0, 0, 0).with_gmt_offset(0), RFC1123, "Thu, 01 Jan 1970 00:00:00 GMT" }, { datetime::from_date(1994, Month.from_ordinal(10), 6, 8, 49, 37).with_gmt_offset(0), RFC1123, "Sun, 06 Nov 1994 08:49:37 GMT" }, { datetime::from_date(2020, Month.JANUARY, 1, 0, 0, 0).with_gmt_offset(0), RFC1123, "Wed, 01 Jan 2020 00:00:00 GMT" }, @@ -35,7 +35,7 @@ fn void test_with_tz() fn void test_without_tz() { - FormatTestSpec[?] tests = { + FormatTestSpec[*] tests = { { datetime::from_date(2006, Month.JANUARY, 2, 15, 4, 05), ANSIC, "Mon Jan 2 15:04:05 2006" }, { datetime::from_date(2006, Month.JANUARY, 2, 15, 4, 05), DATETIME, "2006-01-02 15:04:05" }, { datetime::from_date(2006, Month.JANUARY, 2, 15, 4, 05), DATEONLY, "2006-01-02" },