diff --git a/source/interpreter.c b/source/interpreter.c index b7b11d9..d5df70e 100644 --- a/source/interpreter.c +++ b/source/interpreter.c @@ -33,7 +33,8 @@ bool injectNativeFn(Interpreter* interpreter, char* name, NativeFn func) { return false; } - Literal identifier = TO_IDENTIFIER_LITERAL(copyString(name, strlen(name)), strlen(name)); + int identifierLength = strlen(name); + Literal identifier = TO_IDENTIFIER_LITERAL(copyString(name, identifierLength), identifierLength); //make sure the name isn't taken if (existsLiteralDictionary(&interpreter->scope->variables, identifier)) { @@ -299,7 +300,8 @@ static bool execArithmetic(Interpreter* interpreter, Opcode opcode) { //special case for string concatenation ONLY if (IS_STRING(lhs) && IS_STRING(rhs)) { //check for overflow - if (strlen(AS_STRING(lhs)) + strlen(AS_STRING(rhs)) > MAX_STRING_LENGTH) { + int totalLength = strlen(AS_STRING(lhs)) + strlen(AS_STRING(rhs)); + if (totalLength > MAX_STRING_LENGTH) { interpreter->errorOutput("Can't concatenate these strings (result is too long)\n"); return false; } @@ -307,7 +309,7 @@ static bool execArithmetic(Interpreter* interpreter, Opcode opcode) { //concat the strings char buffer[MAX_STRING_LENGTH]; snprintf(buffer, MAX_STRING_LENGTH, "%s%s", AS_STRING(lhs), AS_STRING(rhs)); - Literal literal = TO_STRING_LITERAL( copyString(buffer, strlen(buffer)), strlen(buffer) ); + Literal literal = TO_STRING_LITERAL( copyString(buffer, totalLength), totalLength); pushLiteralArray(&interpreter->stack, literal); freeLiteral(literal); freeLiteral(lhs); @@ -668,19 +670,22 @@ static bool execValCast(Interpreter* interpreter) { if (IS_BOOLEAN(value)) { char* str = AS_BOOLEAN(value) ? "true" : "false"; - result = TO_STRING_LITERAL(copyString(str, strlen(str)), strlen(str)); + int length = strlen(str); + result = TO_STRING_LITERAL(copyString(str, length), length); } if (IS_INTEGER(value)) { char buffer[128]; snprintf(buffer, 128, "%d", AS_INTEGER(value)); - result = TO_STRING_LITERAL(copyString(buffer, strlen(buffer)), strlen(buffer)); + int length = strlen(buffer); + result = TO_STRING_LITERAL(copyString(buffer, length), length); } if (IS_FLOAT(value)) { char buffer[128]; snprintf(buffer, 128, "%g", AS_FLOAT(value)); - result = TO_STRING_LITERAL(copyString(buffer, strlen(buffer)), strlen(buffer)); + int length = strlen(buffer); + result = TO_STRING_LITERAL(copyString(buffer, length), length); } if (IS_STRING(value)) { @@ -1435,7 +1440,8 @@ static bool execIndex(Interpreter* interpreter) { //get the index function Literal func = TO_NULL_LITERAL; char* keyStr = "_index"; - Literal key = TO_IDENTIFIER_LITERAL(copyString(keyStr, strlen(keyStr)), strlen(keyStr)); + int keyStrLength = strlen(keyStr); + Literal key = TO_IDENTIFIER_LITERAL(copyString(keyStr, keyStrLength), keyStrLength); if (!getScopeVariable(interpreter->scope, key, &func) || !IS_FUNCTION_NATIVE(func)) { interpreter->errorOutput("couldn't get the _index function\n"); @@ -1538,7 +1544,8 @@ static bool execIndexAssign(Interpreter* interpreter) { //get the index function Literal func = TO_NULL_LITERAL; char* keyStr = "_index"; - Literal key = TO_IDENTIFIER_LITERAL(copyString(keyStr, strlen(keyStr)), strlen(keyStr)); + int keyStrLength = strlen(keyStr); + Literal key = TO_IDENTIFIER_LITERAL(copyString(keyStr, keyStrLength), keyStrLength); if (!getScopeVariable(interpreter->scope, key, &func) || !IS_FUNCTION_NATIVE(func)) { interpreter->errorOutput("couldn't get the _index function\n"); @@ -1591,7 +1598,8 @@ static bool execIndexAssign(Interpreter* interpreter) { return false; } - Literal op = TO_STRING_LITERAL(copyString(opStr, strlen(opStr)), strlen(opStr)); + int opLength = strlen(opStr); + Literal op = TO_STRING_LITERAL(copyString(opStr, opLength), opLength); //build the argument list LiteralArray arguments; @@ -1949,7 +1957,8 @@ static void readInterpreterSections(Interpreter* interpreter) { case LITERAL_STRING: { char* s = readString(interpreter->bytecode, &interpreter->count); - Literal literal = TO_STRING_LITERAL( copyString(s, strlen(s)), strlen(s) ); + int length = strlen(s); + Literal literal = TO_STRING_LITERAL( copyString(s, length), length); pushLiteralArray(&interpreter->literalCache, literal); freeLiteral(literal); @@ -2036,7 +2045,8 @@ static void readInterpreterSections(Interpreter* interpreter) { case LITERAL_IDENTIFIER: { char* str = readString(interpreter->bytecode, &interpreter->count); - Literal identifier = TO_IDENTIFIER_LITERAL(copyString(str, strlen(str)), strlen(str)); + int length = strlen(str); + Literal identifier = TO_IDENTIFIER_LITERAL(copyString(str, length), length); pushLiteralArray(&interpreter->literalCache, identifier); diff --git a/source/lib_builtin.c b/source/lib_builtin.c index 7377755..31a532b 100644 --- a/source/lib_builtin.c +++ b/source/lib_builtin.c @@ -10,7 +10,8 @@ static Literal addition(Interpreter* interpreter, Literal lhs, Literal rhs) { //special case for string concatenation ONLY if (IS_STRING(lhs) && IS_STRING(rhs)) { //check for overflow - if (strlen(AS_STRING(lhs)) + strlen(AS_STRING(rhs)) > MAX_STRING_LENGTH) { + int totalLength = strlen(AS_STRING(lhs)) + strlen(AS_STRING(rhs)); + if (totalLength > MAX_STRING_LENGTH) { interpreter->errorOutput("Can't concatenate these strings (result is too long)\n"); return TO_NULL_LITERAL; } @@ -18,7 +19,7 @@ static Literal addition(Interpreter* interpreter, Literal lhs, Literal rhs) { //concat the strings char buffer[MAX_STRING_LENGTH]; snprintf(buffer, MAX_STRING_LENGTH, "%s%s", AS_STRING(lhs), AS_STRING(rhs)); - Literal literal = TO_STRING_LITERAL( copyString(buffer, strlen(buffer)), strlen(buffer) ); + Literal literal = TO_STRING_LITERAL(copyString(buffer, totalLength), totalLength); freeLiteral(lhs); freeLiteral(rhs); @@ -656,10 +657,11 @@ int _index(Interpreter* interpreter, LiteralArray* arguments) { } } + int compoundLength = strlen(AS_STRING(compound)); if (!IS_NULL(second)) { if (IS_BOOLEAN(second)) { freeLiteral(second); - second = TO_INTEGER_LITERAL(strlen(AS_STRING(compound))); + second = TO_INTEGER_LITERAL(compoundLength); } if (IS_IDENTIFIER(second)) { @@ -701,7 +703,8 @@ int _index(Interpreter* interpreter, LiteralArray* arguments) { snprintf(buffer, 16, "%c", c); freeLiteral(value); - value = TO_STRING_LITERAL(copyString(buffer, strlen(buffer)), strlen(buffer)); + int totalLength = strlen(buffer); + value = TO_STRING_LITERAL(copyString(buffer, totalLength), totalLength); pushLiteralArray(&interpreter->stack, value); @@ -716,7 +719,7 @@ int _index(Interpreter* interpreter, LiteralArray* arguments) { return 1; } - if (!IS_INTEGER(second) || (!IS_NULL(third) && !IS_INTEGER(third)) || AS_INTEGER(second) < 0 || AS_INTEGER(second) > (int)strlen(AS_STRING(compound)) || AS_INTEGER(third) == 0) { + if (!IS_INTEGER(second) || (!IS_NULL(third) && !IS_INTEGER(third)) || AS_INTEGER(second) < 0 || AS_INTEGER(second) > compoundLength || AS_INTEGER(third) == 0) { //something is weird - skip out freeLiteral(op); freeLiteral(assign); @@ -745,7 +748,7 @@ int _index(Interpreter* interpreter, LiteralArray* arguments) { //finally, swap out the compound for the result freeLiteral(compound); - compound = TO_STRING_LITERAL(copyString(result, strlen(result)), strlen(result)); + compound = TO_STRING_LITERAL(copyString(result, resultIndex), resultIndex); FREE_ARRAY(char, result, MAX_STRING_LENGTH); } @@ -766,10 +769,11 @@ int _index(Interpreter* interpreter, LiteralArray* arguments) { } } + int compoundLength = strlen(AS_STRING(compound)); if (!IS_NULL(second)) { if (IS_BOOLEAN(second)) { freeLiteral(second); - second = TO_INTEGER_LITERAL(strlen(AS_STRING(compound))); + second = TO_INTEGER_LITERAL(compoundLength); } if (IS_IDENTIFIER(second)) { @@ -834,7 +838,7 @@ int _index(Interpreter* interpreter, LiteralArray* arguments) { return 1; } - if (!IS_INTEGER(second) || (!IS_NULL(third) && !IS_INTEGER(third)) || AS_INTEGER(second) < 0 || AS_INTEGER(second) > (int)strlen(AS_STRING(compound)) || AS_INTEGER(third) == 0) { + if (!IS_INTEGER(second) || (!IS_NULL(third) && !IS_INTEGER(third)) || AS_INTEGER(second) < 0 || AS_INTEGER(second) > compoundLength || AS_INTEGER(third) == 0) { //something is weird - skip out freeLiteral(op); freeLiteral(assign); @@ -857,14 +861,14 @@ int _index(Interpreter* interpreter, LiteralArray* arguments) { result[ resultIndex++ ] = AS_STRING(compound)[ i ]; } - int min = AS_INTEGER(third) > 0 ? 0 : strlen(AS_STRING(assign)) - 1; + int assignLength = strlen(AS_STRING(assign)); + int min = AS_INTEGER(third) > 0 ? 0 : assignLength - 1; - //TODO: optimize strlen(assign) - for (int i = min; i >= 0 && i < (int)strlen(AS_STRING(assign)); i += AS_INTEGER(third)) { + for (int i = min; i >= 0 && i < assignLength; i += AS_INTEGER(third)) { result[ resultIndex++ ] = AS_STRING(assign)[ i ]; } - for (int i = AS_INTEGER(second) + 1; i < (int)strlen(AS_STRING(compound)); i++) { + for (int i = AS_INTEGER(second) + 1; i < compoundLength; i++) { result[ resultIndex++ ] = AS_STRING(compound)[ i ]; } @@ -876,18 +880,19 @@ int _index(Interpreter* interpreter, LiteralArray* arguments) { //copy compound to result snprintf(result, MAX_STRING_LENGTH, AS_STRING(compound)); + int assignLength = strlen(AS_STRING(assign)); int min = AS_INTEGER(third) > 0 ? AS_INTEGER(first) : AS_INTEGER(second) - 1; int assignIndex = 0; - for (int i = min; i >= AS_INTEGER(first) && i <= AS_INTEGER(second) && assignIndex < (int)strlen(AS_STRING(assign)); i += AS_INTEGER(third)) { + for (int i = min; i >= AS_INTEGER(first) && i <= AS_INTEGER(second) && assignIndex < assignLength; i += AS_INTEGER(third)) { result[ i ] = AS_STRING(assign)[ assignIndex++ ]; - resultIndex++; } + resultIndex = strlen(result); } //finally, swap out the compound for the result freeLiteral(compound); - compound = TO_STRING_LITERAL(copyString(result, strlen(result)), strlen(result)); + compound = TO_STRING_LITERAL(copyString(result, resultIndex), resultIndex); FREE_ARRAY(char, result, MAX_STRING_LENGTH); }