Merge branch 'master' into libuv
# Conflicts: # project/xcode/wren.xcodeproj/project.pbxproj # script/wren.mk # src/cli/main.c # src/cli/vm.c # src/cli/vm.h # test/api/main.c
This commit is contained in:
+2
-2
@@ -12,14 +12,14 @@ int main(int argc, const char* argv[])
|
||||
fprintf(stderr, "Usage: wren [file]\n");
|
||||
return 64; // EX_USAGE.
|
||||
}
|
||||
|
||||
|
||||
if (argc == 1)
|
||||
{
|
||||
runRepl();
|
||||
}
|
||||
else if (argc == 2)
|
||||
{
|
||||
runFile(argv[1], NULL);
|
||||
runFile(argv[1]);
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
||||
+51
-33
@@ -10,46 +10,59 @@
|
||||
// The single VM instance that the CLI uses.
|
||||
WrenVM* vm;
|
||||
|
||||
WrenBindForeignMethodFn externalBindForeign;
|
||||
static WrenBindForeignMethodFn bindMethodFn = NULL;
|
||||
static WrenBindForeignClassFn bindClassFn = NULL;
|
||||
|
||||
uv_loop_t* loop;
|
||||
|
||||
static WrenForeignMethodFn bindForeignMethod(WrenVM* vm,
|
||||
const char* module,
|
||||
const char* className,
|
||||
bool isStatic,
|
||||
const char* signature)
|
||||
/// Binds foreign methods declared in either built in modules, or the injected
|
||||
/// API test modules.
|
||||
static WrenForeignMethodFn bindForeignMethod(WrenVM* vm, const char* module,
|
||||
const char* className, bool isStatic, const char* signature)
|
||||
{
|
||||
if (strcmp(module, "timer") == 0)
|
||||
{
|
||||
return timerBindForeign(vm, className, isStatic, signature);
|
||||
}
|
||||
|
||||
if (externalBindForeign != NULL)
|
||||
|
||||
if (bindMethodFn != NULL)
|
||||
{
|
||||
return externalBindForeign(vm, module, className, isStatic, signature);
|
||||
return bindMethodFn(vm, module, className, isStatic, signature);
|
||||
}
|
||||
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/// Binds foreign classes declared in either built in modules, or the injected
|
||||
/// API test modules.
|
||||
static WrenForeignClassMethods bindForeignClass(
|
||||
WrenVM* vm, const char* module, const char* className)
|
||||
{
|
||||
WrenForeignClassMethods methods = { NULL, NULL };
|
||||
|
||||
// TODO: Bind classes for built-in modules here.
|
||||
|
||||
if (bindClassFn != NULL)
|
||||
{
|
||||
return bindClassFn(vm, module, className);
|
||||
}
|
||||
|
||||
return methods;
|
||||
}
|
||||
|
||||
static void initVM()
|
||||
{
|
||||
WrenConfiguration config;
|
||||
wrenInitConfiguration(&config);
|
||||
|
||||
config.bindForeignMethodFn = bindForeignMethod;
|
||||
config.bindForeignClassFn = bindForeignClass;
|
||||
config.loadModuleFn = readModule;
|
||||
|
||||
// Since we're running in a standalone process, be generous with memory.
|
||||
config.initialHeapSize = 1024 * 1024 * 100;
|
||||
|
||||
// Use defaults for these.
|
||||
config.reallocateFn = NULL;
|
||||
config.minHeapSize = 0;
|
||||
config.heapGrowthPercent = 0;
|
||||
|
||||
vm = wrenNewVM(&config);
|
||||
|
||||
|
||||
// Initialize the event loop.
|
||||
loop = (uv_loop_t*)malloc(sizeof(uv_loop_t));
|
||||
uv_loop_init(loop);
|
||||
@@ -58,17 +71,15 @@ static void initVM()
|
||||
static void freeVM()
|
||||
{
|
||||
timerReleaseMethods();
|
||||
|
||||
|
||||
uv_loop_close(loop);
|
||||
free(loop);
|
||||
|
||||
wrenFreeVM(vm);
|
||||
}
|
||||
|
||||
void runFile(const char* path, WrenBindForeignMethodFn bindForeign)
|
||||
void runFile(const char* path)
|
||||
{
|
||||
externalBindForeign = bindForeign;
|
||||
|
||||
// Use the directory where the file is as the root to resolve imports
|
||||
// relative to.
|
||||
char* root = NULL;
|
||||
@@ -87,18 +98,18 @@ void runFile(const char* path, WrenBindForeignMethodFn bindForeign)
|
||||
fprintf(stderr, "Could not find file \"%s\".\n", path);
|
||||
exit(66);
|
||||
}
|
||||
|
||||
|
||||
initVM();
|
||||
|
||||
|
||||
WrenInterpretResult result = wrenInterpret(vm, path, source);
|
||||
|
||||
|
||||
if (result == WREN_RESULT_SUCCESS)
|
||||
{
|
||||
uv_run(loop, UV_RUN_DEFAULT);
|
||||
}
|
||||
|
||||
freeVM();
|
||||
|
||||
|
||||
free(source);
|
||||
free(root);
|
||||
|
||||
@@ -110,30 +121,30 @@ void runFile(const char* path, WrenBindForeignMethodFn bindForeign)
|
||||
int runRepl()
|
||||
{
|
||||
initVM();
|
||||
|
||||
|
||||
printf("\\\\/\"-\n");
|
||||
printf(" \\_/ wren v0.0.0\n");
|
||||
|
||||
|
||||
char line[MAX_LINE_LENGTH];
|
||||
|
||||
|
||||
for (;;)
|
||||
{
|
||||
printf("> ");
|
||||
|
||||
|
||||
if (!fgets(line, MAX_LINE_LENGTH, stdin))
|
||||
{
|
||||
printf("\n");
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
// TODO: Handle failure.
|
||||
wrenInterpret(vm, "Prompt", line);
|
||||
|
||||
|
||||
// TODO: Automatically print the result of expressions.
|
||||
}
|
||||
|
||||
|
||||
freeVM();
|
||||
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -146,3 +157,10 @@ uv_loop_t* getLoop()
|
||||
{
|
||||
return loop;
|
||||
}
|
||||
|
||||
void setForeignCallbacks(
|
||||
WrenBindForeignMethodFn bindMethod, WrenBindForeignClassFn bindClass)
|
||||
{
|
||||
bindMethodFn = bindMethod;
|
||||
bindClassFn = bindClass;
|
||||
}
|
||||
|
||||
+9
-3
@@ -6,9 +6,8 @@
|
||||
|
||||
// Executes the Wren script at [path] in a new VM.
|
||||
//
|
||||
// If [bindForeign] is not `NULL`, it will be called to register any foreign
|
||||
// methods that the CLI itself doesn't handle.
|
||||
void runFile(const char* path, WrenBindForeignMethodFn bindForeign);
|
||||
// Exits if the script failed or could not be loaded.
|
||||
void runFile(const char* path);
|
||||
|
||||
// Runs the Wren interactive REPL.
|
||||
int runRepl();
|
||||
@@ -19,4 +18,11 @@ WrenVM* getVM();
|
||||
// Gets the event loop the VM is using.
|
||||
uv_loop_t* getLoop();
|
||||
|
||||
// Adds additional callbacks to use when binding foreign members from Wren.
|
||||
//
|
||||
// Used by the API test executable to let it wire up its own foreign functions.
|
||||
// This must be called before calling [createVM()].
|
||||
void setForeignCallbacks(WrenBindForeignMethodFn bindMethod,
|
||||
WrenBindForeignClassFn bindClass);
|
||||
|
||||
#endif
|
||||
|
||||
Reference in New Issue
Block a user