#include #include #include "resolution.h" static void writeFn(WrenVM* vm, const char* text) { printf("%s", text); } static void reportError(WrenVM* vm, WrenErrorType type, const char* module, int line, const char* message) { if (type == WREN_ERROR_RUNTIME) printf("%s\n", message); } static void loadModuleComplete(WrenVM* vm, const char* module, WrenLoadModuleResult result) { free((void*)result.source); } static WrenLoadModuleResult loadModule(WrenVM* vm, const char* module) { printf("loading %s\n", module); const char* source; if (strcmp(module, "main/baz/bang") == 0) { source = "import \"foo|bar\""; } else { source = "System.print(\"ok\")"; } char* string = (char*)malloc(strlen(source) + 1); strcpy(string, source); WrenLoadModuleResult result = {0}; result.onComplete = loadModuleComplete; result.source = string; return result; } static void runTestVM(WrenVM* vm, WrenConfiguration* configuration, const char* source) { configuration->writeFn = writeFn; configuration->errorFn = reportError; configuration->loadModuleFn = loadModule; WrenVM* otherVM = wrenNewVM(configuration); // We should be able to execute code. WrenInterpretResult result = wrenInterpret(otherVM, "main", source); if (result != WREN_RESULT_SUCCESS) { wrenSetSlotString(vm, 0, "error"); } else { wrenSetSlotString(vm, 0, "success"); } wrenFreeVM(otherVM); } static void noResolver(WrenVM* vm) { WrenConfiguration configuration; wrenInitConfiguration(&configuration); // Should default to no resolution function. if (configuration.resolveModuleFn != NULL) { wrenSetSlotString(vm, 0, "Did not have null resolve function."); return; } runTestVM(vm, &configuration, "import \"foo/bar\""); } static const char* resolveToNull(WrenVM* vm, const char* importer, const char* name) { return NULL; } static void returnsNull(WrenVM* vm) { WrenConfiguration configuration; wrenInitConfiguration(&configuration); configuration.resolveModuleFn = resolveToNull; runTestVM(vm, &configuration, "import \"foo/bar\""); } static const char* resolveChange(WrenVM* vm, const char* importer, const char* name) { // Concatenate importer and name. size_t length = strlen(importer) + 1 + strlen(name) + 1; char* result = (char*)malloc(length); strcpy(result, importer); strcat(result, "/"); strcat(result, name); // Replace "|" with "/". for (size_t i = 0; i < length; i++) { if (result[i] == '|') result[i] = '/'; } return result; } static void changesString(WrenVM* vm) { WrenConfiguration configuration; wrenInitConfiguration(&configuration); configuration.resolveModuleFn = resolveChange; runTestVM(vm, &configuration, "import \"foo|bar\""); } static void shared(WrenVM* vm) { WrenConfiguration configuration; wrenInitConfiguration(&configuration); configuration.resolveModuleFn = resolveChange; runTestVM(vm, &configuration, "import \"foo|bar\"\nimport \"foo/bar\""); } static void importer(WrenVM* vm) { WrenConfiguration configuration; wrenInitConfiguration(&configuration); configuration.resolveModuleFn = resolveChange; runTestVM(vm, &configuration, "import \"baz|bang\""); } WrenForeignMethodFn resolutionBindMethod(const char* signature) { if (strcmp(signature, "static Resolution.noResolver()") == 0) return noResolver; if (strcmp(signature, "static Resolution.returnsNull()") == 0) return returnsNull; if (strcmp(signature, "static Resolution.changesString()") == 0) return changesString; if (strcmp(signature, "static Resolution.shared()") == 0) return shared; if (strcmp(signature, "static Resolution.importer()") == 0) return importer; return NULL; } void resolutionBindClass(const char* className, WrenForeignClassMethods* methods) { // methods->allocate = foreignClassAllocate; }