From: fennecdjay Date: Tue, 9 Aug 2022 12:14:20 +0000 (+0200) Subject: :art: allow (re)perform X-Git-Tag: nightly~264^2~45 X-Git-Url: http://10.10.0.4:5575/?a=commitdiff_plain;h=06b5af9241ca52409315ca7918d5dfa06b30ae2d;p=gwion.git :art: allow (re)perform --- diff --git a/ast b/ast index d209401a..f28bf415 160000 --- a/ast +++ b/ast @@ -1 +1 @@ -Subproject commit d209401af10f46516613b71cccd91ebc01ebd28c +Subproject commit f28bf415a5e5a787ff357982a7efbf5b0d68de3b diff --git a/include/emit.h b/include/emit.h index 6429f3b2..1b4ad3a6 100644 --- a/include/emit.h +++ b/include/emit.h @@ -48,6 +48,7 @@ typedef struct EmitterStatus { uint16_t this_offset; // reset uint16_t unroll; uint16_t line; + uint32_t effect; // offset of last throw effect bool in_return; } EmitterStatus; diff --git a/src/emit/emit.c b/src/emit/emit.c index 077a39c4..b981760a 100644 --- a/src/emit/emit.c +++ b/src/emit/emit.c @@ -781,7 +781,8 @@ ANN static m_bool emit_prim_id(const Emitter emit, const Symbol *data) { ANN static m_bool emit_prim_perform(const Emitter emit, const Symbol *xid) { const Instr instr = emit_add_instr(emit, PerformEffect); - instr->m_val = (m_uint)s_name(*xid); + if(*xid) instr->m_val = (m_uint)s_name(*xid); + instr->m_val2 = emit->status.effect; return GW_OK; } @@ -2393,14 +2394,20 @@ ANN static inline void try_goto_indexes(const Vector v, const m_uint pc) { ANN static inline m_bool emit_handler_list(const restrict Emitter emit, const Handler_List handlers, const Vector v) { + emit_push_scope(emit); + const m_uint offset = emit_local(emit, emit->gwion->type[et_int]); for(uint32_t i = 0; i < handlers->len; i++) { Handler *handler = mp_vector_at(handlers, Handler, i); + // useless args. should be not in the VM const Instr instr = emit_add_instr(emit, HandleEffect); - instr->m_val2 = (m_uint)handler->xid; + instr->m_val = emit->status.effect = offset; + instr->m_val2 = (m_uint)handler->xid; // are we even using this? CHECK_BB(scoped_stmt(emit, handler->stmt, 1)); emit_try_goto(emit, v); instr->m_val = emit_code_size(emit); } +// emit->status.effect = 0; + emit_pop_scope(emit); return GW_OK; } diff --git a/src/parse/check.c b/src/parse/check.c index 455ab147..e14a99e7 100644 --- a/src/parse/check.c +++ b/src/parse/check.c @@ -391,7 +391,9 @@ ANN static Type check_prim_id(const Env env, const Symbol *data) { } ANN static Type check_prim_perform(const Env env, const Symbol *data) { - env_add_effect(env, *data, prim_pos(data)); + if(*data) env_add_effect(env, *data, prim_pos(data)); + else if(!env->scope->in_try) + ERR_O(prim_pos(data), "`rethrow` outside try/handle statement"); env_weight(env, 1); return env->gwion->type[et_void]; } @@ -1517,10 +1519,13 @@ ANN static inline m_bool check_handler(const restrict Env env, ANN static inline m_bool check_handler_list(const restrict Env env, const Handler_List handlers) { + const bool in_try = env->scope->in_try; + env->scope->in_try = true; for(uint32_t i = 0; i < handlers->len; i++) { Handler *handler = mp_vector_at(handlers, Handler, i); CHECK_BB(check_handler(env, handler)); } + env->scope->in_try = in_try; return GW_OK; } @@ -1528,6 +1533,7 @@ ANN static inline bool find_handler(const Handler_List handlers, const Symbol xi for(uint32_t i = 0; i < handlers->len; i++) { Handler *handler = mp_vector_at(handlers, Handler, i); if(xid == handler->xid) return true; + if(!handler->xid) return true; } return false; } @@ -1537,7 +1543,7 @@ ANN static inline m_bool check_stmt_try_start(const restrict Env env, RET_NSPC(check_stmt(env, stmt->stmt)) } -ANN static inline m_bool _check_stmt_try(const restrict Env env, const Stmt_Try stmt) { +ANN static inline m_bool check_stmt_try(const restrict Env env, const Stmt_Try stmt) { CHECK_BB(check_handler_list(env, stmt->handler)); vector_add(&env->scope->effects, 0); const m_bool ret = check_stmt_try_start(env, stmt); @@ -1553,14 +1559,6 @@ ANN static inline m_bool _check_stmt_try(const restrict Env env, const Stmt_Try return ret; } -ANN static inline m_bool check_stmt_try(const restrict Env env, - const Stmt_Try stmt) { - const bool in_try = env->scope->in_try; - const m_bool ret = _check_stmt_try(env, stmt); - env->scope->in_try = in_try; - return ret; -} - ANN static m_bool _check_stmt_match(const Env env, const Stmt_Match stmt) { CHECK_OB(check_exp(env, stmt->cond)); MATCH_INI(env->scope) diff --git a/src/vm/vm.c b/src/vm/vm.c index d14d07a4..d568972b 100644 --- a/src/vm/vm.c +++ b/src/vm/vm.c @@ -83,6 +83,10 @@ ANN static inline bool find_handle(const VM_Shred shred, const Symbol effect) { (m_bit *)VPTR(&shred->info->frame, VLEN(&shred->info->frame) - 1); shredule(shred->tick->shreduler, shred, 0); shred->pc = pc; // VKEY(m, i); + const Instr instr = vector_at(&shred->code->instr, pc); + if(!instr->m_val) + *(m_uint*)(shred->mem + instr->m_val2) = s_name(effect); + vector_pop(&shred->info->frame); vector_pop(&shred->info->frame); return true; @@ -1215,8 +1219,10 @@ fflush(stdout); // this should check the *xid* of the exception DISPATCH(); performeffect: -// VM_OUT - handle(shred, (m_str)VAL); +{ + const m_str effect = (m_str)VAL ?: *(m_str*)(mem + VAL2); + handle(shred, effect); +} break; noop: DISPATCH();