feat: add foreign class support with allocation, construct opcodes, and CLI callback wiring
Implement the initial infrastructure for foreign classes in the Wren VM, including new opcodes (FOREIGN_CONSTRUCT, FOREIGN_CLASS), a WrenBindForeignClassFn callback type in the public API, and updated CLI vm.c to store and forward foreign binding callbacks via setForeignCallbacks(). The compiler now tracks whether a class is foreign via a new isForeign flag in ClassCompiler, emits CODE_FOREIGN_CONSTRUCT instead of CODE_CONSTRUCT for foreign class constructors, and errors on field definitions inside foreign classes. The debug dump and opcode header gain entries for the new opcodes, and wrenBindSuperclass handles the -1 numFields sentinel for foreign classes to prevent field inheritance from superclasses.
This commit is contained in:
+2
-2
@@ -9,7 +9,7 @@
|
||||
|
||||
static int runRepl()
|
||||
{
|
||||
WrenVM* vm = createVM(NULL);
|
||||
WrenVM* vm = createVM();
|
||||
|
||||
printf("\\\\/\"-\n");
|
||||
printf(" \\_/ wren v0.0.0\n");
|
||||
@@ -50,7 +50,7 @@ int main(int argc, const char* argv[])
|
||||
}
|
||||
else if (argc == 2)
|
||||
{
|
||||
runFile(NULL, argv[1]);
|
||||
runFile(argv[1]);
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
||||
+17
-10
@@ -4,25 +4,25 @@
|
||||
#include "io.h"
|
||||
#include "vm.h"
|
||||
|
||||
WrenVM* createVM(WrenBindForeignMethodFn bindForeign)
|
||||
static WrenBindForeignMethodFn bindMethodFn = NULL;
|
||||
static WrenBindForeignClassFn bindClassFn = NULL;
|
||||
|
||||
WrenVM* createVM()
|
||||
{
|
||||
WrenConfiguration config;
|
||||
|
||||
config.bindForeignMethodFn = bindForeign;
|
||||
wrenInitConfiguration(&config);
|
||||
|
||||
config.bindForeignMethodFn = bindMethodFn;
|
||||
config.bindForeignClassFn = bindClassFn;
|
||||
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;
|
||||
|
||||
return wrenNewVM(&config);
|
||||
}
|
||||
|
||||
void runFile(WrenBindForeignMethodFn bindForeign, const char* path)
|
||||
void runFile(const char* path)
|
||||
{
|
||||
// Use the directory where the file is as the root to resolve imports
|
||||
// relative to.
|
||||
@@ -43,7 +43,7 @@ void runFile(WrenBindForeignMethodFn bindForeign, const char* path)
|
||||
exit(66);
|
||||
}
|
||||
|
||||
WrenVM* vm = createVM(bindForeign);
|
||||
WrenVM* vm = createVM();
|
||||
|
||||
WrenInterpretResult result = wrenInterpret(vm, path, source);
|
||||
|
||||
@@ -55,3 +55,10 @@ void runFile(WrenBindForeignMethodFn bindForeign, const char* path)
|
||||
if (result == WREN_RESULT_COMPILE_ERROR) exit(65); // EX_DATAERR.
|
||||
if (result == WREN_RESULT_RUNTIME_ERROR) exit(70); // EX_SOFTWARE.
|
||||
}
|
||||
|
||||
void setForeignCallbacks(
|
||||
WrenBindForeignMethodFn bindMethod, WrenBindForeignClassFn bindClass)
|
||||
{
|
||||
bindMethodFn = bindMethod;
|
||||
bindClassFn = bindClass;
|
||||
}
|
||||
|
||||
+9
-2
@@ -4,11 +4,18 @@
|
||||
#include "wren.h"
|
||||
|
||||
// Creates a new Wren VM with the CLI's module loader and other configuration.
|
||||
WrenVM* createVM(WrenBindForeignMethodFn bindForeign);
|
||||
WrenVM* createVM();
|
||||
|
||||
// Executes the Wren script at [path] in a new VM.
|
||||
//
|
||||
// Exits if the script failed or could not be loaded.
|
||||
void runFile(WrenBindForeignMethodFn bindForeign, const char* path);
|
||||
void runFile(const char* path);
|
||||
|
||||
// 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