1
0
mirror of https://github.com/janet-lang/janet synced 2024-06-26 07:03:16 +00:00

Make compilation simpler.

This commit is contained in:
bakpakin 2017-07-09 15:35:17 -04:00
parent 8810c65f00
commit 1878ece2af
4 changed files with 42 additions and 59 deletions

View File

@ -83,14 +83,10 @@ static char *gst_getline() {
/* Compile and run an ast */ /* Compile and run an ast */
static int debug_compile_and_run(Gst *vm, GstValue ast, int64_t flags) { static int debug_compile_and_run(Gst *vm, GstValue ast, int64_t flags) {
GstCompiler c; GstValue func = gst_compile(vm, vm->env, ast);
GstValue func;
/* Try to compile generated AST */
gst_compiler(&c, vm);
func = gst_wrap_function(gst_compiler_compile(&c, ast));
/* Check for compilation errors */ /* Check for compilation errors */
if (c.error.type != GST_NIL) { if (func.type != GST_FUNCTION) {
printf_flags(flags, "31", "compiler error: %s\n", (const char *)gst_to_string(vm, c.error)); printf_flags(flags, "31", "compiler error: %s\n", (const char *)gst_to_string(vm, func));
return 1; return 1;
} }
/* Execute function */ /* Execute function */

View File

@ -24,9 +24,25 @@
#define GST_LOCAL_FLAG_MUTABLE 1 #define GST_LOCAL_FLAG_MUTABLE 1
/* Compiler typedefs */
typedef struct GstCompiler GstCompiler;
typedef struct FormOptions FormOptions;
typedef struct SlotTracker SlotTracker;
typedef struct GstScope GstScope;
/* Compilation state */
struct GstCompiler {
Gst *vm;
GstValue error;
jmp_buf onError;
GstScope *tail;
GstBuffer *buffer;
GstTable *env;
int recursionGuard;
};
/* During compilation, FormOptions are passed to ASTs /* During compilation, FormOptions are passed to ASTs
* as configuration options to allow for some optimizations. */ * as configuration options to allow for some optimizations. */
typedef struct FormOptions FormOptions;
struct FormOptions { struct FormOptions {
/* The location the returned Slot must be in. Can be ignored /* The location the returned Slot must be in. Can be ignored
* if either canDrop or canChoose is true */ * if either canDrop or canChoose is true */
@ -68,7 +84,6 @@ struct Slot {
/* A SlotTracker provides a handy way to keep track of /* A SlotTracker provides a handy way to keep track of
* Slots on the stack and free them in bulk. */ * Slots on the stack and free them in bulk. */
typedef struct SlotTracker SlotTracker;
struct SlotTracker { struct SlotTracker {
Slot *slots; Slot *slots;
uint32_t count; uint32_t count;
@ -1293,43 +1308,36 @@ static Slot compile_value(GstCompiler *c, FormOptions opts, GstValue x) {
return ret; return ret;
} }
/* Initialize a GstCompiler struct */
void gst_compiler(GstCompiler *c, Gst *vm) {
c->vm = vm;
c->buffer = gst_buffer(vm, 128);
c->tail = NULL;
c->error.type = GST_NIL;
c->env = vm->env;
c->recursionGuard = GST_RECURSION_GUARD;
compiler_push_scope(c, 0);
}
/* Compile interface. Returns a function that evaluates the /* Compile interface. Returns a function that evaluates the
* given AST. Returns NULL if there was an error during compilation. */ * given AST. Returns NULL if there was an error during compilation. */
GstFunction *gst_compiler_compile(GstCompiler *c, GstValue form) { GstValue gst_compile(Gst *vm, GstTable *env, GstValue form) {
GstCompiler c;
FormOptions opts = form_options_default(); FormOptions opts = form_options_default();
c->recursionGuard = GST_RECURSION_GUARD;
GstFuncDef *def; GstFuncDef *def;
if (setjmp(c->onError)) { if (setjmp(c.onError)) {
/* Clear all but root scope */ if (c.error.type == GST_NIL)
if (c->tail) return gst_string_cv(vm, "unknown error");
c->tail->parent = NULL; return c.error;
if (c->error.type == GST_NIL)
c->error = gst_string_cv(c->vm, "unknown error");
return NULL;
} }
c.error.type = GST_NIL;
c.env = env;
c.vm = vm;
c.tail = NULL;
c.buffer = gst_buffer(vm, 24);
c.recursionGuard = GST_RECURSION_GUARD;
compiler_push_scope(&c, 0);
opts.isTail = 1; opts.isTail = 1;
compiler_return(c, compile_value(c, opts, form)); compiler_return(&c, compile_value(&c, opts, form));
def = compiler_gen_funcdef(c, c->buffer->count, 0, 0); def = compiler_gen_funcdef(&c, c.buffer->count, 0, 0);
{ {
GstFuncEnv *env = gst_alloc(c->vm, sizeof(GstFuncEnv)); GstFuncEnv *env = gst_alloc(vm, sizeof(GstFuncEnv));
GstFunction *func = gst_alloc(c->vm, sizeof(GstFunction)); GstFunction *func = gst_alloc(vm, sizeof(GstFunction));
env->values = NULL; env->values = NULL;
env->stackOffset = 0; env->stackOffset = 0;
env->thread = NULL; env->thread = NULL;
func->parent = NULL; func->parent = NULL;
func->def = def; func->def = def;
func->env = env; func->env = env;
return func; return gst_wrap_function(func);
} }
} }

View File

@ -994,16 +994,11 @@ static int gst_stl_parse(Gst *vm) {
/* Compile a value */ /* Compile a value */
static int gst_stl_compile(Gst *vm) { static int gst_stl_compile(Gst *vm) {
GstFunction *ret; GstTable *env = vm->env;
GstCompiler c;
gst_compiler(&c, vm);
if (gst_arg(vm, 1).type == GST_TABLE) { if (gst_arg(vm, 1).type == GST_TABLE) {
c.env = gst_arg(vm, 1).data.table; env = gst_arg(vm, 1).data.table;
} }
ret = gst_compiler_compile(&c, gst_arg(vm, 0)); gst_c_return(vm, gst_compile(vm, env, gst_arg(vm, 0)));
if (!ret)
gst_c_throw(vm, c.error);
gst_c_return(vm, gst_wrap_function(ret));
} }
/****/ /****/

View File

@ -169,8 +169,6 @@ typedef struct GstModuleItem GstModuleItem;
typedef struct GstUserType GstUserType; typedef struct GstUserType GstUserType;
typedef struct GstParser GstParser; typedef struct GstParser GstParser;
typedef struct GstParseState GstParseState; typedef struct GstParseState GstParseState;
typedef struct GstCompiler GstCompiler;
typedef struct GstScope GstScope;
/* C Api data types */ /* C Api data types */
struct GstModuleItem { struct GstModuleItem {
@ -374,17 +372,6 @@ struct GstParser {
} comment; } comment;
}; };
/* Compilation state */
struct GstCompiler {
Gst *vm;
GstValue error;
jmp_buf onError;
GstScope *tail;
GstBuffer *buffer;
GstTable *env;
int recursionGuard;
};
/* Bytecode */ /* Bytecode */
enum GstOpCode { enum GstOpCode {
GST_OP_FLS, /* Load false */ GST_OP_FLS, /* Load false */
@ -548,10 +535,7 @@ GstValue gst_parse_consume(GstParser *p);
/* Compilation */ /* Compilation */
/***/ /***/
void gst_compiler(GstCompiler *c, Gst *vm); GstValue gst_compile(Gst *vm, GstTable *env, GstValue form);
void gst_compiler_mergeenv(GstCompiler *c, GstValue env);
void gst_compiler_global(GstCompiler *c, const char *name, GstValue x);
GstFunction *gst_compiler_compile(GstCompiler *c, GstValue form);
/****/ /****/
/* GC */ /* GC */