From 780ddaf22baa78b73e11475823769827d55e2951 Mon Sep 17 00:00:00 2001 From: Henrixounez Date: Thu, 22 Aug 2019 06:56:29 +0200 Subject: [PATCH] compiler: handles printing of structures and arrays of structures --- compiler/comptime.v | 3 +++ compiler/parser.v | 13 ++++++++++++- vlib/builtin/array_test.v | 36 +++++++++++++++++++++++++++++++++++- 3 files changed, 50 insertions(+), 2 deletions(-) diff --git a/compiler/comptime.v b/compiler/comptime.v index c60be674ef..e081fbe427 100644 --- a/compiler/comptime.v +++ b/compiler/comptime.v @@ -253,6 +253,9 @@ fn (p mut Parser) gen_array_str(typ mut Type) { }) t := typ.name elm_type := t.right(6) + if p.typ_to_fmt(elm_type, 0) == '' && !p.table.type_has_method(p.table.find_type(elm_type), 'str') { + p.error('cant print ${elm_type}[], unhandled print of ${elm_type}') + } p.cgen.fns << ' string ${t}_str($t a) { strings__Builder sb = strings__new_builder(a.len * 3); diff --git a/compiler/parser.v b/compiler/parser.v index 64cade9538..f02063094b 100644 --- a/compiler/parser.v +++ b/compiler/parser.v @@ -2547,7 +2547,18 @@ fn (p mut Parser) string_expr() { else { f := p.typ_to_fmt(typ, 0) if f == '' { - p.error('unhandled sprintf format "$typ" ') + is_array := typ.starts_with('array_') + has_str_method := p.table.type_has_method(p.table.find_type(typ), 'str') + if is_array || has_str_method { + if is_array && !has_str_method { + p.gen_array_str(mut p.table.find_type(typ)) + } + args = args.all_before_last(val) + '${typ}_str(${val}).len, ${typ}_str(${val}).str' + format += '%.*s ' + } + else { + p.error('unhandled sprintf format "$typ" ') + } } format += f } diff --git a/vlib/builtin/array_test.v b/vlib/builtin/array_test.v index 516d6b653b..68a82b176d 100644 --- a/vlib/builtin/array_test.v +++ b/vlib/builtin/array_test.v @@ -205,4 +205,38 @@ fn test_doubling() { nums[i] *= 2 } assert nums.str() == '[2, 4, 6, 8, 10]' -} \ No newline at end of file +} + +struct Test2 { + one int + two int +} + +struct Test { + a string + b []Test2 +} + +fn (t Test2) str() string { + return '{$t.one $t.two}' +} + +fn (t Test) str() string { + return '{$t.a $t.b}' +} + +fn test_struct_print() { + mut a := Test { + a: 'Test', + b: []Test2 + } + b := Test2 { + one: 1, + two: 2 + } + a.b << b + a.b << b + assert a.str() == '{Test [{1 2}, {1 2}] }' + assert b.str() == '{1 2}' + assert a.b.str() == '[{1 2}, {1 2}]' +}