#include <string>
#include <iostream>
#include "wren.hpp"
using namespace std;
class View
{
public:
};
static void viewAllocate(WrenVM* vm)
{
View** vw = (View**)wrenSetSlotNewForeign(vm,
0, 0, sizeof(View*));
*vw = new View;
}
static void viewFinalize(void* data)
{
auto vw = (View**)data;
if (vw && *vw) {
delete* vw;
*vw = NULL;
}
}
static void viewDraw(WrenVM* vm)
{
View** vw = (View**)wrenGetSlotForeign(vm, 0);
const char* str = wrenGetSlotString(vm, 1);
cout << str << endl;
auto var = wrenGetSlotHandle(vm, 2);
wrenEnsureSlots(vm, 2);
wrenSetSlotHandle(vm, 0, var);
wrenSetSlotString(vm, 1, "form c++");
auto fn = wrenMakeCallHandle(vm, "call(_)");
wrenCall(vm, fn);
wrenReleaseHandle(vm, var);
wrenReleaseHandle(vm, fn);
}
WrenForeignClassMethods bindForeignClass(
WrenVM* vm, const char* module, const char* className)
{
WrenForeignClassMethods methods;
if (strcmp(className, "View") == 0)
{
methods.allocate = viewAllocate;
methods.finalize = viewFinalize;
}
else
{
// Unknown class.
methods.allocate = NULL;
methods.finalize = NULL;
}
return methods;
}
WrenForeignMethodFn bindForeignMethod(WrenVM* vm, const char* module,
const char* className, bool isStatic, const char* signature)
{
if (strcmp(className, "View") == 0)
{
if (!isStatic && strcmp(signature, "draw(_,_)") == 0)
{
return viewDraw;
}
}
// Unknown method.
return NULL;
}
static void loadModuleComplete(
WrenVM* vm,
const char* module,
WrenLoadModuleResult result)
{
}
static string viewCode = R"(
foreign class View {
construct new() {}
foreign draw(text,fn)
}
)";
static WrenLoadModuleResult myLoadModule(WrenVM* vm, const char* name) {
WrenLoadModuleResult result = { 0 };
if (strcmp(name, "view") == 0) {
result.onComplete = loadModuleComplete;
result.source = viewCode.c_str();
}
return result;
}
static void writeFn(WrenVM* vm, const char* text)
{
printf("%s", text);
}
void errorFn(WrenVM* vm, WrenErrorType errorType,
const char* module, const int line,
const char* msg)
{
switch (errorType)
{
case WREN_ERROR_COMPILE:
{
printf("[%s line %d] [Error] %s\n", module, line, msg);
} break;
case WREN_ERROR_STACK_TRACE:
{
printf("[%s line %d] in %s\n", module, line, msg);
} break;
case WREN_ERROR_RUNTIME:
{
printf("[Runtime Error] %s\n", msg);
} break;
}
}
int main()
{
WrenConfiguration config;
wrenInitConfiguration(&config);
config.writeFn = &writeFn;
config.errorFn = &errorFn;
config.loadModuleFn = &myLoadModule;
config.bindForeignClassFn = &bindForeignClass;
config.bindForeignMethodFn = &bindForeignMethod;
WrenVM* vm = wrenNewVM(&config);
const char* module = "main";
const char* script = R"(
import "view" for View
class Main {
static main() {
var vw = View.new()
var fn = Fn.new {|arg|
System.print(arg)
}
vw.draw("Hello,OurNav", fn)
}
}
)";
WrenInterpretResult result = wrenInterpret(vm, module, script);
switch (result) {
case WREN_RESULT_COMPILE_ERROR:
{ printf("Compile Error!\n"); } break;
case WREN_RESULT_RUNTIME_ERROR:
{ printf("Runtime Error!\n"); } break;
case WREN_RESULT_SUCCESS:
{ printf("wrenInterpret Success!\n"); } break;
}
wrenEnsureSlots(vm, 1);
wrenGetVariable(vm, module, "Main", 0);
auto mainFn = wrenMakeCallHandle(vm, "main()");
wrenCall(vm, mainFn);
wrenReleaseHandle(vm, mainFn);
wrenFreeVM(vm);
return 0;
}
wrenInterpret Success!
Hello,OurNav
[Runtime Error] Main metaclass does not implement 'call(_)'.
[main line 6] in main()