cgen: implement fixed array 'for in' for lvalue condition (#6151)

pull/6154/head^2
Nick Treleaven 2020-08-17 20:10:47 +01:00 committed by GitHub
parent 46b4e2a0cd
commit 36c98b3e5d
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 45 additions and 1 deletions

View File

@ -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 }

View File

@ -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)
}
}

View File

@ -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] )