v.gen.js: fix prefix, postfix and assign codegen and add more array tests (#11031)

pull/11039/head
playX 2021-08-03 14:59:46 +03:00 committed by GitHub
parent 0ebad47d2a
commit 0455632b1f
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 164 additions and 8 deletions

View File

@ -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 {

View File

@ -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]

View File

@ -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)
}
}