map: add 3 DenseArray methods for bootstrapping (#7113)

pull/7118/head
Nick Treleaven 2020-12-03 19:12:53 +00:00 committed by GitHub
parent 6c100a0bc3
commit d590ce7675
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 26 additions and 14 deletions

View File

@ -117,6 +117,23 @@ fn new_dense_array(value_bytes int) DenseArray {
} }
} }
[inline]
fn (d &DenseArray) key(i int) voidptr {
return unsafe {voidptr(d.keys + i)}
}
// for cgen
[inline]
fn (d &DenseArray) value(i int) voidptr {
return unsafe {voidptr(d.values + i * d.value_bytes)}
}
[inline]
fn (d &DenseArray) has_index(i int) bool {
pkey := unsafe {d.keys + i}
return pkey.str != 0
}
// Push element to array and return index // Push element to array and return index
// The growth-factor is roughly 1.125 `(x + (x >> 3))` // The growth-factor is roughly 1.125 `(x + (x >> 3))`
[inline] [inline]

View File

@ -258,7 +258,6 @@ fn (mut g Gen) gen_str_for_map(info table.Map, styp string, str_fn_name string)
if !val_sym.has_method('str') { if !val_sym.has_method('str') {
g.gen_str_for_type(info.value_type) g.gen_str_for_type(info.value_type)
} }
zero := g.type_default(info.value_type)
g.type_definitions.writeln('static string ${str_fn_name}($styp m); // auto') g.type_definitions.writeln('static string ${str_fn_name}($styp m); // auto')
g.auto_str_funcs.writeln('static string ${str_fn_name}($styp m) { return indent_${str_fn_name}(m, 0);}') g.auto_str_funcs.writeln('static string ${str_fn_name}($styp m) { return indent_${str_fn_name}(m, 0);}')
g.type_definitions.writeln('static string indent_${str_fn_name}($styp m, int indent_count); // auto') g.type_definitions.writeln('static string indent_${str_fn_name}($styp m, int indent_count); // auto')
@ -266,14 +265,11 @@ fn (mut g Gen) gen_str_for_map(info table.Map, styp string, str_fn_name string)
g.auto_str_funcs.writeln('\tstrings__Builder sb = strings__new_builder(m.key_values.len*10);') g.auto_str_funcs.writeln('\tstrings__Builder sb = strings__new_builder(m.key_values.len*10);')
g.auto_str_funcs.writeln('\tstrings__Builder_write(&sb, _SLIT("{"));') g.auto_str_funcs.writeln('\tstrings__Builder_write(&sb, _SLIT("{"));')
g.auto_str_funcs.writeln('\tfor (unsigned int i = 0; i < m.key_values.len; ++i) {') g.auto_str_funcs.writeln('\tfor (unsigned int i = 0; i < m.key_values.len; ++i) {')
g.auto_str_funcs.writeln('\t\tif (m.key_values.keys[i].str == 0) { continue; }') g.auto_str_funcs.writeln('\t\tif (!DenseArray_has_index(&m.key_values, i)) { continue; }')
g.auto_str_funcs.writeln('\t\tstring key = (*(string*)DenseArray_get(m.key_values, i));') g.auto_str_funcs.writeln('\t\tstring key = *(string*)DenseArray_key(&m.key_values, i);')
g.auto_str_funcs.writeln('\t\tstrings__Builder_write(&sb, _STR("\'%.*s\\000\'", 2, key));') g.auto_str_funcs.writeln('\t\tstrings__Builder_write(&sb, _STR("\'%.*s\\000\'", 2, key));')
g.auto_str_funcs.writeln('\t\tstrings__Builder_write(&sb, _SLIT(": "));') g.auto_str_funcs.writeln('\t\tstrings__Builder_write(&sb, _SLIT(": "));')
g.auto_str_funcs.write('\t$val_styp it = (*($val_styp*)map_get(') g.auto_str_funcs.writeln('\t\t$val_styp it = *($val_styp*)DenseArray_value(&m.key_values, i);')
g.auto_str_funcs.write('m, (*(string*)DenseArray_get(m.key_values, i))')
g.auto_str_funcs.write(', ')
g.auto_str_funcs.writeln(' &($val_styp[]) { $zero }));')
if val_sym.kind == .string { if val_sym.kind == .string {
g.auto_str_funcs.writeln('\t\tstrings__Builder_write(&sb, _STR("\'%.*s\\000\'", 2, it));') g.auto_str_funcs.writeln('\t\tstrings__Builder_write(&sb, _STR("\'%.*s\\000\'", 2, it));')
} else if val_sym.kind == .struct_ && !val_sym.has_method('str') { } else if val_sym.kind == .struct_ && !val_sym.has_method('str') {

View File

@ -1221,28 +1221,27 @@ fn (mut g Gen) for_in(it ast.ForInStmt) {
g.expr(it.cond) g.expr(it.cond)
g.writeln(';') g.writeln(';')
g.writeln('for (int $idx = 0; $idx < (int)${atmp}.key_values.len; ++$idx) {') g.writeln('for (int $idx = 0; $idx < (int)${atmp}.key_values.len; ++$idx) {')
g.writeln('\tif (${atmp}.key_values.keys[$idx].str == 0) {continue;}') g.writeln('\tif (!DenseArray_has_index(&${atmp}.key_values, $idx)) {continue;}')
if it.key_var != '_' { if it.key_var != '_' {
key_styp := g.typ(it.key_type) key_styp := g.typ(it.key_type)
key := c_name(it.key_var) key := c_name(it.key_var)
g.writeln('\t$key_styp $key = /*key*/ *($key_styp*)DenseArray_key(&${atmp}.key_values, $idx);')
// TODO: analyze whether it.key_type has a .clone() method and call .clone() for all types: // TODO: analyze whether it.key_type has a .clone() method and call .clone() for all types:
if it.key_type == table.string_type { if it.key_type == table.string_type {
g.writeln('\t$key_styp $key = /*key*/ string_clone(${atmp}.key_values.keys[$idx]);') g.writeln('\t$key = string_clone($key);')
} else {
g.writeln('\t$key_styp $key = /*key*/ ${atmp}.key_values.keys[$idx];')
} }
} }
if it.val_var != '_' { if it.val_var != '_' {
val_sym := g.table.get_type_symbol(it.val_type) val_sym := g.table.get_type_symbol(it.val_type)
valstr := '(void*)(${atmp}.key_values.values + $idx * (u32)(${atmp}.value_bytes))'
if val_sym.kind == .function { if val_sym.kind == .function {
g.write('\t') g.write('\t')
g.write_fn_ptr_decl(val_sym.info as table.FnType, c_name(it.val_var)) g.write_fn_ptr_decl(val_sym.info as table.FnType, c_name(it.val_var))
g.writeln(' = (*(voidptr*)$valstr);') g.write(' = (*(voidptr*)')
} else { } else {
val_styp := g.typ(it.val_type) val_styp := g.typ(it.val_type)
g.writeln('\t$val_styp ${c_name(it.val_var)} = (*($val_styp*)$valstr);') g.write('\t$val_styp ${c_name(it.val_var)} = (*($val_styp*)')
} }
g.writeln('DenseArray_value(&${atmp}.key_values, $idx));')
} }
g.stmts(it.stmts) g.stmts(it.stmts)
if it.key_type == table.string_type && !g.is_builtin_mod { if it.key_type == table.string_type && !g.is_builtin_mod {