Added _containsKey() and _containsValue()

This commit is contained in:
2023-02-10 15:27:39 +00:00
parent 3ba2e420ea
commit 4fe57f9562
3 changed files with 148 additions and 13 deletions

View File

@@ -115,6 +115,121 @@ static int nativeConcat(Toy_Interpreter* interpreter, Toy_LiteralArray* argument
return -1; return -1;
} }
static int nativeContainsKey(Toy_Interpreter* interpreter, Toy_LiteralArray* arguments) {
//no arguments
if (arguments->count != 2) {
interpreter->errorOutput("Incorrect number of arguments to _containsKey\n");
return -1;
}
//get the args
Toy_Literal keyLiteral = 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 keyLiteralIdn = keyLiteral;
if (TOY_IS_IDENTIFIER(keyLiteral) && Toy_parseIdentifierToValue(interpreter, &keyLiteral)) {
Toy_freeLiteral(keyLiteralIdn);
}
//check type
if (!(/* TOY_IS_ARRAY(selfLiteral) || */ TOY_IS_DICTIONARY(selfLiteral) )) {
interpreter->errorOutput("Incorrect argument type passed to _containsKey\n");
Toy_freeLiteral(selfLiteral);
Toy_freeLiteral(keyLiteral);
return -1;
}
Toy_Literal resultLiteral = TOY_TO_BOOLEAN_LITERAL(false);
if (TOY_IS_DICTIONARY(selfLiteral) && Toy_existsLiteralDictionary( TOY_AS_DICTIONARY(selfLiteral), keyLiteral )) {
//return true of it contains the key
Toy_freeLiteral(resultLiteral);
resultLiteral = TOY_TO_BOOLEAN_LITERAL(true);
}
Toy_pushLiteralArray(&interpreter->stack, resultLiteral);
Toy_freeLiteral(resultLiteral);
Toy_freeLiteral(selfLiteral);
Toy_freeLiteral(keyLiteral);
return 1;
}
static int nativeContainsValue(Toy_Interpreter* interpreter, Toy_LiteralArray* arguments) {
//no arguments
if (arguments->count != 2) {
interpreter->errorOutput("Incorrect number of arguments to _containsValue\n");
return -1;
}
//get the args
Toy_Literal valueLiteral = 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 valueLiteralIdn = valueLiteral;
if (TOY_IS_IDENTIFIER(valueLiteral) && Toy_parseIdentifierToValue(interpreter, &valueLiteral)) {
Toy_freeLiteral(valueLiteralIdn);
}
//check type
if (!( TOY_IS_ARRAY(selfLiteral) || TOY_IS_DICTIONARY(selfLiteral) )) {
interpreter->errorOutput("Incorrect argument type passed to _containsValue\n");
Toy_freeLiteral(selfLiteral);
Toy_freeLiteral(valueLiteral);
return -1;
}
Toy_Literal resultLiteral = TOY_TO_BOOLEAN_LITERAL(false);
if (TOY_IS_DICTIONARY(selfLiteral)) {
for (int i = 0; i < TOY_AS_DICTIONARY(selfLiteral)->capacity; i++) {
if (!TOY_IS_NULL(TOY_AS_DICTIONARY(selfLiteral)->entries[i].key) && Toy_literalsAreEqual( TOY_AS_DICTIONARY(selfLiteral)->entries[i].value, valueLiteral )) {
//return true of it contains the value
Toy_freeLiteral(resultLiteral);
resultLiteral = TOY_TO_BOOLEAN_LITERAL(true);
break;
}
}
}
else if (TOY_IS_ARRAY(selfLiteral)) {
for (int i = 0; i < TOY_AS_ARRAY(selfLiteral)->count; i++) {
Toy_Literal indexLiteral = TOY_TO_INTEGER_LITERAL(i);
Toy_Literal elementLiteral = Toy_getLiteralArray(TOY_AS_ARRAY(selfLiteral), indexLiteral);
if (Toy_literalsAreEqual(elementLiteral, valueLiteral)) {
Toy_freeLiteral(indexLiteral);
Toy_freeLiteral(elementLiteral);
//return true of it contains the value
Toy_freeLiteral(resultLiteral);
resultLiteral = TOY_TO_BOOLEAN_LITERAL(true);
break;
}
Toy_freeLiteral(indexLiteral);
Toy_freeLiteral(elementLiteral);
}
}
Toy_pushLiteralArray(&interpreter->stack, resultLiteral);
Toy_freeLiteral(resultLiteral);
Toy_freeLiteral(selfLiteral);
Toy_freeLiteral(valueLiteral);
return 1;
}
static int nativeEvery(Toy_Interpreter* interpreter, Toy_LiteralArray* arguments) { static int nativeEvery(Toy_Interpreter* interpreter, Toy_LiteralArray* arguments) {
//no arguments //no arguments
if (arguments->count != 2) { if (arguments->count != 2) {
@@ -141,6 +256,7 @@ static int nativeEvery(Toy_Interpreter* interpreter, Toy_LiteralArray* arguments
if (!( TOY_IS_ARRAY(selfLiteral) || TOY_IS_DICTIONARY(selfLiteral) ) || !( TOY_IS_FUNCTION(fnLiteral) || TOY_IS_FUNCTION_NATIVE(fnLiteral) )) { 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"); interpreter->errorOutput("Incorrect argument type passed to _every\n");
Toy_freeLiteral(selfLiteral); Toy_freeLiteral(selfLiteral);
Toy_freeLiteral(fnLiteral);
return -1; return -1;
} }
@@ -227,7 +343,7 @@ static int nativeEvery(Toy_Interpreter* interpreter, Toy_LiteralArray* arguments
Toy_freeLiteral(fnLiteral); Toy_freeLiteral(fnLiteral);
Toy_freeLiteral(selfLiteral); Toy_freeLiteral(selfLiteral);
return 0; return 1;
} }
static int nativeForEach(Toy_Interpreter* interpreter, Toy_LiteralArray* arguments) { static int nativeForEach(Toy_Interpreter* interpreter, Toy_LiteralArray* arguments) {
@@ -256,6 +372,7 @@ static int nativeForEach(Toy_Interpreter* interpreter, Toy_LiteralArray* argumen
if (!( TOY_IS_ARRAY(selfLiteral) || TOY_IS_DICTIONARY(selfLiteral) ) || !( TOY_IS_FUNCTION(fnLiteral) || TOY_IS_FUNCTION_NATIVE(fnLiteral) )) { 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 _forEach\n"); interpreter->errorOutput("Incorrect argument type passed to _forEach\n");
Toy_freeLiteral(selfLiteral); Toy_freeLiteral(selfLiteral);
Toy_freeLiteral(fnLiteral);
return -1; return -1;
} }
@@ -424,6 +541,7 @@ static int nativeMap(Toy_Interpreter* interpreter, Toy_LiteralArray* arguments)
if (!( TOY_IS_ARRAY(selfLiteral) || TOY_IS_DICTIONARY(selfLiteral) ) || !( TOY_IS_FUNCTION(fnLiteral) || TOY_IS_FUNCTION_NATIVE(fnLiteral) )) { 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 _map\n"); interpreter->errorOutput("Incorrect argument type passed to _map\n");
Toy_freeLiteral(selfLiteral); Toy_freeLiteral(selfLiteral);
Toy_freeLiteral(fnLiteral);
return -1; return -1;
} }
@@ -532,6 +650,8 @@ static int nativeReduce(Toy_Interpreter* interpreter, Toy_LiteralArray* argument
if (!( TOY_IS_ARRAY(selfLiteral) || TOY_IS_DICTIONARY(selfLiteral) ) || !( TOY_IS_FUNCTION(fnLiteral) || TOY_IS_FUNCTION_NATIVE(fnLiteral) )) { 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 _reduce\n"); interpreter->errorOutput("Incorrect argument type passed to _reduce\n");
Toy_freeLiteral(selfLiteral); Toy_freeLiteral(selfLiteral);
Toy_freeLiteral(defaultLiteral);
Toy_freeLiteral(fnLiteral);
return -1; return -1;
} }
@@ -625,6 +745,7 @@ static int nativeSome(Toy_Interpreter* interpreter, Toy_LiteralArray* arguments)
if (!( TOY_IS_ARRAY(selfLiteral) || TOY_IS_DICTIONARY(selfLiteral) ) || !( TOY_IS_FUNCTION(fnLiteral) || TOY_IS_FUNCTION_NATIVE(fnLiteral) )) { 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"); interpreter->errorOutput("Incorrect argument type passed to _some\n");
Toy_freeLiteral(selfLiteral); Toy_freeLiteral(selfLiteral);
Toy_freeLiteral(fnLiteral);
return -1; return -1;
} }
@@ -711,7 +832,7 @@ static int nativeSome(Toy_Interpreter* interpreter, Toy_LiteralArray* arguments)
Toy_freeLiteral(fnLiteral); Toy_freeLiteral(fnLiteral);
Toy_freeLiteral(selfLiteral); Toy_freeLiteral(selfLiteral);
return 0; return 1;
} }
static int nativeToLower(Toy_Interpreter* interpreter, Toy_LiteralArray* arguments) { static int nativeToLower(Toy_Interpreter* interpreter, Toy_LiteralArray* arguments) {
@@ -1158,8 +1279,8 @@ int Toy_hookCompound(Toy_Interpreter* interpreter, Toy_Literal identifier, Toy_L
//build the natives list //build the natives list
Natives natives[] = { Natives natives[] = {
{"_concat", nativeConcat}, //array, dictionary, string {"_concat", nativeConcat}, //array, dictionary, string
// {"_containsKey", native}, //dictionary {"_containsKey", nativeContainsKey}, //dictionary
// {"_containsValue", native}, //array, dictionary {"_containsValue", nativeContainsValue}, //array, dictionary
{"_every", nativeEvery}, //array, dictionary {"_every", nativeEvery}, //array, dictionary
// {"_filter", native}, //array, dictionary // {"_filter", native}, //array, dictionary
{"_forEach", nativeForEach}, //array, dictionary {"_forEach", nativeForEach}, //array, dictionary

View File

@@ -3,13 +3,6 @@ import compound;
var a = [false, false, false]; var a = [false, false, false];
var d = ["one": false, "two": false]; var d = ["one": false, "two": false];
fn f(k, v) { return v; } print d.containsKey("one");
print d.containsKey("three");
print a.some(f);
print d.some(f);
a[1] = true;
d["two"] = true;
print a.some(f);
print d.some(f);

View File

@@ -46,6 +46,27 @@ import compound;
} }
//test containsKey
{
var d = ["one": 1, "two": 2];
assert d.containsKey("one") == true, "dictionary.containsKey() == true failed";
assert d.containsKey("three") == false, "dictionary.containsKey() == false failed";
}
//test containsValue
{
var a = [1, 2, 3];
var d = ["one": 1, "two": 2];
assert a.containsValue(1) == true, "array.containsValue() == true failed";
assert a.containsValue(5) == false, "array.containsValue() == false failed";
assert d.containsValue(1) == true, "dictionary.containsValue() == true failed";
assert d.containsValue(3) == false, "dictionary.containsValue() == false failed";
}
//test every //test every
{ {
var a = [1, 2, 3]; var a = [1, 2, 3];