diff --git a/include/cpp2util.h b/include/cpp2util.h index ca7e7999e1..e4bb0a9c35 100644 --- a/include/cpp2util.h +++ b/include/cpp2util.h @@ -199,6 +199,9 @@ #include #include #include + #include + #include + #include #if defined(CPP2_USE_SOURCE_LOCATION) #include @@ -297,7 +300,6 @@ constexpr auto contract_group::set_handler(handler h) -> handler { return old; } - // Null pointer deref checking // auto assert_not_null(auto&& p CPP2_SOURCE_LOCATION_PARAM_WITH_DEFAULT) -> auto&& @@ -326,7 +328,6 @@ auto assert_in_bounds(auto&& x, auto&& arg CPP2_SOURCE_LOCATION_PARAM_WITH_DEFAU return std::forward(x) [ std::forward(arg) ]; } - //----------------------------------------------------------------------- // // Arena objects for std::allocators @@ -825,6 +826,41 @@ inline auto to_string(std::tuple const& t) -> std::string } } +// Helper to convert the arguments of main to safer type. +inline auto convert_main_args(int argc, char** argv) -> std::vector +{ + std::vector args; + for (int i = 0; i < argc; ++i) { + args.push_back(argv[i]); + } + args.shrink_to_fit(); + return args; +} + +#define CPP2_MAIN_VOID_NO_ARGS \ + int main() { \ + cpp2__main(); \ + return 0; \ + } + +#define CPP2_MAIN_INT_NO_ARGS \ + int main() { \ + return cpp2__main(); \ + } + +#define CPP2_MAIN_VOID_ARGS \ + int main(int argc, char** argv) { \ + auto args = cpp2::convert_main_args(argc, argv); \ + cpp2__main(std::span{args}); \ + return 0; \ + } + +#define CPP2_MAIN_INT_ARGS \ + int main(int argc, char** argv) { \ + auto args = cpp2::convert_main_args(argc, argv); \ + return cpp2__main(std::span{args}); \ + } + //----------------------------------------------------------------------- // @@ -881,7 +917,6 @@ inline auto fopen( const char* filename, const char* mode ) { } - using cpp2::cpp2_new; diff --git a/regression-tests/mixed-bounds-check.cpp2 b/regression-tests/mixed-bounds-check.cpp2 index 768d0cf237..47fcef0972 100644 --- a/regression-tests/mixed-bounds-check.cpp2 +++ b/regression-tests/mixed-bounds-check.cpp2 @@ -1,7 +1,7 @@ #include -main: () -> int = { +main: () = { v : std::vector = (1, 2, 3, 4, 5); std::cout << v[5] << "\n"; } diff --git a/regression-tests/mixed-bounds-safety-with-assert-2.cpp2 b/regression-tests/mixed-bounds-safety-with-assert-2.cpp2 index aa3994493b..db3c7c6fe6 100644 --- a/regression-tests/mixed-bounds-safety-with-assert-2.cpp2 +++ b/regression-tests/mixed-bounds-safety-with-assert-2.cpp2 @@ -1,5 +1,5 @@ -main: () -> int = { +main: () = { v: std::vector = (1, 2, 3, 4, 5); add_42_to_subrange(v, 1, 3); diff --git a/regression-tests/mixed-bounds-safety-with-assert.cpp2 b/regression-tests/mixed-bounds-safety-with-assert.cpp2 index 1349c52e25..c18509206f 100644 --- a/regression-tests/mixed-bounds-safety-with-assert.cpp2 +++ b/regression-tests/mixed-bounds-safety-with-assert.cpp2 @@ -1,5 +1,5 @@ -main: () -> int = { +main: () = { v: std::vector = (1, 2, 3, 4, 5); print_subrange(v, 1, 13); } diff --git a/regression-tests/mixed-captures-in-expressions-and-postconditions.cpp2 b/regression-tests/mixed-captures-in-expressions-and-postconditions.cpp2 index 1641462471..7b4e4f5892 100644 --- a/regression-tests/mixed-captures-in-expressions-and-postconditions.cpp2 +++ b/regression-tests/mixed-captures-in-expressions-and-postconditions.cpp2 @@ -2,7 +2,7 @@ #include #include -main: () -> int = { +main: () = { vec: std::vector = ("hello", "2022"); diff --git a/regression-tests/mixed-function-expression-and-std-for-each.cpp2 b/regression-tests/mixed-function-expression-and-std-for-each.cpp2 index 18e19b1cd7..c62665438b 100644 --- a/regression-tests/mixed-function-expression-and-std-for-each.cpp2 +++ b/regression-tests/mixed-function-expression-and-std-for-each.cpp2 @@ -4,7 +4,7 @@ #include #include -main: () -> int = { +main: () = { vec: std::vector = ("hello", "2022"); view: std::span = vec; diff --git a/regression-tests/mixed-function-expression-and-std-ranges-for-each-with-capture.cpp2 b/regression-tests/mixed-function-expression-and-std-ranges-for-each-with-capture.cpp2 index b867e8d5cb..9b13e67d2e 100644 --- a/regression-tests/mixed-function-expression-and-std-ranges-for-each-with-capture.cpp2 +++ b/regression-tests/mixed-function-expression-and-std-ranges-for-each-with-capture.cpp2 @@ -5,7 +5,7 @@ #include #include -main: () -> int = { +main: () = { vec: std::vector = ("hello", "2022"); view: std::span = vec; diff --git a/regression-tests/mixed-function-expression-and-std-ranges-for-each.cpp2 b/regression-tests/mixed-function-expression-and-std-ranges-for-each.cpp2 index 1ac5d34fce..f6432492ad 100644 --- a/regression-tests/mixed-function-expression-and-std-ranges-for-each.cpp2 +++ b/regression-tests/mixed-function-expression-and-std-ranges-for-each.cpp2 @@ -5,7 +5,7 @@ #include #include -main: () -> int = { +main: () = { vec: std::vector = ("hello", "2022"); view: std::span = vec; diff --git a/regression-tests/mixed-function-expression-with-pointer-capture.cpp2 b/regression-tests/mixed-function-expression-with-pointer-capture.cpp2 index 17ddb2b431..910da95599 100644 --- a/regression-tests/mixed-function-expression-with-pointer-capture.cpp2 +++ b/regression-tests/mixed-function-expression-with-pointer-capture.cpp2 @@ -5,7 +5,7 @@ #include #include -main: () -> int = { +main: () = { vec: std::vector = ("hello", "2023"); view: std::span = vec; diff --git a/regression-tests/mixed-function-expression-with-repeated-capture.cpp2 b/regression-tests/mixed-function-expression-with-repeated-capture.cpp2 index e1d113ea57..8a5cf2f2fa 100644 --- a/regression-tests/mixed-function-expression-with-repeated-capture.cpp2 +++ b/regression-tests/mixed-function-expression-with-repeated-capture.cpp2 @@ -5,7 +5,7 @@ #include #include -main: () -> int = { +main: () = { vec: std::vector = ("hello", "2022"); view: std::span = vec; diff --git a/regression-tests/mixed-initialization-safety-1.cpp2 b/regression-tests/mixed-initialization-safety-1.cpp2 index 9f2411969c..429833bdb2 100644 --- a/regression-tests/mixed-initialization-safety-1.cpp2 +++ b/regression-tests/mixed-initialization-safety-1.cpp2 @@ -16,7 +16,7 @@ fill: ( x = value.substr(0, count); } -main: () -> int = +main: () = { x: std::string; // note: uninitialized! diff --git a/regression-tests/mixed-initialization-safety-2.cpp2 b/regression-tests/mixed-initialization-safety-2.cpp2 index a2eabc0568..66aeb8caee 100644 --- a/regression-tests/mixed-initialization-safety-2.cpp2 +++ b/regression-tests/mixed-initialization-safety-2.cpp2 @@ -16,7 +16,7 @@ fill: ( x = value.substr(0, count); } -main: () -> int = +main: () = { x: std::string; // note: uninitialized! diff --git a/regression-tests/mixed-initialization-safety-3.cpp2 b/regression-tests/mixed-initialization-safety-3.cpp2 index 5265c356fa..f0ef330c14 100644 --- a/regression-tests/mixed-initialization-safety-3.cpp2 +++ b/regression-tests/mixed-initialization-safety-3.cpp2 @@ -2,7 +2,7 @@ #include #include -main: () -> int = { +main: () = { x: std::string; // note: uninitialized! if flip_a_coin() { diff --git a/regression-tests/mixed-intro-for-with-counter-include-last.cpp2 b/regression-tests/mixed-intro-for-with-counter-include-last.cpp2 index 9d61d554d9..3c993b36cb 100644 --- a/regression-tests/mixed-intro-for-with-counter-include-last.cpp2 +++ b/regression-tests/mixed-intro-for-with-counter-include-last.cpp2 @@ -1,5 +1,5 @@ -main: () -> int +main: () = { v: std::vector = (1, 2, 3, 4, 5); counter := 42; diff --git a/regression-tests/mixed-lifetime-safety-and-null-contracts.cpp2 b/regression-tests/mixed-lifetime-safety-and-null-contracts.cpp2 index 62aaa6310f..a0a0adf64b 100644 --- a/regression-tests/mixed-lifetime-safety-and-null-contracts.cpp2 +++ b/regression-tests/mixed-lifetime-safety-and-null-contracts.cpp2 @@ -3,7 +3,7 @@ #include #include -main: () -> int = { +main: () = { cpp2::Null.set_handler(call_my_framework&); try_pointer_stuff(); std::cout << "done\n"; diff --git a/regression-tests/mixed-lifetime-safety-pointer-init-1.cpp2 b/regression-tests/mixed-lifetime-safety-pointer-init-1.cpp2 index efa1a38072..491ec58a48 100644 --- a/regression-tests/mixed-lifetime-safety-pointer-init-1.cpp2 +++ b/regression-tests/mixed-lifetime-safety-pointer-init-1.cpp2 @@ -2,7 +2,7 @@ #include #include -main: () -> int = { +main: () = { x: int = 42; p: *int; diff --git a/regression-tests/mixed-lifetime-safety-pointer-init-2.cpp2 b/regression-tests/mixed-lifetime-safety-pointer-init-2.cpp2 index 1420f0b8de..c068b9a2f9 100644 --- a/regression-tests/mixed-lifetime-safety-pointer-init-2.cpp2 +++ b/regression-tests/mixed-lifetime-safety-pointer-init-2.cpp2 @@ -2,7 +2,7 @@ #include #include -main: () -> int = { +main: () = { x: int = 42; p: *int; diff --git a/regression-tests/mixed-lifetime-safety-pointer-init-3.cpp2 b/regression-tests/mixed-lifetime-safety-pointer-init-3.cpp2 index 3c201f3c41..f725c43a18 100644 --- a/regression-tests/mixed-lifetime-safety-pointer-init-3.cpp2 +++ b/regression-tests/mixed-lifetime-safety-pointer-init-3.cpp2 @@ -2,7 +2,7 @@ #include #include -main: () -> int = { +main: () = { x: int = 42; p: *int; diff --git a/regression-tests/mixed-lifetime-safety-pointer-init-4.cpp2 b/regression-tests/mixed-lifetime-safety-pointer-init-4.cpp2 index ff14f53de8..035cccefd3 100644 --- a/regression-tests/mixed-lifetime-safety-pointer-init-4.cpp2 +++ b/regression-tests/mixed-lifetime-safety-pointer-init-4.cpp2 @@ -2,7 +2,7 @@ #include #include -main: () -> int = { +main: () = { x: int = 42; y: int = 43; p: *int; diff --git a/regression-tests/mixed-parameter-passing-with-forward.cpp2 b/regression-tests/mixed-parameter-passing-with-forward.cpp2 index 8ccca8b86b..cbde27549b 100644 --- a/regression-tests/mixed-parameter-passing-with-forward.cpp2 +++ b/regression-tests/mixed-parameter-passing-with-forward.cpp2 @@ -39,4 +39,4 @@ parameter_styles: ( } -main: () -> int = { } +main: () = { } diff --git a/regression-tests/mixed-parameter-passing.cpp2 b/regression-tests/mixed-parameter-passing.cpp2 index 0d0fa4ea54..2a1d668655 100644 --- a/regression-tests/mixed-parameter-passing.cpp2 +++ b/regression-tests/mixed-parameter-passing.cpp2 @@ -37,4 +37,4 @@ parameter_styles: ( } -main: () -> int = { } +main: () = { } diff --git a/regression-tests/mixed-postexpression-with-capture.cpp2 b/regression-tests/mixed-postexpression-with-capture.cpp2 index f986406aff..20d89a4f9c 100644 --- a/regression-tests/mixed-postexpression-with-capture.cpp2 +++ b/regression-tests/mixed-postexpression-with-capture.cpp2 @@ -5,7 +5,7 @@ #include #include -main: () -> int = { +main: () = { insert_at( 0, 42 ); } diff --git a/regression-tests/mixed-postfix-expression-custom-formatting.cpp2 b/regression-tests/mixed-postfix-expression-custom-formatting.cpp2 index 307a37be0c..681029eadb 100644 --- a/regression-tests/mixed-postfix-expression-custom-formatting.cpp2 +++ b/regression-tests/mixed-postfix-expression-custom-formatting.cpp2 @@ -12,4 +12,4 @@ test: (a:_) -> std::string = { ); } -main: () -> int = { } +main: () = { } diff --git a/regression-tests/mixed-string-interpolation.cpp2 b/regression-tests/mixed-string-interpolation.cpp2 index ad7797f7ed..da71766979 100644 --- a/regression-tests/mixed-string-interpolation.cpp2 +++ b/regression-tests/mixed-string-interpolation.cpp2 @@ -5,7 +5,7 @@ struct custom_struct_with_no_stringize_customization { } custom; -main: () -> int = { +main: () = { a := 2; b: std::optional = (); std::cout << "a = (a)$, b = (b)$\n"; diff --git a/regression-tests/mixed-type-safety-1.cpp2 b/regression-tests/mixed-type-safety-1.cpp2 index d7fb8adf99..99a28fc10d 100644 --- a/regression-tests/mixed-type-safety-1.cpp2 +++ b/regression-tests/mixed-type-safety-1.cpp2 @@ -23,7 +23,7 @@ print: ( msg: std::string, b: bool ) = //--- examples ------------------------- -main: () -> int = +main: () = { print( "1.1 is int? ", 1.1 is int ); print( "1 is int? ", 1 is int ); diff --git a/regression-tests/pure2-bounds-safety-pointer-arithmetic-error.cpp2 b/regression-tests/pure2-bounds-safety-pointer-arithmetic-error.cpp2 index b771925028..30598e6e99 100644 --- a/regression-tests/pure2-bounds-safety-pointer-arithmetic-error.cpp2 +++ b/regression-tests/pure2-bounds-safety-pointer-arithmetic-error.cpp2 @@ -1,5 +1,5 @@ -main: () -> int +main: () = { words: std::vector = ( "decorated", "hello", "world" ); diff --git a/regression-tests/pure2-bounds-safety-span.cpp2 b/regression-tests/pure2-bounds-safety-span.cpp2 index d44ef939d6..bf542d2ea7 100644 --- a/regression-tests/pure2-bounds-safety-span.cpp2 +++ b/regression-tests/pure2-bounds-safety-span.cpp2 @@ -1,5 +1,5 @@ -main: () -> int +main: () = { words: std::vector = ( "decorated", "hello", "world" ); diff --git a/regression-tests/pure2-bugfix-for-name-lookup-and-value-decoration.cpp2 b/regression-tests/pure2-bugfix-for-name-lookup-and-value-decoration.cpp2 index 5632572188..954c1891b0 100644 --- a/regression-tests/pure2-bugfix-for-name-lookup-and-value-decoration.cpp2 +++ b/regression-tests/pure2-bugfix-for-name-lookup-and-value-decoration.cpp2 @@ -3,7 +3,7 @@ vals: () -> (i : int) = { return; } -main: () -> int = { +main: () = { v := vals(); v.i; } diff --git a/regression-tests/pure2-hello.cpp2 b/regression-tests/pure2-hello.cpp2 index 8df8da04ba..d97b202e9e 100644 --- a/regression-tests/pure2-hello.cpp2 +++ b/regression-tests/pure2-hello.cpp2 @@ -1,5 +1,5 @@ -main: () -> int = { +main: () = { std::cout << "Hello " << name() << "\n"; } diff --git a/regression-tests/pure2-inspect-expression-in-generic-function-multiple-types.cpp2 b/regression-tests/pure2-inspect-expression-in-generic-function-multiple-types.cpp2 index 89d8d05d16..1dbee69a3d 100644 --- a/regression-tests/pure2-inspect-expression-in-generic-function-multiple-types.cpp2 +++ b/regression-tests/pure2-inspect-expression-in-generic-function-multiple-types.cpp2 @@ -1,4 +1,4 @@ -main: () -> int = { +main: () = { v: std::variant = 42.0; a: std::any = "xyzzy" as std::string; o: std::optional = (); diff --git a/regression-tests/pure2-inspect-expression-with-as-in-generic-function.cpp2 b/regression-tests/pure2-inspect-expression-with-as-in-generic-function.cpp2 index c528fe2138..3e638f7a74 100644 --- a/regression-tests/pure2-inspect-expression-with-as-in-generic-function.cpp2 +++ b/regression-tests/pure2-inspect-expression-with-as-in-generic-function.cpp2 @@ -1,4 +1,4 @@ -main: () -> int = { +main: () = { print_an_int("syzygy"); print_an_int(1); print_an_int(1.1); diff --git a/regression-tests/pure2-inspect-fallback-with-variant-any-optional.cpp2 b/regression-tests/pure2-inspect-fallback-with-variant-any-optional.cpp2 index d518b64a40..4fb8ea2010 100644 --- a/regression-tests/pure2-inspect-fallback-with-variant-any-optional.cpp2 +++ b/regression-tests/pure2-inspect-fallback-with-variant-any-optional.cpp2 @@ -1,5 +1,5 @@ -main: () -> int = { +main: () = { v: std::variant = "xyzzy" as std::string; a: std::any = "xyzzy" as std::string; o: std::optional = "xyzzy" as std::string; diff --git a/regression-tests/pure2-inspect-generic-void-empty-with-variant-any-optional.cpp2 b/regression-tests/pure2-inspect-generic-void-empty-with-variant-any-optional.cpp2 index df08544ab4..73982b1a62 100644 --- a/regression-tests/pure2-inspect-generic-void-empty-with-variant-any-optional.cpp2 +++ b/regression-tests/pure2-inspect-generic-void-empty-with-variant-any-optional.cpp2 @@ -1,5 +1,5 @@ -main: () -> int = { +main: () = { p: std::unique_ptr = (); i: std::vector::iterator = (); v: std::variant = (); @@ -23,4 +23,4 @@ test_generic: ( x: _ ) = { is _ = " no match"; } << "\n"; -} \ No newline at end of file +} diff --git a/regression-tests/pure2-int-main-arg.cpp2 b/regression-tests/pure2-int-main-arg.cpp2 new file mode 100644 index 0000000000..77c09f4a6d --- /dev/null +++ b/regression-tests/pure2-int-main-arg.cpp2 @@ -0,0 +1,4 @@ +main: (move args :std::span) -> int = { + for args do: (arg: _) = std::cout << arg << '\n'; + return 0; +} diff --git a/regression-tests/pure2-intro-example-hello-2022.cpp2 b/regression-tests/pure2-intro-example-hello-2022.cpp2 index 20fc890882..58cedfaaf5 100644 --- a/regression-tests/pure2-intro-example-hello-2022.cpp2 +++ b/regression-tests/pure2-intro-example-hello-2022.cpp2 @@ -1,4 +1,4 @@ -main: () -> int = { +main: () = { vec: std::vector = ("hello", "2022"); view: std::span = vec; diff --git a/regression-tests/pure2-intro-example-three-loops.cpp2 b/regression-tests/pure2-intro-example-three-loops.cpp2 index 4da84b9410..1e7b191798 100644 --- a/regression-tests/pure2-intro-example-three-loops.cpp2 +++ b/regression-tests/pure2-intro-example-three-loops.cpp2 @@ -7,7 +7,7 @@ decorate_and_print: (inout thing:_) = { print(thing); } -main: () -> int = { +main: () = { words: std::vector = ( "hello", "big", "world" ); view: std::span = words; diff --git a/regression-tests/pure2-lifetime-safety-pointer-init-1.cpp2 b/regression-tests/pure2-lifetime-safety-pointer-init-1.cpp2 index 19a7c8aaa3..832607afa0 100644 --- a/regression-tests/pure2-lifetime-safety-pointer-init-1.cpp2 +++ b/regression-tests/pure2-lifetime-safety-pointer-init-1.cpp2 @@ -1,5 +1,5 @@ -main: () -> int = { +main: () = { x: int = 42; p: *int; diff --git a/regression-tests/pure2-lifetime-safety-reject-null.cpp2 b/regression-tests/pure2-lifetime-safety-reject-null.cpp2 index ef0b6775bf..b8795ad8dc 100644 --- a/regression-tests/pure2-lifetime-safety-reject-null.cpp2 +++ b/regression-tests/pure2-lifetime-safety-reject-null.cpp2 @@ -3,7 +3,7 @@ #include #include -main: () -> int +main: () = { words: std::vector = ( "decorated", "hello", "world" ); diff --git a/regression-tests/pure2-stdio-with-raii.cpp2 b/regression-tests/pure2-stdio-with-raii.cpp2 index 104943c9f6..0861332f4f 100644 --- a/regression-tests/pure2-stdio-with-raii.cpp2 +++ b/regression-tests/pure2-stdio-with-raii.cpp2 @@ -1,7 +1,7 @@ // "A better C than C" ... ? // -main: () -> int = { +main: () = { s: std::string = "Freddy"; myfile := cpp2::fopen("xyzzy", "w"); myfile.fprintf( "Hello %s with UFCS!", s.c_str() ); diff --git a/regression-tests/pure2-stdio.cpp2 b/regression-tests/pure2-stdio.cpp2 index 070c4140b1..735c12cf8f 100644 --- a/regression-tests/pure2-stdio.cpp2 +++ b/regression-tests/pure2-stdio.cpp2 @@ -1,7 +1,7 @@ // "A better C than C" ... ? // -main: () -> int = { +main: () = { s: std::string = "Fred"; myfile := fopen("xyzzy", "w"); myfile.fprintf( "Hello %s with UFCS!", s.c_str() ); diff --git a/regression-tests/pure2-type-safety-1.cpp2 b/regression-tests/pure2-type-safety-1.cpp2 index 130f883404..85987f82e9 100644 --- a/regression-tests/pure2-type-safety-1.cpp2 +++ b/regression-tests/pure2-type-safety-1.cpp2 @@ -1,5 +1,5 @@ -main: () -> int = +main: () = { v: std::variant = 42.0; a: std::any = "xyzzy"; diff --git a/regression-tests/pure2-type-safety-2-with-inspect-expression.cpp2 b/regression-tests/pure2-type-safety-2-with-inspect-expression.cpp2 index d09d5e7a1f..27b0f5428b 100644 --- a/regression-tests/pure2-type-safety-2-with-inspect-expression.cpp2 +++ b/regression-tests/pure2-type-safety-2-with-inspect-expression.cpp2 @@ -1,4 +1,4 @@ -main: () -> int = { +main: () = { v: std::variant = 42.0; a: std::any = "xyzzy"; o: std::optional = (); diff --git a/regression-tests/pure2-void-main-arg.cpp2 b/regression-tests/pure2-void-main-arg.cpp2 new file mode 100644 index 0000000000..ef8c5d00b4 --- /dev/null +++ b/regression-tests/pure2-void-main-arg.cpp2 @@ -0,0 +1,3 @@ +main: (move args :std::span) = { + for args do: (arg: _) = std::cout << arg << '\n'; +} diff --git a/regression-tests/test-results/mixed-bounds-check.cpp b/regression-tests/test-results/mixed-bounds-check.cpp index 96392af38e..db5b1f33d2 100644 --- a/regression-tests/test-results/mixed-bounds-check.cpp +++ b/regression-tests/test-results/mixed-bounds-check.cpp @@ -5,13 +5,14 @@ #include -[[nodiscard]] auto main() -> int; //=== Cpp2 definitions ========================================================== #line 3 "mixed-bounds-check.cpp2" -[[nodiscard]] auto main() -> int{ +auto cpp2__main() -> void{ std::vector v { 1, 2, 3, 4, 5 }; std::cout << v[5] << "\n"; } +CPP2_MAIN_VOID_NO_ARGS + diff --git a/regression-tests/test-results/mixed-bounds-safety-with-assert-2.cpp b/regression-tests/test-results/mixed-bounds-safety-with-assert-2.cpp index 977ec0d3be..1b3e0aaa25 100644 --- a/regression-tests/test-results/mixed-bounds-safety-with-assert-2.cpp +++ b/regression-tests/test-results/mixed-bounds-safety-with-assert-2.cpp @@ -3,7 +3,6 @@ #line 2 "mixed-bounds-safety-with-assert-2.cpp2" -[[nodiscard]] auto main() -> int; #line 10 "mixed-bounds-safety-with-assert-2.cpp2" auto add_42_to_subrange(auto& rng, cpp2::in start, cpp2::in end) -> void; #line 23 "mixed-bounds-safety-with-assert-2.cpp2" @@ -16,14 +15,14 @@ auto add_42_to_subrange(auto& rng, cpp2::in start, cpp2::in end) -> vo #line 1 "mixed-bounds-safety-with-assert-2.cpp2" -[[nodiscard]] auto main() -> int{ +auto cpp2__main() -> void{ std::vector v { 1, 2, 3, 4, 5 }; add_42_to_subrange(v, 1, 3); for ( auto&& cpp2_range = v; auto const& i : cpp2_range ) std::cout << i << "\n"; } - +CPP2_MAIN_VOID_NO_ARGS auto add_42_to_subrange(auto& rng, cpp2::in start, cpp2::in end) -> void { cpp2::Bounds.expects(0 <= start, ""); diff --git a/regression-tests/test-results/mixed-bounds-safety-with-assert.cpp b/regression-tests/test-results/mixed-bounds-safety-with-assert.cpp index 52ebc9adca..b8defff696 100644 --- a/regression-tests/test-results/mixed-bounds-safety-with-assert.cpp +++ b/regression-tests/test-results/mixed-bounds-safety-with-assert.cpp @@ -3,7 +3,6 @@ #line 2 "mixed-bounds-safety-with-assert.cpp2" -[[nodiscard]] auto main() -> int; #line 7 "mixed-bounds-safety-with-assert.cpp2" auto print_subrange(auto const& rng, cpp2::in start, cpp2::in end) -> void; #line 19 "mixed-bounds-safety-with-assert.cpp2" @@ -16,11 +15,11 @@ auto print_subrange(auto const& rng, cpp2::in start, cpp2::in end) -> #line 1 "mixed-bounds-safety-with-assert.cpp2" -[[nodiscard]] auto main() -> int{ +auto cpp2__main() -> void{ std::vector v { 1, 2, 3, 4, 5 }; print_subrange(v, 1, 13); } - +CPP2_MAIN_VOID_NO_ARGS auto print_subrange(auto const& rng, cpp2::in start, cpp2::in end) -> void{ cpp2::Bounds.expects(0 <= start, ""); cpp2::Bounds.expects(end <= CPP2_UFCS_0(size, rng), ""); diff --git a/regression-tests/test-results/mixed-captures-in-expressions-and-postconditions.cpp b/regression-tests/test-results/mixed-captures-in-expressions-and-postconditions.cpp index d43a5e3438..a46a539df7 100644 --- a/regression-tests/test-results/mixed-captures-in-expressions-and-postconditions.cpp +++ b/regression-tests/test-results/mixed-captures-in-expressions-and-postconditions.cpp @@ -6,7 +6,6 @@ #include #include -[[nodiscard]] auto main() -> int; #line 17 "mixed-captures-in-expressions-and-postconditions.cpp2" #line 19 "mixed-captures-in-expressions-and-postconditions.cpp2" auto insert_at(cpp2::in where, cpp2::in val) -> void; @@ -15,7 +14,7 @@ auto insert_at(cpp2::in where, cpp2::in val) -> void; #line 4 "mixed-captures-in-expressions-and-postconditions.cpp2" -[[nodiscard]] auto main() -> int{ +auto cpp2__main() -> void{ std::vector vec { "hello", "2022" }; @@ -26,7 +25,7 @@ auto insert_at(cpp2::in where, cpp2::in val) -> void; y = "-ish\n"; std::ranges::for_each( vec, callback ); } - +CPP2_MAIN_VOID_NO_ARGS std::vector vec { }; auto insert_at(cpp2::in where, cpp2::in val) -> void diff --git a/regression-tests/test-results/mixed-function-expression-and-std-for-each.cpp b/regression-tests/test-results/mixed-function-expression-and-std-for-each.cpp index 3f0750f790..a6fbb3c250 100644 --- a/regression-tests/test-results/mixed-function-expression-and-std-for-each.cpp +++ b/regression-tests/test-results/mixed-function-expression-and-std-for-each.cpp @@ -8,13 +8,12 @@ #include #include -[[nodiscard]] auto main() -> int; //=== Cpp2 definitions ========================================================== #line 6 "mixed-function-expression-and-std-for-each.cpp2" -[[nodiscard]] auto main() -> int{ +auto cpp2__main() -> void{ std::vector vec { "hello", "2022" }; std::span view { vec }; @@ -38,3 +37,5 @@ std::cout << str << "\n"; } } +CPP2_MAIN_VOID_NO_ARGS + diff --git a/regression-tests/test-results/mixed-function-expression-and-std-ranges-for-each-with-capture.cpp b/regression-tests/test-results/mixed-function-expression-and-std-ranges-for-each-with-capture.cpp index 1e47076dad..c6569b912c 100644 --- a/regression-tests/test-results/mixed-function-expression-and-std-ranges-for-each-with-capture.cpp +++ b/regression-tests/test-results/mixed-function-expression-and-std-ranges-for-each-with-capture.cpp @@ -9,13 +9,12 @@ #include #include -[[nodiscard]] auto main() -> int; //=== Cpp2 definitions ========================================================== #line 7 "mixed-function-expression-and-std-ranges-for-each-with-capture.cpp2" -[[nodiscard]] auto main() -> int{ +auto cpp2__main() -> void{ std::vector vec { "hello", "2022" }; std::span view { vec }; @@ -30,3 +29,5 @@ for ( auto&& cpp2_range = view; auto const& str : cpp2_range ) std::cout << str << "\n"; } +CPP2_MAIN_VOID_NO_ARGS + diff --git a/regression-tests/test-results/mixed-function-expression-and-std-ranges-for-each.cpp b/regression-tests/test-results/mixed-function-expression-and-std-ranges-for-each.cpp index bdacc99da8..9dc2ffe9f0 100644 --- a/regression-tests/test-results/mixed-function-expression-and-std-ranges-for-each.cpp +++ b/regression-tests/test-results/mixed-function-expression-and-std-ranges-for-each.cpp @@ -9,13 +9,12 @@ #include #include -[[nodiscard]] auto main() -> int; //=== Cpp2 definitions ========================================================== #line 7 "mixed-function-expression-and-std-ranges-for-each.cpp2" -[[nodiscard]] auto main() -> int{ +auto cpp2__main() -> void{ std::vector vec { "hello", "2022" }; std::span view { vec }; @@ -29,3 +28,5 @@ for ( auto&& cpp2_range = view; auto const& str : cpp2_range ) std::cout << str << "\n"; } +CPP2_MAIN_VOID_NO_ARGS + diff --git a/regression-tests/test-results/mixed-function-expression-with-pointer-capture.cpp b/regression-tests/test-results/mixed-function-expression-with-pointer-capture.cpp index 9f1e223133..fc30686444 100644 --- a/regression-tests/test-results/mixed-function-expression-with-pointer-capture.cpp +++ b/regression-tests/test-results/mixed-function-expression-with-pointer-capture.cpp @@ -9,13 +9,12 @@ #include #include -[[nodiscard]] auto main() -> int; //=== Cpp2 definitions ========================================================== #line 7 "mixed-function-expression-with-pointer-capture.cpp2" -[[nodiscard]] auto main() -> int{ +auto cpp2__main() -> void{ std::vector vec { "hello", "2023" }; std::span view { vec }; @@ -31,3 +30,5 @@ for ( auto&& cpp2_range = view; auto const& str : cpp2_range ) std::cout << str << "\n"; } +CPP2_MAIN_VOID_NO_ARGS + diff --git a/regression-tests/test-results/mixed-function-expression-with-repeated-capture.cpp b/regression-tests/test-results/mixed-function-expression-with-repeated-capture.cpp index bd46f99380..565e267be9 100644 --- a/regression-tests/test-results/mixed-function-expression-with-repeated-capture.cpp +++ b/regression-tests/test-results/mixed-function-expression-with-repeated-capture.cpp @@ -9,13 +9,12 @@ #include #include -[[nodiscard]] auto main() -> int; //=== Cpp2 definitions ========================================================== #line 7 "mixed-function-expression-with-repeated-capture.cpp2" -[[nodiscard]] auto main() -> int{ +auto cpp2__main() -> void{ std::vector vec { "hello", "2022" }; std::span view { vec }; @@ -30,3 +29,5 @@ for ( auto&& cpp2_range = view; auto const& str : cpp2_range ) std::cout << str << "\n"; } +CPP2_MAIN_VOID_NO_ARGS + diff --git a/regression-tests/test-results/mixed-initialization-safety-3.cpp b/regression-tests/test-results/mixed-initialization-safety-3.cpp index b77c9d7b72..80d2b0a50e 100644 --- a/regression-tests/test-results/mixed-initialization-safety-3.cpp +++ b/regression-tests/test-results/mixed-initialization-safety-3.cpp @@ -6,7 +6,6 @@ #include #include -[[nodiscard]] auto main() -> int; #line 16 "mixed-initialization-safety-3.cpp2" auto fill( cpp2::out x, @@ -22,7 +21,7 @@ auto print_decorated(auto const& x) -> void; #line 4 "mixed-initialization-safety-3.cpp2" -[[nodiscard]] auto main() -> int{ +auto cpp2__main() -> void{ cpp2::deferred_init x; // note: uninitialized! if (flip_a_coin()) { @@ -32,7 +31,7 @@ auto print_decorated(auto const& x) -> void; } print_decorated(x.value()); } - +CPP2_MAIN_VOID_NO_ARGS auto fill( cpp2::out x, cpp2::in value, diff --git a/regression-tests/test-results/mixed-intro-for-with-counter-include-last.cpp b/regression-tests/test-results/mixed-intro-for-with-counter-include-last.cpp index 2675a0999d..ad3209a769 100644 --- a/regression-tests/test-results/mixed-intro-for-with-counter-include-last.cpp +++ b/regression-tests/test-results/mixed-intro-for-with-counter-include-last.cpp @@ -3,7 +3,6 @@ #line 2 "mixed-intro-for-with-counter-include-last.cpp2" -[[nodiscard]] auto main() -> int; #line 10 "mixed-intro-for-with-counter-include-last.cpp2" #include @@ -14,7 +13,7 @@ #line 1 "mixed-intro-for-with-counter-include-last.cpp2" -[[nodiscard]] auto main() -> int +auto cpp2__main() -> void { std::vector v { 1, 2, 3, 4, 5 }; auto counter { 42 }; @@ -22,3 +21,5 @@ std::cout << i << " " << counter << "\n"; } while (false); counter *= 2; } } +CPP2_MAIN_VOID_NO_ARGS + diff --git a/regression-tests/test-results/mixed-lifetime-safety-and-null-contracts.cpp b/regression-tests/test-results/mixed-lifetime-safety-and-null-contracts.cpp index b167626294..97ede1d3ed 100644 --- a/regression-tests/test-results/mixed-lifetime-safety-and-null-contracts.cpp +++ b/regression-tests/test-results/mixed-lifetime-safety-and-null-contracts.cpp @@ -7,7 +7,6 @@ #include #include -[[nodiscard]] auto main() -> int; #line 11 "mixed-lifetime-safety-and-null-contracts.cpp2" // Calling Cpp1 is the easiest way to create a null... @@ -21,11 +20,12 @@ auto call_my_framework(cpp2::in msg) -> void; #line 5 "mixed-lifetime-safety-and-null-contracts.cpp2" -[[nodiscard]] auto main() -> int{ +auto cpp2__main() -> void{ cpp2::Null.set_handler(&call_my_framework); try_pointer_stuff(); std::cout << "done\n"; } +CPP2_MAIN_VOID_NO_ARGS #line 14 "mixed-lifetime-safety-and-null-contracts.cpp2" auto try_pointer_stuff() -> void{ diff --git a/regression-tests/test-results/mixed-lifetime-safety-pointer-init-4.cpp b/regression-tests/test-results/mixed-lifetime-safety-pointer-init-4.cpp index cc98c76c48..27711af370 100644 --- a/regression-tests/test-results/mixed-lifetime-safety-pointer-init-4.cpp +++ b/regression-tests/test-results/mixed-lifetime-safety-pointer-init-4.cpp @@ -6,7 +6,6 @@ #include #include -[[nodiscard]] auto main() -> int; #line 21 "mixed-lifetime-safety-pointer-init-4.cpp2" auto print_and_decorate(auto const& thing) -> void; #line 23 "mixed-lifetime-safety-pointer-init-4.cpp2" @@ -16,7 +15,7 @@ auto print_and_decorate(auto const& thing) -> void; #line 4 "mixed-lifetime-safety-pointer-init-4.cpp2" -[[nodiscard]] auto main() -> int{ +auto cpp2__main() -> void{ int x { 42 }; int y { 43 }; cpp2::deferred_init p; @@ -31,6 +30,6 @@ auto print_and_decorate(auto const& thing) -> void; print_and_decorate( *p.value()); } - +CPP2_MAIN_VOID_NO_ARGS auto print_and_decorate(auto const& thing) -> void { std::cout << ">> " << thing << "\n"; } diff --git a/regression-tests/test-results/mixed-parameter-passing-with-forward.cpp b/regression-tests/test-results/mixed-parameter-passing-with-forward.cpp index abcf98e7f7..275d9bc2fe 100644 --- a/regression-tests/test-results/mixed-parameter-passing-with-forward.cpp +++ b/regression-tests/test-results/mixed-parameter-passing-with-forward.cpp @@ -17,7 +17,6 @@ auto parameter_styles( auto&& e ) -> void; #line 42 "mixed-parameter-passing-with-forward.cpp2" -[[nodiscard]] auto main() -> int; //=== Cpp2 definitions ========================================================== @@ -61,4 +60,6 @@ requires std::is_same_v } -[[nodiscard]] auto main() -> int{} +auto cpp2__main() -> void{} +CPP2_MAIN_VOID_NO_ARGS + diff --git a/regression-tests/test-results/mixed-parameter-passing.cpp b/regression-tests/test-results/mixed-parameter-passing.cpp index 8f9dd1ae8a..b83fab0859 100644 --- a/regression-tests/test-results/mixed-parameter-passing.cpp +++ b/regression-tests/test-results/mixed-parameter-passing.cpp @@ -16,7 +16,6 @@ auto parameter_styles( std::string&& d ) -> void; #line 40 "mixed-parameter-passing.cpp2" -[[nodiscard]] auto main() -> int; //=== Cpp2 definitions ========================================================== @@ -56,4 +55,6 @@ auto parameter_styles( } -[[nodiscard]] auto main() -> int{} +auto cpp2__main() -> void{} +CPP2_MAIN_VOID_NO_ARGS + diff --git a/regression-tests/test-results/mixed-postexpression-with-capture.cpp b/regression-tests/test-results/mixed-postexpression-with-capture.cpp index b1fbb0a0c1..f350d2ecd8 100644 --- a/regression-tests/test-results/mixed-postexpression-with-capture.cpp +++ b/regression-tests/test-results/mixed-postexpression-with-capture.cpp @@ -9,7 +9,6 @@ #include #include -[[nodiscard]] auto main() -> int; #line 12 "mixed-postexpression-with-capture.cpp2" #line 14 "mixed-postexpression-with-capture.cpp2" auto insert_at(cpp2::in where, cpp2::in val) -> void; @@ -18,10 +17,10 @@ auto insert_at(cpp2::in where, cpp2::in val) -> void; #line 7 "mixed-postexpression-with-capture.cpp2" -[[nodiscard]] auto main() -> int{ +auto cpp2__main() -> void{ insert_at( 0, 42 ); } - +CPP2_MAIN_VOID_NO_ARGS std::vector vec { }; auto insert_at(cpp2::in where, cpp2::in val) -> void diff --git a/regression-tests/test-results/mixed-postfix-expression-custom-formatting.cpp b/regression-tests/test-results/mixed-postfix-expression-custom-formatting.cpp index a7ec157a02..9e008ea127 100644 --- a/regression-tests/test-results/mixed-postfix-expression-custom-formatting.cpp +++ b/regression-tests/test-results/mixed-postfix-expression-custom-formatting.cpp @@ -7,7 +7,6 @@ auto call(auto const& v, auto const& w, auto const& x, auto const& y, auto const #line 4 "mixed-postfix-expression-custom-formatting.cpp2" [[nodiscard]] auto test(auto const& a) -> std::string; #line 15 "mixed-postfix-expression-custom-formatting.cpp2" -[[nodiscard]] auto main() -> int; //=== Cpp2 definitions ========================================================== @@ -26,4 +25,6 @@ auto call(auto const& v, auto const& w, auto const& x, auto const& y, auto const ); } -[[nodiscard]] auto main() -> int{} +auto cpp2__main() -> void{} +CPP2_MAIN_VOID_NO_ARGS + diff --git a/regression-tests/test-results/mixed-string-interpolation.cpp b/regression-tests/test-results/mixed-string-interpolation.cpp index 07fb4ef1c4..76fe543a94 100644 --- a/regression-tests/test-results/mixed-string-interpolation.cpp +++ b/regression-tests/test-results/mixed-string-interpolation.cpp @@ -9,13 +9,12 @@ struct custom_struct_with_no_stringize_customization { } custom; -[[nodiscard]] auto main() -> int; //=== Cpp2 definitions ========================================================== #line 7 "mixed-string-interpolation.cpp2" -[[nodiscard]] auto main() -> int{ +auto cpp2__main() -> void{ auto a { 2 }; std::optional b { }; std::cout << "a = " + cpp2::to_string(a) + ", b = " + cpp2::to_string(b) + "\n"; @@ -61,3 +60,5 @@ struct custom_struct_with_no_stringize_customization { } custom; std::cout << "custom = " + cpp2::to_string(custom) + "\n"; } +CPP2_MAIN_VOID_NO_ARGS + diff --git a/regression-tests/test-results/mixed-type-safety-1.cpp b/regression-tests/test-results/mixed-type-safety-1.cpp index f676065440..f1e7ba53f5 100644 --- a/regression-tests/test-results/mixed-type-safety-1.cpp +++ b/regression-tests/test-results/mixed-type-safety-1.cpp @@ -17,7 +17,6 @@ auto print(cpp2::in msg, auto const& x) -> void; #line 16 "mixed-type-safety-1.cpp2" auto print(cpp2::in msg, cpp2::in b) -> void; #line 26 "mixed-type-safety-1.cpp2" -[[nodiscard]] auto main() -> int; //=== Cpp2 definitions ========================================================== @@ -38,7 +37,7 @@ auto print(cpp2::in msg, cpp2::in b) -> void //--- examples ------------------------- -[[nodiscard]] auto main() -> int +auto cpp2__main() -> void { print( "1.1 is int? ", cpp2::is(1.1)); print( "1 is int? ", cpp2::is(1)); @@ -49,3 +48,5 @@ auto print(cpp2::in msg, cpp2::in b) -> void print( "s* is Circle? ", cpp2::is(*s)); print( "s* is Square? ", cpp2::is(*s)); } +CPP2_MAIN_VOID_NO_ARGS + diff --git a/regression-tests/test-results/pure2-bounds-safety-span.cpp b/regression-tests/test-results/pure2-bounds-safety-span.cpp index 157df1129a..587c5c1c40 100644 --- a/regression-tests/test-results/pure2-bounds-safety-span.cpp +++ b/regression-tests/test-results/pure2-bounds-safety-span.cpp @@ -4,7 +4,6 @@ #line 2 "pure2-bounds-safety-span.cpp2" -[[nodiscard]] auto main() -> int; #line 14 "pure2-bounds-safety-span.cpp2" auto print_and_decorate(auto const& thing) -> void; #line 16 "pure2-bounds-safety-span.cpp2" @@ -14,7 +13,7 @@ auto print_and_decorate(auto const& thing) -> void; #line 1 "pure2-bounds-safety-span.cpp2" -[[nodiscard]] auto main() -> int +auto cpp2__main() -> void { std::vector words { "decorated", "hello", "world" }; @@ -25,6 +24,6 @@ auto print_and_decorate(auto const& thing) -> void; print_and_decorate( s[i] ); } } - +CPP2_MAIN_VOID_NO_ARGS auto print_and_decorate(auto const& thing) -> void { std::cout << ">> " << thing << "\n"; } diff --git a/regression-tests/test-results/pure2-bugfix-for-name-lookup-and-value-decoration.cpp b/regression-tests/test-results/pure2-bugfix-for-name-lookup-and-value-decoration.cpp index ddfee751e9..14083e1bc2 100644 --- a/regression-tests/test-results/pure2-bugfix-for-name-lookup-and-value-decoration.cpp +++ b/regression-tests/test-results/pure2-bugfix-for-name-lookup-and-value-decoration.cpp @@ -10,7 +10,6 @@ struct vals__ret { #line 2 "pure2-bugfix-for-name-lookup-and-value-decoration.cpp2" [[nodiscard]] auto vals() -> vals__ret; #line 6 "pure2-bugfix-for-name-lookup-and-value-decoration.cpp2" -[[nodiscard]] auto main() -> int; //=== Cpp2 definitions ========================================================== @@ -22,7 +21,9 @@ struct vals__ret { return { std::move(i.value()) }; } -[[nodiscard]] auto main() -> int{ +auto cpp2__main() -> void{ auto v { vals() }; v.i; } +CPP2_MAIN_VOID_NO_ARGS + diff --git a/regression-tests/test-results/pure2-hello.cpp b/regression-tests/test-results/pure2-hello.cpp index def1ed6ed3..aa9816ace0 100644 --- a/regression-tests/test-results/pure2-hello.cpp +++ b/regression-tests/test-results/pure2-hello.cpp @@ -4,7 +4,6 @@ #line 2 "pure2-hello.cpp2" -[[nodiscard]] auto main() -> int; #line 6 "pure2-hello.cpp2" [[nodiscard]] auto name() -> std::string; #line 12 "pure2-hello.cpp2" @@ -14,10 +13,10 @@ auto decorate(std::string& s) -> void; #line 1 "pure2-hello.cpp2" -[[nodiscard]] auto main() -> int{ +auto cpp2__main() -> void{ std::cout << "Hello " << name() << "\n"; } - +CPP2_MAIN_VOID_NO_ARGS [[nodiscard]] auto name() -> std::string{ std::string s { "world" }; decorate(s); diff --git a/regression-tests/test-results/pure2-inspect-expression-in-generic-function-multiple-types.cpp b/regression-tests/test-results/pure2-inspect-expression-in-generic-function-multiple-types.cpp index 5c389a074e..c42e9decb0 100644 --- a/regression-tests/test-results/pure2-inspect-expression-in-generic-function-multiple-types.cpp +++ b/regression-tests/test-results/pure2-inspect-expression-in-generic-function-multiple-types.cpp @@ -4,14 +4,13 @@ #line 1 "pure2-inspect-expression-in-generic-function-multiple-types.cpp2" -[[nodiscard]] auto main() -> int; #line 20 "pure2-inspect-expression-in-generic-function-multiple-types.cpp2" auto test_generic(auto const& x) -> void; //=== Cpp2 definitions ========================================================== #line 1 "pure2-inspect-expression-in-generic-function-multiple-types.cpp2" -[[nodiscard]] auto main() -> int{ +auto cpp2__main() -> void{ std::variant v { 42.0 }; std::any a { cpp2::as("xyzzy") }; std::optional o { }; @@ -29,7 +28,7 @@ auto test_generic(auto const& x) -> void; test_generic(a); test_generic(o); } - +CPP2_MAIN_VOID_NO_ARGS auto test_generic(auto const& x) -> void{ std::cout << std::setw(30) << typeid(x).name() diff --git a/regression-tests/test-results/pure2-inspect-expression-with-as-in-generic-function.cpp b/regression-tests/test-results/pure2-inspect-expression-with-as-in-generic-function.cpp index 444c072851..6c3104c5aa 100644 --- a/regression-tests/test-results/pure2-inspect-expression-with-as-in-generic-function.cpp +++ b/regression-tests/test-results/pure2-inspect-expression-with-as-in-generic-function.cpp @@ -4,19 +4,18 @@ #line 1 "pure2-inspect-expression-with-as-in-generic-function.cpp2" -[[nodiscard]] auto main() -> int; #line 7 "pure2-inspect-expression-with-as-in-generic-function.cpp2" auto print_an_int(auto const& x) -> void; //=== Cpp2 definitions ========================================================== #line 1 "pure2-inspect-expression-with-as-in-generic-function.cpp2" -[[nodiscard]] auto main() -> int{ +auto cpp2__main() -> void{ print_an_int("syzygy"); print_an_int(1); print_an_int(1.1); } - +CPP2_MAIN_VOID_NO_ARGS auto print_an_int(auto const& x) -> void{ std::cout << std::setw(30) << typeid(x).name() diff --git a/regression-tests/test-results/pure2-inspect-fallback-with-variant-any-optional.cpp b/regression-tests/test-results/pure2-inspect-fallback-with-variant-any-optional.cpp index dfa3680252..8ffde581f5 100644 --- a/regression-tests/test-results/pure2-inspect-fallback-with-variant-any-optional.cpp +++ b/regression-tests/test-results/pure2-inspect-fallback-with-variant-any-optional.cpp @@ -4,7 +4,6 @@ #line 2 "pure2-inspect-fallback-with-variant-any-optional.cpp2" -[[nodiscard]] auto main() -> int; #line 14 "pure2-inspect-fallback-with-variant-any-optional.cpp2" auto test_generic(auto const& x) -> void; @@ -12,7 +11,7 @@ auto test_generic(auto const& x) -> void; #line 1 "pure2-inspect-fallback-with-variant-any-optional.cpp2" -[[nodiscard]] auto main() -> int{ +auto cpp2__main() -> void{ std::variant v { cpp2::as("xyzzy") }; std::any a { cpp2::as("xyzzy") }; std::optional o { cpp2::as("xyzzy") }; @@ -23,7 +22,7 @@ auto test_generic(auto const& x) -> void; test_generic(a); test_generic(o); } - +CPP2_MAIN_VOID_NO_ARGS auto test_generic(auto const& x) -> void{ std::cout << "\n" << typeid(x).name() << "\n ..." diff --git a/regression-tests/test-results/pure2-inspect-generic-void-empty-with-variant-any-optional.cpp b/regression-tests/test-results/pure2-inspect-generic-void-empty-with-variant-any-optional.cpp index eaa0b04756..ccec95e1ae 100644 --- a/regression-tests/test-results/pure2-inspect-generic-void-empty-with-variant-any-optional.cpp +++ b/regression-tests/test-results/pure2-inspect-generic-void-empty-with-variant-any-optional.cpp @@ -4,7 +4,6 @@ #line 2 "pure2-inspect-generic-void-empty-with-variant-any-optional.cpp2" -[[nodiscard]] auto main() -> int; #line 18 "pure2-inspect-generic-void-empty-with-variant-any-optional.cpp2" auto test_generic(auto const& x) -> void; @@ -12,7 +11,7 @@ auto test_generic(auto const& x) -> void; #line 1 "pure2-inspect-generic-void-empty-with-variant-any-optional.cpp2" -[[nodiscard]] auto main() -> int{ +auto cpp2__main() -> void{ std::unique_ptr p { }; std::vector::iterator i { }; std::variant v { }; @@ -27,7 +26,7 @@ auto test_generic(auto const& x) -> void; test_generic(a); test_generic(o); } - +CPP2_MAIN_VOID_NO_ARGS auto test_generic(auto const& x) -> void{ std::cout << "\n" << typeid(x).name() << "\n ..." diff --git a/regression-tests/test-results/pure2-int-main-arg.cpp b/regression-tests/test-results/pure2-int-main-arg.cpp new file mode 100644 index 0000000000..f8cefd8c61 --- /dev/null +++ b/regression-tests/test-results/pure2-int-main-arg.cpp @@ -0,0 +1,16 @@ +// ----- Cpp2 support ----- +#define CPP2_USE_MODULES Yes +#include "cpp2util.h" + + +#line 1 "pure2-int-main-arg.cpp2" + +//=== Cpp2 definitions ========================================================== + +#line 1 "pure2-int-main-arg.cpp2" +[[nodiscard]] auto cpp2__main(std::span&& args) -> int{ + for ( auto&& cpp2_range = std::move(args); auto const& arg : cpp2_range ) std::cout << arg << '\n'; + return 0; +} +CPP2_MAIN_INT_ARGS + diff --git a/regression-tests/test-results/pure2-int-main-arg.cpp2.output b/regression-tests/test-results/pure2-int-main-arg.cpp2.output new file mode 100644 index 0000000000..d7efa8271f --- /dev/null +++ b/regression-tests/test-results/pure2-int-main-arg.cpp2.output @@ -0,0 +1,2 @@ +pure2-int-main-arg.cpp2... ok (all Cpp2, passes safety checks) + diff --git a/regression-tests/test-results/pure2-intro-example-hello-2022.cpp b/regression-tests/test-results/pure2-intro-example-hello-2022.cpp index 667c6ef81b..9af27a2a3d 100644 --- a/regression-tests/test-results/pure2-intro-example-hello-2022.cpp +++ b/regression-tests/test-results/pure2-intro-example-hello-2022.cpp @@ -4,7 +4,6 @@ #line 1 "pure2-intro-example-hello-2022.cpp2" -[[nodiscard]] auto main() -> int; #line 12 "pure2-intro-example-hello-2022.cpp2" [[nodiscard]] auto decorate(auto& thing) -> int; #line 17 "pure2-intro-example-hello-2022.cpp2" @@ -13,7 +12,7 @@ auto println(auto const& x, auto const& len) -> void; //=== Cpp2 definitions ========================================================== #line 1 "pure2-intro-example-hello-2022.cpp2" -[[nodiscard]] auto main() -> int{ +auto cpp2__main() -> void{ std::vector vec { "hello", "2022" }; std::span view { vec }; @@ -23,7 +22,7 @@ auto println(auto const& x, auto const& len) -> void; println(str, len); } } - +CPP2_MAIN_VOID_NO_ARGS [[nodiscard]] auto decorate(auto& thing) -> int{ thing = "[" + thing + "]"; return CPP2_UFCS_0(ssize, thing); diff --git a/regression-tests/test-results/pure2-intro-example-three-loops.cpp b/regression-tests/test-results/pure2-intro-example-three-loops.cpp index 629d988b4d..c15ff4b29c 100644 --- a/regression-tests/test-results/pure2-intro-example-three-loops.cpp +++ b/regression-tests/test-results/pure2-intro-example-three-loops.cpp @@ -8,7 +8,6 @@ auto print(auto const& thing) -> void; #line 5 "pure2-intro-example-three-loops.cpp2" auto decorate_and_print(auto& thing) -> void; #line 10 "pure2-intro-example-three-loops.cpp2" -[[nodiscard]] auto main() -> int; #line 29 "pure2-intro-example-three-loops.cpp2" @@ -24,7 +23,7 @@ auto decorate_and_print(auto& thing) -> void{ print(thing); } -[[nodiscard]] auto main() -> int{ +auto cpp2__main() -> void{ std::vector words { "hello", "big", "world" }; std::span view { words }; @@ -43,3 +42,5 @@ auto decorate_and_print(auto& thing) -> void{ decorate_and_print(word); } +CPP2_MAIN_VOID_NO_ARGS + diff --git a/regression-tests/test-results/pure2-stdio-with-raii.cpp b/regression-tests/test-results/pure2-stdio-with-raii.cpp index 0f3edb398a..e9b100d6c7 100644 --- a/regression-tests/test-results/pure2-stdio-with-raii.cpp +++ b/regression-tests/test-results/pure2-stdio-with-raii.cpp @@ -4,7 +4,6 @@ #line 4 "pure2-stdio-with-raii.cpp2" -[[nodiscard]] auto main() -> int; //=== Cpp2 definitions ========================================================== @@ -12,8 +11,10 @@ // "A better C than C" ... ? // -[[nodiscard]] auto main() -> int{ +auto cpp2__main() -> void{ std::string s { "Freddy" }; auto myfile { cpp2::fopen("xyzzy", "w") }; CPP2_UFCS(fprintf, myfile, "Hello %s with UFCS!", CPP2_UFCS_0(c_str, s)); } +CPP2_MAIN_VOID_NO_ARGS + diff --git a/regression-tests/test-results/pure2-stdio.cpp b/regression-tests/test-results/pure2-stdio.cpp index 73c7ed0c8a..96fed87478 100644 --- a/regression-tests/test-results/pure2-stdio.cpp +++ b/regression-tests/test-results/pure2-stdio.cpp @@ -4,7 +4,6 @@ #line 4 "pure2-stdio.cpp2" -[[nodiscard]] auto main() -> int; #line 10 "pure2-stdio.cpp2" @@ -14,9 +13,11 @@ // "A better C than C" ... ? // -[[nodiscard]] auto main() -> int{ +auto cpp2__main() -> void{ std::string s { "Fred" }; auto myfile { fopen("xyzzy", "w") }; CPP2_UFCS(fprintf, myfile, "Hello %s with UFCS!", CPP2_UFCS_0(c_str, s)); CPP2_UFCS_0(fclose, myfile); } +CPP2_MAIN_VOID_NO_ARGS + diff --git a/regression-tests/test-results/pure2-type-safety-1.cpp b/regression-tests/test-results/pure2-type-safety-1.cpp index 13340cd2c4..9e04ff3e8a 100644 --- a/regression-tests/test-results/pure2-type-safety-1.cpp +++ b/regression-tests/test-results/pure2-type-safety-1.cpp @@ -4,7 +4,6 @@ #line 2 "pure2-type-safety-1.cpp2" -[[nodiscard]] auto main() -> int; #line 24 "pure2-type-safety-1.cpp2" auto test_generic(auto const& x) -> void; #line 30 "pure2-type-safety-1.cpp2" @@ -16,7 +15,7 @@ auto print(cpp2::in msg, cpp2::in b) -> void; #line 1 "pure2-type-safety-1.cpp2" -[[nodiscard]] auto main() -> int +auto cpp2__main() -> void { std::variant v { 42.0 }; std::any a { "xyzzy" }; @@ -37,7 +36,7 @@ auto print(cpp2::in msg, cpp2::in b) -> void; test_generic(a); test_generic(o); } - +CPP2_MAIN_VOID_NO_ARGS auto test_generic(auto const& x) -> void{ std::string msg { typeid(x).name() }; msg += " is int? "; diff --git a/regression-tests/test-results/pure2-type-safety-2-with-inspect-expression.cpp b/regression-tests/test-results/pure2-type-safety-2-with-inspect-expression.cpp index 19505cb537..e56a11bbfe 100644 --- a/regression-tests/test-results/pure2-type-safety-2-with-inspect-expression.cpp +++ b/regression-tests/test-results/pure2-type-safety-2-with-inspect-expression.cpp @@ -4,14 +4,13 @@ #line 1 "pure2-type-safety-2-with-inspect-expression.cpp2" -[[nodiscard]] auto main() -> int; #line 20 "pure2-type-safety-2-with-inspect-expression.cpp2" auto test_generic(auto const& x) -> void; //=== Cpp2 definitions ========================================================== #line 1 "pure2-type-safety-2-with-inspect-expression.cpp2" -[[nodiscard]] auto main() -> int{ +auto cpp2__main() -> void{ std::variant v { 42.0 }; std::any a { "xyzzy" }; std::optional o { }; @@ -29,7 +28,7 @@ auto test_generic(auto const& x) -> void; test_generic(a); test_generic(o); } - +CPP2_MAIN_VOID_NO_ARGS auto test_generic(auto const& x) -> void{ std::cout << std::setw(30) << typeid(x).name() diff --git a/regression-tests/test-results/pure2-void-main-arg.cpp b/regression-tests/test-results/pure2-void-main-arg.cpp new file mode 100644 index 0000000000..6d94183543 --- /dev/null +++ b/regression-tests/test-results/pure2-void-main-arg.cpp @@ -0,0 +1,15 @@ +// ----- Cpp2 support ----- +#define CPP2_USE_MODULES Yes +#include "cpp2util.h" + + +#line 1 "pure2-void-main-arg.cpp2" + +//=== Cpp2 definitions ========================================================== + +#line 1 "pure2-void-main-arg.cpp2" +auto cpp2__main(std::span&& args) -> void{ + for ( auto&& cpp2_range = std::move(args); auto const& arg : cpp2_range ) std::cout << arg << '\n'; +} +CPP2_MAIN_VOID_ARGS + diff --git a/regression-tests/test-results/pure2-void-main-arg.cpp2.output b/regression-tests/test-results/pure2-void-main-arg.cpp2.output new file mode 100644 index 0000000000..bc6030783e --- /dev/null +++ b/regression-tests/test-results/pure2-void-main-arg.cpp2.output @@ -0,0 +1,2 @@ +pure2-void-main-arg.cpp2... ok (all Cpp2, passes safety checks) + diff --git a/source/cppfront.cpp b/source/cppfront.cpp index b1dd63cff5..8826c8eb72 100644 --- a/source/cppfront.cpp +++ b/source/cppfront.cpp @@ -2357,6 +2357,10 @@ class cppfront auto& func = std::get(n.type); assert(func); + if (printer.doing_declarations_only() && func->is_main) { + // main doesn't need a forward declaration. + return; + } // If this is at expression scope, we can't emit "[[nodiscard]] auto name" // so print the provided intro instead, which will be a lambda-capture-list @@ -2371,8 +2375,12 @@ class cppfront printer.print_cpp2( "[[nodiscard]] ", n.position() ); } printer.print_cpp2( "auto ", n.position() ); - printer.print_cpp2( *n.identifier->identifier, n.identifier->position() ); - emit( *func, n.identifier->identifier ); + if (func->is_main) { + printer.print_cpp2("cpp2__main", n.identifier->position()); + } else { + printer.print_cpp2(*n.identifier->identifier, n.identifier->position()); + } + emit(*func, n.identifier->identifier); } // Function declaration @@ -2486,6 +2494,11 @@ class cppfront function_return_locals, function_epilog, n.position().colno ); + if (func->is_main) { + std::string ret = func->returns.index() != function_type_node::empty ? "INT" : "VOID"; + std::string args = func->parameters->parameters.empty() ? "NO_ARGS" : "ARGS"; + printer.print_cpp2("\nCPP2_MAIN_" + ret + '_' + args + '\n', func->position()); + } function_returns.pop_back(); } diff --git a/source/parse.h b/source/parse.h index 3c549e47df..6fa121e838 100644 --- a/source/parse.h +++ b/source/parse.h @@ -804,6 +804,7 @@ struct function_type_node { std::unique_ptr parameters; bool throws = false; + bool is_main = false; enum active { empty = 0, id, list }; std::variant< diff --git a/source/sema.h b/source/sema.h index 2027acc776..f544ed25b7 100644 --- a/source/sema.h +++ b/source/sema.h @@ -842,6 +842,9 @@ class sema if (n.type.index() != declaration_node::active::object) { --scope_depth; } + if(n.type.index() == declaration_node::active::function && n.identifier && *(n.identifier->identifier) == "main") { + handle_function_main(*std::get(n.type)); + } partial_decl_stack.pop_back(); } } @@ -959,6 +962,141 @@ class sema { // Ignore other node types } +private: + + // An AST matcher to match the expected type of the parameter of cpp2's main. + // + // The expected type is std::span, which has the following AST: + // 0 id-expression + // 1 qualified-id + // 2 unqualified-id + // 3 Identifier: std + // 4 Scope: :: + // 5 unqualified-id + // 6 Identifier: span + // 7 id-expression + // 8 qualified-id + // 9 unqualified-id + // 10 Identifier: std + // 11 Scope: :: + // 12 unqualified-id + // 13 Identifier: string_view + // + // Note this is a customized matcher since there is no generic matcher. + class ast_matcher_main_parameter + { + int index = 0; + bool valid = true; + public: + auto matched() const -> bool { return valid && index == 14; } + + auto start(const id_expression_node& n, int) -> void + { + switch(index++) { + break; case 0: + break; case 7: + break; default: + valid = false; + } + } + + auto start(const qualified_id_node& n, int) -> void + { + switch(index++) { + break; case 1: + break; case 8: + break; default: + valid = false; + } + } + + auto start(const unqualified_id_node& n, int) -> void + { + switch(index++) { + break; case 2: + break; case 5: + break; case 9: + break; case 12: + break; default: + valid = false; + } + } + + auto start(const token& t, int) -> void + { + switch(index++) { + break;case 3: case 10: + valid |= t.type() == lexeme::Identifier && t == "std"; + break;case 4: case 11: + valid |= t.type() == lexeme::Scope; + break;case 6: + valid |= t.type() == lexeme::Identifier && t == "span"; + break;case 13: + valid |= t.type() == lexeme::Identifier && t == "string_view"; + break;default: + valid = false; + } + } + + auto start(auto const & n, int) -> void + { + // Unexpected type. + valid = false; + } + + auto end(auto const &, int) -> void + { + // The validation is done in the start function. + } + }; + + auto is_valid_parameter_main(parameter_declaration_node& p) -> bool + { + if(p.pass != passing_style::move) { + return false; + } + if(p.mod != parameter_declaration_node:: modifier::none) { + return false; + } + auto& d = *p.declaration; + assert(d.type.index() == declaration_node::object); + + ast_matcher_main_parameter m; + std::get>(d.type)->visit(m, 0); + return m.matched(); + } + + auto handle_function_main(function_type_node& func) -> void + { + func.is_main = true; + + if (!func.parameters->parameters.empty()) { + if (func.parameters->parameters.size() == 1) { + if(!is_valid_parameter_main(*func.parameters->parameters.front())) { + errors.emplace_back(func.position(), + "the function main has one argument but it has the wrong signature"); + } + } else { + errors.emplace_back(func.position(), "the function main may only have one parameter, but it has " + + std::to_string(func.parameters->parameters.size()) + + " parameters"); + } + } + + switch (func.returns.index()) { + break; case function_type_node::id: { + auto &r = std::get(func.returns); + if (*r->get_token() != "int") { + errors.emplace_back(r->get_token()->position(), + "return type of main is " + std::string(*r->get_token()) + " instead of int"); + } + } + break; case function_type_node::empty: + /* DO NOTHING */ + break; case function_type_node::list: + errors.emplace_back(func.position(), "main cannot return a list"); + } + } };