Files
wren/test/api/slots.c
Damien Radtke cf258b9074 Add support for retrieving list values from a slot
This PR adds support for retrieving list information from a slot. Rather
than take the whole list, two different methods are provided for
retrieving a) the length of the list, and b) a specific value in the
list.
2016-05-19 14:11:48 -05:00

187 lines
4.6 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;
// TODO: Test wrenGetSlotForeign().
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) != 12.34) result = false;
if (strcmp(wrenGetSlotString(vm, 4), "str") != 0) result = false;
WrenValue* value = wrenGetSlotValue(vm, 5);
if (result)
{
// Otherwise, return the value so we can tell if we captured it correctly.
wrenSetSlotValue(vm, 0, value);
wrenReleaseValue(vm, value);
}
else
{
// If anything failed, return false.
wrenSetSlotBool(vm, 0, false);
}
}
static void setSlots(WrenVM* vm)
{
WrenValue* value = wrenGetSlotValue(vm, 1);
wrenSetSlotBool(vm, 1, true);
wrenSetSlotBytes(vm, 2, "by\0te", 5);
wrenSetSlotDouble(vm, 3, 12.34);
wrenSetSlotString(vm, 4, "str");
// TODO: wrenSetSlotNull().
// 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) != 12.34) result = false;
if (strcmp(wrenGetSlotString(vm, 4), "str") != 0) result = false;
if (result)
{
// Move the value into the return position.
wrenSetSlotValue(vm, 0, value);
wrenReleaseValue(vm, value);
}
else
{
// If anything failed, return false.
wrenSetSlotBool(vm, 0, false);
}
}
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_NULL &&
wrenGetSlotType(vm, 5) == WREN_TYPE_NUM &&
wrenGetSlotType(vm, 6) == WREN_TYPE_STRING &&
wrenGetSlotType(vm, 7) == 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 getListSize(WrenVM* vm)
{
wrenSetSlotDouble(vm, 0, wrenGetSlotListSize(vm, 1));
}
static void getListValue(WrenVM* vm)
{
int index = (int)wrenGetSlotDouble(vm, 2);
WrenValue* value = wrenGetSlotListValue(vm, 1, index);
wrenSetSlotValue(vm, 0, value);
wrenReleaseValue(vm, value);
}
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.getListSize(_)") == 0) return getListSize;
if (strcmp(signature, "static Slots.getListValue(_,_)") == 0) return getListValue;
return NULL;
}
void slotsBindClass(const char* className, WrenForeignClassMethods* methods)
{
methods->allocate = foreignClassAllocate;
}