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:
@@ -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);
|
||||
}
|
||||
|
@@ -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;
|
||||
|
@@ -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);
|
||||
|
@@ -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)
|
||||
|
@@ -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
|
||||
|
@@ -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]
|
||||
|
Reference in New Issue
Block a user