cgen: interface fixes
parent
86ba1645b0
commit
e0f9c042c1
|
@ -16,7 +16,6 @@ const (
|
||||||
'vlib/v/tests/num_lit_call_method_test.v',
|
'vlib/v/tests/num_lit_call_method_test.v',
|
||||||
'vlib/v/tests/pointers_test.v',
|
'vlib/v/tests/pointers_test.v',
|
||||||
'vlib/v/tests/type_test.v',
|
'vlib/v/tests/type_test.v',
|
||||||
'vlib/v/tests/interface_test.v',
|
|
||||||
'vlib/v/tests/valgrind/valgrind_test.v', // ubuntu-musl only
|
'vlib/v/tests/valgrind/valgrind_test.v', // ubuntu-musl only
|
||||||
'vlib/v/tests/pointers_str_test.v',
|
'vlib/v/tests/pointers_str_test.v',
|
||||||
'vlib/net/http/cookie_test.v',
|
'vlib/net/http/cookie_test.v',
|
||||||
|
|
|
@ -573,11 +573,11 @@ fn (mut g Gen) stmt(node ast.Stmt) {
|
||||||
}
|
}
|
||||||
ast.Import {}
|
ast.Import {}
|
||||||
ast.InterfaceDecl {
|
ast.InterfaceDecl {
|
||||||
g.writeln('//interface')
|
g.definitions.writeln('//interface')
|
||||||
g.writeln('typedef struct {')
|
g.definitions.writeln('typedef struct {')
|
||||||
g.writeln('\tvoid* _object;')
|
g.definitions.writeln('\tvoid* _object;')
|
||||||
g.writeln('\tint _interface_idx;')
|
g.definitions.writeln('\tint _interface_idx;')
|
||||||
g.writeln('} $it.name;')
|
g.definitions.writeln('} $it.name;')
|
||||||
}
|
}
|
||||||
ast.Module {}
|
ast.Module {}
|
||||||
ast.Return {
|
ast.Return {
|
||||||
|
@ -1301,7 +1301,7 @@ fn (mut g Gen) assign_expr(node ast.AssignExpr) {
|
||||||
g.write(', ')
|
g.write(', ')
|
||||||
}
|
}
|
||||||
g.is_assign_lhs = false
|
g.is_assign_lhs = false
|
||||||
//right_sym := g.table.get_type_symbol(node.right_type)
|
// right_sym := g.table.get_type_symbol(node.right_type)
|
||||||
// left_sym := g.table.get_type_symbol(node.left_type)
|
// left_sym := g.table.get_type_symbol(node.left_type)
|
||||||
mut cloned := false
|
mut cloned := false
|
||||||
// !g.is_array_set
|
// !g.is_array_set
|
||||||
|
|
|
@ -249,11 +249,22 @@ fn (mut g Gen) method_call(node ast.CallExpr) {
|
||||||
typ_sym := g.table.get_type_symbol(node.receiver_type)
|
typ_sym := g.table.get_type_symbol(node.receiver_type)
|
||||||
mut receiver_name := typ_sym.name
|
mut receiver_name := typ_sym.name
|
||||||
if typ_sym.kind == .interface_ {
|
if typ_sym.kind == .interface_ {
|
||||||
|
// Find the index of the method
|
||||||
|
mut idx := -1
|
||||||
|
for i, method in typ_sym.methods {
|
||||||
|
if method.name == node.name {
|
||||||
|
idx = i
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if idx == -1 {
|
||||||
|
verror('method_call: cannot find interface method index')
|
||||||
|
}
|
||||||
|
sret_type := g.typ(node.return_type)
|
||||||
g.writeln('// interface method call')
|
g.writeln('// interface method call')
|
||||||
// `((void (*)())(Speaker_name_table[s._interface_idx][1]))(s._object);`
|
// `((void (*)())(Speaker_name_table[s._interface_idx][1]))(s._object);`
|
||||||
g.write('((void (*)())(${receiver_name}_name_table[')
|
g.write('(($sret_type (*)())(${receiver_name}_name_table[')
|
||||||
g.expr(node.left)
|
g.expr(node.left)
|
||||||
g.write('._interface_idx][1]))(')
|
g.write('._interface_idx][$idx]))(')
|
||||||
g.expr(node.left)
|
g.expr(node.left)
|
||||||
g.write('._object)')
|
g.write('._object)')
|
||||||
return
|
return
|
||||||
|
@ -443,17 +454,33 @@ fn (mut g Gen) call_args(args []ast.CallArg, expected_types []table.Type) {
|
||||||
is_forwarding_varg := args.len > 0 && args[args.len - 1].typ.flag_is(.variadic)
|
is_forwarding_varg := args.len > 0 && args[args.len - 1].typ.flag_is(.variadic)
|
||||||
gen_vargs := is_variadic && !is_forwarding_varg
|
gen_vargs := is_variadic && !is_forwarding_varg
|
||||||
mut arg_no := 0
|
mut arg_no := 0
|
||||||
for arg in args {
|
for i, arg in args {
|
||||||
if gen_vargs && arg_no == expected_types.len - 1 {
|
if gen_vargs && arg_no == expected_types.len - 1 {
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
|
// if arg.typ.name.starts_with('I') {
|
||||||
|
// }
|
||||||
|
mut is_interface := false
|
||||||
// some c fn definitions dont have args (cfns.v) or are not updated in checker
|
// some c fn definitions dont have args (cfns.v) or are not updated in checker
|
||||||
// when these are fixed we wont need this check
|
// when these are fixed we wont need this check
|
||||||
if arg_no < expected_types.len {
|
if arg_no < expected_types.len {
|
||||||
|
if expected_types[arg_no] != 0 {
|
||||||
|
// Cast a type to interface
|
||||||
|
// `foo(dog)` => `foo(I_Dog_to_Animal(dog))`
|
||||||
|
exp_sym := g.table.get_type_symbol(expected_types[arg_no])
|
||||||
|
sym := g.table.get_type_symbol(arg.typ)
|
||||||
|
if exp_sym.kind == .interface_ {
|
||||||
|
g.write('I_${sym.name}_to_${exp_sym.name}(')
|
||||||
|
is_interface = true
|
||||||
|
}
|
||||||
|
}
|
||||||
g.ref_or_deref_arg(arg, expected_types[arg_no])
|
g.ref_or_deref_arg(arg, expected_types[arg_no])
|
||||||
} else {
|
} else {
|
||||||
g.expr(arg.expr)
|
g.expr(arg.expr)
|
||||||
}
|
}
|
||||||
|
if is_interface {
|
||||||
|
g.write(')')
|
||||||
|
}
|
||||||
if arg_no < args.len - 1 || gen_vargs {
|
if arg_no < args.len - 1 || gen_vargs {
|
||||||
g.write(', ')
|
g.write(', ')
|
||||||
}
|
}
|
||||||
|
|
|
@ -36,10 +36,8 @@ interface Speaker {
|
||||||
fn perform_speak(s Speaker) {
|
fn perform_speak(s Speaker) {
|
||||||
s.speak()
|
s.speak()
|
||||||
assert true
|
assert true
|
||||||
/*
|
|
||||||
name := s.name()
|
name := s.name()
|
||||||
assert name == 'Dog' || name == 'Cat'
|
assert name == 'Dog' || name == 'Cat'
|
||||||
*/
|
|
||||||
println(s.name())
|
println(s.name())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -48,7 +46,7 @@ fn test_perform_speak() {
|
||||||
perform_speak(dog)
|
perform_speak(dog)
|
||||||
cat := Cat{}
|
cat := Cat{}
|
||||||
perform_speak(cat)
|
perform_speak(cat)
|
||||||
// perform_speakers([dog, cat])
|
//perform_speakers([dog, cat])
|
||||||
/*
|
/*
|
||||||
f := Foo {
|
f := Foo {
|
||||||
speaker: dog
|
speaker: dog
|
||||||
|
@ -56,6 +54,8 @@ fn test_perform_speak() {
|
||||||
*/
|
*/
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//fn perform_speakers(speakers []Speaker) {}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
interface Speak2er {
|
interface Speak2er {
|
||||||
name ()string
|
name ()string
|
||||||
|
@ -67,7 +67,6 @@ struct Foo {
|
||||||
speakers []Speaker
|
speakers []Speaker
|
||||||
}
|
}
|
||||||
|
|
||||||
fn perform_speakers(speakers []Speaker) {}
|
|
||||||
|
|
||||||
|
|
||||||
interface Register {
|
interface Register {
|
||||||
|
|
Loading…
Reference in New Issue