diff options
-rw-r--r-- | Makefile.am | 6 | ||||
-rw-r--r-- | builtin.c | 18 | ||||
-rw-r--r-- | builtin.h | 14 | ||||
-rw-r--r-- | bytecode.c | 32 | ||||
-rw-r--r-- | bytecode.h | 46 | ||||
-rw-r--r-- | compile.c | 1 | ||||
-rw-r--r-- | compile.h | 6 | ||||
-rw-r--r-- | execute.c | 25 | ||||
-rw-r--r-- | jq_parser.h | 2 | ||||
-rw-r--r-- | opcode.c | 31 | ||||
-rw-r--r-- | opcode.h | 41 |
11 files changed, 103 insertions, 119 deletions
diff --git a/Makefile.am b/Makefile.am index f320c66e..228e78cf 100644 --- a/Makefile.am +++ b/Makefile.am @@ -1,11 +1,11 @@ ### C source files to be built and distributed. LIBJQ_INCS = jq_parser.h builtin.h bytecode.h compile.h exec_stack.h \ - jv_alloc.h jv_dtoa.h jv_parse.h jv_unicode.h locfile.h opcode.h \ + jv_alloc.h jv_dtoa.h jv_parse.h jv_unicode.h locfile.h \ opcode_list.h parser.y jv_utf8_tables.h lexer.l -LIBJQ_SRC = locfile.c opcode.c bytecode.c compile.c execute.c builtin.c \ - jv.c jv_parse.c jv_print.c jv_dtoa.c jv_unicode.c jv_aux.c jv_file.c \ +LIBJQ_SRC = locfile.c bytecode.c compile.c execute.c builtin.c jv.c \ + jv_parse.c jv_print.c jv_dtoa.c jv_unicode.c jv_aux.c jv_file.c \ jv_alloc.c jq_test.c ${LIBJQ_INCS} @@ -3,27 +3,11 @@ #include "builtin.h" #include "compile.h" #include "jq_parser.h" +#include "bytecode.h" #include "locfile.h" #include "jv_unicode.h" - -typedef jv (*func_1)(jv); -typedef jv (*func_2)(jv,jv); -typedef jv (*func_3)(jv,jv,jv); -typedef jv (*func_4)(jv,jv,jv,jv); -typedef jv (*func_5)(jv,jv,jv,jv,jv); -jv cfunction_invoke(struct cfunction* function, jv input[]) { - switch (function->nargs) { - case 1: return ((func_1)function->fptr)(input[0]); - case 2: return ((func_2)function->fptr)(input[0], input[1]); - case 3: return ((func_3)function->fptr)(input[0], input[1], input[2]); - case 4: return ((func_4)function->fptr)(input[0], input[1], input[2], input[3]); - case 5: return ((func_5)function->fptr)(input[0], input[1], input[2], input[3], input[4]); - default: return jv_invalid_with_msg(jv_string("Function takes too many arguments")); - } -} - static jv type_error(jv bad, const char* msg) { jv err = jv_invalid_with_msg(jv_string_fmt("%s %s", jv_kind_name(jv_get_kind(bad)), @@ -1,21 +1,9 @@ #ifndef BUILTIN_H #define BUILTIN_H +#include "bytecode.h" #include "compile.h" int builtins_bind(block*); - -typedef void (*cfunction_ptr)(void); - -struct cfunction { - cfunction_ptr fptr; - const char* name; - int nargs; -}; - - -jv cfunction_invoke(struct cfunction* function, jv input[]); - - #endif @@ -3,9 +3,39 @@ #include <stdlib.h> #include "bytecode.h" -#include "opcode.h" #include "jv_alloc.h" +// flags, length +#define NONE 0, 1 +#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_CFUNC | OP_HAS_BINDING), 3 +#define UFUNC (OP_HAS_UFUNC | OP_HAS_BINDING | OP_IS_CALL_PSEUDO), 4 +#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) \ + {name, #name, imm, in, out}, + +static const struct opcode_description opcode_descriptions[] = { +#include "opcode_list.h" +}; + +static const struct opcode_description invalid_opcode_description = { + -1, "#INVALID", 0, 0, 0, 0 +}; + + +const struct opcode_description* opcode_describe(opcode op) { + if ((int)op >= 0 && (int)op < NUM_OPCODES) { + return &opcode_descriptions[op]; + } else { + return &invalid_opcode_description; + } +} + + static int bytecode_operation_length(uint16_t* codeptr) { int length = opcode_describe(*codeptr)->length; if (*codeptr == CALL_JQ) { @@ -3,10 +3,52 @@ #include <stdint.h> #include "jv.h" -#include "opcode.h" -#include "builtin.h" + +typedef enum { +#define OP(name, imm, in, out) name, +#include "opcode_list.h" +#undef OP +} opcode; + +enum { + NUM_OPCODES = +#define OP(name, imm, in, out) +1 +#include "opcode_list.h" +#undef OP +}; + +enum { + OP_HAS_CONSTANT = 2, + OP_HAS_VARIABLE = 4, + OP_HAS_BRANCH = 8, + OP_HAS_CFUNC = 32, + OP_HAS_UFUNC = 64, + OP_IS_CALL_PSEUDO = 128, + OP_HAS_BINDING = 1024, +}; +struct opcode_description { + opcode op; + const char* name; + + int flags; + + // length in 16-bit units + int length; + + int stack_in, stack_out; +}; + +const struct opcode_description* opcode_describe(opcode op); + #define MAX_CFUNCTION_ARGS 10 +typedef void (*cfunction_ptr)(); +struct cfunction { + cfunction_ptr fptr; + const char* name; + int nargs; +}; + struct symbol_table { struct cfunction* cfunctions; int ncfunctions; @@ -2,7 +2,6 @@ #include <assert.h> #include <string.h> #include <stdlib.h> -#include "opcode.h" #include "compile.h" #include "bytecode.h" #include "locfile.h" @@ -2,13 +2,9 @@ #define COMPILE_H #include <stdint.h> #include "jv.h" -#include "opcode.h" +#include "bytecode.h" #include "locfile.h" -struct bytecode; -struct symbol_table; -struct cfunction; - struct inst; typedef struct inst inst; @@ -4,7 +4,6 @@ #include <stdint.h> #include "exec_stack.h" -#include "opcode.h" #include "bytecode.h" #include "jv_alloc.h" @@ -240,6 +239,8 @@ static void jq_reset(jq_state *jq) { } + + void print_error(jv value) { assert(!jv_is_valid(value)); jv msg = jv_invalid_get_msg(value); @@ -600,12 +601,26 @@ jv jq_next(jq_state *jq) { case CALL_BUILTIN: { int nargs = *pc++; jv top = stack_pop(jq); - cfunc_input[0] = top; + jv* in = cfunc_input; + in[0] = top; for (int i = 1; i < nargs; i++) { - cfunc_input[i] = stack_pop(jq); + in[i] = stack_pop(jq); } - struct cfunction* func = &frame_current(jq)->bc->globals->cfunctions[*pc++]; - top = cfunction_invoke(func, cfunc_input); + struct cfunction* function = &frame_current(jq)->bc->globals->cfunctions[*pc++]; + typedef jv (*func_1)(jv); + typedef jv (*func_2)(jv,jv); + typedef jv (*func_3)(jv,jv,jv); + typedef jv (*func_4)(jv,jv,jv,jv); + typedef jv (*func_5)(jv,jv,jv,jv,jv); + switch (function->nargs) { + case 1: top = ((func_1)function->fptr)(in[0]); break; + case 2: top = ((func_2)function->fptr)(in[0], in[1]); break; + case 3: top = ((func_3)function->fptr)(in[0], in[1], in[2]); break; + case 4: top = ((func_4)function->fptr)(in[0], in[1], in[2], in[3]); break; + case 5: top = ((func_5)function->fptr)(in[0], in[1], in[2], in[3], in[4]); break; + default: return jv_invalid_with_msg(jv_string("Function takes too many arguments")); + } + if (jv_is_valid(top)) { stack_push(jq, top); } else { diff --git a/jq_parser.h b/jq_parser.h index 8dc37163..809ace06 100644 --- a/jq_parser.h +++ b/jq_parser.h @@ -1,5 +1,7 @@ #ifndef JQ_PARSER_H #define JQ_PARSER_H +#include "locfile.h" +#include "compile.h" int jq_parse(struct locfile* source, block* answer); int jq_parse_library(struct locfile* locations, block* answer); diff --git a/opcode.c b/opcode.c deleted file mode 100644 index 4e785b8f..00000000 --- a/opcode.c +++ /dev/null @@ -1,31 +0,0 @@ -#include "opcode.h" - -// flags, length -#define NONE 0, 1 -#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_CFUNC | OP_HAS_BINDING), 3 -#define UFUNC (OP_HAS_UFUNC | OP_HAS_BINDING | OP_IS_CALL_PSEUDO), 4 -#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) \ - {name, #name, imm, in, out}, - -static const struct opcode_description opcode_descriptions[] = { -#include "opcode_list.h" -}; - -static const struct opcode_description invalid_opcode_description = { - -1, "#INVALID", 0, 0, 0, 0 -}; - - -const struct opcode_description* opcode_describe(opcode op) { - if ((int)op >= 0 && (int)op < NUM_OPCODES) { - return &opcode_descriptions[op]; - } else { - return &invalid_opcode_description; - } -} diff --git a/opcode.h b/opcode.h deleted file mode 100644 index ee956e27..00000000 --- a/opcode.h +++ /dev/null @@ -1,41 +0,0 @@ -#ifndef OPCODE_H -#define OPCODE_H -#include <assert.h> - -typedef enum { -#define OP(name, imm, in, out) name, -#include "opcode_list.h" -#undef OP -} opcode; - -enum { - NUM_OPCODES = -#define OP(name, imm, in, out) +1 -#include "opcode_list.h" -#undef OP -}; - -enum { - OP_HAS_CONSTANT = 2, - OP_HAS_VARIABLE = 4, - OP_HAS_BRANCH = 8, - OP_HAS_CFUNC = 32, - OP_HAS_UFUNC = 64, - OP_IS_CALL_PSEUDO = 128, - OP_HAS_BINDING = 1024, -}; -struct opcode_description { - opcode op; - const char* name; - - int flags; - - // length in 16-bit units - int length; - - int stack_in, stack_out; -}; - -const struct opcode_description* opcode_describe(opcode op); - -#endif |