cgen: further fixes to and array/map of fns (#5916)
parent
c3a2e9b5c4
commit
a370dd2867
|
@ -912,6 +912,7 @@ fn (mut g Gen) for_in(it ast.ForInStmt) {
|
|||
// `for num in nums {`
|
||||
g.writeln('// FOR IN array')
|
||||
styp := g.typ(it.val_type)
|
||||
val_sym := g.table.get_type_symbol(it.val_type)
|
||||
cond_type_is_ptr := it.cond_type.is_ptr()
|
||||
atmp := g.new_tmp_var()
|
||||
atmp_type := if cond_type_is_ptr { 'array *' } else { 'array' }
|
||||
|
@ -922,7 +923,13 @@ fn (mut g Gen) for_in(it ast.ForInStmt) {
|
|||
op_field := if cond_type_is_ptr { '->' } else { '.' }
|
||||
g.writeln('for (int $i = 0; $i < $atmp${op_field}len; ++$i) {')
|
||||
if it.val_var != '_' {
|
||||
g.writeln('\t$styp ${c_name(it.val_var)} = (($styp*)$atmp${op_field}data)[$i];')
|
||||
if val_sym.kind == .function {
|
||||
g.write('\t')
|
||||
g.write_fn_ptr_decl(val_sym.info as table.FnType, c_name(it.val_var))
|
||||
g.writeln(' = ((voidptr*)$atmp${op_field}data)[$i];')
|
||||
} else {
|
||||
g.write('\t$styp ${c_name(it.val_var)} = (($styp*)$atmp${op_field}data)[$i];')
|
||||
}
|
||||
}
|
||||
g.stmts(it.stmts)
|
||||
g.writeln('}')
|
||||
|
@ -931,6 +938,7 @@ fn (mut g Gen) for_in(it ast.ForInStmt) {
|
|||
g.writeln('// FOR IN map')
|
||||
key_styp := g.typ(it.key_type)
|
||||
val_styp := g.typ(it.val_type)
|
||||
val_sym := g.table.get_type_symbol(it.val_type)
|
||||
keys_tmp := 'keys_' + g.new_tmp_var()
|
||||
idx := g.new_tmp_var()
|
||||
key := if it.key_var in ['', '_'] { g.new_tmp_var() } else { it.key_var }
|
||||
|
@ -949,8 +957,13 @@ fn (mut g Gen) for_in(it ast.ForInStmt) {
|
|||
g.writeln('\t$key_styp $key = /*kkkk*/ (($key_styp*)${keys_tmp}.data)[$idx];')
|
||||
}
|
||||
if it.val_var != '_' {
|
||||
g.write('\t$val_styp ${c_name(it.val_var)} = /*vvv*/ (*($val_styp*)map_get($atmp')
|
||||
g.writeln(', $key, &($val_styp[]){ $zero }));')
|
||||
if val_sym.kind == .function {
|
||||
g.write('\t')
|
||||
g.write_fn_ptr_decl(val_sym.info as table.FnType, c_name(it.val_var))
|
||||
g.writeln(' = (*(voidptr*)map_get($atmp, $key, &(voidptr[]){ $zero }));')
|
||||
} else {
|
||||
g.writeln('\t$val_styp ${c_name(it.val_var)} = (*($val_styp*)map_get($atmp, $key, &($val_styp[]){ $zero }));')
|
||||
}
|
||||
}
|
||||
g.stmts(it.stmts)
|
||||
g.writeln('}')
|
||||
|
@ -1142,6 +1155,20 @@ fn (mut g Gen) gen_assert_single_expr(e ast.Expr, t table.Type) {
|
|||
g.write(' /* typeof: ' + typeof(e) + ' type: ' + t.str() + ' */ ')
|
||||
}
|
||||
|
||||
fn (g &Gen) write_fn_ptr_decl(func &table.FnType, ptr_name string) {
|
||||
ret_styp := g.typ(func.func.return_type)
|
||||
g.write('$ret_styp (*$ptr_name) (')
|
||||
arg_len := func.func.args.len
|
||||
for i, arg in func.func.args {
|
||||
arg_typ := g.table.get_type_symbol(arg.typ)
|
||||
g.write('$arg_typ.str() $arg.name')
|
||||
if i < arg_len - 1 {
|
||||
g.write(', ')
|
||||
}
|
||||
}
|
||||
g.write(')')
|
||||
}
|
||||
|
||||
fn (mut g Gen) gen_assign_stmt(assign_stmt ast.AssignStmt) {
|
||||
if assign_stmt.is_static {
|
||||
g.write('static ')
|
||||
|
@ -1198,23 +1225,13 @@ fn (mut g Gen) gen_assign_stmt(assign_stmt ast.AssignStmt) {
|
|||
for i, left in assign_stmt.left {
|
||||
match left {
|
||||
ast.Ident {
|
||||
var_type := assign_stmt.left_types[i]
|
||||
left_sym := g.table.get_type_symbol(var_type)
|
||||
left_typ := assign_stmt.left_types[i]
|
||||
left_sym := g.table.get_type_symbol(left_typ)
|
||||
if left_sym.kind == .function {
|
||||
func := left_sym.info as table.FnType
|
||||
ret_styp := g.typ(func.func.return_type)
|
||||
g.write('$ret_styp (*_var_$left.pos.pos) (')
|
||||
arg_len := func.func.args.len
|
||||
for j, arg in func.func.args {
|
||||
arg_type := g.table.get_type_symbol(arg.typ)
|
||||
g.write('$arg_type.str() $arg.name')
|
||||
if j < arg_len - 1 {
|
||||
g.write(', ')
|
||||
}
|
||||
}
|
||||
g.writeln(') = $left.name;')
|
||||
g.write_fn_ptr_decl(left_sym.info as table.FnType, '_var_$left.pos.pos')
|
||||
g.writeln(' = $left.name;')
|
||||
} else {
|
||||
styp := g.typ(var_type)
|
||||
styp := g.typ(left_typ)
|
||||
g.writeln('$styp _var_$left.pos.pos = $left.name;')
|
||||
}
|
||||
}
|
||||
|
@ -1222,24 +1239,14 @@ fn (mut g Gen) gen_assign_stmt(assign_stmt ast.AssignStmt) {
|
|||
sym := g.table.get_type_symbol(left.left_type)
|
||||
if sym.kind == .array {
|
||||
info := sym.info as table.Array
|
||||
styp := g.typ(info.elem_type)
|
||||
elem_typ := g.table.get_type_symbol(info.elem_type)
|
||||
if elem_typ.kind == .function {
|
||||
var_type := assign_stmt.left_types[i]
|
||||
left_sym := g.table.get_type_symbol(var_type)
|
||||
func := left_sym.info as table.FnType
|
||||
ret_styp := g.typ(func.func.return_type)
|
||||
g.write('$ret_styp (*_var_$left.pos.pos) (')
|
||||
arg_len := func.func.args.len
|
||||
for j, arg in func.func.args {
|
||||
arg_type := g.table.get_type_symbol(arg.typ)
|
||||
g.write('$arg_type.str() $arg.name')
|
||||
if j < arg_len - 1 {
|
||||
g.write(', ')
|
||||
}
|
||||
}
|
||||
g.write(') = *(voidptr*)array_get(')
|
||||
left_typ := assign_stmt.left_types[i]
|
||||
left_sym := g.table.get_type_symbol(left_typ)
|
||||
g.write_fn_ptr_decl(left_sym.info as table.FnType, '_var_$left.pos.pos')
|
||||
g.write(' = *(voidptr*)array_get(')
|
||||
} else {
|
||||
styp := g.typ(info.elem_type)
|
||||
g.write('$styp _var_$left.pos.pos = *($styp*)array_get(')
|
||||
}
|
||||
if left.left_type.is_ptr() {
|
||||
|
@ -1253,22 +1260,12 @@ fn (mut g Gen) gen_assign_stmt(assign_stmt ast.AssignStmt) {
|
|||
info := sym.info as table.Map
|
||||
styp := g.typ(info.value_type)
|
||||
zero := g.type_default(info.value_type)
|
||||
value_typ := g.table.get_type_symbol(info.value_type)
|
||||
if value_typ.kind == .function {
|
||||
var_type := assign_stmt.left_types[i]
|
||||
left_sym := g.table.get_type_symbol(var_type)
|
||||
func := left_sym.info as table.FnType
|
||||
ret_styp := g.typ(func.func.return_type)
|
||||
g.write('$ret_styp (*_var_$left.pos.pos) (')
|
||||
arg_len := func.func.args.len
|
||||
for j, arg in func.func.args {
|
||||
arg_type := g.table.get_type_symbol(arg.typ)
|
||||
g.write('$arg_type.str() $arg.name')
|
||||
if j < arg_len - 1 {
|
||||
g.write(', ')
|
||||
}
|
||||
}
|
||||
g.write(') = *(voidptr*)map_get(')
|
||||
val_typ := g.table.get_type_symbol(info.value_type)
|
||||
if val_typ.kind == .function {
|
||||
left_type := assign_stmt.left_types[i]
|
||||
left_sym := g.table.get_type_symbol(left_type)
|
||||
g.write_fn_ptr_decl(left_sym.info as table.FnType, '_var_$left.pos.pos')
|
||||
g.write(' = *(voidptr*)map_get(')
|
||||
} else {
|
||||
g.write('$styp _var_$left.pos.pos = *($styp*)map_get(')
|
||||
}
|
||||
|
@ -1278,7 +1275,7 @@ fn (mut g Gen) gen_assign_stmt(assign_stmt ast.AssignStmt) {
|
|||
g.expr(left.left)
|
||||
g.write(', ')
|
||||
g.expr(left.index)
|
||||
if value_typ.kind == .function {
|
||||
if val_typ.kind == .function {
|
||||
g.writeln(', &(voidptr[]){ $zero });')
|
||||
} else {
|
||||
g.writeln(', &($styp[]){ $zero });')
|
||||
|
|
|
@ -24,6 +24,9 @@ fn test_array_with_fns() {
|
|||
b[0] = a[0]
|
||||
f4 := b[0]
|
||||
assert f4('bbbbbb') == 26
|
||||
for func in b {
|
||||
assert func('ccccccc') == 27
|
||||
}
|
||||
}
|
||||
|
||||
fn test_map_with_fns() {
|
||||
|
@ -42,4 +45,7 @@ fn test_map_with_fns() {
|
|||
b['one'] = a['one']
|
||||
f4 := b['one']
|
||||
assert f4('bbbbbb') == 26
|
||||
for _, func in b {
|
||||
assert func('ccccccc') == 27
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue