mirror of
https://github.com/krgamestudios/Toy.git
synced 2026-04-15 23:04:08 +10:00
Added _every() and _some()
This commit is contained in:
@@ -115,6 +115,121 @@ static int nativeConcat(Toy_Interpreter* interpreter, Toy_LiteralArray* argument
|
|||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int nativeEvery(Toy_Interpreter* interpreter, Toy_LiteralArray* arguments) {
|
||||||
|
//no arguments
|
||||||
|
if (arguments->count != 2) {
|
||||||
|
interpreter->errorOutput("Incorrect number of arguments to _every\n");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
//get the args
|
||||||
|
Toy_Literal fnLiteral = Toy_popLiteralArray(arguments);
|
||||||
|
Toy_Literal selfLiteral = Toy_popLiteralArray(arguments);
|
||||||
|
|
||||||
|
//parse to value if needed
|
||||||
|
Toy_Literal selfLiteralIdn = selfLiteral;
|
||||||
|
if (TOY_IS_IDENTIFIER(selfLiteral) && Toy_parseIdentifierToValue(interpreter, &selfLiteral)) {
|
||||||
|
Toy_freeLiteral(selfLiteralIdn);
|
||||||
|
}
|
||||||
|
|
||||||
|
Toy_Literal fnLiteralIdn = fnLiteral;
|
||||||
|
if (TOY_IS_IDENTIFIER(fnLiteral) && Toy_parseIdentifierToValue(interpreter, &fnLiteral)) {
|
||||||
|
Toy_freeLiteral(fnLiteralIdn);
|
||||||
|
}
|
||||||
|
|
||||||
|
//check type
|
||||||
|
if (!( TOY_IS_ARRAY(selfLiteral) || TOY_IS_DICTIONARY(selfLiteral) ) || !( TOY_IS_FUNCTION(fnLiteral) || TOY_IS_FUNCTION_NATIVE(fnLiteral) )) {
|
||||||
|
interpreter->errorOutput("Incorrect argument type passed to _every\n");
|
||||||
|
Toy_freeLiteral(selfLiteral);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
//call the given function on each element, based on the compound type
|
||||||
|
if (TOY_IS_ARRAY(selfLiteral)) {
|
||||||
|
bool result = true;
|
||||||
|
|
||||||
|
//
|
||||||
|
for (int i = 0; i < TOY_AS_ARRAY(selfLiteral)->count; i++) {
|
||||||
|
Toy_Literal indexLiteral = TOY_TO_INTEGER_LITERAL(i);
|
||||||
|
|
||||||
|
Toy_LiteralArray arguments;
|
||||||
|
Toy_initLiteralArray(&arguments);
|
||||||
|
Toy_pushLiteralArray(&arguments, TOY_AS_ARRAY(selfLiteral)->literals[i]);
|
||||||
|
Toy_pushLiteralArray(&arguments, indexLiteral);
|
||||||
|
|
||||||
|
Toy_LiteralArray returns;
|
||||||
|
Toy_initLiteralArray(&returns);
|
||||||
|
|
||||||
|
Toy_callLiteralFn(interpreter, fnLiteral, &arguments, &returns);
|
||||||
|
|
||||||
|
//grab the results
|
||||||
|
Toy_Literal lit = Toy_popLiteralArray(&returns);
|
||||||
|
|
||||||
|
Toy_freeLiteralArray(&arguments);
|
||||||
|
Toy_freeLiteralArray(&returns);
|
||||||
|
Toy_freeLiteral(indexLiteral);
|
||||||
|
|
||||||
|
//if not truthy
|
||||||
|
if (!TOY_IS_TRUTHY(lit)) {
|
||||||
|
Toy_freeLiteral(lit);
|
||||||
|
result = false;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
Toy_freeLiteral(lit);
|
||||||
|
}
|
||||||
|
|
||||||
|
Toy_Literal resultLiteral = TOY_TO_BOOLEAN_LITERAL(result);
|
||||||
|
Toy_pushLiteralArray(&interpreter->stack, resultLiteral);
|
||||||
|
Toy_freeLiteral(resultLiteral);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (TOY_IS_DICTIONARY(selfLiteral)) {
|
||||||
|
bool result = true;
|
||||||
|
|
||||||
|
for (int i = 0; i < TOY_AS_DICTIONARY(selfLiteral)->capacity; i++) {
|
||||||
|
//skip nulls
|
||||||
|
if (TOY_IS_NULL(TOY_AS_DICTIONARY(selfLiteral)->entries[i].key)) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
Toy_LiteralArray arguments;
|
||||||
|
Toy_initLiteralArray(&arguments);
|
||||||
|
Toy_pushLiteralArray(&arguments, TOY_AS_DICTIONARY(selfLiteral)->entries[i].value);
|
||||||
|
Toy_pushLiteralArray(&arguments, TOY_AS_DICTIONARY(selfLiteral)->entries[i].key);
|
||||||
|
|
||||||
|
Toy_LiteralArray returns;
|
||||||
|
Toy_initLiteralArray(&returns);
|
||||||
|
|
||||||
|
Toy_callLiteralFn(interpreter, fnLiteral, &arguments, &returns);
|
||||||
|
|
||||||
|
//grab the results
|
||||||
|
Toy_Literal lit = Toy_popLiteralArray(&returns);
|
||||||
|
|
||||||
|
Toy_freeLiteralArray(&arguments);
|
||||||
|
Toy_freeLiteralArray(&returns);
|
||||||
|
|
||||||
|
//if not truthy
|
||||||
|
if (!TOY_IS_TRUTHY(lit)) {
|
||||||
|
Toy_freeLiteral(lit);
|
||||||
|
result = false;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
Toy_freeLiteral(lit);
|
||||||
|
}
|
||||||
|
|
||||||
|
Toy_Literal resultLiteral = TOY_TO_BOOLEAN_LITERAL(result);
|
||||||
|
Toy_pushLiteralArray(&interpreter->stack, resultLiteral);
|
||||||
|
Toy_freeLiteral(resultLiteral);
|
||||||
|
}
|
||||||
|
|
||||||
|
Toy_freeLiteral(fnLiteral);
|
||||||
|
Toy_freeLiteral(selfLiteral);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
static int nativeForEach(Toy_Interpreter* interpreter, Toy_LiteralArray* arguments) {
|
static int nativeForEach(Toy_Interpreter* interpreter, Toy_LiteralArray* arguments) {
|
||||||
//no arguments
|
//no arguments
|
||||||
if (arguments->count != 2) {
|
if (arguments->count != 2) {
|
||||||
@@ -484,6 +599,121 @@ static int nativeReduce(Toy_Interpreter* interpreter, Toy_LiteralArray* argument
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int nativeSome(Toy_Interpreter* interpreter, Toy_LiteralArray* arguments) {
|
||||||
|
//no arguments
|
||||||
|
if (arguments->count != 2) {
|
||||||
|
interpreter->errorOutput("Incorrect number of arguments to _some\n");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
//get the args
|
||||||
|
Toy_Literal fnLiteral = Toy_popLiteralArray(arguments);
|
||||||
|
Toy_Literal selfLiteral = Toy_popLiteralArray(arguments);
|
||||||
|
|
||||||
|
//parse to value if needed
|
||||||
|
Toy_Literal selfLiteralIdn = selfLiteral;
|
||||||
|
if (TOY_IS_IDENTIFIER(selfLiteral) && Toy_parseIdentifierToValue(interpreter, &selfLiteral)) {
|
||||||
|
Toy_freeLiteral(selfLiteralIdn);
|
||||||
|
}
|
||||||
|
|
||||||
|
Toy_Literal fnLiteralIdn = fnLiteral;
|
||||||
|
if (TOY_IS_IDENTIFIER(fnLiteral) && Toy_parseIdentifierToValue(interpreter, &fnLiteral)) {
|
||||||
|
Toy_freeLiteral(fnLiteralIdn);
|
||||||
|
}
|
||||||
|
|
||||||
|
//check type
|
||||||
|
if (!( TOY_IS_ARRAY(selfLiteral) || TOY_IS_DICTIONARY(selfLiteral) ) || !( TOY_IS_FUNCTION(fnLiteral) || TOY_IS_FUNCTION_NATIVE(fnLiteral) )) {
|
||||||
|
interpreter->errorOutput("Incorrect argument type passed to _some\n");
|
||||||
|
Toy_freeLiteral(selfLiteral);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
//call the given function on each element, based on the compound type
|
||||||
|
if (TOY_IS_ARRAY(selfLiteral)) {
|
||||||
|
bool result = false;
|
||||||
|
|
||||||
|
//
|
||||||
|
for (int i = 0; i < TOY_AS_ARRAY(selfLiteral)->count; i++) {
|
||||||
|
Toy_Literal indexLiteral = TOY_TO_INTEGER_LITERAL(i);
|
||||||
|
|
||||||
|
Toy_LiteralArray arguments;
|
||||||
|
Toy_initLiteralArray(&arguments);
|
||||||
|
Toy_pushLiteralArray(&arguments, TOY_AS_ARRAY(selfLiteral)->literals[i]);
|
||||||
|
Toy_pushLiteralArray(&arguments, indexLiteral);
|
||||||
|
|
||||||
|
Toy_LiteralArray returns;
|
||||||
|
Toy_initLiteralArray(&returns);
|
||||||
|
|
||||||
|
Toy_callLiteralFn(interpreter, fnLiteral, &arguments, &returns);
|
||||||
|
|
||||||
|
//grab the results
|
||||||
|
Toy_Literal lit = Toy_popLiteralArray(&returns);
|
||||||
|
|
||||||
|
Toy_freeLiteralArray(&arguments);
|
||||||
|
Toy_freeLiteralArray(&returns);
|
||||||
|
Toy_freeLiteral(indexLiteral);
|
||||||
|
|
||||||
|
//if not truthy
|
||||||
|
if (TOY_IS_TRUTHY(lit)) {
|
||||||
|
Toy_freeLiteral(lit);
|
||||||
|
result = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
Toy_freeLiteral(lit);
|
||||||
|
}
|
||||||
|
|
||||||
|
Toy_Literal resultLiteral = TOY_TO_BOOLEAN_LITERAL(result);
|
||||||
|
Toy_pushLiteralArray(&interpreter->stack, resultLiteral);
|
||||||
|
Toy_freeLiteral(resultLiteral);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (TOY_IS_DICTIONARY(selfLiteral)) {
|
||||||
|
bool result = false;
|
||||||
|
|
||||||
|
for (int i = 0; i < TOY_AS_DICTIONARY(selfLiteral)->capacity; i++) {
|
||||||
|
//skip nulls
|
||||||
|
if (TOY_IS_NULL(TOY_AS_DICTIONARY(selfLiteral)->entries[i].key)) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
Toy_LiteralArray arguments;
|
||||||
|
Toy_initLiteralArray(&arguments);
|
||||||
|
Toy_pushLiteralArray(&arguments, TOY_AS_DICTIONARY(selfLiteral)->entries[i].value);
|
||||||
|
Toy_pushLiteralArray(&arguments, TOY_AS_DICTIONARY(selfLiteral)->entries[i].key);
|
||||||
|
|
||||||
|
Toy_LiteralArray returns;
|
||||||
|
Toy_initLiteralArray(&returns);
|
||||||
|
|
||||||
|
Toy_callLiteralFn(interpreter, fnLiteral, &arguments, &returns);
|
||||||
|
|
||||||
|
//grab the results
|
||||||
|
Toy_Literal lit = Toy_popLiteralArray(&returns);
|
||||||
|
|
||||||
|
Toy_freeLiteralArray(&arguments);
|
||||||
|
Toy_freeLiteralArray(&returns);
|
||||||
|
|
||||||
|
//if not truthy
|
||||||
|
if (TOY_IS_TRUTHY(lit)) {
|
||||||
|
Toy_freeLiteral(lit);
|
||||||
|
result = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
Toy_freeLiteral(lit);
|
||||||
|
}
|
||||||
|
|
||||||
|
Toy_Literal resultLiteral = TOY_TO_BOOLEAN_LITERAL(result);
|
||||||
|
Toy_pushLiteralArray(&interpreter->stack, resultLiteral);
|
||||||
|
Toy_freeLiteral(resultLiteral);
|
||||||
|
}
|
||||||
|
|
||||||
|
Toy_freeLiteral(fnLiteral);
|
||||||
|
Toy_freeLiteral(selfLiteral);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
static int nativeToLower(Toy_Interpreter* interpreter, Toy_LiteralArray* arguments) {
|
static int nativeToLower(Toy_Interpreter* interpreter, Toy_LiteralArray* arguments) {
|
||||||
//no arguments
|
//no arguments
|
||||||
if (arguments->count != 1) {
|
if (arguments->count != 1) {
|
||||||
@@ -930,7 +1160,7 @@ int Toy_hookCompound(Toy_Interpreter* interpreter, Toy_Literal identifier, Toy_L
|
|||||||
{"_concat", nativeConcat}, //array, dictionary, string
|
{"_concat", nativeConcat}, //array, dictionary, string
|
||||||
// {"_containsKey", native}, //dictionary
|
// {"_containsKey", native}, //dictionary
|
||||||
// {"_containsValue", native}, //array, dictionary
|
// {"_containsValue", native}, //array, dictionary
|
||||||
// {"_every", native}, //array, dictionary, string
|
{"_every", nativeEvery}, //array, dictionary
|
||||||
// {"_filter", native}, //array, dictionary
|
// {"_filter", native}, //array, dictionary
|
||||||
{"_forEach", nativeForEach}, //array, dictionary
|
{"_forEach", nativeForEach}, //array, dictionary
|
||||||
{"_getKeys", nativeGetKeys}, //dictionary
|
{"_getKeys", nativeGetKeys}, //dictionary
|
||||||
@@ -941,7 +1171,7 @@ int Toy_hookCompound(Toy_Interpreter* interpreter, Toy_Literal identifier, Toy_L
|
|||||||
{"_reduce", nativeReduce}, //array, dictionary
|
{"_reduce", nativeReduce}, //array, dictionary
|
||||||
// {"_remove", native}, //array, dictionary
|
// {"_remove", native}, //array, dictionary
|
||||||
// {"_replace", native}, //string
|
// {"_replace", native}, //string
|
||||||
// {"_some", native}, //array, dictionary, string
|
{"_some", nativeSome}, //array, dictionary
|
||||||
// {"_sort", native}, //array
|
// {"_sort", native}, //array
|
||||||
{"_toLower", nativeToLower}, //string
|
{"_toLower", nativeToLower}, //string
|
||||||
{"_toString", nativeToString}, //array, dictionary
|
{"_toString", nativeToString}, //array, dictionary
|
||||||
|
|||||||
@@ -1,2 +1,15 @@
|
|||||||
/*
|
import compound;
|
||||||
|
|
||||||
|
var a = [false, false, false];
|
||||||
|
var d = ["one": false, "two": false];
|
||||||
|
|
||||||
|
fn f(k, v) { return v; }
|
||||||
|
|
||||||
|
print a.some(f);
|
||||||
|
print d.some(f);
|
||||||
|
|
||||||
|
a[1] = true;
|
||||||
|
d["two"] = true;
|
||||||
|
|
||||||
|
print a.some(f);
|
||||||
|
print d.some(f);
|
||||||
|
|||||||
@@ -72,7 +72,7 @@ void Toy_freeLiteral(Toy_Literal literal) {
|
|||||||
|
|
||||||
bool Toy_private_isTruthy(Toy_Literal x) {
|
bool Toy_private_isTruthy(Toy_Literal x) {
|
||||||
if (TOY_IS_NULL(x)) {
|
if (TOY_IS_NULL(x)) {
|
||||||
fprintf(stderr, TOY_CC_ERROR "TOY_CC_ERROR: Null is neither true nor false\n" TOY_CC_RESET);
|
fprintf(stderr, TOY_CC_ERROR "Null is neither true nor false\n" TOY_CC_RESET);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -228,7 +228,7 @@ Toy_Literal Toy_copyLiteral(Toy_Literal original) {
|
|||||||
return original;
|
return original;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
fprintf(stderr, TOY_CC_ERROR "TOY_CC_ERROR: Can't copy that literal type: %d\n" TOY_CC_RESET, original.type);
|
fprintf(stderr, TOY_CC_ERROR "Can't copy that literal type: %d\n" TOY_CC_RESET, original.type);
|
||||||
return TOY_TO_NULL_LITERAL;
|
return TOY_TO_NULL_LITERAL;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -45,6 +45,34 @@ import compound;
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//test every
|
||||||
|
{
|
||||||
|
var a = [1, 2, 3];
|
||||||
|
var d = ["one": 1, "two": 2];
|
||||||
|
|
||||||
|
var counter = 0;
|
||||||
|
fn f(k, v) {
|
||||||
|
counter++;
|
||||||
|
return v;
|
||||||
|
}
|
||||||
|
|
||||||
|
assert a.every(f) == true, "array.every() == true failed";
|
||||||
|
assert d.every(f) == true, "dictionary.every() == true failed";
|
||||||
|
|
||||||
|
assert counter == 5, "Unexpected number of calls for _every() == true";
|
||||||
|
|
||||||
|
counter = 0;
|
||||||
|
a[1] = false;
|
||||||
|
d["two"] = false;
|
||||||
|
|
||||||
|
assert a.every(f) == false, "array.every() == false failed";
|
||||||
|
assert d.every(f) == false, "dictionary.every() == false failed";
|
||||||
|
|
||||||
|
assert counter == 4, "Unexpected number of calls for _every() == false";
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
//test forEach
|
//test forEach
|
||||||
{
|
{
|
||||||
var counter = 0;
|
var counter = 0;
|
||||||
@@ -65,6 +93,7 @@ import compound;
|
|||||||
assert counter == 4, "forEach ran an unusual number of times";
|
assert counter == 4, "forEach ran an unusual number of times";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
//test getKeys
|
//test getKeys
|
||||||
{
|
{
|
||||||
var d = ["foo": 1, "bar": 2];
|
var d = ["foo": 1, "bar": 2];
|
||||||
@@ -127,6 +156,33 @@ import compound;
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//test some
|
||||||
|
{
|
||||||
|
var a = [false, false, false];
|
||||||
|
var d = ["one": false, "two": false];
|
||||||
|
|
||||||
|
var counter = 0;
|
||||||
|
fn f(k, v) {
|
||||||
|
counter++;
|
||||||
|
return v;
|
||||||
|
}
|
||||||
|
|
||||||
|
assert a.some(f) == false, "array.some() == false failed";
|
||||||
|
assert d.some(f) == false, "dictionary.some() == false failed";
|
||||||
|
|
||||||
|
assert counter == 5, "Unexpected number of calls for _some() == false";
|
||||||
|
|
||||||
|
counter = 0;
|
||||||
|
a[1] = true;
|
||||||
|
d["two"] = true;
|
||||||
|
|
||||||
|
assert a.some(f) == true, "array.some() == true failed";
|
||||||
|
assert d.some(f) == true, "dictionary.some() == true failed";
|
||||||
|
|
||||||
|
assert counter == 4, "Unexpected number of calls for _some() == true";
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
//test toLower
|
//test toLower
|
||||||
{
|
{
|
||||||
assert "Hello World".toLower() == "hello world", "_toLower() failed";
|
assert "Hello World".toLower() == "hello world", "_toLower() failed";
|
||||||
|
|||||||
Reference in New Issue
Block a user