nac3core/codegen: supports list iter
This commit is contained in:
parent
fb92b6d364
commit
181607008d
|
@ -102,6 +102,8 @@ pub fn gen_for<'ctx, 'a, G: CodeGenerator + ?Sized>(
|
||||||
stmt: &Stmt<Option<Type>>,
|
stmt: &Stmt<Option<Type>>,
|
||||||
) {
|
) {
|
||||||
if let StmtKind::For { iter, target, body, orelse, .. } = &stmt.node {
|
if let StmtKind::For { iter, target, body, orelse, .. } = &stmt.node {
|
||||||
|
let int32 = ctx.ctx.i32_type();
|
||||||
|
let zero = int32.const_zero();
|
||||||
let current = ctx.builder.get_insert_block().unwrap().get_parent().unwrap();
|
let current = ctx.builder.get_insert_block().unwrap().get_parent().unwrap();
|
||||||
let test_bb = ctx.ctx.append_basic_block(current, "test");
|
let test_bb = ctx.ctx.append_basic_block(current, "test");
|
||||||
let body_bb = ctx.ctx.append_basic_block(current, "body");
|
let body_bb = ctx.ctx.append_basic_block(current, "body");
|
||||||
|
@ -117,7 +119,6 @@ pub fn gen_for<'ctx, 'a, G: CodeGenerator + ?Sized>(
|
||||||
// setup
|
// setup
|
||||||
let iter_val = iter_val.into_pointer_value();
|
let iter_val = iter_val.into_pointer_value();
|
||||||
let i = generator.gen_store_target(ctx, target);
|
let i = generator.gen_store_target(ctx, target);
|
||||||
let int32 = ctx.ctx.i32_type();
|
|
||||||
let start;
|
let start;
|
||||||
let end;
|
let end;
|
||||||
let step;
|
let step;
|
||||||
|
@ -166,7 +167,11 @@ pub fn gen_for<'ctx, 'a, G: CodeGenerator + ?Sized>(
|
||||||
"sign",
|
"sign",
|
||||||
);
|
);
|
||||||
// add and test
|
// add and test
|
||||||
let tmp = ctx.builder.build_int_add(ctx.builder.build_load(i, "i").into_int_value(), step, "start_loop");
|
let tmp = ctx.builder.build_int_add(
|
||||||
|
ctx.builder.build_load(i, "i").into_int_value(),
|
||||||
|
step,
|
||||||
|
"start_loop",
|
||||||
|
);
|
||||||
ctx.builder.build_store(i, tmp);
|
ctx.builder.build_store(i, tmp);
|
||||||
// // if step > 0, continue when i < end
|
// // if step > 0, continue when i < end
|
||||||
let cmp1 = ctx.builder.build_int_compare(inkwell::IntPredicate::SLT, tmp, end, "cmp1");
|
let cmp1 = ctx.builder.build_int_compare(inkwell::IntPredicate::SLT, tmp, end, "cmp1");
|
||||||
|
@ -179,11 +184,44 @@ pub fn gen_for<'ctx, 'a, G: CodeGenerator + ?Sized>(
|
||||||
body_bb,
|
body_bb,
|
||||||
orelse_bb,
|
orelse_bb,
|
||||||
);
|
);
|
||||||
|
ctx.builder.position_at_end(body_bb);
|
||||||
} else {
|
} else {
|
||||||
unimplemented!()
|
let counter = generator.gen_var_alloc(ctx, ctx.primitives.int32);
|
||||||
|
// counter = -1
|
||||||
|
ctx.builder.build_store(counter, ctx.ctx.i32_type().const_int(u64::max_value(), true));
|
||||||
|
let len = unsafe {
|
||||||
|
ctx.builder
|
||||||
|
.build_load(
|
||||||
|
ctx.builder.build_in_bounds_gep(
|
||||||
|
iter_val.into_pointer_value(),
|
||||||
|
&[zero, zero],
|
||||||
|
"len_ptr",
|
||||||
|
),
|
||||||
|
"len",
|
||||||
|
)
|
||||||
|
.into_int_value()
|
||||||
|
};
|
||||||
|
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, int32.const_int(1, false), "inc");
|
||||||
|
ctx.builder.build_store(counter, tmp);
|
||||||
|
let cmp = ctx.builder.build_int_compare(inkwell::IntPredicate::SLT, tmp, len, "cmp");
|
||||||
|
ctx.builder.build_conditional_branch(cmp, body_bb, orelse_bb);
|
||||||
|
ctx.builder.position_at_end(body_bb);
|
||||||
|
unsafe {
|
||||||
|
let ptr_to_arr = ctx.builder.build_in_bounds_gep(
|
||||||
|
iter_val.into_pointer_value(),
|
||||||
|
&[zero, int32.const_int(1, false)],
|
||||||
|
"ptr_to_arr",
|
||||||
|
);
|
||||||
|
let arr_ptr = ctx.builder.build_load(ptr_to_arr, "loadptr").into_pointer_value();
|
||||||
|
let ptr = ctx.builder.build_gep(arr_ptr, &[tmp], "loadarrgep");
|
||||||
|
let val = ctx.builder.build_load(ptr, "loadarr");
|
||||||
|
generator.gen_assign(ctx, target, val);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
ctx.builder.position_at_end(body_bb);
|
|
||||||
for stmt in body.iter() {
|
for stmt in body.iter() {
|
||||||
generator.gen_stmt(ctx, stmt);
|
generator.gen_stmt(ctx, stmt);
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue