]> granicus.if.org Git - jq/commitdiff
Closures over variables
authorStephen Dolan <mu@netsoc.tcd.ie>
Tue, 21 Aug 2012 17:24:38 +0000 (18:24 +0100)
committerStephen Dolan <mu@netsoc.tcd.ie>
Tue, 21 Aug 2012 17:24:38 +0000 (18:24 +0100)
c/bytecode.c
c/compile.c
c/execute.c
c/opcode.c
c/opcode.h
c/testdata

index 82e38f4c36f70f4e945185173198e81beaf66486..08d7fff3a8c3b325e38aaa743165c3c992b40da7 100644 (file)
@@ -35,7 +35,7 @@ void dump_operation(struct bytecode* bc, uint16_t* codeptr) {
   printf("%04d ", pc);
   const struct opcode_description* op = opcode_describe(bc->code[pc++]);
   printf("%s", op->name);
-  if (op->flags & OP_HAS_IMMEDIATE) {
+  if (op->flags & OP_HAS_IMMEDIATE || op->flags & OP_HAS_DOUBLE_IMMEDIATE) {
     uint16_t imm = bc->code[pc++];
     if (op->flags & OP_HAS_VARIABLE_LENGTH_ARGLIST) {
       for (int i=0; i<imm; i++) {
@@ -53,10 +53,15 @@ void dump_operation(struct bytecode* bc, uint16_t* codeptr) {
     } else if (op->flags & OP_HAS_BRANCH) {
       printf(" %04d", pc + imm);
     } else if (op->flags & OP_HAS_CONSTANT) {
+      printf(" ");
       json_dumpf(json_array_get(bc->constants, imm),
                  stdout, JSON_ENCODE_ANY);
     } else if (op->flags & OP_HAS_VARIABLE) {
-      printf(" v%d", imm);
+      uint16_t v = bc->code[pc++];
+      printf(" v%d", v);
+      if (imm) {
+        printf("^%d", imm);
+      }
     } else {
       printf(" %d", imm);
     }
index 89446330d3df457182133ca02dc07395d949fde6..cf5834b24eeec88661a4bbb42ca1306f73a4650f 100644 (file)
@@ -344,8 +344,7 @@ static void compile(struct bytecode* bc, block b) {
       code[pos++] = json_array_size(constant_pool);
       json_array_append(constant_pool, curr->imm.constant);
     } else if (opflags & OP_HAS_VARIABLE) {
-      // no closing over variables yet
-      assert(curr->bound_by->compiled == bc);
+      code[pos++] = nesting_level(bc, curr->bound_by);
       uint16_t var = (uint16_t)curr->bound_by->imm.intval;
       code[pos++] = var;
       if (var > maxvar) maxvar = var;
index 8bd8ec3cb8981f72d52fa1ee850f83dbd49d72bb..5245682bc1607ab98261f1e2a4d791dfb4f7dba6 100644 (file)
@@ -204,15 +204,19 @@ json_t* jq_next() {
     }
 
     case LOADV: {
+      uint16_t level = *pc++;
       uint16_t v = *pc++;
-      json_t** var = frame_local_var(frame_current(&frame_stk), v);
+      frame_ptr fp = frame_get_level(&frame_stk, frame_current(&frame_stk), level);
+      json_t** var = frame_local_var(fp, v);
       stack_push(stackval_replace(stack_pop(), *var));
       break;
     }
 
     case STOREV: {
+      uint16_t level = *pc++;
       uint16_t v = *pc++;
-      json_t** var = frame_local_var(frame_current(&frame_stk), v);
+      frame_ptr fp = frame_get_level(&frame_stk, frame_current(&frame_stk), level);
+      json_t** var = frame_local_var(fp, v);
       stackval val = stack_pop();
       printf("V%d = ", v);
       json_dumpf(val.value, stdout, JSON_ENCODE_ANY);
index ff41f86c0927655e48619f26abf022a32d091200..87179a51c4e93e73c9e35ae21b80c6ad3ee9fc93 100644 (file)
@@ -2,7 +2,7 @@
 
 #define NONE 0
 #define CONSTANT (OP_HAS_IMMEDIATE | OP_HAS_CONSTANT)
-#define VARIABLE (OP_HAS_IMMEDIATE | OP_HAS_VARIABLE | OP_HAS_BINDING)
+#define VARIABLE (OP_HAS_DOUBLE_IMMEDIATE | OP_HAS_VARIABLE | OP_HAS_BINDING)
 #define BRANCH (OP_HAS_IMMEDIATE | OP_HAS_BRANCH)
 #define CFUNC (OP_HAS_IMMEDIATE | OP_HAS_SYMBOL | OP_HAS_CFUNC)
 #define UFUNC (OP_HAS_IMMEDIATE | OP_HAS_UFUNC | OP_HAS_VARIABLE_LENGTH_ARGLIST)
index 262ecb3b859e30bada4c6f70db71824f15b5cff9..87d2434921bf2041c3ef9e04702b3ac07aba3b6f 100644 (file)
@@ -25,6 +25,7 @@ enum {
   OP_HAS_VARIABLE_LENGTH_ARGLIST = 256,
   OP_HAS_BLOCK = 512,
   OP_HAS_BINDING = 1024,
+  OP_HAS_DOUBLE_IMMEDIATE = 2048,
 };
 struct opcode_description {
   opcode op;
@@ -36,6 +37,8 @@ struct opcode_description {
 const struct opcode_description* opcode_describe(opcode op);
 
 static inline int opcode_length(opcode op) {
-  return 1 + (opcode_describe(op)->flags & OP_HAS_IMMEDIATE ? 1 : 0);
+  return 1 + 
+    (opcode_describe(op)->flags & OP_HAS_IMMEDIATE ? 1 : 0) +
+    (opcode_describe(op)->flags & OP_HAS_DOUBLE_IMMEDIATE ? 2 : 0);
 }
 #endif
index cc4d17bc528622182f8d468ff6701076b4ab86e4..cefc4b044aad40fecb9a698782b8195b2d40fdea 100644 (file)
@@ -140,4 +140,4 @@ def f: . + 1; def g: def g: . + 100; $$f | $$g | $$f; ($$f | $$g), $$g
 
 [[100,200][] as $x | def f: . + $x; $$f | $$f | $$f]
 1
-[300.0, 600.0]
\ No newline at end of file
+[301.0, 601.0]