]> Nishi Git Mirror - gwion.git/commitdiff
:art: allow (re)perform
authorfennecdjay <fennecdjay@gmail.com>
Tue, 9 Aug 2022 12:14:20 +0000 (14:14 +0200)
committerfennecdjay <fennecdjay@gmail.com>
Tue, 9 Aug 2022 12:14:20 +0000 (14:14 +0200)
ast
include/emit.h
src/emit/emit.c
src/parse/check.c
src/vm/vm.c

diff --git a/ast b/ast
index d209401af10f46516613b71cccd91ebc01ebd28c..f28bf415a5e5a787ff357982a7efbf5b0d68de3b 160000 (submodule)
--- a/ast
+++ b/ast
@@ -1 +1 @@
-Subproject commit d209401af10f46516613b71cccd91ebc01ebd28c
+Subproject commit f28bf415a5e5a787ff357982a7efbf5b0d68de3b
index 6429f3b2b3c2ae0ccc269aa5daae7919a9451e0f..1b4ad3a6a1422a80e73238f84d1bc04fda60ca2c 100644 (file)
@@ -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;
 
index 077a39c4a07e333b2312cf04b9280646e70e7789..b981760a62e16c1ebe5f882cf8b0f2e69b22b630 100644 (file)
@@ -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;
 }
 
index 455ab1470ec88549a01aadd4059471e71cf98636..e14a99e7f91a9251f7e83c361f9138eeb54cf46f 100644 (file)
@@ -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)
index d14d07a4bd2b81f13672279dc3db03c29b655e41..d568972b5491a3a769e378091e740ebe1a31ff57 100644 (file)
@@ -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();