1
0
forked from Mirror/wren

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.
This commit is contained in:
Damien Radtke
2016-05-19 13:26:01 -05:00
parent befe90501b
commit cf258b9074
5 changed files with 49 additions and 1 deletions

View File

@ -16,3 +16,4 @@ Evan Hahn <me@evanhahn.com>
Starbeamrainbowlabs <contact@starbeamrainbowlabs.com>
Alexander Roper <minirop@gmail.com>
Will Speak <will@willspeak.me>
Damien Radtke <damienradtke@gmail.com>

View File

@ -345,6 +345,12 @@ double wrenGetSlotDouble(WrenVM* vm, int slot);
// foreign class.
void* wrenGetSlotForeign(WrenVM* vm, int slot);
// Returns the size of the list stored in [slot].
int wrenGetSlotListSize(WrenVM* vm, int slot);
// Reads a value from the list in [slot].
WrenValue* wrenGetSlotListValue(WrenVM* vm, int slot, int index);
// Reads a string from [slot].
//
// The memory for the returned string is owned by Wren. You can inspect it

View File

@ -1547,6 +1547,26 @@ void* wrenGetSlotForeign(WrenVM* vm, int slot)
return AS_FOREIGN(vm->apiStack[slot])->data;
}
int wrenGetSlotListSize(WrenVM* vm, int slot)
{
validateApiSlot(vm, slot);
ASSERT(IS_LIST(vm->apiStack[slot]),
"Slot must hold a list instance.");
ValueBuffer elements = AS_LIST(vm->apiStack[slot])->elements;
return elements.count;
}
WrenValue* wrenGetSlotListValue(WrenVM* vm, int slot, int index)
{
validateApiSlot(vm, slot);
ASSERT(IS_LIST(vm->apiStack[slot]),
"Slot must hold a list instance.");
ValueBuffer elements = AS_LIST(vm->apiStack[slot])->elements;
return wrenCaptureValue(vm, elements.data[index]);
}
const char* wrenGetSlotString(WrenVM* vm, int slot)
{
validateApiSlot(vm, slot);

View File

@ -153,6 +153,19 @@ 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;
@ -161,6 +174,8 @@ WrenForeignMethodFn slotsBindMethod(const char* signature)
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;
}
@ -168,4 +183,4 @@ WrenForeignMethodFn slotsBindMethod(const char* signature)
void slotsBindClass(const char* className, WrenForeignClassMethods* methods)
{
methods->allocate = foreignClassAllocate;
}
}

View File

@ -5,6 +5,8 @@ class Slots {
foreign static slotTypes(bool, foreignObj, list, nullObj, num, string, unknown)
foreign static ensure()
foreign static ensureOutsideForeign()
foreign static getListSize(list)
foreign static getListValue(list, index)
}
foreign class ForeignType {
@ -30,3 +32,7 @@ System.print(Slots.ensure())
System.print(Slots.ensureOutsideForeign())
// expect: 0 -> 20 (190)
var ducks = ["Huey", "Dewey", "Louie"]
System.print(Slots.getListSize(ducks)) // expect: 3
System.print(Slots.getListValue(ducks, 1)) // expect: Dewey