cgen: fix cross assign with mutable args (fix #5609 #5610 #5611) (#5614)

pull/5620/head
yuyi 2020-07-02 17:09:26 +08:00 committed by GitHub
parent c21527d3c6
commit 6cbc0e84f0
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 91 additions and 37 deletions

View File

@ -877,16 +877,3 @@ fn test_plus_assign_string() {
a[0] += 'abc'
assert a == ['abc']
}
fn test_cross_assign() {
mut a := [0, 1]
a[0], a[1] = a[1], a[0]
assert a[0] == 1
assert a[1] == 0
mut b1 := [1, 2, 3]
mut b2 := 4
b1[2], b2, b1[0] = b1[0], b1[2], 5
assert b1 == [5, 2, 1]
assert b2 == 3
}

View File

@ -291,7 +291,6 @@ fn test_plus_assign_string() {
assert m['one'] == '1'
}
fn test_map_keys_to_array() {
m := {'a': 'b', 'c': 'd'}
mut arr := []string{}
@ -302,11 +301,3 @@ fn test_map_keys_to_array() {
println(sarr)
assert sarr == "['a', 'c']"
}
fn test_map_cross_assign() {
mut a := {'one':1, 'two':2}
a['one'], a['two'] = a['two'], a['one']
println(a)
assert a['one'] == 2
assert a['two'] == 1
}

View File

@ -1099,6 +1099,9 @@ fn (mut g Gen) gen_assign_stmt(assign_stmt ast.AssignStmt) {
info := sym.info as table.Array
styp := g.typ(info.elem_type)
g.write('$styp _var_$left.pos.pos = *($styp*)array_get(')
if left.left_type.is_ptr() {
g.write('*')
}
g.expr(left.left)
g.write(', ')
g.expr(left.index)
@ -1108,6 +1111,9 @@ fn (mut g Gen) gen_assign_stmt(assign_stmt ast.AssignStmt) {
styp := g.typ(info.value_type)
zero := g.type_default(info.value_type)
g.write('$styp _var_$left.pos.pos = *($styp*)map_get(')
if left.left_type.is_ptr() {
g.write('*')
}
g.expr(left.left)
g.write(', ')
g.expr(left.index)
@ -1118,7 +1124,11 @@ fn (mut g Gen) gen_assign_stmt(assign_stmt ast.AssignStmt) {
styp := g.typ(left.typ)
g.write('$styp _var_$left.pos.pos = ')
g.expr(left.expr)
g.writeln('.$left.field_name;')
if left.expr_type.is_ptr() {
g.writeln('->$left.field_name;')
} else {
g.writeln('.$left.field_name;')
}
}
else {}
}

View File

@ -0,0 +1,80 @@
// Test cross assign of array elements
fn test_cross_assign_of_array() {
mut a := [0, 1]
a[0], a[1] = a[1], a[0]
assert a[0] == 1
assert a[1] == 0
mut b1 := [1, 2, 3]
mut b2 := 4
b1[2], b2, b1[0] = b1[0], b1[2], 5
assert b1 == [5, 2, 1]
assert b2 == 3
}
// Test cross assign of array elements in function
fn foo1(mut arr []int) {
arr[0], arr[1] = arr[1], arr[0]
}
fn test_cross_assign_of_array_in_fn() {
mut arr := [1,2]
foo1(mut arr)
assert arr[0] == 2
assert arr[1] == 1
}
// Test cross assign of map values
fn test_cross_assign_of_map() {
mut a := {'one':1, 'two':2}
a['one'], a['two'] = a['two'], a['one']
println(a)
assert a['one'] == 2
assert a['two'] == 1
}
// Test cross assign of map values in function
fn foo2(mut a map[string]int) {
a['one'], a['two'] = a['two'], a['one']
}
fn test_cross_assign_of_map_in_fn() {
mut a := {'one':1, 'two':2}
foo2(mut a)
assert a['one'] == 2
assert a['two'] == 1
}
// Test cross assign of struct fields
struct Zoo {
mut:
a int
b int
}
fn test_cross_assign_of_struct() {
mut x := Zoo{a:1, b:2}
x.a, x.b = x.b, x.a
//println(x)
assert x.a == 2
assert x.b == 1
}
// Test cross assign of struct fields in function
struct Foo {
mut:
a int
b int
}
fn foo3(mut f &Foo) {
f.a, f.b = f.b, f.a
}
fn test_cross_assign_of_struct_in_fn() {
mut a := Foo{a:1, b:2}
foo3(mut a)
println(a)
assert a.a == 2
assert a.b == 1
}

View File

@ -313,17 +313,3 @@ fn test_struct_with_default_values_no_init() {
assert s2.field_optional == 3
assert s3.field_optional == 2
}
struct Zoo {
mut:
a int
b int
}
fn test_struct_field_cross_assign() {
mut x := Zoo{a:1, b:2}
x.a, x.b = x.b, x.a
//println(x)
assert x.a == 2
assert x.b == 1
}