Simplify block functions for variables
This commit is contained in:
1 parent
2a18f97d12
commit
824ce76cec
4 files changed
+46
-56
No files matched your search
@@ -528,20 +528,18 @@ static block bind_bytecoded_builtins(block b) {
|
|||||||
};
|
};
|
||||||
for (unsigned i=0; i<sizeof(builtin_def_1arg)/sizeof(builtin_def_1arg[0]); i++) {
|
for (unsigned i=0; i<sizeof(builtin_def_1arg)/sizeof(builtin_def_1arg[0]); i++) {
|
||||||
builtins = BLOCK(builtins, gen_function(builtin_def_1arg[i].name,
|
builtins = BLOCK(builtins, gen_function(builtin_def_1arg[i].name,
|
||||||
gen_op_block_unbound(CLOSURE_PARAM, "arg"),
|
gen_param("arg"),
|
||||||
builtin_def_1arg[i].code));
|
builtin_def_1arg[i].code));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
{
|
{
|
||||||
block rangevar = block_bind(gen_op_var_unbound(STOREV, "rangevar"),
|
block rangevar = gen_op_var_fresh(STOREV, "rangevar");
|
||||||
gen_noop(), OP_HAS_VARIABLE);
|
|
||||||
block init = BLOCK(gen_op_simple(DUP), gen_call("start", gen_noop()), rangevar);
|
block init = BLOCK(gen_op_simple(DUP), gen_call("start", gen_noop()), rangevar);
|
||||||
block range = BLOCK(init,
|
block range = BLOCK(init,
|
||||||
gen_call("end", gen_noop()),
|
gen_call("end", gen_noop()),
|
||||||
gen_op_var_bound(RANGE, rangevar));
|
gen_op_bound(RANGE, rangevar));
|
||||||
builtins = BLOCK(builtins, gen_function("range",
|
builtins = BLOCK(builtins, gen_function("range",
|
||||||
BLOCK(gen_op_block_unbound(CLOSURE_PARAM, "start"),
|
BLOCK(gen_param("start"), gen_param("end")),
|
||||||
gen_op_block_unbound(CLOSURE_PARAM, "end")),
|
|
||||||
range));
|
range));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -153,33 +153,26 @@ void inst_set_target(block b, block target) {
|
|||||||
b.first->imm.target = target.last;
|
b.first->imm.target = target.last;
|
||||||
}
|
}
|
||||||
|
|
||||||
block gen_op_var_unbound(opcode op, const char* name) {
|
block gen_op_unbound(opcode op, const char* name) {
|
||||||
|
assert(opcode_describe(op)->flags & OP_HAS_BINDING);
|
||||||
|
inst* i = inst_new(op);
|
||||||
|
i->symbol = strdup(name);
|
||||||
|
return inst_block(i);
|
||||||
|
}
|
||||||
|
|
||||||
|
block gen_op_var_fresh(opcode op, const char* name) {
|
||||||
assert(opcode_describe(op)->flags & OP_HAS_VARIABLE);
|
assert(opcode_describe(op)->flags & OP_HAS_VARIABLE);
|
||||||
inst* i = inst_new(op);
|
return block_bind(gen_op_unbound(op, name),
|
||||||
i->symbol = strdup(name);
|
gen_noop(), OP_HAS_VARIABLE);
|
||||||
return inst_block(i);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
block gen_op_var_bound(opcode op, block binder) {
|
block gen_op_bound(opcode op, block binder) {
|
||||||
assert(block_is_single(binder));
|
assert(block_is_single(binder));
|
||||||
block b = gen_op_var_unbound(op, binder.first->symbol);
|
block b = gen_op_unbound(op, binder.first->symbol);
|
||||||
b.first->bound_by = binder.first;
|
b.first->bound_by = binder.first;
|
||||||
return b;
|
return b;
|
||||||
}
|
}
|
||||||
|
|
||||||
block gen_op_block_unbound(opcode op, const char* name) {
|
|
||||||
assert(opcode_describe(op)->flags & OP_IS_CALL_PSEUDO);
|
|
||||||
inst* i = inst_new(op);
|
|
||||||
i->symbol = strdup(name);
|
|
||||||
return inst_block(i);
|
|
||||||
}
|
|
||||||
|
|
||||||
block gen_op_block_bound(opcode op, block binder) {
|
|
||||||
assert(block_is_single(binder));
|
|
||||||
block b = gen_op_block_unbound(op, binder.first->symbol);
|
|
||||||
b.first->bound_by = binder.first;
|
|
||||||
return b;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void inst_join(inst* a, inst* b) {
|
static void inst_join(inst* a, inst* b) {
|
||||||
assert(a && b);
|
assert(a && b);
|
||||||
@@ -280,12 +273,16 @@ block gen_function(const char* name, block formals, block body) {
|
|||||||
return b;
|
return b;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
block gen_param(const char* name) {
|
||||||
|
return gen_op_unbound(CLOSURE_PARAM, name);
|
||||||
|
}
|
||||||
|
|
||||||
block gen_lambda(block body) {
|
block gen_lambda(block body) {
|
||||||
return gen_function("@lambda", gen_noop(), body);
|
return gen_function("@lambda", gen_noop(), body);
|
||||||
}
|
}
|
||||||
|
|
||||||
block gen_call(const char* name, block args) {
|
block gen_call(const char* name, block args) {
|
||||||
block b = gen_op_block_unbound(CALL_JQ, name);
|
block b = gen_op_unbound(CALL_JQ, name);
|
||||||
b.first->arglist = args;
|
b.first->arglist = args;
|
||||||
return b;
|
return b;
|
||||||
}
|
}
|
||||||
@@ -306,30 +303,27 @@ block gen_both(block a, block b) {
|
|||||||
|
|
||||||
|
|
||||||
block gen_collect(block expr) {
|
block gen_collect(block expr) {
|
||||||
block array_var = block_bind(gen_op_var_unbound(STOREV, "collect"),
|
block array_var = gen_op_var_fresh(STOREV, "collect");
|
||||||
gen_noop(), OP_HAS_VARIABLE);
|
|
||||||
block c = BLOCK(gen_op_simple(DUP), gen_const(jv_array()), array_var);
|
block c = BLOCK(gen_op_simple(DUP), gen_const(jv_array()), array_var);
|
||||||
|
|
||||||
block tail = BLOCK(gen_op_var_bound(APPEND, array_var),
|
block tail = BLOCK(gen_op_bound(APPEND, array_var),
|
||||||
gen_op_simple(BACKTRACK));
|
gen_op_simple(BACKTRACK));
|
||||||
|
|
||||||
return BLOCK(c,
|
return BLOCK(c,
|
||||||
gen_op_target(FORK, tail),
|
gen_op_target(FORK, tail),
|
||||||
expr,
|
expr,
|
||||||
tail,
|
tail,
|
||||||
gen_op_var_bound(LOADVN, array_var));
|
gen_op_bound(LOADVN, array_var));
|
||||||
}
|
}
|
||||||
|
|
||||||
block gen_reduce(const char* varname, block source, block init, block body) {
|
block gen_reduce(const char* varname, block source, block init, block body) {
|
||||||
block res_var = block_bind(gen_op_var_unbound(STOREV, "reduce"),
|
block res_var = gen_op_var_fresh(STOREV, "reduce");
|
||||||
gen_noop(), OP_HAS_VARIABLE);
|
|
||||||
|
|
||||||
block loop = BLOCK(gen_op_simple(DUP),
|
block loop = BLOCK(gen_op_simple(DUP),
|
||||||
source,
|
source,
|
||||||
block_bind(gen_op_var_unbound(STOREV, varname),
|
block_bind(gen_op_unbound(STOREV, varname),
|
||||||
BLOCK(gen_op_var_bound(LOADVN, res_var),
|
BLOCK(gen_op_bound(LOADVN, res_var),
|
||||||
body,
|
body,
|
||||||
gen_op_var_bound(STOREV, res_var)),
|
gen_op_bound(STOREV, res_var)),
|
||||||
OP_HAS_VARIABLE),
|
OP_HAS_VARIABLE),
|
||||||
gen_op_simple(BACKTRACK));
|
gen_op_simple(BACKTRACK));
|
||||||
return BLOCK(gen_op_simple(DUP),
|
return BLOCK(gen_op_simple(DUP),
|
||||||
@@ -337,19 +331,18 @@ block gen_reduce(const char* varname, block source, block init, block body) {
|
|||||||
res_var,
|
res_var,
|
||||||
gen_op_target(FORK, loop),
|
gen_op_target(FORK, loop),
|
||||||
loop,
|
loop,
|
||||||
gen_op_var_bound(LOADVN, res_var));
|
gen_op_bound(LOADVN, res_var));
|
||||||
}
|
}
|
||||||
|
|
||||||
block gen_definedor(block a, block b) {
|
block gen_definedor(block a, block b) {
|
||||||
// var found := false
|
// var found := false
|
||||||
block found_var = block_bind(gen_op_var_unbound(STOREV, "found"),
|
block found_var = gen_op_var_fresh(STOREV, "found");
|
||||||
gen_noop(), OP_HAS_VARIABLE);
|
|
||||||
block init = BLOCK(gen_op_simple(DUP), gen_const(jv_false()), found_var);
|
block init = BLOCK(gen_op_simple(DUP), gen_const(jv_false()), found_var);
|
||||||
|
|
||||||
// if found, backtrack. Otherwise execute b
|
// if found, backtrack. Otherwise execute b
|
||||||
block backtrack = gen_op_simple(BACKTRACK);
|
block backtrack = gen_op_simple(BACKTRACK);
|
||||||
block tail = BLOCK(gen_op_simple(DUP),
|
block tail = BLOCK(gen_op_simple(DUP),
|
||||||
gen_op_var_bound(LOADV, found_var),
|
gen_op_bound(LOADV, found_var),
|
||||||
gen_op_target(JUMP_F, backtrack),
|
gen_op_target(JUMP_F, backtrack),
|
||||||
backtrack,
|
backtrack,
|
||||||
gen_op_simple(POP),
|
gen_op_simple(POP),
|
||||||
@@ -361,7 +354,7 @@ block gen_definedor(block a, block b) {
|
|||||||
// found := true, produce result
|
// found := true, produce result
|
||||||
block if_found = BLOCK(gen_op_simple(DUP),
|
block if_found = BLOCK(gen_op_simple(DUP),
|
||||||
gen_const(jv_true()),
|
gen_const(jv_true()),
|
||||||
gen_op_var_bound(STOREV, found_var),
|
gen_op_bound(STOREV, found_var),
|
||||||
gen_op_target(JUMP, tail));
|
gen_op_target(JUMP, tail));
|
||||||
|
|
||||||
return BLOCK(init,
|
return BLOCK(init,
|
||||||
@@ -400,7 +393,7 @@ block gen_or(block a, block b) {
|
|||||||
|
|
||||||
block gen_var_binding(block var, const char* name, block body) {
|
block gen_var_binding(block var, const char* name, block body) {
|
||||||
return BLOCK(gen_op_simple(DUP), var,
|
return BLOCK(gen_op_simple(DUP), var,
|
||||||
block_bind(gen_op_var_unbound(STOREV, name),
|
block_bind(gen_op_unbound(STOREV, name),
|
||||||
body, OP_HAS_VARIABLE));
|
body, OP_HAS_VARIABLE));
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -475,7 +468,7 @@ static int expand_call_arglist(struct locfile* locations, block* b) {
|
|||||||
break;
|
break;
|
||||||
case CLOSURE_CREATE:
|
case CLOSURE_CREATE:
|
||||||
block_append(&prelude, b);
|
block_append(&prelude, b);
|
||||||
block_append(&callargs, gen_op_block_bound(CLOSURE_REF, b));
|
block_append(&callargs, gen_op_bound(CLOSURE_REF, b));
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
actual_args++;
|
actual_args++;
|
||||||
|
|||||||
@@ -24,11 +24,12 @@ block gen_noop();
|
|||||||
block gen_op_simple(opcode op);
|
block gen_op_simple(opcode op);
|
||||||
block gen_const(jv constant);
|
block gen_const(jv constant);
|
||||||
block gen_op_target(opcode op, block target);
|
block gen_op_target(opcode op, block target);
|
||||||
block gen_op_var_unbound(opcode op, const char* name);
|
block gen_op_unbound(opcode op, const char* name);
|
||||||
block gen_op_var_bound(opcode op, block binder);
|
block gen_op_bound(opcode op, block binder);
|
||||||
block gen_op_block_unbound(opcode op, const char* name);
|
block gen_op_var_fresh(opcode op, const char* name);
|
||||||
|
|
||||||
block gen_function(const char* name, block formals, block body);
|
block gen_function(const char* name, block formals, block body);
|
||||||
|
block gen_param(const char* name);
|
||||||
block gen_lambda(block body);
|
block gen_lambda(block body);
|
||||||
block gen_call(const char* name, block body);
|
block gen_call(const char* name, block body);
|
||||||
block gen_subexp(block a);
|
block gen_subexp(block a);
|
||||||
|
|||||||
@@ -170,24 +170,22 @@ static block gen_format(block a, jv fmt) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
static block gen_definedor_assign(block object, block val) {
|
static block gen_definedor_assign(block object, block val) {
|
||||||
block tmp = block_bind(gen_op_var_unbound(STOREV, "tmp"),
|
block tmp = gen_op_var_fresh(STOREV, "tmp");
|
||||||
gen_noop(), OP_HAS_VARIABLE);
|
|
||||||
return BLOCK(gen_op_simple(DUP),
|
return BLOCK(gen_op_simple(DUP),
|
||||||
val, tmp,
|
val, tmp,
|
||||||
gen_call("_modify", BLOCK(gen_lambda(object),
|
gen_call("_modify", BLOCK(gen_lambda(object),
|
||||||
gen_lambda(gen_definedor(gen_noop(),
|
gen_lambda(gen_definedor(gen_noop(),
|
||||||
gen_op_var_bound(LOADV, tmp))))));
|
gen_op_bound(LOADV, tmp))))));
|
||||||
}
|
}
|
||||||
|
|
||||||
static block gen_update(block object, block val, int optype) {
|
static block gen_update(block object, block val, int optype) {
|
||||||
block tmp = block_bind(gen_op_var_unbound(STOREV, "tmp"),
|
block tmp = gen_op_var_fresh(STOREV, "tmp");
|
||||||
gen_noop(), OP_HAS_VARIABLE);
|
|
||||||
return BLOCK(gen_op_simple(DUP),
|
return BLOCK(gen_op_simple(DUP),
|
||||||
val,
|
val,
|
||||||
tmp,
|
tmp,
|
||||||
gen_call("_modify", BLOCK(gen_lambda(object),
|
gen_call("_modify", BLOCK(gen_lambda(object),
|
||||||
gen_lambda(gen_binop(gen_noop(),
|
gen_lambda(gen_binop(gen_noop(),
|
||||||
gen_op_var_bound(LOADV, tmp),
|
gen_op_bound(LOADV, tmp),
|
||||||
optype)))));
|
optype)))));
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -337,7 +335,7 @@ FuncDef:
|
|||||||
|
|
||||||
"def" IDENT '(' IDENT ')' ':' Exp ';' {
|
"def" IDENT '(' IDENT ')' ':' Exp ';' {
|
||||||
$$ = gen_function(jv_string_value($2),
|
$$ = gen_function(jv_string_value($2),
|
||||||
gen_op_block_unbound(CLOSURE_PARAM, jv_string_value($4)),
|
gen_param(jv_string_value($4)),
|
||||||
$7);
|
$7);
|
||||||
jv_free($2);
|
jv_free($2);
|
||||||
jv_free($4);
|
jv_free($4);
|
||||||
@@ -345,8 +343,8 @@ FuncDef:
|
|||||||
|
|
||||||
"def" IDENT '(' IDENT ';' IDENT ')' ':' Exp ';' {
|
"def" IDENT '(' IDENT ';' IDENT ')' ':' Exp ';' {
|
||||||
$$ = gen_function(jv_string_value($2),
|
$$ = gen_function(jv_string_value($2),
|
||||||
BLOCK(gen_op_block_unbound(CLOSURE_PARAM, jv_string_value($4)),
|
BLOCK(gen_param(jv_string_value($4)),
|
||||||
gen_op_block_unbound(CLOSURE_PARAM, jv_string_value($6))),
|
gen_param(jv_string_value($6))),
|
||||||
$9);
|
$9);
|
||||||
jv_free($2);
|
jv_free($2);
|
||||||
jv_free($4);
|
jv_free($4);
|
||||||
@@ -459,7 +457,7 @@ FORMAT {
|
|||||||
$$ = BLOCK(gen_subexp(gen_const(jv_object())), $2, gen_op_simple(POP));
|
$$ = BLOCK(gen_subexp(gen_const(jv_object())), $2, gen_op_simple(POP));
|
||||||
} |
|
} |
|
||||||
'$' IDENT {
|
'$' IDENT {
|
||||||
$$ = gen_location(@$, gen_op_var_unbound(LOADV, jv_string_value($2)));
|
$$ = gen_location(@$, gen_op_unbound(LOADV, jv_string_value($2)));
|
||||||
jv_free($2);
|
jv_free($2);
|
||||||
} |
|
} |
|
||||||
IDENT {
|
IDENT {
|
||||||
|
|||||||
Reference in new issue
Block a user