first pass at assignment
This commit is contained in:
1 parent
a847d2250f
commit
6c8b55793a
8 files changed
+117
-11
No files matched your search
+19
@@ -288,6 +288,25 @@ block gen_collect(block expr) {
|
|||||||
return c;
|
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) {
|
block gen_else(block a, block b) {
|
||||||
assert(0);
|
assert(0);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -25,6 +25,7 @@ block gen_op_symbol(opcode op, const char* name);
|
|||||||
block gen_subexp(block a);
|
block gen_subexp(block a);
|
||||||
block gen_both(block a, block b);
|
block gen_both(block a, block b);
|
||||||
block gen_collect(block expr);
|
block gen_collect(block expr);
|
||||||
|
block gen_assign(block expr);
|
||||||
block gen_else(block a, block b);
|
block gen_else(block a, block b);
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
+33
-11
@@ -12,6 +12,8 @@
|
|||||||
#include "forkable_stack.h"
|
#include "forkable_stack.h"
|
||||||
#include "frame_layout.h"
|
#include "frame_layout.h"
|
||||||
|
|
||||||
|
#include "jv.h"
|
||||||
|
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
json_t* value;
|
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);
|
return *frame_closure_arg(fr, idx);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
#define stack_push stk_push
|
#define stack_push stk_push
|
||||||
#define stack_pop stk_pop
|
#define stack_pop stk_pop
|
||||||
|
|
||||||
@@ -245,20 +249,37 @@ json_t* jq_next() {
|
|||||||
}
|
}
|
||||||
#endif
|
#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: {
|
case INDEX: {
|
||||||
stackval t = stack_pop();
|
stackval t = stack_pop();
|
||||||
json_t* k = stack_pop().value;
|
json_t* k = stack_pop().value;
|
||||||
stackval v;
|
json_t* v = jv_lookup(t.value, k);
|
||||||
if (json_is_string(k)) {
|
if (v) {
|
||||||
v.value = json_object_get(t.value, json_string_value(k));
|
stackval sv;
|
||||||
} else if (json_is_integer(k)) {
|
sv.value = v;
|
||||||
v.value = json_array_get(t.value, json_integer_value(k));
|
sv.pathidx = path_push(t, k);
|
||||||
} else {
|
stack_push(sv);
|
||||||
assert(0 && "key neither string nor int");
|
|
||||||
}
|
|
||||||
if (v.value) {
|
|
||||||
v.pathidx = path_push(t, k);
|
|
||||||
stack_push(v);
|
|
||||||
} else {
|
} else {
|
||||||
assert(0 && "bad lookup");
|
assert(0 && "bad lookup");
|
||||||
}
|
}
|
||||||
@@ -314,6 +335,7 @@ json_t* jq_next() {
|
|||||||
pc++; // skip offset this time
|
pc++; // skip offset this time
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
case ON_BACKTRACK(FORK): {
|
case ON_BACKTRACK(FORK): {
|
||||||
uint16_t offset = *pc++;
|
uint16_t offset = *pc++;
|
||||||
pc += offset;
|
pc += offset;
|
||||||
|
|||||||
@@ -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
|
||||||
@@ -12,6 +12,7 @@
|
|||||||
"==" { return EQ; }
|
"==" { return EQ; }
|
||||||
"as" { return AS; }
|
"as" { return AS; }
|
||||||
"def" { return DEF; }
|
"def" { return DEF; }
|
||||||
|
"|=" { return SETPIPE; }
|
||||||
"."|"="|";"|"["|"]"|","|":"|"("|")"|"{"|"}"|"|"|"+"|"\$" { return yytext[0];}
|
"."|"="|";"|"["|"]"|","|":"|"("|")"|"{"|"}"|"|"|"+"|"\$" { return yytext[0];}
|
||||||
|
|
||||||
[[:digit:]]+ { yylval->num = atoi(yytext); return NUMBER;}
|
[[:digit:]]+ { yylval->num = atoi(yytext); return NUMBER;}
|
||||||
|
|||||||
@@ -14,6 +14,9 @@ OP(BACKTRACK, NONE, 0, 0)
|
|||||||
OP(APPEND, NONE, 2, 1)
|
OP(APPEND, NONE, 2, 1)
|
||||||
OP(INSERT, NONE, 4, 2)
|
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_1_1, CFUNC, 1, 1)
|
||||||
OP(CALL_BUILTIN_3_1, CFUNC, 3, 1)
|
OP(CALL_BUILTIN_3_1, CFUNC, 3, 1)
|
||||||
|
|
||||||
|
|||||||
+18
@@ -28,6 +28,8 @@
|
|||||||
%token EQ "=="
|
%token EQ "=="
|
||||||
%token AS "as"
|
%token AS "as"
|
||||||
%token DEF "def"
|
%token DEF "def"
|
||||||
|
%token SETPIPE "|="
|
||||||
|
%nonassoc '=' SETPIPE
|
||||||
%nonassoc EQ
|
%nonassoc EQ
|
||||||
%left '+'
|
%left '+'
|
||||||
|
|
||||||
@@ -76,6 +78,22 @@ Term "as" '$' IDENT '|' Exp {
|
|||||||
block_append(&$$, block_bind(gen_op_var_unbound(STOREV, $4), $6, OP_HAS_VARIABLE));
|
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 {
|
Exp '|' Exp {
|
||||||
$$ = block_join($1, $3);
|
$$ = block_join($1, $3);
|
||||||
} |
|
} |
|
||||||
|
|||||||
@@ -153,3 +153,4 @@ def f(x): $$x | $$x; $$f([.], . + [42])
|
|||||||
[[1,2,3],42]
|
[[1,2,3],42]
|
||||||
[[1,2,3,42]]
|
[[1,2,3,42]]
|
||||||
[1,2,3,42,42]
|
[1,2,3,42,42]
|
||||||
|
|
||||||
Reference in new issue
Block a user