Files
wren/test/api/slots.c
Aviv Beeri de6a312868 Functions for operating on Maps from C (#725)
new API functions for maps:
wrenSetSlotNewMap
wrenGetMapCount
wrenGetMapContainsKey
wrenGetMapValue
wrenSetMapValue
wrenRemoveMapValue
2020-06-14 14:45:23 -07:00

194 lines
4.8 KiB
C

#include <stdio.h>
#include <string.h>
#include "slots.h"
static void noSet(WrenVM* vm)
{
// Do nothing.
}
static void getSlots(WrenVM* vm)
{
bool result = true;
if (wrenGetSlotBool(vm, 1) != true) result = false;
int length;
const char* bytes = wrenGetSlotBytes(vm, 2, &length);
if (length != 5) result = false;
if (memcmp(bytes, "by\0te", length) != 0) result = false;
if (wrenGetSlotDouble(vm, 3) != 1.5) result = false;
if (strcmp(wrenGetSlotString(vm, 4), "str") != 0) result = false;
WrenHandle* handle = wrenGetSlotHandle(vm, 5);
if (result)
{
// Otherwise, return the value so we can tell if we captured it correctly.
wrenSetSlotHandle(vm, 0, handle);
}
else
{
// If anything failed, return false.
wrenSetSlotBool(vm, 0, false);
}
wrenReleaseHandle(vm, handle);
}
static void setSlots(WrenVM* vm)
{
WrenHandle* handle = wrenGetSlotHandle(vm, 1);
wrenSetSlotBool(vm, 1, true);
wrenSetSlotBytes(vm, 2, "by\0te", 5);
wrenSetSlotDouble(vm, 3, 1.5);
wrenSetSlotString(vm, 4, "str");
wrenSetSlotNull(vm, 5);
// Read the slots back to make sure they were set correctly.
bool result = true;
if (wrenGetSlotBool(vm, 1) != true) result = false;
int length;
const char* bytes = wrenGetSlotBytes(vm, 2, &length);
if (length != 5) result = false;
if (memcmp(bytes, "by\0te", length) != 0) result = false;
if (wrenGetSlotDouble(vm, 3) != 1.5) result = false;
if (strcmp(wrenGetSlotString(vm, 4), "str") != 0) result = false;
if (wrenGetSlotType(vm, 5) != WREN_TYPE_NULL) result = false;
if (result)
{
// Move the value into the return position.
wrenSetSlotHandle(vm, 0, handle);
}
else
{
// If anything failed, return false.
wrenSetSlotBool(vm, 0, false);
}
wrenReleaseHandle(vm, handle);
}
static void slotTypes(WrenVM* vm)
{
bool result =
wrenGetSlotType(vm, 1) == WREN_TYPE_BOOL &&
wrenGetSlotType(vm, 2) == WREN_TYPE_FOREIGN &&
wrenGetSlotType(vm, 3) == WREN_TYPE_LIST &&
wrenGetSlotType(vm, 4) == WREN_TYPE_MAP &&
wrenGetSlotType(vm, 5) == WREN_TYPE_NULL &&
wrenGetSlotType(vm, 6) == WREN_TYPE_NUM &&
wrenGetSlotType(vm, 7) == WREN_TYPE_STRING &&
wrenGetSlotType(vm, 8) == WREN_TYPE_UNKNOWN;
wrenSetSlotBool(vm, 0, result);
}
static void ensure(WrenVM* vm)
{
int before = wrenGetSlotCount(vm);
wrenEnsureSlots(vm, 20);
int after = wrenGetSlotCount(vm);
// Use the slots to make sure they're available.
for (int i = 0; i < 20; i++)
{
wrenSetSlotDouble(vm, i, i);
}
int sum = 0;
for (int i = 0; i < 20; i++)
{
sum += (int)wrenGetSlotDouble(vm, i);
}
char result[100];
sprintf(result, "%d -> %d (%d)", before, after, sum);
wrenSetSlotString(vm, 0, result);
}
static void ensureOutsideForeign(WrenVM* vm)
{
// To test the behavior outside of a foreign method (which we're currently
// in), create a new separate VM.
WrenConfiguration config;
wrenInitConfiguration(&config);
WrenVM* otherVM = wrenNewVM(&config);
int before = wrenGetSlotCount(otherVM);
wrenEnsureSlots(otherVM, 20);
int after = wrenGetSlotCount(otherVM);
// Use the slots to make sure they're available.
for (int i = 0; i < 20; i++)
{
wrenSetSlotDouble(otherVM, i, i);
}
int sum = 0;
for (int i = 0; i < 20; i++)
{
sum += (int)wrenGetSlotDouble(otherVM, i);
}
wrenFreeVM(otherVM);
char result[100];
sprintf(result, "%d -> %d (%d)", before, after, sum);
wrenSetSlotString(vm, 0, result);
}
static void foreignClassAllocate(WrenVM* vm)
{
wrenSetSlotNewForeign(vm, 0, 0, 4);
}
static void getListCount(WrenVM* vm)
{
wrenSetSlotDouble(vm, 0, wrenGetListCount(vm, 1));
}
static void getListElement(WrenVM* vm)
{
int index = (int)wrenGetSlotDouble(vm, 2);
wrenGetListElement(vm, 1, index, 0);
}
static void getMapValue(WrenVM* vm)
{
wrenGetMapValue(vm, 1, 2, 0);
}
WrenForeignMethodFn slotsBindMethod(const char* signature)
{
if (strcmp(signature, "static Slots.noSet") == 0) return noSet;
if (strcmp(signature, "static Slots.getSlots(_,_,_,_,_)") == 0) return getSlots;
if (strcmp(signature, "static Slots.setSlots(_,_,_,_,_)") == 0) return setSlots;
if (strcmp(signature, "static Slots.slotTypes(_,_,_,_,_,_,_,_)") == 0) return slotTypes;
if (strcmp(signature, "static Slots.ensure()") == 0) return ensure;
if (strcmp(signature, "static Slots.ensureOutsideForeign()") == 0) return ensureOutsideForeign;
if (strcmp(signature, "static Slots.getListCount(_)") == 0) return getListCount;
if (strcmp(signature, "static Slots.getListElement(_,_)") == 0) return getListElement;
if (strcmp(signature, "static Slots.getMapValue(_,_)") == 0) return getMapValue;
return NULL;
}
void slotsBindClass(const char* className, WrenForeignClassMethods* methods)
{
methods->allocate = foreignClassAllocate;
}