feat: add WrenResolveModuleFn callback and module name parameter to wrenInterpret for relative import resolution

This breaking API change introduces a new `WrenResolveModuleFn` callback in the configuration that allows the host to canonicalize import module names, enabling relative imports. The `wrenInterpret()` function now requires a `module` parameter to specify the module name for the code being interpreted. The `wrenInterpretInModule()` function is removed in favor of the updated `wrenInterpret()`. The `metaCompile` function now dynamically looks up the caller's module name instead of hardcoding "main". New test files `resolution.c`, `resolution.h`, and `resolution.wren` are added to verify resolver behavior including null default, NULL return error, string rewriting, shared module deduplication, and importer propagation.
This commit is contained in:
Bob Nystrom
2018-03-23 14:54:09 +00:00
parent 88ad0fc138
commit 761032c0fc
12 changed files with 290 additions and 20 deletions
+10 -2
View File
@@ -14,9 +14,17 @@ void metaCompile(WrenVM* vm)
bool printErrors = wrenGetSlotBool(vm, 3);
// TODO: Allow passing in module?
ObjClosure* closure = wrenCompileSource(vm, "main", source,
isExpression, printErrors);
// Look up the module surrounding the callsite. This is brittle. The -2 walks
// up the callstack assuming that the meta module has one level of
// indirection before hitting the user's code. Any change to meta may require
// this constant to be tweaked.
ObjFiber* currentFiber = vm->fiber;
ObjFn* fn = currentFiber->frames[currentFiber->numFrames - 2].closure->fn;
ObjString* module = fn->module->name;
ObjClosure* closure = wrenCompileSource(vm, module->value, source,
isExpression, printErrors);
// Return the result. We can't use the public API for this since we have a
// bare ObjClosure*.
if (closure == NULL)