Skip to content

Commit b34f23a

Browse files
committed
Allow single-argument global main that gets a vector<string_view>, closes #262
1 parent a6e383b commit b34f23a

File tree

7 files changed

+58
-4
lines changed

7 files changed

+58
-4
lines changed

include/cpp2util.h

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -203,6 +203,7 @@
203203
#include <memory>
204204
#include <string>
205205
#include <string_view>
206+
#include <vector>
206207
#include <iostream>
207208
#include <variant>
208209
#include <any>
@@ -1408,6 +1409,21 @@ inline auto to_string(std::tuple<Ts...> const& t) -> std::string
14081409
}
14091410

14101411

1412+
//-----------------------------------------------------------------------
1413+
//
1414+
// args: see main() arguments as vector<string_view>
1415+
//
1416+
//-----------------------------------------------------------------------
1417+
//
1418+
auto args(int argc, char **argv) -> std::vector<std::string_view> {
1419+
auto ret = std::vector<std::string_view>{(size_t)argc};
1420+
for (auto i = 0; i < argc; ++i) {
1421+
ret[i] = std::string_view{argv[i]};
1422+
}
1423+
return ret;
1424+
}
1425+
1426+
14111427
//-----------------------------------------------------------------------
14121428
//
14131429
// Speculative: RAII wrapping for the C standard library

regression-tests/mixed-fixed-type-aliases.cpp2

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,10 +12,13 @@ test: (x:_) = {
1212
<< "\n";
1313
}
1414

15-
main: (argc: int, argv: **char) -> int = {
15+
main: (args) -> int = {
1616
y: my::u16 = 42;
1717
test(y);
1818

1919
z: u16 = 42;
2020
test(z);
21+
22+
for args do :(arg) =
23+
std::cout << arg << "\n";
2124
}
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,3 @@
11
true
22
false
3+
./test.exe
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,3 @@
11
true
22
false
3+
./test.exe

regression-tests/test-results/mixed-fixed-type-aliases.cpp

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ namespace my {
1313
#line 8 "mixed-fixed-type-aliases.cpp2"
1414
auto test(auto const& x) -> void;
1515
#line 15 "mixed-fixed-type-aliases.cpp2"
16-
[[nodiscard]] auto main(cpp2::in<int> argc, cpp2::in<char**> argv) -> int;
16+
[[nodiscard]] auto main(int argc, char **argv) -> int;
1717

1818
//=== Cpp2 definitions ==========================================================
1919

@@ -26,11 +26,16 @@ auto test(auto const& x) -> void{
2626
<< "\n";
2727
}
2828

29-
[[nodiscard]] auto main(cpp2::in<int> argc, cpp2::in<char**> argv) -> int{
29+
[[nodiscard]] auto main(int argc, char **argv) -> int{
30+
auto args = cpp2::args(argc, argv);
31+
#line 16 "mixed-fixed-type-aliases.cpp2"
3032
my::u16 y {42};
3133
test(std::move(y));
3234

3335
cpp2::u16 z {42};
3436
test(std::move(z));
37+
38+
for ( auto const& cpp2_range = args; auto const& arg : cpp2_range )
39+
std::cout << arg << "\n";
3540
}
3641

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,3 @@
11
true
22
false
3+
test.exe

source/cppfront.cpp

Lines changed: 28 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2962,7 +2962,34 @@ class cppfront
29622962
auto emit(function_type_node const& n, token const* ident, bool is_main) -> void
29632963
{
29642964
assert(n.parameters);
2965-
emit(*n.parameters);
2965+
if (is_main && n.parameters->parameters.size() == 1) {
2966+
auto& param1 = *n.parameters->parameters[0];
2967+
auto param1_name = param1.declaration->identifier->get_token()->to_string(true);
2968+
if (param1.pass != passing_style::in ||
2969+
param1.declaration->type.index() != declaration_node::object ||
2970+
!std::get<declaration_node::object>(param1.declaration->type)->is_wildcard()
2971+
)
2972+
{
2973+
// we don't currently bail right after emitting the declarations (because
2974+
// we don't necessarily want to hide other interesting errors), so this
2975+
// avoids emitting the error a second time when we emit the definitions
2976+
static auto once = true;
2977+
if (std::exchange(once, false)) {
2978+
errors.emplace_back(
2979+
param1.position(),
2980+
"when 'main' has a single parameter, that parameter should be declared as just: main: (" + param1_name + ") - the type 'std::vector<std::string_view>' will be deduced"
2981+
);
2982+
}
2983+
return;
2984+
}
2985+
printer.print_cpp2( "(int argc, char **argv)", n.parameters->position() );
2986+
current_function.back().prolog.push_back(
2987+
"auto " + param1_name + " = cpp2::args(argc, argv); "
2988+
);
2989+
}
2990+
else {
2991+
emit(*n.parameters);
2992+
}
29662993

29672994
// Add implicit noexcept when we implement proper EH
29682995
// to handle calling Cpp1 code that throws

0 commit comments

Comments
 (0)