1
0
mirror of https://github.com/janet-lang/janet synced 2025-10-30 23:23:07 +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

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
* 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;
while (scope) {
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;
return 1;
}
scope = scope->parent;
}
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. */
static Slot compile_symbol(GstCompiler *c, FormOptions opts, GstValue sym) {
GstBuffer * buffer = c->buffer;
GstScope * scope = c->tail;
uint16_t index = 0;
uint16_t level = 0;
Slot ret;
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");
}
if (level > 0) {
/* We have an upvalue */
ret = compiler_get_target(c, opts);
@@ -452,7 +454,7 @@ static Slot compile_assign(GstCompiler *c, FormOptions opts, GstValue left, GstV
Slot slot;
subOpts.isTail = 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
* local variable */
if (level != 0) {
@@ -1022,39 +1024,35 @@ void gst_compiler(GstCompiler *c, Gst *vm) {
compiler_push_scope(c, 0);
}
/* Add environment */
void gst_compiler_env(GstCompiler *c, GstValue env) {
/* Add a global variable */
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;
GstBucket *bucket;
/* Register everything in environment */
if (env.type == GST_OBJECT) {
for (i = 0; i < env.data.object->capacity; ++i) {
bucket = env.data.object->buckets[i];
while (bucket) {
if (bucket->key.type == GST_SYMBOL) {
compiler_declare_symbol(c, c->tail, bucket->key);
gst_array_push(c->vm, c->env, bucket->value);
}
bucket = bucket->next;
for (i = 0; i < env->capacity; ++i) {
bucket = env->buckets[i];
while (bucket) {
if (bucket->key.type == GST_SYMBOL) {
compiler_declare_symbol(c, c->tail, bucket->key);
gst_array_push(c->vm, c->env, bucket->value);
}
bucket = bucket->next;
}
}
}
/* Register a global for the compilation environment. */
void gst_compiler_add_global(GstCompiler *c, const char *name, GstValue x) {
GstValue sym = gst_load_cstring(c->vm, name);
sym.type = GST_SYMBOL;
compiler_declare_symbol(c, c->tail, sym);
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);
/* Use a module that was loaded into the vm */
void gst_compiler_usemodule(GstCompiler *c, const char *modulename) {
GstValue mod = gst_object_get(c->vm->rootenv, gst_load_csymbol(c->vm, modulename));
if (mod.type == GST_OBJECT) {
gst_compiler_globals(c, mod.data.object);
}
}
/* 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 */
void gst_collect(Gst *vm) {
GstValueUnion renv;
/* Thread can be null */
if (vm->thread) {
GstValueUnion t;
t.thread = vm->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_sweep(vm);
vm->nextCollection = 0;

View File

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

View File

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