]> Nishi Git Mirror - gwion.git/commitdiff
:art: Add defer
authorJérémie Astor <fennecdjay@gmail.com>
Mon, 1 Feb 2021 00:58:51 +0000 (01:58 +0100)
committerJérémie Astor <fennecdjay@gmail.com>
Mon, 1 Feb 2021 00:58:51 +0000 (01:58 +0100)
ast
include/emit.h
src/clean.c
src/emit/emit.c
src/parse/check.c
src/parse/scan1.c
src/parse/scan2.c

diff --git a/ast b/ast
index 5d05f28d371e29fbebbf3928572c1039ca45c04f..e3ea3bb0f5634a3a620ac7a8c535976fd5afa530 160000 (submodule)
--- a/ast
+++ b/ast
@@ -1 +1 @@
-Subproject commit 5d05f28d371e29fbebbf3928572c1039ca45c04f
+Subproject commit e3ea3bb0f5634a3a620ac7a8c535976fd5afa530
index 301d988de1022dd0f7cc0d9ca3a2c684b4905dcf..11936165079e3605a08eba10df2d0256213353be 100644 (file)
@@ -4,13 +4,16 @@
 typedef struct Frame_ {
   size_t curr_offset;
   struct Vector_ stack;
+  struct Vector_ defer;
 } Frame;
 
 typedef struct Code_ {
   Frame* frame;
   size_t stack_depth;
   struct Vector_ instr;
-  struct Vector_ stack_cont, stack_break, stack_return;
+  struct Vector_  stack_cont;
+  struct Vector_ stack_break;
+  struct Vector_ stack_return;
   m_str  name;
 } Code;
 
index b4591701d75e1fc2d8ebcc54555c8ec1e62445d2..f9d92cab23d6e25b2e83ae9f2e4da33019cd0cd3 100644 (file)
@@ -239,6 +239,9 @@ ANN static void clean_stmt_case(Clean *a, Stmt_Match b) {
   --a->scope;
 }
 
+ANN static void clean_stmt_defer(Clean *a, Stmt_Defer b) {
+  clean_stmt(a, b->stmt);
+}
 
 ANN static void clean_dummy(Clean *a NUSED, void *b NUSED) {}
 #define clean_stmt_jump clean_dummy
index 770d2e6eca5db416a3db46165dae29208f1417eb..ca1eb23ed5869fef97e10f3bf361ac5646bfaa5d 100644 (file)
@@ -45,6 +45,8 @@ ANEW static Frame* new_frame(MemPool p) {
   Frame* frame = mp_calloc(p, Frame);
   vector_init(&frame->stack);
   vector_add(&frame->stack, (vtype)NULL);
+  vector_init(&frame->defer);
+  vector_add(&frame->defer, (vtype)NULL);
   return frame;
 }
 
@@ -74,6 +76,7 @@ ANN static m_uint frame_local(MemPool p, Frame* frame, const Type t, const uint
 
 ANN static inline void frame_push(Frame* frame) {
   vector_add(&frame->stack, (vtype)NULL);
+  vector_add(&frame->defer, (vtype)NULL);
 }
 
 static const f_instr regpushimm[] = { RegPushImm, RegPushImm2, RegPushImm3, RegPushImm4 };
@@ -154,17 +157,43 @@ ANN static void struct_pop(const Emitter emit, const Type type, const m_uint off
   }
 }
 
-ANN static m_int frame_pop(const Emitter emit) {
+ANN static m_bool emit_stmt(const Emitter emit, const Stmt stmt, const m_bool pop);
+
+ANN static m_bool emit_defers(const Emitter emit) {
+  if(!vector_size(&emit->code->frame->defer))
+    return GW_OK;
+  Stmt stmt;
+  while((stmt = (Stmt)vector_pop(&emit->code->frame->defer)))
+    CHECK_BB(emit_stmt(emit, stmt, 1))
+  return GW_OK;
+}
+
+ANN static m_bool emit_defers2(const Emitter emit) {
+  for(m_uint i = vector_size(&emit->code->frame->defer) + 1; --i;) {
+    const Stmt stmt = (Stmt)vector_at(&emit->code->frame->defer, i-1);
+    if(!stmt)
+      break;
+    CHECK_BB(emit_stmt(emit, stmt, 1))
+  }
+  return GW_OK;
+}
+
+ANN static m_int _frame_pop(const Emitter emit) {
   Frame *frame = emit->code->frame;
   DECL_OB(const Local*, l, = (Local*)vector_pop(&frame->stack))
   frame->curr_offset -= l->type->size;
   if(l->skip)
-    return frame_pop(emit);
+    return _frame_pop(emit);
   if(tflag(l->type, tflag_struct)) {
     struct_pop(emit, l->type, l->offset);
-    return frame_pop(emit);
+    return _frame_pop(emit);
   }
-  return isa(l->type, emit->gwion->type[et_object]) > 0 ? (m_int)l->offset : frame_pop(emit);
+  return isa(l->type, emit->gwion->type[et_object]) > 0 ? (m_int)l->offset : _frame_pop(emit);
+}
+
+ANN static m_int frame_pop(const Emitter emit) {
+  emit_defers(emit);
+  return _frame_pop(emit);
 }
 
 ANN /*static */m_bool emit_exp(const Emitter emit, Exp exp);
@@ -1508,6 +1537,7 @@ ANN static m_bool optimize_taill_call(const Emitter emit, const Exp_Call* e) {
 }
 
 ANN static m_bool emit_stmt_return(const Emitter emit, const Stmt_Exp stmt) {
+  CHECK_BB(emit_defers2(emit))
   if(stmt->val) {
     if(stmt->val->exp_type == ae_exp_call) {
       const Func f = stmt->val->d.exp_call.func->type->info->func;
@@ -1537,6 +1567,7 @@ ANN static inline m_bool emit_jump_index(const Emitter emit, const Vector v, con
 }
 
 ANN static inline m_bool emit_stmt_continue(const Emitter emit, const Stmt_Index stmt) {
+  CHECK_BB(emit_defers2(emit))
   if(stmt->idx == -1 || stmt->idx == 1)
     vector_add(&emit->code->stack_cont, (vtype)emit_add_instr(emit, Goto));
   else if(stmt->idx) {
@@ -1547,6 +1578,7 @@ ANN static inline m_bool emit_stmt_continue(const Emitter emit, const Stmt_Index
 }
 
 ANN static inline m_bool emit_stmt_break(const Emitter emit, const Stmt_Index stmt NUSED) {
+  CHECK_BB(emit_defers2(emit))
   if(stmt->idx == -1 || stmt->idx == 1)
     vector_add(&emit->code->stack_break, (vtype)emit_add_instr(emit, Goto));
   else if(stmt->idx) {
@@ -1778,7 +1810,6 @@ ANN static m_bool _emit_stmt_loop(const Emitter emit, const Stmt_Loop stmt, m_ui
   *index = emit_code_size(emit);
   struct Looper loop = { .stmt=stmt->body, .offset=offset, .n=n,
     .roll=stmt_loop_roll };
-//roll(emit, &loop);
   CHECK_BB(looper_run(emit, &loop))
   const Instr _goto = emit_add_instr(emit, Goto);
   _goto->m_val = *index;
@@ -1997,6 +2028,11 @@ ANN static m_bool emit_stmt_pp(const Emitter emit, const struct Stmt_PP_* stmt)
   return GW_OK;
 }
 
+ANN static m_bool emit_stmt_defer(const Emitter emit, const struct Stmt_Defer_* stmt) {
+  vector_add(&emit->code->frame->defer, (m_uint)stmt->stmt);
+  return GW_OK;
+}
+
 #define emit_stmt_while emit_stmt_flow
 #define emit_stmt_until emit_stmt_flow
 DECL_STMT_FUNC(emit, m_bool , Emitter)
@@ -2051,8 +2087,9 @@ ANN static void emit_func_def_ensure(const Emitter emit, const Func_Def fdef) {
   vector_add(&emit->code->stack_return, (vtype)emit_add_instr(emit, Goto));
 }
 
-ANN static void emit_func_def_return(const Emitter emit) {
+ANN static m_bool emit_func_def_return(const Emitter emit) {
   const m_uint val = emit_code_size(emit);
+  CHECK_BB(emit_defers(emit))
   LOOP_OPTIM
   for(m_uint i = vector_size(&emit->code->stack_return) + 1; --i; ) {
     const Instr instr = (Instr)vector_at(&emit->code->stack_return, i-1);
@@ -2063,6 +2100,7 @@ ANN static void emit_func_def_return(const Emitter emit) {
     const Instr instr = emit_add_instr(emit, MemoizeStore);
     instr->m_val = emit->env->func->def->stack_depth;
   }
+  return GW_OK;
 }
 
 ANN static VM_Code emit_internal(const Emitter emit, const Func f) {
@@ -2285,7 +2323,7 @@ ANN static VM_Code emit_free_stack(const Emitter emit) {
 ANN static inline m_bool emit_ast_inner(const Emitter emit, Ast ast) {
   do CHECK_BB(emit_section(emit, ast->section))
   while((ast = ast->next));
-  return GW_OK;
+  return emit_defers(emit);
 }
 
 ANN m_bool emit_ast(const Env env, Ast ast) {
index 973018f507018759c77d63f99f92641993e80fda..be94441041be4e9c2932ac9c49c7ed3d920553dd 100644 (file)
@@ -1111,6 +1111,10 @@ ANN static m_bool check_stmt_pp(const Env env, const Stmt_PP stmt) {
   return GW_OK;
 }
 
+ANN static m_bool check_stmt_defer(const Env env, const Stmt_Defer stmt) {
+  return check_stmt(env, stmt->stmt);
+}
+
 DECL_STMT_FUNC(check, m_bool , Env)
 
 ANN m_bool check_stmt(const Env env, const Stmt stmt) {
index d6a7bd6e0e4b39892e741ae79db89a2b1898a255..624af641201f1b9f2e43550a6556397daf25dee9 100644 (file)
@@ -459,6 +459,10 @@ ANN static m_bool scan1_stmt_pp(const Env env, const Stmt_PP stmt) {
   return GW_OK;
 }
 
+ANN static m_bool scan1_stmt_defer(const Env env, const Stmt_Defer stmt) {
+  return scan1_stmt(env, stmt->stmt);
+}
+
 DECL_STMT_FUNC(scan1, m_bool, Env)
 
 ANN static inline m_bool scan1_stmt(const Env env, const Stmt stmt) {
index 7407540fdb2db1fa19d572c21f24f02522f3fd0d..837e50914c6c5083b8128e4eb041783d832e3abe 100644 (file)
@@ -253,6 +253,10 @@ ANN static m_bool scan2_stmt_pp(const Env env, const Stmt_PP stmt) {
   return GW_OK;
 }
 
+ANN static m_bool scan2_stmt_defer(const Env env, const Stmt_Defer stmt) {
+  return scan2_stmt(env, stmt->stmt);
+}
+
 DECL_STMT_FUNC(scan2, m_bool, Env)
 
 ANN static m_bool scan2_stmt(const Env env, const Stmt stmt) {