mirror of
https://github.com/vlang/v.git
synced 2023-08-10 21:13:21 +03:00
cgen: further fixes to and array/map of fns (#5916)
This commit is contained in:
parent
c3a2e9b5c4
commit
a370dd2867
@ -912,6 +912,7 @@ fn (mut g Gen) for_in(it ast.ForInStmt) {
|
|||||||
// `for num in nums {`
|
// `for num in nums {`
|
||||||
g.writeln('// FOR IN array')
|
g.writeln('// FOR IN array')
|
||||||
styp := g.typ(it.val_type)
|
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()
|
cond_type_is_ptr := it.cond_type.is_ptr()
|
||||||
atmp := g.new_tmp_var()
|
atmp := g.new_tmp_var()
|
||||||
atmp_type := if cond_type_is_ptr { 'array *' } else { 'array' }
|
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 { '.' }
|
op_field := if cond_type_is_ptr { '->' } else { '.' }
|
||||||
g.writeln('for (int $i = 0; $i < $atmp${op_field}len; ++$i) {')
|
g.writeln('for (int $i = 0; $i < $atmp${op_field}len; ++$i) {')
|
||||||
if it.val_var != '_' {
|
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.stmts(it.stmts)
|
||||||
g.writeln('}')
|
g.writeln('}')
|
||||||
@ -931,6 +938,7 @@ fn (mut g Gen) for_in(it ast.ForInStmt) {
|
|||||||
g.writeln('// FOR IN map')
|
g.writeln('// FOR IN map')
|
||||||
key_styp := g.typ(it.key_type)
|
key_styp := g.typ(it.key_type)
|
||||||
val_styp := g.typ(it.val_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()
|
keys_tmp := 'keys_' + g.new_tmp_var()
|
||||||
idx := g.new_tmp_var()
|
idx := g.new_tmp_var()
|
||||||
key := if it.key_var in ['', '_'] { g.new_tmp_var() } else { it.key_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];')
|
g.writeln('\t$key_styp $key = /*kkkk*/ (($key_styp*)${keys_tmp}.data)[$idx];')
|
||||||
}
|
}
|
||||||
if it.val_var != '_' {
|
if it.val_var != '_' {
|
||||||
g.write('\t$val_styp ${c_name(it.val_var)} = /*vvv*/ (*($val_styp*)map_get($atmp')
|
if val_sym.kind == .function {
|
||||||
g.writeln(', $key, &($val_styp[]){ $zero }));')
|
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.stmts(it.stmts)
|
||||||
g.writeln('}')
|
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() + ' */ ')
|
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) {
|
fn (mut g Gen) gen_assign_stmt(assign_stmt ast.AssignStmt) {
|
||||||
if assign_stmt.is_static {
|
if assign_stmt.is_static {
|
||||||
g.write('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 {
|
for i, left in assign_stmt.left {
|
||||||
match left {
|
match left {
|
||||||
ast.Ident {
|
ast.Ident {
|
||||||
var_type := assign_stmt.left_types[i]
|
left_typ := assign_stmt.left_types[i]
|
||||||
left_sym := g.table.get_type_symbol(var_type)
|
left_sym := g.table.get_type_symbol(left_typ)
|
||||||
if left_sym.kind == .function {
|
if left_sym.kind == .function {
|
||||||
func := left_sym.info as table.FnType
|
g.write_fn_ptr_decl(left_sym.info as table.FnType, '_var_$left.pos.pos')
|
||||||
ret_styp := g.typ(func.func.return_type)
|
g.writeln(' = $left.name;')
|
||||||
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;')
|
|
||||||
} else {
|
} else {
|
||||||
styp := g.typ(var_type)
|
styp := g.typ(left_typ)
|
||||||
g.writeln('$styp _var_$left.pos.pos = $left.name;')
|
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)
|
sym := g.table.get_type_symbol(left.left_type)
|
||||||
if sym.kind == .array {
|
if sym.kind == .array {
|
||||||
info := sym.info as table.Array
|
info := sym.info as table.Array
|
||||||
styp := g.typ(info.elem_type)
|
|
||||||
elem_typ := g.table.get_type_symbol(info.elem_type)
|
elem_typ := g.table.get_type_symbol(info.elem_type)
|
||||||
if elem_typ.kind == .function {
|
if elem_typ.kind == .function {
|
||||||
var_type := assign_stmt.left_types[i]
|
left_typ := assign_stmt.left_types[i]
|
||||||
left_sym := g.table.get_type_symbol(var_type)
|
left_sym := g.table.get_type_symbol(left_typ)
|
||||||
func := left_sym.info as table.FnType
|
g.write_fn_ptr_decl(left_sym.info as table.FnType, '_var_$left.pos.pos')
|
||||||
ret_styp := g.typ(func.func.return_type)
|
g.write(' = *(voidptr*)array_get(')
|
||||||
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(')
|
|
||||||
} else {
|
} else {
|
||||||
|
styp := g.typ(info.elem_type)
|
||||||
g.write('$styp _var_$left.pos.pos = *($styp*)array_get(')
|
g.write('$styp _var_$left.pos.pos = *($styp*)array_get(')
|
||||||
}
|
}
|
||||||
if left.left_type.is_ptr() {
|
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
|
info := sym.info as table.Map
|
||||||
styp := g.typ(info.value_type)
|
styp := g.typ(info.value_type)
|
||||||
zero := g.type_default(info.value_type)
|
zero := g.type_default(info.value_type)
|
||||||
value_typ := g.table.get_type_symbol(info.value_type)
|
val_typ := g.table.get_type_symbol(info.value_type)
|
||||||
if value_typ.kind == .function {
|
if val_typ.kind == .function {
|
||||||
var_type := assign_stmt.left_types[i]
|
left_type := assign_stmt.left_types[i]
|
||||||
left_sym := g.table.get_type_symbol(var_type)
|
left_sym := g.table.get_type_symbol(left_type)
|
||||||
func := left_sym.info as table.FnType
|
g.write_fn_ptr_decl(left_sym.info as table.FnType, '_var_$left.pos.pos')
|
||||||
ret_styp := g.typ(func.func.return_type)
|
g.write(' = *(voidptr*)map_get(')
|
||||||
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(')
|
|
||||||
} else {
|
} else {
|
||||||
g.write('$styp _var_$left.pos.pos = *($styp*)map_get(')
|
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.expr(left.left)
|
||||||
g.write(', ')
|
g.write(', ')
|
||||||
g.expr(left.index)
|
g.expr(left.index)
|
||||||
if value_typ.kind == .function {
|
if val_typ.kind == .function {
|
||||||
g.writeln(', &(voidptr[]){ $zero });')
|
g.writeln(', &(voidptr[]){ $zero });')
|
||||||
} else {
|
} else {
|
||||||
g.writeln(', &($styp[]){ $zero });')
|
g.writeln(', &($styp[]){ $zero });')
|
||||||
|
@ -24,6 +24,9 @@ fn test_array_with_fns() {
|
|||||||
b[0] = a[0]
|
b[0] = a[0]
|
||||||
f4 := b[0]
|
f4 := b[0]
|
||||||
assert f4('bbbbbb') == 26
|
assert f4('bbbbbb') == 26
|
||||||
|
for func in b {
|
||||||
|
assert func('ccccccc') == 27
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn test_map_with_fns() {
|
fn test_map_with_fns() {
|
||||||
@ -42,4 +45,7 @@ fn test_map_with_fns() {
|
|||||||
b['one'] = a['one']
|
b['one'] = a['one']
|
||||||
f4 := b['one']
|
f4 := b['one']
|
||||||
assert f4('bbbbbb') == 26
|
assert f4('bbbbbb') == 26
|
||||||
|
for _, func in b {
|
||||||
|
assert func('ccccccc') == 27
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user