diff --git a/vlib/v/ast/ast.v b/vlib/v/ast/ast.v index 1f66466c03..4d4789db3a 100644 --- a/vlib/v/ast/ast.v +++ b/vlib/v/ast/ast.v @@ -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 } diff --git a/vlib/v/gen/cgen.v b/vlib/v/gen/cgen.v index 53da273556..0758500f87 100644 --- a/vlib/v/gen/cgen.v +++ b/vlib/v/gen/cgen.v @@ -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) } } diff --git a/vlib/v/tests/fixed_array_test.v b/vlib/v/tests/fixed_array_test.v index 96809826d6..f54e1673ba 100644 --- a/vlib/v/tests/fixed_array_test.v +++ b/vlib/v/tests/fixed_array_test.v @@ -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] )