1
0
mirror of https://github.com/stedolan/jq.git synced 2024-05-11 05:55:39 +00:00

Closures over variables

This commit is contained in:
Stephen Dolan
2012-08-21 18:24:38 +01:00
parent c128c2029e
commit 79d81f4bee
6 changed files with 20 additions and 9 deletions

View 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);
}

View 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;

View 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);

View 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)

View 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

View 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]
[301.0, 601.0]