first pass at assignment

This commit is contained in:
Stephen Dolan committed 2012-08-27 10:12:02 +01:00
1 parent a847d2250f
commit 6c8b55793a
8 files changed
+117 -11

No files matched your search

+19
View File
@@ -288,6 +288,25 @@ block gen_collect(block expr) {
return c;
}
block gen_assign(block expr) {
block c = gen_noop();
block_append(&c, gen_op_simple(DUP));
block result_var = block_bind(gen_op_var_unbound(STOREV, "result"),
gen_noop(), OP_HAS_VARIABLE);
block_append(&c, result_var);
block loop = gen_noop();
block_append(&loop, gen_op_simple(DUP));
block_append(&loop, expr);
block_append(&loop, gen_op_var_bound(ASSIGN, result_var));
block_append(&loop, gen_op_simple(BACKTRACK));
block_append(&c, gen_op_target(FORK, loop));
block_append(&c, loop);
block_append(&c, gen_op_var_bound(LOADV, result_var));
return c;
}
block gen_else(block a, block b) {
assert(0);
}
+1
View File
@@ -25,6 +25,7 @@ block gen_op_symbol(opcode op, const char* name);
block gen_subexp(block a);
block gen_both(block a, block b);
block gen_collect(block expr);
block gen_assign(block expr);
block gen_else(block a, block b);
+33 -11
View File
@@ -12,6 +12,8 @@
#include "forkable_stack.h"
#include "frame_layout.h"
#include "jv.h"
typedef struct {
json_t* value;
@@ -108,6 +110,8 @@ static struct closure make_closure(struct forkable_stack* stk, frame_ptr fr, uin
return *frame_closure_arg(fr, idx);
}
}
#define stack_push stk_push
#define stack_pop stk_pop
@@ -245,20 +249,37 @@ json_t* jq_next() {
}
#endif
case ASSIGN_DBG: {
stackval replacement = stack_pop();
stackval path_end = 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);
stack_push(stackval_replace(path_start, obj));
break;
}
case ASSIGN: {
stackval replacement = stack_pop();
stackval path_end = stack_pop();
stackval path_start = stack_pop();
uint16_t level = *pc++;
uint16_t v = *pc++;
frame_ptr fp = frame_get_level(&frame_stk, frame_current(&frame_stk), level);
json_t** var = frame_local_var(fp, v);
*var = jv_insert(*var, replacement.value, pathbuf + path_start.pathidx, path_end.pathidx - path_start.pathidx);
break;
}
case INDEX: {
stackval t = stack_pop();
json_t* k = stack_pop().value;
stackval v;
if (json_is_string(k)) {
v.value = json_object_get(t.value, json_string_value(k));
} else if (json_is_integer(k)) {
v.value = json_array_get(t.value, json_integer_value(k));
} else {
assert(0 && "key neither string nor int");
}
if (v.value) {
v.pathidx = path_push(t, k);
stack_push(v);
json_t* v = jv_lookup(t.value, k);
if (v) {
stackval sv;
sv.value = v;
sv.pathidx = path_push(t, k);
stack_push(sv);
} else {
assert(0 && "bad lookup");
}
@@ -314,6 +335,7 @@ json_t* jq_next() {
pc++; // skip offset this time
break;
}
case ON_BACKTRACK(FORK): {
uint16_t offset = *pc++;
pc += offset;
+41
View File
@@ -0,0 +1,41 @@
#ifndef JV_H
#define JV_H
#include <jansson.h>
static json_t* jv_lookup(json_t* t, json_t* k) {
json_t* v;
if (json_is_object(t) && json_is_string(k)) {
v = json_object_get(t, json_string_value(k));
} else if (json_is_array(t) && json_is_number(k)) {
v = json_array_get(t, json_integer_value(k));
} else {
assert(0&&"bad lookup");
}
if (v)
return v;
else
return json_null();
}
static json_t* jv_modify(json_t* t, json_t* k, json_t* v) {
t = json_copy(t);
if (json_is_object(t) && json_is_string(k)) {
json_object_set(t, json_string_value(k), v);
} else if (json_is_array(t) && json_is_number(k)) {
json_array_set(t, json_integer_value(k), v);
} else {
assert(0 && "bad mod");
}
return t;
}
static json_t* jv_insert(json_t* root, json_t* value, json_t** path, int pathlen) {
if (pathlen == 0) {
return value;
}
return jv_modify(root, *path, jv_insert(jv_lookup(root, *path), value, path+1, pathlen-1));
}
#endif
+1
View File
@@ -12,6 +12,7 @@
"==" { return EQ; }
"as" { return AS; }
"def" { return DEF; }
"|=" { return SETPIPE; }
"."|"="|";"|"["|"]"|","|":"|"("|")"|"{"|"}"|"|"|"+"|"\$" { return yytext[0];}
[[:digit:]]+ { yylval->num = atoi(yytext); return NUMBER;}
+3
View File
@@ -14,6 +14,9 @@ OP(BACKTRACK, NONE, 0, 0)
OP(APPEND, NONE, 2, 1)
OP(INSERT, NONE, 4, 2)
OP(ASSIGN_DBG, NONE, 3, 1)
OP(ASSIGN, VARIABLE, 3, 0)
OP(CALL_BUILTIN_1_1, CFUNC, 1, 1)
OP(CALL_BUILTIN_3_1, CFUNC, 3, 1)
+18
View File
@@ -28,6 +28,8 @@
%token EQ "=="
%token AS "as"
%token DEF "def"
%token SETPIPE "|="
%nonassoc '=' SETPIPE
%nonassoc EQ
%left '+'
@@ -76,6 +78,22 @@ Term "as" '$' IDENT '|' Exp {
block_append(&$$, block_bind(gen_op_var_unbound(STOREV, $4), $6, OP_HAS_VARIABLE));
} |
Exp '=' Exp {
block assign = gen_op_simple(DUP);
block_append(&assign, $3);
block_append(&assign, gen_op_simple(SWAP));
block_append(&assign, $1);
block_append(&assign, gen_op_simple(SWAP));
$$ = gen_assign(assign);
} |
Exp "|=" Exp {
block assign = $1;
block_append(&assign, gen_op_simple(DUP));
block_append(&assign, $3);
$$ = gen_assign(assign);
} |
Exp '|' Exp {
$$ = block_join($1, $3);
} |
+1
View File
@@ -153,3 +153,4 @@ def f(x): $$x | $$x; $$f([.], . + [42])
[[1,2,3],42]
[[1,2,3,42]]
[1,2,3,42,42]