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
|
call_expr.return_type = table.string_type
|
||||||
return 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)
|
c.error('unknown method: ${left_type_sym.name}.$method_name', call_expr.pos)
|
||||||
return table.void_type
|
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) {
|
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
|
mut name := node.name
|
||||||
is_print := name == 'println' || name == 'print'
|
is_print := name == 'println' || name == 'print'
|
||||||
print_method := if name == 'println' { 'println' } else { 'print' }
|
print_method := if name == 'println' { 'println' } else { 'print' }
|
||||||
|
|
|
@ -153,7 +153,11 @@ struct MySt {
|
||||||
fn test_fn_type_call() {
|
fn test_fn_type_call() {
|
||||||
mut arr := []MyFn
|
mut arr := []MyFn
|
||||||
arr << MyFn(test)
|
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}
|
st := MySt{f:test}
|
||||||
assert st.f(10) == 1010
|
assert st.f(10) == 1010
|
||||||
|
|
Loading…
Reference in New Issue