From 7f0f17b6e043c739b66e14bf682d876749ee84a5 Mon Sep 17 00:00:00 2001 From: Kayne Ruse Date: Mon, 20 Feb 2023 06:11:30 +0000 Subject: [PATCH] Patched up failures from Toy_parseIdentifierToValue I really don't like that function - it needs to be replaced. --- repl/lib_runner.c | 42 +++++++++++ repl/lib_standard.c | 116 +++++++++++++++++++++++++++++- source/toy_builtin.c | 110 +++++++++++++++++++++++++++++ source/toy_interpreter.c | 149 ++++++++++++++++++++++++++++++++++++++- 4 files changed, 411 insertions(+), 6 deletions(-) diff --git a/repl/lib_runner.c b/repl/lib_runner.c index 49f177a..4b8ef80 100644 --- a/repl/lib_runner.c +++ b/repl/lib_runner.c @@ -33,6 +33,11 @@ static int nativeLoadScript(Toy_Interpreter* interpreter, Toy_LiteralArray* argu Toy_freeLiteral(drivePathLiteralIdn); } + if (TOY_IS_IDENTIFIER(drivePathLiteral)) { + Toy_freeLiteral(drivePathLiteral); + return -1; + } + Toy_Literal filePathLiteral = Toy_getFilePathLiteral(interpreter, &drivePathLiteral); if (TOY_IS_NULL(filePathLiteral)) { @@ -103,6 +108,11 @@ static int nativeLoadScriptBytecode(Toy_Interpreter* interpreter, Toy_LiteralArr Toy_freeLiteral(drivePathLiteralIdn); } + if (TOY_IS_IDENTIFIER(drivePathLiteral)) { + Toy_freeLiteral(drivePathLiteral); + return -1; + } + Toy_RefString* drivePath = Toy_copyRefString(TOY_AS_STRING(drivePathLiteral)); //get the drive and path as a string (can't trust that pesky strtok - custom split) TODO: move this to refstring library @@ -213,6 +223,11 @@ static int nativeRunScript(Toy_Interpreter* interpreter, Toy_LiteralArray* argum Toy_freeLiteral(runnerIdn); } + if (TOY_IS_IDENTIFIER(runnerLiteral)) { + Toy_freeLiteral(runnerLiteral); + return -1; + } + if (TOY_GET_OPAQUE_TAG(runnerLiteral) != TOY_OPAQUE_TAG_RUNNER) { interpreter->errorOutput("Unrecognized opaque literal in runScript\n"); return -1; @@ -260,6 +275,12 @@ static int nativeGetScriptVar(Toy_Interpreter* interpreter, Toy_LiteralArray* ar Toy_freeLiteral(runnerIdn); } + if (TOY_IS_IDENTIFIER(varName) || TOY_IS_IDENTIFIER(runnerLiteral)) { + Toy_freeLiteral(varName); + Toy_freeLiteral(runnerLiteral); + return -1; + } + if (TOY_GET_OPAQUE_TAG(runnerLiteral) != TOY_OPAQUE_TAG_RUNNER) { interpreter->errorOutput("Unrecognized opaque literal in getScriptVar\n"); return -1; @@ -332,6 +353,12 @@ static int nativeCallScriptFn(Toy_Interpreter* interpreter, Toy_LiteralArray* ar Toy_freeLiteral(runnerIdn); } + if (TOY_IS_IDENTIFIER(varName) || TOY_IS_IDENTIFIER(runnerLiteral)) { + Toy_freeLiteral(varName); + Toy_freeLiteral(runnerLiteral); + return -1; + } + if (TOY_GET_OPAQUE_TAG(runnerLiteral) != TOY_OPAQUE_TAG_RUNNER) { interpreter->errorOutput("Unrecognized opaque literal in callScriptFn\n"); return -1; @@ -401,6 +428,11 @@ static int nativeResetScript(Toy_Interpreter* interpreter, Toy_LiteralArray* arg Toy_freeLiteral(runnerIdn); } + if (TOY_IS_IDENTIFIER(runnerLiteral)) { + Toy_freeLiteral(runnerLiteral); + return -1; + } + if (TOY_GET_OPAQUE_TAG(runnerLiteral) != TOY_OPAQUE_TAG_RUNNER) { interpreter->errorOutput("Unrecognized opaque literal in resetScript\n"); return -1; @@ -437,6 +469,11 @@ static int nativeFreeScript(Toy_Interpreter* interpreter, Toy_LiteralArray* argu Toy_freeLiteral(runnerIdn); } + if (TOY_IS_IDENTIFIER(runnerLiteral)) { + Toy_freeLiteral(runnerLiteral); + return -1; + } + if (TOY_GET_OPAQUE_TAG(runnerLiteral) != TOY_OPAQUE_TAG_RUNNER) { interpreter->errorOutput("Unrecognized opaque literal in freeScript\n"); return -1; @@ -471,6 +508,11 @@ static int nativeCheckScriptDirty(Toy_Interpreter* interpreter, Toy_LiteralArray Toy_freeLiteral(runnerIdn); } + if (TOY_IS_IDENTIFIER(runnerLiteral)) { + Toy_freeLiteral(runnerLiteral); + return -1; + } + if (TOY_GET_OPAQUE_TAG(runnerLiteral) != TOY_OPAQUE_TAG_RUNNER) { interpreter->errorOutput("Unrecognized opaque literal in checkScriptDirty\n"); return -1; diff --git a/repl/lib_standard.c b/repl/lib_standard.c index 92dfb90..d7d5a8c 100644 --- a/repl/lib_standard.c +++ b/repl/lib_standard.c @@ -54,6 +54,12 @@ static int nativeConcat(Toy_Interpreter* interpreter, Toy_LiteralArray* argument Toy_freeLiteral(otherLiteralIdn); } + if (TOY_IS_IDENTIFIER(selfLiteral) || TOY_IS_IDENTIFIER(otherLiteral)) { + Toy_freeLiteral(selfLiteral); + Toy_freeLiteral(otherLiteral); + return -1; + } + //for each self type if (TOY_IS_ARRAY(selfLiteral)) { if (!TOY_IS_ARRAY(otherLiteral)) { @@ -164,6 +170,12 @@ static int nativeContainsKey(Toy_Interpreter* interpreter, Toy_LiteralArray* arg Toy_freeLiteral(keyLiteralIdn); } + if (TOY_IS_IDENTIFIER(selfLiteral) || TOY_IS_IDENTIFIER(keyLiteral)) { + Toy_freeLiteral(selfLiteral); + Toy_freeLiteral(keyLiteral); + return -1; + } + //check type if (!(/* TOY_IS_ARRAY(selfLiteral) || */ TOY_IS_DICTIONARY(selfLiteral) )) { interpreter->errorOutput("Incorrect argument type passed to containsKey\n"); @@ -209,6 +221,12 @@ static int nativeContainsValue(Toy_Interpreter* interpreter, Toy_LiteralArray* a Toy_freeLiteral(valueLiteralIdn); } + if (TOY_IS_IDENTIFIER(selfLiteral) || TOY_IS_IDENTIFIER(valueLiteral)) { + Toy_freeLiteral(selfLiteral); + Toy_freeLiteral(valueLiteral); + return -1; + } + //check type if (!( TOY_IS_ARRAY(selfLiteral) || TOY_IS_DICTIONARY(selfLiteral) )) { interpreter->errorOutput("Incorrect argument type passed to containsValue\n"); @@ -279,6 +297,12 @@ static int nativeEvery(Toy_Interpreter* interpreter, Toy_LiteralArray* arguments Toy_freeLiteral(fnLiteralIdn); } + if (TOY_IS_IDENTIFIER(selfLiteral) || TOY_IS_IDENTIFIER(fnLiteral)) { + Toy_freeLiteral(selfLiteral); + Toy_freeLiteral(fnLiteral); + return -1; + } + //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"); @@ -395,6 +419,12 @@ static int nativeFilter(Toy_Interpreter* interpreter, Toy_LiteralArray* argument Toy_freeLiteral(fnLiteralIdn); } + if (TOY_IS_IDENTIFIER(selfLiteral) || TOY_IS_IDENTIFIER(fnLiteral)) { + Toy_freeLiteral(selfLiteral); + Toy_freeLiteral(fnLiteral); + return -1; + } + //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 filter\n"); @@ -509,6 +539,12 @@ static int nativeForEach(Toy_Interpreter* interpreter, Toy_LiteralArray* argumen Toy_freeLiteral(fnLiteralIdn); } + if (TOY_IS_IDENTIFIER(selfLiteral) || TOY_IS_IDENTIFIER(fnLiteral)) { + Toy_freeLiteral(selfLiteral); + Toy_freeLiteral(fnLiteral); + return -1; + } + //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 forEach\n"); @@ -581,6 +617,11 @@ static int nativeGetKeys(Toy_Interpreter* interpreter, Toy_LiteralArray* argumen Toy_freeLiteral(selfLiteralIdn); } + if (TOY_IS_IDENTIFIER(selfLiteral)) { + Toy_freeLiteral(selfLiteral); + return -1; + } + //check type if (!TOY_IS_DICTIONARY(selfLiteral)) { interpreter->errorOutput("Incorrect argument type passed to getKeys\n"); @@ -626,6 +667,11 @@ static int nativeGetValues(Toy_Interpreter* interpreter, Toy_LiteralArray* argum Toy_freeLiteral(selfLiteralIdn); } + if (TOY_IS_IDENTIFIER(selfLiteral)) { + Toy_freeLiteral(selfLiteral); + return -1; + } + //check type if (!TOY_IS_DICTIONARY(selfLiteral)) { interpreter->errorOutput("Incorrect argument type passed to getValues\n"); @@ -678,6 +724,12 @@ static int nativeIndexOf(Toy_Interpreter* interpreter, Toy_LiteralArray* argumen Toy_freeLiteral(valueLiteralIdn); } + if (TOY_IS_IDENTIFIER(selfLiteral) || TOY_IS_IDENTIFIER(valueLiteral)) { + Toy_freeLiteral(selfLiteral); + Toy_freeLiteral(valueLiteral); + return -1; + } + //check type if (!TOY_IS_ARRAY(selfLiteral)) { interpreter->errorOutput("Incorrect argument type passed to indexOf\n"); @@ -725,6 +777,12 @@ static int nativeMap(Toy_Interpreter* interpreter, Toy_LiteralArray* arguments) Toy_freeLiteral(fnLiteralIdn); } + if (TOY_IS_IDENTIFIER(selfLiteral) || TOY_IS_IDENTIFIER(fnLiteral)) { + Toy_freeLiteral(selfLiteral); + Toy_freeLiteral(fnLiteral); + return -1; + } + //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 map\n"); @@ -834,6 +892,13 @@ static int nativeReduce(Toy_Interpreter* interpreter, Toy_LiteralArray* argument Toy_freeLiteral(fnLiteralIdn); } + if (TOY_IS_IDENTIFIER(selfLiteral) || TOY_IS_IDENTIFIER(defaultLiteral) || TOY_IS_IDENTIFIER(fnLiteral)) { + Toy_freeLiteral(selfLiteral); + Toy_freeLiteral(defaultLiteral); + Toy_freeLiteral(fnLiteral); + return -1; + } + //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 reduce\n"); @@ -929,6 +994,12 @@ static int nativeSome(Toy_Interpreter* interpreter, Toy_LiteralArray* arguments) Toy_freeLiteral(fnLiteralIdn); } + if (TOY_IS_IDENTIFIER(selfLiteral) || TOY_IS_IDENTIFIER(fnLiteral)) { + Toy_freeLiteral(selfLiteral); + Toy_freeLiteral(fnLiteral); + return -1; + } + //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"); @@ -1093,6 +1164,12 @@ static int nativeSort(Toy_Interpreter* interpreter, Toy_LiteralArray* arguments) Toy_freeLiteral(fnLiteralIdn); } + if (TOY_IS_IDENTIFIER(selfLiteral) || TOY_IS_IDENTIFIER(fnLiteral)) { + Toy_freeLiteral(selfLiteral); + Toy_freeLiteral(fnLiteral); + return -1; + } + //check type if (!TOY_IS_ARRAY(selfLiteral) || !( TOY_IS_FUNCTION(fnLiteral) || TOY_IS_FUNCTION_NATIVE(fnLiteral) )) { interpreter->errorOutput("Incorrect argument type passed to sort\n"); @@ -1129,6 +1206,11 @@ static int nativeToLower(Toy_Interpreter* interpreter, Toy_LiteralArray* argumen Toy_freeLiteral(selfLiteralIdn); } + if (TOY_IS_IDENTIFIER(selfLiteral)) { + Toy_freeLiteral(selfLiteral); + return -1; + } + if (!TOY_IS_STRING(selfLiteral)) { interpreter->errorOutput("Incorrect argument type passed to toLower\n"); Toy_freeLiteral(selfLiteral); @@ -1190,6 +1272,11 @@ static int nativeToString(Toy_Interpreter* interpreter, Toy_LiteralArray* argume Toy_freeLiteral(selfLiteralIdn); } + if (TOY_IS_IDENTIFIER(selfLiteral)) { + Toy_freeLiteral(selfLiteral); + return -1; + } + //BUGFIX: probably an undefined variable if (TOY_IS_IDENTIFIER(selfLiteral)) { Toy_freeLiteral(selfLiteral); @@ -1229,6 +1316,11 @@ static int nativeToUpper(Toy_Interpreter* interpreter, Toy_LiteralArray* argumen Toy_freeLiteral(selfLiteralIdn); } + if (TOY_IS_IDENTIFIER(selfLiteral)) { + Toy_freeLiteral(selfLiteral); + return -1; + } + if (!TOY_IS_STRING(selfLiteral)) { interpreter->errorOutput("Incorrect argument type passed to toUpper\n"); Toy_freeLiteral(selfLiteral); @@ -1289,7 +1381,13 @@ static int nativeTrim(Toy_Interpreter* interpreter, Toy_LiteralArray* arguments) Toy_freeLiteral(selfLiteralIdn); } - if (!TOY_IS_STRING(selfLiteral)) { + if (TOY_IS_IDENTIFIER(selfLiteral) || TOY_IS_IDENTIFIER(trimCharsLiteral)) { + Toy_freeLiteral(selfLiteral); + Toy_freeLiteral(trimCharsLiteral); + return -1; + } + + if (!TOY_IS_STRING(selfLiteral) || !TOY_IS_STRING(trimCharsLiteral)) { interpreter->errorOutput("Incorrect argument type passed to trim\n"); Toy_freeLiteral(trimCharsLiteral); Toy_freeLiteral(selfLiteral); @@ -1400,7 +1498,13 @@ static int nativeTrimBegin(Toy_Interpreter* interpreter, Toy_LiteralArray* argum Toy_freeLiteral(selfLiteralIdn); } - if (!TOY_IS_STRING(selfLiteral)) { + if (TOY_IS_IDENTIFIER(selfLiteral) || TOY_IS_IDENTIFIER(trimCharsLiteral)) { + Toy_freeLiteral(selfLiteral); + Toy_freeLiteral(trimCharsLiteral); + return -1; + } + + if (!TOY_IS_STRING(selfLiteral) || !TOY_IS_STRING(trimCharsLiteral)) { interpreter->errorOutput("Incorrect argument type passed to trimBegin\n"); Toy_freeLiteral(trimCharsLiteral); Toy_freeLiteral(selfLiteral); @@ -1488,7 +1592,13 @@ static int nativeTrimEnd(Toy_Interpreter* interpreter, Toy_LiteralArray* argumen Toy_freeLiteral(selfLiteralIdn); } - if (!TOY_IS_STRING(selfLiteral)) { + if (TOY_IS_IDENTIFIER(selfLiteral) || TOY_IS_IDENTIFIER(trimCharsLiteral)) { + Toy_freeLiteral(selfLiteral); + Toy_freeLiteral(trimCharsLiteral); + return -1; + } + + if (!TOY_IS_STRING(selfLiteral) || !TOY_IS_STRING(trimCharsLiteral)) { interpreter->errorOutput("Incorrect argument type passed to trimEnd\n"); Toy_freeLiteral(trimCharsLiteral); Toy_freeLiteral(selfLiteral); diff --git a/source/toy_builtin.c b/source/toy_builtin.c index b0d50ab..1b175eb 100644 --- a/source/toy_builtin.c +++ b/source/toy_builtin.c @@ -279,6 +279,17 @@ int Toy_private_index(Toy_Interpreter* interpreter, Toy_LiteralArray* arguments) Toy_freeLiteral(idn); } + if (TOY_IS_IDENTIFIER(first) || TOY_IS_IDENTIFIER(second) || TOY_IS_IDENTIFIER(third)) { + Toy_freeLiteral(op); + Toy_freeLiteral(assign); + Toy_freeLiteral(third); + Toy_freeLiteral(second); + Toy_freeLiteral(first); + Toy_freeLiteral(compound); + + return -1; + } + //second and third are bad args to dictionaries if (!TOY_IS_NULL(second) || !TOY_IS_NULL(third)) { interpreter->errorOutput("Index slicing not allowed for dictionaries\n"); @@ -401,6 +412,17 @@ int Toy_private_index(Toy_Interpreter* interpreter, Toy_LiteralArray* arguments) Toy_freeLiteral(idn); } + if (TOY_IS_IDENTIFIER(first) || TOY_IS_IDENTIFIER(second) || TOY_IS_IDENTIFIER(third)) { + Toy_freeLiteral(op); + Toy_freeLiteral(assign); + Toy_freeLiteral(third); + Toy_freeLiteral(second); + Toy_freeLiteral(first); + Toy_freeLiteral(compound); + + return -1; + } + //handle each error case if (!TOY_IS_INTEGER(first) || TOY_AS_INTEGER(first) < 0 || TOY_AS_INTEGER(first) >= TOY_AS_ARRAY(compound)->count) { interpreter->errorOutput("Bad first indexing\n"); @@ -543,6 +565,17 @@ int Toy_private_index(Toy_Interpreter* interpreter, Toy_LiteralArray* arguments) Toy_freeLiteral(idn); } + if (TOY_IS_IDENTIFIER(first) || TOY_IS_IDENTIFIER(second) || TOY_IS_IDENTIFIER(third)) { + Toy_freeLiteral(op); + Toy_freeLiteral(assign); + Toy_freeLiteral(third); + Toy_freeLiteral(second); + Toy_freeLiteral(first); + Toy_freeLiteral(compound); + + return -1; + } + //handle each error case if (!TOY_IS_INTEGER(first) || TOY_AS_INTEGER(first) < 0 || TOY_AS_INTEGER(first) >= TOY_AS_ARRAY(compound)->count) { interpreter->errorOutput("Bad first indexing assignment\n"); @@ -705,6 +738,17 @@ int Toy_private_index(Toy_Interpreter* interpreter, Toy_LiteralArray* arguments) Toy_freeLiteral(idn); } + if (TOY_IS_IDENTIFIER(first)) { + Toy_freeLiteral(op); + Toy_freeLiteral(assign); + Toy_freeLiteral(third); + Toy_freeLiteral(second); + Toy_freeLiteral(first); + Toy_freeLiteral(compound); + + return -1; + } + Toy_Literal value = Toy_getLiteralArray(TOY_AS_ARRAY(compound), first); if (TOY_IS_STRING(op) && Toy_equalsRefStringCString(TOY_AS_STRING(op), "+=")) { @@ -793,6 +837,17 @@ int Toy_private_index(Toy_Interpreter* interpreter, Toy_LiteralArray* arguments) Toy_freeLiteral(idn); } + if (TOY_IS_IDENTIFIER(first) || TOY_IS_IDENTIFIER(second) || TOY_IS_IDENTIFIER(third)) { + Toy_freeLiteral(op); + Toy_freeLiteral(assign); + Toy_freeLiteral(third); + Toy_freeLiteral(second); + Toy_freeLiteral(first); + Toy_freeLiteral(compound); + + return -1; + } + //handle each error case if (!TOY_IS_INTEGER(first) || TOY_AS_INTEGER(first) < 0 || TOY_AS_INTEGER(first) >= (int)Toy_lengthRefString(TOY_AS_STRING(compound))) { interpreter->errorOutput("Bad first indexing in string\n"); @@ -937,6 +992,17 @@ int Toy_private_index(Toy_Interpreter* interpreter, Toy_LiteralArray* arguments) Toy_freeLiteral(idn); } + if (TOY_IS_IDENTIFIER(first) || TOY_IS_IDENTIFIER(second) || TOY_IS_IDENTIFIER(third)) { + Toy_freeLiteral(op); + Toy_freeLiteral(assign); + Toy_freeLiteral(third); + Toy_freeLiteral(second); + Toy_freeLiteral(first); + Toy_freeLiteral(compound); + + return -1; + } + //handle each error case if (!TOY_IS_INTEGER(first) || TOY_AS_INTEGER(first) < 0 || TOY_AS_INTEGER(first) >= (int)Toy_lengthRefString(TOY_AS_STRING(compound))) { interpreter->errorOutput("Bad first indexing in string assignment\n"); @@ -1080,6 +1146,10 @@ int Toy_private_set(Toy_Interpreter* interpreter, Toy_LiteralArray* arguments) { Toy_parseIdentifierToValue(interpreter, &obj); + if (TOY_IS_IDENTIFIER(obj)) { + return -1; + } + bool freeKey = false; if (TOY_IS_IDENTIFIER(key)) { Toy_parseIdentifierToValue(interpreter, &key); @@ -1092,6 +1162,16 @@ int Toy_private_set(Toy_Interpreter* interpreter, Toy_LiteralArray* arguments) { freeVal = true; } + if (TOY_IS_IDENTIFIER(key) || TOY_IS_IDENTIFIER(val)) { + if (freeKey) { + Toy_freeLiteral(key); + } + if (freeVal) { + Toy_freeLiteral(val); + } + return -1; + } + switch(obj.type) { case TOY_LITERAL_ARRAY: { Toy_Literal typeLiteral = Toy_getScopeType(interpreter->scope, key); @@ -1201,6 +1281,16 @@ int Toy_private_get(Toy_Interpreter* interpreter, Toy_LiteralArray* arguments) { freeKey = true; } + if (TOY_IS_IDENTIFIER(obj) || TOY_IS_IDENTIFIER(key)) { + if (freeObj) { + Toy_freeLiteral(obj); + } + if (freeKey) { + Toy_freeLiteral(key); + } + return -1; + } + switch(obj.type) { case TOY_LITERAL_ARRAY: { if (!TOY_IS_INTEGER(key)) { @@ -1268,12 +1358,20 @@ int Toy_private_push(Toy_Interpreter* interpreter, Toy_LiteralArray* arguments) Toy_parseIdentifierToValue(interpreter, &obj); + if (TOY_IS_IDENTIFIER(obj)) { + return -1; + } + bool freeVal = false; if (TOY_IS_IDENTIFIER(val)) { Toy_parseIdentifierToValue(interpreter, &val); freeVal = true; } + if (TOY_IS_IDENTIFIER(val)) { + return -1; + } + switch(obj.type) { case TOY_LITERAL_ARRAY: { Toy_Literal typeLiteral = Toy_getScopeType(interpreter->scope, val); @@ -1330,6 +1428,10 @@ int Toy_private_pop(Toy_Interpreter* interpreter, Toy_LiteralArray* arguments) { Toy_parseIdentifierToValue(interpreter, &obj); + if (TOY_IS_IDENTIFIER(obj)) { + return -1; + } + switch(obj.type) { case TOY_LITERAL_ARRAY: { Toy_Literal lit = Toy_popLiteralArray(TOY_AS_ARRAY(obj)); @@ -1371,6 +1473,10 @@ int Toy_private_length(Toy_Interpreter* interpreter, Toy_LiteralArray* arguments freeObj = true; } + if (TOY_IS_IDENTIFIER(obj)) { + return -1; + } + switch(obj.type) { case TOY_LITERAL_ARRAY: { Toy_Literal lit = TOY_TO_INTEGER_LITERAL( TOY_AS_ARRAY(obj)->count ); @@ -1424,6 +1530,10 @@ int Toy_private_clear(Toy_Interpreter* interpreter, Toy_LiteralArray* arguments) Toy_parseIdentifierToValue(interpreter, &obj); + if (TOY_IS_IDENTIFIER(obj)) { + return -1; + } + //NOTE: just pass in new compounds switch(obj.type) { diff --git a/source/toy_interpreter.c b/source/toy_interpreter.c index cbd91a7..c33bb0d 100644 --- a/source/toy_interpreter.c +++ b/source/toy_interpreter.c @@ -231,6 +231,12 @@ static bool execAssert(Toy_Interpreter* interpreter) { Toy_freeLiteral(lhsIdn); } + if (TOY_IS_IDENTIFIER(lhs)) { + Toy_freeLiteral(lhs); + Toy_freeLiteral(rhs); + return false; + } + if (!TOY_IS_STRING(rhs)) { interpreter->errorOutput("The assert keyword needs a string as the second argument, received: "); Toy_printLiteralCustom(rhs, interpreter->errorOutput); @@ -265,10 +271,13 @@ static bool execPrint(Toy_Interpreter* interpreter) { Toy_freeLiteral(idn); } - if (!TOY_IS_IDENTIFIER(lit)) { - Toy_printLiteralCustom(lit, interpreter->printOutput); + if (TOY_IS_IDENTIFIER(lit)) { + Toy_freeLiteral(lit); + return false; } + Toy_printLiteralCustom(lit, interpreter->printOutput); + Toy_freeLiteral(lit); return true; @@ -299,6 +308,11 @@ static bool rawLiteral(Toy_Interpreter* interpreter) { Toy_freeLiteral(idn); } + if (TOY_IS_IDENTIFIER(lit)) { + Toy_freeLiteral(lit); + return false; + } + Toy_pushLiteralArray(&interpreter->stack, lit); Toy_freeLiteral(lit); @@ -314,6 +328,11 @@ static bool execNegate(Toy_Interpreter* interpreter) { Toy_freeLiteral(idn); } + if (TOY_IS_IDENTIFIER(lit)) { + Toy_freeLiteral(lit); + return false; + } + if (TOY_IS_INTEGER(lit)) { lit = TOY_TO_INTEGER_LITERAL(-TOY_AS_INTEGER(lit)); } @@ -345,6 +364,11 @@ static bool execInvert(Toy_Interpreter* interpreter) { Toy_freeLiteral(idn); } + if (TOY_IS_IDENTIFIER(lit)) { + Toy_freeLiteral(lit); + return false; + } + if (TOY_IS_BOOLEAN(lit)) { lit = TOY_TO_BOOLEAN_LITERAL(!TOY_AS_BOOLEAN(lit)); } @@ -378,6 +402,12 @@ static bool execArithmetic(Toy_Interpreter* interpreter, Toy_Opcode opcode) { Toy_freeLiteral(lhsIdn); } + if (TOY_IS_IDENTIFIER(lhs) || TOY_IS_IDENTIFIER(rhs)) { + Toy_freeLiteral(lhs); + Toy_freeLiteral(rhs); + return false; + } + //special case for string concatenation ONLY if (TOY_IS_STRING(lhs) && TOY_IS_STRING(rhs) && (opcode == TOY_OP_ADDITION || opcode == TOY_OP_VAR_ADDITION_ASSIGN)) { //check for overflow @@ -510,6 +540,10 @@ static Toy_Literal parseTypeToValue(Toy_Interpreter* interpreter, Toy_Literal ty Toy_freeLiteral(typeIdn); } + if (TOY_IS_IDENTIFIER(type)) { + return TOY_TO_NULL_LITERAL; + } + //if this is an array or dictionary, continue to the subtypes if (TOY_IS_TYPE(type) && (TOY_AS_TYPE(type).typeOf == TOY_LITERAL_ARRAY || TOY_AS_TYPE(type).typeOf == TOY_LITERAL_DICTIONARY)) { for (int i = 0; i < TOY_AS_TYPE(type).count; i++) { @@ -550,6 +584,12 @@ static bool execVarDecl(Toy_Interpreter* interpreter, bool lng) { Toy_freeLiteral(typeIdn); } + if (TOY_IS_IDENTIFIER(type)) { + Toy_freeLiteral(identifier); + Toy_freeLiteral(type); + return false; + } + //BUGFIX: because identifiers are getting embedded in type definitions type = parseTypeToValue(interpreter, type); @@ -567,6 +607,13 @@ static bool execVarDecl(Toy_Interpreter* interpreter, bool lng) { Toy_freeLiteral(valIdn); } + if (TOY_IS_IDENTIFIER(val)) { + Toy_freeLiteral(identifier); + Toy_freeLiteral(type); + Toy_freeLiteral(val); + return false; + } + if (TOY_IS_ARRAY(val) || TOY_IS_DICTIONARY(val)) { Toy_parseCompoundToPureValues(interpreter, &val); } @@ -647,6 +694,12 @@ static bool execVarAssign(Toy_Interpreter* interpreter) { Toy_freeLiteral(rhsIdn); } + if (TOY_IS_IDENTIFIER(rhs)) { + Toy_freeLiteral(lhs); + Toy_freeLiteral(rhs); + return false; + } + if (TOY_IS_ARRAY(rhs) || TOY_IS_DICTIONARY(rhs)) { Toy_parseCompoundToPureValues(interpreter, &rhs); } @@ -716,6 +769,12 @@ static bool execValCast(Toy_Interpreter* interpreter) { Toy_freeLiteral(valueIdn); } + if (TOY_IS_IDENTIFIER(value)) { + Toy_freeLiteral(type); + Toy_freeLiteral(value); + return false; + } + Toy_Literal result = TOY_TO_NULL_LITERAL; if (TOY_IS_NULL(value)) { @@ -850,6 +909,12 @@ static bool execCompareEqual(Toy_Interpreter* interpreter, bool invert) { Toy_freeLiteral(lhsIdn); } + if (TOY_IS_IDENTIFIER(lhs) || TOY_IS_IDENTIFIER(rhs)) { + Toy_freeLiteral(lhs); + Toy_freeLiteral(rhs); + return false; + } + bool result = Toy_literalsAreEqual(lhs, rhs); if (invert) { @@ -878,6 +943,12 @@ static bool execCompareLess(Toy_Interpreter* interpreter, bool invert) { Toy_freeLiteral(lhsIdn); } + if (TOY_IS_IDENTIFIER(lhs) || TOY_IS_IDENTIFIER(rhs)) { + Toy_freeLiteral(lhs); + Toy_freeLiteral(rhs); + return false; + } + //not a number, return falure if (!(TOY_IS_INTEGER(lhs) || TOY_IS_FLOAT(lhs))) { interpreter->errorOutput("Incorrect type in comparison, value \""); @@ -938,6 +1009,12 @@ static bool execCompareLessEqual(Toy_Interpreter* interpreter, bool invert) { Toy_freeLiteral(lhsIdn); } + if (TOY_IS_IDENTIFIER(lhs) || TOY_IS_IDENTIFIER(rhs)) { + Toy_freeLiteral(lhs); + Toy_freeLiteral(rhs); + return false; + } + //not a number, return falure if (!(TOY_IS_INTEGER(lhs) || TOY_IS_FLOAT(lhs))) { interpreter->errorOutput("Incorrect type in comparison, value \""); @@ -999,6 +1076,12 @@ static bool execAnd(Toy_Interpreter* interpreter) { Toy_freeLiteral(lhsIdn); } + if (TOY_IS_IDENTIFIER(lhs) || TOY_IS_IDENTIFIER(rhs)) { + Toy_freeLiteral(lhs); + Toy_freeLiteral(rhs); + return false; + } + if (TOY_IS_TRUTHY(lhs) && TOY_IS_TRUTHY(rhs)) { Toy_pushLiteralArray(&interpreter->stack, TOY_TO_BOOLEAN_LITERAL(true)); } @@ -1026,6 +1109,12 @@ static bool execOr(Toy_Interpreter* interpreter) { Toy_freeLiteral(lhsIdn); } + if (TOY_IS_IDENTIFIER(lhs) || TOY_IS_IDENTIFIER(rhs)) { + Toy_freeLiteral(lhs); + Toy_freeLiteral(rhs); + return false; + } + if (TOY_IS_TRUTHY(lhs) || TOY_IS_TRUTHY(rhs)) { Toy_pushLiteralArray(&interpreter->stack, TOY_TO_BOOLEAN_LITERAL(true)); } @@ -1069,6 +1158,11 @@ static bool execFalseJump(Toy_Interpreter* interpreter) { Toy_freeLiteral(litIdn); } + if (TOY_IS_IDENTIFIER(lit)) { + Toy_freeLiteral(lit); + return false; + } + if (TOY_IS_NULL(lit)) { interpreter->errorOutput("Null detected in comparison\n"); Toy_freeLiteral(lit); @@ -1185,7 +1279,7 @@ bool Toy_callLiteralFn(Toy_Interpreter* interpreter, Toy_Literal func, Toy_Liter int returnsCount = TOY_AS_FUNCTION_NATIVE(func)(interpreter, arguments); if (returnsCount < 0) { - interpreter->errorOutput("Unknown error from native function\n"); + // interpreter->errorOutput("Unknown error from native function\n"); return false; } @@ -1289,6 +1383,17 @@ bool Toy_callLiteralFn(Toy_Interpreter* interpreter, Toy_Literal func, Toy_Liter Toy_freeLiteral(argIdn); } + if (TOY_IS_IDENTIFIER(arg)) { + //free, and skip out + Toy_freeLiteral(arg); + Toy_popScope(inner.scope); + + Toy_freeLiteralArray(&inner.stack); + Toy_freeLiteralArray(&inner.literalCache); + + return false; + } + if (!Toy_setScopeVariable(inner.scope, paramArray->literals[i], arg, false)) { interpreter->errorOutput("[internal] Could not define parameter (bad type?)\n"); @@ -1457,6 +1562,12 @@ static bool execFnReturn(Toy_Interpreter* interpreter) { Toy_freeLiteral(litIdn); } + if (TOY_IS_IDENTIFIER(lit)) { + Toy_freeLiteralArray(&returns); + Toy_freeLiteral(lit); + return false; + } + if (TOY_IS_ARRAY(lit) || TOY_IS_DICTIONARY(lit)) { Toy_parseCompoundToPureValues(interpreter, &lit); } @@ -1528,6 +1639,17 @@ static bool execIndex(Toy_Interpreter* interpreter, bool assignIntermediate) { freeIdn = true; } + if (TOY_IS_IDENTIFIER(compound)) { + Toy_freeLiteral(third); + Toy_freeLiteral(second); + Toy_freeLiteral(first); + Toy_freeLiteral(compound); + if (freeIdn) { + Toy_freeLiteral(compoundIdn); + } + return true; + } + if (!TOY_IS_ARRAY(compound) && !TOY_IS_DICTIONARY(compound) && !TOY_IS_STRING(compound)) { interpreter->errorOutput("Unknown compound found in indexing notation: "); Toy_printLiteralCustom(compound, interpreter->errorOutput); @@ -1612,12 +1734,33 @@ static bool execIndexAssign(Toy_Interpreter* interpreter) { Toy_freeLiteral(assignIdn); } + if (TOY_IS_IDENTIFIER(assign)) { + Toy_freeLiteral(compound); + Toy_freeLiteral(first); + Toy_freeLiteral(second); + Toy_freeLiteral(third); + Toy_freeLiteral(assign); + return false; + } + Toy_Literal compoundIdn = compound; bool freeIdn = false; if (TOY_IS_IDENTIFIER(compound) && Toy_parseIdentifierToValue(interpreter, &compound)) { freeIdn = true; } + if (TOY_IS_IDENTIFIER(compound)) { + Toy_freeLiteral(compound); + Toy_freeLiteral(first); + Toy_freeLiteral(second); + Toy_freeLiteral(third); + Toy_freeLiteral(assign); + if (freeIdn) { + Toy_freeLiteral(compoundIdn); + } + return false; + } + if (!TOY_IS_ARRAY(compound) && !TOY_IS_DICTIONARY(compound) && !TOY_IS_STRING(compound)) { interpreter->errorOutput("Unknown compound found in index assigning notation\n"); Toy_freeLiteral(assign);