From 06173834c003a2cfcb05e9fcaf3902185fd95fad Mon Sep 17 00:00:00 2001 From: Alexander Medvednikov Date: Sat, 2 May 2020 10:10:52 +0200 Subject: [PATCH] cgen: interface_call() --- vlib/v/gen/cgen.v | 70 +++++++++++++++++++++++++++-------------------- vlib/v/gen/fn.v | 7 +++-- 2 files changed, 45 insertions(+), 32 deletions(-) diff --git a/vlib/v/gen/cgen.v b/vlib/v/gen/cgen.v index b68a5d2d67..ed5391400e 100644 --- a/vlib/v/gen/cgen.v +++ b/vlib/v/gen/cgen.v @@ -36,11 +36,11 @@ const ( 'unsigned', 'void', 'volatile', - 'while', - //'new' + 'while' ] ) +// 'new' fn foo(t token.Token) { util.full_hash() } @@ -2202,9 +2202,10 @@ string _STR(const char *fmt, int nfmts, ...) { int k = strlen(fmt); bool is_fspec = false; for (int j=0; j= '+"'E'"+' && fup <= '+"'G'"+') { // floating point + } else if (fup >= ' + + "'E'" + ' && fup <= ' + "'G'" + ') { // floating point _STR_PRINT_ARG(fmt, &buf, &nbytes, &memsize, k+10, va_arg(argptr, double)); - } else if (f == '+"'s'"+') { // v string + } else if (f == ' + + "'s'" + ') { // v string string s = va_arg(argptr, string); - if (fmt[k-4] == '+"'*'"+') { // %*.*s + if (fmt[k-4] == ' + "'*'" + + ') { // %*.*s int fwidth = va_arg(argptr, int); if (fwidth < 0) fwidth -= (s.len - utf8_str_len(s)); @@ -2440,13 +2446,13 @@ fn (mut g Gen) string_inter_literal(node ast.StringInterLiteral) { sym := g.table.get_type_symbol(node.expr_types[i]) sfmt := node.expr_fmts[i] mut fspec := `_` // placeholder - mut fmt := '' // field width and precision + mut fmt := '' // field width and precision if sfmt.len > 0 { // analyze and validate format specifier if sfmt[sfmt.len - 1] in [`E`, `F`, `G`, `e`, `f`, `g`, `e`, `d`, `u`, `x`, `X`, `o`, `c`, `s`] { - fspec = sfmt[sfmt.len - 1] - } + fspec = sfmt[sfmt.len - 1] + } fmt = if fspec == `_` { sfmt[1..sfmt.len] } else { @@ -2460,9 +2466,8 @@ fn (mut g Gen) string_inter_literal(node ast.StringInterLiteral) { fspec = `d` } else if node.expr_types[i].is_unsigned() { fspec = `u` - } else if node.expr_types[i] in [table.string_type, table.bool_type] || - sym.kind in [.enum_, .array, .array_fixed, .struct_, .map] || - g.typ(node.expr_types[i]).starts_with('Option') || + } else if node.expr_types[i] in [table.string_type, table.bool_type] || sym.kind in + [.enum_, .array, .array_fixed, .struct_, .map] || g.typ(node.expr_types[i]).starts_with('Option') || sym.has_method('str') { fspec = `s` } else { @@ -2473,17 +2478,17 @@ fn (mut g Gen) string_inter_literal(node ast.StringInterLiteral) { fields := fmt.split('.') // validate format // only floats should have precision specifier - if fields.len > 2 || fields.len == 2 && !(node.expr_types[i].is_float()) || - node.expr_types[i].is_signed() && !(fspec in [`d`, `c`, `x`, `X`, `o`]) || - node.expr_types[i].is_unsigned() && !(fspec in [`u`, `x`, `X`, `o`, `c`]) || - node.expr_types[i].is_float() && !(fspec in [`E`, `F`, `G`, `e`, `f`, `g`, `e`]) { + if fields.len > 2 || fields.len == 2 && !(node.expr_types[i].is_float()) || node.expr_types[i].is_signed() && + !(fspec in [`d`, `c`, `x`, `X`, `o`]) || node.expr_types[i].is_unsigned() && !(fspec in [`u`, + `x`, `X`, `o`, `c`]) || node.expr_types[i].is_float() && !(fspec in [`E`, `F`, `G`, `e`, `f`, + `g`, `e`]) { verror('illegal format specifier ${fspec:c} for type ${g.table.get_type_name(node.expr_types[i])}') } // make sure that format paramters are valid numbers for j, f in fields { for k, c in f { - if (c < `0` || c > `9`) && - !(j == 0 && k == 0 && (node.expr_types[i].is_number() && c == `+` || c == `-`)) { + if (c < `0` || c > `9`) && !(j == 0 && k == 0 && (node.expr_types[i].is_number() && + c == `+` || c == `-`)) { verror('illegal character ${c:c} in format specifier ${fmt}') } } @@ -2506,8 +2511,8 @@ fn (mut g Gen) string_inter_literal(node ast.StringInterLiteral) { g.write('$fmt${fspec:c}') } else if node.expr_types[i].is_int() { if fspec == `c` { - if node.expr_types[i].idx() in [table.i64_type_idx table.f64_type_idx] { - verror("64 bit integer types cannot be interpolated as character") + if node.expr_types[i].idx() in [table.i64_type_idx, table.f64_type_idx] { + verror('64 bit integer types cannot be interpolated as character') } else { g.write('${fmt}c') } @@ -2565,11 +2570,7 @@ fn (mut g Gen) string_inter_literal(node ast.StringInterLiteral) { } } else if sym.has_method('str') || sym.kind in [.array, .array_fixed, .map, .struct_] { is_p := node.expr_types[i].is_ptr() - val_type := if is_p { - node.expr_types[i].deref() - } else { - node.expr_types[i] - } + val_type := if is_p { node.expr_types[i].deref() } else { node.expr_types[i] } str_fn_name := g.gen_str_for_type(val_type) if is_p { g.write('string_add(_SLIT("&"), ${str_fn_name}(*(') @@ -3550,9 +3551,12 @@ fn (mut g Gen) array_init(it ast.ArrayInit) { if it.is_interface { // sym := g.table.get_type_symbol(it.interface_types[i]) // isym := g.table.get_type_symbol(it.interface_type) + /* interface_styp := g.typ(it.interface_type) styp := g.typ(it.interface_types[i]) g.write('I_${styp}_to_${interface_styp}(') + */ + g.interface_call(it.interface_types[i], it.interface_type) } g.expr(expr) if it.is_interface { @@ -3562,3 +3566,11 @@ fn (mut g Gen) array_init(it ast.ArrayInit) { } g.write('\n})') } + +// `ui.foo(button)` => +// `ui__foo(I_ui__Button_to_ui__Widget(` ... +fn (g &Gen) interface_call(typ, interface_type table.Type) { + interface_styp := g.typ(interface_type).replace('*', '') + styp := g.typ(typ).replace('*', '') + g.write('I_${styp}_to_${interface_styp}(') +} diff --git a/vlib/v/gen/fn.v b/vlib/v/gen/fn.v index d3b16dfa34..a47d8670ed 100644 --- a/vlib/v/gen/fn.v +++ b/vlib/v/gen/fn.v @@ -508,10 +508,11 @@ fn (mut g Gen) call_args(args []ast.CallArg, expected_types []table.Type) { // Cast a type to interface // `foo(dog)` => `foo(I_Dog_to_Animal(dog))` exp_sym := g.table.get_type_symbol(expected_types[arg_no]) - exp_styp := g.typ(expected_types[arg_no]) // g.table.get_type_symbol(expected_types[arg_no]) - styp := g.typ(arg.typ) // g.table.get_type_symbol(arg.typ) + // exp_styp := g.typ(expected_types[arg_no]) // g.table.get_type_symbol(expected_types[arg_no]) + // styp := g.typ(arg.typ) // g.table.get_type_symbol(arg.typ) if exp_sym.kind == .interface_ { - g.write('I_${styp}_to_${exp_styp}(') + g.interface_call(arg.typ, expected_types[arg_no]) + // g.write('/*Z*/I_${styp}_to_${exp_styp}(') is_interface = true } }