parent
a3c3fd4d20
commit
8ab59c5f0f
|
@ -1431,6 +1431,20 @@ pub fn (mut c Checker) call_fn(mut call_expr ast.CallExpr) table.Type {
|
||||||
f = f1
|
f = f1
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if !found && call_expr.left is ast.IndexExpr {
|
||||||
|
c.expr(call_expr.left)
|
||||||
|
expr := call_expr.left as ast.IndexExpr
|
||||||
|
sym := c.table.get_type_symbol(expr.left_type)
|
||||||
|
if sym.kind == .array {
|
||||||
|
info := sym.info as table.Array
|
||||||
|
elem_typ := c.table.get_type_symbol(info.elem_type)
|
||||||
|
if elem_typ.info is table.FnType {
|
||||||
|
return elem_typ.info.func.return_type
|
||||||
|
}
|
||||||
|
}
|
||||||
|
found = true
|
||||||
|
return table.string_type
|
||||||
|
}
|
||||||
// already prefixed (mod.fn) or C/builtin/main
|
// already prefixed (mod.fn) or C/builtin/main
|
||||||
if !found {
|
if !found {
|
||||||
if f1 := c.table.find_fn(fn_name) {
|
if f1 := c.table.find_fn(fn_name) {
|
||||||
|
|
|
@ -116,6 +116,7 @@ mut:
|
||||||
called_fn_name string
|
called_fn_name string
|
||||||
cur_mod ast.Module
|
cur_mod ast.Module
|
||||||
is_js_call bool // for handling a special type arg #1 `json.decode(User, ...)`
|
is_js_call bool // for handling a special type arg #1 `json.decode(User, ...)`
|
||||||
|
is_fn_index_call bool
|
||||||
// nr_vars_to_free int
|
// nr_vars_to_free int
|
||||||
// doing_autofree_tmp bool
|
// doing_autofree_tmp bool
|
||||||
inside_lambda bool
|
inside_lambda bool
|
||||||
|
@ -3763,6 +3764,12 @@ fn (mut g Gen) index_expr(node ast.IndexExpr) {
|
||||||
}
|
}
|
||||||
if is_direct_array_access {
|
if is_direct_array_access {
|
||||||
g.write('(($array_ptr_type_str)')
|
g.write('(($array_ptr_type_str)')
|
||||||
|
} else if g.is_fn_index_call {
|
||||||
|
if elem_typ.info is table.FnType {
|
||||||
|
g.write('((')
|
||||||
|
g.write_fn_ptr_decl(&elem_typ.info, '')
|
||||||
|
g.write(')(*($array_ptr_type_str)/*ee elem_typ */array_get(')
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
g.write('(*($array_ptr_type_str)/*ee elem_typ */array_get(')
|
g.write('(*($array_ptr_type_str)/*ee elem_typ */array_get(')
|
||||||
if left_is_ptr && !node.left_type.has_flag(.shared_f) {
|
if left_is_ptr && !node.left_type.has_flag(.shared_f) {
|
||||||
|
@ -3790,7 +3797,11 @@ fn (mut g Gen) index_expr(node ast.IndexExpr) {
|
||||||
} else {
|
} else {
|
||||||
g.write(', ')
|
g.write(', ')
|
||||||
g.expr(node.index)
|
g.expr(node.index)
|
||||||
g.write('))')
|
if g.is_fn_index_call {
|
||||||
|
g.write(')))')
|
||||||
|
} else {
|
||||||
|
g.write('))')
|
||||||
|
}
|
||||||
}
|
}
|
||||||
if needs_clone {
|
if needs_clone {
|
||||||
g.write(')')
|
g.write(')')
|
||||||
|
@ -4314,6 +4325,9 @@ fn (mut g Gen) struct_init(struct_init ast.StructInit) {
|
||||||
if field.name in inited_fields {
|
if field.name in inited_fields {
|
||||||
sfield := struct_init.fields[inited_fields[field.name]]
|
sfield := struct_init.fields[inited_fields[field.name]]
|
||||||
field_name := c_name(sfield.name)
|
field_name := c_name(sfield.name)
|
||||||
|
if sfield.typ == 0 {
|
||||||
|
continue
|
||||||
|
}
|
||||||
g.write('.$field_name = ')
|
g.write('.$field_name = ')
|
||||||
field_type_sym := g.table.get_type_symbol(sfield.typ)
|
field_type_sym := g.table.get_type_symbol(sfield.typ)
|
||||||
mut cloned := false
|
mut cloned := false
|
||||||
|
|
|
@ -254,6 +254,11 @@ fn (mut g Gen) call_expr(node ast.CallExpr) {
|
||||||
if node.left is ast.AnonFn {
|
if node.left is ast.AnonFn {
|
||||||
g.expr(node.left)
|
g.expr(node.left)
|
||||||
}
|
}
|
||||||
|
if node.left is ast.IndexExpr && node.name == '' {
|
||||||
|
g.is_fn_index_call = true
|
||||||
|
g.expr(node.left)
|
||||||
|
g.is_fn_index_call = false
|
||||||
|
}
|
||||||
if node.should_be_skipped {
|
if node.should_be_skipped {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
|
@ -263,6 +263,19 @@ pub fn (mut p Parser) expr_with_left(left ast.Expr, precedence int, is_stmt_iden
|
||||||
} else if p.tok.kind == .lsbr {
|
} else if p.tok.kind == .lsbr {
|
||||||
node = p.index_expr(node)
|
node = p.index_expr(node)
|
||||||
p.is_stmt_ident = is_stmt_ident
|
p.is_stmt_ident = is_stmt_ident
|
||||||
|
if p.tok.kind == .lpar && p.tok.line_nr == p.prev_tok.line_nr && node is ast.IndexExpr {
|
||||||
|
p.next()
|
||||||
|
pos := p.tok.position()
|
||||||
|
args := p.call_args()
|
||||||
|
p.check(.rpar)
|
||||||
|
node = ast.CallExpr{
|
||||||
|
left: node
|
||||||
|
args: args
|
||||||
|
pos: pos
|
||||||
|
scope: p.scope
|
||||||
|
}
|
||||||
|
p.is_stmt_ident = is_stmt_ident
|
||||||
|
}
|
||||||
} else if p.tok.kind == .key_as {
|
} else if p.tok.kind == .key_as {
|
||||||
// sum type as cast `x := SumType as Variant`
|
// sum type as cast `x := SumType as Variant`
|
||||||
pos := p.tok.position()
|
pos := p.tok.position()
|
||||||
|
|
|
@ -0,0 +1,17 @@
|
||||||
|
struct Placeholder {
|
||||||
|
name string
|
||||||
|
}
|
||||||
|
|
||||||
|
struct FnStruct {
|
||||||
|
mut:
|
||||||
|
array_of_fn []fn(int, &Placeholder, string)bool
|
||||||
|
}
|
||||||
|
|
||||||
|
fn test_fn_array_direct_call() {
|
||||||
|
mut fs := FnStruct{}
|
||||||
|
fs.array_of_fn << fn(x int, y &Placeholder, z string) bool {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
assert fs.array_of_fn[0](1, &Placeholder{name: 'Bob'}, 'Builder') == false
|
||||||
|
}
|
Loading…
Reference in New Issue