From f6367fa89d7fbafea54866040b9a737fe018a8e0 Mon Sep 17 00:00:00 2001 From: Kayne Ruse Date: Sat, 26 Nov 2022 09:43:19 +0000 Subject: [PATCH] Updated interpreter --- source/builtin.c | 75 ++++++++++--------- source/interpreter.c | 48 ++++++------ source/parser.c | 4 +- test/makefile | 3 + ...xtest_interpreter.c => test_interpreter.c} | 8 +- 5 files changed, 73 insertions(+), 65 deletions(-) rename test/{xtest_interpreter.c => test_interpreter.c} (98%) diff --git a/source/builtin.c b/source/builtin.c index b3e7141..15bd573 100644 --- a/source/builtin.c +++ b/source/builtin.c @@ -10,7 +10,7 @@ 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 - int totalLength = strlen(AS_STRING(lhs)) + strlen(AS_STRING(rhs)); + int totalLength = AS_STRING(lhs)->length + AS_STRING(rhs)->length; if (totalLength > MAX_STRING_LENGTH) { interpreter->errorOutput("Can't concatenate these strings (result is too long)\n"); return TO_NULL_LITERAL; @@ -18,8 +18,9 @@ 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, totalLength), totalLength); + snprintf(buffer, MAX_STRING_LENGTH, "%s%s", toCString(AS_STRING(lhs)), toCString(AS_STRING(rhs))); + Literal literal = TO_STRING_LITERAL(createRefStringLength(buffer, totalLength)); + freeLiteral(lhs); freeLiteral(rhs); @@ -296,35 +297,35 @@ int _index(Interpreter* interpreter, LiteralArray* arguments) { return 1; } - else if (!strcmp( AS_STRING(op), "=")) { + else if (equalsRefStringCString(AS_STRING(op), "=")) { setLiteralDictionary(AS_DICTIONARY(compound), first, assign); } - else if (!strcmp( AS_STRING(op), "+=")) { + else if (equalsRefStringCString(AS_STRING(op), "+=")) { Literal lit = addition(interpreter, value, assign); setLiteralDictionary(AS_DICTIONARY(compound), first, lit); freeLiteral(lit); } - else if (!strcmp( AS_STRING(op), "-=")) { + else if (equalsRefStringCString(AS_STRING(op), "-=")) { Literal lit = subtraction(interpreter, value, assign); setLiteralDictionary(AS_DICTIONARY(compound), first, lit); freeLiteral(lit); } - else if (!strcmp( AS_STRING(op), "*=")) { + else if (equalsRefStringCString(AS_STRING(op), "*=")) { Literal lit = multiplication(interpreter, value, assign); setLiteralDictionary(AS_DICTIONARY(compound), first, lit); freeLiteral(lit); } - else if (!strcmp( AS_STRING(op), "/=")) { + else if (equalsRefStringCString(AS_STRING(op), "/=")) { Literal lit = division(interpreter, value, assign); setLiteralDictionary(AS_DICTIONARY(compound), first, lit); freeLiteral(lit); } - else if (!strcmp( AS_STRING(op), "%=")) { + else if (equalsRefStringCString(AS_STRING(op), "%=")) { Literal lit = modulo(interpreter, value, assign); setLiteralDictionary(AS_DICTIONARY(compound), first, lit); freeLiteral(lit); @@ -440,7 +441,7 @@ int _index(Interpreter* interpreter, LiteralArray* arguments) { } //array slice assignment - if (IS_STRING(op) && !strcmp( AS_STRING(op), "=")) { + if (IS_STRING(op) && equalsRefStringCString(AS_STRING(op), "=")) { //parse out the booleans & their defaults if (!IS_NULL(first)) { if (IS_BOOLEAN(first)) { @@ -620,31 +621,31 @@ int _index(Interpreter* interpreter, LiteralArray* arguments) { value = getLiteralArray(AS_ARRAY(compound), first); - if (IS_STRING(op) && !strcmp( AS_STRING(op), "+=")) { + if (IS_STRING(op) && equalsRefStringCString(AS_STRING(op), "+=")) { Literal lit = addition(interpreter, value, assign); setLiteralArray(AS_ARRAY(compound), first, lit); freeLiteral(lit); } - if (IS_STRING(op) && !strcmp( AS_STRING(op), "-=")) { + if (IS_STRING(op) && equalsRefStringCString(AS_STRING(op), "-=")) { Literal lit = subtraction(interpreter, value, assign); setLiteralArray(AS_ARRAY(compound), first, lit); freeLiteral(lit); } - if (IS_STRING(op) && !strcmp( AS_STRING(op), "*=")) { + if (IS_STRING(op) && equalsRefStringCString(AS_STRING(op), "*=")) { Literal lit = multiplication(interpreter, value, assign); setLiteralArray(AS_ARRAY(compound), first, lit); freeLiteral(lit); } - if (IS_STRING(op) && !strcmp( AS_STRING(op), "/=")) { + if (IS_STRING(op) && equalsRefStringCString(AS_STRING(op), "/=")) { Literal lit = division(interpreter, value, assign); setLiteralArray(AS_ARRAY(compound), first, lit); freeLiteral(lit); } - if (IS_STRING(op) && !strcmp( AS_STRING(op), "%=")) { + if (IS_STRING(op) && equalsRefStringCString(AS_STRING(op), "%=")) { Literal lit = modulo(interpreter, value, assign); setLiteralArray(AS_ARRAY(compound), first, lit); freeLiteral(lit); @@ -669,7 +670,7 @@ int _index(Interpreter* interpreter, LiteralArray* arguments) { } } - int compoundLength = strlen(AS_STRING(compound)); + int compoundLength = AS_STRING(compound)->length; if (!IS_NULL(second)) { if (IS_BOOLEAN(second)) { freeLiteral(second); @@ -709,14 +710,14 @@ int _index(Interpreter* interpreter, LiteralArray* arguments) { } if (IS_NULL(second)) { //assign only a single character - char c = AS_STRING(compound)[AS_INTEGER(first)]; + char c = toCString(AS_STRING(compound))[AS_INTEGER(first)]; char buffer[16]; snprintf(buffer, 16, "%c", c); freeLiteral(value); int totalLength = strlen(buffer); - value = TO_STRING_LITERAL(copyString(buffer, totalLength), totalLength); + value = TO_STRING_LITERAL(createRefStringLength(buffer, totalLength)); pushLiteralArray(&interpreter->stack, value); @@ -754,20 +755,20 @@ int _index(Interpreter* interpreter, LiteralArray* arguments) { //copy compound into result int resultIndex = 0; for (int i = min; i >= 0 && i >= lower && i <= max; i += AS_INTEGER(third)) { - result[ resultIndex++ ] = AS_STRING(compound)[ i ]; + result[ resultIndex++ ] = toCString(AS_STRING(compound))[ i ]; } result[ resultIndex ] = '\0'; //finally, swap out the compound for the result freeLiteral(compound); - compound = TO_STRING_LITERAL(copyString(result, resultIndex), resultIndex); + compound = TO_STRING_LITERAL(createRefStringLength(result, resultIndex)); FREE_ARRAY(char, result, MAX_STRING_LENGTH); } //string slice assignment - else if (IS_STRING(op) && !strcmp( AS_STRING(op), "=")) { + else if (IS_STRING(op) && equalsRefStringCString(AS_STRING(op), "=")) { //parse out the booleans & their defaults if (!IS_NULL(first)) { if (IS_BOOLEAN(first)) { @@ -782,7 +783,7 @@ int _index(Interpreter* interpreter, LiteralArray* arguments) { } } - int compoundLength = strlen(AS_STRING(compound)); + int compoundLength = AS_STRING(compound)->length; if (!IS_NULL(second)) { if (IS_BOOLEAN(second)) { freeLiteral(second); @@ -823,7 +824,7 @@ int _index(Interpreter* interpreter, LiteralArray* arguments) { if (IS_NULL(second)) { //assign only a single character //set the "first" within the array, then skip out - if (strlen( AS_STRING(assign) ) != 1) { + if (AS_STRING(assign)->length != 1) { //something is weird - skip out freeLiteral(op); freeLiteral(assign); @@ -836,9 +837,11 @@ int _index(Interpreter* interpreter, LiteralArray* arguments) { return -1; } - AS_STRING(compound)[AS_INTEGER(first)] = AS_STRING(assign)[0]; + Literal copiedCompound = TO_STRING_LITERAL(deepCopyRefString(AS_STRING(compound))); - pushLiteralArray(&interpreter->stack, compound); + AS_STRING(copiedCompound)->data[AS_INTEGER(first)] = toCString(AS_STRING(assign))[0]; + + pushLiteralArray(&interpreter->stack, copiedCompound); freeLiteral(op); freeLiteral(assign); @@ -871,18 +874,18 @@ int _index(Interpreter* interpreter, LiteralArray* arguments) { int resultIndex = 0; if (AS_INTEGER(third) == 1 || AS_INTEGER(third) == -1) { for (int i = 0; i < AS_INTEGER(first); i++) { - result[ resultIndex++ ] = AS_STRING(compound)[ i ]; + result[ resultIndex++ ] = toCString(AS_STRING(compound))[ i ]; } - int assignLength = strlen(AS_STRING(assign)); + int assignLength = AS_STRING(assign)->length; int min = AS_INTEGER(third) > 0 ? 0 : assignLength - 1; for (int i = min; i >= 0 && i < assignLength; i += AS_INTEGER(third)) { - result[ resultIndex++ ] = AS_STRING(assign)[ i ]; + result[ resultIndex++ ] = toCString(AS_STRING(assign))[ i ]; } for (int i = AS_INTEGER(second) + 1; i < compoundLength; i++) { - result[ resultIndex++ ] = AS_STRING(compound)[ i ]; + result[ resultIndex++ ] = toCString(AS_STRING(compound))[ i ]; } result[ resultIndex ] = '\0'; @@ -891,26 +894,26 @@ int _index(Interpreter* interpreter, LiteralArray* arguments) { //else override elements of the array instead else { //copy compound to result - snprintf(result, MAX_STRING_LENGTH, "%s", AS_STRING(compound)); + snprintf(result, MAX_STRING_LENGTH, "%s", toCString(AS_STRING(compound))); - int assignLength = strlen(AS_STRING(assign)); + int assignLength = AS_STRING(assign)->length; 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 < assignLength; i += AS_INTEGER(third)) { - result[ i ] = AS_STRING(assign)[ assignIndex++ ]; + result[ i ] = toCString(AS_STRING(assign))[ assignIndex++ ]; } resultIndex = strlen(result); } //finally, swap out the compound for the result freeLiteral(compound); - compound = TO_STRING_LITERAL(copyString(result, resultIndex), resultIndex); + compound = TO_STRING_LITERAL(createRefStringLength(result, resultIndex)); FREE_ARRAY(char, result, MAX_STRING_LENGTH); } - else if (IS_STRING(op) && !strcmp( AS_STRING(op), "+=")) { + else if (IS_STRING(op) && equalsRefStringCString(AS_STRING(op), "+=")) { Literal tmp = addition(interpreter, compound, assign); freeLiteral(compound); compound = tmp; //don't clear tmp @@ -1229,7 +1232,7 @@ int _pop(Interpreter* interpreter, LiteralArray* arguments) { int _length(Interpreter* interpreter, LiteralArray* arguments) { //if wrong number of arguments, fail if (arguments->count != 1) { - interpreter->errorOutput("Incorrect number of arguments to _get\n"); + interpreter->errorOutput("Incorrect number of arguments to _length\n"); return -1; } @@ -1257,7 +1260,7 @@ int _length(Interpreter* interpreter, LiteralArray* arguments) { } case LITERAL_STRING: { - Literal lit = TO_INTEGER_LITERAL( strlen(AS_STRING(obj)) ); + Literal lit = TO_INTEGER_LITERAL( AS_STRING(obj)->length ); pushLiteralArray(&interpreter->stack, lit); freeLiteral(lit); break; diff --git a/source/interpreter.c b/source/interpreter.c index 44e238b..1ca1425 100644 --- a/source/interpreter.c +++ b/source/interpreter.c @@ -34,7 +34,7 @@ bool injectNativeFn(Interpreter* interpreter, char* name, NativeFn func) { } int identifierLength = strlen(name); - Literal identifier = TO_IDENTIFIER_LITERAL(copyString(name, identifierLength), identifierLength); + Literal identifier = TO_IDENTIFIER_LITERAL(createRefStringLength(name, identifierLength)); //make sure the name isn't taken if (existsLiteralDictionary(&interpreter->scope->variables, identifier)) { @@ -64,7 +64,7 @@ bool injectNativeHook(Interpreter* interpreter, char* name, HookFn hook) { } int identifierLength = strlen(name); - Literal identifier = TO_IDENTIFIER_LITERAL(copyString(name, identifierLength), identifierLength); + Literal identifier = TO_IDENTIFIER_LITERAL(createRefStringLength(name, identifierLength)); //make sure the name isn't taken if (existsLiteralDictionary(interpreter->hooks, identifier)) { @@ -235,7 +235,7 @@ static bool execAssert(Interpreter* interpreter) { } if (IS_NULL(lhs) || !IS_TRUTHY(lhs)) { - (*interpreter->assertOutput)(AS_STRING(rhs)); + (*interpreter->assertOutput)(toCString(AS_STRING(rhs))); freeLiteral(rhs); interpreter->panic = true; return false; @@ -387,7 +387,7 @@ static bool execArithmetic(Interpreter* interpreter, Opcode opcode) { //special case for string concatenation ONLY if (IS_STRING(lhs) && IS_STRING(rhs)) { //check for overflow - int totalLength = strlen(AS_STRING(lhs)) + strlen(AS_STRING(rhs)); + int totalLength = AS_STRING(lhs)->length + AS_STRING(rhs)->length; if (totalLength > MAX_STRING_LENGTH) { interpreter->errorOutput("Can't concatenate these strings (result is too long)\n"); return false; @@ -395,9 +395,11 @@ 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, totalLength), totalLength); + snprintf(buffer, MAX_STRING_LENGTH, "%s%s", toCString(AS_STRING(lhs)), toCString(AS_STRING(rhs))); + Literal literal = TO_STRING_LITERAL(createRefStringLength(buffer, totalLength)); pushLiteralArray(&interpreter->stack, literal); + + //cleanup freeLiteral(literal); freeLiteral(lhs); freeLiteral(rhs); @@ -751,7 +753,7 @@ static bool execValCast(Interpreter* interpreter) { if (IS_STRING(value)) { int val = 0; - sscanf(AS_STRING(value), "%d", &val); + sscanf(toCString(AS_STRING(value)), "%d", &val); result = TO_INTEGER_LITERAL(val); } break; @@ -771,7 +773,7 @@ static bool execValCast(Interpreter* interpreter) { if (IS_STRING(value)) { float val = 0; - sscanf(AS_STRING(value), "%f", &val); + sscanf(toCString(AS_STRING(value)), "%f", &val); result = TO_FLOAT_LITERAL(val); } break; @@ -781,21 +783,21 @@ static bool execValCast(Interpreter* interpreter) { char* str = AS_BOOLEAN(value) ? "true" : "false"; int length = strlen(str); - result = TO_STRING_LITERAL(copyString(str, length), length); + result = TO_STRING_LITERAL(createRefStringLength(str, length)); //TODO: static reference optimisation? } if (IS_INTEGER(value)) { char buffer[128]; snprintf(buffer, 128, "%d", AS_INTEGER(value)); int length = strlen(buffer); - result = TO_STRING_LITERAL(copyString(buffer, length), length); + result = TO_STRING_LITERAL(createRefStringLength(buffer, length)); } if (IS_FLOAT(value)) { char buffer[128]; snprintf(buffer, 128, "%g", AS_FLOAT(value)); int length = strlen(buffer); - result = TO_STRING_LITERAL(copyString(buffer, length), length); + result = TO_STRING_LITERAL(createRefStringLength(buffer, length)); } if (IS_STRING(value)) { @@ -1143,12 +1145,12 @@ static bool execFnCall(Interpreter* interpreter, bool looseFirstArgument) { //let's screw with the fn name, too if (looseFirstArgument) { - int length = strlen(AS_IDENTIFIER(identifier)) + 1; + int length = AS_IDENTIFIER(identifier)->length + 1; char buffer[MAX_STRING_LENGTH]; - snprintf(buffer, MAX_STRING_LENGTH, "_%s", AS_IDENTIFIER(identifier)); //prepend an underscore + snprintf(buffer, MAX_STRING_LENGTH, "_%s", toCString(AS_IDENTIFIER(identifier))); //prepend an underscore freeLiteral(identifier); - identifier = TO_IDENTIFIER_LITERAL(copyString(buffer, length), length); + identifier = TO_IDENTIFIER_LITERAL(createRefStringLength(buffer, length)); } Literal func = identifier; @@ -1219,7 +1221,7 @@ bool callLiteralFn(Interpreter* interpreter, Literal func, LiteralArray* argumen initLiteralArray(&inner.literalCache); inner.scope = pushScope(func.as.function.scope); inner.bytecode = AS_FUNCTION(func).bytecode; - inner.length = func.as.function.length; + inner.length = AS_FUNCTION(func).length; inner.count = 0; inner.codeStart = -1; inner.depth = interpreter->depth + 1; @@ -1414,7 +1416,7 @@ bool callLiteralFn(Interpreter* interpreter, Literal func, LiteralArray* argumen } bool callFn(Interpreter* interpreter, char* name, LiteralArray* arguments, LiteralArray* returns) { - Literal key = TO_IDENTIFIER_LITERAL(copyString(name, strlen(name)), strlen(name)); + Literal key = TO_IDENTIFIER_LITERAL(createRefStringLength(name, strlen(name))); Literal val = TO_NULL_LITERAL; if (!isDelcaredScopeVariable(interpreter->scope, key)) { @@ -1605,7 +1607,7 @@ static bool execIndex(Interpreter* interpreter, bool assignIntermediate) { Literal func = TO_NULL_LITERAL; char* keyStr = "_index"; int keyStrLength = strlen(keyStr); - Literal key = TO_IDENTIFIER_LITERAL(copyString(keyStr, keyStrLength), keyStrLength); + Literal key = TO_IDENTIFIER_LITERAL(createRefStringLength(keyStr, keyStrLength)); if (!getScopeVariable(interpreter->scope, key, &func) || !IS_FUNCTION_NATIVE(func)) { interpreter->errorOutput("couldn't get the _index function\n"); @@ -1704,7 +1706,7 @@ static bool execIndexAssign(Interpreter* interpreter) { Literal func = TO_NULL_LITERAL; char* keyStr = "_index"; int keyStrLength = strlen(keyStr); - Literal key = TO_IDENTIFIER_LITERAL(copyString(keyStr, keyStrLength), keyStrLength); + Literal key = TO_IDENTIFIER_LITERAL(createRefStringLength(keyStr, keyStrLength)); if (!getScopeVariable(interpreter->scope, key, &func) || !IS_FUNCTION_NATIVE(func)) { interpreter->errorOutput("couldn't get the _index function\n"); @@ -1760,7 +1762,7 @@ static bool execIndexAssign(Interpreter* interpreter) { } int opLength = strlen(opStr); - Literal op = TO_STRING_LITERAL(copyString(opStr, opLength), opLength); + Literal op = TO_STRING_LITERAL(createRefStringLength(opStr, opLength)); //TODO: static reference optimisation? //build the argument list LiteralArray arguments; @@ -1815,7 +1817,7 @@ static bool execIndexAssign(Interpreter* interpreter) { char* opStr = "="; //shadow, but force assignment int opLength = strlen(opStr); - op = TO_STRING_LITERAL(copyString(opStr, opLength), opLength); + op = TO_STRING_LITERAL(createRefStringLength(opStr, opLength)); //TODO: static reference optimisation? //assign to the idn / compound - with _index pushLiteralArray(&arguments, idn); @@ -2194,7 +2196,7 @@ static void readInterpreterSections(Interpreter* interpreter) { case LITERAL_STRING: { char* s = readString(interpreter->bytecode, &interpreter->count); int length = strlen(s); - Literal literal = TO_STRING_LITERAL( copyString(s, length), length); + Literal literal = TO_STRING_LITERAL(createRefStringLength(s, length)); pushLiteralArray(&interpreter->literalCache, literal); freeLiteral(literal); @@ -2290,13 +2292,13 @@ static void readInterpreterSections(Interpreter* interpreter) { char* str = readString(interpreter->bytecode, &interpreter->count); int length = strlen(str); - Literal identifier = TO_IDENTIFIER_LITERAL(copyString(str, length), length); + Literal identifier = TO_IDENTIFIER_LITERAL(createRefStringLength(str, length)); pushLiteralArray(&interpreter->literalCache, identifier); #ifndef TOY_EXPORT if (command.verbose) { - printf("(identifier %s (hash: %x))\n", AS_IDENTIFIER(identifier), identifier.as.identifier.hash); + printf("(identifier %s (hash: %x))\n", toCString(AS_IDENTIFIER(identifier)), identifier.as.identifier.hash); } #endif diff --git a/source/parser.c b/source/parser.c index 141d7f3..bb165e3 100644 --- a/source/parser.c +++ b/source/parser.c @@ -1616,7 +1616,7 @@ static void fnDecl(Parser* parser, ASTNode** nodeHandle) { error(parser, parser->previous, "Identifiers can only be a maximum of 256 characters long"); } - Literal argIdentifier = TO_IDENTIFIER_LITERAL(createRefStringLength(identifierToken.lexeme, length)); + Literal argIdentifier = TO_IDENTIFIER_LITERAL(createRefStringLength(argIdentifierToken.lexeme, length)); //set the type (array of any types) Literal argTypeLiteral = TO_TYPE_LITERAL(LITERAL_FUNCTION_ARG_REST, false); @@ -1651,7 +1651,7 @@ static void fnDecl(Parser* parser, ASTNode** nodeHandle) { error(parser, parser->previous, "Identifiers can only be a maximum of 256 characters long"); } - Literal argIdentifier = TO_IDENTIFIER_LITERAL(createRefStringLength(identifierToken.lexeme, length)); + Literal argIdentifier = TO_IDENTIFIER_LITERAL(createRefStringLength(argIdentifierToken.lexeme, length)); //read optional type of the identifier Literal argTypeLiteral; diff --git a/test/makefile b/test/makefile index ccc0d68..38d58b7 100644 --- a/test/makefile +++ b/test/makefile @@ -22,6 +22,9 @@ TARGETS+=../source/parser.c #compiler TARGETS+=../source/compiler.c +#interpreter +TARGETS+=../source/interpreter.c ../source/builtin.c + TESTS = $(wildcard test_*.c) OBJ = $(addprefix $(ODIR)/,$(TARGETS:../source/%.c=%.o)) $(addprefix $(ODIR)/,$(TESTS:.c=.o)) diff --git a/test/xtest_interpreter.c b/test/test_interpreter.c similarity index 98% rename from test/xtest_interpreter.c rename to test/test_interpreter.c index 3df0664..ea8f6a5 100644 --- a/test/xtest_interpreter.c +++ b/test/test_interpreter.c @@ -75,16 +75,16 @@ unsigned char* compileString(char* source, size_t* size) { ASTNode* node = scanParser(&parser); while(node != NULL) { //pack up and leave - if (node->type == AST_NODEERROR) { + if (node->type == AST_NODE_ERROR) { printf(ERROR "error node detected\n" RESET); - freeNode(node); + freeASTNode(node); freeCompiler(&compiler); freeParser(&parser); return NULL; } writeCompiler(&compiler, node); - freeNode(node); + freeASTNode(node); node = scanParser(&parser); } @@ -168,7 +168,7 @@ int main() { runInterpreter(&interpreter, bytecode, size); //cleanup - freeNode(node); + freeASTNode(node); freeParser(&parser); freeCompiler(&compiler); freeInterpreter(&interpreter);