cgen: use voidptr key methods: map_get_1, map_set_1, map_get_and_set_1 (#7390)

pull/7405/head^2
Nick Treleaven 2020-12-18 23:05:16 +00:00 committed by GitHub
parent 6854ba27e2
commit 042449cd3d
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 49 additions and 28 deletions

View File

@ -458,7 +458,7 @@ fn (m map) get(key string, zero voidptr) voidptr {
// If `key` matches the key of an element in the container,
// the method returns a reference to its mapped value.
// If not, a zero/default value is returned.
fn (m map) get_1(key voidptr, zero voidptr) voidptr {
fn (m &map) get_1(key voidptr, zero voidptr) voidptr {
mut index, mut meta := m.key_to_index(key)
for {
if meta == unsafe {m.metas[index]} {
@ -482,7 +482,7 @@ fn (m map) exists(key string) bool {
}
// Checks whether a particular key exists in the map.
fn (m map) exists_1(key voidptr) bool {
fn (m &map) exists_1(key voidptr) bool {
mut index, mut meta := m.key_to_index(key)
for {
if meta == unsafe {m.metas[index]} {

View File

@ -1714,16 +1714,20 @@ fn (mut g Gen) gen_assign_stmt(assign_stmt ast.AssignStmt) {
left_type := assign_stmt.left_types[i]
left_sym := g.table.get_type_symbol(left_type)
g.write_fn_ptr_decl(left_sym.info as table.FnType, '_var_$left.pos.pos')
g.write(' = *(voidptr*)map_get(')
g.write(' = *(voidptr*)map_get_1(')
} else {
g.write('$styp _var_$left.pos.pos = *($styp*)map_get(')
g.write('$styp _var_$left.pos.pos = *($styp*)map_get_1(')
}
if left.left_type.is_ptr() {
g.write('*')
if !left.left_type.is_ptr() {
g.write('ADDR(map, ')
g.expr(left.left)
g.write(')')
} else {
g.expr(left.left)
}
g.expr(left.left)
g.write(', ')
g.write(', &(string[]){')
g.expr(left.index)
g.write('}')
if val_typ.kind == .function {
g.writeln(', &(voidptr[]){ $zero });')
} else {
@ -3843,9 +3847,9 @@ fn (mut g Gen) index_expr(node ast.IndexExpr) {
if g.is_assign_lhs && !g.is_array_set && !get_and_set_types {
if g.assign_op == .assign || info.value_type == table.string_type {
g.is_array_set = true
g.write('map_set(')
g.write('map_set_1(')
} else {
g.write('*(($elem_type_str*)map_get_and_set(')
g.write('*(($elem_type_str*)map_get_and_set_1(')
}
if !left_is_ptr || node.left_type.has_flag(.shared_f) {
g.write('&')
@ -3858,8 +3862,9 @@ fn (mut g Gen) index_expr(node ast.IndexExpr) {
g.write('.val')
}
}
g.write(', ')
g.write(', &(string[]){')
g.expr(node.index)
g.write('}')
if elem_typ.kind == .function {
g.write(', &(voidptr[]) { ')
} else {
@ -3872,31 +3877,34 @@ fn (mut g Gen) index_expr(node ast.IndexExpr) {
} else if (g.inside_map_postfix || g.inside_map_infix) ||
(g.is_assign_lhs && !g.is_array_set && get_and_set_types) {
zero := g.type_default(info.value_type)
g.write('(*($elem_type_str*)map_get_and_set(')
g.write('(*($elem_type_str*)map_get_and_set_1(')
if !left_is_ptr {
g.write('&')
}
g.expr(node.left)
g.write(', ')
g.write(', &(string[]){')
g.expr(node.index)
g.write(', &($elem_type_str[]){ $zero }))')
g.write('}, &($elem_type_str[]){ $zero }))')
} else {
zero := g.type_default(info.value_type)
if g.is_fn_index_call {
if elem_typ.info is table.FnType {
g.write('((')
g.write_fn_ptr_decl(&elem_typ.info, '')
g.write(')(*(voidptr*)map_get(')
g.write(')(*(voidptr*)map_get_1(')
}
} else if elem_typ.kind == .function {
g.write('(*(voidptr*)map_get(')
g.write('(*(voidptr*)map_get_1(')
} else {
g.write('(*($elem_type_str*)map_get(')
g.write('(*($elem_type_str*)map_get_1(')
}
if node.left_type.is_ptr() && !node.left_type.has_flag(.shared_f) {
g.write('*')
if !left_is_ptr || node.left_type.has_flag(.shared_f) {
g.write('ADDR(map, ')
g.expr(node.left)
} else {
g.write('(')
g.expr(node.left)
}
g.expr(node.left)
if node.left_type.has_flag(.shared_f) {
if left_is_ptr {
g.write('->val')
@ -3904,8 +3912,9 @@ fn (mut g Gen) index_expr(node ast.IndexExpr) {
g.write('.val')
}
}
g.write(', ')
g.write('), &(string[]){')
g.expr(node.index)
g.write('}')
if g.is_fn_index_call {
g.write(', &(voidptr[]){ $zero })))')
} else if elem_typ.kind == .function {
@ -4546,14 +4555,14 @@ fn (mut g Gen) gen_map_equality_fn(left table.Type) string {
g.definitions.write(', ')
}
}
g.definitions.writeln(') = (*(voidptr*)map_get(a, k, &(voidptr[]){ 0 }));')
g.definitions.writeln(') = (*(voidptr*)map_get_1(&a, &k, &(voidptr[]){ 0 }));')
} else {
g.definitions.writeln('\t\t$value_typ v = (*($value_typ*)map_get(a, k, &($value_typ[]){ 0 }));')
g.definitions.writeln('\t\t$value_typ v = (*($value_typ*)map_get_1(&a, &k, &($value_typ[]){ 0 }));')
}
match value_sym.kind {
.string { g.definitions.writeln('\t\tif (!map_exists(b, k) || string_ne((*($value_typ*)map_get(b, k, &($value_typ[]){_SLIT("")})), v)) {') }
.function { g.definitions.writeln('\t\tif (!map_exists(b, k) || (*(voidptr*)map_get(b, k, &(voidptr[]){ 0 })) != v) {') }
else { g.definitions.writeln('\t\tif (!map_exists(b, k) || (*($value_typ*)map_get(b, k, &($value_typ[]){ 0 })) != v) {') }
.string { g.definitions.writeln('\t\tif (!map_exists(b, k) || string_ne((*(string*)map_get_1(&b, &k, &(string[]){_SLIT("")})), v)) {') }
.function { g.definitions.writeln('\t\tif (!map_exists(b, k) || (*(voidptr*)map_get_1(&b, &k, &(voidptr[]){ 0 })) != v) {') }
else { g.definitions.writeln('\t\tif (!map_exists(b, k) || (*($value_typ*)map_get_1(&b, &k, &($value_typ[]){ 0 })) != v) {') }
}
g.definitions.writeln('\t\t\treturn false;')
g.definitions.writeln('\t\t}')

View File

@ -269,6 +269,8 @@ static void* g_live_info = NULL;
//#define tos4(s, slen) ((string){.str=(s), .len=(slen)})
// `"" s` is used to enforce a string literal argument
#define _SLIT(s) ((string){.str=(byteptr)("" s), .len=(sizeof(s)-1), .is_lit=1})
// take the address of an rvalue
#define ADDR(type, expr) (&((type[]){expr}[0]))
#define _PUSH_MANY(arr, val, tmp, tmp_typ) {tmp_typ tmp = (val); array_push_many(arr, tmp.data, tmp.len);}
#define _IN(typ, val, arr) array_##typ##_contains(arr, val)
#define _IN_MAP(val, m) map_exists(m, val)

View File

@ -263,7 +263,8 @@ fn (mut g Gen) decode_map(key_type table.Type, value_type table.Type) string {
cJSON_ArrayForEach(jsval, root)
{
$s
map_set(&res, tos2( (byteptr) jsval->string ) , &val );
string key = tos2( (byteptr) jsval->string );
map_set_1(&res, &key, &val);
}
'
}
@ -286,7 +287,7 @@ fn (mut g Gen) encode_map(key_type table.Type, value_type table.Type) string {
array_$styp $keys_tmp = map_keys(&val);
for (int i = 0; i < ${keys_tmp}.len; ++i) {
$key
cJSON_AddItemToObject(o, (char*) key.str, $fn_name_v ( *($styp_v*) map_get(val, key, &($styp_v[]) { $zero } ) ) );
cJSON_AddItemToObject(o, (char*) key.str, $fn_name_v ( *($styp_v*) map_get_1(&val, &key, &($styp_v[]) { $zero } ) ) );
}
array_free(&$keys_tmp);
'

View File

@ -0,0 +1,9 @@
fn test_string_int() {
mut m := {'hi':4}
m2:= {'hi':5}
assert m != m2
m['hi']++
assert m == m2
m.delete('hi')
assert m != m2
}