From 0455632b1f07c8219356c888682ebb33cbc784b7 Mon Sep 17 00:00:00 2001 From: playX Date: Tue, 3 Aug 2021 14:59:46 +0300 Subject: [PATCH] v.gen.js: fix prefix, postfix and assign codegen and add more array tests (#11031) --- vlib/v/gen/js/js.v | 72 +++++++++++++++++++++-- vlib/v/gen/js/tests/testdata/array.out | 20 ++++++- vlib/v/gen/js/tests/testdata/array.v | 80 ++++++++++++++++++++++++++ 3 files changed, 164 insertions(+), 8 deletions(-) diff --git a/vlib/v/gen/js/js.v b/vlib/v/gen/js/js.v index 6ec623e2eb..f7dfddbce2 100644 --- a/vlib/v/gen/js/js.v +++ b/vlib/v/gen/js/js.v @@ -677,7 +677,11 @@ fn (mut g JsGen) expr(node ast.Expr) { } ast.PostfixExpr { g.expr(node.expr) - g.write(node.op.str()) + if node.op in [.inc, .dec] { + g.write('.val $node.op') + } else { + g.write(node.op.str()) + } } ast.PrefixExpr { if node.op in [.amp, .mul] { @@ -699,10 +703,16 @@ fn (mut g JsGen) expr(node ast.Expr) { } } else { g.write(node.op.str()) - g.write('(') - g.expr(node.right) - g.write('.valueOf()') - g.write(')') + + if node.op in [.inc, .dec] { + g.expr(node.right) + g.write('.val ') + } else { + g.write('(') + g.expr(node.right) + g.write('.valueOf()') + g.write(')') + } } } ast.RangeExpr { @@ -820,6 +830,10 @@ fn (mut g JsGen) gen_assign_stmt(stmt ast.AssignStmt) { if stmt.op == .decl_assign { op = .assign } + is_assign := stmt.op in [.plus_assign, .minus_assign, .mult_assign, .div_assign, + .xor_assign, .mod_assign, .or_assign, .and_assign, .right_shift_assign, + .left_shift_assign, + ] val := stmt.right[i] mut is_mut := false if left is ast.Ident { @@ -859,7 +873,49 @@ fn (mut g JsGen) gen_assign_stmt(stmt ast.AssignStmt) { } g.write(')') } else { - g.write(' $op ') + if is_assign { + g.write('.val') + g.write(' = ') + g.expr(left) + + match op { + .plus_assign { + g.write(' + ') + } + .minus_assign { + g.write(' - ') + } + .mult_assign { + g.write(' * ') + } + .div_assign { + g.write(' / ') + } + .mod_assign { + g.write(' % ') + } + .xor_assign { + g.write(' ^ ') + } + .and_assign { + g.write(' & ') + } + .right_shift_assign { + g.write(' << ') + } + .left_shift_assign { + g.write(' >> ') + } + .or_assign { + g.write(' | ') + } + else { + panic('unexpected op $op') + } + } + } else { + g.write(' $op ') + } // TODO: Multiple types?? should_cast := (g.table.type_kind(stmt.left_types.first()) in js.shallow_equatables) @@ -1768,6 +1824,7 @@ fn (mut g JsGen) gen_infix_expr(it ast.InfixExpr) { g.write(g.typ(it.right_type)) } else { is_arithmetic := it.op in [token.Kind.plus, .minus, .mul, .div, .mod] + mut needs_cast := is_arithmetic && it.left_type != it.right_type mut greater_typ := 0 // todo(playX): looks like this cast is always required to perform .eq operation on types. @@ -1785,8 +1842,11 @@ fn (mut g JsGen) gen_infix_expr(it ast.InfixExpr) { g.write('${g.typ(greater_typ)}(') g.cast_stack << greater_typ } + g.expr(it.left) + g.write(' $it.op ') + g.expr(it.right) if true || needs_cast { diff --git a/vlib/v/gen/js/tests/testdata/array.out b/vlib/v/gen/js/tests/testdata/array.out index b375fcb7cf..64f10c6467 100644 --- a/vlib/v/gen/js/tests/testdata/array.out +++ b/vlib/v/gen/js/tests/testdata/array.out @@ -3,8 +3,8 @@ 2 4 255 -256 -2 +1 +512 4 131 4 @@ -229,3 +229,19 @@ true 0 1 79 +[0,1,15,27,38,50,79] +[0,1,15,27,38,50,79] +3 +[14,2,3] +test b +[true,false,true] +1,1 +2,2 +3,3 +4,4 +1,1 +2,2 +3,3 +4,4 +6 +[2,0,2,2] diff --git a/vlib/v/gen/js/tests/testdata/array.v b/vlib/v/gen/js/tests/testdata/array.v index 8ef56bc19f..86ab5ad938 100644 --- a/vlib/v/gen/js/tests/testdata/array.v +++ b/vlib/v/gen/js/tests/testdata/array.v @@ -15,6 +15,11 @@ struct User { name string } +struct Foo { +mut: + bar []int +} + fn map_test_helper_1(i int) int { return i * i } @@ -768,4 +773,79 @@ fn main() { println(f[1]) println(f[6]) } + { + // test f64 sort + mut f := [50.0, 15, 1, 79, 38, 0, 27] + f.sort() + println(f) + assert f[0] == 0.0 + assert f[1] == 1.0 + assert f[6] == 79.0 + } + { + // test i64 sort + mut f := [i64(50), 15, 1, 79, 38, 0, 27] + f.sort() + println(f) + assert f[0] == 0 + assert f[1] == 1 + assert f[6] == 79 + } + { + // test in struct + + mut baz := Foo{ + bar: [0, 0, 0] + } + baz.bar[0] += 2 + baz.bar[0]++ + println(baz.bar[0]) + } + { + // test direct modification + mut foo := [2, 0, 5] + foo[1] = 3 + foo[0] *= 7 + foo[1]-- + foo[2] -= 2 + println(foo) + } + { + // test bools + println('test b') + mut a := [true, false] + a << true + println(a) + } + { + // test push many self + mut actual_arr := [1, 2, 3, 4] + actual_arr << actual_arr + expected_arr := [1, 2, 3, 4, 1, 2, 3, 4] + assert actual_arr.len == expected_arr.len + for i in 0 .. actual_arr.len { + print(actual_arr[i]) + print(',') + println(expected_arr[i]) + } + } + { + // test for + nums := [1, 2, 3] + mut sum := 0 + for num in nums { + sum += num + } + println(sum) + } + { + // test left shift precedence + + mut arr := []int{} + arr << 1 + 1 + arr << 1 - 1 + arr << 2 / 1 + arr << 2 * 1 + println(arr) + } }