Skip to content

Commit

Permalink
Add statement (including block) scope in/inout parameters, and apply …
Browse files Browse the repository at this point in the history
…that syntax to `for` (remove `:` and `=`), closes #386
  • Loading branch information
hsutter committed Apr 23, 2023
1 parent 1886ed2 commit 928186e
Show file tree
Hide file tree
Showing 26 changed files with 241 additions and 97 deletions.
4 changes: 2 additions & 2 deletions regression-tests/mixed-bounds-safety-with-assert-2.cpp2
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ main: () -> int = {
v: std::vector<int> = (1, 2, 3, 4, 5);
add_42_to_subrange(v, 1, 3);

for v do :(i) =
for v do (i)
std::cout << i << "\n";
}

Expand All @@ -15,7 +15,7 @@ add_42_to_subrange: (inout rng:_, start:int, end:int)
count := 0;
for rng
next count++
do :(inout i) =
do (inout i)
if start <= count <= end {
i += 42;
}
Expand Down
2 changes: 1 addition & 1 deletion regression-tests/mixed-bounds-safety-with-assert.cpp2
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ print_subrange: (rng:_, start:int, end:int) = {
count := 0;
for rng
next count++
do: (i:_) =
do (i)
if start <= count && count <= end {
std::cout << i << "\n";
}
Expand Down
2 changes: 1 addition & 1 deletion regression-tests/mixed-fixed-type-aliases.cpp2
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,6 @@ main: (args) -> int = {
z: u16 = 42;
test(z);

for args do :(arg) =
for args do (arg)
std::cout << arg << "\n";
}
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ main: () -> int = {
callback
);

for view do :(str:_) = {
for view do (str) {
std::cout << str << "\n";
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
#include <iostream>

main: () -> int = {
vec: std::vector<std::string>
vec: std::vector<std::string>
= ("hello", "2022");
view: std::span = vec;

Expand All @@ -17,6 +17,6 @@ main: () -> int = {
callback := :(inout x:_) = x += "-ish";
std::ranges::for_each( view, callback );

for view do :(str:_) =
for view do (str)
std::cout << str << "\n";
}
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
#include <iostream>

main: () -> int = {
vec: std::vector<std::string>
vec: std::vector<std::string>
= ("hello", "2022");
view: std::span = vec;

Expand All @@ -16,6 +16,6 @@ main: () -> int = {
callback := :(inout x:_) = x += "-ish";
std::ranges::for_each( view, callback );

for view do :(str:_) =
for view do (str)
std::cout << str << "\n";
}
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
#include <iostream>

main: () -> int = {
vec: std::vector<std::string>
vec: std::vector<std::string>
= ("hello", "2023");
view: std::span = vec;

Expand All @@ -18,6 +18,6 @@ main: () -> int = {
callback := :(inout x:_) = x += "-ish";
std::ranges::for_each( view, callback );

for view do :(str:_) =
for view do (str)
std::cout << str << "\n";
}
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
#include <iostream>

main: () -> int = {
vec: std::vector<std::string>
vec: std::vector<std::string>
= ("hello", "2022");
view: std::span = vec;

Expand All @@ -17,6 +17,6 @@ main: () -> int = {
callback := :(inout x:_) = x += "-ish";
std::ranges::for_each( view, callback );

for view do :(str:_) =
for view do (str)
std::cout << str << "\n";
}
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ main: () -> int
= {
v: std::vector<int> = (1, 2, 3, 4, 5);
counter := 42;
for v next counter *= 2 do: (i:_) = {
for v next counter *= 2 do (i) {
std::cout << i << " " << counter << "\n";
}
}
Expand Down
16 changes: 8 additions & 8 deletions regression-tests/pure2-break-continue.cpp2
Original file line number Diff line number Diff line change
Expand Up @@ -161,9 +161,9 @@ for_continue_inner: () =
{
vi: std::vector = ( 0, 1, 2 );
counter := 0;
for vi next counter++ do :(i) = {
for vi next counter++ do (i) {
vj: std::vector = ( 0, 1, 2 );
inner: for vj do :(j) = {
inner: for vj do (j) {
std::cout << i << j << " ";
if j == 1 {
continue inner;
Expand All @@ -179,9 +179,9 @@ for_continue_outer: () =
{
vi: std::vector = ( 0, 1, 2 );
counter := 0;
outer: for vi next counter++ do :(i) = {
outer: for vi next counter++ do (i) {
vj: std::vector = ( 0, 1, 2 );
for vj do :(j) = {
for vj do (j) {
std::cout << i << j << " ";
if j == 1 {
continue outer;
Expand All @@ -197,9 +197,9 @@ for_break_inner: () =
{
vi: std::vector = ( 0, 1, 2 );
counter := 0;
for vi next counter++ do :(i) = {
for vi next counter++ do (i) {
vj: std::vector = ( 0, 1, 2 );
inner: for vj do :(j) = {
inner: for vj do (j) {
std::cout << i << j << " ";
if j == 1 {
break inner;
Expand All @@ -215,9 +215,9 @@ for_break_outer: () =
{
vi: std::vector = ( 0, 1, 2 );
counter := 0;
outer: for vi next counter++ do :(i) = {
outer: for vi next counter++ do (i) {
vj: std::vector = ( 0, 1, 2 );
for vj do :(j) = {
for vj do (j) {
std::cout << i << j << " ";
if j == 1 {
break outer;
Expand Down
10 changes: 5 additions & 5 deletions regression-tests/pure2-intro-example-hello-2022.cpp2
Original file line number Diff line number Diff line change
@@ -1,21 +1,21 @@
main: () -> int = {
vec: std::vector<std::string>
vec: std::vector<std::string>
= ("hello", "2022");
view: std::span = vec;

for view do :(inout str:_) = {
for view do (inout str) {
len := decorate(str);
println(str, len);
}
}

decorate: (inout thing: _ ) -> int = {
decorate: (inout thing: _ ) -> int = {
thing = "[" + thing + "]";
return thing.ssize();
}

println: (x: _, len: _) =
std::cout
<< ">> " << x
<< " - length "
<< ">> " << x
<< " - length "
<< len << "\n";
2 changes: 1 addition & 1 deletion regression-tests/pure2-intro-example-three-loops.cpp2
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ main: () -> int = {
} while i* > 1 next i*--;

std::cout << "\n";
for words do: (inout word:_) =
for words do (inout word)
decorate_and_print(word);

print( : std::string = "end of program" );
Expand Down
15 changes: 15 additions & 0 deletions regression-tests/pure2-statement-scope-parameters.cpp2
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@

main: (args) = {
local_int := 42;

// 'in' (read-only) statement scope variable
(i := local_int) for args do (arg) {
std::cout << i << "\n"; // prints 42
}

// 'inout' (read-write) statement scope variable
(inout i := local_int) {
i++;
}
std::cout << local_int << "\n"; // prints 43
}
2 changes: 1 addition & 1 deletion regression-tests/pure2-type-and-namespace-aliases.cpp2
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ myfunc: () = {

v2 :== v;

for v2 do :(s) =
for v2 do (s)
std::cout << "(s)$\n";
}

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
42
43
Empty file.
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
42
43
Empty file.
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ auto add_42_to_subrange(auto& rng, cpp2::in<int> start, cpp2::in<int> end) -> vo
auto count {0};
for ( auto&& cpp2_range = rng;

auto& i : cpp2_range ) { do
auto& i : cpp2_range ) { do
if ([_0 = start, _1 = count, _2 = end]{ return cpp2::cmp_less_eq(_0,_1) && cpp2::cmp_less_eq(_1,_2); }()) {
i += 42;
} while (false); ++count; }
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
42
43
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
pure2-statement-scope-parameters.cpp
47 changes: 47 additions & 0 deletions regression-tests/test-results/pure2-statement-scope-parameters.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@

#define CPP2_USE_MODULES Yes

//=== Cpp2 type declarations ====================================================


#include "cpp2util.h"



//=== Cpp2 type definitions and function declarations ===========================


#line 2 "pure2-statement-scope-parameters.cpp2"
auto main(int const argc_, char const* const* const argv_) -> int;


//=== Cpp2 function definitions =================================================


#line 2 "pure2-statement-scope-parameters.cpp2"
auto main(int const argc_, char const* const* const argv_) -> int{
auto args = cpp2::make_args(argc_, argv_);
#line 3 "pure2-statement-scope-parameters.cpp2"
auto local_int {42};
{
auto const& i = local_int;

// 'in' (read-only) statement scope variable
#line 6 "pure2-statement-scope-parameters.cpp2"
for ( auto const& cpp2_range = args; auto const& arg : cpp2_range ) {
std::cout << i << "\n"; // prints 42
}
}
{
auto& i = local_int;

// 'inout' (read-write) statement scope variable
#line 11 "pure2-statement-scope-parameters.cpp2"
{
++i;
}
}
#line 14 "pure2-statement-scope-parameters.cpp2"
std::cout << std::move(local_int) << "\n";// prints 43
}

Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
pure2-statement-scope-parameters.cpp2... ok (all Cpp2, passes safety checks)

Loading

4 comments on commit 928186e

@JohelEGP
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is an empty statement parameter list intentional?
I hope to take advantage of it in a metafunction.
See https://cpp2.godbolt.org/z/EqPsT68dz:

main: () = {
  () _ = 0;
}
#line 1 "/app/example.cpp2"
auto main() -> int{
{
#line 2 "/app/example.cpp2"
  static_cast<void>(0);
}
#line 3 "/app/example.cpp2"
}

@hsutter
Copy link
Owner Author

@hsutter hsutter commented on 928186e Jan 4, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@JohelEGP Sorry for the delay -- I just usually allow empty paren-lists in general, and I don't think I thought about that case either way here in particular because I just didn't think about examples like that. If you have a use for it I'm happy to let it stand and be cited as a curiosity in 'obfuscated code' contests 😁

@JohelEGP
Copy link
Contributor

@JohelEGP JohelEGP commented on 928186e Jan 4, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Here's some more detail on the use case.
I was generating statement parameters in the for loop of @array.
I noticed that, sometimes, the parameter list was empty.
So I started to wonder whether it was something I could rely on.
I have since refactored @array to not have that parameter list.

@hsutter
Copy link
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

OK, I'll just leave it alone and let it stand for now. I don't see a reason to remove it... I don't think there's a surprising parse the way things are parsed right now (if there is one then we should reconsider this of course).

Please sign in to comment.