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++) {
} 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);
}
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;
}
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);
#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)
OP_HAS_VARIABLE_LENGTH_ARGLIST = 256,
OP_HAS_BLOCK = 512,
OP_HAS_BINDING = 1024,
+ OP_HAS_DOUBLE_IMMEDIATE = 2048,
};
struct opcode_description {
opcode op;
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
[[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]