forked from M-Labs/nac3
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:
parent
b4983526bd
commit
4481d48709
|
@ -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() {
|
||||||
|
|
|
@ -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
|
Loading…
Reference in New Issue