From 4481d48709ecc2eda7f6eaba86e9b94511d418c4 Mon Sep 17 00:00:00 2001 From: David Mak Date: Tue, 5 Sep 2023 18:05:05 +0800 Subject: [PATCH] core: Use C-style for loop logic for iterables Index increment is now performed at the end of the loop body. --- nac3core/src/codegen/stmt.rs | 18 +++++++++--------- nac3standalone/demo/src/loop_iterable.py | 17 +++++++++++++++++ 2 files changed, 26 insertions(+), 9 deletions(-) create mode 100644 nac3standalone/demo/src/loop_iterable.py diff --git a/nac3core/src/codegen/stmt.rs b/nac3core/src/codegen/stmt.rs index f1edf77d..b310097d 100644 --- a/nac3core/src/codegen/stmt.rs +++ b/nac3core/src/codegen/stmt.rs @@ -321,9 +321,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(), Some("for.counter.addr"))?; - // counter = -1 - ctx.builder.build_store(counter, size_t.const_int(u64::max_value(), true)); + let index_addr = generator.gen_var_alloc(ctx, size_t.into(), Some("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(), @@ -333,20 +332,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() { diff --git a/nac3standalone/demo/src/loop_iterable.py b/nac3standalone/demo/src/loop_iterable.py new file mode 100644 index 00000000..d97ab305 --- /dev/null +++ b/nac3standalone/demo/src/loop_iterable.py @@ -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