cgen: fix array and map printing (#6508)

pull/6510/head
Daniel Däschle 2020-09-30 01:26:27 +02:00 committed by GitHub
parent 96102613f3
commit c38a050125
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 39 additions and 8 deletions

View File

@ -89,16 +89,18 @@ fn (mut g Gen) gen_str_for_array(info table.Array, styp, str_fn_name string) {
g.gen_str_for_type_with_styp(info.elem_type, field_styp)
}
g.type_definitions.writeln('string ${str_fn_name}($styp a); // auto')
g.auto_str_funcs.writeln('string ${str_fn_name}($styp a) {')
g.auto_str_funcs.writeln('string ${str_fn_name}($styp a) { return indent_${str_fn_name}(a, 0);}')
g.type_definitions.writeln('string indent_${str_fn_name}($styp a, int indent_count); // auto')
g.auto_str_funcs.writeln('string indent_${str_fn_name}($styp a, int indent_count) {')
g.auto_str_funcs.writeln('\tstrings__Builder sb = strings__new_builder(a.len * 10);')
g.auto_str_funcs.writeln('\tstrings__Builder_write(&sb, tos_lit("["));')
g.auto_str_funcs.writeln('\tfor (int i = 0; i < a.len; ++i) {')
g.auto_str_funcs.writeln('\t\t$field_styp it = (*($field_styp*)array_get(a, i));')
if sym.kind == .struct_ && !sym_has_str_method {
if is_elem_ptr {
g.auto_str_funcs.writeln('\t\tstring x = ${elem_str_fn_name}(*it);')
g.auto_str_funcs.writeln('\t\tstring x = indent_${elem_str_fn_name}(*it, indent_count);')
} else {
g.auto_str_funcs.writeln('\t\tstring x = ${elem_str_fn_name}(it);')
g.auto_str_funcs.writeln('\t\tstring x = indent_${elem_str_fn_name}(it, indent_count);')
}
} else if sym.kind in [.f32, .f64] {
g.auto_str_funcs.writeln('\t\tstring x = _STR("%g", 1, it);')
@ -147,12 +149,14 @@ fn (mut g Gen) gen_str_for_array_fixed(info table.ArrayFixed, styp, str_fn_name
g.gen_str_for_type_with_styp(info.elem_type, field_styp)
}
g.type_definitions.writeln('string ${str_fn_name}($styp a); // auto')
g.auto_str_funcs.writeln('string ${str_fn_name}($styp a) {')
g.auto_str_funcs.writeln('string ${str_fn_name}($styp a) { return indent_${str_fn_name}(a, 0);}')
g.type_definitions.writeln('string indent_${str_fn_name}($styp a, int indent_count); // auto')
g.auto_str_funcs.writeln('string indent_${str_fn_name}($styp a, int indent_count) {')
g.auto_str_funcs.writeln('\tstrings__Builder sb = strings__new_builder($info.size * 10);')
g.auto_str_funcs.writeln('\tstrings__Builder_write(&sb, tos_lit("["));')
g.auto_str_funcs.writeln('\tfor (int i = 0; i < $info.size; ++i) {')
if sym.kind == .struct_ && !sym_has_str_method {
g.auto_str_funcs.writeln('\t\tstrings__Builder_write(&sb, ${elem_str_fn_name}(a[i]));')
g.auto_str_funcs.writeln('\t\tstrings__Builder_write(&sb, ${elem_str_fn_name}(a[i], indent_count));')
} else if sym.kind in [.f32, .f64] {
g.auto_str_funcs.writeln('\t\tstrings__Builder_write(&sb, _STR("%g", 1, a[i]));')
} else if sym.kind == .string {
@ -189,7 +193,9 @@ fn (mut g Gen) gen_str_for_map(info table.Map, styp, str_fn_name string) {
}
zero := g.type_default(info.value_type)
g.type_definitions.writeln('string ${str_fn_name}($styp m); // auto')
g.auto_str_funcs.writeln('string ${str_fn_name}($styp m) { /* gen_str_for_map */')
g.auto_str_funcs.writeln('string ${str_fn_name}($styp m) { return indent_${str_fn_name}(m, 0);}')
g.type_definitions.writeln('string indent_${str_fn_name}($styp m, int indent_count); // auto')
g.auto_str_funcs.writeln('string indent_${str_fn_name}($styp m, int indent_count) { /* gen_str_for_map */')
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, tos_lit("{"));')
g.auto_str_funcs.writeln('\tfor (unsigned int i = 0; i < m.key_values.len; ++i) {')
@ -203,7 +209,7 @@ fn (mut g Gen) gen_str_for_map(info table.Map, styp, str_fn_name string) {
if val_sym.kind == .string {
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') {
g.auto_str_funcs.writeln('\t\tstrings__Builder_write(&sb, ${elem_str_fn_name}(it));')
g.auto_str_funcs.writeln('\t\tstrings__Builder_write(&sb, indent_${elem_str_fn_name}(it, indent_count));')
} else if val_sym.kind in [.f32, .f64] {
g.auto_str_funcs.writeln('\t\tstrings__Builder_write(&sb, _STR("%g", 1, it));')
} else {
@ -381,7 +387,10 @@ fn struct_auto_str_func(sym table.TypeSymbol, field_type table.Type, fn_name, fi
return 'indent_${fn_name}($obj, indent_count + 1)'
}
} else if sym.kind in [.array, .array_fixed, .map] {
return '${fn_name}(it->${c_name(field_name)})'
if has_custom_str {
return '${fn_name}(it->${c_name(field_name)})'
}
return 'indent_${fn_name}(it->${c_name(field_name)}, indent_count + 1)'
} else if sym.kind == .sum_type {
return 'indent_${fn_name}(it->${c_name(field_name)}, indent_count + 1)'
} else {

View File

@ -196,3 +196,25 @@ fn test_struct_with_f32_pointer() {
assert '$w' == 'Wrapper5 {\n foo: &5.1\n}'
assert w.str() == 'Wrapper5 {\n foo: &5.1\n}'
}
struct TestStruct {
x int
}
struct ArrayWithStruct {
foo []TestStruct
}
fn test_array_with_struct() {
a := ArrayWithStruct{[TestStruct{}]}
assert a.str() == 'ArrayWithStruct {\n foo: [TestStruct {\n x: 0\n }]\n}'
assert '$a' == 'ArrayWithStruct {\n foo: [TestStruct {\n x: 0\n }]\n}'
}
struct MapWithStruct {
foo map[string]TestStruct
}
fn test_map_with_struct() {
a := MapWithStruct{{'test': TestStruct{}}}
assert a.str() == 'MapWithStruct {\n foo: {\'test\': TestStruct {\n x: 0\n }}\n}'
assert '$a' == 'MapWithStruct {\n foo: {\'test\': TestStruct {\n x: 0\n }}\n}'
}