refactor: move meta and random modules from vm and cli into new aux library category

Restructure module hierarchy by extracting meta and random from the core VM and CLI-specific modules into a new "aux" (auxiliary) directory. This introduces WREN_AUX_META and WREN_AUX_RANDOM configuration flags, updates include paths and build system to compile aux sources separately, removes random module registration from CLI modules.c, and adjusts the VM's module loading to implicitly import core into all modules regardless of name.
This commit is contained in:
Bob Nystrom
2015-10-18 05:09:48 +00:00
parent 455c1dc7c1
commit 88a4e0a4e9
15 changed files with 264 additions and 167 deletions
+9 -5
View File
@@ -44,11 +44,15 @@
#endif
#endif
// If true, loads the "meta" built in module.
//
// Defaults to on.
#ifndef WREN_USE_META_MODULE
#define WREN_USE_META_MODULE 1
// The VM includes a number of optional "auxiliary" modules. You can choose to
// include these or not. By default, they are all available. To disable one,
// set the corresponding `WREN_AUX_<name>` define to `0`.
#ifndef WREN_AUX_META
#define WREN_AUX_META 1
#endif
#ifndef WREN_AUX_RANDOM
#define WREN_AUX_RANDOM 1
#endif
// These flags are useful for debugging and hacking on Wren itself. They are not
-56
View File
@@ -1,56 +0,0 @@
#include "wren_meta.h"
#if WREN_USE_META_MODULE
#include <string.h>
#include "wren_primitive.h"
#include "wren_meta.wren.inc"
void metaCompile(WrenVM* vm)
{
// Evaluate the code in the module where the calling function was defined.
// That's one stack frame back from the top since the top-most frame is the
// helper eval() method in Meta itself.
Value callingFn = OBJ_VAL(vm->fiber->frames[vm->fiber->numFrames - 2].fn);
ObjModule* module = IS_FN(callingFn)
? AS_FN(callingFn)->module
: AS_CLOSURE(callingFn)->fn->module;
// Compile it.
ObjFn* fn = wrenCompile(vm, module, wrenGetArgumentString(vm, 1), false);
if (fn == NULL) return;
// Return the result. We can't use the public API for this since we have a
// bare ObjFn.
*vm->foreignCallSlot = OBJ_VAL(fn);
vm->foreignCallSlot = NULL;
}
static WrenForeignMethodFn bindMetaForeignMethods(WrenVM* vm,
const char* module,
const char* className,
bool isStatic,
const char* signature)
{
// There is only one foreign method in the meta module.
ASSERT(strcmp(module, "meta") == 0, "Should be in meta module.");
ASSERT(strcmp(className, "Meta") == 0, "Should be in Meta class.");
ASSERT(isStatic, "Should be static.");
ASSERT(strcmp(signature, "compile_(_)") == 0, "Should be compile method.");
return metaCompile;
}
void wrenLoadMetaModule(WrenVM* vm)
{
WrenBindForeignMethodFn previousBindFn = vm->config.bindForeignMethodFn;
vm->config.bindForeignMethodFn = bindMetaForeignMethods;
wrenInterpretInModule(vm, "meta", metaModuleSource);
vm->config.bindForeignMethodFn = previousBindFn;
}
#endif
-15
View File
@@ -1,15 +0,0 @@
#ifndef wren_meta_h
#define wren_meta_h
#include "wren_common.h"
#include "wren.h"
// This module defines the Meta class and its associated methods.
#if WREN_USE_META_MODULE
void wrenLoadMetaModule(WrenVM* vm);
#endif
#endif
-15
View File
@@ -1,15 +0,0 @@
// Generated automatically from builtin/meta.wren. Do not edit.
static const char* metaModuleSource =
"class Meta {\n"
" static eval(source) {\n"
" if (!(source is String)) Fiber.abort(\"Source code must be a string.\")\n"
"\n"
" var fn = compile_(source)\n"
" // TODO: Include compile errors.\n"
" if (fn == null) Fiber.abort(\"Could not compile source code.\")\n"
"\n"
" Fiber.new(fn).call()\n"
" }\n"
"\n"
" foreign static compile_(source)\n"
"}\n";
+18 -14
View File
@@ -8,8 +8,11 @@
#include "wren_debug.h"
#include "wren_vm.h"
#if WREN_USE_META_MODULE
#include "wren_meta.h"
#if WREN_AUX_META
#include "wren_aux_meta.h"
#endif
#if WREN_AUX_RANDOM
#include "wren_aux_random.h"
#endif
#if WREN_DEBUG_TRACE_MEMORY || WREN_DEBUG_TRACE_GC
@@ -57,10 +60,14 @@ WrenVM* wrenNewVM(WrenConfiguration* config)
wrenInitializeCore(vm);
#if WREN_USE_META_MODULE
// TODO: Lazy load these.
#if WREN_AUX_META
wrenLoadMetaModule(vm);
#endif
#if WREN_AUX_RANDOM
wrenLoadRandomModule(vm);
#endif
return vm;
}
@@ -449,17 +456,14 @@ static ObjFiber* loadModule(WrenVM* vm, Value name, const char* source)
// multiple times.
wrenMapSet(vm, vm->modules, name, OBJ_VAL(module));
// Implicitly import the core module (unless we *are* core).
if (!IS_NULL(name))
// Implicitly import the core module.
ObjModule* coreModule = getModule(vm, NULL_VAL);
for (int i = 0; i < coreModule->variables.count; i++)
{
ObjModule* coreModule = getModule(vm, NULL_VAL);
for (int i = 0; i < coreModule->variables.count; i++)
{
wrenDefineVariable(vm, module,
coreModule->variableNames.data[i].buffer,
coreModule->variableNames.data[i].length,
coreModule->variables.data[i]);
}
wrenDefineVariable(vm, module,
coreModule->variableNames.data[i].buffer,
coreModule->variableNames.data[i].length,
coreModule->variables.data[i]);
}
}