return GW_OK;
}
-ANN static inline m_bool emit_stmt_continue(const Emitter emit, const Stmt stmt NUSED) {
- vector_add(&emit->code->stack_cont, (vtype)emit_add_instr(emit, Goto));
+ANN static inline m_bool emit_jump_index(const Emitter emit, const Vector v, const m_int n) {
+ vector_add(v, 0); // make room
+ const m_uint sz = vector_size(v);
+ m_int idx = 1;
+ for(m_uint i = sz; --i > 1;) {
+ if(!vector_at(v, i) && ++idx == n) {
+ m_uint *data = v->ptr + OFFSET + i*SZ_INT;
+ memcpy(data + SZ_INT, data, (sz-i) * SZ_INT);
+ const Instr instr = emit_add_instr(emit, Goto);
+ VPTR(v, i-1) = (m_uint)instr;
+ return GW_OK;
+ }
+ }
+ return GW_ERROR;
+}
+
+ANN static inline m_bool emit_stmt_continue(const Emitter emit, const Stmt_Index stmt) {
+ if(stmt->idx == -1 || stmt->idx == 1)
+ vector_add(&emit->code->stack_cont, (vtype)emit_add_instr(emit, Goto));
+ else if(stmt->idx) {
+ if(emit_jump_index(emit, &emit->code->stack_cont, stmt->idx) < 0)
+ ERR_B(stmt_self(stmt)->pos, _("to many jumps required."))
+ }
return GW_OK;
}
-ANN static inline m_bool emit_stmt_break(const Emitter emit, const Stmt stmt NUSED) {
- vector_add(&emit->code->stack_break, (vtype)emit_add_instr(emit, Goto));
+ANN static inline m_bool emit_stmt_break(const Emitter emit, const Stmt_Index stmt NUSED) {
+ if(stmt->idx == -1 || stmt->idx == 1)
+ vector_add(&emit->code->stack_break, (vtype)emit_add_instr(emit, Goto));
+ else if(stmt->idx) {
+ if(emit_jump_index(emit, &emit->code->stack_break, stmt->idx) < 0)
+ ERR_B(stmt_self(stmt)->pos, _("to many jumps required."))
+ }
return GW_OK;
}
return ret;
}
-ANN static m_bool emit_stmt_jump(const Emitter emit, const Stmt_Jump stmt) {
- if(!stmt->is_label)
- stmt->data.instr = emit_add_instr(emit, Goto);
- else {
- assert(stmt->data.v.ptr);
- const m_uint size = vector_size(&stmt->data.v);
- if(!size)
-//return GW_OK;
- ERR_B(stmt_self(stmt)->pos, _("label '%s' defined but not used."), s_name(stmt->name))
- LOOP_OPTIM
- for(m_uint i = size + 1; --i;) {
- const Stmt_Jump label = (Stmt_Jump)vector_at(&stmt->data.v, i - 1);
- if(!label->data.instr)
- ERR_B(stmt_self(label)->pos, _("you are trying to use a upper label."))
- label->data.instr->m_val = emit_code_size(emit);
- }
- }
- return GW_OK;
-}
-
ANN static m_bool emit_type_def(const Emitter emit, const Type_Def tdef) {
return (!is_fptr(emit->gwion, tdef->type) && tdef->type->info->cdef) ?
emit_class_def(emit, tdef->type->info->cdef) : GW_OK;
}
ANN void unload_context(const Context context, const Env env) {
- if(context->lbls.ptr) {
- LOOP_OPTIM
- for(m_uint i = 0; i < map_size(&context->lbls); i++)
- free_map(env->gwion->mp, (Map)map_at(&context->lbls, i));
- map_release(&context->lbls);
- }
context_remref(context, env->gwion);
env->curr = (Nspc)vector_pop(&env->scope->nspc_stack);
}
#include "vm.h"
#include "parse.h"
-ANN Map env_label(const Env env) {
- return &env->context->lbls;
-}
-
#define GET(a,b) ((a) & (b)) == (b)
ANN m_bool env_access(const Env env, const ae_flag flag, const loc_t pos) {
if(env->scope->depth) {
if(!strcmp(s_name(exp->d.prim.d.var), v->name)) {
*mut = 1;
const Exp exp_func = call->func;
- const Exp exp_base = call->func->d.exp_dot.base;
const Exp exp_args = call->args;
e->exp_type = ae_exp_binary;
e->d.exp_binary.lhs = cpy_exp(env->gwion->mp, exp_func);
describe_check_stmt_stack(conts, continue)
describe_check_stmt_stack(breaks, break)
-ANN static m_bool check_stmt_jump(const Env env, const Stmt_Jump stmt) {
- if(stmt->is_label)
- return GW_OK;
- const Map label = env_label(env);
- const m_uint* key = env->class_def && !env->func ?
- (m_uint*)env->class_def : (m_uint*)env->func;
- const Map m = label->ptr ? (Map)map_get(label, (vtype)key) : NULL;
- if(!m)
- ERR_B(stmt_self(stmt)->pos, _("label '%s' used but not defined"), s_name(stmt->name))
- const Stmt_Jump ref = (Stmt_Jump)map_get(m, (vtype)stmt->name);
- if(!ref)
- ERR_B(stmt_self(stmt)->pos, _("label '%s' used but not defined"), s_name(stmt->name))
- vector_add(&ref->data.v, (vtype)stmt);
- return GW_OK;
-}
-
ANN m_bool check_union_def(const Env env NUSED, const Union_Def udef) {
if(tmpl_base(udef->tmpl)) // there's a func for this
return GW_OK;
#define scan1_stmt_until scan1_stmt_flow
#define scan1_stmt_continue (void*)dummy_func
#define scan1_stmt_break (void*)dummy_func
-#define scan1_stmt_jump (void*)dummy_func
#define scan1_stmt_return scan1_stmt_exp
ANN static m_bool scan1_stmt_pp(const Env env, const Stmt_PP stmt) {
return stmt->val ? scan2_exp(env, stmt->val) : 1;
}
-__attribute__((returns_nonnull))
-ANN static Map scan2_label_map(const Env env) {
- Map m, label = env_label(env);
- const m_uint* key = env->class_def && !env->func ?
- (m_uint*)env->class_def : (m_uint*)env->func;
- if(!label->ptr)
- map_init(label);
- if(!(m = (Map)map_get(label, (vtype)key))) {
- m = new_map(env->gwion->mp);
- map_set(label, (vtype)key, (vtype)m);
- }
- return m;
-}
-
-ANN static m_bool scan2_stmt_jump(const Env env, const Stmt_Jump stmt) {
- if(stmt->is_label) {
- const Map m = scan2_label_map(env);
- if(map_get(m, (vtype)stmt->name))
- ERR_B(stmt_self(stmt)->pos, _("label '%s' already defined"), s_name(stmt->name))
- map_set(m, (vtype)stmt->name, (vtype)stmt);
- vector_init(&stmt->data.v);
- }
- return GW_OK;
-}
-
ANN m_bool scan2_union_def(const Env env NUSED, const Union_Def udef) {
if(tmpl_base(udef->tmpl))
return GW_OK;