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:
parent
8810c65f00
commit
1878ece2af
|
@ -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 */
|
||||||
|
|
|
@ -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);
|
||||||
}
|
}
|
||||||
}
|
}
|
11
core/stl.c
11
core/stl.c
|
@ -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));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/****/
|
/****/
|
||||||
|
|
|
@ -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 */
|
||||||
|
|
Loading…
Reference in New Issue
Block a user