Move from Jansson to JV - interpreter loop
Passes tests, but leaks some memory.
This commit is contained in:
1 parent
2cb9a6e61d
commit
f72c5ffac0
7 files changed
+90
-103
No files matched your search
+2
-2
@@ -17,8 +17,8 @@ parser.tab.c: parser.y lexer.yy.h
|
|||||||
bison -W -d parser.y -v --report-file=parser.info
|
bison -W -d parser.y -v --report-file=parser.info
|
||||||
parser.tab.h: parser.tab.c
|
parser.tab.h: parser.tab.c
|
||||||
|
|
||||||
parsertest: parser.tab.c lexer.yy.c main.c opcode.c bytecode.c compile.c execute.c builtin.c
|
parsertest: parser.tab.c lexer.yy.c main.c opcode.c bytecode.c compile.c execute.c builtin.c jv.c jv_parse.c jv_print.c jv_dtoa.c
|
||||||
$(CC) -o $@ $^ -ljansson
|
$(CC) -o $@ $^
|
||||||
|
|
||||||
jvtest: jvtest.c jv.c jv_print.c
|
jvtest: jvtest.c jv.c jv_print.c
|
||||||
$(CC) -DNO_JANSSON -o $@ $^
|
$(CC) -DNO_JANSSON -o $@ $^
|
||||||
|
|||||||
+71
-75
@@ -1,10 +1,8 @@
|
|||||||
#include <jansson.h>
|
|
||||||
#include <assert.h>
|
#include <assert.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
|
|
||||||
|
|
||||||
#include "opcode.h"
|
#include "opcode.h"
|
||||||
#include "bytecode.h"
|
#include "bytecode.h"
|
||||||
#include "compile.h"
|
#include "compile.h"
|
||||||
@@ -16,16 +14,16 @@
|
|||||||
|
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
json_t* value;
|
jv value;
|
||||||
int pathidx;
|
int pathidx;
|
||||||
} stackval;
|
} stackval;
|
||||||
|
|
||||||
|
|
||||||
json_t** pathbuf;
|
jv* pathbuf;
|
||||||
int pathsize; // number of allocated elements
|
int pathsize; // number of allocated elements
|
||||||
|
|
||||||
|
// FIXME mem
|
||||||
int path_push(stackval sv, json_t* val) {
|
int path_push(stackval sv, jv val) {
|
||||||
int pos = sv.pathidx;
|
int pos = sv.pathidx;
|
||||||
assert(pos <= pathsize);
|
assert(pos <= pathsize);
|
||||||
assert(pos >= 0);
|
assert(pos >= 0);
|
||||||
@@ -37,14 +35,15 @@ int path_push(stackval sv, json_t* val) {
|
|||||||
return pos + 1;
|
return pos + 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
stackval stackval_replace(stackval value, json_t* newjs) {
|
stackval stackval_replace(stackval value, jv newjs) {
|
||||||
|
jv_free(value.value);
|
||||||
stackval s = {newjs, value.pathidx};
|
stackval s = {newjs, value.pathidx};
|
||||||
return s;
|
return s;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// Probably all uses of this function are bugs
|
// Probably all uses of this function are bugs
|
||||||
stackval stackval_root(json_t* v) {
|
stackval stackval_root(jv v) {
|
||||||
stackval s = {v, 0};
|
stackval s = {v, 0};
|
||||||
return s;
|
return s;
|
||||||
}
|
}
|
||||||
@@ -63,7 +62,9 @@ void stk_push(stackval val) {
|
|||||||
stackval stk_pop() {
|
stackval stk_pop() {
|
||||||
data_stk_elem* s = forkable_stack_peek(&data_stk);
|
data_stk_elem* s = forkable_stack_peek(&data_stk);
|
||||||
stackval sv = s->sv;
|
stackval sv = s->sv;
|
||||||
forkable_stack_pop(&data_stk);
|
if (!forkable_stack_pop(&data_stk)) {
|
||||||
|
sv.value = jv_copy(sv.value);
|
||||||
|
}
|
||||||
return sv;
|
return sv;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -118,9 +119,9 @@ static struct closure make_closure(struct forkable_stack* stk, frame_ptr fr, uin
|
|||||||
|
|
||||||
#define ON_BACKTRACK(op) ((op)+NUM_OPCODES)
|
#define ON_BACKTRACK(op) ((op)+NUM_OPCODES)
|
||||||
|
|
||||||
json_t* jq_next() {
|
jv jq_next() {
|
||||||
json_t* cfunc_input[MAX_CFUNCTION_ARGS] = {0};
|
jv cfunc_input[MAX_CFUNCTION_ARGS];
|
||||||
json_t* cfunc_output[MAX_CFUNCTION_ARGS] = {0};
|
jv cfunc_output[MAX_CFUNCTION_ARGS];
|
||||||
|
|
||||||
assert(!forkable_stack_empty(&frame_stk));
|
assert(!forkable_stack_empty(&frame_stk));
|
||||||
uint16_t* pc = *frame_current_retaddr(&frame_stk);
|
uint16_t* pc = *frame_current_retaddr(&frame_stk);
|
||||||
@@ -143,7 +144,7 @@ json_t* jq_next() {
|
|||||||
} else {
|
} else {
|
||||||
param = forkable_stack_peek_next(&data_stk, param);
|
param = forkable_stack_peek_next(&data_stk, param);
|
||||||
}
|
}
|
||||||
json_dumpf(param->sv.value, stdout, JSON_ENCODE_ANY);
|
jv_dump(jv_copy(param->sv.value));
|
||||||
if (i < opdesc->stack_in-1) printf(" | ");
|
if (i < opdesc->stack_in-1) printf(" | ");
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -159,16 +160,18 @@ json_t* jq_next() {
|
|||||||
default: assert(0 && "invalid instruction");
|
default: assert(0 && "invalid instruction");
|
||||||
|
|
||||||
case LOADK: {
|
case LOADK: {
|
||||||
json_t* v = json_array_get(frame_current_bytecode(&frame_stk)->constants, *pc++);
|
jv v = jv_array_get(jv_copy(frame_current_bytecode(&frame_stk)->constants), *pc++);
|
||||||
assert(v);
|
//FIXME assert(v);
|
||||||
stack_push(stackval_replace(stack_pop(), v));
|
stack_push(stackval_replace(stack_pop(), v));
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
case DUP: {
|
case DUP: {
|
||||||
stackval v = stack_pop();
|
stackval v = stack_pop();
|
||||||
|
stackval v2 = v;
|
||||||
|
v2.value = jv_copy(v.value);
|
||||||
stack_push(v);
|
stack_push(v);
|
||||||
stack_push(v);
|
stack_push(v2);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -181,44 +184,42 @@ json_t* jq_next() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
case POP: {
|
case POP: {
|
||||||
stack_pop();
|
jv_free(stack_pop().value);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
case APPEND: {
|
case APPEND: {
|
||||||
// FIXME paths
|
// FIXME paths
|
||||||
json_t* v = stack_pop().value;
|
jv v = stack_pop().value;
|
||||||
json_t* array = stack_pop().value;
|
jv array = stack_pop().value;
|
||||||
array = json_copy(array);
|
array = jv_array_append(array, v);
|
||||||
json_array_append(array, v);
|
|
||||||
stack_push(stackval_root(array));
|
stack_push(stackval_root(array));
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
case INSERT: {
|
case INSERT: {
|
||||||
stackval stktop = stack_pop();
|
stackval stktop = stack_pop();
|
||||||
json_t* v = stack_pop().value;
|
jv v = stack_pop().value;
|
||||||
json_t* k = stack_pop().value;
|
jv k = stack_pop().value;
|
||||||
stackval objv = stack_pop();
|
stackval objv = stack_pop();
|
||||||
assert(json_is_string(k));
|
assert(jv_get_kind(k) == JV_KIND_STRING);
|
||||||
assert(json_is_object(objv.value));
|
assert(jv_get_kind(objv.value) == JV_KIND_OBJECT);
|
||||||
json_t* obj = json_copy(objv.value);
|
objv.value = jv_object_set(objv.value, k, v);
|
||||||
json_object_set(obj, json_string_value(k), v);
|
stack_push(objv);
|
||||||
assert(json_is_object(obj));
|
|
||||||
stack_push(stackval_replace(objv, obj));
|
|
||||||
stack_push(stktop);
|
stack_push(stktop);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// FIXME: loadv/storev may do too much copying/freeing
|
||||||
case LOADV: {
|
case LOADV: {
|
||||||
uint16_t level = *pc++;
|
uint16_t level = *pc++;
|
||||||
uint16_t v = *pc++;
|
uint16_t v = *pc++;
|
||||||
frame_ptr fp = frame_get_level(&frame_stk, frame_current(&frame_stk), level);
|
frame_ptr fp = frame_get_level(&frame_stk, frame_current(&frame_stk), level);
|
||||||
json_t** var = frame_local_var(fp, v);
|
jv* var = frame_local_var(fp, v);
|
||||||
printf("V%d = ", v);
|
printf("V%d = ", v);
|
||||||
json_dumpf(*var, stdout, JSON_ENCODE_ANY);
|
jv_dump(jv_copy(*var));
|
||||||
printf("\n");
|
printf("\n");
|
||||||
stack_push(stackval_replace(stack_pop(), *var));
|
stack_push(stackval_replace(stack_pop(), jv_copy(*var)));
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -226,43 +227,31 @@ json_t* jq_next() {
|
|||||||
uint16_t level = *pc++;
|
uint16_t level = *pc++;
|
||||||
uint16_t v = *pc++;
|
uint16_t v = *pc++;
|
||||||
frame_ptr fp = frame_get_level(&frame_stk, frame_current(&frame_stk), level);
|
frame_ptr fp = frame_get_level(&frame_stk, frame_current(&frame_stk), level);
|
||||||
json_t** var = frame_local_var(fp, v);
|
jv* var = frame_local_var(fp, v);
|
||||||
stackval val = stack_pop();
|
stackval val = stack_pop();
|
||||||
printf("V%d = ", v);
|
printf("V%d = ", v);
|
||||||
json_dumpf(val.value, stdout, JSON_ENCODE_ANY);
|
jv_dump(jv_copy(val.value));
|
||||||
printf("\n");
|
printf("\n");
|
||||||
|
jv_free(*var);
|
||||||
*var = val.value;
|
*var = val.value;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
#if 0
|
|
||||||
case DISPLAY: {
|
|
||||||
stackval sv = stack_pop();
|
|
||||||
if (sv.value) {
|
|
||||||
json_dumpf(sv.value, stdout, JSON_ENCODE_ANY);
|
|
||||||
} else {
|
|
||||||
printf("#ERROR");
|
|
||||||
}
|
|
||||||
printf(" - ");
|
|
||||||
for (int i = 0; i < sv.pathidx; i++) {
|
|
||||||
printf("/");
|
|
||||||
json_dumpf(pathbuf[i], stdout, JSON_ENCODE_ANY);
|
|
||||||
}
|
|
||||||
printf("\n");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
case ASSIGN_DBG: {
|
case ASSIGN_DBG: {
|
||||||
|
assert(0);
|
||||||
|
/*
|
||||||
stackval replacement = stack_pop();
|
stackval replacement = stack_pop();
|
||||||
stackval path_end = stack_pop();
|
stackval path_end = stack_pop();
|
||||||
stackval path_start = stack_pop();
|
stackval path_start = stack_pop();
|
||||||
json_t* obj = jv_insert(path_start.value, replacement.value, pathbuf + path_start.pathidx, path_end.pathidx - path_start.pathidx);
|
json_t* obj = jv_insert(path_start.value, replacement.value, pathbuf + path_start.pathidx, path_end.pathidx - path_start.pathidx);
|
||||||
stack_push(stackval_replace(path_start, obj));
|
stack_push(stackval_replace(path_start, obj));
|
||||||
|
*/
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
case ASSIGN: {
|
case ASSIGN: {
|
||||||
|
assert(0);
|
||||||
|
/*
|
||||||
stackval replacement = stack_pop();
|
stackval replacement = stack_pop();
|
||||||
stackval path_end = stack_pop();
|
stackval path_end = stack_pop();
|
||||||
stackval path_start = stack_pop();
|
stackval path_start = stack_pop();
|
||||||
@@ -272,17 +261,18 @@ json_t* jq_next() {
|
|||||||
frame_ptr fp = frame_get_level(&frame_stk, frame_current(&frame_stk), level);
|
frame_ptr fp = frame_get_level(&frame_stk, frame_current(&frame_stk), level);
|
||||||
json_t** var = frame_local_var(fp, v);
|
json_t** var = frame_local_var(fp, v);
|
||||||
*var = jv_insert(*var, replacement.value, pathbuf + path_start.pathidx, path_end.pathidx - path_start.pathidx);
|
*var = jv_insert(*var, replacement.value, pathbuf + path_start.pathidx, path_end.pathidx - path_start.pathidx);
|
||||||
|
*/
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
case INDEX: {
|
case INDEX: {
|
||||||
stackval t = stack_pop();
|
stackval t = stack_pop();
|
||||||
json_t* k = stack_pop().value;
|
jv k = stack_pop().value;
|
||||||
json_t* v = jv_lookup(t.value, k);
|
jv v = jv_lookup(t.value, k);
|
||||||
if (v) {
|
if (1 /* fixme invalid lookups */) {
|
||||||
stackval sv;
|
stackval sv;
|
||||||
sv.value = v;
|
sv.value = v;
|
||||||
sv.pathidx = path_push(t, k);
|
sv.pathidx = 0; //FIXME path_push(t, k);
|
||||||
stack_push(sv);
|
stack_push(sv);
|
||||||
} else {
|
} else {
|
||||||
assert(0 && "bad lookup");
|
assert(0 && "bad lookup");
|
||||||
@@ -298,23 +288,24 @@ json_t* jq_next() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
case EACH:
|
case EACH:
|
||||||
stack_push(stackval_root(json_integer(0)));
|
stack_push(stackval_root(jv_number(0)));
|
||||||
// fallthrough
|
// fallthrough
|
||||||
case ON_BACKTRACK(EACH): {
|
case ON_BACKTRACK(EACH): {
|
||||||
json_t* idxj = stack_pop().value;
|
int idx = jv_number_value(stack_pop().value);
|
||||||
int idx = json_integer_value(idxj);
|
|
||||||
stackval array = stack_pop();
|
stackval array = stack_pop();
|
||||||
if (idx >= json_array_size(array.value)) {
|
if (idx >= jv_array_length(jv_copy(array.value))) {
|
||||||
goto do_backtrack;
|
goto do_backtrack;
|
||||||
} else {
|
} else {
|
||||||
stack_save();
|
stack_save();
|
||||||
stack_push(array);
|
stackval array2 = array;
|
||||||
stack_push(stackval_root(json_integer(idx+1)));
|
array2.value = jv_copy(array2.value);
|
||||||
|
stack_push(array2);
|
||||||
|
stack_push(stackval_root(jv_number(idx+1)));
|
||||||
frame_push_backtrack(&frame_stk, pc - 1);
|
frame_push_backtrack(&frame_stk, pc - 1);
|
||||||
stack_switch();
|
stack_switch();
|
||||||
|
|
||||||
stackval sv = {json_array_get(array.value, idx),
|
stackval sv = {jv_array_get(array.value, idx),
|
||||||
path_push(array, json_integer(idx))};
|
path_push(array, jv_number(idx))};
|
||||||
stack_push(sv);
|
stack_push(sv);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
@@ -323,7 +314,8 @@ json_t* jq_next() {
|
|||||||
do_backtrack:
|
do_backtrack:
|
||||||
case BACKTRACK: {
|
case BACKTRACK: {
|
||||||
if (forkable_stack_empty(&fork_stk)) {
|
if (forkable_stack_empty(&fork_stk)) {
|
||||||
return 0;
|
// FIXME: invalid
|
||||||
|
return jv_null();
|
||||||
}
|
}
|
||||||
stack_restore();
|
stack_restore();
|
||||||
pc = *frame_current_retaddr(&frame_stk);
|
pc = *frame_current_retaddr(&frame_stk);
|
||||||
@@ -347,7 +339,7 @@ json_t* jq_next() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
case YIELD: {
|
case YIELD: {
|
||||||
json_t* value = stack_pop().value;
|
jv value = stack_pop().value;
|
||||||
frame_push_backtrack(&frame_stk, pc);
|
frame_push_backtrack(&frame_stk, pc);
|
||||||
return value;
|
return value;
|
||||||
}
|
}
|
||||||
@@ -361,7 +353,8 @@ json_t* jq_next() {
|
|||||||
struct cfunction* func = &frame_current_bytecode(&frame_stk)->globals->cfunctions[*pc++];
|
struct cfunction* func = &frame_current_bytecode(&frame_stk)->globals->cfunctions[*pc++];
|
||||||
printf(" call %s\n", func->name);
|
printf(" call %s\n", func->name);
|
||||||
func->fptr(cfunc_input, cfunc_output);
|
func->fptr(cfunc_input, cfunc_output);
|
||||||
stack_push(stackval_replace(top, cfunc_output[0]));
|
top.value = cfunc_output[0];
|
||||||
|
stack_push(top);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -370,15 +363,16 @@ json_t* jq_next() {
|
|||||||
pc++; // skip nclosures
|
pc++; // skip nclosures
|
||||||
pc++; // skip level
|
pc++; // skip level
|
||||||
stackval top = stack_pop();
|
stackval top = stack_pop();
|
||||||
json_t* a = stack_pop().value;
|
jv a = stack_pop().value;
|
||||||
json_t* b = stack_pop().value;
|
jv b = stack_pop().value;
|
||||||
cfunc_input[0] = top.value;
|
cfunc_input[0] = top.value;
|
||||||
cfunc_input[1] = a;
|
cfunc_input[1] = a;
|
||||||
cfunc_input[2] = b;
|
cfunc_input[2] = b;
|
||||||
struct cfunction* func = &frame_current_bytecode(&frame_stk)->globals->cfunctions[*pc++];
|
struct cfunction* func = &frame_current_bytecode(&frame_stk)->globals->cfunctions[*pc++];
|
||||||
printf(" call %s\n", func->name);
|
printf(" call %s\n", func->name);
|
||||||
func->fptr(cfunc_input, cfunc_output);
|
func->fptr(cfunc_input, cfunc_output);
|
||||||
stack_push(stackval_replace(top, cfunc_output[0]));
|
top.value = cfunc_output[0];
|
||||||
|
stack_push(top);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -409,7 +403,7 @@ json_t* jq_next() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void jq_init(struct bytecode* bc, json_t* input) {
|
void jq_init(struct bytecode* bc, jv input) {
|
||||||
forkable_stack_init(&data_stk, sizeof(stackval) * 1000); // FIXME: lower this number, see if it breaks
|
forkable_stack_init(&data_stk, sizeof(stackval) * 1000); // FIXME: lower this number, see if it breaks
|
||||||
forkable_stack_init(&frame_stk, 10240); // FIXME: lower this number, see if it breaks
|
forkable_stack_init(&frame_stk, 10240); // FIXME: lower this number, see if it breaks
|
||||||
forkable_stack_init(&fork_stk, 10240); // FIXME: lower this number, see if it breaks
|
forkable_stack_init(&fork_stk, 10240); // FIXME: lower this number, see if it breaks
|
||||||
@@ -421,10 +415,12 @@ void jq_init(struct bytecode* bc, json_t* input) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void run_program(struct bytecode* bc) {
|
void run_program(struct bytecode* bc) {
|
||||||
jq_init(bc, json_loadf(stdin, 0, 0));
|
char buf[4096];
|
||||||
json_t* result;
|
fgets(buf, sizeof(buf), stdin);
|
||||||
while ((result = jq_next())) {
|
jq_init(bc, jv_parse(buf));
|
||||||
json_dumpf(result, stdout, JSON_ENCODE_ANY);
|
jv result;
|
||||||
|
while (jv_get_kind(result = jq_next()) != JV_KIND_NULL) {
|
||||||
|
jv_dump(result);
|
||||||
printf("\n");
|
printf("\n");
|
||||||
}
|
}
|
||||||
printf("end of results\n");
|
printf("end of results\n");
|
||||||
|
|||||||
-14
@@ -1,14 +0,0 @@
|
|||||||
#include "opcode.h"
|
|
||||||
#define MAX_CFUNCTION_PARAM 10
|
|
||||||
typedef struct {
|
|
||||||
json_t* value;
|
|
||||||
int pathidx;
|
|
||||||
} stackval;
|
|
||||||
|
|
||||||
typedef void (*cfunction_ptr)(stackval* input, stackval* output);
|
|
||||||
|
|
||||||
struct cfunction {
|
|
||||||
cfunction_ptr fptr;
|
|
||||||
const char* name;
|
|
||||||
opcode callop;
|
|
||||||
};
|
|
||||||
+5
-1
@@ -83,10 +83,14 @@ static void* forkable_stack_peek_next(struct forkable_stack* s, void* top) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void forkable_stack_pop(struct forkable_stack* s) {
|
// Returns 1 if the object being popped can not be accessed again
|
||||||
|
// (i.e. was not saved with a fork)
|
||||||
|
static int forkable_stack_pop(struct forkable_stack* s) {
|
||||||
forkable_stack_check(s);
|
forkable_stack_check(s);
|
||||||
|
int finalpop = s->pos < s->savedlimit ? 1 : 0;
|
||||||
struct forkable_stack_header* elem = forkable_stack_peek(s);
|
struct forkable_stack_header* elem = forkable_stack_peek(s);
|
||||||
s->pos = elem->next;
|
s->pos = elem->next;
|
||||||
|
return finalpop;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
+5
-3
@@ -1,7 +1,6 @@
|
|||||||
#ifndef FRAME_LAYOUT_H
|
#ifndef FRAME_LAYOUT_H
|
||||||
#include "forkable_stack.h"
|
#include "forkable_stack.h"
|
||||||
#include "bytecode.h"
|
#include "bytecode.h"
|
||||||
#include <jansson.h>
|
|
||||||
|
|
||||||
struct closure {
|
struct closure {
|
||||||
struct bytecode* bc;
|
struct bytecode* bc;
|
||||||
@@ -18,7 +17,7 @@ typedef union frame_elem {
|
|||||||
FORKABLE_STACK_HEADER;
|
FORKABLE_STACK_HEADER;
|
||||||
struct continuation cont;
|
struct continuation cont;
|
||||||
struct closure closure;
|
struct closure closure;
|
||||||
json_t* jsonval;
|
jv jsonval;
|
||||||
} *frame_ptr;
|
} *frame_ptr;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@@ -43,7 +42,7 @@ static struct closure* frame_closure_arg(frame_ptr fr, int closure) {
|
|||||||
return &fr[2+closure].closure;
|
return &fr[2+closure].closure;
|
||||||
}
|
}
|
||||||
|
|
||||||
static json_t** frame_local_var(frame_ptr fr, int var) {
|
static jv* frame_local_var(frame_ptr fr, int var) {
|
||||||
assert(var >= 0);
|
assert(var >= 0);
|
||||||
assert(var < frame_self(fr)->bc->nlocals);
|
assert(var < frame_self(fr)->bc->nlocals);
|
||||||
return &fr[2 + frame_self(fr)->bc->nclosures + var].jsonval;
|
return &fr[2 + frame_self(fr)->bc->nclosures + var].jsonval;
|
||||||
@@ -85,6 +84,9 @@ static frame_ptr frame_push(struct forkable_stack* stk, struct closure cl, uint1
|
|||||||
cc->bc = cl.bc;
|
cc->bc = cl.bc;
|
||||||
cc->env = cl.env;
|
cc->env = cl.env;
|
||||||
cc->retaddr = retaddr;
|
cc->retaddr = retaddr;
|
||||||
|
for (int i=0; i<cl.bc->nlocals; i++) {
|
||||||
|
*frame_local_var(fp, i) = jv_null();
|
||||||
|
}
|
||||||
return fp;
|
return fp;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -239,7 +239,7 @@ jv jv_array_concat(jv a, jv b) {
|
|||||||
assert(jv_get_kind(b) == JV_KIND_ARRAY);
|
assert(jv_get_kind(b) == JV_KIND_ARRAY);
|
||||||
|
|
||||||
// FIXME: could be much faster
|
// FIXME: could be much faster
|
||||||
for (int i=0; i<jv_array_length(b); i++) {
|
for (int i=0; i<jv_array_length(jv_copy(b)); i++) {
|
||||||
a = jv_array_append(a, jv_array_get(jv_copy(b), i));
|
a = jv_array_append(a, jv_array_get(jv_copy(b), i));
|
||||||
}
|
}
|
||||||
jv_free(b);
|
jv_free(b);
|
||||||
|
|||||||
@@ -6,10 +6,10 @@
|
|||||||
|
|
||||||
block compile(const char* str);
|
block compile(const char* str);
|
||||||
|
|
||||||
//void jq_init(struct bytecode* bc, jv value);
|
void jq_init(struct bytecode* bc, jv value);
|
||||||
//jv jq_next();
|
jv jq_next();
|
||||||
|
|
||||||
//void run_program(struct bytecode* bc);
|
void run_program(struct bytecode* bc);
|
||||||
|
|
||||||
int skipline(const char* buf) {
|
int skipline(const char* buf) {
|
||||||
int p = 0;
|
int p = 0;
|
||||||
@@ -39,13 +39,12 @@ void run_tests() {
|
|||||||
printf("\n");
|
printf("\n");
|
||||||
fgets(buf, sizeof(buf), testdata);
|
fgets(buf, sizeof(buf), testdata);
|
||||||
jv input = jv_parse(buf);
|
jv input = jv_parse(buf);
|
||||||
jv_free(input); //jq_init(bc, input);
|
jq_init(bc, input);
|
||||||
|
|
||||||
while (fgets(buf, sizeof(buf), testdata)) {
|
while (fgets(buf, sizeof(buf), testdata)) {
|
||||||
if (skipline(buf)) break;
|
if (skipline(buf)) break;
|
||||||
jv expected = jv_parse(buf);
|
jv expected = jv_parse(buf);
|
||||||
//jv actual = jq_next(); FIXME
|
jv actual = jq_next();
|
||||||
jv actual = jv_copy(expected);
|
|
||||||
if (!1) {
|
if (!1) {
|
||||||
printf("Insufficient results\n");
|
printf("Insufficient results\n");
|
||||||
pass = 0;
|
pass = 0;
|
||||||
@@ -84,5 +83,5 @@ int main(int argc, char* argv[]) {
|
|||||||
block_free(blk);
|
block_free(blk);
|
||||||
dump_disassembly(0, bc);
|
dump_disassembly(0, bc);
|
||||||
printf("\n");
|
printf("\n");
|
||||||
//run_program(bc);
|
run_program(bc);
|
||||||
}
|
}
|
||||||
Reference in new issue
Block a user