mirror of
https://github.com/vlang/v.git
synced 2023-08-10 21:13:21 +03:00
cgen: interface_call()
This commit is contained in:
parent
aa9bb6f71a
commit
06173834c0
@ -36,11 +36,11 @@ const (
|
|||||||
'unsigned',
|
'unsigned',
|
||||||
'void',
|
'void',
|
||||||
'volatile',
|
'volatile',
|
||||||
'while',
|
'while'
|
||||||
//'new'
|
|
||||||
]
|
]
|
||||||
)
|
)
|
||||||
|
|
||||||
|
// 'new'
|
||||||
fn foo(t token.Token) {
|
fn foo(t token.Token) {
|
||||||
util.full_hash()
|
util.full_hash()
|
||||||
}
|
}
|
||||||
@ -2202,9 +2202,10 @@ string _STR(const char *fmt, int nfmts, ...) {
|
|||||||
int k = strlen(fmt);
|
int k = strlen(fmt);
|
||||||
bool is_fspec = false;
|
bool is_fspec = false;
|
||||||
for (int j=0; j<k; j++) {
|
for (int j=0; j<k; j++) {
|
||||||
if (fmt[j] == '+"'%'"+') {
|
if (fmt[j] == ' +
|
||||||
|
"'%'" + ') {
|
||||||
j++;
|
j++;
|
||||||
if(fmt[j] != '+"'%'"+') {
|
if(fmt[j] != ' + "'%'" + ') {
|
||||||
is_fspec = true;
|
is_fspec = true;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@ -2213,17 +2214,22 @@ string _STR(const char *fmt, int nfmts, ...) {
|
|||||||
if (is_fspec) {
|
if (is_fspec) {
|
||||||
char f = fmt[k-1];
|
char f = fmt[k-1];
|
||||||
char fup = f & 0xdf; // toupper
|
char fup = f & 0xdf; // toupper
|
||||||
bool l = fmt[k-2] == '+"'l'"+';
|
bool l = fmt[k-2] == ' +
|
||||||
bool ll = l && fmt[k-3] == '+"'l'"+';
|
"'l'" + ';
|
||||||
if (f == '+"'u'"+' || fup == '+"'X'"+' || f == '+"'o'"+' || f == '+"'d'"+' || f == '+"'c'"+') { // int...
|
bool ll = l && fmt[k-3] == ' + "'l'" + ';
|
||||||
|
if (f == ' + "'u'" + ' || fup == ' +
|
||||||
|
"'X'" + ' || f == ' + "'o'" + ' || f == ' + "'d'" + ' || f == ' + "'c'" + ') { // int...
|
||||||
if (ll) _STR_PRINT_ARG(fmt, &buf, &nbytes, &memsize, k+16, va_arg(argptr, long long));
|
if (ll) _STR_PRINT_ARG(fmt, &buf, &nbytes, &memsize, k+16, va_arg(argptr, long long));
|
||||||
else if (l) _STR_PRINT_ARG(fmt, &buf, &nbytes, &memsize, k+10, va_arg(argptr, long));
|
else if (l) _STR_PRINT_ARG(fmt, &buf, &nbytes, &memsize, k+10, va_arg(argptr, long));
|
||||||
else _STR_PRINT_ARG(fmt, &buf, &nbytes, &memsize, k+8, va_arg(argptr, int));
|
else _STR_PRINT_ARG(fmt, &buf, &nbytes, &memsize, k+8, va_arg(argptr, int));
|
||||||
} else if (fup >= '+"'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));
|
_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);
|
string s = va_arg(argptr, string);
|
||||||
if (fmt[k-4] == '+"'*'"+') { // %*.*s
|
if (fmt[k-4] == ' + "'*'" +
|
||||||
|
') { // %*.*s
|
||||||
int fwidth = va_arg(argptr, int);
|
int fwidth = va_arg(argptr, int);
|
||||||
if (fwidth < 0)
|
if (fwidth < 0)
|
||||||
fwidth -= (s.len - utf8_str_len(s));
|
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])
|
sym := g.table.get_type_symbol(node.expr_types[i])
|
||||||
sfmt := node.expr_fmts[i]
|
sfmt := node.expr_fmts[i]
|
||||||
mut fspec := `_` // placeholder
|
mut fspec := `_` // placeholder
|
||||||
mut fmt := '' // field width and precision
|
mut fmt := '' // field width and precision
|
||||||
if sfmt.len > 0 {
|
if sfmt.len > 0 {
|
||||||
// analyze and validate format specifier
|
// analyze and validate format specifier
|
||||||
if sfmt[sfmt.len - 1] in [`E`, `F`, `G`, `e`, `f`, `g`, `e`,
|
if sfmt[sfmt.len - 1] in [`E`, `F`, `G`, `e`, `f`, `g`, `e`,
|
||||||
`d`, `u`, `x`, `X`, `o`, `c`, `s`] {
|
`d`, `u`, `x`, `X`, `o`, `c`, `s`] {
|
||||||
fspec = sfmt[sfmt.len - 1]
|
fspec = sfmt[sfmt.len - 1]
|
||||||
}
|
}
|
||||||
fmt = if fspec == `_` {
|
fmt = if fspec == `_` {
|
||||||
sfmt[1..sfmt.len]
|
sfmt[1..sfmt.len]
|
||||||
} else {
|
} else {
|
||||||
@ -2460,9 +2466,8 @@ fn (mut g Gen) string_inter_literal(node ast.StringInterLiteral) {
|
|||||||
fspec = `d`
|
fspec = `d`
|
||||||
} else if node.expr_types[i].is_unsigned() {
|
} else if node.expr_types[i].is_unsigned() {
|
||||||
fspec = `u`
|
fspec = `u`
|
||||||
} else if node.expr_types[i] in [table.string_type, table.bool_type] ||
|
} else if node.expr_types[i] in [table.string_type, table.bool_type] || sym.kind in
|
||||||
sym.kind in [.enum_, .array, .array_fixed, .struct_, .map] ||
|
[.enum_, .array, .array_fixed, .struct_, .map] || g.typ(node.expr_types[i]).starts_with('Option') ||
|
||||||
g.typ(node.expr_types[i]).starts_with('Option') ||
|
|
||||||
sym.has_method('str') {
|
sym.has_method('str') {
|
||||||
fspec = `s`
|
fspec = `s`
|
||||||
} else {
|
} else {
|
||||||
@ -2473,17 +2478,17 @@ fn (mut g Gen) string_inter_literal(node ast.StringInterLiteral) {
|
|||||||
fields := fmt.split('.')
|
fields := fmt.split('.')
|
||||||
// validate format
|
// validate format
|
||||||
// only floats should have precision specifier
|
// only floats should have precision specifier
|
||||||
if fields.len > 2 || fields.len == 2 && !(node.expr_types[i].is_float()) ||
|
if fields.len > 2 || fields.len == 2 && !(node.expr_types[i].is_float()) || node.expr_types[i].is_signed() &&
|
||||||
node.expr_types[i].is_signed() && !(fspec in [`d`, `c`, `x`, `X`, `o`]) ||
|
!(fspec in [`d`, `c`, `x`, `X`, `o`]) || node.expr_types[i].is_unsigned() && !(fspec in [`u`,
|
||||||
node.expr_types[i].is_unsigned() && !(fspec in [`u`, `x`, `X`, `o`, `c`]) ||
|
`x`, `X`, `o`, `c`]) || node.expr_types[i].is_float() && !(fspec in [`E`, `F`, `G`, `e`, `f`,
|
||||||
node.expr_types[i].is_float() && !(fspec in [`E`, `F`, `G`, `e`, `f`, `g`, `e`]) {
|
`g`, `e`]) {
|
||||||
verror('illegal format specifier ${fspec:c} for type ${g.table.get_type_name(node.expr_types[i])}')
|
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
|
// make sure that format paramters are valid numbers
|
||||||
for j, f in fields {
|
for j, f in fields {
|
||||||
for k, c in f {
|
for k, c in f {
|
||||||
if (c < `0` || c > `9`) &&
|
if (c < `0` || c > `9`) && !(j == 0 && k == 0 && (node.expr_types[i].is_number() &&
|
||||||
!(j == 0 && k == 0 && (node.expr_types[i].is_number() && c == `+` || c == `-`)) {
|
c == `+` || c == `-`)) {
|
||||||
verror('illegal character ${c:c} in format specifier ${fmt}')
|
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}')
|
g.write('$fmt${fspec:c}')
|
||||||
} else if node.expr_types[i].is_int() {
|
} else if node.expr_types[i].is_int() {
|
||||||
if fspec == `c` {
|
if fspec == `c` {
|
||||||
if node.expr_types[i].idx() in [table.i64_type_idx table.f64_type_idx] {
|
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")
|
verror('64 bit integer types cannot be interpolated as character')
|
||||||
} else {
|
} else {
|
||||||
g.write('${fmt}c')
|
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_] {
|
} else if sym.has_method('str') || sym.kind in [.array, .array_fixed, .map, .struct_] {
|
||||||
is_p := node.expr_types[i].is_ptr()
|
is_p := node.expr_types[i].is_ptr()
|
||||||
val_type := if is_p {
|
val_type := if is_p { node.expr_types[i].deref() } else { node.expr_types[i] }
|
||||||
node.expr_types[i].deref()
|
|
||||||
} else {
|
|
||||||
node.expr_types[i]
|
|
||||||
}
|
|
||||||
str_fn_name := g.gen_str_for_type(val_type)
|
str_fn_name := g.gen_str_for_type(val_type)
|
||||||
if is_p {
|
if is_p {
|
||||||
g.write('string_add(_SLIT("&"), ${str_fn_name}(*(')
|
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 {
|
if it.is_interface {
|
||||||
// sym := g.table.get_type_symbol(it.interface_types[i])
|
// sym := g.table.get_type_symbol(it.interface_types[i])
|
||||||
// isym := g.table.get_type_symbol(it.interface_type)
|
// isym := g.table.get_type_symbol(it.interface_type)
|
||||||
|
/*
|
||||||
interface_styp := g.typ(it.interface_type)
|
interface_styp := g.typ(it.interface_type)
|
||||||
styp := g.typ(it.interface_types[i])
|
styp := g.typ(it.interface_types[i])
|
||||||
g.write('I_${styp}_to_${interface_styp}(')
|
g.write('I_${styp}_to_${interface_styp}(')
|
||||||
|
*/
|
||||||
|
g.interface_call(it.interface_types[i], it.interface_type)
|
||||||
}
|
}
|
||||||
g.expr(expr)
|
g.expr(expr)
|
||||||
if it.is_interface {
|
if it.is_interface {
|
||||||
@ -3562,3 +3566,11 @@ fn (mut g Gen) array_init(it ast.ArrayInit) {
|
|||||||
}
|
}
|
||||||
g.write('\n})')
|
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}(')
|
||||||
|
}
|
||||||
|
@ -508,10 +508,11 @@ fn (mut g Gen) call_args(args []ast.CallArg, expected_types []table.Type) {
|
|||||||
// Cast a type to interface
|
// Cast a type to interface
|
||||||
// `foo(dog)` => `foo(I_Dog_to_Animal(dog))`
|
// `foo(dog)` => `foo(I_Dog_to_Animal(dog))`
|
||||||
exp_sym := g.table.get_type_symbol(expected_types[arg_no])
|
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])
|
// 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)
|
// styp := g.typ(arg.typ) // g.table.get_type_symbol(arg.typ)
|
||||||
if exp_sym.kind == .interface_ {
|
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
|
is_interface = true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user