cgen: add g.auto_str_funcs, print &Struct pointers with enum fields
							parent
							
								
									baf3bf6778
								
							
						
					
					
						commit
						7c1d6b60c2
					
				|  | @ -53,6 +53,7 @@ struct Gen { | |||
| 	inits                strings.Builder // contents of `void _vinit(){}`
 | ||||
| 	gowrappers           strings.Builder // all go callsite wrappers
 | ||||
| 	stringliterals       strings.Builder // all string literals (they depend on tos3() beeing defined
 | ||||
| 	auto_str_funcs       strings.Builder // function bodies of all auto generated _str funcs
 | ||||
| 	table                &table.Table | ||||
| 	pref                 &pref.Preferences | ||||
| mut: | ||||
|  | @ -105,6 +106,7 @@ pub fn cgen(files []ast.File, table &table.Table, pref &pref.Preferences) string | |||
| 		definitions: strings.new_builder(100) | ||||
| 		gowrappers: strings.new_builder(100) | ||||
| 		stringliterals: strings.new_builder(100) | ||||
| 		auto_str_funcs: strings.new_builder(100) | ||||
| 		inits: strings.new_builder(100) | ||||
| 		table: table | ||||
| 		pref: pref | ||||
|  | @ -147,10 +149,17 @@ pub fn cgen(files []ast.File, table &table.Table, pref &pref.Preferences) string | |||
| 	} | ||||
| 	//
 | ||||
| 	g.finish() | ||||
| 	return g.hashes() + '\n// V typedefs:\n' + g.typedefs.str() + '\n// V typedefs2:\n' + g.typedefs2.str() + | ||||
| 		'\n// V cheaders:\n' + g.cheaders.str() + '\n// V includes:\n' + g.includes.str() + '\n// V definitions:\n' + | ||||
| 		g.definitions.str() + '\n// V gowrappers:\n' + g.gowrappers.str() + '\n// V stringliterals:\n' + | ||||
| 		g.stringliterals.str() + '\n// V out\n' + g.out.str() | ||||
| 	return g.hashes() + | ||||
| 		'\n// V typedefs:\n' + g.typedefs.str() + | ||||
| 		'\n// V typedefs2:\n' + g.typedefs2.str() + | ||||
| 		'\n// V cheaders:\n' + g.cheaders.str() + | ||||
| 		'\n// V includes:\n' + g.includes.str() + | ||||
| 		'\n// V definitions:\n' + g.definitions.str() + | ||||
| 		'\n// V gowrappers:\n' + g.gowrappers.str() + | ||||
| 		'\n// V stringliterals:\n' + g.stringliterals.str() + | ||||
| 		'\n// V auto str functions:\n' + g.auto_str_funcs.str() + | ||||
| 		'\n// V out\n' + g.out.str() + | ||||
| 		'\n// THE END.' | ||||
| } | ||||
| 
 | ||||
| pub fn (g Gen) hashes() string { | ||||
|  | @ -428,19 +437,29 @@ fn (mut g Gen) stmt(node ast.Stmt) { | |||
| 		ast.EnumDecl { | ||||
| 			enum_name := it.name.replace('.', '__') | ||||
| 			g.typedefs.writeln('typedef enum {') | ||||
| 			mut cur_enum_expr := '' | ||||
| 			mut cur_enum_offset := 0 | ||||
| 			for j, field in it.fields { | ||||
| 				g.typedefs.write('\t${enum_name}_$field.name') | ||||
| 				g.typedefs.write('\t${enum_name}_${field.name}') | ||||
| 				if field.has_expr { | ||||
| 					g.typedefs.write(' = ') | ||||
| 					pos := g.out.len | ||||
| 					g.expr(field.expr) | ||||
| 					expr_str := g.out.after(pos) | ||||
| 					g.out.go_back(expr_str.len) | ||||
| 					g.typedefs.write('$expr_str') | ||||
| 					g.typedefs.write(expr_str) | ||||
| 					cur_enum_expr = expr_str | ||||
| 					cur_enum_offset = 0 | ||||
| 				} | ||||
| 				g.typedefs.writeln(', // $j') | ||||
| 				cur_value := if cur_enum_offset > 0 { | ||||
| 				   '${cur_enum_expr}+${cur_enum_offset}' | ||||
| 				} else { | ||||
| 				   cur_enum_expr | ||||
| 				} | ||||
| 				g.typedefs.writeln(', // ${cur_value}') | ||||
| 				cur_enum_offset++ | ||||
| 			} | ||||
| 			g.typedefs.writeln('} $enum_name;\n') | ||||
| 			g.typedefs.writeln('} ${enum_name};\n') | ||||
| 		} | ||||
| 		ast.ExprStmt { | ||||
| 			g.expr(it.expr) | ||||
|  | @ -2302,12 +2321,13 @@ fn (mut g Gen) string_inter_literal(node ast.StringInterLiteral) { | |||
| 				} | ||||
| 				if is_var { | ||||
| 					styp := g.typ(node.expr_types[i]) | ||||
| 					g.gen_str_for_type(sym, styp) | ||||
| 					g.write('${styp}_str(') | ||||
| 					str_fn_name := styp_to_str_fn_name(styp) | ||||
| 					g.gen_str_for_type(sym, styp, str_fn_name) | ||||
| 					g.write('${str_fn_name}(') | ||||
| 					g.enum_expr(expr) | ||||
| 					g.write(')') | ||||
| 					g.write('.len, ') | ||||
| 					g.write('${styp}_str(') | ||||
| 					g.write('${str_fn_name}(') | ||||
| 					g.enum_expr(expr) | ||||
| 					g.write(').str') | ||||
| 				} else { | ||||
|  | @ -2321,22 +2341,24 @@ fn (mut g Gen) string_inter_literal(node ast.StringInterLiteral) { | |||
| 				} | ||||
| 			} else if sym.kind in [.array, .array_fixed] { | ||||
| 				styp := g.typ(node.expr_types[i]) | ||||
| 				g.gen_str_for_type(sym, styp) | ||||
| 				g.write('${styp}_str(') | ||||
| 				str_fn_name := styp_to_str_fn_name(styp) | ||||
| 				g.gen_str_for_type(sym, styp, str_fn_name) | ||||
| 				g.write('${str_fn_name}(') | ||||
| 				g.expr(expr) | ||||
| 				g.write(')') | ||||
| 				g.write('.len, ') | ||||
| 				g.write('${styp}_str(') | ||||
| 				g.write('${str_fn_name}(') | ||||
| 				g.expr(expr) | ||||
| 				g.write(').str') | ||||
| 			} else if sym.kind == .struct_ && !sym.has_method('str') { | ||||
| 				styp := g.typ(node.expr_types[i]) | ||||
| 				g.gen_str_for_type(sym, styp) | ||||
| 				g.write('${styp}_str(') | ||||
| 				str_fn_name := styp_to_str_fn_name(styp) | ||||
| 				g.gen_str_for_type(sym, styp, str_fn_name) | ||||
| 				g.write('${str_fn_name}(') | ||||
| 				g.expr(expr) | ||||
| 				g.write(',0)') | ||||
| 				g.write('.len, ') | ||||
| 				g.write('${styp}_str(') | ||||
| 				g.write('${str_fn_name}(') | ||||
| 				g.expr(expr) | ||||
| 				g.write(',0).str') | ||||
| 			} else { | ||||
|  | @ -2792,22 +2814,28 @@ fn (mut g Gen) is_expr(node ast.InfixExpr) { | |||
| 	g.expr(node.right) | ||||
| } | ||||
| 
 | ||||
| fn styp_to_str_fn_name(styp string) string { | ||||
| 	res := styp.replace('.', '__').replace('*','_ptr') + '_str' | ||||
| 	return res | ||||
| } | ||||
| 
 | ||||
| // already generated styp, reuse it
 | ||||
| fn (mut g Gen) gen_str_for_type(sym table.TypeSymbol, styp string) { | ||||
| 	if sym.has_method('str') || styp in g.str_types { | ||||
| fn (mut g Gen) gen_str_for_type(sym table.TypeSymbol, styp string, str_fn_name string) { | ||||
| 	already_generated_key := '${styp}:${str_fn_name}' | ||||
| 	if sym.has_method('str') ||  already_generated_key in g.str_types { | ||||
| 		return | ||||
| 	} | ||||
| 	g.str_types << styp | ||||
| 	g.str_types << already_generated_key | ||||
| 	match sym.info { | ||||
| 		table.Alias { g.gen_str_default(sym, styp) } | ||||
| 		table.Array { g.gen_str_for_array(it, styp) } | ||||
| 		table.Enum { g.gen_str_for_enum(it, styp) } | ||||
| 		table.Struct { g.gen_str_for_struct(it, styp) } | ||||
| 		else { verror("could not generate string method for type \'${styp}\'") } | ||||
| 		table.Alias { g.gen_str_default(sym, styp, str_fn_name) } | ||||
| 		table.Array { g.gen_str_for_array(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) } | ||||
| 		else { verror("could not generate string method $str_fn_name for type \'${styp}\'") } | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| fn (mut g Gen) gen_str_default(sym table.TypeSymbol, styp string) { | ||||
| fn (mut g Gen) gen_str_default(sym table.TypeSymbol, styp string, str_fn_name string) { | ||||
| 	mut convertor := '' | ||||
| 	mut typename := '' | ||||
| 	if sym.parent_idx in table.integer_type_idxs { | ||||
|  | @ -2825,97 +2853,127 @@ fn (mut g Gen) gen_str_default(sym table.TypeSymbol, styp string) { | |||
| 	} else { | ||||
| 		verror("could not generate string method for type \'${styp}\'") | ||||
| 	} | ||||
| 	g.definitions.writeln('string ${styp}_str($styp it) {') | ||||
| 	g.definitions.writeln('string ${str_fn_name}($styp it); // auto') | ||||
| 	g.auto_str_funcs.writeln('string ${str_fn_name}($styp it) {') | ||||
| 	if convertor == 'bool' { | ||||
| 		g.definitions.writeln('\tstring tmp1 = string_add(tos3("${styp}("), (${convertor})it ? tos3("true") : tos3("false"));') | ||||
| 		g.auto_str_funcs.writeln('\tstring tmp1 = string_add(tos3("${styp}("), (${convertor})it ? tos3("true") : tos3("false"));') | ||||
| 	} else { | ||||
| 		g.definitions.writeln('\tstring tmp1 = string_add(tos3("${styp}("), tos3(${typename}_str((${convertor})it).str));') | ||||
| 		g.auto_str_funcs.writeln('\tstring tmp1 = string_add(tos3("${styp}("), tos3(${typename}_str((${convertor})it).str));') | ||||
| 	} | ||||
| 	g.definitions.writeln('\tstring tmp2 = string_add(tmp1, tos3(")"));') | ||||
| 	g.definitions.writeln('\tstring_free(tmp1);') | ||||
| 	g.definitions.writeln('\treturn tmp2;') | ||||
| 	g.definitions.writeln('}') | ||||
| 	g.auto_str_funcs.writeln('\tstring tmp2 = string_add(tmp1, tos3(")"));') | ||||
| 	g.auto_str_funcs.writeln('\tstring_free(tmp1);') | ||||
| 	g.auto_str_funcs.writeln('\treturn tmp2;') | ||||
| 	g.auto_str_funcs.writeln('}') | ||||
| } | ||||
| 
 | ||||
| fn (mut g Gen) gen_str_for_enum(info table.Enum, styp string) { | ||||
| fn (mut g Gen) gen_str_for_enum(info table.Enum, styp string, str_fn_name string) { | ||||
| 	s := styp.replace('.', '__') | ||||
| 	g.definitions.write('string ${s}_str($styp it) {\n\tswitch(it) {\n') | ||||
| 	g.definitions.writeln('string ${str_fn_name}($styp it); // auto') | ||||
| 	g.auto_str_funcs.writeln('string ${str_fn_name}($styp it) { /* gen_str_for_enum */') | ||||
| 	g.auto_str_funcs.writeln('\tswitch(it) {') | ||||
| 	for i, val in info.vals { | ||||
| 		g.definitions.write('\t\tcase ${s}_$val: return tos3("$val");\n') | ||||
| 		g.auto_str_funcs.writeln('\t\tcase ${s}_$val: return tos3("$val");') | ||||
| 	} | ||||
| 	g.definitions.write('\t\tdefault: return tos3("unknown enum value"); } }\n') | ||||
| 	g.auto_str_funcs.writeln('\t\tdefault: return tos3("unknown enum value");') | ||||
| 	g.auto_str_funcs.writeln('\t}') | ||||
| 	g.auto_str_funcs.writeln('}') | ||||
| } | ||||
| 
 | ||||
| fn (mut g Gen) gen_str_for_struct(info table.Struct, styp string) { | ||||
| fn (mut g Gen) gen_str_for_struct(info table.Struct, styp string, str_fn_name string) { | ||||
| 	// TODO: short it if possible
 | ||||
| 	// generates all definitions of substructs
 | ||||
| 	mut fnames2strfunc := map[string]string | ||||
| 	for i, field in info.fields { | ||||
| 		sym := g.table.get_type_symbol(field.typ) | ||||
| 		if sym.kind == .struct_ { | ||||
| 		if sym.kind in [.struct_, .array, .array_fixed, .enum_] { | ||||
| 			field_styp := g.typ(field.typ) | ||||
| 			g.gen_str_for_type(sym, field_styp) | ||||
| 			field_fn_name := styp_to_str_fn_name( field_styp ) | ||||
| 			fnames2strfunc[ field_styp ] = field_fn_name | ||||
| 			g.gen_str_for_type(sym, field_styp, field_fn_name) | ||||
| 		} | ||||
| 	} | ||||
| 	s := styp.replace('.', '__') | ||||
| 	g.definitions.write('string ${s}_str($styp it, int indent_count) {\n') | ||||
| 	g.definitions.writeln('string ${str_fn_name}($styp x, int indent_count); // auto') | ||||
| 	g.auto_str_funcs.writeln('string ${str_fn_name}($styp x, int indent_count) {') | ||||
| 	mut clean_struct_v_type_name := styp.replace('__','.') | ||||
| 	if styp.ends_with('*') { | ||||
| 		deref_typ := styp.replace('*', '') | ||||
| 		g.auto_str_funcs.writeln('\t${deref_typ} *it = x;') | ||||
| 		clean_struct_v_type_name = '&' + clean_struct_v_type_name.replace('*', '') | ||||
| 	}else{ | ||||
| 		deref_typ := styp | ||||
| 		g.auto_str_funcs.writeln('\t${deref_typ} *it = &x;') | ||||
| 	} | ||||
| 	// generate ident / indent length = 4 spaces
 | ||||
| 	g.definitions.write('\tstring indents = tos3("");\n\tfor (int i = 0; i < indent_count; i++) { indents = string_add(indents, tos3("    ")); }\n') | ||||
| 	g.definitions.write('\treturn _STR("$styp {\\n') | ||||
| 	g.auto_str_funcs.writeln('\tstring indents = tos3("");') | ||||
| 	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}') | ||||
| 	g.auto_str_funcs.writeln('\treturn _STR("${clean_struct_v_type_name} {\\n"') | ||||
| 	for field in info.fields { | ||||
| 		fmt := g.type_to_fmt(field.typ) | ||||
| 		g.definitions.write('%.*s    ' + '$field.name: $fmt\\n') | ||||
| 		g.auto_str_funcs.writeln('\t\t"%.*s    ' + '$field.name: $fmt\\n"') | ||||
| 	} | ||||
| 	g.definitions.write('%.*s}"') | ||||
| 	g.auto_str_funcs.write('\t\t"%.*s}"') | ||||
| 	if info.fields.len > 0 { | ||||
| 		g.definitions.write(', ') | ||||
| 		g.auto_str_funcs.write(',\n\t\t') | ||||
| 		for i, field in info.fields { | ||||
| 			sym := g.table.get_type_symbol(field.typ) | ||||
| 			if sym.kind in [.struct_, .array, .array_fixed] { | ||||
| 				field_styp := g.typ(field.typ) | ||||
| 				second_str_param := if sym.has_method('str') { '' } else { ', indent_count + 1' } | ||||
| 				g.definitions.write('indents.len, indents.str, ${field_styp}_str(it.$field.name$second_str_param).len, ${field_styp}_str(it.$field.name$second_str_param).str') | ||||
| 			has_custom_str := sym.has_method('str') | ||||
| 			second_str_param := if has_custom_str {''} else {', indent_count + 1'} | ||||
| 			field_styp := g.typ(field.typ) | ||||
| 			field_styp_fn_name := if has_custom_str {'${field_styp}_str'} else {fnames2strfunc[ field_styp ]} | ||||
| 			if sym.kind  == .enum_ { | ||||
| 				g.auto_str_funcs.write('indents.len, indents.str, ') | ||||
| 				g.auto_str_funcs.write('${field_styp_fn_name}( it->${field.name} ).len, ') | ||||
| 				g.auto_str_funcs.write('${field_styp_fn_name}( it->${field.name} ).str  ') | ||||
| 			}else if sym.kind in [.struct_, .array, .array_fixed] { | ||||
| 				g.auto_str_funcs.write('indents.len, indents.str, ') | ||||
| 				g.auto_str_funcs.write('${field_styp_fn_name}( it->${field.name}${second_str_param} ).len, ') | ||||
| 				g.auto_str_funcs.write('${field_styp_fn_name}( it->${field.name}${second_str_param} ).str  ') | ||||
| 			} else { | ||||
| 				g.definitions.write('indents.len, indents.str, it.$field.name') | ||||
| 				g.auto_str_funcs.write('indents.len, indents.str, it->${field.name}') | ||||
| 				if field.typ == table.string_type { | ||||
| 					g.definitions.write('.len, it.${field.name}.str') | ||||
| 					g.auto_str_funcs.write('.len, it->${field.name}.str') | ||||
| 				} else if field.typ == table.bool_type { | ||||
| 					g.definitions.write(' ? 4 : 5, it.${field.name} ? "true" : "false"') | ||||
| 					g.auto_str_funcs.write(' ? 4 : 5, it->${field.name} ? "true" : "false"') | ||||
| 				} | ||||
| 			} | ||||
| 			if i < info.fields.len - 1 { | ||||
| 				g.definitions.write(', ') | ||||
| 				g.auto_str_funcs.write(',\n\t\t') | ||||
| 			} | ||||
| 		} | ||||
| 	} | ||||
| 	g.definitions.writeln(', indents.len, indents.str);\n}') | ||||
| 	g.auto_str_funcs.writeln(',') | ||||
| 	g.auto_str_funcs.writeln('\t\tindents.len, indents.str);') | ||||
| 	g.auto_str_funcs.writeln('}') | ||||
| } | ||||
| 
 | ||||
| fn (mut g Gen) gen_str_for_array(info table.Array, styp string) { | ||||
| 	s := styp.replace('.', '__') | ||||
| fn (mut g Gen) gen_str_for_array(info table.Array, styp string, str_fn_name string) { | ||||
| 	sym := g.table.get_type_symbol(info.elem_type) | ||||
| 	field_styp := g.typ(info.elem_type) | ||||
| 	if sym.kind == .struct_ && !sym.has_method('str') { | ||||
| 		g.gen_str_for_type(sym, field_styp) | ||||
| 		g.gen_str_for_type(sym, field_styp, styp_to_str_fn_name(field_styp) ) | ||||
| 	} | ||||
| 	g.definitions.writeln('string ${s}_str($styp a) {') | ||||
| 	g.definitions.writeln('\tstrings__Builder sb = strings__new_builder(a.len * 10);') | ||||
| 	g.definitions.writeln('\tstrings__Builder_write(&sb, tos3("["));') | ||||
| 	g.definitions.writeln('\tfor (int i = 0; i < a.len; i++) {') | ||||
| 	g.definitions.writeln('\t\t${field_styp} it = (*(${field_styp}*)array_get(a, i));') | ||||
| 	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('\tstrings__Builder sb = strings__new_builder(a.len * 10);') | ||||
| 	g.auto_str_funcs.writeln('\tstrings__Builder_write(&sb, tos3("["));') | ||||
| 	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_method('str') { | ||||
| 		g.definitions.writeln('\t\t\tstrings__Builder_write(&sb, ${field_styp}_str(it,0));') | ||||
| 		g.auto_str_funcs.writeln('\t\t\tstrings__Builder_write(&sb, ${field_styp}_str(it,0));') | ||||
| 	} else if sym.kind in [.f32, .f64] { | ||||
| 		g.definitions.writeln('\t\t\tstrings__Builder_write(&sb, _STR("%g", it));') | ||||
| 		g.auto_str_funcs.writeln('\t\t\tstrings__Builder_write(&sb, _STR("%g", it));') | ||||
| 	} else { | ||||
| 		g.definitions.writeln('\t\t\tstrings__Builder_write(&sb, ${field_styp}_str(it));') | ||||
| 		g.auto_str_funcs.writeln('\t\t\tstrings__Builder_write(&sb, ${field_styp}_str(it));') | ||||
| 	} | ||||
| 	g.definitions.writeln('\t\tif (i != a.len-1) {') | ||||
| 	g.definitions.writeln('\t\t\tstrings__Builder_write(&sb, tos3(", "));') | ||||
| 	g.definitions.writeln('\t\t}') | ||||
| 	g.definitions.writeln('\t}') | ||||
| 	g.definitions.writeln('\tstrings__Builder_write(&sb, tos3("]"));') | ||||
| 	g.definitions.writeln('\treturn strings__Builder_str(&sb);') | ||||
| 	g.definitions.writeln('}') | ||||
| 	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}') | ||||
| 	g.auto_str_funcs.writeln('\t}') | ||||
| 	g.auto_str_funcs.writeln('\tstrings__Builder_write(&sb, tos3("]"));') | ||||
| 	g.auto_str_funcs.writeln('\treturn strings__Builder_str(&sb);') | ||||
| 	g.auto_str_funcs.writeln('}') | ||||
| } | ||||
| 
 | ||||
| fn (g Gen) type_to_fmt(typ table.Type) string { | ||||
|  | @ -2926,6 +2984,8 @@ fn (g Gen) type_to_fmt(typ table.Type) string { | |||
| 		return "\'%.*s\'" | ||||
| 	} else if typ == table.bool_type { | ||||
| 		return '%.*s' | ||||
| 	} else if sym.kind == .enum_ { | ||||
| 		return '%.*s' | ||||
| 	} else if typ in [table.f32_type, table.f64_type] { | ||||
| 		return '%g' // g removes trailing zeros unlike %f
 | ||||
| 	} | ||||
|  |  | |||
|  | @ -310,12 +310,13 @@ fn (g mut Gen) fn_call(node ast.CallExpr) { | |||
| 		if table.type_is_ptr(typ) { | ||||
| 			styp = styp.replace('*', '') | ||||
| 		} | ||||
| 		g.gen_str_for_type(sym, styp) | ||||
| 		mut str_fn_name := styp_to_str_fn_name(styp) | ||||
| 		g.gen_str_for_type(sym, styp, str_fn_name) | ||||
| 		if g.autofree && !table.type_is(typ, .optional) { | ||||
| 			// Create a temporary variable so that the value can be freed
 | ||||
| 			tmp := g.new_tmp_var() | ||||
| 			// tmps << tmp
 | ||||
| 			g.write('string $tmp = ${styp}_str(') | ||||
| 			g.write('string $tmp = ${str_fn_name}(') | ||||
| 			g.expr(node.args[0].expr) | ||||
| 			g.writeln('); ${print_method}($tmp); string_free($tmp); //MEM2 $styp') | ||||
| 		} else { | ||||
|  | @ -334,10 +335,11 @@ fn (g mut Gen) fn_call(node ast.CallExpr) { | |||
| 			if table.type_is_ptr(typ) && sym.kind != .struct_ { | ||||
| 				// ptr_str() for pointers
 | ||||
| 				styp = 'ptr' | ||||
| 				str_fn_name = 'ptr_str' | ||||
| 			} | ||||
| 			if sym.kind == .enum_ { | ||||
| 				if is_var { | ||||
| 					g.write('${print_method}(${styp}_str(') | ||||
| 					g.write('${print_method}(${str_fn_name}(') | ||||
| 				} else { | ||||
| 					// when no var, print string directly
 | ||||
| 					g.write('${print_method}(tos3("') | ||||
|  | @ -352,7 +354,7 @@ fn (g mut Gen) fn_call(node ast.CallExpr) { | |||
| 					g.write('"') | ||||
| 				} | ||||
| 			} else { | ||||
| 				g.write('${print_method}(${styp}_str(') | ||||
| 				g.write('${print_method}(${str_fn_name}(') | ||||
| 				if table.type_is_ptr(typ) && sym.kind == .struct_ { | ||||
| 					// dereference
 | ||||
| 					g.write('*') | ||||
|  |  | |||
|  | @ -26,3 +26,10 @@ fn test_enum_non_default_value() { | |||
| 	assert int(t.e) == 22 | ||||
| 	assert 't.e: $t.e | int(t.e): ${int(t.e).str()}' == 't.e: third | int(t.e): 22' | ||||
| } | ||||
| 
 | ||||
| fn test_generation_of_string_interpolation_method_for_pointer_to_struct_containing_enum_fields(){ | ||||
| 	t := &MyStruct{ | ||||
| 		e: .third | ||||
| 	} | ||||
| 	assert 't: $t' == 't: &MyStruct {\n    e: third\n}' | ||||
| } | ||||
|  |  | |||
		Loading…
	
		Reference in New Issue