Support #reverse on #soa arrays

This commit is contained in:
gingerBill
2023-05-29 23:24:03 +01:00
parent 97490c6445
commit f07453d0ae
2 changed files with 32 additions and 13 deletions

View File

@@ -1596,10 +1596,6 @@ gb_internal void check_range_stmt(CheckerContext *ctx, Ast *node, u32 mod_flags)
if (is_ptr) use_by_reference_for_value = true;
array_add(&vals, t->Struct.soa_elem);
array_add(&vals, t_int);
if (is_reverse) {
error(node, "#reverse for is not yet supported for #soa types");
}
}
break;
}

View File

@@ -730,6 +730,8 @@ gb_internal void lb_build_range_stmt_struct_soa(lbProcedure *p, AstRangeStmt *rs
lbBlock *body = nullptr;
lbBlock *done = nullptr;
bool is_reverse = rs->reverse;
lb_open_scope(p, scope);
@@ -751,19 +753,40 @@ gb_internal void lb_build_range_stmt_struct_soa(lbProcedure *p, AstRangeStmt *rs
lbAddr index = lb_add_local_generated(p, t_int, false);
lb_addr_store(p, index, lb_const_int(p->module, t_int, cast(u64)-1));
loop = lb_create_block(p, "for.soa.loop");
lb_emit_jump(p, loop);
lb_start_block(p, loop);
lbValue incr = {};
lbValue cond = {};
lbValue incr = lb_emit_arith(p, Token_Add, lb_addr_load(p, index), lb_const_int(p->module, t_int, 1), t_int);
lb_addr_store(p, index, incr);
if (!is_reverse) {
lb_addr_store(p, index, lb_const_int(p->module, t_int, cast(u64)-1));
body = lb_create_block(p, "for.soa.body");
done = lb_create_block(p, "for.soa.done");
loop = lb_create_block(p, "for.soa.loop");
lb_emit_jump(p, loop);
lb_start_block(p, loop);
lbValue cond = lb_emit_comp(p, Token_Lt, incr, count);
incr = lb_emit_arith(p, Token_Add, lb_addr_load(p, index), lb_const_int(p->module, t_int, 1), t_int);
lb_addr_store(p, index, incr);
body = lb_create_block(p, "for.soa.body");
done = lb_create_block(p, "for.soa.done");
cond = lb_emit_comp(p, Token_Lt, incr, count);
} else {
// NOTE(bill): REVERSED LOGIC
lb_addr_store(p, index, count);
loop = lb_create_block(p, "for.soa.loop");
lb_emit_jump(p, loop);
lb_start_block(p, loop);
incr = lb_emit_arith(p, Token_Sub, lb_addr_load(p, index), lb_const_int(p->module, t_int, 1), t_int);
lb_addr_store(p, index, incr);
body = lb_create_block(p, "for.soa.body");
done = lb_create_block(p, "for.soa.done");
cond = lb_emit_comp(p, Token_GtEq, incr, lb_const_int(p->module, t_int, 0));
}
lb_emit_if(p, cond, body, done);
lb_start_block(p, body);