diff --git a/compiler/fn.v b/compiler/fn.v index 0a01c84117..7d5cb054a4 100644 --- a/compiler/fn.v +++ b/compiler/fn.v @@ -706,6 +706,19 @@ fn (p mut Parser) fn_call_args(f *Fn) *Fn { else { // Make sure this type has a `str()` method if !T.has_method('str') { + if ((*T).fields.len > 0) { + mut index := p.cgen.cur_line.len - 1 + for index > 0 && p.cgen.cur_line[index] != ` ` { index-- } + name := p.cgen.cur_line.right(index + 1) + if name == '}' { + p.error('`$typ` needs to have method `str() string` to be printable') + } + p.cgen.cur_line = p.cgen.cur_line.left(index) + p.create_type_string(*T, name) + p.cgen.cur_line.replace(typ, '') + p.next() + return p.fn_call_args(f) + } p.error('`$typ` needs to have method `str() string` to be printable') } p.cgen.set_placeholder(amp_ph, '${typ}_str(') diff --git a/compiler/scanner.v b/compiler/scanner.v index 99e348e0e5..6941141cc0 100644 --- a/compiler/scanner.v +++ b/compiler/scanner.v @@ -654,3 +654,49 @@ fn is_name_char(c byte) bool { return c.is_letter() || c == `_` } +fn (s mut Scanner) get_opening_bracket() int { + mut pos := s.pos + mut parentheses := 0 + mut inside_string := false + + for pos > 0 && s.text[pos] != `\n` { + if s.text[pos] == `)` && !inside_string { + parentheses++ + } + if s.text[pos] == `(` && !inside_string { + parentheses-- + } + if s.text[pos] == `\'` && s.text[pos - 1] != `\\` && s.text[pos - 1] != `\`` { + inside_string = !inside_string + } + if parentheses == 0 { + break + } + pos-- + } + return pos +} + +fn (s mut Scanner) create_type_string(T Type, name string) { + line := s.line_nr + inside_string := s.inside_string + mut newtext := '\'{ ' + start := s.get_opening_bracket() + 1 + end := s.pos + + for i, field in T.fields { + if i != 0 { + newtext += ', ' + } + newtext += '$field.name: ' + '$${name}.${field.name}' + } + newtext += ' }\'' + s.text = s.text.substr(0, start) + newtext + s.text.substr(end, s.text.len) + s.pos = start - 2 + s.line_nr = line + s.inside_string = inside_string +} + +fn (p mut Parser) create_type_string(T Type, name string) { + p.scanner.create_type_string(T, name) +} \ No newline at end of file