mirror of
https://github.com/wren-lang/wren.git
synced 2026-01-11 06:08:41 +01:00
Functions for operating on Maps from C (#725)
new API functions for maps: wrenSetSlotNewMap wrenGetMapCount wrenGetMapContainsKey wrenGetMapValue wrenSetMapValue wrenRemoveMapValue
This commit is contained in:
@ -40,6 +40,9 @@ WrenForeignMethodFn APITest_bindForeignMethod(
|
||||
method = listsBindMethod(fullName);
|
||||
if (method != NULL) return method;
|
||||
|
||||
method = mapsBindMethod(fullName);
|
||||
if (method != NULL) return method;
|
||||
|
||||
method = newVMBindMethod(fullName);
|
||||
if (method != NULL) return method;
|
||||
|
||||
|
||||
@ -16,6 +16,7 @@
|
||||
#include "foreign_class.h"
|
||||
#include "handle.h"
|
||||
#include "lists.h"
|
||||
#include "maps.h"
|
||||
#include "new_vm.h"
|
||||
#include "reset_stack_after_call_abort.h"
|
||||
#include "reset_stack_after_foreign_construct.h"
|
||||
|
||||
130
test/api/maps.c
Normal file
130
test/api/maps.c
Normal file
@ -0,0 +1,130 @@
|
||||
#include <string.h>
|
||||
|
||||
#include "maps.h"
|
||||
|
||||
static void newMap(WrenVM* vm)
|
||||
{
|
||||
wrenSetSlotNewMap(vm, 0);
|
||||
}
|
||||
|
||||
static void invalidInsert(WrenVM* vm)
|
||||
{
|
||||
wrenSetSlotNewMap(vm, 0);
|
||||
|
||||
wrenEnsureSlots(vm, 3);
|
||||
// Foreign Class is in slot 1
|
||||
wrenSetSlotString(vm, 2, "England");
|
||||
wrenSetMapValue(vm, 0, 1, 2); // expect this to cause errors
|
||||
}
|
||||
|
||||
static void insert(WrenVM* vm)
|
||||
{
|
||||
wrenSetSlotNewMap(vm, 0);
|
||||
|
||||
wrenEnsureSlots(vm, 3);
|
||||
|
||||
// Insert String
|
||||
wrenSetSlotString(vm, 1, "England");
|
||||
wrenSetSlotString(vm, 2, "London");
|
||||
wrenSetMapValue(vm, 0, 1, 2);
|
||||
|
||||
// Insert Double
|
||||
wrenSetSlotDouble(vm, 1, 1.0);
|
||||
wrenSetSlotDouble(vm, 2, 42.0);
|
||||
wrenSetMapValue(vm, 0, 1, 2);
|
||||
|
||||
// Insert Boolean
|
||||
wrenSetSlotBool(vm, 1, false);
|
||||
wrenSetSlotBool(vm, 2, true);
|
||||
wrenSetMapValue(vm, 0, 1, 2);
|
||||
|
||||
// Insert Null
|
||||
wrenSetSlotNull(vm, 1);
|
||||
wrenSetSlotNull(vm, 2);
|
||||
wrenSetMapValue(vm, 0, 1, 2);
|
||||
|
||||
// Insert List
|
||||
wrenSetSlotString(vm, 1, "Empty");
|
||||
wrenSetSlotNewList(vm, 2);
|
||||
wrenSetMapValue(vm, 0, 1, 2);
|
||||
}
|
||||
|
||||
static void remove(WrenVM* vm)
|
||||
{
|
||||
wrenEnsureSlots(vm, 3);
|
||||
|
||||
wrenSetSlotString(vm, 2, "key");
|
||||
wrenRemoveMapValue(vm, 1, 2, 0);
|
||||
}
|
||||
|
||||
static void countWren(WrenVM* vm)
|
||||
{
|
||||
int count = wrenGetMapCount(vm, 1);
|
||||
wrenSetSlotDouble(vm, 0, count);
|
||||
}
|
||||
|
||||
static void countAPI(WrenVM* vm)
|
||||
{
|
||||
insert(vm);
|
||||
int count = wrenGetMapCount(vm, 0);
|
||||
wrenSetSlotDouble(vm, 0, count);
|
||||
}
|
||||
|
||||
static void containsWren(WrenVM* vm)
|
||||
{
|
||||
bool result = wrenGetMapContainsKey(vm, 1, 2);
|
||||
wrenSetSlotBool(vm, 0, result);
|
||||
}
|
||||
|
||||
|
||||
static void containsAPI(WrenVM* vm)
|
||||
{
|
||||
insert(vm);
|
||||
|
||||
wrenEnsureSlots(vm, 1);
|
||||
wrenSetSlotString(vm, 1, "England");
|
||||
|
||||
bool result = wrenGetMapContainsKey(vm, 0, 1);
|
||||
wrenSetSlotBool(vm, 0, result);
|
||||
}
|
||||
|
||||
static void containsAPIFalse(WrenVM* vm)
|
||||
{
|
||||
insert(vm);
|
||||
|
||||
wrenEnsureSlots(vm, 1);
|
||||
wrenSetSlotString(vm, 1, "DefinitelyNotARealKey");
|
||||
|
||||
bool result = wrenGetMapContainsKey(vm, 0, 1);
|
||||
wrenSetSlotBool(vm, 0, result);
|
||||
}
|
||||
|
||||
|
||||
WrenForeignMethodFn mapsBindMethod(const char* signature)
|
||||
{
|
||||
if (strcmp(signature, "static Maps.newMap()") == 0) return newMap;
|
||||
if (strcmp(signature, "static Maps.insert()") == 0) return insert;
|
||||
if (strcmp(signature, "static Maps.remove(_)") == 0) return remove;
|
||||
if (strcmp(signature, "static Maps.count(_)") == 0) return countWren;
|
||||
if (strcmp(signature, "static Maps.count()") == 0) return countAPI;
|
||||
if (strcmp(signature, "static Maps.contains()") == 0) return containsAPI;
|
||||
if (strcmp(signature, "static Maps.containsFalse()") == 0) return containsAPIFalse;
|
||||
if (strcmp(signature, "static Maps.contains(_,_)") == 0) return containsWren;
|
||||
if (strcmp(signature, "static Maps.invalidInsert(_)") == 0) return invalidInsert;
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void foreignAllocate(WrenVM* vm) {
|
||||
wrenSetSlotNewForeign(vm, 0, 0, 0);
|
||||
}
|
||||
|
||||
void mapBindClass(
|
||||
const char* className, WrenForeignClassMethods* methods)
|
||||
{
|
||||
if (strcmp(className, "ForeignClass") == 0)
|
||||
{
|
||||
methods->allocate = foreignAllocate;
|
||||
return;
|
||||
}
|
||||
}
|
||||
5
test/api/maps.h
Normal file
5
test/api/maps.h
Normal file
@ -0,0 +1,5 @@
|
||||
#include "wren.h"
|
||||
|
||||
WrenForeignMethodFn mapsBindMethod(const char* signature);
|
||||
void mapBindClass(
|
||||
const char* className, WrenForeignClassMethods* methods);
|
||||
68
test/api/maps.wren
Normal file
68
test/api/maps.wren
Normal file
@ -0,0 +1,68 @@
|
||||
class ForeignClass {
|
||||
construct new() {}
|
||||
}
|
||||
|
||||
class Maps {
|
||||
foreign static newMap()
|
||||
foreign static insert()
|
||||
foreign static contains(map, key)
|
||||
foreign static contains()
|
||||
foreign static containsFalse()
|
||||
foreign static count()
|
||||
foreign static count(map)
|
||||
foreign static remove(map)
|
||||
foreign static invalidInsert(obj)
|
||||
}
|
||||
|
||||
// map new + get/set API
|
||||
|
||||
var map = Maps.newMap()
|
||||
System.print(map is Map) // expect: true
|
||||
System.print(map.count) // expect: 0
|
||||
|
||||
var data = Maps.insert()
|
||||
System.print(data["England"]) // expect: London
|
||||
System.print(data["Empty"]) // expect: []
|
||||
System.print(data[1.0]) // expect: 42
|
||||
System.print(data[false]) // expect: true
|
||||
System.print(data[null]) // expect: null
|
||||
|
||||
// remove API
|
||||
|
||||
var removed = Maps.remove({ "key":"value", "other":"data" })
|
||||
System.print(removed) // expect: value
|
||||
|
||||
var removedNone = Maps.remove({})
|
||||
System.print(removedNone) // expect: null
|
||||
|
||||
// count API
|
||||
|
||||
var countMap = { "key":"value", "other":"data", 4:"number key" }
|
||||
System.print(Maps.count(countMap)) // expect: 3
|
||||
Maps.remove(countMap) //remove using API
|
||||
System.print(Maps.count(countMap)) // expect: 2
|
||||
countMap.remove("other") //remove wren side
|
||||
System.print(Maps.count(countMap)) // expect: 1
|
||||
|
||||
var countAPI = Maps.count()
|
||||
System.print(countAPI) // expect: 5
|
||||
|
||||
//contains key API
|
||||
|
||||
var containsMap = { "key":"value", "other":"data", 4:"number key" }
|
||||
System.print(Maps.contains(containsMap, "key")) // expect: true
|
||||
System.print(Maps.contains(containsMap, "fake")) // expect: false
|
||||
System.print(Maps.contains(containsMap, "other")) // expect: true
|
||||
|
||||
Maps.remove(containsMap) //remove using API
|
||||
System.print(Maps.contains(containsMap, "key")) // expect: false
|
||||
|
||||
containsMap.remove("other") //remove wren side
|
||||
System.print(Maps.contains(containsMap, "other")) // expect: false
|
||||
|
||||
System.print(Maps.contains()) // expect: true
|
||||
System.print(Maps.containsFalse()) // expect: false
|
||||
|
||||
//
|
||||
|
||||
Maps.invalidInsert(ForeignClass.new()) // expect runtime error: Key must be a value type.
|
||||
@ -82,10 +82,11 @@ static void slotTypes(WrenVM* vm)
|
||||
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;
|
||||
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);
|
||||
}
|
||||
@ -166,16 +167,22 @@ static void getListElement(WrenVM* vm)
|
||||
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.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;
|
||||
}
|
||||
|
||||
@ -2,11 +2,12 @@ class Slots {
|
||||
foreign static noSet
|
||||
foreign static getSlots(bool, num, string, bytes, value)
|
||||
foreign static setSlots(a, b, c, d, e)
|
||||
foreign static slotTypes(bool, foreignObj, list, nullObj, num, string, unknown)
|
||||
foreign static slotTypes(bool, foreignObj, list, map, nullObj, num, string, unknown)
|
||||
foreign static ensure()
|
||||
foreign static ensureOutsideForeign()
|
||||
foreign static getListCount(list)
|
||||
foreign static getListElement(list, index)
|
||||
foreign static getMapValue(map, key)
|
||||
}
|
||||
|
||||
foreign class ForeignType {
|
||||
@ -24,7 +25,7 @@ System.print(Slots.getSlots(true, "by\0te", 1.5, "str", value) == value)
|
||||
System.print(Slots.setSlots(value, 0, 0, 0, 0) == value)
|
||||
// expect: true
|
||||
|
||||
System.print(Slots.slotTypes(false, ForeignType.new(), [], null, 1.2, "str", 1..2))
|
||||
System.print(Slots.slotTypes(false, ForeignType.new(), [], {}, null, 1.2, "str", 1..2))
|
||||
// expect: true
|
||||
|
||||
System.print(Slots.ensure())
|
||||
@ -37,3 +38,14 @@ var ducks = ["Huey", "Dewey", "Louie"]
|
||||
System.print(Slots.getListCount(ducks)) // expect: 3
|
||||
System.print(Slots.getListElement(ducks, 0)) // expect: Huey
|
||||
System.print(Slots.getListElement(ducks, 1)) // expect: Dewey
|
||||
|
||||
var capitals = {
|
||||
"England": "London",
|
||||
"Scotland": "Edinburgh",
|
||||
"Wales": "Cardiff",
|
||||
"N. Ireland": "Belfast"
|
||||
}
|
||||
|
||||
System.print(Slots.getMapValue(capitals, "England")) // expect: London
|
||||
System.print(Slots.getMapValue(capitals, "Wales")) // expect: Cardiff
|
||||
System.print(Slots.getMapValue(capitals, "S. Ireland")) // expect: null
|
||||
|
||||
Reference in New Issue
Block a user