From 9c0758639bfe75a01664a3e88b5014d64eec1cb3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Uwe=20Kr=C3=BCger?= <45282134+UweKrueger@users.noreply.github.com> Date: Wed, 23 Sep 2020 06:05:12 +0200 Subject: [PATCH] cgen: fix `for match {...} {` and `for select {...} {` (#6441) --- vlib/v/checker/checker.v | 1 + vlib/v/gen/cgen.v | 13 +++++--- vlib/v/tests/for_loops_2_test.v | 55 +++++++++++++++++++++++++++++++++ 3 files changed, 64 insertions(+), 5 deletions(-) create mode 100644 vlib/v/tests/for_loops_2_test.v diff --git a/vlib/v/checker/checker.v b/vlib/v/checker/checker.v index 29de12d9a3..daf06e82d6 100644 --- a/vlib/v/checker/checker.v +++ b/vlib/v/checker/checker.v @@ -2295,6 +2295,7 @@ fn (mut c Checker) stmt(node ast.Stmt) { } ast.ForStmt { c.in_for_count++ + c.expected_type = table.bool_type typ := c.expr(node.cond) if !node.is_inf && typ.idx() != table.bool_type_idx && !c.pref.translated { c.error('non-bool used as for condition', node.pos) diff --git a/vlib/v/gen/cgen.v b/vlib/v/gen/cgen.v index b791f24994..1c53bf5c7b 100644 --- a/vlib/v/gen/cgen.v +++ b/vlib/v/gen/cgen.v @@ -897,13 +897,15 @@ fn (mut g Gen) stmt(node ast.Stmt) { ast.ForStmt { g.write_v_source_line_info(node.pos) g.is_vlines_enabled = false - g.write('while (') - if node.is_inf { - g.write('1') - } else { + g.writeln('for (;;) {') + if !node.is_inf { + g.indent++ + g.stmt_path_pos << g.out.len + g.write('if (!(') g.expr(node.cond) + g.writeln(')) break;') + g.indent-- } - g.writeln(') {') g.is_vlines_enabled = true g.stmts(node.stmts) g.writeln('}') @@ -2888,6 +2890,7 @@ fn (mut g Gen) select_expr(node ast.SelectExpr) { } g.writeln('}') if is_expr { + g.empty_line = false g.write(cur_line) g.write('($select_result != -2)') } diff --git a/vlib/v/tests/for_loops_2_test.v b/vlib/v/tests/for_loops_2_test.v new file mode 100644 index 0000000000..8db5c284c8 --- /dev/null +++ b/vlib/v/tests/for_loops_2_test.v @@ -0,0 +1,55 @@ +fn test_for_match() { + mut a := 2 + mut b := 0 + for match a { + 2 { + println('a == 2') + a = 0 + true + } + 0 { + println('a == 0') + a = 5 + false + } + else { + println('unexpected branch') + false + } + } { + b++ + println('${b}. run') + } + assert a == 5 + assert b == 1 +} + +fn test_for_select() { + ch1 := chan int{} + ch2 := chan f64{} + go do_send(ch1, ch2) + mut a := 0 + mut b := 0 + for select { + x := <-ch1 { + a += x + } + y := <- ch2 { + a += int(y) + } + } { + // count number of receive events + b++ + println('${b}. event') + } + assert a == 10 + assert b == 3 +} + +fn do_send(ch1 chan int, ch2 chan f64) { + ch1 <- 3 + ch2 <- 5.0 + ch2.close() + ch1 <- 2 + ch1.close() +}