checker/cgen: fix calling struct field with fn type
parent
da28bc7026
commit
fde83aff0b
|
@ -346,6 +346,17 @@ pub fn (c mut Checker) call_method(call_expr mut ast.CallExpr) table.Type {
|
|||
call_expr.return_type = table.string_type
|
||||
return table.string_type
|
||||
}
|
||||
// call struct field fn type
|
||||
// TODO: can we use SelectorExpr for all?
|
||||
if field := c.table.struct_find_field(left_type_sym, method_name) {
|
||||
field_type_sym := c.table.get_type_symbol(field.typ)
|
||||
if field_type_sym.kind == .function {
|
||||
call_expr.is_method = false
|
||||
info := field_type_sym.info as table.FnType
|
||||
call_expr.return_type = info.func.return_type
|
||||
return info.func.return_type
|
||||
}
|
||||
}
|
||||
c.error('unknown method: ${left_type_sym.name}.$method_name', call_expr.pos)
|
||||
return table.void_type
|
||||
}
|
||||
|
|
|
@ -242,6 +242,19 @@ fn (g mut Gen) method_call(node ast.CallExpr) {
|
|||
}
|
||||
|
||||
fn (g mut Gen) fn_call(node ast.CallExpr) {
|
||||
// call struct field with fn type
|
||||
// TODO: test node.left instead
|
||||
// left & left_type will be `x` and `x type` in `x.fieldfn()`
|
||||
// will be `0` for `foo()`
|
||||
if node.left_type != 0 {
|
||||
g.expr(node.left)
|
||||
if table.type_is_ptr(node.left_type) {
|
||||
g.write('->')
|
||||
}
|
||||
else {
|
||||
g.write('.')
|
||||
}
|
||||
}
|
||||
mut name := node.name
|
||||
is_print := name == 'println' || name == 'print'
|
||||
print_method := if name == 'println' { 'println' } else { 'print' }
|
||||
|
|
|
@ -153,7 +153,11 @@ struct MySt {
|
|||
fn test_fn_type_call() {
|
||||
mut arr := []MyFn
|
||||
arr << MyFn(test)
|
||||
assert arr[0](10) == 1010
|
||||
// TODO: `arr[0](10)`
|
||||
// assert arr[0](10) == 1010
|
||||
x1 := arr[0]
|
||||
x2 := x1(10)
|
||||
assert x2 == 1010
|
||||
|
||||
st := MySt{f:test}
|
||||
assert st.f(10) == 1010
|
||||
|
|
Loading…
Reference in New Issue