cgen: implement fixed array 'for in' for lvalue condition (#6151)
parent
46b4e2a0cd
commit
36c98b3e5d
|
@ -1059,6 +1059,16 @@ pub fn (expr Expr) position() token.Position {
|
|||
}
|
||||
}
|
||||
|
||||
pub fn (expr Expr) is_lvalue() bool {
|
||||
match expr {
|
||||
Ident {return true}
|
||||
IndexExpr {return expr.left.is_lvalue()}
|
||||
SelectorExpr {return expr.expr.is_lvalue()}
|
||||
else {}
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
pub fn (stmt Stmt) position() token.Position {
|
||||
match stmt {
|
||||
AssertStmt { return stmt.pos }
|
||||
|
|
|
@ -975,6 +975,33 @@ fn (mut g Gen) for_in(it ast.ForInStmt) {
|
|||
}
|
||||
g.stmts(it.stmts)
|
||||
g.writeln('}')
|
||||
} else if it.kind == .array_fixed {
|
||||
atmp := g.new_tmp_var()
|
||||
atmp_type := g.typ(it.cond_type)
|
||||
if !it.cond.is_lvalue() {
|
||||
g.error('for in: unhandled condition `$it.cond`', it.pos)
|
||||
}
|
||||
// TODO rvalue cond
|
||||
g.write('$atmp_type *$atmp = &')
|
||||
g.expr(it.cond)
|
||||
g.writeln(';')
|
||||
i := if it.key_var in ['', '_'] { g.new_tmp_var() } else { it.key_var }
|
||||
cond_sym := g.table.get_type_symbol(it.cond_type)
|
||||
info := cond_sym.info as table.ArrayFixed
|
||||
g.writeln('for (int $i = 0; $i != $info.size; ++$i) {')
|
||||
if it.val_var != '_' {
|
||||
val_sym := g.table.get_type_symbol(it.val_type)
|
||||
if val_sym.kind == .function {
|
||||
g.write('\t')
|
||||
g.write_fn_ptr_decl(val_sym.info as table.FnType, c_name(it.val_var))
|
||||
} else {
|
||||
styp := g.typ(it.val_type)
|
||||
g.write('\t$styp ${c_name(it.val_var)}')
|
||||
}
|
||||
g.writeln(' = (*$atmp)[$i];')
|
||||
}
|
||||
g.stmts(it.stmts)
|
||||
g.writeln('}')
|
||||
} else if it.kind == .map {
|
||||
// `for key, val in map {`
|
||||
g.writeln('// FOR IN map')
|
||||
|
@ -1038,7 +1065,7 @@ fn (mut g Gen) for_in(it ast.ForInStmt) {
|
|||
g.writeln('}')
|
||||
} else {
|
||||
s := g.table.type_to_str(it.cond_type)
|
||||
g.error('`for`: unhandled symbol `$it.cond` of type `$s`', it.pos)
|
||||
g.error('for in: unhandled symbol `$it.cond` of type `$s`', it.pos)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -4,6 +4,10 @@ fn test_fixed_array_can_be_assigned() {
|
|||
assert v[1] == 0
|
||||
v = [1.0, x, 3.0,4.0,5.0,6.0,7.0,8.0]!!
|
||||
assert v[1] == x
|
||||
v[1] = 2.0
|
||||
for i, e in v {
|
||||
assert e == i + 1
|
||||
}
|
||||
v = [8]f64{}
|
||||
assert v[1] == 0
|
||||
// test slicing
|
||||
|
@ -32,6 +36,9 @@ fn test_fixed_array_can_be_assigned_to_a_struct_field() {
|
|||
ctx.vb = [1.1, x, 3.3, 4.4, 5.0, 6.0, 7.0, 8.9]!!
|
||||
assert ctx.vb[1] == x
|
||||
assert ctx.vb[7] == 8.9
|
||||
for i, e in ctx.vb {
|
||||
assert e == ctx.vb[i]
|
||||
}
|
||||
assert ctx.vb == ctx.vb
|
||||
/*
|
||||
println( ctx.vb[0] )
|
||||
|
|
Loading…
Reference in New Issue