core: Use C-style for loop logic for iterables

Index increment is performed at the end of the loop body.
David Mak 2023-09-05 18:05:05 +08:00
parent f46140d74a
commit 18a3263af1
2 changed files with 26 additions and 9 deletions

View File

@ -320,9 +320,8 @@ pub fn gen_for<'ctx, 'a, G: CodeGenerator>(
} else {
let test_bb = backedge_bb_target;
let counter = generator.gen_var_alloc(ctx, size_t.into())?;
// counter = -1
ctx.builder.build_store(counter, size_t.const_int(u64::max_value(), true));
let index_addr = generator.gen_var_alloc_named(ctx, size_t.into(), "for.index.addr")?;
ctx.builder.build_store(index_addr, size_t.const_zero());
let len = ctx
.build_gep_and_load(
iter_val.into_pointer_value(),
@ -332,20 +331,21 @@ pub fn gen_for<'ctx, 'a, G: CodeGenerator>(
ctx.builder.build_unconditional_branch(test_bb);
ctx.builder.position_at_end(test_bb);
let tmp = ctx.builder.build_load(counter, "i").into_int_value();
let tmp = ctx.builder.build_int_add(tmp, size_t.const_int(1, false), "inc");
ctx.builder.build_store(counter, tmp);
let cmp = ctx.builder.build_int_compare(IntPredicate::SLT, tmp, len, "cmp");
let index = ctx.builder.build_load(index_addr, "for.index").into_int_value();
let cmp = ctx.builder.build_int_compare(IntPredicate::SLT, index, len, "cond");
ctx.builder.build_conditional_branch(cmp, body_bb, orelse_bb);
ctx.builder.position_at_end(body_bb);
let arr_ptr = ctx
.build_gep_and_load(iter_val.into_pointer_value(), &[zero, zero])
.into_pointer_value();
let val = ctx.build_gep_and_load(arr_ptr, &[tmp]);
let val = ctx.build_gep_and_load(arr_ptr, &[index]);
generator.gen_assign(ctx, target, val.into())?;
gen_block(generator, ctx, body.iter())?;
let index = ctx.builder.build_load(index_addr, "for.index").into_int_value();
let inc = ctx.builder.build_int_add(index, size_t.const_int(1, true), "");
ctx.builder.build_store(index_addr, inc);
}
for (k, (_, _, counter)) in var_assignment.iter() {

View File

@ -0,0 +1,17 @@
# For Loop using a list as its iterable
@extern
def output_int32(x: int32):
...
def run() -> int32:
l = [0, 1, 2, 3, 4]
# i: int32 # declaration-without-initializer not yet supported
i = 0 # i must be declared before the loop; this is not necessary in Python
for i in l:
output_int32(i)
i = 0
output_int32(i)
output_int32(i)
return 0