cgen: use tos_lit

pull/4788/head
Alexander Medvednikov 2020-05-08 13:25:14 +02:00
parent 13b11a4155
commit 847a1035a5
1 changed files with 58 additions and 42 deletions

View File

@ -778,16 +778,16 @@ fn (mut g Gen) for_in(it ast.ForInStmt) {
} }
// use instead of expr() when you need to cast to sum type (can add other casts also) // use instead of expr() when you need to cast to sum type (can add other casts also)
fn (mut g Gen) expr_with_cast(expr ast.Expr, got_type, exp_type table.Type) { fn (mut g Gen) expr_with_cast(expr ast.Expr, got_type, expected_type table.Type) {
// cast to sum type // cast to sum type
if exp_type != table.void_type { if expected_type != table.void_type {
exp_sym := g.table.get_type_symbol(exp_type) exp_sym := g.table.get_type_symbol(expected_type)
if exp_sym.kind == .sum_type { if exp_sym.kind == .sum_type {
sum_info := exp_sym.info as table.SumType sum_info := exp_sym.info as table.SumType
if got_type in sum_info.variants { if got_type in sum_info.variants {
got_sym := g.table.get_type_symbol(got_type) got_sym := g.table.get_type_symbol(got_type)
got_styp := g.typ(got_type) got_styp := g.typ(got_type)
exp_styp := g.typ(exp_type) exp_styp := g.typ(expected_type)
got_idx := got_type.idx() got_idx := got_type.idx()
g.write('/* sum type cast */ ($exp_styp) {.obj = memdup(&(${got_styp}[]) {') g.write('/* sum type cast */ ($exp_styp) {.obj = memdup(&(${got_styp}[]) {')
g.expr(expr) g.expr(expr)
@ -815,10 +815,10 @@ fn (mut g Gen) gen_assert_stmt(a ast.AssertStmt) {
if g.is_test { if g.is_test {
g.writeln('{') g.writeln('{')
g.writeln(' g_test_oks++;') g.writeln(' g_test_oks++;')
g.writeln(' cb_assertion_ok( tos3("${mod_path}"), ${a.pos.line_nr+1}, tos3("assert ${s_assertion}"), tos3("${g.fn_decl.name}()") );') g.writeln(' cb_assertion_ok( tos_lit("${mod_path}"), ${a.pos.line_nr+1}, tos_lit("assert ${s_assertion}"), tos_lit("${g.fn_decl.name}()") );')
g.writeln('}else{') g.writeln('}else{')
g.writeln(' g_test_fails++;') g.writeln(' g_test_fails++;')
g.writeln(' cb_assertion_failed( tos3("${mod_path}"), ${a.pos.line_nr+1}, tos3("assert ${s_assertion}"), tos3("${g.fn_decl.name}()") );') g.writeln(' cb_assertion_failed( tos_lit("${mod_path}"), ${a.pos.line_nr+1}, tos_lit("assert ${s_assertion}"), tos_lit("${g.fn_decl.name}()") );')
g.writeln(' exit(1);') g.writeln(' exit(1);')
g.writeln(' // TODO') g.writeln(' // TODO')
g.writeln(' // Maybe print all vars in a test function if it fails?') g.writeln(' // Maybe print all vars in a test function if it fails?')
@ -826,7 +826,7 @@ fn (mut g Gen) gen_assert_stmt(a ast.AssertStmt) {
return return
} }
g.writeln('{}else{') g.writeln('{}else{')
g.writeln(' eprintln( tos3("${mod_path}:${a.pos.line_nr+1}: FAIL: fn ${g.fn_decl.name}(): assert $s_assertion"));') g.writeln(' eprintln( tos_lit("${mod_path}:${a.pos.line_nr+1}: FAIL: fn ${g.fn_decl.name}(): assert $s_assertion"));')
g.writeln(' exit(1);') g.writeln(' exit(1);')
g.writeln('}') g.writeln('}')
} }
@ -1250,7 +1250,7 @@ fn (mut g Gen) expr(node ast.Expr) {
ast.StringLiteral { ast.StringLiteral {
if it.is_raw { if it.is_raw {
escaped_val := it.val.replace_each(['"', '\\"', '\\', '\\\\']) escaped_val := it.val.replace_each(['"', '\\"', '\\', '\\\\'])
g.write('tos3("$escaped_val")') g.write('tos_lit("$escaped_val")')
return return
} }
escaped_val := it.val.replace_each(['"', '\\"', '\r\n', '\\n', '\n', '\\n']) escaped_val := it.val.replace_each(['"', '\\"', '\r\n', '\\n', '\n', '\\n'])
@ -1265,7 +1265,8 @@ fn (mut g Gen) expr(node ast.Expr) {
// g.write('tos4("$escaped_val", strlen("$escaped_val"))') // g.write('tos4("$escaped_val", strlen("$escaped_val"))')
// g.write('tos4("$escaped_val", $it.val.len)') // g.write('tos4("$escaped_val", $it.val.len)')
// g.write('_SLIT("$escaped_val")') // g.write('_SLIT("$escaped_val")')
g.write('tos3("$escaped_val")') g.write('tos_lit("$escaped_val")')
// g.write('tos_lit("$escaped_val")')
} }
} }
ast.StringInterLiteral { ast.StringInterLiteral {
@ -1329,7 +1330,7 @@ fn (mut g Gen) typeof_expr(node ast.TypeOf) {
} else if sym.kind == .array_fixed { } else if sym.kind == .array_fixed {
fixed_info := sym.info as table.ArrayFixed fixed_info := sym.info as table.ArrayFixed
typ_name := g.table.get_type_name(fixed_info.elem_type) typ_name := g.table.get_type_name(fixed_info.elem_type)
g.write('tos3("[$fixed_info.size]${typ_name}")') g.write('tos_lit("[$fixed_info.size]${typ_name}")')
} else if sym.kind == .function { } else if sym.kind == .function {
info := sym.info as table.FnType info := sym.info as table.FnType
fn_info := info.func fn_info := info.func
@ -1344,9 +1345,9 @@ fn (mut g Gen) typeof_expr(node ast.TypeOf) {
if fn_info.return_type != table.void_type { if fn_info.return_type != table.void_type {
repr += ' ${g.table.get_type_name(fn_info.return_type)}' repr += ' ${g.table.get_type_name(fn_info.return_type)}'
} }
g.write('tos3("$repr")') g.write('tos_lit("$repr")')
} else { } else {
g.write('tos3("${sym.name}")') g.write('tos_lit("${sym.name}")')
} }
} }
@ -2161,6 +2162,13 @@ fn (mut g Gen) struct_init(struct_init ast.StructInit) {
field_name := c_name(field.name) field_name := c_name(field.name)
inited_fields << field.name inited_fields << field.name
g.write('\t.$field_name = ') g.write('\t.$field_name = ')
/*
if g.autofree && right_sym.kind in [.array, .string] {
g.write('/*clone1*/')
if g.gen_clone_assignment(field.expr, right_sym, true) {
}
}
*/
g.expr_with_cast(field.expr, field.typ, field.expected_type) g.expr_with_cast(field.expr, field.typ, field.expected_type)
g.writeln(',') g.writeln(',')
} }
@ -2596,7 +2604,7 @@ fn (mut g Gen) string_inter_literal(node ast.StringInterLiteral) {
g.enum_expr(expr) g.enum_expr(expr)
g.write(')') g.write(')')
} else { } else {
g.write('tos3("') g.write('tos_lit("')
g.enum_expr(expr) g.enum_expr(expr)
g.write('")') g.write('")')
} }
@ -2972,7 +2980,7 @@ fn (g Gen) type_default(typ table.Type) string {
/* /*
return match typ { return match typ {
'bool'{ '0'} 'bool'{ '0'}
'string'{ 'tos3("")'} 'string'{ 'tos_lit("")'}
'i8'{ '0'} 'i8'{ '0'}
'i16'{ '0'} 'i16'{ '0'}
'i64'{ '0'} 'i64'{ '0'}
@ -3003,12 +3011,12 @@ pub fn (mut g Gen) write_tests_main() {
g.writeln('') g.writeln('')
all_tfuncs := g.get_all_test_function_names() all_tfuncs := g.get_all_test_function_names()
if g.pref.is_stats { if g.pref.is_stats {
g.writeln('\tBenchedTests bt = start_testing(${all_tfuncs.len}, tos3("$g.pref.path"));') g.writeln('\tBenchedTests bt = start_testing(${all_tfuncs.len}, tos_lit("$g.pref.path"));')
} }
for t in all_tfuncs { for t in all_tfuncs {
g.writeln('') g.writeln('')
if g.pref.is_stats { if g.pref.is_stats {
g.writeln('\tBenchedTests_testing_step_start(&bt, tos3("$t"));') g.writeln('\tBenchedTests_testing_step_start(&bt, tos_lit("$t"));')
} }
g.writeln('\t${t}();') g.writeln('\t${t}();')
if g.pref.is_stats { if g.pref.is_stats {
@ -3263,7 +3271,7 @@ fn (mut g Gen) gen_str_for_type_with_styp(typ table.Type, styp string) string {
table.Enum { g.gen_str_for_enum(it, styp, str_fn_name) } table.Enum { g.gen_str_for_enum(it, styp, str_fn_name) }
table.Struct { g.gen_str_for_struct(it, styp, str_fn_name) } table.Struct { g.gen_str_for_struct(it, styp, str_fn_name) }
table.Map { g.gen_str_for_map(it, styp, str_fn_name) } table.Map { g.gen_str_for_map(it, styp, str_fn_name) }
else { verror("could not generate string method $str_fn_name for type \'${styp}\' | sym.name: ${sym.name}") } else { verror("could not generate string method $str_fn_name for type \'${styp}\'") }
} }
} }
// if varg, generate str for varg // if varg, generate str for varg
@ -3299,11 +3307,11 @@ fn (mut g Gen) gen_str_default(sym table.TypeSymbol, styp, str_fn_name string) {
g.definitions.writeln('string ${str_fn_name}($styp it); // auto') g.definitions.writeln('string ${str_fn_name}($styp it); // auto')
g.auto_str_funcs.writeln('string ${str_fn_name}($styp it) {') g.auto_str_funcs.writeln('string ${str_fn_name}($styp it) {')
if convertor == 'bool' { if convertor == 'bool' {
g.auto_str_funcs.writeln('\tstring tmp1 = string_add(tos3("${styp}("), (${convertor})it ? tos3("true") : tos3("false"));') g.auto_str_funcs.writeln('\tstring tmp1 = string_add(tos_lit("${styp}("), (${convertor})it ? tos_lit("true") : tos_lit("false"));')
} else { } else {
g.auto_str_funcs.writeln('\tstring tmp1 = string_add(tos3("${styp}("), tos3(${typename}_str((${convertor})it).str));') g.auto_str_funcs.writeln('\tstring tmp1 = string_add(tos_lit("${styp}("), tos3(${typename}_str((${convertor})it).str));')
} }
g.auto_str_funcs.writeln('\tstring tmp2 = string_add(tmp1, tos3(")"));') g.auto_str_funcs.writeln('\tstring tmp2 = string_add(tmp1, tos_lit(")"));')
g.auto_str_funcs.writeln('\tstring_free(&tmp1);') g.auto_str_funcs.writeln('\tstring_free(&tmp1);')
g.auto_str_funcs.writeln('\treturn tmp2;') g.auto_str_funcs.writeln('\treturn tmp2;')
g.auto_str_funcs.writeln('}') g.auto_str_funcs.writeln('}')
@ -3315,9 +3323,9 @@ fn (mut g Gen) gen_str_for_enum(info table.Enum, styp, str_fn_name string) {
g.auto_str_funcs.writeln('string ${str_fn_name}($styp it) { /* gen_str_for_enum */') g.auto_str_funcs.writeln('string ${str_fn_name}($styp it) { /* gen_str_for_enum */')
g.auto_str_funcs.writeln('\tswitch(it) {') g.auto_str_funcs.writeln('\tswitch(it) {')
for val in info.vals { for val in info.vals {
g.auto_str_funcs.writeln('\t\tcase ${s}_$val: return tos3("$val");') g.auto_str_funcs.writeln('\t\tcase ${s}_$val: return tos_lit("$val");')
} }
g.auto_str_funcs.writeln('\t\tdefault: return tos3("unknown enum value");') g.auto_str_funcs.writeln('\t\tdefault: return tos_lit("unknown enum value");')
g.auto_str_funcs.writeln('\t}') g.auto_str_funcs.writeln('\t}')
g.auto_str_funcs.writeln('}') g.auto_str_funcs.writeln('}')
} }
@ -3348,9 +3356,9 @@ fn (mut g Gen) gen_str_for_struct(info table.Struct, styp, str_fn_name string) {
g.auto_str_funcs.writeln('\t${deref_typ} *it = &x;') g.auto_str_funcs.writeln('\t${deref_typ} *it = &x;')
} }
// generate ident / indent length = 4 spaces // generate ident / indent length = 4 spaces
g.auto_str_funcs.writeln('\tstring indents = tos3("");') g.auto_str_funcs.writeln('\tstring indents = tos_lit("");')
g.auto_str_funcs.writeln('\tfor (int i = 0; i < indent_count; i++) {') g.auto_str_funcs.writeln('\tfor (int i = 0; i < indent_count; i++) {')
g.auto_str_funcs.writeln('\t\tindents = string_add(indents, tos3(" "));') g.auto_str_funcs.writeln('\t\tindents = string_add(indents, tos_lit(" "));')
g.auto_str_funcs.writeln('\t}') g.auto_str_funcs.writeln('\t}')
g.auto_str_funcs.writeln('\treturn _STR("${clean_struct_v_type_name} {\\n"') g.auto_str_funcs.writeln('\treturn _STR("${clean_struct_v_type_name} {\\n"')
for field in info.fields { for field in info.fields {
@ -3398,9 +3406,13 @@ fn (mut g Gen) gen_str_for_array(info table.Array, styp, str_fn_name string) {
sym_has_str_method, str_method_expects_ptr, _ := sym.str_method_info() sym_has_str_method, str_method_expects_ptr, _ := sym.str_method_info()
mut elem_str_fn_name := '' mut elem_str_fn_name := ''
if sym_has_str_method { if sym_has_str_method {
elem_str_fn_name = if is_elem_ptr { field_styp.replace('*', '') +'_str' } else { field_styp + '_str' } elem_str_fn_name = if is_elem_ptr {
field_styp.replace('*', '') + '_str'
} else {
field_styp + '_str'
}
} else { } else {
elem_str_fn_name = styp_to_str_fn_name( field_styp ) elem_str_fn_name = styp_to_str_fn_name(field_styp)
} }
if !sym_has_str_method { if !sym_has_str_method {
// eprintln('> sym.name: does not have method `str`') // eprintln('> sym.name: does not have method `str`')
@ -3409,13 +3421,13 @@ fn (mut g Gen) gen_str_for_array(info table.Array, styp, str_fn_name string) {
g.definitions.writeln('string ${str_fn_name}($styp a); // auto') g.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) {')
g.auto_str_funcs.writeln('\tstrings__Builder sb = strings__new_builder(a.len * 10);') g.auto_str_funcs.writeln('\tstrings__Builder sb = strings__new_builder(a.len * 10);')
g.auto_str_funcs.writeln('\tstrings__Builder_write(&sb, tos3("["));') 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('\tfor (int i = 0; i < a.len; i++) {')
g.auto_str_funcs.writeln('\t\t${field_styp} it = (*(${field_styp}*)array_get(a, 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 sym.kind == .struct_ && !sym_has_str_method {
if is_elem_ptr { if is_elem_ptr {
g.auto_str_funcs.writeln('\t\tstring x = ${elem_str_fn_name}(*it,0);') g.auto_str_funcs.writeln('\t\tstring x = ${elem_str_fn_name}(*it,0);')
}else{ } else {
g.auto_str_funcs.writeln('\t\tstring x = ${elem_str_fn_name}(it,0);') g.auto_str_funcs.writeln('\t\tstring x = ${elem_str_fn_name}(it,0);')
} }
} else if sym.kind in [.f32, .f64] { } else if sym.kind in [.f32, .f64] {
@ -3438,10 +3450,10 @@ fn (mut g Gen) gen_str_for_array(info table.Array, styp, str_fn_name string) {
g.auto_str_funcs.writeln('\t\tstring_free(&x);') g.auto_str_funcs.writeln('\t\tstring_free(&x);')
} }
g.auto_str_funcs.writeln('\t\tif (i < a.len-1) {') g.auto_str_funcs.writeln('\t\tif (i < a.len-1) {')
g.auto_str_funcs.writeln('\t\t\tstrings__Builder_write(&sb, tos3(", "));') g.auto_str_funcs.writeln('\t\t\tstrings__Builder_write(&sb, tos_lit(", "));')
g.auto_str_funcs.writeln('\t\t}') g.auto_str_funcs.writeln('\t\t}')
g.auto_str_funcs.writeln('\t}') g.auto_str_funcs.writeln('\t}')
g.auto_str_funcs.writeln('\tstrings__Builder_write(&sb, tos3("]"));') g.auto_str_funcs.writeln('\tstrings__Builder_write(&sb, tos_lit("]"));')
g.auto_str_funcs.writeln('\tstring res = strings__Builder_str(&sb);') g.auto_str_funcs.writeln('\tstring res = strings__Builder_str(&sb);')
g.auto_str_funcs.writeln('\tstrings__Builder_free(&sb);') g.auto_str_funcs.writeln('\tstrings__Builder_free(&sb);')
// g.auto_str_funcs.writeln('\treturn strings__Builder_str(&sb);') // g.auto_str_funcs.writeln('\treturn strings__Builder_str(&sb);')
@ -3456,9 +3468,13 @@ fn (mut g Gen) gen_str_for_array_fixed(info table.ArrayFixed, styp, str_fn_name
sym_has_str_method, str_method_expects_ptr, _ := sym.str_method_info() sym_has_str_method, str_method_expects_ptr, _ := sym.str_method_info()
mut elem_str_fn_name := '' mut elem_str_fn_name := ''
if sym_has_str_method { if sym_has_str_method {
elem_str_fn_name = if is_elem_ptr { field_styp.replace('*', '') +'_str' } else { field_styp + '_str' } elem_str_fn_name = if is_elem_ptr {
field_styp.replace('*', '') + '_str'
} else {
field_styp + '_str'
}
} else { } else {
elem_str_fn_name = styp_to_str_fn_name( field_styp ) elem_str_fn_name = styp_to_str_fn_name(field_styp)
} }
if !sym.has_method('str') { if !sym.has_method('str') {
g.gen_str_for_type_with_styp(info.elem_type, field_styp) g.gen_str_for_type_with_styp(info.elem_type, field_styp)
@ -3466,7 +3482,7 @@ fn (mut g Gen) gen_str_for_array_fixed(info table.ArrayFixed, styp, str_fn_name
g.definitions.writeln('string ${str_fn_name}($styp a); // auto') g.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) {')
g.auto_str_funcs.writeln('\tstrings__Builder sb = strings__new_builder($info.size * 10);') g.auto_str_funcs.writeln('\tstrings__Builder sb = strings__new_builder($info.size * 10);')
g.auto_str_funcs.writeln('\tstrings__Builder_write(&sb, tos3("["));') g.auto_str_funcs.writeln('\tstrings__Builder_write(&sb, tos_lit("["));')
g.auto_str_funcs.writeln('\tfor (int i = 0; i < $info.size; i++) {') g.auto_str_funcs.writeln('\tfor (int i = 0; i < $info.size; i++) {')
if sym.kind == .struct_ && !sym_has_str_method { if sym.kind == .struct_ && !sym_has_str_method {
g.auto_str_funcs.writeln('\t\tstrings__Builder_write(&sb, ${elem_str_fn_name}(a[i],0));') g.auto_str_funcs.writeln('\t\tstrings__Builder_write(&sb, ${elem_str_fn_name}(a[i],0));')
@ -3484,10 +3500,10 @@ fn (mut g Gen) gen_str_for_array_fixed(info table.ArrayFixed, styp, str_fn_name
} }
} }
g.auto_str_funcs.writeln('\t\tif (i < ${info.size-1}) {') g.auto_str_funcs.writeln('\t\tif (i < ${info.size-1}) {')
g.auto_str_funcs.writeln('\t\t\tstrings__Builder_write(&sb, tos3(", "));') g.auto_str_funcs.writeln('\t\t\tstrings__Builder_write(&sb, tos_lit(", "));')
g.auto_str_funcs.writeln('\t\t}') g.auto_str_funcs.writeln('\t\t}')
g.auto_str_funcs.writeln('\t}') g.auto_str_funcs.writeln('\t}')
g.auto_str_funcs.writeln('\tstrings__Builder_write(&sb, tos3("]"));') g.auto_str_funcs.writeln('\tstrings__Builder_write(&sb, tos_lit("]"));')
g.auto_str_funcs.writeln('\treturn strings__Builder_str(&sb);') g.auto_str_funcs.writeln('\treturn strings__Builder_str(&sb);')
g.auto_str_funcs.writeln('}') g.auto_str_funcs.writeln('}')
} }
@ -3508,11 +3524,11 @@ fn (mut g Gen) gen_str_for_map(info table.Map, styp, str_fn_name string) {
g.definitions.writeln('string ${str_fn_name}($styp m); // auto') g.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) { /* gen_str_for_map */')
g.auto_str_funcs.writeln('\tstrings__Builder sb = strings__new_builder(m.key_values.size*10);') g.auto_str_funcs.writeln('\tstrings__Builder sb = strings__new_builder(m.key_values.size*10);')
g.auto_str_funcs.writeln('\tstrings__Builder_write(&sb, tos3("{"));') 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.size; i++) {') g.auto_str_funcs.writeln('\tfor (unsigned int i = 0; i < m.key_values.size; i++) {')
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_get(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, tos3(": "));') g.auto_str_funcs.writeln('\t\tstrings__Builder_write(&sb, tos_lit(": "));')
g.auto_str_funcs.write('\t$val_styp it = (*($val_styp*)map_get3(') g.auto_str_funcs.write('\t$val_styp it = (*($val_styp*)map_get3(')
g.auto_str_funcs.write('m, (*(string*)DenseArray_get(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.write(', ')
@ -3527,10 +3543,10 @@ fn (mut g Gen) gen_str_for_map(info table.Map, styp, str_fn_name string) {
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, ${elem_str_fn_name}(it));')
} }
g.auto_str_funcs.writeln('\t\tif (i != m.key_values.size-1) {') g.auto_str_funcs.writeln('\t\tif (i != m.key_values.size-1) {')
g.auto_str_funcs.writeln('\t\t\tstrings__Builder_write(&sb, tos3(", "));') g.auto_str_funcs.writeln('\t\t\tstrings__Builder_write(&sb, tos_lit(", "));')
g.auto_str_funcs.writeln('\t\t}') g.auto_str_funcs.writeln('\t\t}')
g.auto_str_funcs.writeln('\t}') g.auto_str_funcs.writeln('\t}')
g.auto_str_funcs.writeln('\tstrings__Builder_write(&sb, tos3("}"));') g.auto_str_funcs.writeln('\tstrings__Builder_write(&sb, tos_lit("}"));')
g.auto_str_funcs.writeln('\treturn strings__Builder_str(&sb);') g.auto_str_funcs.writeln('\treturn strings__Builder_str(&sb);')
g.auto_str_funcs.writeln('}') g.auto_str_funcs.writeln('}')
} }
@ -3539,14 +3555,14 @@ fn (mut g Gen) gen_str_for_varg(styp, str_fn_name string) {
g.definitions.writeln('string varg_${str_fn_name}(varg_$styp it); // auto') g.definitions.writeln('string varg_${str_fn_name}(varg_$styp it); // auto')
g.auto_str_funcs.writeln('string varg_${str_fn_name}(varg_$styp it) {') g.auto_str_funcs.writeln('string varg_${str_fn_name}(varg_$styp it) {')
g.auto_str_funcs.writeln('\tstrings__Builder sb = strings__new_builder(it.len);') g.auto_str_funcs.writeln('\tstrings__Builder sb = strings__new_builder(it.len);')
g.auto_str_funcs.writeln('\tstrings__Builder_write(&sb, tos3("["));') g.auto_str_funcs.writeln('\tstrings__Builder_write(&sb, tos_lit("["));')
g.auto_str_funcs.writeln('\tfor(int i=0; i<it.len; i++) {') g.auto_str_funcs.writeln('\tfor(int i=0; i<it.len; i++) {')
g.auto_str_funcs.writeln('\t\tstrings__Builder_write(&sb, ${str_fn_name}(it.args[i], 0));') g.auto_str_funcs.writeln('\t\tstrings__Builder_write(&sb, ${str_fn_name}(it.args[i], 0));')
g.auto_str_funcs.writeln('\t\tif (i < it.len-1) {') g.auto_str_funcs.writeln('\t\tif (i < it.len-1) {')
g.auto_str_funcs.writeln('\t\t\tstrings__Builder_write(&sb, tos3(", "));') g.auto_str_funcs.writeln('\t\t\tstrings__Builder_write(&sb, tos_lit(", "));')
g.auto_str_funcs.writeln('\t\t}') g.auto_str_funcs.writeln('\t\t}')
g.auto_str_funcs.writeln('\t}') g.auto_str_funcs.writeln('\t}')
g.auto_str_funcs.writeln('\tstrings__Builder_write(&sb, tos3("]"));') g.auto_str_funcs.writeln('\tstrings__Builder_write(&sb, tos_lit("]"));')
g.auto_str_funcs.writeln('\treturn strings__Builder_str(&sb);') g.auto_str_funcs.writeln('\treturn strings__Builder_str(&sb);')
g.auto_str_funcs.writeln('}') g.auto_str_funcs.writeln('}')
} }