map: fix m[a]++ etc

pull/5489/head
yuyi 2020-06-25 02:41:26 +08:00 committed by GitHub
parent 955c0b1576
commit 67d9d94fb3
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 69 additions and 10 deletions

View File

@ -359,6 +359,25 @@ fn (m map) get3(key string, zero voidptr) voidptr {
return zero
}
fn (mut m map) get2(key string, zero voidptr) voidptr {
for {
mut index,mut meta := m.key_to_index(key)
for {
if meta == m.metas[index] {
kv_index := m.metas[index + 1]
if fast_string_eq(key, m.key_values.keys[kv_index]) {
return voidptr(m.key_values.values + kv_index * u32(m.value_bytes))
}
}
index += 2
meta += probe_inc
if meta > m.metas[index] { break }
}
// set zero if not found
m.set(key, zero)
}
}
fn (m map) exists(key string) bool {
mut index,mut meta := m.key_to_index(key)
for {

View File

@ -239,13 +239,40 @@ fn test_map_assign() {
's': u16(5)
't': 3
}
d := Mstruct1 {
_ := Mstruct1 {
{ 'p': 12 }
}
e := Mstruct2 {
_ := Mstruct2 {
{ 'q': 1.7 }
}
f := Mstruct3 {
_ := Mstruct3 {
{ 'r': u16(6), 's': 5 }
}
}
fn test_postfix_op_directly() {
mut a := map[string]int
a['aaa']++
assert a['aaa'] == 1
a['aaa']++
assert a['aaa'] == 2
a['bbb']--
assert a['bbb'] == -1
a['bbb']--
assert a['bbb'] == -2
}
fn test_map_push_directly() {
mut a := map[string][]string
a['aaa'] << ['a', 'b', 'c']
assert a['aaa'].len == 3
assert a['aaa'] == ['a', 'b', 'c']
}
fn test_assign_directly() {
mut a := map[string]int
a['aaa'] += 4
assert a['aaa'] == 4
a['aaa'] -= 2
assert a['aaa'] == 2
}

View File

@ -60,6 +60,8 @@ mut:
is_sql bool // Inside `sql db{}` statement, generating sql instead of C (e.g. `and` instead of `&&` etc)
optionals []string // to avoid duplicates TODO perf, use map
inside_ternary int // ?: comma separated statements on a single line
inside_map_postfix bool // inside map++/-- postfix expr
inside_map_infix bool // inside map<</+=/-= infix expr
ternary_names map[string]string
ternary_level_names map[string][]string
stmt_path_pos []int
@ -1485,7 +1487,13 @@ fn (mut g Gen) expr(node ast.Expr) {
g.index_expr(node)
}
ast.InfixExpr {
g.infix_expr(node)
if node.op in [.left_shift, .plus_assign, .minus_assign] {
g.inside_map_infix = true
g.infix_expr(node)
g.inside_map_infix = false
} else {
g.infix_expr(node)
}
}
ast.IntegerLiteral {
if node.val.starts_with('0o') {
@ -1530,7 +1538,9 @@ fn (mut g Gen) expr(node ast.Expr) {
g.write(')')
}
ast.PostfixExpr {
g.inside_map_postfix = true
g.expr(node.expr)
g.inside_map_postfix = false
g.write(node.op.str())
}
ast.PrefixExpr {
@ -2232,14 +2242,17 @@ fn (mut g Gen) index_expr(node ast.IndexExpr) {
g.write(', ')
g.expr(node.index)
g.write(', &($elem_type_str[]) { ')
} else {
/*
} else if g.inside_map_postfix || g.inside_map_infix {
zero := g.type_default(info.value_type)
g.write('(*($elem_type_str*)map_get2(')
if !left_is_ptr {
g.write('&')
}
g.expr(node.left)
g.write(', ')
g.expr(node.index)
g.write('))')
*/
g.write(', ')
g.expr(node.index)
g.write(', &($elem_type_str[]){ $zero }))\n')
} else {
zero := g.type_default(info.value_type)
g.write('(*($elem_type_str*)map_get3(')
g.expr(node.left)