Add C API functions for working with lists:

- wrenEnsureSlots()
  Lets you go the foreign slot stack to make room for a temporary work
  area.

- wrenSetSlotNewList()
  Creates a new empty list and stores it in a slot.

- wrenInsertInList()
  Takes a value from one slot and inserts it into the list in another.

Still need more functions like getting elements from a list, removing,
etc. but this at least lets you create, populate, and return lists from
foreign methods.
This commit is contained in:
Bob Nystrom
2015-12-16 16:28:26 -08:00
parent 7fcdcf2f1a
commit 6f37d379f4
9 changed files with 210 additions and 53 deletions
+46
View File
@@ -0,0 +1,46 @@
#include <string.h>
#include "lists.h"
static void newList(WrenVM* vm)
{
wrenSetSlotNewList(vm, 0);
}
// Helper function to store a double in a slot then insert it into the list at
// slot zero.
static void insertNumber(WrenVM* vm, int index, double value)
{
wrenSetSlotDouble(vm, 1, value);
wrenInsertInList(vm, 0, index, 1);
}
static void insert(WrenVM* vm)
{
wrenSetSlotNewList(vm, 0);
wrenEnsureSlots(vm, 2);
// Appending.
insertNumber(vm, 0, 1.0);
insertNumber(vm, 1, 2.0);
insertNumber(vm, 2, 3.0);
// Inserting.
insertNumber(vm, 0, 4.0);
insertNumber(vm, 1, 5.0);
insertNumber(vm, 2, 6.0);
// Negative indexes.
insertNumber(vm, -1, 7.0);
insertNumber(vm, -2, 8.0);
insertNumber(vm, -3, 9.0);
}
WrenForeignMethodFn listsBindMethod(const char* signature)
{
if (strcmp(signature, "static Lists.newList()") == 0) return newList;
if (strcmp(signature, "static Lists.insert()") == 0) return insert;
return NULL;
}
+3
View File
@@ -0,0 +1,3 @@
#include "wren.h"
WrenForeignMethodFn listsBindMethod(const char* signature);
+10
View File
@@ -0,0 +1,10 @@
class Lists {
foreign static newList()
foreign static insert()
}
var list = Lists.newList()
System.print(list is List) // expect: true
System.print(list.count) // expect: 0
System.print(Lists.insert()) // expect: [4, 5, 6, 1, 2, 3, 9, 8, 7]
+4
View File
@@ -7,6 +7,7 @@
#include "benchmark.h"
#include "call.h"
#include "foreign_class.h"
#include "lists.h"
#include "slots.h"
#include "value.h"
@@ -36,6 +37,9 @@ static WrenForeignMethodFn bindForeignMethod(
method = foreignClassBindMethod(fullName);
if (method != NULL) return method;
method = listsBindMethod(fullName);
if (method != NULL) return method;
method = slotsBindMethod(fullName);
if (method != NULL) return method;
+28
View File
@@ -1,3 +1,4 @@
#include <stdio.h>
#include <string.h>
#include "slots.h"
@@ -73,11 +74,38 @@ static void setSlots(WrenVM* vm)
}
}
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);
}
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.ensure()") == 0) return ensure;
return NULL;
}
+3 -2
View File
@@ -1,9 +1,8 @@
class Slots {
foreign static noSet
foreign static getSlots(bool, num, string, bytes, value)
foreign static setSlots(a, b, c, d)
foreign static ensure()
}
// If nothing is set in the return slot, it retains its previous value, the
@@ -14,3 +13,5 @@ var value = ["value"]
System.print(Slots.getSlots(true, "by\0te", 12.34, "str", value) == value) // expect: true
System.print(Slots.setSlots(value, 0, 0, 0) == value) // expect: true
System.print(Slots.ensure()) // expect: 1 -> 20 (190)