]> granicus.if.org Git - jq/commitdiff
Remove the YIELD opcode (use RET instead)
authorStephen Dolan <mu@netsoc.tcd.ie>
Wed, 15 May 2013 00:23:06 +0000 (01:23 +0100)
committerStephen Dolan <mu@netsoc.tcd.ie>
Wed, 15 May 2013 00:23:06 +0000 (01:23 +0100)
compile.c
execute.c
opcode_list.h

index de9c14c36ca3c8538c6731ffacbf641892741015..d305c5c89d648baeff3a23d734d96ee1589ad299 100644 (file)
--- a/compile.c
+++ b/compile.c
@@ -507,13 +507,7 @@ static int compile(struct locfile* locations, struct bytecode* bc, block b) {
   int var_frame_idx = 0;
   bc->nsubfunctions = 0;
   errors += expand_call_arglist(locations, &b);
-  if (bc->parent) {
-    // functions should end in a return
-    b = BLOCK(b, gen_op_simple(RET));
-  } else {
-    // the toplevel should YIELD;BACKTRACK; when it finds an answer
-    b = BLOCK(b, gen_op_simple(YIELD), gen_op_simple(BACKTRACK));
-  }
+  b = BLOCK(b, gen_op_simple(RET));
   for (inst* curr = b.first; curr; curr = curr->next) {
     if (!curr->next) assert(curr == b.last);
     int length = opcode_describe(curr->op)->length;
index b9d1d31d897c4401568aa7994aad5695033eb9e4..f5bd033eef8d96dc01e09959d3859c4ef65bb5ca 100644 (file)
--- a/execute.c
+++ b/execute.c
@@ -26,6 +26,7 @@ struct jq_state {
   jv path;
   int subexp_nest;
   int debug_trace_enabled;
+  int initial_execution;
 };
 
 typedef struct {
@@ -149,7 +150,8 @@ jv jq_next(jq_state *jq) {
   uint16_t* pc = stack_restore(jq);
   assert(pc);
 
-  int backtracking = 0;
+  int backtracking = !jq->initial_execution;
+  jq->initial_execution = 0;
   while (1) {
     uint16_t opcode = *pc;
 
@@ -465,13 +467,6 @@ jv jq_next(jq_state *jq) {
       pc += offset;
       break;
     }
-
-    case YIELD: {
-      jv value = stack_pop(jq);
-      stack_save(jq, pc);
-      stack_switch(jq);
-      return value;
-    }
       
     case CALL_BUILTIN: {
       int nargs = *pc++;
@@ -510,10 +505,25 @@ jv jq_next(jq_state *jq) {
     }
 
     case RET: {
-      pc = *frame_current_retaddr(&jq->frame_stk);
-      frame_pop(&jq->frame_stk);
+      uint16_t* retaddr = *frame_current_retaddr(&jq->frame_stk);
+      if (retaddr) {
+        // function return
+        pc = retaddr;
+        frame_pop(&jq->frame_stk);
+      } else {
+        // top-level return, yielding value
+        jv value = stack_pop(jq);
+        stack_save(jq, pc - 1);
+        stack_push(jq, jv_null());
+        stack_switch(jq);
+        return value;
+      }
       break;
     }
+    case ON_BACKTRACK(RET): {
+      // resumed after top-level return
+      goto do_backtrack;
+    }
     }
   }
 }
@@ -538,6 +548,7 @@ void jq_init(struct bytecode* bc, jv input, jq_state **jq, int flags) {
   } else {
     new_jq->debug_trace_enabled = 0;
   }
+  new_jq->initial_execution = 1;
   *jq = new_jq;
 }
 
index 38206871d8f9d4a213385a3a6ef23854cb509c33..14450c5187a6081620e0e8e823d25600449f94d9 100644 (file)
@@ -5,7 +5,6 @@ OP(POP,   NONE,     1, 0)
 OP(LOADV, VARIABLE, 1, 1)
 OP(STOREV, VARIABLE, 1, 0)
 OP(INDEX, NONE,     2, 1)
-OP(YIELD, NONE, 1, 0)
 OP(EACH,  NONE,     1, 1)
 OP(FORK,  BRANCH,   0, 0)
 OP(JUMP,  BRANCH,   0, 0)