1
0
mirror of https://github.com/janet-lang/janet synced 2024-12-26 00:10:27 +00:00

Begin implementing module system.

This commit is contained in:
Calvin Rose 2017-04-12 21:21:46 -04:00
parent ded3d06387
commit e28e31f818
10 changed files with 90 additions and 62 deletions

View File

@ -16,7 +16,7 @@ all: $(GST_TARGET)
################################### ###################################
GST_CORE_SOURCES=$(addprefix core/,\ GST_CORE_SOURCES=$(addprefix core/,\
compile.c disasm.c parse.c stl.c strings.c \ compile.c disasm.c parse.c stl.c strings.c \
value.c vm.c ds.c gc.c thread.c serialize.c) value.c vm.c ds.c gc.c thread.c serialize.c capi.c)
GST_CORE_OBJECTS=$(patsubst %.c,%.o,$(GST_CORE_SOURCES)) GST_CORE_OBJECTS=$(patsubst %.c,%.o,$(GST_CORE_SOURCES))
$(GST_CORELIB): $(GST_CORE_OBJECTS) $(GST_HEADERS) $(GST_CORELIB): $(GST_CORE_OBJECTS) $(GST_HEADERS)
ar rcs $(GST_CORELIB) $(GST_CORE_OBJECTS) ar rcs $(GST_CORELIB) $(GST_CORE_OBJECTS)

View File

@ -16,10 +16,7 @@ void debug_repl(FILE *in, FILE *out) {
GstCompiler c; GstCompiler c;
gst_init(&vm); gst_init(&vm);
gst_stl_load(&vm);
vm.rootenv.type = GST_OBJECT;
vm.rootenv.data.object = gst_object(&vm, 10);
gst_object_put(&vm, vm.rootenv.data.object, gst_load_csymbol(&vm, "_ENV"), vm.rootenv);
for (;;) { for (;;) {
@ -61,9 +58,8 @@ void debug_repl(FILE *in, FILE *out) {
/* Try to compile generated AST */ /* Try to compile generated AST */
gst_compiler(&c, &vm); gst_compiler(&c, &vm);
func.type = GST_NIL; func.type = GST_NIL;
gst_compiler_add_global(&c, "ans", func); gst_compiler_usemodule(&c, "std");
gst_stl_load(&c); gst_compiler_global(&c, "ans", gst_object_get(vm.rootenv, gst_load_csymbol(&vm, "ans")));
gst_compiler_env(&c, vm.rootenv);
func.type = GST_FUNCTION; func.type = GST_FUNCTION;
func.data.function = gst_compiler_compile(&c, p.value); func.data.function = gst_compiler_compile(&c, p.value);
@ -98,7 +94,7 @@ void debug_repl(FILE *in, FILE *out) {
continue; continue;
} else if (out) { } else if (out) {
fprintf(out, "%s\n", (char *)gst_to_string(&vm, vm.ret)); fprintf(out, "%s\n", (char *)gst_to_string(&vm, vm.ret));
gst_object_put(&vm, vm.rootenv.data.object, gst_load_csymbol(&vm, "ans"), vm.ret); gst_object_put(&vm, vm.rootenv, gst_load_csymbol(&vm, "ans"), vm.ret);
} }
} }

23
core/capi.c Normal file
View File

@ -0,0 +1,23 @@
#include <gst/gst.h>
GstObject *gst_c_module(Gst *vm, const GstModuleItem *mod) {
GstObject *module = gst_object(vm, 10);
while (mod->name != NULL) {
GstValue key = gst_load_csymbol(vm, mod->name);
GstValue val;
val.type = GST_CFUNCTION;
val.data.cfunction = mod->data;
gst_object_put(vm, module, key, val);
mod++;
}
return module;
}
void gst_c_register(Gst *vm, const char *packagename, GstObject *mod) {
GstValue modv;
if (vm->rootenv == NULL)
vm->rootenv = gst_object(vm, 10);
modv.type = GST_OBJECT;
modv.data.object = mod;
gst_object_put(vm, vm->rootenv, gst_load_csymbol(vm, packagename), modv);
}

View File

@ -327,7 +327,8 @@ static uint16_t compiler_declare_symbol(GstCompiler *c, GstScope *scope, GstValu
/* Try to resolve a symbol. If the symbol can be resovled, return true and /* Try to resolve a symbol. If the symbol can be resovled, return true and
* pass back the level and index by reference. */ * pass back the level and index by reference. */
static int symbol_resolve(GstScope *scope, GstValue x, uint16_t *level, uint16_t *index) { static int symbol_resolve(GstCompiler *c, GstValue x, uint16_t *level, uint16_t *index) {
GstScope *scope = c->tail;
uint32_t currentLevel = scope->level; uint32_t currentLevel = scope->level;
while (scope) { while (scope) {
GstValue check = gst_object_get(scope->locals, x); GstValue check = gst_object_get(scope->locals, x);
@ -336,6 +337,7 @@ static int symbol_resolve(GstScope *scope, GstValue x, uint16_t *level, uint16_t
*index = (uint16_t) check.data.number; *index = (uint16_t) check.data.number;
return 1; return 1;
} }
scope = scope->parent; scope = scope->parent;
} }
return 0; return 0;
@ -409,13 +411,13 @@ static Slot compile_nonref_type(GstCompiler *c, FormOptions opts, GstValue x) {
/* Compile a symbol. Resolves any kind of symbol. */ /* Compile a symbol. Resolves any kind of symbol. */
static Slot compile_symbol(GstCompiler *c, FormOptions opts, GstValue sym) { static Slot compile_symbol(GstCompiler *c, FormOptions opts, GstValue sym) {
GstBuffer * buffer = c->buffer; GstBuffer * buffer = c->buffer;
GstScope * scope = c->tail;
uint16_t index = 0; uint16_t index = 0;
uint16_t level = 0; uint16_t level = 0;
Slot ret; Slot ret;
if (opts.resultUnused) return nil_slot(); if (opts.resultUnused) return nil_slot();
if (!symbol_resolve(scope, sym, &level, &index)) if (!symbol_resolve(c, sym, &level, &index)) {
c_error(c, "undefined symbol"); c_error(c, "undefined symbol");
}
if (level > 0) { if (level > 0) {
/* We have an upvalue */ /* We have an upvalue */
ret = compiler_get_target(c, opts); ret = compiler_get_target(c, opts);
@ -452,7 +454,7 @@ static Slot compile_assign(GstCompiler *c, FormOptions opts, GstValue left, GstV
Slot slot; Slot slot;
subOpts.isTail = 0; subOpts.isTail = 0;
subOpts.resultUnused = 0; subOpts.resultUnused = 0;
if (symbol_resolve(scope, left, &level, &target)) { if (symbol_resolve(c, left, &level, &target)) {
/* Check if we have an up value. Otherwise, it's just a normal /* Check if we have an up value. Otherwise, it's just a normal
* local variable */ * local variable */
if (level != 0) { if (level != 0) {
@ -1022,14 +1024,19 @@ void gst_compiler(GstCompiler *c, Gst *vm) {
compiler_push_scope(c, 0); compiler_push_scope(c, 0);
} }
/* Add environment */ /* Add a global variable */
void gst_compiler_env(GstCompiler *c, GstValue env) { void gst_compiler_global(GstCompiler *c, const char *name, GstValue x) {
GstValue sym = gst_load_csymbol(c->vm, name);
compiler_declare_symbol(c, c->tail, sym);
gst_array_push(c->vm, c->env, x);
}
/* Add many global variables */
void gst_compiler_globals(GstCompiler *c, GstObject *env) {
uint32_t i; uint32_t i;
GstBucket *bucket; GstBucket *bucket;
/* Register everything in environment */ for (i = 0; i < env->capacity; ++i) {
if (env.type == GST_OBJECT) { bucket = env->buckets[i];
for (i = 0; i < env.data.object->capacity; ++i) {
bucket = env.data.object->buckets[i];
while (bucket) { while (bucket) {
if (bucket->key.type == GST_SYMBOL) { if (bucket->key.type == GST_SYMBOL) {
compiler_declare_symbol(c, c->tail, bucket->key); compiler_declare_symbol(c, c->tail, bucket->key);
@ -1039,22 +1046,13 @@ void gst_compiler_env(GstCompiler *c, GstValue env) {
} }
} }
} }
}
/* Register a global for the compilation environment. */ /* Use a module that was loaded into the vm */
void gst_compiler_add_global(GstCompiler *c, const char *name, GstValue x) { void gst_compiler_usemodule(GstCompiler *c, const char *modulename) {
GstValue sym = gst_load_cstring(c->vm, name); GstValue mod = gst_object_get(c->vm->rootenv, gst_load_csymbol(c->vm, modulename));
sym.type = GST_SYMBOL; if (mod.type == GST_OBJECT) {
compiler_declare_symbol(c, c->tail, sym); gst_compiler_globals(c, mod.data.object);
gst_array_push(c->vm, c->env, x);
} }
/* Register a global c function for the compilation environment. */
void gst_compiler_add_global_cfunction(GstCompiler *c, const char *name, GstCFunction f) {
GstValue func;
func.type = GST_CFUNCTION;
func.data.cfunction = f;
gst_compiler_add_global(c, name, func);
} }
/* Compile interface. Returns a function that evaluates the /* Compile interface. Returns a function that evaluates the

View File

@ -235,13 +235,15 @@ void gst_mem_tag(void *mem, uint32_t tags) {
/* Run garbage collection */ /* Run garbage collection */
void gst_collect(Gst *vm) { void gst_collect(Gst *vm) {
GstValueUnion renv;
/* Thread can be null */ /* Thread can be null */
if (vm->thread) { if (vm->thread) {
GstValueUnion t; GstValueUnion t;
t.thread = vm->thread; t.thread = vm->thread;
gst_mark(vm, t, GST_THREAD); gst_mark(vm, t, GST_THREAD);
} }
gst_mark_value(vm, vm->rootenv); renv.object = vm->rootenv;
gst_mark(vm, renv, GST_OBJECT);
gst_mark_value(vm, vm->ret); gst_mark_value(vm, vm->ret);
gst_sweep(vm); gst_sweep(vm);
vm->nextCollection = 0; vm->nextCollection = 0;

View File

@ -396,12 +396,7 @@ int gst_stl_serialize(Gst *vm) {
/* Bootstraping */ /* Bootstraping */
/****/ /****/
struct GstRegistryItem { static const GstModuleItem const std_module[] = {
const char *name;
GstCFunction func;
};
static const struct GstRegistryItem const registry[] = {
{"+", gst_stl_add}, {"+", gst_stl_add},
{"*", gst_stl_mul}, {"*", gst_stl_mul},
{"-", gst_stl_sub}, {"-", gst_stl_sub},
@ -430,9 +425,7 @@ static const struct GstRegistryItem const registry[] = {
}; };
/* Load all libraries */ /* Load all libraries */
void gst_stl_load(GstCompiler *c) { void gst_stl_load(Gst *vm) {
const struct GstRegistryItem *item; GstObject *module = gst_c_module(vm, std_module);
for (item = registry; item->name; ++item) { gst_c_register(vm, "std", module);
gst_compiler_add_global_cfunction(c, item->name, item->func);
}
} }

View File

@ -504,16 +504,17 @@ void gst_init(Gst *vm) {
vm->black = 0; vm->black = 0;
/* Add thread */ /* Add thread */
vm->thread = NULL; vm->thread = NULL;
vm->rootenv.type = GST_NIL;
/* Set up string cache */ /* Set up string cache */
gst_stringcache_init(vm, 128); gst_stringcache_init(vm, 128);
/* Set up global env */
vm->rootenv = NULL;
} }
/* Clear all memory associated with the VM */ /* Clear all memory associated with the VM */
void gst_deinit(Gst *vm) { void gst_deinit(Gst *vm) {
gst_clear_memory(vm); gst_clear_memory(vm);
vm->thread = NULL; vm->thread = NULL;
vm->rootenv.type = GST_NIL; vm->rootenv = NULL;
vm->ret.type = GST_NIL; vm->ret.type = GST_NIL;
gst_stringcache_deinit(vm); gst_stringcache_deinit(vm);
} }

View File

@ -20,14 +20,14 @@ struct GstCompiler {
/* Initialize the Compiler */ /* Initialize the Compiler */
void gst_compiler(GstCompiler *c, Gst *vm); void gst_compiler(GstCompiler *c, Gst *vm);
/* Register an environment for compilation */ /* Add many globals */
void gst_compiler_env(GstCompiler *c, GstValue env); void gst_compiler_globals(GstCompiler *c, GstObject *env);
/* Register a global for the compilation environment. */ /* Register a global for the compilation environment. */
void gst_compiler_add_global(GstCompiler *c, const char *name, GstValue x); void gst_compiler_global(GstCompiler *c, const char *name, GstValue x);
/* Register a global c function for the compilation environment. */ /* Use a module */
void gst_compiler_add_global_cfunction(GstCompiler *c, const char *name, GstCFunction f); void gst_compiler_usemodule(GstCompiler *c, const char *modulename);
/* Compile a function that evaluates the given form. */ /* Compile a function that evaluates the given form. */
GstFunction *gst_compiler_compile(GstCompiler *c, GstValue form); GstFunction *gst_compiler_compile(GstCompiler *c, GstValue form);

View File

@ -131,6 +131,15 @@ typedef union GstValueUnion GstValueUnion;
/* Definitely implementation details */ /* Definitely implementation details */
typedef struct GstBucket GstBucket; typedef struct GstBucket GstBucket;
/* API Types */
typedef struct GstModuleItem GstModuleItem;
/* C Api data types */
struct GstModuleItem {
const char *name;
GstCFunction data;
};
/* Union datatype */ /* Union datatype */
union GstValueUnion { union GstValueUnion {
GstBoolean boolean; GstBoolean boolean;
@ -174,7 +183,7 @@ struct GstThread {
} status; } status;
}; };
/* A dynamic array type. Useful for implementing a stack. */ /* A dynamic array type. */
struct GstArray { struct GstArray {
uint32_t count; uint32_t count;
uint32_t capacity; uint32_t capacity;
@ -257,7 +266,7 @@ struct Gst {
/* Thread */ /* Thread */
GstThread *thread; GstThread *thread;
/* A GC root */ /* A GC root */
GstValue rootenv; GstObject *rootenv;
/* Return state */ /* Return state */
const char *crash; const char *crash;
GstValue ret; /* Returned value from gst_start. Also holds errors. */ GstValue ret; /* Returned value from gst_start. Also holds errors. */
@ -462,4 +471,11 @@ GstValue gst_arg(Gst *vm, uint16_t index);
void gst_set_arg(Gst *vm, uint16_t index, GstValue x); void gst_set_arg(Gst *vm, uint16_t index, GstValue x);
uint16_t gst_count_args(Gst *vm); uint16_t gst_count_args(Gst *vm);
/***/
/* C Api */
/***/
GstObject *gst_c_module(Gst *vm, const GstModuleItem *mod);
void gst_c_register(Gst *vm, const char *packagename, GstObject *mod);
#endif // GST_H_defined #endif // GST_H_defined

View File

@ -2,10 +2,9 @@
#define stl_h_INCLUDED #define stl_h_INCLUDED
#include <gst/gst.h> #include <gst/gst.h>
#include <gst/compile.h>
/* Load the standard library */ /* Load the standard library */
void gst_stl_load(GstCompiler *c); void gst_stl_load(Gst *vm);
#endif // stl_h_INCLUDED #endif // stl_h_INCLUDED