cgen: fix array.insert and arr.prepend

pull/5408/head
yuyi 2020-06-18 06:22:34 +08:00 committed by GitHub
parent 7056f875db
commit 3f01e2b796
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 86 additions and 55 deletions

View File

@ -113,54 +113,40 @@ fn test_push() {
assert a.str() == '[1, 3]' assert a.str() == '[1, 3]'
} }
// TODO array.insert is broken
// Cannot pass literal or primitive type as it cannot be cast to voidptr.
// In the current state only that would work:
// i := 3
// a.insert(0, &i)
// ----------------------------
/*
fn test_insert() { fn test_insert() {
mut a := [1, 2] mut a := [1, 2]
a.insert(0, 3) a.insert(0, 3)
println(a) assert a[0] == 3
assert a[2] == 2
assert a.len == 3
a.insert(1, 4)
assert a[1] == 4
assert a[2] == 1
assert a.len == 4
a.insert(4, 5)
assert a[4] == 5
assert a[3] == 2
assert a.len == 5
mut b := []f64{}
assert b.len == 0
b.insert(0, f64(1.1))
assert b.len == 1
assert b[0] == f64(1.1)
} }
*/
// fn test_insert() { fn test_prepend() {
// mut a := [1, 2] mut a := []int{}
// a.insert(0, 3) assert a.len == 0
// assert a[0] == 3 a.prepend(1)
// assert a[2] == 2 assert a.len == 1
// assert a.len == 3 assert a[0] == 1
// a.insert(1, 4) mut b := []f64{}
// assert a[1] == 4 assert b.len == 0
// assert a[2] == 1 b.prepend(f64(1.1))
// assert a.len == 4 assert b.len == 1
// a.insert(4, 5) assert b[0] == f64(1.1)
// assert a[4] == 5 }
// assert a[3] == 2
// assert a.len == 5
// mut b := []f64{}
// assert b.len == 0
// b.insert(0, f64(1.1))
// assert b.len == 1
// assert b[0] == f64(1.1)
// }
// TODO array.prepend is broken
// It depends on array.insert
// -----------------------------
// fn test_prepend() {
// mut a := []int{}
// assert a.len == 0
// a.prepend(1)
// assert a.len == 1
// assert a[0] == 1
// mut b := []f64{}
// assert b.len == 0
// b.prepend(f64(1.1))
// assert b.len == 1
// assert b[0] == f64(1.1)
// }
fn test_strings() { fn test_strings() {
a := ['a', 'b', 'c'] a := ['a', 'b', 'c']
assert a.str() == "['a', 'b', 'c']" assert a.str() == "['a', 'b', 'c']"

View File

@ -3069,7 +3069,7 @@ fn (mut g Gen) gen_expr_to_string(expr ast.Expr, etype table.Type) ?bool {
} }
// `nums.map(it % 2 == 0)` // `nums.map(it % 2 == 0)`
fn (mut g Gen) gen_map(node ast.CallExpr) { fn (mut g Gen) gen_array_map(node ast.CallExpr) {
tmp := g.new_tmp_var() tmp := g.new_tmp_var()
s := g.go_before_stmt(0) s := g.go_before_stmt(0)
// println('filter s="$s"') // println('filter s="$s"')
@ -3127,7 +3127,7 @@ fn (mut g Gen) gen_map(node ast.CallExpr) {
} }
// `nums.filter(it % 2 == 0)` // `nums.filter(it % 2 == 0)`
fn (mut g Gen) gen_filter(node ast.CallExpr) { fn (mut g Gen) gen_array_filter(node ast.CallExpr) {
tmp := g.new_tmp_var() tmp := g.new_tmp_var()
s := g.go_before_stmt(0) s := g.go_before_stmt(0)
// println('filter s="$s"') // println('filter s="$s"')
@ -3177,6 +3177,38 @@ fn (mut g Gen) gen_filter(node ast.CallExpr) {
g.write(tmp) g.write(tmp)
} }
// `nums.insert(0, 2)`
fn (mut g Gen) gen_array_insert(node ast.CallExpr) {
sym := g.table.get_type_symbol(node.left_type)
if sym.kind != .array {
verror('insert() requires an array')
}
info := sym.info as table.Array
elem_type_str := g.typ(info.elem_type)
g.write('array_insert(&')
g.expr(node.left)
g.write(', ')
g.expr(node.args[0].expr)
g.write(', &($elem_type_str[]){')
g.expr(node.args[1].expr)
g.write('});')
}
// `nums.prepend(2)`
fn (mut g Gen) gen_array_prepend(node ast.CallExpr) {
sym := g.table.get_type_symbol(node.left_type)
if sym.kind != .array {
verror('prepend() requires an array')
}
info := sym.info as table.Array
elem_type_str := g.typ(info.elem_type)
g.write('array_prepend(&')
g.expr(node.left)
g.write(', &($elem_type_str[]){')
g.expr(node.args[0].expr)
g.write('});')
}
[inline] [inline]
fn (g &Gen) nth_stmt_pos(n int) int { fn (g &Gen) nth_stmt_pos(n int) int {
return g.stmt_path_pos[g.stmt_path_pos.len - (1 + n)] return g.stmt_path_pos[g.stmt_path_pos.len - (1 + n)]

View File

@ -359,14 +359,27 @@ fn (mut g Gen) method_call(node ast.CallExpr) {
g.write(')') g.write(')')
return return
} }
if typ_sym.kind == .array && node.name == 'map' { left_sym := g.table.get_type_symbol(node.left_type)
g.gen_map(node) if left_sym.kind == .array {
return match node.name {
} 'filter' {
// rec_sym := g.table.get_type_symbol(node.receiver_type) g.gen_array_filter(node)
if typ_sym.kind == .array && node.name == 'filter' { return
g.gen_filter(node) }
return 'insert' {
g.gen_array_insert(node)
return
}
'map' {
g.gen_array_map(node)
return
}
'prepend' {
g.gen_array_prepend(node)
return
}
else {}
}
} }
if node.name == 'str' { if node.name == 'str' {
mut styp := g.typ(node.receiver_type) mut styp := g.typ(node.receiver_type)
@ -376,7 +389,7 @@ fn (mut g Gen) method_call(node ast.CallExpr) {
g.gen_str_for_type_with_styp(node.receiver_type, styp) g.gen_str_for_type_with_styp(node.receiver_type, styp)
} }
// TODO performance, detect `array` method differently // TODO performance, detect `array` method differently
if typ_sym.kind == .array && node.name in ['repeat', 'sort_with_compare', 'free', 'push_many', if left_sym.kind == .array && node.name in ['repeat', 'sort_with_compare', 'free', 'push_many',
'trim', 'trim',
'first', 'first',
'last', 'last',