-Subproject commit ec83de3d86f1288cf88d3dc095fd77e35a48126f
+Subproject commit 5c6ff39a52550be2956e927091e58470d3cc6dc6
--a->scope;
}
+ANN static void clean_idx(Clean *a, struct EachIdx_ *b) {
+ if(b->v)
+ value_remref(b->v, a->gwion);
+}
+
ANN static void clean_stmt_each(Clean *a, Stmt_Each b) {
++a->scope;
clean_exp(a, b->exp);
clean_stmt(a, b->body);
if(b->v)
value_remref(b->v, a->gwion);
+ if(b->idx)
+ clean_idx(a, b->idx);
--a->scope;
}
}
ANN static void stmt_loop_roll(const Emitter emit, const struct Looper *loop) {
- const Instr cpy = emit_add_instr(emit, RegPushMem4);
- cpy->m_val = loop->offset;
+ const Instr counter = emit_add_instr(emit, RegPushMem4);
+ counter->m_val = loop->offset;
emit_add_instr(emit, int_post_dec);
}
+ANN static void stmt_loop_roll_idx(const Emitter emit, const struct Looper *loop) {
+ const Instr target = emit_add_instr(emit, RegPushMem);
+ target->m_val = loop->offset + SZ_INT;
+ const Instr counter = emit_add_instr(emit, RegPushMem4);
+ counter->m_val = loop->offset;
+ emit_add_instr(emit, int_post_inc);
+ emit_add_instr(emit, int_minus);
+}
+
ANN static m_bool _emit_stmt_loop(const Emitter emit, const Stmt_Loop stmt, m_uint *index) {
const uint n = emit->info->unroll;
if(n)
unroll_init(emit, n);
const m_uint offset = emit_local(emit, emit->gwion->type[et_int]);
+ if(stmt->idx)
+ emit_local(emit, emit->gwion->type[et_int]);
CHECK_BB(emit_exp_pop_next(emit, stmt->cond));
regpop(emit, SZ_INT);
+// set mem
const Instr tomem = emit_add_instr(emit, Reg2Mem);
- tomem->m_val = offset;
+ tomem->m_val = offset + !stmt->idx ? 0 : SZ_INT;
*index = emit_code_size(emit);
struct Looper loop = { .stmt=stmt->body, .offset=offset, .n=n,
- .roll=stmt_loop_roll };
+ .roll= !stmt->idx ? stmt_loop_roll : stmt_loop_roll_idx};
CHECK_BB(looper_run(emit, &loop));
const Instr _goto = emit_add_instr(emit, Goto);
_goto->m_val = *index;
return depth ? array_type(env, t, depth) : t;
}
+ANN static void check_idx(const Env env, struct EachIdx_ *const idx) {
+ idx->v = new_value(env->gwion->mp, env->gwion->type[et_int], s_name(idx->sym));
+ valuefrom(env, idx->v->from, idx->pos);
+ set_vflag(idx->v, vflag_valid);
+ nspc_add_value(env->curr, idx->sym, idx->v);
+}
+
ANN static m_bool do_stmt_each(const Env env, const Stmt_Each stmt) {
DECL_OB(const Type, base, = foreach_type(env, stmt->exp));
CHECK_BB(ensure_traverse(env, base));
stmt->v = new_value(env->gwion->mp, ret, s_name(stmt->sym));
set_vflag(stmt->v, vflag_valid);
nspc_add_value(env->curr, stmt->sym, stmt->v);
- if(stmt->idx) {
- stmt->idx->v = new_value(env->gwion->mp, env->gwion->type[et_int], s_name(stmt->idx->sym));
- valuefrom(env, stmt->idx->v->from, stmt->idx->pos);
- set_vflag(stmt->idx->v, vflag_valid);
- nspc_add_value(env->curr, stmt->idx->sym, stmt->idx->v);
- }
+ if(stmt->idx)
+ check_idx(env, stmt->idx);
+ return check_conts(env, stmt_self(stmt), stmt->body);
+}
+
+ANN static m_bool do_stmt_repeat(const Env env, const Stmt_Loop stmt) {
+ if(stmt->idx)
+ check_idx(env, stmt->idx);
return check_conts(env, stmt_self(stmt), stmt->body);
}
!check_flow(env, stmt->c2->d.stmt_exp.val) ||
(stmt->c3 && !check_exp(env, stmt->c3)) ||
check_conts(env, stmt_self(stmt), stmt->body) < 0) ? 1 : -1)
-stmt_func_xxx(loop, Stmt_Loop,, !(!check_exp(env, stmt->cond) ||
+stmt_func_xxx(loop, Stmt_Loop, check_idx(env, stmt->idx), !(!check_exp(env, stmt->cond) ||
cond_type(env, stmt->cond) < 0 ||
- check_conts(env, stmt_self(stmt), stmt->body) < 0) ? 1 : -1)
+ do_stmt_repeat(env, stmt) < 0) ? 1 : -1)
stmt_func_xxx(each, Stmt_Each,, do_stmt_each(env, stmt))
ANN static m_bool check_stmt_return(const Env env, const Stmt_Exp stmt) {
return GW_OK;
}
+ANN static inline m_bool shadow_err(const Env env, const Symbol sym, const loc_t loc) {
+ ERR_B(loc, _("argument '%s' shadows a previously defined variable"),
+ s_name(sym))
+}
+
+ANN static inline m_bool shadow_arg(const Env env, const Symbol sym, const loc_t loc) {
+ Nspc nspc = env->curr;
+ do if(nspc_lookup_value0(nspc, sym))
+ return shadow_err(env, sym, loc);
+ while((nspc = nspc->parent));
+ return GW_OK;
+}
+
+ANN static inline m_bool shadow_var(const Env env, const Symbol sym, const loc_t loc) {
+ if(nspc_lookup_value1(env->curr, sym))
+ return shadow_err(env, sym, loc);
+ return GW_OK;
+}
+
#define describe_ret_nspc(name, type, prolog, exp) describe_stmt_func(scan1, name, type, prolog, exp)
describe_ret_nspc(flow, Stmt_Flow,, !(scan1_exp(env, stmt->cond) < 0 ||
scan1_stmt(env, stmt->body) < 0) ? 1 : -1)
scan1_stmt(env, stmt->body) < 0) ? 1 : -1)
describe_ret_nspc(each, Stmt_Each,, !(stmt_each_defined(env, stmt) < 0 || scan1_exp(env, stmt->exp) < 0 ||
scan1_stmt(env, stmt->body) < 0) ? 1 : -1)
-describe_ret_nspc(loop, Stmt_Loop,, !(scan1_exp(env, stmt->cond) < 0 ||
+describe_ret_nspc(loop, Stmt_Loop,, !( (!stmt->idx ? GW_OK : shadow_var(env, stmt->idx->sym, stmt->idx->pos)) < 0 ||
+ scan1_exp(env, stmt->cond) < 0 ||
scan1_stmt(env, stmt->body) < 0) ? 1 : -1)
describe_ret_nspc(if, Stmt_If,, !(scan1_exp(env, stmt->cond) < 0 ||
scan1_stmt(env, stmt->if_body) < 0 ||
}
ANN static m_bool scan1_fdef_args(const Env env, Arg_List list) {
- do {
- Nspc nspc = env->curr;
- do if(nspc_lookup_value0(nspc, list->var_decl->xid))
- ERR_B(list->var_decl->pos, _("argument '%s' shadows a previously defined variable"),
- s_name(list->var_decl->xid))
- while((nspc = nspc->parent));
- } while((list = list->next));
+ do CHECK_BB(shadow_arg(env, list->var_decl->xid, list->var_decl->pos));
+ while((list = list->next));
return GW_OK;
}
--- /dev/null
+repeat(i, 100000)
+ <<< "${i} test" >>>;
+repeat(100000)
+ <<< "test" >>>;
--- /dev/null
+#! [contains] shadows a previously defined variable
+var int i;
+
+repeat(i, 12);