core: Use C-style for loop logic for iterables

Index increment is now performed at the end of the loop body.
This commit is contained in:
David Mak 2023-09-05 18:05:05 +08:00
parent b4983526bd
commit 4481d48709
2 changed files with 26 additions and 9 deletions

View File

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