mirror of
https://github.com/stedolan/jq.git
synced 2024-05-11 05:55:39 +00:00
General cleanup - rename a few things, delete dead code.
This commit is contained in:
10
builtin.c
10
builtin.c
@ -277,11 +277,11 @@ struct bytecoded_builtin { const char* name; block code; };
|
||||
static block bind_bytecoded_builtins(block b) {
|
||||
struct bytecoded_builtin builtin_defs[] = {
|
||||
{"empty", gen_op_simple(BACKTRACK)},
|
||||
{"false", gen_op_const(LOADK, jv_false())},
|
||||
{"true", gen_op_const(LOADK, jv_true())},
|
||||
{"null", gen_op_const(LOADK, jv_null())},
|
||||
{"not", gen_condbranch(gen_op_const(LOADK, jv_false()),
|
||||
gen_op_const(LOADK, jv_true()))}
|
||||
{"false", gen_const(jv_false())},
|
||||
{"true", gen_const(jv_true())},
|
||||
{"null", gen_const(jv_null())},
|
||||
{"not", gen_condbranch(gen_const(jv_false()),
|
||||
gen_const(jv_true()))}
|
||||
};
|
||||
block builtins = gen_noop();
|
||||
for (unsigned i=0; i<sizeof(builtin_defs)/sizeof(builtin_defs[0]); i++) {
|
||||
|
@ -6,7 +6,7 @@
|
||||
#include "opcode.h"
|
||||
|
||||
static int bytecode_operation_length(uint16_t* codeptr) {
|
||||
if (opcode_describe(*codeptr)->flags & OP_HAS_VARIABLE_LENGTH_ARGLIST) {
|
||||
if (*codeptr == CALL_JQ) {
|
||||
return 4 + codeptr[1] * 2;
|
||||
} else {
|
||||
return opcode_length(*codeptr);
|
||||
@ -41,7 +41,7 @@ void dump_operation(struct bytecode* bc, uint16_t* codeptr) {
|
||||
printf("%s", op->name);
|
||||
if (op->length > 1) {
|
||||
uint16_t imm = bc->code[pc++];
|
||||
if (op->flags & OP_HAS_VARIABLE_LENGTH_ARGLIST) {
|
||||
if (op->op == CALL_JQ) {
|
||||
for (int i=0; i<imm+1; i++) {
|
||||
uint16_t level = bc->code[pc++];
|
||||
uint16_t idx = bc->code[pc++];
|
||||
|
106
compile.c
106
compile.c
@ -109,9 +109,9 @@ block gen_op_simple(opcode op) {
|
||||
}
|
||||
|
||||
|
||||
block gen_op_const(opcode op, jv constant) {
|
||||
assert(opcode_describe(op)->flags & OP_HAS_CONSTANT);
|
||||
inst* i = inst_new(op);
|
||||
block gen_const(jv constant) {
|
||||
assert(opcode_describe(LOADK)->flags & OP_HAS_CONSTANT);
|
||||
inst* i = inst_new(LOADK);
|
||||
i->imm.constant = constant;
|
||||
return inst_block(i);
|
||||
}
|
||||
@ -151,13 +151,6 @@ block gen_op_var_bound(opcode op, block binder) {
|
||||
return b;
|
||||
}
|
||||
|
||||
block gen_op_symbol(opcode op, const char* sym) {
|
||||
assert(opcode_describe(op)->flags & OP_HAS_SYMBOL);
|
||||
inst* i = inst_new(op);
|
||||
i->symbol = strdup(sym);
|
||||
return inst_block(i);
|
||||
}
|
||||
|
||||
block gen_op_block_unbound(opcode op, const char* name) {
|
||||
assert(opcode_describe(op)->flags & OP_IS_CALL_PSEUDO);
|
||||
inst* i = inst_new(op);
|
||||
@ -180,32 +173,6 @@ static void inst_join(inst* a, inst* b) {
|
||||
b->prev = a;
|
||||
}
|
||||
|
||||
static void block_insert_after(inst* i, block b) {
|
||||
if (b.first) {
|
||||
assert(b.last);
|
||||
if (i->next) {
|
||||
inst* j = i->next;
|
||||
i->next = 0;
|
||||
j->prev = 0;
|
||||
inst_join(b.last, j);
|
||||
}
|
||||
inst_join(i, b.first);
|
||||
}
|
||||
}
|
||||
|
||||
static void block_insert_before(inst* i, block b) {
|
||||
if (b.first) {
|
||||
assert(b.last);
|
||||
if (i->prev) {
|
||||
inst* j = i->prev;
|
||||
i->prev = 0;
|
||||
j->next = 0;
|
||||
inst_join(j, b.first);
|
||||
}
|
||||
inst_join(b.last, i);
|
||||
}
|
||||
}
|
||||
|
||||
void block_append(block* b, block b2) {
|
||||
if (b2.first) {
|
||||
if (b->last) {
|
||||
@ -248,14 +215,10 @@ static void block_bind_subblock(block binder, block body, int bindflags) {
|
||||
// bind this instruction
|
||||
i->bound_by = binder.first;
|
||||
}
|
||||
if (flags & OP_HAS_BLOCK) {
|
||||
// binding recurses into closures
|
||||
block_bind_subblock(binder, i->subfn, bindflags);
|
||||
}
|
||||
if (flags & OP_HAS_VARIABLE_LENGTH_ARGLIST) {
|
||||
// binding recurses into argument list
|
||||
block_bind_subblock(binder, i->arglist, bindflags);
|
||||
}
|
||||
// binding recurses into closures
|
||||
block_bind_subblock(binder, i->subfn, bindflags);
|
||||
// binding recurses into argument list
|
||||
block_bind_subblock(binder, i->arglist, bindflags);
|
||||
}
|
||||
}
|
||||
|
||||
@ -306,7 +269,7 @@ block gen_both(block a, block b) {
|
||||
block gen_collect(block expr) {
|
||||
block array_var = block_bind(gen_op_var_unbound(STOREV, "collect"),
|
||||
gen_noop(), OP_HAS_VARIABLE);
|
||||
block c = BLOCK(gen_op_simple(DUP), gen_op_const(LOADK, jv_array()), array_var);
|
||||
block c = BLOCK(gen_op_simple(DUP), gen_const(jv_array()), array_var);
|
||||
|
||||
block tail = BLOCK(gen_op_simple(DUP),
|
||||
gen_op_var_bound(LOADV, array_var),
|
||||
@ -342,7 +305,7 @@ block gen_definedor(block a, block b) {
|
||||
// var found := false
|
||||
block found_var = block_bind(gen_op_var_unbound(STOREV, "found"),
|
||||
gen_noop(), OP_HAS_VARIABLE);
|
||||
block init = BLOCK(gen_op_simple(DUP), gen_op_const(LOADK, jv_false()), found_var);
|
||||
block init = BLOCK(gen_op_simple(DUP), gen_const(jv_false()), found_var);
|
||||
|
||||
// if found, backtrack. Otherwise execute b
|
||||
block backtrack = gen_op_simple(BACKTRACK);
|
||||
@ -358,7 +321,7 @@ block gen_definedor(block a, block b) {
|
||||
|
||||
// found := true, produce result
|
||||
block if_found = BLOCK(gen_op_simple(DUP),
|
||||
gen_op_const(LOADK, jv_true()),
|
||||
gen_const(jv_true()),
|
||||
gen_op_var_bound(STOREV, found_var),
|
||||
gen_op_target(JUMP, tail));
|
||||
|
||||
@ -381,19 +344,19 @@ block gen_and(block a, block b) {
|
||||
return BLOCK(gen_op_simple(DUP), a,
|
||||
gen_condbranch(BLOCK(gen_op_simple(POP),
|
||||
b,
|
||||
gen_condbranch(gen_op_const(LOADK, jv_true()),
|
||||
gen_op_const(LOADK, jv_false()))),
|
||||
BLOCK(gen_op_simple(POP), gen_op_const(LOADK, jv_false()))));
|
||||
gen_condbranch(gen_const(jv_true()),
|
||||
gen_const(jv_false()))),
|
||||
BLOCK(gen_op_simple(POP), gen_const(jv_false()))));
|
||||
}
|
||||
|
||||
block gen_or(block a, block b) {
|
||||
// a or b = if a then true else (if b then true else false)
|
||||
return BLOCK(gen_op_simple(DUP), a,
|
||||
gen_condbranch(BLOCK(gen_op_simple(POP), gen_op_const(LOADK, jv_true())),
|
||||
gen_condbranch(BLOCK(gen_op_simple(POP), gen_const(jv_true())),
|
||||
BLOCK(gen_op_simple(POP),
|
||||
b,
|
||||
gen_condbranch(gen_op_const(LOADK, jv_true()),
|
||||
gen_op_const(LOADK, jv_false())))));
|
||||
gen_condbranch(gen_const(jv_true()),
|
||||
gen_const(jv_false())))));
|
||||
}
|
||||
|
||||
block gen_cond(block cond, block iftrue, block iffalse) {
|
||||
@ -427,8 +390,7 @@ static int count_cfunctions(block b) {
|
||||
int n = 0;
|
||||
for (inst* i = b.first; i; i = i->next) {
|
||||
if (i->op == CLOSURE_CREATE_C) n++;
|
||||
if (opcode_describe(i->op)->flags & OP_HAS_BLOCK)
|
||||
n += count_cfunctions(i->subfn);
|
||||
n += count_cfunctions(i->subfn);
|
||||
}
|
||||
return n;
|
||||
}
|
||||
@ -439,8 +401,7 @@ static int count_cfunctions(block b) {
|
||||
static block expand_call_arglist(block b) {
|
||||
block ret = gen_noop();
|
||||
for (inst* curr; (curr = block_take(&b));) {
|
||||
if (opcode_describe(curr->op)->flags & OP_HAS_VARIABLE_LENGTH_ARGLIST) {
|
||||
assert(curr->op == CALL_JQ);
|
||||
if (curr->op == CALL_JQ) {
|
||||
inst* seq_end = block_take(&b);
|
||||
assert(seq_end && seq_end->op == CALLSEQ_END);
|
||||
// We expand the argument list as a series of instructions
|
||||
@ -541,11 +502,11 @@ static int compile(struct locfile* locations, struct bytecode* bc, block b) {
|
||||
curr->bound_by == curr) {
|
||||
curr->imm.intval = var_frame_idx++;
|
||||
}
|
||||
if (opflags & OP_HAS_BLOCK) {
|
||||
|
||||
if (curr->op == CLOSURE_CREATE) {
|
||||
assert(curr->bound_by == curr);
|
||||
curr->imm.intval = bc->nsubfunctions++;
|
||||
}
|
||||
|
||||
if (curr->op == CLOSURE_PARAM) {
|
||||
assert(curr->bound_by == curr);
|
||||
curr->imm.intval = bc->nclosures++;
|
||||
@ -560,14 +521,14 @@ static int compile(struct locfile* locations, struct bytecode* bc, block b) {
|
||||
if (bc->nsubfunctions) {
|
||||
bc->subfunctions = malloc(sizeof(struct bytecode*) * bc->nsubfunctions);
|
||||
for (inst* curr = b.first; curr; curr = curr->next) {
|
||||
if (!(opcode_describe(curr->op)->flags & OP_HAS_BLOCK))
|
||||
continue;
|
||||
struct bytecode* subfn = malloc(sizeof(struct bytecode));
|
||||
bc->subfunctions[curr->imm.intval] = subfn;
|
||||
subfn->globals = bc->globals;
|
||||
subfn->parent = bc;
|
||||
errors += compile(locations, subfn, curr->subfn);
|
||||
curr->subfn = gen_noop();
|
||||
if (curr->op == CLOSURE_CREATE) {
|
||||
struct bytecode* subfn = malloc(sizeof(struct bytecode));
|
||||
bc->subfunctions[curr->imm.intval] = subfn;
|
||||
subfn->globals = bc->globals;
|
||||
subfn->parent = bc;
|
||||
errors += compile(locations, subfn, curr->subfn);
|
||||
curr->subfn = gen_noop();
|
||||
}
|
||||
}
|
||||
} else {
|
||||
bc->subfunctions = 0;
|
||||
@ -583,7 +544,6 @@ static int compile(struct locfile* locations, struct bytecode* bc, block b) {
|
||||
if (op->length == 0)
|
||||
continue;
|
||||
code[pos++] = curr->op;
|
||||
int opflags = op->flags;
|
||||
assert(!(op->flags & OP_IS_CALL_PSEUDO));
|
||||
if (curr->op == CALL_BUILTIN) {
|
||||
int nargs = curr->imm.intval;
|
||||
@ -591,12 +551,10 @@ static int compile(struct locfile* locations, struct bytecode* bc, block b) {
|
||||
assert(block_is_single(curr->arglist));
|
||||
inst* cfunc = curr->arglist.first;
|
||||
assert(cfunc && cfunc->bound_by->op == CLOSURE_CREATE_C);
|
||||
//*opcode_rewrite = bc->globals->cfunctions[cfunc->bound_by->imm.intval].callop;
|
||||
code[pos++] = cfunc->bound_by->imm.intval;
|
||||
// FIXME arg errors
|
||||
assert(nargs == bc->globals->cfunctions[cfunc->bound_by->imm.intval].nargs);
|
||||
} else if (opflags & OP_HAS_VARIABLE_LENGTH_ARGLIST) {
|
||||
assert(curr->op == CALL_JQ);
|
||||
} else if (curr->op == CALL_JQ) {
|
||||
int nargs = curr->imm.intval;
|
||||
assert(nargs >= 0 && nargs < 100); //FIXME
|
||||
code[pos++] = (uint16_t)nargs;
|
||||
@ -623,15 +581,15 @@ static int compile(struct locfile* locations, struct bytecode* bc, block b) {
|
||||
assert(curr->bound_by->op == CLOSURE_CREATE);
|
||||
code[pos++] = curr->bound_by->imm.intval | ARG_NEWCLOSURE;
|
||||
}
|
||||
} else if (opflags & OP_HAS_CONSTANT) {
|
||||
} else if (op->flags & OP_HAS_CONSTANT) {
|
||||
code[pos++] = jv_array_length(jv_copy(constant_pool));
|
||||
constant_pool = jv_array_append(constant_pool, jv_copy(curr->imm.constant));
|
||||
} else if (opflags & OP_HAS_VARIABLE) {
|
||||
} else if (op->flags & OP_HAS_VARIABLE) {
|
||||
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;
|
||||
} else if (opflags & OP_HAS_BRANCH) {
|
||||
} else if (op->flags & OP_HAS_BRANCH) {
|
||||
assert(curr->imm.target->bytecode_pos != -1);
|
||||
assert(curr->imm.target->bytecode_pos > pos); // only forward branches
|
||||
code[pos] = curr->imm.target->bytecode_pos - (pos + 1);
|
||||
|
@ -21,12 +21,11 @@ block gen_location(location, block);
|
||||
|
||||
block gen_noop();
|
||||
block gen_op_simple(opcode op);
|
||||
block gen_op_const(opcode op, jv constant);
|
||||
block gen_const(jv constant);
|
||||
block gen_op_target(opcode op, block target);
|
||||
block gen_op_var_unbound(opcode op, const char* name);
|
||||
block gen_op_var_bound(opcode op, block binder);
|
||||
block gen_op_block_unbound(opcode op, const char* name);
|
||||
block gen_op_symbol(opcode op, const char* name);
|
||||
|
||||
block gen_function(const char* name, block body);
|
||||
block gen_lambda(block body);
|
||||
|
@ -15,7 +15,6 @@ struct forkable_stack_header {
|
||||
|
||||
struct forkable_stack {
|
||||
// Stack grows down from stk+length
|
||||
|
||||
char* stk;
|
||||
|
||||
// stk+length is just past end of allocated area
|
||||
@ -61,7 +60,6 @@ static void* forkable_stack_push(struct forkable_stack* s, size_t sz_size) {
|
||||
forkable_stack_check(s);
|
||||
int curr = s->pos < s->savedlimit ? s->pos : s->savedlimit;
|
||||
if (curr - size < 0) {
|
||||
//assert(0);
|
||||
int oldlen = s->length;
|
||||
s->length = (size + oldlen + 1024) * 2;
|
||||
s->stk = realloc(s->stk, s->length);
|
||||
|
8
opcode.c
8
opcode.c
@ -5,12 +5,10 @@
|
||||
#define CONSTANT OP_HAS_CONSTANT, 2
|
||||
#define VARIABLE (OP_HAS_VARIABLE | OP_HAS_BINDING), 3
|
||||
#define BRANCH OP_HAS_BRANCH, 2
|
||||
#define CFUNC (OP_HAS_SYMBOL | OP_HAS_CFUNC), 3
|
||||
#define UFUNC (OP_HAS_UFUNC | OP_HAS_VARIABLE_LENGTH_ARGLIST), 2
|
||||
#define CFUNC OP_HAS_CFUNC, 3
|
||||
#define UFUNC OP_HAS_UFUNC, 2
|
||||
#define CALLSEQ_END_IMM (OP_IS_CALL_PSEUDO), 0
|
||||
#define CLOSURE_PARAM_IMM (OP_IS_CALL_PSEUDO | OP_HAS_BINDING), 0
|
||||
#define CLOSURE_CREATE_IMM (OP_HAS_BLOCK | OP_IS_CALL_PSEUDO | OP_HAS_BINDING), 0
|
||||
#define CLOSURE_CREATE_C_IMM (OP_IS_CALL_PSEUDO | OP_HAS_BINDING), 0
|
||||
#define DEFINITION (OP_IS_CALL_PSEUDO | OP_HAS_BINDING), 0
|
||||
#define CLOSURE_REF_IMM (OP_IS_CALL_PSEUDO | OP_HAS_BINDING), 2
|
||||
|
||||
#define OP(name, imm, in, out) \
|
||||
|
3
opcode.h
3
opcode.h
@ -19,12 +19,9 @@ enum {
|
||||
OP_HAS_CONSTANT = 2,
|
||||
OP_HAS_VARIABLE = 4,
|
||||
OP_HAS_BRANCH = 8,
|
||||
OP_HAS_SYMBOL = 16,
|
||||
OP_HAS_CFUNC = 32,
|
||||
OP_HAS_UFUNC = 64,
|
||||
OP_IS_CALL_PSEUDO = 128,
|
||||
OP_HAS_VARIABLE_LENGTH_ARGLIST = 256,
|
||||
OP_HAS_BLOCK = 512,
|
||||
OP_HAS_BINDING = 1024,
|
||||
};
|
||||
struct opcode_description {
|
||||
|
@ -5,7 +5,6 @@ OP(POP, NONE, 1, 0)
|
||||
OP(LOADV, VARIABLE, 1, 1)
|
||||
OP(STOREV, VARIABLE, 1, 0)
|
||||
OP(INDEX, NONE, 2, 1)
|
||||
//OP(DISPLAY, NONE, 1, 0)
|
||||
OP(YIELD, NONE, 1, 0)
|
||||
OP(EACH, NONE, 1, 1)
|
||||
OP(FORK, BRANCH, 0, 0)
|
||||
@ -23,7 +22,7 @@ OP(CALL_JQ, UFUNC, 1, 1)
|
||||
OP(RET, NONE, 1, 1)
|
||||
|
||||
OP(CALLSEQ_END, CALLSEQ_END_IMM, 0, 0)
|
||||
OP(CLOSURE_PARAM, CLOSURE_PARAM_IMM, 0, 0)
|
||||
OP(CLOSURE_PARAM, DEFINITION, 0, 0)
|
||||
OP(CLOSURE_REF, CLOSURE_REF_IMM, 0, 0)
|
||||
OP(CLOSURE_CREATE, CLOSURE_CREATE_IMM, 0, 0)
|
||||
OP(CLOSURE_CREATE_C, CLOSURE_CREATE_C_IMM, 0, 0)
|
||||
OP(CLOSURE_CREATE, DEFINITION, 0, 0)
|
||||
OP(CLOSURE_CREATE_C, DEFINITION, 0, 0)
|
||||
|
31
parser.y
31
parser.y
@ -297,11 +297,6 @@ Term {
|
||||
$$ = $1;
|
||||
}
|
||||
|
||||
String:
|
||||
QQSTRING_START QQString QQSTRING_END {
|
||||
$$ = $2;
|
||||
}
|
||||
|
||||
FuncDef:
|
||||
"def" IDENT ':' Exp ';' {
|
||||
$$ = gen_function(jv_string_value($2), $4);
|
||||
@ -315,12 +310,18 @@ FuncDef:
|
||||
jv_free($4);
|
||||
}
|
||||
|
||||
|
||||
String:
|
||||
QQSTRING_START QQString QQSTRING_END {
|
||||
$$ = $2;
|
||||
}
|
||||
|
||||
QQString:
|
||||
/* empty */ {
|
||||
$$ = gen_op_const(LOADK, jv_string(""));
|
||||
$$ = gen_const(jv_string(""));
|
||||
} |
|
||||
QQString QQSTRING_TEXT {
|
||||
$$ = gen_binop($1, gen_op_const(LOADK, $2), '+');
|
||||
$$ = gen_binop($1, gen_const($2), '+');
|
||||
} |
|
||||
QQString QQSTRING_INTERP_START Exp QQSTRING_INTERP_END {
|
||||
$$ = gen_binop($1, gen_format($3), '+');
|
||||
@ -350,10 +351,10 @@ Term:
|
||||
$$ = gen_noop();
|
||||
} |
|
||||
Term '.' IDENT {
|
||||
$$ = gen_index($1, gen_op_const(LOADK, $3));
|
||||
$$ = gen_index($1, gen_const($3));
|
||||
} |
|
||||
'.' IDENT {
|
||||
$$ = gen_index(gen_noop(), gen_op_const(LOADK, $2));
|
||||
$$ = gen_index(gen_noop(), gen_const($2));
|
||||
} |
|
||||
/* FIXME: string literals */
|
||||
Term '[' Exp ']' {
|
||||
@ -363,7 +364,7 @@ Term '[' ']' {
|
||||
$$ = block_join($1, gen_op_simple(EACH));
|
||||
} |
|
||||
LITERAL {
|
||||
$$ = gen_op_const(LOADK, $1);
|
||||
$$ = gen_const($1);
|
||||
} |
|
||||
String {
|
||||
$$ = $1;
|
||||
@ -375,10 +376,10 @@ String {
|
||||
$$ = gen_collect($2);
|
||||
} |
|
||||
'[' ']' {
|
||||
$$ = gen_op_const(LOADK, jv_array());
|
||||
$$ = gen_const(jv_array());
|
||||
} |
|
||||
'{' MkDict '}' {
|
||||
$$ = BLOCK(gen_subexp(gen_op_const(LOADK, jv_object())), $2, gen_op_simple(POP));
|
||||
$$ = BLOCK(gen_subexp(gen_const(jv_object())), $2, gen_op_simple(POP));
|
||||
} |
|
||||
'$' IDENT {
|
||||
$$ = gen_location(@$, gen_op_var_unbound(LOADV, jv_string_value($2)));
|
||||
@ -408,14 +409,14 @@ MkDict:
|
||||
|
||||
MkDictPair
|
||||
: IDENT ':' ExpD {
|
||||
$$ = gen_dictpair(gen_op_const(LOADK, $1), $3);
|
||||
$$ = gen_dictpair(gen_const($1), $3);
|
||||
}
|
||||
| String ':' ExpD {
|
||||
$$ = gen_dictpair($1, $3);
|
||||
}
|
||||
| IDENT {
|
||||
$$ = gen_dictpair(gen_op_const(LOADK, jv_copy($1)),
|
||||
gen_index(gen_noop(), gen_op_const(LOADK, $1)));
|
||||
$$ = gen_dictpair(gen_const(jv_copy($1)),
|
||||
gen_index(gen_noop(), gen_const($1)));
|
||||
}
|
||||
| '(' Exp ')' ':' ExpD {
|
||||
$$ = gen_dictpair($2, $5);
|
||||
|
Reference in New Issue
Block a user