diff --git a/repl/lib_runner.c b/repl/lib_runner.c index 6f776e4..9433873 100644 --- a/repl/lib_runner.c +++ b/repl/lib_runner.c @@ -1,23 +1,23 @@ #include "lib_runner.h" -#include "memory.h" -#include "interpreter.h" +#include "toy_memory.h" +#include "toy_interpreter.h" #include "repl_tools.h" #include #include -typedef struct Runner { - Interpreter interpreter; +typedef struct Toy_Runner { + Toy_Interpreter interpreter; unsigned char* bytecode; size_t size; bool dirty; -} Runner; +} Toy_Runner; //Toy native functions -static int nativeLoadScript(Interpreter* interpreter, LiteralArray* arguments) { +static int nativeLoadScript(Toy_Interpreter* interpreter, Toy_LiteralArray* arguments) { //arguments if (arguments->count != 1) { interpreter->errorOutput("Incorrect number of arguments to loadScript\n"); @@ -25,60 +25,60 @@ static int nativeLoadScript(Interpreter* interpreter, LiteralArray* arguments) { } //get the argument - Literal drivePathLiteral = popLiteralArray(arguments); - RefString* drivePath = copyRefString(AS_STRING(drivePathLiteral)); + Toy_Literal drivePathLiteral = Toy_popLiteralArray(arguments); + 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 int driveLength = 0; - while (toCString(drivePath)[driveLength] != ':') { - if (driveLength >= lengthRefString(drivePath)) { + while (Toy_toCString(drivePath)[driveLength] != ':') { + if (driveLength >= Toy_lengthRefString(drivePath)) { interpreter->errorOutput("Incorrect drive path format given to loadScript\n"); - deleteRefString(drivePath); - freeLiteral(drivePathLiteral); + Toy_deleteRefString(drivePath); + Toy_freeLiteral(drivePathLiteral); return -1; } driveLength++; } - RefString* drive = createRefStringLength(toCString(drivePath), driveLength); - RefString* path = createRefStringLength( &toCString(drivePath)[driveLength + 1], lengthRefString(drivePath) - driveLength ); + Toy_RefString* drive = Toy_createRefStringLength(Toy_toCString(drivePath), driveLength); + Toy_RefString* path = Toy_createRefStringLength( &Toy_toCString(drivePath)[driveLength + 1], Toy_lengthRefString(drivePath) - driveLength ); //get the real drive file path - Literal driveLiteral = TO_STRING_LITERAL(drive); //NOTE: driveLiteral takes ownership of the refString - Literal realDriveLiteral = getLiteralDictionary(getDriveDictionary(), driveLiteral); + Toy_Literal driveLiteral = TOY_TO_STRING_LITERAL(drive); //NOTE: driveLiteral takes ownership of the refString + Toy_Literal realDriveLiteral = Toy_getLiteralDictionary(Toy_getDriveDictionary(), driveLiteral); - if (!IS_STRING(realDriveLiteral)) { + if (!TOY_IS_STRING(realDriveLiteral)) { interpreter->errorOutput("Incorrect literal type found for drive: "); - printLiteralCustom(realDriveLiteral, interpreter->errorOutput); + Toy_printLiteralCustom(realDriveLiteral, interpreter->errorOutput); interpreter->errorOutput("\n"); - freeLiteral(realDriveLiteral); - freeLiteral(driveLiteral); - deleteRefString(path); - deleteRefString(drivePath); - freeLiteral(drivePathLiteral); + Toy_freeLiteral(realDriveLiteral); + Toy_freeLiteral(driveLiteral); + Toy_deleteRefString(path); + Toy_deleteRefString(drivePath); + Toy_freeLiteral(drivePathLiteral); return -1; } //get the final real file path (concat) TODO: move this concat to refstring library - RefString* realDrive = copyRefString(AS_STRING(realDriveLiteral)); - int realLength = lengthRefString(realDrive) + lengthRefString(path); + Toy_RefString* realDrive = Toy_copyRefString(TOY_AS_STRING(realDriveLiteral)); + int realLength = Toy_lengthRefString(realDrive) + Toy_lengthRefString(path); - char* filePath = ALLOCATE(char, realLength + 1); //+1 for null - snprintf(filePath, realLength, "%s%s", toCString(realDrive), toCString(path)); + char* filePath = TOY_ALLOCATE(char, realLength + 1); //+1 for null + snprintf(filePath, realLength, "%s%s", Toy_toCString(realDrive), Toy_toCString(path)); //clean up the drivepath stuff - deleteRefString(realDrive); - freeLiteral(realDriveLiteral); - freeLiteral(driveLiteral); - deleteRefString(path); - deleteRefString(drivePath); - freeLiteral(drivePathLiteral); + Toy_deleteRefString(realDrive); + Toy_freeLiteral(realDriveLiteral); + Toy_freeLiteral(driveLiteral); + Toy_deleteRefString(path); + Toy_deleteRefString(drivePath); + Toy_freeLiteral(drivePathLiteral); //check for file extensions if (!(filePath[realLength - 5] == '.' && filePath[realLength - 4] == 't' && filePath[realLength - 3] == 'o' && filePath[realLength - 2] == 'y')) { interpreter->errorOutput("Bad script file extension (expected .toy)\n"); - FREE_ARRAY(char, filePath, realLength); + TOY_FREE_ARRAY(char, filePath, realLength); return -1; } @@ -86,21 +86,21 @@ static int nativeLoadScript(Interpreter* interpreter, LiteralArray* arguments) { for (int i = 0; i < realLength - 1; i++) { if (filePath[i] == '.' && filePath[i + 1] == '.') { interpreter->errorOutput("Parent directory access not allowed\n"); - FREE_ARRAY(char, filePath, realLength); + TOY_FREE_ARRAY(char, filePath, realLength); return -1; } } //load and compile the bytecode size_t fileSize = 0; - char* source = readFile(filePath, &fileSize); + char* source = Toy_readFile(filePath, &fileSize); if (!source) { interpreter->errorOutput("Failed to load source file\n"); return -1; } - unsigned char* bytecode = compileString(source, &fileSize); + unsigned char* bytecode = Toy_compileString(source, &fileSize); free((void*)source); if (!bytecode) { @@ -109,27 +109,27 @@ static int nativeLoadScript(Interpreter* interpreter, LiteralArray* arguments) { } //build the runner object - Runner* runner = ALLOCATE(Runner, 1); - setInterpreterPrint(&runner->interpreter, interpreter->printOutput); - setInterpreterAssert(&runner->interpreter, interpreter->assertOutput); - setInterpreterError(&runner->interpreter, interpreter->errorOutput); + Toy_Runner* runner = TOY_ALLOCATE(Toy_Runner, 1); + Toy_setInterpreterPrint(&runner->interpreter, interpreter->printOutput); + Toy_setInterpreterAssert(&runner->interpreter, interpreter->assertOutput); + Toy_setInterpreterError(&runner->interpreter, interpreter->errorOutput); runner->interpreter.hooks = interpreter->hooks; runner->interpreter.scope = NULL; - resetInterpreter(&runner->interpreter); + Toy_resetInterpreter(&runner->interpreter); runner->bytecode = bytecode; runner->size = fileSize; runner->dirty = false; //build the opaque object, and push it to the stack - Literal runnerLiteral = TO_OPAQUE_LITERAL(runner, OPAQUE_TAG_RUNNER); - pushLiteralArray(&interpreter->stack, runnerLiteral); + Toy_Literal runnerLiteral = TOY_TO_OPAQUE_LITERAL(runner, TOY_OPAQUE_TAG_RUNNER); + Toy_pushLiteralArray(&interpreter->stack, runnerLiteral); - FREE_ARRAY(char, filePath, realLength); + TOY_FREE_ARRAY(char, filePath, realLength); return 1; } -static int nativeLoadScriptBytecode(Interpreter* interpreter, LiteralArray* arguments) { +static int nativeLoadScriptBytecode(Toy_Interpreter* interpreter, Toy_LiteralArray* arguments) { //arguments if (arguments->count != 1) { interpreter->errorOutput("Incorrect number of arguments to loadScriptBytecode\n"); @@ -137,60 +137,60 @@ static int nativeLoadScriptBytecode(Interpreter* interpreter, LiteralArray* argu } //get the argument - Literal drivePathLiteral = popLiteralArray(arguments); - RefString* drivePath = copyRefString(AS_STRING(drivePathLiteral)); + Toy_Literal drivePathLiteral = Toy_popLiteralArray(arguments); + 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 int driveLength = 0; - while (toCString(drivePath)[driveLength] != ':') { - if (driveLength >= lengthRefString(drivePath)) { + while (Toy_toCString(drivePath)[driveLength] != ':') { + if (driveLength >= Toy_lengthRefString(drivePath)) { interpreter->errorOutput("Incorrect drive path format given to loadScriptBytecode\n"); - deleteRefString(drivePath); - freeLiteral(drivePathLiteral); + Toy_deleteRefString(drivePath); + Toy_freeLiteral(drivePathLiteral); return -1; } driveLength++; } - RefString* drive = createRefStringLength(toCString(drivePath), driveLength); - RefString* path = createRefStringLength( &toCString(drivePath)[driveLength + 1], lengthRefString(drivePath) - driveLength ); + Toy_RefString* drive = Toy_createRefStringLength(Toy_toCString(drivePath), driveLength); + Toy_RefString* path = Toy_createRefStringLength( &Toy_toCString(drivePath)[driveLength + 1], Toy_lengthRefString(drivePath) - driveLength ); //get the real drive file path - Literal driveLiteral = TO_STRING_LITERAL(drive); //NOTE: driveLiteral takes ownership of the refString - Literal realDriveLiteral = getLiteralDictionary(getDriveDictionary(), driveLiteral); + Toy_Literal driveLiteral = TOY_TO_STRING_LITERAL(drive); //NOTE: driveLiteral takes ownership of the refString + Toy_Literal realDriveLiteral = Toy_getLiteralDictionary(Toy_getDriveDictionary(), driveLiteral); - if (!IS_STRING(realDriveLiteral)) { + if (!TOY_IS_STRING(realDriveLiteral)) { interpreter->errorOutput("Incorrect literal type found for drive: "); - printLiteralCustom(realDriveLiteral, interpreter->errorOutput); + Toy_printLiteralCustom(realDriveLiteral, interpreter->errorOutput); interpreter->errorOutput("\n"); - freeLiteral(realDriveLiteral); - freeLiteral(driveLiteral); - deleteRefString(path); - deleteRefString(drivePath); - freeLiteral(drivePathLiteral); + Toy_freeLiteral(realDriveLiteral); + Toy_freeLiteral(driveLiteral); + Toy_deleteRefString(path); + Toy_deleteRefString(drivePath); + Toy_freeLiteral(drivePathLiteral); return -1; } //get the final real file path (concat) TODO: move this concat to refstring library - RefString* realDrive = copyRefString(AS_STRING(realDriveLiteral)); - int realLength = lengthRefString(realDrive) + lengthRefString(path); + Toy_RefString* realDrive = Toy_copyRefString(TOY_AS_STRING(realDriveLiteral)); + int realLength = Toy_lengthRefString(realDrive) + Toy_lengthRefString(path); - char* filePath = ALLOCATE(char, realLength + 1); //+1 for null - snprintf(filePath, realLength, "%s%s", toCString(realDrive), toCString(path)); + char* filePath = TOY_ALLOCATE(char, realLength + 1); //+1 for null + snprintf(filePath, realLength, "%s%s", Toy_toCString(realDrive), Toy_toCString(path)); //clean up the drivepath stuff - deleteRefString(realDrive); - freeLiteral(realDriveLiteral); - freeLiteral(driveLiteral); - deleteRefString(path); - deleteRefString(drivePath); - freeLiteral(drivePathLiteral); + Toy_deleteRefString(realDrive); + Toy_freeLiteral(realDriveLiteral); + Toy_freeLiteral(driveLiteral); + Toy_deleteRefString(path); + Toy_deleteRefString(drivePath); + Toy_freeLiteral(drivePathLiteral); //check for file extensions if (!(filePath[realLength - 4] == '.' && filePath[realLength - 3] == 't' && filePath[realLength - 2] == 'b')) { interpreter->errorOutput("Bad binary file extension (expected .tb)\n"); - FREE_ARRAY(char, filePath, realLength); + TOY_FREE_ARRAY(char, filePath, realLength); return -1; } @@ -198,14 +198,14 @@ static int nativeLoadScriptBytecode(Interpreter* interpreter, LiteralArray* argu for (int i = 0; i < realLength - 1; i++) { if (filePath[i] == '.' && filePath[i + 1] == '.') { interpreter->errorOutput("Parent directory access not allowed\n"); - FREE_ARRAY(char, filePath, realLength); + TOY_FREE_ARRAY(char, filePath, realLength); return -1; } } //load the bytecode size_t fileSize = 0; - unsigned char* bytecode = (unsigned char*)readFile(filePath, &fileSize); + unsigned char* bytecode = (unsigned char*)Toy_readFile(filePath, &fileSize); if (!bytecode) { interpreter->errorOutput("Failed to load bytecode file\n"); @@ -213,27 +213,27 @@ static int nativeLoadScriptBytecode(Interpreter* interpreter, LiteralArray* argu } //build the runner object - Runner* runner = ALLOCATE(Runner, 1); - setInterpreterPrint(&runner->interpreter, interpreter->printOutput); - setInterpreterAssert(&runner->interpreter, interpreter->assertOutput); - setInterpreterError(&runner->interpreter, interpreter->errorOutput); + Toy_Runner* runner = TOY_ALLOCATE(Toy_Runner, 1); + Toy_setInterpreterPrint(&runner->interpreter, interpreter->printOutput); + Toy_setInterpreterAssert(&runner->interpreter, interpreter->assertOutput); + Toy_setInterpreterError(&runner->interpreter, interpreter->errorOutput); runner->interpreter.hooks = interpreter->hooks; runner->interpreter.scope = NULL; - resetInterpreter(&runner->interpreter); + Toy_resetInterpreter(&runner->interpreter); runner->bytecode = bytecode; runner->size = fileSize; runner->dirty = false; //build the opaque object, and push it to the stack - Literal runnerLiteral = TO_OPAQUE_LITERAL(runner, OPAQUE_TAG_RUNNER); - pushLiteralArray(&interpreter->stack, runnerLiteral); + Toy_Literal runnerLiteral = TOY_TO_OPAQUE_LITERAL(runner, TOY_OPAQUE_TAG_RUNNER); + Toy_pushLiteralArray(&interpreter->stack, runnerLiteral); - FREE_ARRAY(char, filePath, realLength); + TOY_FREE_ARRAY(char, filePath, realLength); return 1; } -static int nativeRunScript(Interpreter* interpreter, LiteralArray* arguments) { +static int nativeRunScript(Toy_Interpreter* interpreter, Toy_LiteralArray* arguments) { //no arguments if (arguments->count != 1) { interpreter->errorOutput("Incorrect number of arguments to _runScript\n"); @@ -241,40 +241,40 @@ static int nativeRunScript(Interpreter* interpreter, LiteralArray* arguments) { } //get the runner object - Literal runnerLiteral = popLiteralArray(arguments); + Toy_Literal runnerLiteral = Toy_popLiteralArray(arguments); - Literal runnerIdn = runnerLiteral; - if (IS_IDENTIFIER(runnerLiteral) && parseIdentifierToValue(interpreter, &runnerLiteral)) { - freeLiteral(runnerIdn); + Toy_Literal runnerIdn = runnerLiteral; + if (TOY_IS_IDENTIFIER(runnerLiteral) && Toy_parseIdentifierToValue(interpreter, &runnerLiteral)) { + Toy_freeLiteral(runnerIdn); } - if (OPAQUE_TAG(runnerLiteral) != OPAQUE_TAG_RUNNER) { + if (TOY_GET_OPAQUE_TAG(runnerLiteral) != TOY_OPAQUE_TAG_RUNNER) { interpreter->errorOutput("Unrecognized opaque literal in _runScript\n"); return -1; } - Runner* runner = AS_OPAQUE(runnerLiteral); + Toy_Runner* runner = TOY_AS_OPAQUE(runnerLiteral); //run if (runner->dirty) { interpreter->errorOutput("Can't re-run a dirty script (try resetting it first)\n"); - freeLiteral(runnerLiteral); + Toy_freeLiteral(runnerLiteral); return -1; } - unsigned char* bytecodeCopy = ALLOCATE(unsigned char, runner->size); + unsigned char* bytecodeCopy = TOY_ALLOCATE(unsigned char, runner->size); memcpy(bytecodeCopy, runner->bytecode, runner->size); //need a COPY of the bytecode, because the interpreter eats it - runInterpreter(&runner->interpreter, bytecodeCopy, runner->size); + Toy_runInterpreter(&runner->interpreter, bytecodeCopy, runner->size); runner->dirty = true; //cleanup - freeLiteral(runnerLiteral); + Toy_freeLiteral(runnerLiteral); return 0; } -static int nativeGetScriptVar(Interpreter* interpreter, LiteralArray* arguments) { +static int nativeGetScriptVar(Toy_Interpreter* interpreter, Toy_LiteralArray* arguments) { //no arguments if (arguments->count != 2) { interpreter->errorOutput("Incorrect number of arguments to _getScriptVar\n"); @@ -282,50 +282,50 @@ static int nativeGetScriptVar(Interpreter* interpreter, LiteralArray* arguments) } //get the runner object - Literal varName = popLiteralArray(arguments); - Literal runnerLiteral = popLiteralArray(arguments); + Toy_Literal varName = Toy_popLiteralArray(arguments); + Toy_Literal runnerLiteral = Toy_popLiteralArray(arguments); - Literal varNameIdn = varName; - if (IS_IDENTIFIER(varName) && parseIdentifierToValue(interpreter, &varName)) { - freeLiteral(varNameIdn); + Toy_Literal varNameIdn = varName; + if (TOY_IS_IDENTIFIER(varName) && Toy_parseIdentifierToValue(interpreter, &varName)) { + Toy_freeLiteral(varNameIdn); } - Literal runnerIdn = runnerLiteral; - if (IS_IDENTIFIER(runnerLiteral) && parseIdentifierToValue(interpreter, &runnerLiteral)) { - freeLiteral(runnerIdn); + Toy_Literal runnerIdn = runnerLiteral; + if (TOY_IS_IDENTIFIER(runnerLiteral) && Toy_parseIdentifierToValue(interpreter, &runnerLiteral)) { + Toy_freeLiteral(runnerIdn); } - if (OPAQUE_TAG(runnerLiteral) != OPAQUE_TAG_RUNNER) { + if (TOY_GET_OPAQUE_TAG(runnerLiteral) != TOY_OPAQUE_TAG_RUNNER) { interpreter->errorOutput("Unrecognized opaque literal in _runScript\n"); return -1; } - Runner* runner = AS_OPAQUE(runnerLiteral); + Toy_Runner* runner = TOY_AS_OPAQUE(runnerLiteral); //dirty check if (!runner->dirty) { interpreter->errorOutput("Can't access variable from a non-dirty script (try running it first)\n"); - freeLiteral(runnerLiteral); + Toy_freeLiteral(runnerLiteral); return -1; } //get the desired variable - Literal varIdn = TO_IDENTIFIER_LITERAL(copyRefString(AS_STRING(varName))); - Literal result = TO_NULL_LITERAL; - getScopeVariable(runner->interpreter.scope, varIdn, &result); + Toy_Literal varIdn = TOY_TO_IDENTIFIER_LITERAL(Toy_copyRefString(TOY_AS_STRING(varName))); + Toy_Literal result = TOY_TO_NULL_LITERAL; + Toy_getScopeVariable(runner->interpreter.scope, varIdn, &result); - pushLiteralArray(&interpreter->stack, result); + Toy_pushLiteralArray(&interpreter->stack, result); //cleanup - freeLiteral(result); - freeLiteral(varIdn); - freeLiteral(varName); - freeLiteral(runnerLiteral); + Toy_freeLiteral(result); + Toy_freeLiteral(varIdn); + Toy_freeLiteral(varName); + Toy_freeLiteral(runnerLiteral); return 1; } -static int nativeCallScriptFn(Interpreter* interpreter, LiteralArray* arguments) { +static int nativeCallScriptFn(Toy_Interpreter* interpreter, Toy_LiteralArray* arguments) { //no arguments if (arguments->count < 2) { interpreter->errorOutput("Incorrect number of arguments to _callScriptFn\n"); @@ -333,96 +333,96 @@ static int nativeCallScriptFn(Interpreter* interpreter, LiteralArray* arguments) } //get the rest args - LiteralArray tmp; - initLiteralArray(&tmp); + Toy_LiteralArray tmp; + Toy_initLiteralArray(&tmp); while (arguments->count > 2) { - Literal lit = popLiteralArray(arguments); - pushLiteralArray(&tmp, lit); - freeLiteral(lit); + Toy_Literal lit = Toy_popLiteralArray(arguments); + Toy_pushLiteralArray(&tmp, lit); + Toy_freeLiteral(lit); } - LiteralArray rest; - initLiteralArray(&rest); + Toy_LiteralArray rest; + Toy_initLiteralArray(&rest); while (tmp.count) { //correct the order of the rest args - Literal lit = popLiteralArray(&tmp); - pushLiteralArray(&rest, lit); - freeLiteral(lit); + Toy_Literal lit = Toy_popLiteralArray(&tmp); + Toy_pushLiteralArray(&rest, lit); + Toy_freeLiteral(lit); } - freeLiteralArray(&tmp); + Toy_freeLiteralArray(&tmp); //get the runner object - Literal varName = popLiteralArray(arguments); - Literal runnerLiteral = popLiteralArray(arguments); + Toy_Literal varName = Toy_popLiteralArray(arguments); + Toy_Literal runnerLiteral = Toy_popLiteralArray(arguments); - Literal varNameIdn = varName; - if (IS_IDENTIFIER(varName) && parseIdentifierToValue(interpreter, &varName)) { - freeLiteral(varNameIdn); + Toy_Literal varNameIdn = varName; + if (TOY_IS_IDENTIFIER(varName) && Toy_parseIdentifierToValue(interpreter, &varName)) { + Toy_freeLiteral(varNameIdn); } - Literal runnerIdn = runnerLiteral; - if (IS_IDENTIFIER(runnerLiteral) && parseIdentifierToValue(interpreter, &runnerLiteral)) { - freeLiteral(runnerIdn); + Toy_Literal runnerIdn = runnerLiteral; + if (TOY_IS_IDENTIFIER(runnerLiteral) && Toy_parseIdentifierToValue(interpreter, &runnerLiteral)) { + Toy_freeLiteral(runnerIdn); } - if (OPAQUE_TAG(runnerLiteral) != OPAQUE_TAG_RUNNER) { + if (TOY_GET_OPAQUE_TAG(runnerLiteral) != TOY_OPAQUE_TAG_RUNNER) { interpreter->errorOutput("Unrecognized opaque literal in _runScript\n"); return -1; } - Runner* runner = AS_OPAQUE(runnerLiteral); + Toy_Runner* runner = TOY_AS_OPAQUE(runnerLiteral); //dirty check if (!runner->dirty) { interpreter->errorOutput("Can't access fn from a non-dirty script (try running it first)\n"); - freeLiteral(runnerLiteral); - freeLiteralArray(&rest); + Toy_freeLiteral(runnerLiteral); + Toy_freeLiteralArray(&rest); return -1; } //get the desired variable - Literal varIdn = TO_IDENTIFIER_LITERAL(copyRefString(AS_STRING(varName))); - Literal fn = TO_NULL_LITERAL; - getScopeVariable(runner->interpreter.scope, varIdn, &fn); + Toy_Literal varIdn = TOY_TO_IDENTIFIER_LITERAL(Toy_copyRefString(TOY_AS_STRING(varName))); + Toy_Literal fn = TOY_TO_NULL_LITERAL; + Toy_getScopeVariable(runner->interpreter.scope, varIdn, &fn); - if (!IS_FUNCTION(fn)) { + if (!TOY_IS_FUNCTION(fn)) { interpreter->errorOutput("Can't run a non-function literal\n"); - freeLiteral(fn); - freeLiteral(varIdn); - freeLiteral(varName); - freeLiteral(runnerLiteral); - freeLiteralArray(&rest); + Toy_freeLiteral(fn); + Toy_freeLiteral(varIdn); + Toy_freeLiteral(varName); + Toy_freeLiteral(runnerLiteral); + Toy_freeLiteralArray(&rest); } //call - LiteralArray resultArray; - initLiteralArray(&resultArray); + Toy_LiteralArray resultArray; + Toy_initLiteralArray(&resultArray); - callLiteralFn(interpreter, fn, &rest, &resultArray); + Toy_callLiteralFn(interpreter, fn, &rest, &resultArray); - Literal result = TO_NULL_LITERAL; + Toy_Literal result = TOY_TO_NULL_LITERAL; if (resultArray.count > 0) { - result = popLiteralArray(&resultArray); + result = Toy_popLiteralArray(&resultArray); } - pushLiteralArray(&interpreter->stack, result); + Toy_pushLiteralArray(&interpreter->stack, result); //cleanup - freeLiteralArray(&resultArray); - freeLiteral(result); - freeLiteral(fn); - freeLiteral(varIdn); - freeLiteral(varName); - freeLiteral(runnerLiteral); - freeLiteralArray(&rest); + Toy_freeLiteralArray(&resultArray); + Toy_freeLiteral(result); + Toy_freeLiteral(fn); + Toy_freeLiteral(varIdn); + Toy_freeLiteral(varName); + Toy_freeLiteral(runnerLiteral); + Toy_freeLiteralArray(&rest); return 1; } -static int nativeResetScript(Interpreter* interpreter, LiteralArray* arguments) { +static int nativeResetScript(Toy_Interpreter* interpreter, Toy_LiteralArray* arguments) { //no arguments if (arguments->count != 1) { interpreter->errorOutput("Incorrect number of arguments to _resetScript\n"); @@ -430,35 +430,35 @@ static int nativeResetScript(Interpreter* interpreter, LiteralArray* arguments) } //get the runner object - Literal runnerLiteral = popLiteralArray(arguments); + Toy_Literal runnerLiteral = Toy_popLiteralArray(arguments); - Literal runnerIdn = runnerLiteral; - if (IS_IDENTIFIER(runnerLiteral) && parseIdentifierToValue(interpreter, &runnerLiteral)) { - freeLiteral(runnerIdn); + Toy_Literal runnerIdn = runnerLiteral; + if (TOY_IS_IDENTIFIER(runnerLiteral) && Toy_parseIdentifierToValue(interpreter, &runnerLiteral)) { + Toy_freeLiteral(runnerIdn); } - if (OPAQUE_TAG(runnerLiteral) != OPAQUE_TAG_RUNNER) { + if (TOY_GET_OPAQUE_TAG(runnerLiteral) != TOY_OPAQUE_TAG_RUNNER) { interpreter->errorOutput("Unrecognized opaque literal in _runScript\n"); return -1; } - Runner* runner = AS_OPAQUE(runnerLiteral); + Toy_Runner* runner = TOY_AS_OPAQUE(runnerLiteral); //reset if (!runner->dirty) { interpreter->errorOutput("Can't reset a non-dirty script (try running it first)\n"); - freeLiteral(runnerLiteral); + Toy_freeLiteral(runnerLiteral); return -1; } - resetInterpreter(&runner->interpreter); + Toy_resetInterpreter(&runner->interpreter); runner->dirty = false; - freeLiteral(runnerLiteral); + Toy_freeLiteral(runnerLiteral); return 0; } -static int nativeFreeScript(Interpreter* interpreter, LiteralArray* arguments) { +static int nativeFreeScript(Toy_Interpreter* interpreter, Toy_LiteralArray* arguments) { //no arguments if (arguments->count != 1) { interpreter->errorOutput("Incorrect number of arguments to _freeScript\n"); @@ -466,33 +466,33 @@ static int nativeFreeScript(Interpreter* interpreter, LiteralArray* arguments) { } //get the runner object - Literal runnerLiteral = popLiteralArray(arguments); + Toy_Literal runnerLiteral = Toy_popLiteralArray(arguments); - Literal runnerIdn = runnerLiteral; - if (IS_IDENTIFIER(runnerLiteral) && parseIdentifierToValue(interpreter, &runnerLiteral)) { - freeLiteral(runnerIdn); + Toy_Literal runnerIdn = runnerLiteral; + if (TOY_IS_IDENTIFIER(runnerLiteral) && Toy_parseIdentifierToValue(interpreter, &runnerLiteral)) { + Toy_freeLiteral(runnerIdn); } - if (OPAQUE_TAG(runnerLiteral) != OPAQUE_TAG_RUNNER) { + if (TOY_GET_OPAQUE_TAG(runnerLiteral) != TOY_OPAQUE_TAG_RUNNER) { interpreter->errorOutput("Unrecognized opaque literal in _freeScript\n"); return -1; } - Runner* runner = AS_OPAQUE(runnerLiteral); + Toy_Runner* runner = TOY_AS_OPAQUE(runnerLiteral); //clear out the runner object runner->interpreter.hooks = NULL; - freeInterpreter(&runner->interpreter); - FREE_ARRAY(unsigned char, runner->bytecode, runner->size); + Toy_freeInterpreter(&runner->interpreter); + TOY_FREE_ARRAY(unsigned char, runner->bytecode, runner->size); - FREE(Runner, runner); + TOY_FREE(Toy_Runner, runner); - freeLiteral(runnerLiteral); + Toy_freeLiteral(runnerLiteral); return 0; } -static int nativeCheckScriptDirty(Interpreter* interpreter, LiteralArray* arguments) { +static int nativeCheckScriptDirty(Toy_Interpreter* interpreter, Toy_LiteralArray* arguments) { //no arguments if (arguments->count != 1) { interpreter->errorOutput("Incorrect number of arguments to _runScript\n"); @@ -500,28 +500,28 @@ static int nativeCheckScriptDirty(Interpreter* interpreter, LiteralArray* argume } //get the runner object - Literal runnerLiteral = popLiteralArray(arguments); + Toy_Literal runnerLiteral = Toy_popLiteralArray(arguments); - Literal runnerIdn = runnerLiteral; - if (IS_IDENTIFIER(runnerLiteral) && parseIdentifierToValue(interpreter, &runnerLiteral)) { - freeLiteral(runnerIdn); + Toy_Literal runnerIdn = runnerLiteral; + if (TOY_IS_IDENTIFIER(runnerLiteral) && Toy_parseIdentifierToValue(interpreter, &runnerLiteral)) { + Toy_freeLiteral(runnerIdn); } - if (OPAQUE_TAG(runnerLiteral) != OPAQUE_TAG_RUNNER) { + if (TOY_GET_OPAQUE_TAG(runnerLiteral) != TOY_OPAQUE_TAG_RUNNER) { interpreter->errorOutput("Unrecognized opaque literal in _runScript\n"); return -1; } - Runner* runner = AS_OPAQUE(runnerLiteral); + Toy_Runner* runner = TOY_AS_OPAQUE(runnerLiteral); //run - Literal result = TO_BOOLEAN_LITERAL(runner->dirty); + Toy_Literal result = TOY_TO_BOOLEAN_LITERAL(runner->dirty); - pushLiteralArray(&interpreter->stack, result); + Toy_pushLiteralArray(&interpreter->stack, result); //cleanup - freeLiteral(result); - freeLiteral(runnerLiteral); + Toy_freeLiteral(result); + Toy_freeLiteral(runnerLiteral); return 0; } @@ -529,10 +529,10 @@ static int nativeCheckScriptDirty(Interpreter* interpreter, LiteralArray* argume //call the hook typedef struct Natives { char* name; - NativeFn fn; + Toy_NativeFn fn; } Natives; -int hookRunner(Interpreter* interpreter, Literal identifier, Literal alias) { +int Toy_hookRunner(Toy_Interpreter* interpreter, Toy_Literal identifier, Toy_Literal alias) { //build the natives list Natives natives[] = { {"loadScript", nativeLoadScript}, @@ -547,67 +547,67 @@ int hookRunner(Interpreter* interpreter, Literal identifier, Literal alias) { }; //store the library in an aliased dictionary - if (!IS_NULL(alias)) { + if (!TOY_IS_NULL(alias)) { //make sure the name isn't taken - if (isDelcaredScopeVariable(interpreter->scope, alias)) { + if (Toy_isDelcaredScopeVariable(interpreter->scope, alias)) { interpreter->errorOutput("Can't override an existing variable\n"); - freeLiteral(alias); + Toy_freeLiteral(alias); return false; } //create the dictionary to load up with functions - LiteralDictionary* dictionary = ALLOCATE(LiteralDictionary, 1); - initLiteralDictionary(dictionary); + Toy_LiteralDictionary* dictionary = TOY_ALLOCATE(Toy_LiteralDictionary, 1); + Toy_initLiteralDictionary(dictionary); //load the dict with functions for (int i = 0; natives[i].name; i++) { - Literal name = TO_STRING_LITERAL(createRefString(natives[i].name)); - Literal func = TO_FUNCTION_LITERAL((void*)natives[i].fn, 0); - func.type = LITERAL_FUNCTION_NATIVE; + Toy_Literal name = TOY_TO_STRING_LITERAL(Toy_createRefString(natives[i].name)); + Toy_Literal func = TOY_TO_FUNCTION_LITERAL((void*)natives[i].fn, 0); + func.type = TOY_LITERAL_FUNCTION_NATIVE; - setLiteralDictionary(dictionary, name, func); + Toy_setLiteralDictionary(dictionary, name, func); - freeLiteral(name); - freeLiteral(func); + Toy_freeLiteral(name); + Toy_freeLiteral(func); } //build the type - Literal type = TO_TYPE_LITERAL(LITERAL_DICTIONARY, true); - Literal strType = TO_TYPE_LITERAL(LITERAL_STRING, true); - Literal fnType = TO_TYPE_LITERAL(LITERAL_FUNCTION_NATIVE, true); - TYPE_PUSH_SUBTYPE(&type, strType); - TYPE_PUSH_SUBTYPE(&type, fnType); + Toy_Literal type = TOY_TO_TYPE_LITERAL(TOY_LITERAL_DICTIONARY, true); + Toy_Literal strType = TOY_TO_TYPE_LITERAL(TOY_LITERAL_STRING, true); + Toy_Literal fnType = TOY_TO_TYPE_LITERAL(TOY_LITERAL_FUNCTION_NATIVE, true); + TOY_TYPE_PUSH_SUBTYPE(&type, strType); + TOY_TYPE_PUSH_SUBTYPE(&type, fnType); //set scope - Literal dict = TO_DICTIONARY_LITERAL(dictionary); - declareScopeVariable(interpreter->scope, alias, type); - setScopeVariable(interpreter->scope, alias, dict, false); + Toy_Literal dict = TOY_TO_DICTIONARY_LITERAL(dictionary); + Toy_declareScopeVariable(interpreter->scope, alias, type); + Toy_setScopeVariable(interpreter->scope, alias, dict, false); //cleanup - freeLiteral(dict); - freeLiteral(type); + Toy_freeLiteral(dict); + Toy_freeLiteral(type); return 0; } //default for (int i = 0; natives[i].name; i++) { - injectNativeFn(interpreter, natives[i].name, natives[i].fn); + Toy_injectNativeFn(interpreter, natives[i].name, natives[i].fn); } return 0; } //file system API -static LiteralDictionary driveDictionary; +static Toy_LiteralDictionary Toy_driveDictionary; -void initDriveDictionary() { - initLiteralDictionary(&driveDictionary); +void Toy_initDriveDictionary() { + Toy_initLiteralDictionary(&Toy_driveDictionary); } -void freeDriveDictionary() { - freeLiteralDictionary(&driveDictionary); +void Toy_freeDriveDictionary() { + Toy_freeLiteralDictionary(&Toy_driveDictionary); } -LiteralDictionary* getDriveDictionary() { - return &driveDictionary; +Toy_LiteralDictionary* Toy_getDriveDictionary() { + return &Toy_driveDictionary; } \ No newline at end of file diff --git a/repl/lib_runner.h b/repl/lib_runner.h index e7d2c13..1912de4 100644 --- a/repl/lib_runner.h +++ b/repl/lib_runner.h @@ -1,12 +1,12 @@ #pragma once -#include "interpreter.h" +#include "toy_interpreter.h" -int hookRunner(Interpreter* interpreter, Literal identifier, Literal alias); +int Toy_hookRunner(Toy_Interpreter* interpreter, Toy_Literal identifier, Toy_Literal alias); //file system API - these need to be set by the host -void initDriveDictionary(); -void freeDriveDictionary(); -LiteralDictionary* getDriveDictionary(); +void Toy_initDriveDictionary(); +void Toy_freeDriveDictionary(); +Toy_LiteralDictionary* Toy_getDriveDictionary(); -#define OPAQUE_TAG_RUNNER 100 +#define TOY_OPAQUE_TAG_RUNNER 100 diff --git a/repl/lib_standard.c b/repl/lib_standard.c index 22f7aa1..b253286 100644 --- a/repl/lib_standard.c +++ b/repl/lib_standard.c @@ -1,11 +1,11 @@ #include "lib_standard.h" -#include "memory.h" +#include "toy_memory.h" #include #include -static int nativeClock(Interpreter* interpreter, LiteralArray* arguments) { +static int nativeClock(Toy_Interpreter* interpreter, Toy_LiteralArray* arguments) { //no arguments if (arguments->count != 0) { interpreter->errorOutput("Incorrect number of arguments to clock\n"); @@ -19,13 +19,13 @@ static int nativeClock(Interpreter* interpreter, LiteralArray* arguments) { //push to the stack int len = strlen(timestr) - 1; //-1 for the newline - Literal timeLiteral = TO_STRING_LITERAL(createRefStringLength(timestr, len)); + Toy_Literal timeLiteral = TOY_TO_STRING_LITERAL(Toy_createRefStringLength(timestr, len)); //push to the stack - pushLiteralArray(&interpreter->stack, timeLiteral); + Toy_pushLiteralArray(&interpreter->stack, timeLiteral); //cleanup - freeLiteral(timeLiteral); + Toy_freeLiteral(timeLiteral); return 1; } @@ -33,10 +33,10 @@ static int nativeClock(Interpreter* interpreter, LiteralArray* arguments) { //call the hook typedef struct Natives { char* name; - NativeFn fn; + Toy_NativeFn fn; } Natives; -int hookStandard(Interpreter* interpreter, Literal identifier, Literal alias) { +int Toy_hookStandard(Toy_Interpreter* interpreter, Toy_Literal identifier, Toy_Literal alias) { //build the natives list Natives natives[] = { {"clock", nativeClock}, @@ -44,51 +44,51 @@ int hookStandard(Interpreter* interpreter, Literal identifier, Literal alias) { }; //store the library in an aliased dictionary - if (!IS_NULL(alias)) { + if (!TOY_IS_NULL(alias)) { //make sure the name isn't taken - if (isDelcaredScopeVariable(interpreter->scope, alias)) { + if (Toy_isDelcaredScopeVariable(interpreter->scope, alias)) { interpreter->errorOutput("Can't override an existing variable\n"); - freeLiteral(alias); + Toy_freeLiteral(alias); return false; } //create the dictionary to load up with functions - LiteralDictionary* dictionary = ALLOCATE(LiteralDictionary, 1); - initLiteralDictionary(dictionary); + Toy_LiteralDictionary* dictionary = TOY_ALLOCATE(Toy_LiteralDictionary, 1); + Toy_initLiteralDictionary(dictionary); //load the dict with functions for (int i = 0; natives[i].name; i++) { - Literal name = TO_STRING_LITERAL(createRefString(natives[i].name)); - Literal func = TO_FUNCTION_LITERAL((void*)natives[i].fn, 0); - func.type = LITERAL_FUNCTION_NATIVE; + Toy_Literal name = TOY_TO_STRING_LITERAL(Toy_createRefString(natives[i].name)); + Toy_Literal func = TOY_TO_FUNCTION_LITERAL((void*)natives[i].fn, 0); + func.type = TOY_LITERAL_FUNCTION_NATIVE; - setLiteralDictionary(dictionary, name, func); + Toy_setLiteralDictionary(dictionary, name, func); - freeLiteral(name); - freeLiteral(func); + Toy_freeLiteral(name); + Toy_freeLiteral(func); } //build the type - Literal type = TO_TYPE_LITERAL(LITERAL_DICTIONARY, true); - Literal strType = TO_TYPE_LITERAL(LITERAL_STRING, true); - Literal fnType = TO_TYPE_LITERAL(LITERAL_FUNCTION_NATIVE, true); - TYPE_PUSH_SUBTYPE(&type, strType); - TYPE_PUSH_SUBTYPE(&type, fnType); + Toy_Literal type = TOY_TO_TYPE_LITERAL(TOY_LITERAL_DICTIONARY, true); + Toy_Literal strType = TOY_TO_TYPE_LITERAL(TOY_LITERAL_STRING, true); + Toy_Literal fnType = TOY_TO_TYPE_LITERAL(TOY_LITERAL_FUNCTION_NATIVE, true); + TOY_TYPE_PUSH_SUBTYPE(&type, strType); + TOY_TYPE_PUSH_SUBTYPE(&type, fnType); //set scope - Literal dict = TO_DICTIONARY_LITERAL(dictionary); - declareScopeVariable(interpreter->scope, alias, type); - setScopeVariable(interpreter->scope, alias, dict, false); + Toy_Literal dict = TOY_TO_DICTIONARY_LITERAL(dictionary); + Toy_declareScopeVariable(interpreter->scope, alias, type); + Toy_setScopeVariable(interpreter->scope, alias, dict, false); //cleanup - freeLiteral(dict); - freeLiteral(type); + Toy_freeLiteral(dict); + Toy_freeLiteral(type); return 0; } //default for (int i = 0; natives[i].name; i++) { - injectNativeFn(interpreter, natives[i].name, natives[i].fn); + Toy_injectNativeFn(interpreter, natives[i].name, natives[i].fn); } return 0; diff --git a/repl/lib_standard.h b/repl/lib_standard.h index 46c146d..d1b9816 100644 --- a/repl/lib_standard.h +++ b/repl/lib_standard.h @@ -1,6 +1,6 @@ #pragma once -#include "interpreter.h" +#include "toy_interpreter.h" -int hookStandard(Interpreter* interpreter, Literal identifier, Literal alias); +int Toy_hookStandard(Toy_Interpreter* interpreter, Toy_Literal identifier, Toy_Literal alias); diff --git a/repl/lib_timer.c b/repl/lib_timer.c index fbda56f..60a4c28 100644 --- a/repl/lib_timer.c +++ b/repl/lib_timer.c @@ -1,13 +1,13 @@ #include "lib_timer.h" -#include "memory.h" +#include "toy_memory.h" #include #include #include //GOD DAMN IT: https://stackoverflow.com/questions/15846762/timeval-subtract-explanation -int timeval_subtract(struct timeval *result, struct timeval *x, struct timeval *y) { +static int timeval_subtract(struct timeval *result, struct timeval *x, struct timeval *y) { //normallize if (x->tv_usec > 999999) { x->tv_sec += x->tv_usec / 1000000; @@ -34,7 +34,7 @@ int timeval_subtract(struct timeval *result, struct timeval *x, struct timeval * //god damn it static struct timeval* diff(struct timeval* lhs, struct timeval* rhs) { - struct timeval* d = ALLOCATE(struct timeval, 1); + struct timeval* d = TOY_ALLOCATE(struct timeval, 1); //I gave up, copied from SO timeval_subtract(d, rhs, lhs); @@ -43,7 +43,7 @@ static struct timeval* diff(struct timeval* lhs, struct timeval* rhs) { } //callbacks -static int nativeStartTimer(Interpreter* interpreter, LiteralArray* arguments) { +static int nativeStartTimer(Toy_Interpreter* interpreter, Toy_LiteralArray* arguments) { //no arguments if (arguments->count != 0) { interpreter->errorOutput("Incorrect number of arguments to startTimer\n"); @@ -51,19 +51,19 @@ static int nativeStartTimer(Interpreter* interpreter, LiteralArray* arguments) { } //get the timeinfo from C - struct timeval* timeinfo = ALLOCATE(struct timeval, 1); + struct timeval* timeinfo = TOY_ALLOCATE(struct timeval, 1); gettimeofday(timeinfo, NULL); //wrap in an opaque literal for Toy - Literal timeLiteral = TO_OPAQUE_LITERAL(timeinfo, -1); - pushLiteralArray(&interpreter->stack, timeLiteral); + Toy_Literal timeLiteral = TOY_TO_OPAQUE_LITERAL(timeinfo, -1); + Toy_pushLiteralArray(&interpreter->stack, timeLiteral); - freeLiteral(timeLiteral); + Toy_freeLiteral(timeLiteral); return 1; } -static int nativeStopTimer(Interpreter* interpreter, LiteralArray* arguments) { +static int nativeStopTimer(Toy_Interpreter* interpreter, Toy_LiteralArray* arguments) { //no arguments if (arguments->count != 1) { interpreter->errorOutput("Incorrect number of arguments to _stopTimer\n"); @@ -75,34 +75,34 @@ static int nativeStopTimer(Interpreter* interpreter, LiteralArray* arguments) { gettimeofday(&timerStop, NULL); //unwrap the opaque literal - Literal timeLiteral = popLiteralArray(arguments); + Toy_Literal timeLiteral = Toy_popLiteralArray(arguments); - Literal timeLiteralIdn = timeLiteral; - if (IS_IDENTIFIER(timeLiteral) && parseIdentifierToValue(interpreter, &timeLiteral)) { - freeLiteral(timeLiteralIdn); + Toy_Literal timeLiteralIdn = timeLiteral; + if (TOY_IS_IDENTIFIER(timeLiteral) && Toy_parseIdentifierToValue(interpreter, &timeLiteral)) { + Toy_freeLiteral(timeLiteralIdn); } - if (!IS_OPAQUE(timeLiteral)) { + if (!TOY_IS_OPAQUE(timeLiteral)) { interpreter->errorOutput("Incorrect argument type passed to _stopTimer\n"); - freeLiteral(timeLiteral); + Toy_freeLiteral(timeLiteral); return -1; } - struct timeval* timerStart = AS_OPAQUE(timeLiteral); + struct timeval* timerStart = TOY_AS_OPAQUE(timeLiteral); //determine the difference, and wrap it struct timeval* d = diff(timerStart, &timerStop); - Literal diffLiteral = TO_OPAQUE_LITERAL(d, -1); - pushLiteralArray(&interpreter->stack, diffLiteral); + Toy_Literal diffLiteral = TOY_TO_OPAQUE_LITERAL(d, -1); + Toy_pushLiteralArray(&interpreter->stack, diffLiteral); //cleanup - freeLiteral(timeLiteral); - freeLiteral(diffLiteral); + Toy_freeLiteral(timeLiteral); + Toy_freeLiteral(diffLiteral); return 1; } -static int nativeCreateTimer(Interpreter* interpreter, LiteralArray* arguments) { +static int nativeCreateTimer(Toy_Interpreter* interpreter, Toy_LiteralArray* arguments) { //no arguments if (arguments->count != 2) { interpreter->errorOutput("Incorrect number of arguments to createTimer\n"); @@ -110,50 +110,50 @@ static int nativeCreateTimer(Interpreter* interpreter, LiteralArray* arguments) } //get the args - Literal microsecondLiteral = popLiteralArray(arguments); - Literal secondLiteral = popLiteralArray(arguments); + Toy_Literal microsecondLiteral = Toy_popLiteralArray(arguments); + Toy_Literal secondLiteral = Toy_popLiteralArray(arguments); - Literal secondLiteralIdn = secondLiteral; - if (IS_IDENTIFIER(secondLiteral) && parseIdentifierToValue(interpreter, &secondLiteral)) { - freeLiteral(secondLiteralIdn); + Toy_Literal secondLiteralIdn = secondLiteral; + if (TOY_IS_IDENTIFIER(secondLiteral) && Toy_parseIdentifierToValue(interpreter, &secondLiteral)) { + Toy_freeLiteral(secondLiteralIdn); } - Literal microsecondLiteralIdn = microsecondLiteral; - if (IS_IDENTIFIER(microsecondLiteral) && parseIdentifierToValue(interpreter, µsecondLiteral)) { - freeLiteral(microsecondLiteralIdn); + Toy_Literal microsecondLiteralIdn = microsecondLiteral; + if (TOY_IS_IDENTIFIER(microsecondLiteral) && Toy_parseIdentifierToValue(interpreter, µsecondLiteral)) { + Toy_freeLiteral(microsecondLiteralIdn); } - if (!IS_INTEGER(secondLiteral) || !IS_INTEGER(microsecondLiteral)) { + if (!TOY_IS_INTEGER(secondLiteral) || !TOY_IS_INTEGER(microsecondLiteral)) { interpreter->errorOutput("Incorrect argument type passed to createTimer\n"); - freeLiteral(secondLiteral); - freeLiteral(microsecondLiteral); + Toy_freeLiteral(secondLiteral); + Toy_freeLiteral(microsecondLiteral); return -1; } - if (AS_INTEGER(microsecondLiteral) <= -1000 * 1000 || AS_INTEGER(microsecondLiteral) >= 1000 * 1000 || (AS_INTEGER(secondLiteral) != 0 && AS_INTEGER(microsecondLiteral) < 0) ) { + if (TOY_AS_INTEGER(microsecondLiteral) <= -1000 * 1000 || TOY_AS_INTEGER(microsecondLiteral) >= 1000 * 1000 || (TOY_AS_INTEGER(secondLiteral) != 0 && TOY_AS_INTEGER(microsecondLiteral) < 0) ) { interpreter->errorOutput("Microseconds out of range in createTimer\n"); - freeLiteral(secondLiteral); - freeLiteral(microsecondLiteral); + Toy_freeLiteral(secondLiteral); + Toy_freeLiteral(microsecondLiteral); return -1; } //get the timeinfo from toy - struct timeval* timeinfo = ALLOCATE(struct timeval, 1); - timeinfo->tv_sec = AS_INTEGER(secondLiteral); - timeinfo->tv_usec = AS_INTEGER(microsecondLiteral); + struct timeval* timeinfo = TOY_ALLOCATE(struct timeval, 1); + timeinfo->tv_sec = TOY_AS_INTEGER(secondLiteral); + timeinfo->tv_usec = TOY_AS_INTEGER(microsecondLiteral); //wrap in an opaque literal for Toy - Literal timeLiteral = TO_OPAQUE_LITERAL(timeinfo, -1); - pushLiteralArray(&interpreter->stack, timeLiteral); + Toy_Literal timeLiteral = TOY_TO_OPAQUE_LITERAL(timeinfo, -1); + Toy_pushLiteralArray(&interpreter->stack, timeLiteral); - freeLiteral(timeLiteral); - freeLiteral(secondLiteral); - freeLiteral(microsecondLiteral); + Toy_freeLiteral(timeLiteral); + Toy_freeLiteral(secondLiteral); + Toy_freeLiteral(microsecondLiteral); return 1; } -static int nativeGetTimerSeconds(Interpreter* interpreter, LiteralArray* arguments) { +static int nativeGetTimerSeconds(Toy_Interpreter* interpreter, Toy_LiteralArray* arguments) { //no arguments if (arguments->count != 1) { interpreter->errorOutput("Incorrect number of arguments to _getTimerSeconds\n"); @@ -161,33 +161,33 @@ static int nativeGetTimerSeconds(Interpreter* interpreter, LiteralArray* argumen } //unwrap the opaque literal - Literal timeLiteral = popLiteralArray(arguments); + Toy_Literal timeLiteral = Toy_popLiteralArray(arguments); - Literal timeLiteralIdn = timeLiteral; - if (IS_IDENTIFIER(timeLiteral) && parseIdentifierToValue(interpreter, &timeLiteral)) { - freeLiteral(timeLiteralIdn); + Toy_Literal timeLiteralIdn = timeLiteral; + if (TOY_IS_IDENTIFIER(timeLiteral) && Toy_parseIdentifierToValue(interpreter, &timeLiteral)) { + Toy_freeLiteral(timeLiteralIdn); } - if (!IS_OPAQUE(timeLiteral)) { + if (!TOY_IS_OPAQUE(timeLiteral)) { interpreter->errorOutput("Incorrect argument type passed to _getTimerSeconds\n"); - freeLiteral(timeLiteral); + Toy_freeLiteral(timeLiteral); return -1; } - struct timeval* timer = AS_OPAQUE(timeLiteral); + struct timeval* timer = TOY_AS_OPAQUE(timeLiteral); //create the result literal - Literal result = TO_INTEGER_LITERAL(timer->tv_sec); - pushLiteralArray(&interpreter->stack, result); + Toy_Literal result = TOY_TO_INTEGER_LITERAL(timer->tv_sec); + Toy_pushLiteralArray(&interpreter->stack, result); //cleanup - freeLiteral(timeLiteral); - freeLiteral(result); + Toy_freeLiteral(timeLiteral); + Toy_freeLiteral(result); return 1; } -static int nativeGetTimerMicroseconds(Interpreter* interpreter, LiteralArray* arguments) { +static int nativeGetTimerMicroseconds(Toy_Interpreter* interpreter, Toy_LiteralArray* arguments) { //no arguments if (arguments->count != 1) { interpreter->errorOutput("Incorrect number of arguments to _getTimerMicroseconds\n"); @@ -195,33 +195,33 @@ static int nativeGetTimerMicroseconds(Interpreter* interpreter, LiteralArray* ar } //unwrap the opaque literal - Literal timeLiteral = popLiteralArray(arguments); + Toy_Literal timeLiteral = Toy_popLiteralArray(arguments); - Literal timeLiteralIdn = timeLiteral; - if (IS_IDENTIFIER(timeLiteral) && parseIdentifierToValue(interpreter, &timeLiteral)) { - freeLiteral(timeLiteralIdn); + Toy_Literal timeLiteralIdn = timeLiteral; + if (TOY_IS_IDENTIFIER(timeLiteral) && Toy_parseIdentifierToValue(interpreter, &timeLiteral)) { + Toy_freeLiteral(timeLiteralIdn); } - if (!IS_OPAQUE(timeLiteral)) { + if (!TOY_IS_OPAQUE(timeLiteral)) { interpreter->errorOutput("Incorrect argument type passed to _getTimerMicroseconds\n"); - freeLiteral(timeLiteral); + Toy_freeLiteral(timeLiteral); return -1; } - struct timeval* timer = AS_OPAQUE(timeLiteral); + struct timeval* timer = TOY_AS_OPAQUE(timeLiteral); //create the result literal - Literal result = TO_INTEGER_LITERAL(timer->tv_usec); - pushLiteralArray(&interpreter->stack, result); + Toy_Literal result = TOY_TO_INTEGER_LITERAL(timer->tv_usec); + Toy_pushLiteralArray(&interpreter->stack, result); //cleanup - freeLiteral(timeLiteral); - freeLiteral(result); + Toy_freeLiteral(timeLiteral); + Toy_freeLiteral(result); return 1; } -static int nativeCompareTimer(Interpreter* interpreter, LiteralArray* arguments) { +static int nativeCompareTimer(Toy_Interpreter* interpreter, Toy_LiteralArray* arguments) { //no arguments if (arguments->count != 2) { interpreter->errorOutput("Incorrect number of arguments to _compareTimer\n"); @@ -229,43 +229,43 @@ static int nativeCompareTimer(Interpreter* interpreter, LiteralArray* arguments) } //unwrap the opaque literals - Literal rhsLiteral = popLiteralArray(arguments); - Literal lhsLiteral = popLiteralArray(arguments); + Toy_Literal rhsLiteral = Toy_popLiteralArray(arguments); + Toy_Literal lhsLiteral = Toy_popLiteralArray(arguments); - Literal lhsLiteralIdn = lhsLiteral; - if (IS_IDENTIFIER(lhsLiteral) && parseIdentifierToValue(interpreter, &lhsLiteral)) { - freeLiteral(lhsLiteralIdn); + Toy_Literal lhsLiteralIdn = lhsLiteral; + if (TOY_IS_IDENTIFIER(lhsLiteral) && Toy_parseIdentifierToValue(interpreter, &lhsLiteral)) { + Toy_freeLiteral(lhsLiteralIdn); } - Literal rhsLiteralIdn = rhsLiteral; - if (IS_IDENTIFIER(rhsLiteral) && parseIdentifierToValue(interpreter, &rhsLiteral)) { - freeLiteral(rhsLiteralIdn); + Toy_Literal rhsLiteralIdn = rhsLiteral; + if (TOY_IS_IDENTIFIER(rhsLiteral) && Toy_parseIdentifierToValue(interpreter, &rhsLiteral)) { + Toy_freeLiteral(rhsLiteralIdn); } - if (!IS_OPAQUE(lhsLiteral) || !IS_OPAQUE(rhsLiteral)) { + if (!TOY_IS_OPAQUE(lhsLiteral) || !TOY_IS_OPAQUE(rhsLiteral)) { interpreter->errorOutput("Incorrect argument type passed to _compareTimer\n"); - freeLiteral(lhsLiteral); - freeLiteral(rhsLiteral); + Toy_freeLiteral(lhsLiteral); + Toy_freeLiteral(rhsLiteral); return -1; } - struct timeval* lhsTimer = AS_OPAQUE(lhsLiteral); - struct timeval* rhsTimer = AS_OPAQUE(rhsLiteral); + struct timeval* lhsTimer = TOY_AS_OPAQUE(lhsLiteral); + struct timeval* rhsTimer = TOY_AS_OPAQUE(rhsLiteral); //determine the difference, and wrap it struct timeval* d = diff(lhsTimer, rhsTimer); - Literal diffLiteral = TO_OPAQUE_LITERAL(d, -1); - pushLiteralArray(&interpreter->stack, diffLiteral); + Toy_Literal diffLiteral = TOY_TO_OPAQUE_LITERAL(d, -1); + Toy_pushLiteralArray(&interpreter->stack, diffLiteral); //cleanup - freeLiteral(lhsLiteral); - freeLiteral(rhsLiteral); - freeLiteral(diffLiteral); + Toy_freeLiteral(lhsLiteral); + Toy_freeLiteral(rhsLiteral); + Toy_freeLiteral(diffLiteral); return 1; } -static int nativeTimerToString(Interpreter* interpreter, LiteralArray* arguments) { +static int nativeTimerToString(Toy_Interpreter* interpreter, Toy_LiteralArray* arguments) { //no arguments if (arguments->count != 1) { interpreter->errorOutput("Incorrect number of arguments to _timerToString\n"); @@ -273,44 +273,44 @@ static int nativeTimerToString(Interpreter* interpreter, LiteralArray* arguments } //unwrap in an opaque literal - Literal timeLiteral = popLiteralArray(arguments); + Toy_Literal timeLiteral = Toy_popLiteralArray(arguments); - Literal timeLiteralIdn = timeLiteral; - if (IS_IDENTIFIER(timeLiteral) && parseIdentifierToValue(interpreter, &timeLiteral)) { - freeLiteral(timeLiteralIdn); + Toy_Literal timeLiteralIdn = timeLiteral; + if (TOY_IS_IDENTIFIER(timeLiteral) && Toy_parseIdentifierToValue(interpreter, &timeLiteral)) { + Toy_freeLiteral(timeLiteralIdn); } - if (!IS_OPAQUE(timeLiteral)) { + if (!TOY_IS_OPAQUE(timeLiteral)) { interpreter->errorOutput("Incorrect argument type passed to _timerToString\n"); - freeLiteral(timeLiteral); + Toy_freeLiteral(timeLiteral); return -1; } - struct timeval* timer = AS_OPAQUE(timeLiteral); + struct timeval* timer = TOY_AS_OPAQUE(timeLiteral); //create the string literal - Literal resultLiteral = TO_NULL_LITERAL; + Toy_Literal resultLiteral = TOY_TO_NULL_LITERAL; if (timer->tv_sec == 0 && timer->tv_usec < 0) { //special case, for when the negative sign is encoded in the usec char buffer[128]; snprintf(buffer, 128, "-%ld.%06ld", timer->tv_sec, -timer->tv_usec); - resultLiteral = TO_STRING_LITERAL(createRefStringLength(buffer, strlen(buffer))); + resultLiteral = TOY_TO_STRING_LITERAL(Toy_createRefStringLength(buffer, strlen(buffer))); } else { //normal case char buffer[128]; snprintf(buffer, 128, "%ld.%06ld", timer->tv_sec, timer->tv_usec); - resultLiteral = TO_STRING_LITERAL(createRefStringLength(buffer, strlen(buffer))); + resultLiteral = TOY_TO_STRING_LITERAL(Toy_createRefStringLength(buffer, strlen(buffer))); } - pushLiteralArray(&interpreter->stack, resultLiteral); + Toy_pushLiteralArray(&interpreter->stack, resultLiteral); //cleanup - freeLiteral(timeLiteral); - freeLiteral(resultLiteral); + Toy_freeLiteral(timeLiteral); + Toy_freeLiteral(resultLiteral); return 1; } -static int nativeDestroyTimer(Interpreter* interpreter, LiteralArray* arguments) { +static int nativeDestroyTimer(Toy_Interpreter* interpreter, Toy_LiteralArray* arguments) { //no arguments if (arguments->count != 1) { interpreter->errorOutput("Incorrect number of arguments to _destroyTimer\n"); @@ -318,24 +318,24 @@ static int nativeDestroyTimer(Interpreter* interpreter, LiteralArray* arguments) } //unwrap in an opaque literal - Literal timeLiteral = popLiteralArray(arguments); + Toy_Literal timeLiteral = Toy_popLiteralArray(arguments); - Literal timeLiteralIdn = timeLiteral; - if (IS_IDENTIFIER(timeLiteral) && parseIdentifierToValue(interpreter, &timeLiteral)) { - freeLiteral(timeLiteralIdn); + Toy_Literal timeLiteralIdn = timeLiteral; + if (TOY_IS_IDENTIFIER(timeLiteral) && Toy_parseIdentifierToValue(interpreter, &timeLiteral)) { + Toy_freeLiteral(timeLiteralIdn); } - if (!IS_OPAQUE(timeLiteral)) { + if (!TOY_IS_OPAQUE(timeLiteral)) { interpreter->errorOutput("Incorrect argument type passed to _destroyTimer\n"); - freeLiteral(timeLiteral); + Toy_freeLiteral(timeLiteral); return -1; } - struct timeval* timer = AS_OPAQUE(timeLiteral); + struct timeval* timer = TOY_AS_OPAQUE(timeLiteral); - FREE(struct timeval, timer); + TOY_FREE(struct timeval, timer); - freeLiteral(timeLiteral); + Toy_freeLiteral(timeLiteral); return 0; } @@ -343,10 +343,10 @@ static int nativeDestroyTimer(Interpreter* interpreter, LiteralArray* arguments) //call the hook typedef struct Natives { char* name; - NativeFn fn; + Toy_NativeFn fn; } Natives; -int hookTimer(Interpreter* interpreter, Literal identifier, Literal alias) { +int Toy_hookTimer(Toy_Interpreter* interpreter, Toy_Literal identifier, Toy_Literal alias) { //build the natives list Natives natives[] = { {"startTimer", nativeStartTimer}, @@ -361,51 +361,51 @@ int hookTimer(Interpreter* interpreter, Literal identifier, Literal alias) { }; //store the library in an aliased dictionary - if (!IS_NULL(alias)) { + if (!TOY_IS_NULL(alias)) { //make sure the name isn't taken - if (isDelcaredScopeVariable(interpreter->scope, alias)) { + if (Toy_isDelcaredScopeVariable(interpreter->scope, alias)) { interpreter->errorOutput("Can't override an existing variable\n"); - freeLiteral(alias); + Toy_freeLiteral(alias); return false; } //create the dictionary to load up with functions - LiteralDictionary* dictionary = ALLOCATE(LiteralDictionary, 1); - initLiteralDictionary(dictionary); + Toy_LiteralDictionary* dictionary = TOY_ALLOCATE(Toy_LiteralDictionary, 1); + Toy_initLiteralDictionary(dictionary); //load the dict with functions for (int i = 0; natives[i].name; i++) { - Literal name = TO_STRING_LITERAL(createRefString(natives[i].name)); - Literal func = TO_FUNCTION_LITERAL((void*)natives[i].fn, 0); - func.type = LITERAL_FUNCTION_NATIVE; + Toy_Literal name = TOY_TO_STRING_LITERAL(Toy_createRefString(natives[i].name)); + Toy_Literal func = TOY_TO_FUNCTION_LITERAL((void*)natives[i].fn, 0); + func.type = TOY_LITERAL_FUNCTION_NATIVE; - setLiteralDictionary(dictionary, name, func); + Toy_setLiteralDictionary(dictionary, name, func); - freeLiteral(name); - freeLiteral(func); + Toy_freeLiteral(name); + Toy_freeLiteral(func); } //build the type - Literal type = TO_TYPE_LITERAL(LITERAL_DICTIONARY, true); - Literal strType = TO_TYPE_LITERAL(LITERAL_STRING, true); - Literal fnType = TO_TYPE_LITERAL(LITERAL_FUNCTION_NATIVE, true); - TYPE_PUSH_SUBTYPE(&type, strType); - TYPE_PUSH_SUBTYPE(&type, fnType); + Toy_Literal type = TOY_TO_TYPE_LITERAL(TOY_LITERAL_DICTIONARY, true); + Toy_Literal strType = TOY_TO_TYPE_LITERAL(TOY_LITERAL_STRING, true); + Toy_Literal fnType = TOY_TO_TYPE_LITERAL(TOY_LITERAL_FUNCTION_NATIVE, true); + TOY_TYPE_PUSH_SUBTYPE(&type, strType); + TOY_TYPE_PUSH_SUBTYPE(&type, fnType); //set scope - Literal dict = TO_DICTIONARY_LITERAL(dictionary); - declareScopeVariable(interpreter->scope, alias, type); - setScopeVariable(interpreter->scope, alias, dict, false); + Toy_Literal dict = TOY_TO_DICTIONARY_LITERAL(dictionary); + Toy_declareScopeVariable(interpreter->scope, alias, type); + Toy_setScopeVariable(interpreter->scope, alias, dict, false); //cleanup - freeLiteral(dict); - freeLiteral(type); + Toy_freeLiteral(dict); + Toy_freeLiteral(type); return 0; } //default for (int i = 0; natives[i].name; i++) { - injectNativeFn(interpreter, natives[i].name, natives[i].fn); + Toy_injectNativeFn(interpreter, natives[i].name, natives[i].fn); } return 0; diff --git a/repl/lib_timer.h b/repl/lib_timer.h index 4fa99e7..90193e8 100644 --- a/repl/lib_timer.h +++ b/repl/lib_timer.h @@ -1,6 +1,6 @@ #pragma once -#include "interpreter.h" +#include "toy_interpreter.h" -int hookTimer(Interpreter* interpreter, Literal identifier, Literal alias); +int Toy_hookTimer(Toy_Interpreter* interpreter, Toy_Literal identifier, Toy_Literal alias); diff --git a/repl/repl_main.c b/repl/repl_main.c index 19e579a..dadebf0 100644 --- a/repl/repl_main.c +++ b/repl/repl_main.c @@ -3,12 +3,12 @@ #include "lib_timer.h" #include "lib_runner.h" -#include "console_colors.h" +#include "toy_console_colors.h" -#include "lexer.h" -#include "parser.h" -#include "compiler.h" -#include "interpreter.h" +#include "toy_lexer.h" +#include "toy_parser.h" +#include "toy_compiler.h" +#include "toy_interpreter.h" #include #include @@ -22,13 +22,13 @@ void repl() { char input[size]; memset(input, 0, size); - Interpreter interpreter; //persist the interpreter for the scopes - initInterpreter(&interpreter); + Toy_Interpreter interpreter; //persist the interpreter for the scopes + Toy_initInterpreter(&interpreter); //inject the libs - injectNativeHook(&interpreter, "standard", hookStandard); - injectNativeHook(&interpreter, "timer", hookTimer); - injectNativeHook(&interpreter, "runner", hookRunner); + Toy_injectNativeHook(&interpreter, "standard", Toy_hookStandard); + Toy_injectNativeHook(&interpreter, "timer", Toy_hookTimer); + Toy_injectNativeHook(&interpreter, "runner", Toy_hookRunner); for(;;) { printf("> "); @@ -44,100 +44,100 @@ void repl() { } //setup this iteration - Lexer lexer; - Parser parser; - Compiler compiler; + Toy_Lexer lexer; + Toy_Parser parser; + Toy_Compiler compiler; - initLexer(&lexer, input); - initParser(&parser, &lexer); - initCompiler(&compiler); + Toy_initLexer(&lexer, input); + Toy_initParser(&parser, &lexer); + Toy_initCompiler(&compiler); //run this iteration - ASTNode* node = scanParser(&parser); + Toy_ASTNode* node = Toy_scanParser(&parser); while(node != NULL) { //pack up and restart - if (node->type == AST_NODE_ERROR) { - printf(ERROR "error node detected\n" RESET); + if (node->type == TOY_AST_NODE_ERROR) { + printf(TOY_CC_ERROR "error node detected\n" TOY_CC_RESET); error = true; - freeASTNode(node); + Toy_freeASTNode(node); break; } - writeCompiler(&compiler, node); - freeASTNode(node); - node = scanParser(&parser); + Toy_writeCompiler(&compiler, node); + Toy_freeASTNode(node); + node = Toy_scanParser(&parser); } if (!error) { //get the bytecode dump int size = 0; - unsigned char* tb = collateCompiler(&compiler, &size); + unsigned char* tb = Toy_collateCompiler(&compiler, &size); //run the bytecode - runInterpreter(&interpreter, tb, size); + Toy_runInterpreter(&interpreter, tb, size); } //clean up this iteration - freeCompiler(&compiler); - freeParser(&parser); + Toy_freeCompiler(&compiler); + Toy_freeParser(&parser); error = false; } - freeInterpreter(&interpreter); + Toy_freeInterpreter(&interpreter); } //entry point int main(int argc, const char* argv[]) { - initCommand(argc, argv); + Toy_initCommand(argc, argv); //lib setup (hacky - only really for this program) - initDriveDictionary(); + Toy_initDriveDictionary(); - Literal driveLiteral = TO_STRING_LITERAL(createRefString("scripts")); - Literal pathLiteral = TO_STRING_LITERAL(createRefString("scripts")); + Toy_Literal driveLiteral = TOY_TO_STRING_LITERAL(Toy_createRefString("scripts")); + Toy_Literal pathLiteral = TOY_TO_STRING_LITERAL(Toy_createRefString("scripts")); - setLiteralDictionary(getDriveDictionary(), driveLiteral, pathLiteral); + Toy_setLiteralDictionary(Toy_getDriveDictionary(), driveLiteral, pathLiteral); - freeLiteral(driveLiteral); - freeLiteral(pathLiteral); + Toy_freeLiteral(driveLiteral); + Toy_freeLiteral(pathLiteral); //command specific actions if (command.error) { - usageCommand(argc, argv); + Toy_usageCommand(argc, argv); return 0; } if (command.help) { - helpCommand(argc, argv); + Toy_helpCommand(argc, argv); return 0; } if (command.version) { - copyrightCommand(argc, argv); + Toy_copyrightCommand(argc, argv); return 0; } //version if (command.verbose) { - printf(NOTICE "Toy Programming Language Version %d.%d.%d\n" RESET, TOY_VERSION_MAJOR, TOY_VERSION_MINOR, TOY_VERSION_PATCH); + printf(TOY_CC_NOTICE "Toy Programming Language Version %d.%d.%d\n" TOY_CC_RESET, TOY_VERSION_MAJOR, TOY_VERSION_MINOR, TOY_VERSION_PATCH); } //run source file if (command.sourcefile) { - runSourceFile(command.sourcefile); + Toy_runSourceFile(command.sourcefile); //lib cleanup - freeDriveDictionary(); + Toy_freeDriveDictionary(); return 0; } //run from stdin if (command.source) { - runSource(command.source); + Toy_runSource(command.source); //lib cleanup - freeDriveDictionary(); + Toy_freeDriveDictionary(); return 0; } @@ -145,21 +145,21 @@ int main(int argc, const char* argv[]) { //compile source file if (command.compilefile && command.outfile) { size_t size = 0; - char* source = readFile(command.compilefile, &size); - unsigned char* tb = compileString(source, &size); + char* source = Toy_readFile(command.compilefile, &size); + unsigned char* tb = Toy_compileString(source, &size); if (!tb) { return 1; } - writeFile(command.outfile, tb, size); + Toy_writeFile(command.outfile, tb, size); return 0; } //run binary if (command.binaryfile) { - runBinaryFile(command.binaryfile); + Toy_runBinaryFile(command.binaryfile); //lib cleanup - freeDriveDictionary(); + Toy_freeDriveDictionary(); return 0; } @@ -167,7 +167,7 @@ int main(int argc, const char* argv[]) { repl(); //lib cleanup - freeDriveDictionary(); + Toy_freeDriveDictionary(); return 0; } diff --git a/repl/repl_tools.c b/repl/repl_tools.c index 17b12ff..0b67a57 100644 --- a/repl/repl_tools.c +++ b/repl/repl_tools.c @@ -3,22 +3,22 @@ #include "lib_timer.h" #include "lib_runner.h" -#include "console_colors.h" +#include "toy_console_colors.h" -#include "lexer.h" -#include "parser.h" -#include "compiler.h" -#include "interpreter.h" +#include "toy_lexer.h" +#include "toy_parser.h" +#include "toy_compiler.h" +#include "toy_interpreter.h" #include #include //IO functions -char* readFile(char* path, size_t* fileSize) { +char* Toy_readFile(char* path, size_t* fileSize) { FILE* file = fopen(path, "rb"); if (file == NULL) { - fprintf(stderr, ERROR "Could not open file \"%s\"\n" RESET, path); + fprintf(stderr, TOY_CC_ERROR "Could not open file \"%s\"\n" TOY_CC_RESET, path); return NULL; } @@ -29,7 +29,7 @@ char* readFile(char* path, size_t* fileSize) { char* buffer = (char*)malloc(*fileSize + 1); if (buffer == NULL) { - fprintf(stderr, ERROR "Not enough memory to read \"%s\"\n" RESET, path); + fprintf(stderr, TOY_CC_ERROR "Not enough memory to read \"%s\"\n" TOY_CC_RESET, path); return NULL; } @@ -38,7 +38,7 @@ char* readFile(char* path, size_t* fileSize) { buffer[*fileSize] = '\0'; //NOTE: fread doesn't append this if (bytesRead < *fileSize) { - fprintf(stderr, ERROR "Could not read file \"%s\"\n" RESET, path); + fprintf(stderr, TOY_CC_ERROR "Could not read file \"%s\"\n" TOY_CC_RESET, path); return NULL; } @@ -47,18 +47,18 @@ char* readFile(char* path, size_t* fileSize) { return buffer; } -int writeFile(char* path, unsigned char* bytes, size_t size) { +int Toy_writeFile(char* path, unsigned char* bytes, size_t size) { FILE* file = fopen(path, "wb"); if (file == NULL) { - fprintf(stderr, ERROR "Could not open file \"%s\"\n" RESET, path); + fprintf(stderr, TOY_CC_ERROR "Could not open file \"%s\"\n" TOY_CC_RESET, path); return -1; } int written = fwrite(bytes, size, 1, file); if (written != 1) { - fprintf(stderr, ERROR "Could not write file \"%s\"\n" RESET, path); + fprintf(stderr, TOY_CC_ERROR "Could not write file \"%s\"\n" TOY_CC_RESET, path); return -1; } @@ -68,79 +68,79 @@ int writeFile(char* path, unsigned char* bytes, size_t size) { } //repl functions -unsigned char* compileString(char* source, size_t* size) { - Lexer lexer; - Parser parser; - Compiler compiler; +unsigned char* Toy_compileString(char* source, size_t* size) { + Toy_Lexer lexer; + Toy_Parser parser; + Toy_Compiler compiler; - initLexer(&lexer, source); - initParser(&parser, &lexer); - initCompiler(&compiler); + Toy_initLexer(&lexer, source); + Toy_initParser(&parser, &lexer); + Toy_initCompiler(&compiler); //run the parser until the end of the source - ASTNode* node = scanParser(&parser); + Toy_ASTNode* node = Toy_scanParser(&parser); while(node != NULL) { //pack up and leave - if (node->type == AST_NODE_ERROR) { - freeASTNode(node); - freeCompiler(&compiler); - freeParser(&parser); + if (node->type == TOY_AST_NODE_ERROR) { + Toy_freeASTNode(node); + Toy_freeCompiler(&compiler); + Toy_freeParser(&parser); return NULL; } - writeCompiler(&compiler, node); - freeASTNode(node); - node = scanParser(&parser); + Toy_writeCompiler(&compiler, node); + Toy_freeASTNode(node); + node = Toy_scanParser(&parser); } //get the bytecode dump - unsigned char* tb = collateCompiler(&compiler, (int*)(size)); + unsigned char* tb = Toy_collateCompiler(&compiler, (int*)(size)); //cleanup - freeCompiler(&compiler); - freeParser(&parser); + Toy_freeCompiler(&compiler); + Toy_freeParser(&parser); //no lexer to clean up //finally return tb; } -void runBinary(unsigned char* tb, size_t size) { - Interpreter interpreter; - initInterpreter(&interpreter); +void Toy_runBinary(unsigned char* tb, size_t size) { + Toy_Interpreter interpreter; + Toy_initInterpreter(&interpreter); //inject the libs - injectNativeHook(&interpreter, "standard", hookStandard); - injectNativeHook(&interpreter, "timer", hookTimer); - injectNativeHook(&interpreter, "runner", hookRunner); + Toy_injectNativeHook(&interpreter, "standard", Toy_hookStandard); + Toy_injectNativeHook(&interpreter, "timer", Toy_hookTimer); + Toy_injectNativeHook(&interpreter, "runner", Toy_hookRunner); - runInterpreter(&interpreter, tb, size); - freeInterpreter(&interpreter); + Toy_runInterpreter(&interpreter, tb, size); + Toy_freeInterpreter(&interpreter); } -void runBinaryFile(char* fname) { +void Toy_runBinaryFile(char* fname) { size_t size = 0; //not used - unsigned char* tb = (unsigned char*)readFile(fname, &size); + unsigned char* tb = (unsigned char*)Toy_readFile(fname, &size); if (!tb) { return; } - runBinary(tb, size); + Toy_runBinary(tb, size); //interpreter takes ownership of the binary data } -void runSource(char* source) { +void Toy_runSource(char* source) { size_t size = 0; - unsigned char* tb = compileString(source, &size); + unsigned char* tb = Toy_compileString(source, &size); if (!tb) { return; } - runBinary(tb, size); + Toy_runBinary(tb, size); } -void runSourceFile(char* fname) { +void Toy_runSourceFile(char* fname) { size_t size = 0; //not used - char* source = readFile(fname, &size); - runSource(source); + char* source = Toy_readFile(fname, &size); + Toy_runSource(source); free((void*)source); } diff --git a/repl/repl_tools.h b/repl/repl_tools.h index 289abd1..57f5605 100644 --- a/repl/repl_tools.h +++ b/repl/repl_tools.h @@ -2,13 +2,13 @@ #include "toy_common.h" -char* readFile(char* path, size_t* fileSize); -int writeFile(char* path, unsigned char* bytes, size_t size); +char* Toy_readFile(char* path, size_t* fileSize); +int Toy_writeFile(char* path, unsigned char* bytes, size_t size); -unsigned char* compileString(char* source, size_t* size); +unsigned char* Toy_compileString(char* source, size_t* size); -void runBinary(unsigned char* tb, size_t size); -void runBinaryFile(char* fname); -void runSource(char* source); -void runSourceFile(char* fname); +void Toy_runBinary(unsigned char* tb, size_t size); +void Toy_runBinaryFile(char* fname); +void Toy_runSource(char* source); +void Toy_runSourceFile(char* fname); diff --git a/source/toy_ast_node.c b/source/toy_ast_node.c index 8785663..8740205 100644 --- a/source/toy_ast_node.c +++ b/source/toy_ast_node.c @@ -1,173 +1,173 @@ -#include "ast_node.h" +#include "toy_ast_node.h" -#include "memory.h" +#include "toy_memory.h" #include #include -void freeASTNodeCustom(ASTNode* node, bool freeSelf) { +static void freeASTNodeCustom(Toy_ASTNode* node, bool freeSelf) { //don't free a NULL node if (node == NULL) { return; } switch(node->type) { - case AST_NODE_ERROR: + case TOY_AST_NODE_ERROR: //NO-OP break; - case AST_NODE_LITERAL: - freeLiteral(node->atomic.literal); + case TOY_AST_NODE_LITERAL: + Toy_freeLiteral(node->atomic.literal); break; - case AST_NODE_UNARY: - freeASTNode(node->unary.child); + case TOY_AST_NODE_UNARY: + Toy_freeASTNode(node->unary.child); break; - case AST_NODE_BINARY: - freeASTNode(node->binary.left); - freeASTNode(node->binary.right); + case TOY_AST_NODE_BINARY: + Toy_freeASTNode(node->binary.left); + Toy_freeASTNode(node->binary.right); break; - case AST_NODE_TERNARY: - freeASTNode(node->ternary.condition); - freeASTNode(node->ternary.thenPath); - freeASTNode(node->ternary.elsePath); + case TOY_AST_NODE_TERNARY: + Toy_freeASTNode(node->ternary.condition); + Toy_freeASTNode(node->ternary.thenPath); + Toy_freeASTNode(node->ternary.elsePath); break; - case AST_NODE_GROUPING: - freeASTNode(node->grouping.child); + case TOY_AST_NODE_GROUPING: + Toy_freeASTNode(node->grouping.child); break; - case AST_NODE_BLOCK: + case TOY_AST_NODE_BLOCK: for (int i = 0; i < node->block.count; i++) { freeASTNodeCustom(node->block.nodes + i, false); } - FREE_ARRAY(ASTNode, node->block.nodes, node->block.capacity); + TOY_FREE_ARRAY(Toy_ASTNode, node->block.nodes, node->block.capacity); break; - case AST_NODE_COMPOUND: + case TOY_AST_NODE_COMPOUND: for (int i = 0; i < node->compound.count; i++) { freeASTNodeCustom(node->compound.nodes + i, false); } - FREE_ARRAY(ASTNode, node->compound.nodes, node->compound.capacity); + TOY_FREE_ARRAY(Toy_ASTNode, node->compound.nodes, node->compound.capacity); break; - case AST_NODE_PAIR: - freeASTNode(node->pair.left); - freeASTNode(node->pair.right); + case TOY_AST_NODE_PAIR: + Toy_freeASTNode(node->pair.left); + Toy_freeASTNode(node->pair.right); break; - case AST_NODE_INDEX: - freeASTNode(node->index.first); - freeASTNode(node->index.second); - freeASTNode(node->index.third); + case TOY_AST_NODE_INDEX: + Toy_freeASTNode(node->index.first); + Toy_freeASTNode(node->index.second); + Toy_freeASTNode(node->index.third); break; - case AST_NODE_VAR_DECL: - freeLiteral(node->varDecl.identifier); - freeLiteral(node->varDecl.typeLiteral); - freeASTNode(node->varDecl.expression); + case TOY_AST_NODE_VAR_DECL: + Toy_freeLiteral(node->varDecl.identifier); + Toy_freeLiteral(node->varDecl.typeLiteral); + Toy_freeASTNode(node->varDecl.expression); break; - case AST_NODE_FN_COLLECTION: + case TOY_AST_NODE_FN_COLLECTION: for (int i = 0; i < node->fnCollection.count; i++) { freeASTNodeCustom(node->fnCollection.nodes + i, false); } - FREE_ARRAY(ASTNode, node->fnCollection.nodes, node->fnCollection.capacity); + TOY_FREE_ARRAY(Toy_ASTNode, node->fnCollection.nodes, node->fnCollection.capacity); break; - case AST_NODE_FN_DECL: - freeLiteral(node->fnDecl.identifier); - freeASTNode(node->fnDecl.arguments); - freeASTNode(node->fnDecl.returns); - freeASTNode(node->fnDecl.block); + case TOY_AST_NODE_FN_DECL: + Toy_freeLiteral(node->fnDecl.identifier); + Toy_freeASTNode(node->fnDecl.arguments); + Toy_freeASTNode(node->fnDecl.returns); + Toy_freeASTNode(node->fnDecl.block); break; - case AST_NODE_FN_CALL: - freeASTNode(node->fnCall.arguments); + case TOY_AST_NODE_FN_CALL: + Toy_freeASTNode(node->fnCall.arguments); break; - case AST_NODE_FN_RETURN: - freeASTNode(node->returns.returns); + case TOY_AST_NODE_FN_RETURN: + Toy_freeASTNode(node->returns.returns); break; - case AST_NODE_IF: - freeASTNode(node->pathIf.condition); - freeASTNode(node->pathIf.thenPath); - freeASTNode(node->pathIf.elsePath); + case TOY_AST_NODE_IF: + Toy_freeASTNode(node->pathIf.condition); + Toy_freeASTNode(node->pathIf.thenPath); + Toy_freeASTNode(node->pathIf.elsePath); break; - case AST_NODE_WHILE: - freeASTNode(node->pathWhile.condition); - freeASTNode(node->pathWhile.thenPath); + case TOY_AST_NODE_WHILE: + Toy_freeASTNode(node->pathWhile.condition); + Toy_freeASTNode(node->pathWhile.thenPath); break; - case AST_NODE_FOR: - freeASTNode(node->pathFor.preClause); - freeASTNode(node->pathFor.postClause); - freeASTNode(node->pathFor.condition); - freeASTNode(node->pathFor.thenPath); + case TOY_AST_NODE_FOR: + Toy_freeASTNode(node->pathFor.preClause); + Toy_freeASTNode(node->pathFor.postClause); + Toy_freeASTNode(node->pathFor.condition); + Toy_freeASTNode(node->pathFor.thenPath); break; - case AST_NODE_BREAK: + case TOY_AST_NODE_BREAK: //NO-OP break; - case AST_NODE_CONTINUE: + case TOY_AST_NODE_CONTINUE: //NO-OP break; - case AST_NODE_PREFIX_INCREMENT: - freeLiteral(node->prefixIncrement.identifier); + case TOY_AST_NODE_PREFIX_INCREMENT: + Toy_freeLiteral(node->prefixIncrement.identifier); break; - case AST_NODE_PREFIX_DECREMENT: - freeLiteral(node->prefixDecrement.identifier); + case TOY_AST_NODE_PREFIX_DECREMENT: + Toy_freeLiteral(node->prefixDecrement.identifier); break; - case AST_NODE_POSTFIX_INCREMENT: - freeLiteral(node->postfixIncrement.identifier); + case TOY_AST_NODE_POSTFIX_INCREMENT: + Toy_freeLiteral(node->postfixIncrement.identifier); break; - case AST_NODE_POSTFIX_DECREMENT: - freeLiteral(node->postfixDecrement.identifier); + case TOY_AST_NODE_POSTFIX_DECREMENT: + Toy_freeLiteral(node->postfixDecrement.identifier); break; - case AST_NODE_IMPORT: - freeLiteral(node->import.identifier); - freeLiteral(node->import.alias); + case TOY_AST_NODE_IMPORT: + Toy_freeLiteral(node->import.identifier); + Toy_freeLiteral(node->import.alias); break; } if (freeSelf) { - FREE(ASTNode, node); + TOY_FREE(Toy_ASTNode, node); } } -void freeASTNode(ASTNode* node) { +void Toy_freeASTNode(Toy_ASTNode* node) { freeASTNodeCustom(node, true); } //various emitters -void emitASTNodeLiteral(ASTNode** nodeHandle, Literal literal) { +void Toy_emitASTNodeLiteral(Toy_ASTNode** nodeHandle, Toy_Literal literal) { //allocate a new node - *nodeHandle = ALLOCATE(ASTNode, 1); + *nodeHandle = TOY_ALLOCATE(Toy_ASTNode, 1); - (*nodeHandle)->type = AST_NODE_LITERAL; - (*nodeHandle)->atomic.literal = copyLiteral(literal); + (*nodeHandle)->type = TOY_AST_NODE_LITERAL; + (*nodeHandle)->atomic.literal = Toy_copyLiteral(literal); } -void emitASTNodeUnary(ASTNode** nodeHandle, Opcode opcode, ASTNode* child) { +void Toy_emitASTNodeUnary(Toy_ASTNode** nodeHandle, Toy_Opcode opcode, Toy_ASTNode* child) { //allocate a new node - *nodeHandle = ALLOCATE(ASTNode, 1); + *nodeHandle = TOY_ALLOCATE(Toy_ASTNode, 1); - (*nodeHandle)->type = AST_NODE_UNARY; + (*nodeHandle)->type = TOY_AST_NODE_UNARY; (*nodeHandle)->unary.opcode = opcode; (*nodeHandle)->unary.child = child; } -void emitASTNodeBinary(ASTNode** nodeHandle, ASTNode* rhs, Opcode opcode) { - ASTNode* tmp = ALLOCATE(ASTNode, 1); +void Toy_emitASTNodeBinary(Toy_ASTNode** nodeHandle, Toy_ASTNode* rhs, Toy_Opcode opcode) { + Toy_ASTNode* tmp = TOY_ALLOCATE(Toy_ASTNode, 1); - tmp->type = AST_NODE_BINARY; + tmp->type = TOY_AST_NODE_BINARY; tmp->binary.opcode = opcode; tmp->binary.left = *nodeHandle; tmp->binary.right = rhs; @@ -175,10 +175,10 @@ void emitASTNodeBinary(ASTNode** nodeHandle, ASTNode* rhs, Opcode opcode) { *nodeHandle = tmp; } -void emitASTNodeTernary(ASTNode** nodeHandle, ASTNode* condition, ASTNode* thenPath, ASTNode* elsePath) { - ASTNode* tmp = ALLOCATE(ASTNode, 1); +void Toy_emitASTNodeTernary(Toy_ASTNode** nodeHandle, Toy_ASTNode* condition, Toy_ASTNode* thenPath, Toy_ASTNode* elsePath) { + Toy_ASTNode* tmp = TOY_ALLOCATE(Toy_ASTNode, 1); - tmp->type = AST_NODE_TERNARY; + tmp->type = TOY_AST_NODE_TERNARY; tmp->ternary.condition = condition; tmp->ternary.thenPath = thenPath; tmp->ternary.elsePath = elsePath; @@ -186,19 +186,19 @@ void emitASTNodeTernary(ASTNode** nodeHandle, ASTNode* condition, ASTNode* thenP *nodeHandle = tmp; } -void emitASTNodeGrouping(ASTNode** nodeHandle) { - ASTNode* tmp = ALLOCATE(ASTNode, 1); +void Toy_emitASTNodeGrouping(Toy_ASTNode** nodeHandle) { + Toy_ASTNode* tmp = TOY_ALLOCATE(Toy_ASTNode, 1); - tmp->type = AST_NODE_GROUPING; + tmp->type = TOY_AST_NODE_GROUPING; tmp->grouping.child = *nodeHandle; *nodeHandle = tmp; } -void emitASTNodeBlock(ASTNode** nodeHandle) { - ASTNode* tmp = ALLOCATE(ASTNode, 1); +void Toy_emitASTNodeBlock(Toy_ASTNode** nodeHandle) { + Toy_ASTNode* tmp = TOY_ALLOCATE(Toy_ASTNode, 1); - tmp->type = AST_NODE_BLOCK; + tmp->type = TOY_AST_NODE_BLOCK; tmp->block.nodes = NULL; //NOTE: appended by the parser tmp->block.capacity = 0; tmp->block.count = 0; @@ -206,10 +206,10 @@ void emitASTNodeBlock(ASTNode** nodeHandle) { *nodeHandle = tmp; } -void emitASTNodeCompound(ASTNode** nodeHandle, LiteralType literalType) { - ASTNode* tmp = ALLOCATE(ASTNode, 1); +void Toy_emitASTNodeCompound(Toy_ASTNode** nodeHandle, Toy_LiteralType literalType) { + Toy_ASTNode* tmp = TOY_ALLOCATE(Toy_ASTNode, 1); - tmp->type = AST_NODE_COMPOUND; + tmp->type = TOY_AST_NODE_COMPOUND; tmp->compound.literalType = literalType; tmp->compound.nodes = NULL; tmp->compound.capacity = 0; @@ -218,17 +218,17 @@ void emitASTNodeCompound(ASTNode** nodeHandle, LiteralType literalType) { *nodeHandle = tmp; } -void setASTNodePair(ASTNode* node, ASTNode* left, ASTNode* right) { +void Toy_setASTNodePair(Toy_ASTNode* node, Toy_ASTNode* left, Toy_ASTNode* right) { //set - assume the node has already been allocated - node->type = AST_NODE_PAIR; + node->type = TOY_AST_NODE_PAIR; node->pair.left = left; node->pair.right = right; } -void emitASTNodeIndex(ASTNode** nodeHandle, ASTNode* first, ASTNode* second, ASTNode* third) { - ASTNode* tmp = ALLOCATE(ASTNode, 1); +void Toy_emitASTNodeIndex(Toy_ASTNode** nodeHandle, Toy_ASTNode* first, Toy_ASTNode* second, Toy_ASTNode* third) { + Toy_ASTNode* tmp = TOY_ALLOCATE(Toy_ASTNode, 1); - tmp->type = AST_NODE_INDEX; + tmp->type = TOY_AST_NODE_INDEX; tmp->index.first = first; tmp->index.second = second; tmp->index.third = third; @@ -236,10 +236,10 @@ void emitASTNodeIndex(ASTNode** nodeHandle, ASTNode* first, ASTNode* second, AST *nodeHandle = tmp; } -void emitASTNodeVarDecl(ASTNode** nodeHandle, Literal identifier, Literal typeLiteral, ASTNode* expression) { - ASTNode* tmp = ALLOCATE(ASTNode, 1); +void Toy_emitASTNodeVarDecl(Toy_ASTNode** nodeHandle, Toy_Literal identifier, Toy_Literal typeLiteral, Toy_ASTNode* expression) { + Toy_ASTNode* tmp = TOY_ALLOCATE(Toy_ASTNode, 1); - tmp->type = AST_NODE_VAR_DECL; + tmp->type = TOY_AST_NODE_VAR_DECL; tmp->varDecl.identifier = identifier; tmp->varDecl.typeLiteral = typeLiteral; tmp->varDecl.expression = expression; @@ -247,10 +247,10 @@ void emitASTNodeVarDecl(ASTNode** nodeHandle, Literal identifier, Literal typeLi *nodeHandle = tmp; } -void emitASTNodeFnCollection(ASTNode** nodeHandle) { //a collection of nodes, intended for use with functions - ASTNode* tmp = ALLOCATE(ASTNode, 1); +void Toy_emitASTNodeFnCollection(Toy_ASTNode** nodeHandle) { //a collection of nodes, intended for use with functions + Toy_ASTNode* tmp = TOY_ALLOCATE(Toy_ASTNode, 1); - tmp->type = AST_NODE_FN_COLLECTION; + tmp->type = TOY_AST_NODE_FN_COLLECTION; tmp->fnCollection.nodes = NULL; tmp->fnCollection.capacity = 0; tmp->fnCollection.count = 0; @@ -258,10 +258,10 @@ void emitASTNodeFnCollection(ASTNode** nodeHandle) { //a collection of nodes, in *nodeHandle = tmp; } -void emitASTNodeFnDecl(ASTNode** nodeHandle, Literal identifier, ASTNode* arguments, ASTNode* returns, ASTNode* block) { - ASTNode* tmp = ALLOCATE(ASTNode, 1); +void Toy_emitASTNodeFnDecl(Toy_ASTNode** nodeHandle, Toy_Literal identifier, Toy_ASTNode* arguments, Toy_ASTNode* returns, Toy_ASTNode* block) { + Toy_ASTNode* tmp = TOY_ALLOCATE(Toy_ASTNode, 1); - tmp->type = AST_NODE_FN_DECL; + tmp->type = TOY_AST_NODE_FN_DECL; tmp->fnDecl.identifier = identifier; tmp->fnDecl.arguments = arguments; tmp->fnDecl.returns = returns; @@ -270,29 +270,29 @@ void emitASTNodeFnDecl(ASTNode** nodeHandle, Literal identifier, ASTNode* argume *nodeHandle = tmp; } -void emitASTNodeFnCall(ASTNode** nodeHandle, ASTNode* arguments) { - ASTNode* tmp = ALLOCATE(ASTNode, 1); +void Toy_emitASTNodeFnCall(Toy_ASTNode** nodeHandle, Toy_ASTNode* arguments) { + Toy_ASTNode* tmp = TOY_ALLOCATE(Toy_ASTNode, 1); - tmp->type = AST_NODE_FN_CALL; + tmp->type = TOY_AST_NODE_FN_CALL; tmp->fnCall.arguments = arguments; tmp->fnCall.argumentCount = arguments->fnCollection.count; *nodeHandle = tmp; } -void emitASTNodeFnReturn(ASTNode** nodeHandle, ASTNode* returns) { - ASTNode* tmp = ALLOCATE(ASTNode, 1); +void Toy_emitASTNodeFnReturn(Toy_ASTNode** nodeHandle, Toy_ASTNode* returns) { + Toy_ASTNode* tmp = TOY_ALLOCATE(Toy_ASTNode, 1); - tmp->type = AST_NODE_FN_RETURN; + tmp->type = TOY_AST_NODE_FN_RETURN; tmp->returns.returns = returns; *nodeHandle = tmp; } -void emitASTNodeIf(ASTNode** nodeHandle, ASTNode* condition, ASTNode* thenPath, ASTNode* elsePath) { - ASTNode* tmp = ALLOCATE(ASTNode, 1); +void Toy_emitASTNodeIf(Toy_ASTNode** nodeHandle, Toy_ASTNode* condition, Toy_ASTNode* thenPath, Toy_ASTNode* elsePath) { + Toy_ASTNode* tmp = TOY_ALLOCATE(Toy_ASTNode, 1); - tmp->type = AST_NODE_IF; + tmp->type = TOY_AST_NODE_IF; tmp->pathIf.condition = condition; tmp->pathIf.thenPath = thenPath; tmp->pathIf.elsePath = elsePath; @@ -300,20 +300,20 @@ void emitASTNodeIf(ASTNode** nodeHandle, ASTNode* condition, ASTNode* thenPath, *nodeHandle = tmp; } -void emitASTNodeWhile(ASTNode** nodeHandle, ASTNode* condition, ASTNode* thenPath) { - ASTNode* tmp = ALLOCATE(ASTNode, 1); +void Toy_emitASTNodeWhile(Toy_ASTNode** nodeHandle, Toy_ASTNode* condition, Toy_ASTNode* thenPath) { + Toy_ASTNode* tmp = TOY_ALLOCATE(Toy_ASTNode, 1); - tmp->type = AST_NODE_WHILE; + tmp->type = TOY_AST_NODE_WHILE; tmp->pathWhile.condition = condition; tmp->pathWhile.thenPath = thenPath; *nodeHandle = tmp; } -void emitASTNodeFor(ASTNode** nodeHandle, ASTNode* preClause, ASTNode* condition, ASTNode* postClause, ASTNode* thenPath) { - ASTNode* tmp = ALLOCATE(ASTNode, 1); +void Toy_emitASTNodeFor(Toy_ASTNode** nodeHandle, Toy_ASTNode* preClause, Toy_ASTNode* condition, Toy_ASTNode* postClause, Toy_ASTNode* thenPath) { + Toy_ASTNode* tmp = TOY_ALLOCATE(Toy_ASTNode, 1); - tmp->type = AST_NODE_FOR; + tmp->type = TOY_AST_NODE_FOR; tmp->pathFor.preClause = preClause; tmp->pathFor.condition = condition; tmp->pathFor.postClause = postClause; @@ -322,64 +322,64 @@ void emitASTNodeFor(ASTNode** nodeHandle, ASTNode* preClause, ASTNode* condition *nodeHandle = tmp; } -void emitASTNodeBreak(ASTNode** nodeHandle) { - ASTNode* tmp = ALLOCATE(ASTNode, 1); +void Toy_emitASTNodeBreak(Toy_ASTNode** nodeHandle) { + Toy_ASTNode* tmp = TOY_ALLOCATE(Toy_ASTNode, 1); - tmp->type = AST_NODE_BREAK; + tmp->type = TOY_AST_NODE_BREAK; *nodeHandle = tmp; } -void emitASTNodeContinue(ASTNode** nodeHandle) { - ASTNode* tmp = ALLOCATE(ASTNode, 1); +void Toy_emitASTNodeContinue(Toy_ASTNode** nodeHandle) { + Toy_ASTNode* tmp = TOY_ALLOCATE(Toy_ASTNode, 1); - tmp->type = AST_NODE_CONTINUE; + tmp->type = TOY_AST_NODE_CONTINUE; *nodeHandle = tmp; } -void emitASTNodePrefixIncrement(ASTNode** nodeHandle, Literal identifier) { - ASTNode* tmp = ALLOCATE(ASTNode, 1); +void Toy_emitASTNodePrefixIncrement(Toy_ASTNode** nodeHandle, Toy_Literal identifier) { + Toy_ASTNode* tmp = TOY_ALLOCATE(Toy_ASTNode, 1); - tmp->type = AST_NODE_PREFIX_INCREMENT; - tmp->prefixIncrement.identifier = copyLiteral(identifier); + tmp->type = TOY_AST_NODE_PREFIX_INCREMENT; + tmp->prefixIncrement.identifier = Toy_copyLiteral(identifier); *nodeHandle = tmp; } -void emitASTNodePrefixDecrement(ASTNode** nodeHandle, Literal identifier) { - ASTNode* tmp = ALLOCATE(ASTNode, 1); +void Toy_emitASTNodePrefixDecrement(Toy_ASTNode** nodeHandle, Toy_Literal identifier) { + Toy_ASTNode* tmp = TOY_ALLOCATE(Toy_ASTNode, 1); - tmp->type = AST_NODE_PREFIX_DECREMENT; - tmp->prefixDecrement.identifier = copyLiteral(identifier); + tmp->type = TOY_AST_NODE_PREFIX_DECREMENT; + tmp->prefixDecrement.identifier = Toy_copyLiteral(identifier); *nodeHandle = tmp; } -void emitASTNodePostfixIncrement(ASTNode** nodeHandle, Literal identifier) { - ASTNode* tmp = ALLOCATE(ASTNode, 1); +void Toy_emitASTNodePostfixIncrement(Toy_ASTNode** nodeHandle, Toy_Literal identifier) { + Toy_ASTNode* tmp = TOY_ALLOCATE(Toy_ASTNode, 1); - tmp->type = AST_NODE_POSTFIX_INCREMENT; - tmp->postfixIncrement.identifier = copyLiteral(identifier); + tmp->type = TOY_AST_NODE_POSTFIX_INCREMENT; + tmp->postfixIncrement.identifier = Toy_copyLiteral(identifier); *nodeHandle = tmp; } -void emitASTNodePostfixDecrement(ASTNode** nodeHandle, Literal identifier) { - ASTNode* tmp = ALLOCATE(ASTNode, 1); +void Toy_emitASTNodePostfixDecrement(Toy_ASTNode** nodeHandle, Toy_Literal identifier) { + Toy_ASTNode* tmp = TOY_ALLOCATE(Toy_ASTNode, 1); - tmp->type = AST_NODE_POSTFIX_DECREMENT; - tmp->postfixDecrement.identifier = copyLiteral(identifier); + tmp->type = TOY_AST_NODE_POSTFIX_DECREMENT; + tmp->postfixDecrement.identifier = Toy_copyLiteral(identifier); *nodeHandle = tmp; } -void emitASTNodeImport(ASTNode** nodeHandle, Literal identifier, Literal alias) { - ASTNode* tmp = ALLOCATE(ASTNode, 1); +void Toy_emitASTNodeImport(Toy_ASTNode** nodeHandle, Toy_Literal identifier, Toy_Literal alias) { + Toy_ASTNode* tmp = TOY_ALLOCATE(Toy_ASTNode, 1); - tmp->type = AST_NODE_IMPORT; - tmp->import.identifier = copyLiteral(identifier); - tmp->import.alias = copyLiteral(alias); + tmp->type = TOY_AST_NODE_IMPORT; + tmp->import.identifier = Toy_copyLiteral(identifier); + tmp->import.alias = Toy_copyLiteral(alias); *nodeHandle = tmp; } diff --git a/source/toy_ast_node.h b/source/toy_ast_node.h index 84e4170..ede7c59 100644 --- a/source/toy_ast_node.h +++ b/source/toy_ast_node.h @@ -1,269 +1,269 @@ #pragma once #include "toy_common.h" -#include "literal.h" -#include "opcodes.h" -#include "token_types.h" +#include "toy_literal.h" +#include "toy_opcodes.h" +#include "toy_token_types.h" //nodes are the intermediaries between parsers and compilers -typedef union _node ASTNode; +typedef union Toy_private_node Toy_ASTNode; -typedef enum ASTNodeType { - AST_NODE_ERROR, - AST_NODE_LITERAL, //a simple value - AST_NODE_UNARY, //one child + opcode - AST_NODE_BINARY, //two children, left and right + opcode - AST_NODE_TERNARY, //three children, condition, then path & else path - AST_NODE_GROUPING, //one child - AST_NODE_BLOCK, //contains a sub-node array - AST_NODE_COMPOUND, //contains a sub-node array - AST_NODE_PAIR, //contains a left and right - AST_NODE_INDEX, //index a variable - AST_NODE_VAR_DECL, //contains identifier literal, typenode, expression definition - AST_NODE_FN_DECL, //containd identifier literal, arguments node, returns node, block node - AST_NODE_FN_COLLECTION, //parts of a function - AST_NODE_FN_CALL, //call a function - AST_NODE_FN_RETURN, //for control flow - AST_NODE_IF, //for control flow - AST_NODE_WHILE, //for control flow - AST_NODE_FOR, //for control flow - AST_NODE_BREAK, //for control flow - AST_NODE_CONTINUE, //for control flow - AST_NODE_PREFIX_INCREMENT, //increment a variable - AST_NODE_POSTFIX_INCREMENT, //increment a variable - AST_NODE_PREFIX_DECREMENT, //decrement a variable - AST_NODE_POSTFIX_DECREMENT, //decrement a variable - AST_NODE_IMPORT, //import a library -} ASTNodeType; +typedef enum Toy_ASTNodeType { + TOY_AST_NODE_ERROR, + TOY_AST_NODE_LITERAL, //a simple value + TOY_AST_NODE_UNARY, //one child + opcode + TOY_AST_NODE_BINARY, //two children, left and right + opcode + TOY_AST_NODE_TERNARY, //three children, condition, then path & else path + TOY_AST_NODE_GROUPING, //one child + TOY_AST_NODE_BLOCK, //contains a sub-node array + TOY_AST_NODE_COMPOUND, //contains a sub-node array + TOY_AST_NODE_PAIR, //contains a left and right + TOY_AST_NODE_INDEX, //index a variable + TOY_AST_NODE_VAR_DECL, //contains identifier literal, typenode, expression definition + TOY_AST_NODE_FN_DECL, //containd identifier literal, arguments node, returns node, block node + TOY_AST_NODE_FN_COLLECTION, //parts of a function + TOY_AST_NODE_FN_CALL, //call a function + TOY_AST_NODE_FN_RETURN, //for control flow + TOY_AST_NODE_IF, //for control flow + TOY_AST_NODE_WHILE, //for control flow + TOY_AST_NODE_FOR, //for control flow + TOY_AST_NODE_BREAK, //for control flow + TOY_AST_NODE_CONTINUE, //for control flow + TOY_AST_NODE_PREFIX_INCREMENT, //increment a variable + TOY_AST_NODE_POSTFIX_INCREMENT, //increment a variable + TOY_AST_NODE_PREFIX_DECREMENT, //decrement a variable + TOY_AST_NODE_POSTFIX_DECREMENT, //decrement a variable + TOY_AST_NODE_IMPORT, //import a library +} Toy_ASTNodeType; //literals -void emitASTNodeLiteral(ASTNode** nodeHandle, Literal literal); +void Toy_emitASTNodeLiteral(Toy_ASTNode** nodeHandle, Toy_Literal literal); -typedef struct NodeLiteral { - ASTNodeType type; - Literal literal; -} NodeLiteral; +typedef struct Toy_NodeLiteral { + Toy_ASTNodeType type; + Toy_Literal literal; +} Toy_NodeLiteral; //unary operator -void emitASTNodeUnary(ASTNode** nodeHandle, Opcode opcode, ASTNode* child); +void Toy_emitASTNodeUnary(Toy_ASTNode** nodeHandle, Toy_Opcode opcode, Toy_ASTNode* child); -typedef struct NodeUnary { - ASTNodeType type; - Opcode opcode; - ASTNode* child; -} NodeUnary; +typedef struct Toy_NodeUnary { + Toy_ASTNodeType type; + Toy_Opcode opcode; + Toy_ASTNode* child; +} Toy_NodeUnary; //binary operator -void emitASTNodeBinary(ASTNode** nodeHandle, ASTNode* rhs, Opcode opcode); //handled node becomes lhs +void Toy_emitASTNodeBinary(Toy_ASTNode** nodeHandle, Toy_ASTNode* rhs, Toy_Opcode opcode); //handled node becomes lhs -typedef struct NodeBinary { - ASTNodeType type; - Opcode opcode; - ASTNode* left; - ASTNode* right; -} NodeBinary; +typedef struct Toy_NodeBinary { + Toy_ASTNodeType type; + Toy_Opcode opcode; + Toy_ASTNode* left; + Toy_ASTNode* right; +} Toy_NodeBinary; //ternary operator -void emitASTNodeTernary(ASTNode** nodeHandle, ASTNode* condition, ASTNode* thenPath, ASTNode* elsePath); +void Toy_emitASTNodeTernary(Toy_ASTNode** nodeHandle, Toy_ASTNode* condition, Toy_ASTNode* thenPath, Toy_ASTNode* elsePath); -typedef struct NodeTernary { - ASTNodeType type; - ASTNode* condition; - ASTNode* thenPath; - ASTNode* elsePath; -} NodeTernary; +typedef struct Toy_NodeTernary { + Toy_ASTNodeType type; + Toy_ASTNode* condition; + Toy_ASTNode* thenPath; + Toy_ASTNode* elsePath; +} Toy_NodeTernary; //grouping of other AST nodes -void emitASTNodeGrouping(ASTNode** nodeHandle); +void Toy_emitASTNodeGrouping(Toy_ASTNode** nodeHandle); -typedef struct NodeGrouping { - ASTNodeType type; - ASTNode* child; -} NodeGrouping; +typedef struct Toy_NodeGrouping { + Toy_ASTNodeType type; + Toy_ASTNode* child; +} Toy_NodeGrouping; //block of statement nodes -void emitASTNodeBlock(ASTNode** nodeHandle); +void Toy_emitASTNodeBlock(Toy_ASTNode** nodeHandle); -typedef struct NodeBlock { - ASTNodeType type; - ASTNode* nodes; +typedef struct Toy_NodeBlock { + Toy_ASTNodeType type; + Toy_ASTNode* nodes; int capacity; int count; -} NodeBlock; +} Toy_NodeBlock; //compound literals (array, dictionary) -void emitASTNodeCompound(ASTNode** nodeHandle, LiteralType literalType); +void Toy_emitASTNodeCompound(Toy_ASTNode** nodeHandle, Toy_LiteralType literalType); -typedef struct NodeCompound { - ASTNodeType type; - LiteralType literalType; - ASTNode* nodes; +typedef struct Toy_NodeCompound { + Toy_ASTNodeType type; + Toy_LiteralType literalType; + Toy_ASTNode* nodes; int capacity; int count; -} NodeCompound; +} Toy_NodeCompound; -void setASTNodePair(ASTNode* node, ASTNode* left, ASTNode* right); //NOTE: this is a set function, not an emit function +void Toy_setASTNodePair(Toy_ASTNode* node, Toy_ASTNode* left, Toy_ASTNode* right); //NOTE: this is a set function, not an emit function -typedef struct NodePair { - ASTNodeType type; - ASTNode* left; - ASTNode* right; -} NodePair; +typedef struct Toy_NodePair { + Toy_ASTNodeType type; + Toy_ASTNode* left; + Toy_ASTNode* right; +} Toy_NodePair; -void emitASTNodeIndex(ASTNode** nodeHandle, ASTNode* first, ASTNode* second, ASTNode* third); +void Toy_emitASTNodeIndex(Toy_ASTNode** nodeHandle, Toy_ASTNode* first, Toy_ASTNode* second, Toy_ASTNode* third); -typedef struct NodeIndex { - ASTNodeType type; - ASTNode* first; - ASTNode* second; - ASTNode* third; -} NodeIndex; +typedef struct Toy_NodeIndex { + Toy_ASTNodeType type; + Toy_ASTNode* first; + Toy_ASTNode* second; + Toy_ASTNode* third; +} Toy_NodeIndex; //variable declaration -void emitASTNodeVarDecl(ASTNode** nodeHandle, Literal identifier, Literal type, ASTNode* expression); +void Toy_emitASTNodeVarDecl(Toy_ASTNode** nodeHandle, Toy_Literal identifier, Toy_Literal type, Toy_ASTNode* expression); -typedef struct NodeVarDecl { - ASTNodeType type; - Literal identifier; - Literal typeLiteral; - ASTNode* expression; -} NodeVarDecl; +typedef struct Toy_NodeVarDecl { + Toy_ASTNodeType type; + Toy_Literal identifier; + Toy_Literal typeLiteral; + Toy_ASTNode* expression; +} Toy_NodeVarDecl; //NOTE: fnCollection is used by fnDecl, fnCall and fnReturn -void emitASTNodeFnCollection(ASTNode** nodeHandle); +void Toy_emitASTNodeFnCollection(Toy_ASTNode** nodeHandle); -typedef struct NodeFnCollection { - ASTNodeType type; - ASTNode* nodes; +typedef struct Toy_NodeFnCollection { + Toy_ASTNodeType type; + Toy_ASTNode* nodes; int capacity; int count; -} NodeFnCollection; +} Toy_NodeFnCollection; //function declaration -void emitASTNodeFnDecl(ASTNode** nodeHandle, Literal identifier, ASTNode* arguments, ASTNode* returns, ASTNode* block); +void Toy_emitASTNodeFnDecl(Toy_ASTNode** nodeHandle, Toy_Literal identifier, Toy_ASTNode* arguments, Toy_ASTNode* returns, Toy_ASTNode* block); -typedef struct NodeFnDecl { - ASTNodeType type; - Literal identifier; - ASTNode* arguments; - ASTNode* returns; - ASTNode* block; -} NodeFnDecl; +typedef struct Toy_NodeFnDecl { + Toy_ASTNodeType type; + Toy_Literal identifier; + Toy_ASTNode* arguments; + Toy_ASTNode* returns; + Toy_ASTNode* block; +} Toy_NodeFnDecl; //function call -void emitASTNodeFnCall(ASTNode** nodeHandle, ASTNode* arguments); +void Toy_emitASTNodeFnCall(Toy_ASTNode** nodeHandle, Toy_ASTNode* arguments); -typedef struct NodeFnCall { - ASTNodeType type; - ASTNode* arguments; +typedef struct Toy_NodeFnCall { + Toy_ASTNodeType type; + Toy_ASTNode* arguments; int argumentCount; //NOTE: leave this, so it can be hacked by dottify() -} NodeFnCall; +} Toy_NodeFnCall; //function return -void emitASTNodeFnReturn(ASTNode** nodeHandle, ASTNode* returns); +void Toy_emitASTNodeFnReturn(Toy_ASTNode** nodeHandle, Toy_ASTNode* returns); -typedef struct NodeFnReturn { - ASTNodeType type; - ASTNode* returns; -} NodeFnReturn; +typedef struct Toy_NodeFnReturn { + Toy_ASTNodeType type; + Toy_ASTNode* returns; +} Toy_NodeFnReturn; //control flow path - if-else, while, for, break, continue, return -void emitASTNodeIf(ASTNode** nodeHandle, ASTNode* condition, ASTNode* thenPath, ASTNode* elsePath); -void emitASTNodeWhile(ASTNode** nodeHandle, ASTNode* condition, ASTNode* thenPath); -void emitASTNodeFor(ASTNode** nodeHandle, ASTNode* preClause, ASTNode* condition, ASTNode* postClause, ASTNode* thenPath); -void emitASTNodeBreak(ASTNode** nodeHandle); -void emitASTNodeContinue(ASTNode** nodeHandle); +void Toy_emitASTNodeIf(Toy_ASTNode** nodeHandle, Toy_ASTNode* condition, Toy_ASTNode* thenPath, Toy_ASTNode* elsePath); +void Toy_emitASTNodeWhile(Toy_ASTNode** nodeHandle, Toy_ASTNode* condition, Toy_ASTNode* thenPath); +void Toy_emitASTNodeFor(Toy_ASTNode** nodeHandle, Toy_ASTNode* preClause, Toy_ASTNode* condition, Toy_ASTNode* postClause, Toy_ASTNode* thenPath); +void Toy_emitASTNodeBreak(Toy_ASTNode** nodeHandle); +void Toy_emitASTNodeContinue(Toy_ASTNode** nodeHandle); -typedef struct NodeIf { - ASTNodeType type; - ASTNode* condition; - ASTNode* thenPath; - ASTNode* elsePath; -} NodeIf; +typedef struct Toy_NodeIf { + Toy_ASTNodeType type; + Toy_ASTNode* condition; + Toy_ASTNode* thenPath; + Toy_ASTNode* elsePath; +} Toy_NodeIf; -typedef struct NodeWhile { - ASTNodeType type; - ASTNode* condition; - ASTNode* thenPath; -} NodeWhile; +typedef struct Toy_NodeWhile { + Toy_ASTNodeType type; + Toy_ASTNode* condition; + Toy_ASTNode* thenPath; +} Toy_NodeWhile; -typedef struct NodeFor { - ASTNodeType type; - ASTNode* preClause; - ASTNode* condition; - ASTNode* postClause; - ASTNode* thenPath; -} NodeFor; +typedef struct Toy_NodeFor { + Toy_ASTNodeType type; + Toy_ASTNode* preClause; + Toy_ASTNode* condition; + Toy_ASTNode* postClause; + Toy_ASTNode* thenPath; +} Toy_NodeFor; -typedef struct NodeBreak { - ASTNodeType type; -} NodeBreak; +typedef struct Toy_NodeBreak { + Toy_ASTNodeType type; +} Toy_NodeBreak; -typedef struct NodeContinue { - ASTNodeType type; -} NodeContinue; +typedef struct Toy_NodeContinue { + Toy_ASTNodeType type; +} Toy_NodeContinue; //pre-post increment/decrement -void emitASTNodePrefixIncrement(ASTNode** nodeHandle, Literal identifier); -void emitASTNodePrefixDecrement(ASTNode** nodeHandle, Literal identifier); -void emitASTNodePostfixIncrement(ASTNode** nodeHandle, Literal identifier); -void emitASTNodePostfixDecrement(ASTNode** nodeHandle, Literal identifier); +void Toy_emitASTNodePrefixIncrement(Toy_ASTNode** nodeHandle, Toy_Literal identifier); +void Toy_emitASTNodePrefixDecrement(Toy_ASTNode** nodeHandle, Toy_Literal identifier); +void Toy_emitASTNodePostfixIncrement(Toy_ASTNode** nodeHandle, Toy_Literal identifier); +void Toy_emitASTNodePostfixDecrement(Toy_ASTNode** nodeHandle, Toy_Literal identifier); -typedef struct NodePrefixIncrement { - ASTNodeType type; - Literal identifier; -} NodePrefixIncrement; +typedef struct Toy_NodePrefixIncrement { + Toy_ASTNodeType type; + Toy_Literal identifier; +} Toy_NodePrefixIncrement; -typedef struct NodePrefixDecrement { - ASTNodeType type; - Literal identifier; -} NodePrefixDecrement; +typedef struct Toy_NodePrefixDecrement { + Toy_ASTNodeType type; + Toy_Literal identifier; +} Toy_NodePrefixDecrement; -typedef struct NodePostfixIncrement { - ASTNodeType type; - Literal identifier; -} NodePostfixIncrement; +typedef struct Toy_NodePostfixIncrement { + Toy_ASTNodeType type; + Toy_Literal identifier; +} Toy_NodePostfixIncrement; -typedef struct NodePostfixDecrement { - ASTNodeType type; - Literal identifier; -} NodePostfixDecrement; +typedef struct Toy_NodePostfixDecrement { + Toy_ASTNodeType type; + Toy_Literal identifier; +} Toy_NodePostfixDecrement; //import a library -void emitASTNodeImport(ASTNode** nodeHandle, Literal identifier, Literal alias); +void Toy_emitASTNodeImport(Toy_ASTNode** nodeHandle, Toy_Literal identifier, Toy_Literal alias); -typedef struct NodeImport { - ASTNodeType type; - Literal identifier; - Literal alias; -} NodeImport; +typedef struct Toy_NodeImport { + Toy_ASTNodeType type; + Toy_Literal identifier; + Toy_Literal alias; +} Toy_NodeImport; -union _node { - ASTNodeType type; - NodeLiteral atomic; - NodeUnary unary; - NodeBinary binary; - NodeTernary ternary; - NodeGrouping grouping; - NodeBlock block; - NodeCompound compound; - NodePair pair; - NodeIndex index; - NodeVarDecl varDecl; - NodeFnCollection fnCollection; - NodeFnDecl fnDecl; - NodeFnCall fnCall; - NodeFnReturn returns; - NodeIf pathIf; - NodeWhile pathWhile; - NodeFor pathFor; - NodeBreak pathBreak; - NodeContinue pathContinue; - NodePrefixIncrement prefixIncrement; - NodePrefixDecrement prefixDecrement; - NodePostfixIncrement postfixIncrement; - NodePostfixDecrement postfixDecrement; - NodeImport import; +union Toy_private_node { + Toy_ASTNodeType type; + Toy_NodeLiteral atomic; + Toy_NodeUnary unary; + Toy_NodeBinary binary; + Toy_NodeTernary ternary; + Toy_NodeGrouping grouping; + Toy_NodeBlock block; + Toy_NodeCompound compound; + Toy_NodePair pair; + Toy_NodeIndex index; + Toy_NodeVarDecl varDecl; + Toy_NodeFnCollection fnCollection; + Toy_NodeFnDecl fnDecl; + Toy_NodeFnCall fnCall; + Toy_NodeFnReturn returns; + Toy_NodeIf pathIf; + Toy_NodeWhile pathWhile; + Toy_NodeFor pathFor; + Toy_NodeBreak pathBreak; + Toy_NodeContinue pathContinue; + Toy_NodePrefixIncrement prefixIncrement; + Toy_NodePrefixDecrement prefixDecrement; + Toy_NodePostfixIncrement postfixIncrement; + Toy_NodePostfixDecrement postfixDecrement; + Toy_NodeImport import; }; -TOY_API void freeASTNode(ASTNode* node); +TOY_API void Toy_freeASTNode(Toy_ASTNode* node); diff --git a/source/toy_builtin.c b/source/toy_builtin.c index df5f70b..92d82df 100644 --- a/source/toy_builtin.c +++ b/source/toy_builtin.c @@ -1,235 +1,235 @@ -#include "builtin.h" +#include "toy_builtin.h" -#include "memory.h" -#include "literal.h" +#include "toy_memory.h" +#include "toy_literal.h" #include //static math utils, copied from the interpreter -static Literal addition(Interpreter* interpreter, Literal lhs, Literal rhs) { +static Toy_Literal addition(Toy_Interpreter* interpreter, Toy_Literal lhs, Toy_Literal rhs) { //special case for string concatenation ONLY - if (IS_STRING(lhs) && IS_STRING(rhs)) { + if (TOY_IS_STRING(lhs) && TOY_IS_STRING(rhs)) { //check for overflow - int totalLength = AS_STRING(lhs)->length + AS_STRING(rhs)->length; - if (totalLength > MAX_STRING_LENGTH) { + int totalLength = TOY_AS_STRING(lhs)->length + TOY_AS_STRING(rhs)->length; + if (totalLength > TOY_MAX_STRING_LENGTH) { interpreter->errorOutput("Can't concatenate these strings (result is too long)\n"); - return TO_NULL_LITERAL; + return TOY_TO_NULL_LITERAL; } //concat the strings - char buffer[MAX_STRING_LENGTH]; - snprintf(buffer, MAX_STRING_LENGTH, "%s%s", toCString(AS_STRING(lhs)), toCString(AS_STRING(rhs))); - Literal literal = TO_STRING_LITERAL(createRefStringLength(buffer, totalLength)); + char buffer[TOY_MAX_STRING_LENGTH]; + snprintf(buffer, TOY_MAX_STRING_LENGTH, "%s%s", Toy_toCString(TOY_AS_STRING(lhs)), Toy_toCString(TOY_AS_STRING(rhs))); + Toy_Literal literal = TOY_TO_STRING_LITERAL(Toy_createRefStringLength(buffer, totalLength)); - freeLiteral(lhs); - freeLiteral(rhs); + Toy_freeLiteral(lhs); + Toy_freeLiteral(rhs); return literal; } //type coersion - if (IS_FLOAT(lhs) && IS_INTEGER(rhs)) { - rhs = TO_FLOAT_LITERAL(AS_INTEGER(rhs)); + if (TOY_IS_FLOAT(lhs) && TOY_IS_INTEGER(rhs)) { + rhs = TOY_TO_FLOAT_LITERAL(TOY_AS_INTEGER(rhs)); } - if (IS_INTEGER(lhs) && IS_FLOAT(rhs)) { - lhs = TO_FLOAT_LITERAL(AS_INTEGER(lhs)); + if (TOY_IS_INTEGER(lhs) && TOY_IS_FLOAT(rhs)) { + lhs = TOY_TO_FLOAT_LITERAL(TOY_AS_INTEGER(lhs)); } //results - Literal result = TO_NULL_LITERAL; + Toy_Literal result = TOY_TO_NULL_LITERAL; - if (IS_INTEGER(lhs) && IS_INTEGER(rhs)) { - result = TO_INTEGER_LITERAL( AS_INTEGER(lhs) + AS_INTEGER(rhs) ); + if (TOY_IS_INTEGER(lhs) && TOY_IS_INTEGER(rhs)) { + result = TOY_TO_INTEGER_LITERAL( TOY_AS_INTEGER(lhs) + TOY_AS_INTEGER(rhs) ); - freeLiteral(lhs); - freeLiteral(rhs); + Toy_freeLiteral(lhs); + Toy_freeLiteral(rhs); return result; } - if (IS_FLOAT(lhs) && IS_FLOAT(rhs)) { - result = TO_FLOAT_LITERAL( AS_FLOAT(lhs) + AS_FLOAT(rhs) ); + if (TOY_IS_FLOAT(lhs) && TOY_IS_FLOAT(rhs)) { + result = TOY_TO_FLOAT_LITERAL( TOY_AS_FLOAT(lhs) + TOY_AS_FLOAT(rhs) ); - freeLiteral(lhs); - freeLiteral(rhs); + Toy_freeLiteral(lhs); + Toy_freeLiteral(rhs); return result; } //wrong types interpreter->errorOutput("Bad arithmetic argument "); - printLiteralCustom(lhs, interpreter->errorOutput); + Toy_printLiteralCustom(lhs, interpreter->errorOutput); interpreter->errorOutput(" and "); - printLiteralCustom(rhs, interpreter->errorOutput); + Toy_printLiteralCustom(rhs, interpreter->errorOutput); interpreter->errorOutput("\n"); - freeLiteral(lhs); - freeLiteral(rhs); + Toy_freeLiteral(lhs); + Toy_freeLiteral(rhs); - return TO_NULL_LITERAL; + return TOY_TO_NULL_LITERAL; } -static Literal subtraction(Interpreter* interpreter, Literal lhs, Literal rhs) { +static Toy_Literal subtraction(Toy_Interpreter* interpreter, Toy_Literal lhs, Toy_Literal rhs) { //type coersion - if (IS_FLOAT(lhs) && IS_INTEGER(rhs)) { - rhs = TO_FLOAT_LITERAL(AS_INTEGER(rhs)); + if (TOY_IS_FLOAT(lhs) && TOY_IS_INTEGER(rhs)) { + rhs = TOY_TO_FLOAT_LITERAL(TOY_AS_INTEGER(rhs)); } - if (IS_INTEGER(lhs) && IS_FLOAT(rhs)) { - lhs = TO_FLOAT_LITERAL(AS_INTEGER(lhs)); + if (TOY_IS_INTEGER(lhs) && TOY_IS_FLOAT(rhs)) { + lhs = TOY_TO_FLOAT_LITERAL(TOY_AS_INTEGER(lhs)); } //results - Literal result = TO_NULL_LITERAL; + Toy_Literal result = TOY_TO_NULL_LITERAL; - if (IS_INTEGER(lhs) && IS_INTEGER(rhs)) { - result = TO_INTEGER_LITERAL( AS_INTEGER(lhs) - AS_INTEGER(rhs) ); + if (TOY_IS_INTEGER(lhs) && TOY_IS_INTEGER(rhs)) { + result = TOY_TO_INTEGER_LITERAL( TOY_AS_INTEGER(lhs) - TOY_AS_INTEGER(rhs) ); - freeLiteral(lhs); - freeLiteral(rhs); + Toy_freeLiteral(lhs); + Toy_freeLiteral(rhs); return result; } - if (IS_FLOAT(lhs) && IS_FLOAT(rhs)) { - result = TO_FLOAT_LITERAL( AS_FLOAT(lhs) - AS_FLOAT(rhs) ); + if (TOY_IS_FLOAT(lhs) && TOY_IS_FLOAT(rhs)) { + result = TOY_TO_FLOAT_LITERAL( TOY_AS_FLOAT(lhs) - TOY_AS_FLOAT(rhs) ); - freeLiteral(lhs); - freeLiteral(rhs); + Toy_freeLiteral(lhs); + Toy_freeLiteral(rhs); return result; } //wrong types interpreter->errorOutput("Bad arithmetic argument "); - printLiteralCustom(lhs, interpreter->errorOutput); + Toy_printLiteralCustom(lhs, interpreter->errorOutput); interpreter->errorOutput(" and "); - printLiteralCustom(rhs, interpreter->errorOutput); + Toy_printLiteralCustom(rhs, interpreter->errorOutput); interpreter->errorOutput("\n"); - freeLiteral(lhs); - freeLiteral(rhs); + Toy_freeLiteral(lhs); + Toy_freeLiteral(rhs); - return TO_NULL_LITERAL; + return TOY_TO_NULL_LITERAL; } -static Literal multiplication(Interpreter* interpreter, Literal lhs, Literal rhs) { +static Toy_Literal multiplication(Toy_Interpreter* interpreter, Toy_Literal lhs, Toy_Literal rhs) { //type coersion - if (IS_FLOAT(lhs) && IS_INTEGER(rhs)) { - rhs = TO_FLOAT_LITERAL(AS_INTEGER(rhs)); + if (TOY_IS_FLOAT(lhs) && TOY_IS_INTEGER(rhs)) { + rhs = TOY_TO_FLOAT_LITERAL(TOY_AS_INTEGER(rhs)); } - if (IS_INTEGER(lhs) && IS_FLOAT(rhs)) { - lhs = TO_FLOAT_LITERAL(AS_INTEGER(lhs)); + if (TOY_IS_INTEGER(lhs) && TOY_IS_FLOAT(rhs)) { + lhs = TOY_TO_FLOAT_LITERAL(TOY_AS_INTEGER(lhs)); } //results - Literal result = TO_NULL_LITERAL; + Toy_Literal result = TOY_TO_NULL_LITERAL; - if (IS_INTEGER(lhs) && IS_INTEGER(rhs)) { - result = TO_INTEGER_LITERAL( AS_INTEGER(lhs) * AS_INTEGER(rhs) ); + if (TOY_IS_INTEGER(lhs) && TOY_IS_INTEGER(rhs)) { + result = TOY_TO_INTEGER_LITERAL( TOY_AS_INTEGER(lhs) * TOY_AS_INTEGER(rhs) ); - freeLiteral(lhs); - freeLiteral(rhs); + Toy_freeLiteral(lhs); + Toy_freeLiteral(rhs); return result; } - if (IS_FLOAT(lhs) && IS_FLOAT(rhs)) { - result = TO_FLOAT_LITERAL( AS_FLOAT(lhs) * AS_FLOAT(rhs) ); + if (TOY_IS_FLOAT(lhs) && TOY_IS_FLOAT(rhs)) { + result = TOY_TO_FLOAT_LITERAL( TOY_AS_FLOAT(lhs) * TOY_AS_FLOAT(rhs) ); - freeLiteral(lhs); - freeLiteral(rhs); + Toy_freeLiteral(lhs); + Toy_freeLiteral(rhs); return result; } //wrong types interpreter->errorOutput("Bad arithmetic argument "); - printLiteralCustom(lhs, interpreter->errorOutput); + Toy_printLiteralCustom(lhs, interpreter->errorOutput); interpreter->errorOutput(" and "); - printLiteralCustom(rhs, interpreter->errorOutput); + Toy_printLiteralCustom(rhs, interpreter->errorOutput); interpreter->errorOutput("\n"); - freeLiteral(lhs); - freeLiteral(rhs); + Toy_freeLiteral(lhs); + Toy_freeLiteral(rhs); - return TO_NULL_LITERAL; + return TOY_TO_NULL_LITERAL; } -static Literal division(Interpreter* interpreter, Literal lhs, Literal rhs) { +static Toy_Literal division(Toy_Interpreter* interpreter, Toy_Literal lhs, Toy_Literal rhs) { //division check - if ((IS_INTEGER(rhs) && AS_INTEGER(rhs) == 0) || (IS_FLOAT(rhs) && AS_FLOAT(rhs) == 0)) { + if ((TOY_IS_INTEGER(rhs) && TOY_AS_INTEGER(rhs) == 0) || (TOY_IS_FLOAT(rhs) && TOY_AS_FLOAT(rhs) == 0)) { interpreter->errorOutput("Can't divide by zero"); } //type coersion - if (IS_FLOAT(lhs) && IS_INTEGER(rhs)) { - rhs = TO_FLOAT_LITERAL(AS_INTEGER(rhs)); + if (TOY_IS_FLOAT(lhs) && TOY_IS_INTEGER(rhs)) { + rhs = TOY_TO_FLOAT_LITERAL(TOY_AS_INTEGER(rhs)); } - if (IS_INTEGER(lhs) && IS_FLOAT(rhs)) { - lhs = TO_FLOAT_LITERAL(AS_INTEGER(lhs)); + if (TOY_IS_INTEGER(lhs) && TOY_IS_FLOAT(rhs)) { + lhs = TOY_TO_FLOAT_LITERAL(TOY_AS_INTEGER(lhs)); } //results - Literal result = TO_NULL_LITERAL; + Toy_Literal result = TOY_TO_NULL_LITERAL; - if (IS_INTEGER(lhs) && IS_INTEGER(rhs)) { - result = TO_INTEGER_LITERAL( AS_INTEGER(lhs) + AS_INTEGER(rhs) ); + if (TOY_IS_INTEGER(lhs) && TOY_IS_INTEGER(rhs)) { + result = TOY_TO_INTEGER_LITERAL( TOY_AS_INTEGER(lhs) + TOY_AS_INTEGER(rhs) ); - freeLiteral(lhs); - freeLiteral(rhs); + Toy_freeLiteral(lhs); + Toy_freeLiteral(rhs); return result; } - if (IS_FLOAT(lhs) && IS_FLOAT(rhs)) { - result = TO_FLOAT_LITERAL( AS_FLOAT(lhs) + AS_FLOAT(rhs) ); + if (TOY_IS_FLOAT(lhs) && TOY_IS_FLOAT(rhs)) { + result = TOY_TO_FLOAT_LITERAL( TOY_AS_FLOAT(lhs) + TOY_AS_FLOAT(rhs) ); - freeLiteral(lhs); - freeLiteral(rhs); + Toy_freeLiteral(lhs); + Toy_freeLiteral(rhs); return result; } //wrong types interpreter->errorOutput("Bad arithmetic argument "); - printLiteralCustom(lhs, interpreter->errorOutput); + Toy_printLiteralCustom(lhs, interpreter->errorOutput); interpreter->errorOutput(" and "); - printLiteralCustom(rhs, interpreter->errorOutput); + Toy_printLiteralCustom(rhs, interpreter->errorOutput); interpreter->errorOutput("\n"); - freeLiteral(lhs); - freeLiteral(rhs); + Toy_freeLiteral(lhs); + Toy_freeLiteral(rhs); - return TO_NULL_LITERAL; + return TOY_TO_NULL_LITERAL; } -static Literal modulo(Interpreter* interpreter, Literal lhs, Literal rhs) { +static Toy_Literal modulo(Toy_Interpreter* interpreter, Toy_Literal lhs, Toy_Literal rhs) { //division check - if ((IS_INTEGER(rhs) && AS_INTEGER(rhs) == 0) || (IS_FLOAT(rhs) && AS_FLOAT(rhs) == 0)) { + if ((TOY_IS_INTEGER(rhs) && TOY_AS_INTEGER(rhs) == 0) || (TOY_IS_FLOAT(rhs) && TOY_AS_FLOAT(rhs) == 0)) { interpreter->errorOutput("Can't divide by zero"); } //type coersion - if (IS_FLOAT(lhs) && IS_INTEGER(rhs)) { - rhs = TO_FLOAT_LITERAL(AS_INTEGER(rhs)); + if (TOY_IS_FLOAT(lhs) && TOY_IS_INTEGER(rhs)) { + rhs = TOY_TO_FLOAT_LITERAL(TOY_AS_INTEGER(rhs)); } - if (IS_INTEGER(lhs) && IS_FLOAT(rhs)) { - lhs = TO_FLOAT_LITERAL(AS_INTEGER(lhs)); + if (TOY_IS_INTEGER(lhs) && TOY_IS_FLOAT(rhs)) { + lhs = TOY_TO_FLOAT_LITERAL(TOY_AS_INTEGER(lhs)); } //results - Literal result = TO_NULL_LITERAL; + Toy_Literal result = TOY_TO_NULL_LITERAL; - if (IS_INTEGER(lhs) && IS_INTEGER(rhs)) { - result = TO_INTEGER_LITERAL( AS_INTEGER(lhs) + AS_INTEGER(rhs) ); + if (TOY_IS_INTEGER(lhs) && TOY_IS_INTEGER(rhs)) { + result = TOY_TO_INTEGER_LITERAL( TOY_AS_INTEGER(lhs) + TOY_AS_INTEGER(rhs) ); - freeLiteral(lhs); - freeLiteral(rhs); + Toy_freeLiteral(lhs); + Toy_freeLiteral(rhs); return result; } @@ -238,654 +238,654 @@ static Literal modulo(Interpreter* interpreter, Literal lhs, Literal rhs) { //wrong types interpreter->errorOutput("Bad arithmetic argument "); - printLiteralCustom(lhs, interpreter->errorOutput); + Toy_printLiteralCustom(lhs, interpreter->errorOutput); interpreter->errorOutput(" and "); - printLiteralCustom(rhs, interpreter->errorOutput); + Toy_printLiteralCustom(rhs, interpreter->errorOutput); interpreter->errorOutput("\n"); - freeLiteral(lhs); - freeLiteral(rhs); + Toy_freeLiteral(lhs); + Toy_freeLiteral(rhs); - return TO_NULL_LITERAL; + return TOY_TO_NULL_LITERAL; } -int _index(Interpreter* interpreter, LiteralArray* arguments) { +int _index(Toy_Interpreter* interpreter, Toy_LiteralArray* arguments) { //_index(compound, first, second, third, assignValue, op) - Literal op = popLiteralArray(arguments); - Literal assign = popLiteralArray(arguments); - Literal third = popLiteralArray(arguments); - Literal second = popLiteralArray(arguments); - Literal first = popLiteralArray(arguments); - Literal compound = popLiteralArray(arguments); + Toy_Literal op = Toy_popLiteralArray(arguments); + Toy_Literal assign = Toy_popLiteralArray(arguments); + Toy_Literal third = Toy_popLiteralArray(arguments); + Toy_Literal second = Toy_popLiteralArray(arguments); + Toy_Literal first = Toy_popLiteralArray(arguments); + Toy_Literal compound = Toy_popLiteralArray(arguments); - Literal value = TO_NULL_LITERAL; + Toy_Literal value = TOY_TO_NULL_LITERAL; //dictionary - no slicing - if (IS_DICTIONARY(compound)) { - if (IS_IDENTIFIER(first)) { - Literal idn = first; - parseIdentifierToValue(interpreter, &first); - freeLiteral(idn); + if (TOY_IS_DICTIONARY(compound)) { + if (TOY_IS_IDENTIFIER(first)) { + Toy_Literal idn = first; + Toy_parseIdentifierToValue(interpreter, &first); + Toy_freeLiteral(idn); } - if (IS_IDENTIFIER(second)) { - Literal idn = second; - parseIdentifierToValue(interpreter, &second); - freeLiteral(idn); + if (TOY_IS_IDENTIFIER(second)) { + Toy_Literal idn = second; + Toy_parseIdentifierToValue(interpreter, &second); + Toy_freeLiteral(idn); } - if (IS_IDENTIFIER(third)) { - Literal idn = third; - parseIdentifierToValue(interpreter, &third); - freeLiteral(idn); + if (TOY_IS_IDENTIFIER(third)) { + Toy_Literal idn = third; + Toy_parseIdentifierToValue(interpreter, &third); + Toy_freeLiteral(idn); } - value = getLiteralDictionary(AS_DICTIONARY(compound), first); + value = Toy_getLiteralDictionary(TOY_AS_DICTIONARY(compound), first); //dictionary - if (IS_NULL(op)) { - pushLiteralArray(&interpreter->stack, value); + if (TOY_IS_NULL(op)) { + Toy_pushLiteralArray(&interpreter->stack, value); - freeLiteral(op); - freeLiteral(assign); - freeLiteral(third); - freeLiteral(second); - freeLiteral(first); - freeLiteral(compound); - freeLiteral(value); + Toy_freeLiteral(op); + Toy_freeLiteral(assign); + Toy_freeLiteral(third); + Toy_freeLiteral(second); + Toy_freeLiteral(first); + Toy_freeLiteral(compound); + Toy_freeLiteral(value); return 1; } - else if (equalsRefStringCString(AS_STRING(op), "=")) { - setLiteralDictionary(AS_DICTIONARY(compound), first, assign); + else if (Toy_equalsRefStringCString(TOY_AS_STRING(op), "=")) { + Toy_setLiteralDictionary(TOY_AS_DICTIONARY(compound), first, assign); } - else if (equalsRefStringCString(AS_STRING(op), "+=")) { - Literal lit = addition(interpreter, value, assign); - setLiteralDictionary(AS_DICTIONARY(compound), first, lit); - freeLiteral(lit); + else if (Toy_equalsRefStringCString(TOY_AS_STRING(op), "+=")) { + Toy_Literal lit = addition(interpreter, value, assign); + Toy_setLiteralDictionary(TOY_AS_DICTIONARY(compound), first, lit); + Toy_freeLiteral(lit); } - else if (equalsRefStringCString(AS_STRING(op), "-=")) { - Literal lit = subtraction(interpreter, value, assign); - setLiteralDictionary(AS_DICTIONARY(compound), first, lit); - freeLiteral(lit); + else if (Toy_equalsRefStringCString(TOY_AS_STRING(op), "-=")) { + Toy_Literal lit = subtraction(interpreter, value, assign); + Toy_setLiteralDictionary(TOY_AS_DICTIONARY(compound), first, lit); + Toy_freeLiteral(lit); } - else if (equalsRefStringCString(AS_STRING(op), "*=")) { - Literal lit = multiplication(interpreter, value, assign); - setLiteralDictionary(AS_DICTIONARY(compound), first, lit); - freeLiteral(lit); + else if (Toy_equalsRefStringCString(TOY_AS_STRING(op), "*=")) { + Toy_Literal lit = multiplication(interpreter, value, assign); + Toy_setLiteralDictionary(TOY_AS_DICTIONARY(compound), first, lit); + Toy_freeLiteral(lit); } - else if (equalsRefStringCString(AS_STRING(op), "/=")) { - Literal lit = division(interpreter, value, assign); - setLiteralDictionary(AS_DICTIONARY(compound), first, lit); - freeLiteral(lit); + else if (Toy_equalsRefStringCString(TOY_AS_STRING(op), "/=")) { + Toy_Literal lit = division(interpreter, value, assign); + Toy_setLiteralDictionary(TOY_AS_DICTIONARY(compound), first, lit); + Toy_freeLiteral(lit); } - else if (equalsRefStringCString(AS_STRING(op), "%=")) { - Literal lit = modulo(interpreter, value, assign); - setLiteralDictionary(AS_DICTIONARY(compound), first, lit); - freeLiteral(lit); + else if (Toy_equalsRefStringCString(TOY_AS_STRING(op), "%=")) { + Toy_Literal lit = modulo(interpreter, value, assign); + Toy_setLiteralDictionary(TOY_AS_DICTIONARY(compound), first, lit); + Toy_freeLiteral(lit); } } //array - slicing - if (IS_ARRAY(compound)) { + if (TOY_IS_ARRAY(compound)) { //array slice - if (IS_NULL(op)) { + if (TOY_IS_NULL(op)) { //parse out the blanks & their defaults - if (!IS_NULL(first)) { - if (IS_INDEX_BLANK(first)) { - freeLiteral(first); - first = TO_INTEGER_LITERAL(0); + if (!TOY_IS_NULL(first)) { + if (TOY_IS_INDEX_BLANK(first)) { + Toy_freeLiteral(first); + first = TOY_TO_INTEGER_LITERAL(0); } - if (IS_IDENTIFIER(first)) { - Literal idn = first; - parseIdentifierToValue(interpreter, &first); - freeLiteral(idn); + if (TOY_IS_IDENTIFIER(first)) { + Toy_Literal idn = first; + Toy_parseIdentifierToValue(interpreter, &first); + Toy_freeLiteral(idn); } } - if (!IS_NULL(second)) { - if (IS_INDEX_BLANK(second)) { - freeLiteral(second); - second = TO_INTEGER_LITERAL(AS_ARRAY(compound)->count - 1); + if (!TOY_IS_NULL(second)) { + if (TOY_IS_INDEX_BLANK(second)) { + Toy_freeLiteral(second); + second = TOY_TO_INTEGER_LITERAL(TOY_AS_ARRAY(compound)->count - 1); } - if (IS_IDENTIFIER(second)) { - Literal idn = second; - parseIdentifierToValue(interpreter, &second); - freeLiteral(idn); + if (TOY_IS_IDENTIFIER(second)) { + Toy_Literal idn = second; + Toy_parseIdentifierToValue(interpreter, &second); + Toy_freeLiteral(idn); } } - if (IS_NULL(third) || IS_INDEX_BLANK(third)) { - freeLiteral(third); - third = TO_INTEGER_LITERAL(1); + if (TOY_IS_NULL(third) || TOY_IS_INDEX_BLANK(third)) { + Toy_freeLiteral(third); + third = TOY_TO_INTEGER_LITERAL(1); } - if (IS_IDENTIFIER(third)) { - Literal idn = third; - parseIdentifierToValue(interpreter, &third); - freeLiteral(idn); + if (TOY_IS_IDENTIFIER(third)) { + Toy_Literal idn = third; + Toy_parseIdentifierToValue(interpreter, &third); + Toy_freeLiteral(idn); } //handle each null case - if (IS_NULL(first) || !IS_INTEGER(first)) { + if (TOY_IS_NULL(first) || !TOY_IS_INTEGER(first)) { //something is weird - skip out - freeLiteral(op); - freeLiteral(assign); - freeLiteral(third); - freeLiteral(second); - freeLiteral(first); - freeLiteral(compound); - freeLiteral(value); + Toy_freeLiteral(op); + Toy_freeLiteral(assign); + Toy_freeLiteral(third); + Toy_freeLiteral(second); + Toy_freeLiteral(first); + Toy_freeLiteral(compound); + Toy_freeLiteral(value); return -1; } - if (IS_NULL(second)) { //assign only a single character + if (TOY_IS_NULL(second)) { //assign only a single character //get the "first" within the array, then skip out - freeLiteral(value); - value = getLiteralArray(AS_ARRAY(compound), first); - pushLiteralArray(&interpreter->stack, value); + Toy_freeLiteral(value); + value = Toy_getLiteralArray(TOY_AS_ARRAY(compound), first); + Toy_pushLiteralArray(&interpreter->stack, value); - freeLiteral(op); - freeLiteral(assign); - freeLiteral(third); - freeLiteral(second); - freeLiteral(first); - freeLiteral(compound); - freeLiteral(value); + Toy_freeLiteral(op); + Toy_freeLiteral(assign); + Toy_freeLiteral(third); + Toy_freeLiteral(second); + Toy_freeLiteral(first); + Toy_freeLiteral(compound); + Toy_freeLiteral(value); return 1; } - if (!IS_INTEGER(second) || (!IS_NULL(third) && !IS_INTEGER(third)) || AS_INTEGER(second) < 0 || AS_INTEGER(second) > AS_ARRAY(compound)->count || AS_INTEGER(third) == 0) { + if (!TOY_IS_INTEGER(second) || (!TOY_IS_NULL(third) && !TOY_IS_INTEGER(third)) || TOY_AS_INTEGER(second) < 0 || TOY_AS_INTEGER(second) > TOY_AS_ARRAY(compound)->count || TOY_AS_INTEGER(third) == 0) { //something is weird - skip out - freeLiteral(op); - freeLiteral(assign); - freeLiteral(third); - freeLiteral(second); - freeLiteral(first); - freeLiteral(compound); - freeLiteral(value); + Toy_freeLiteral(op); + Toy_freeLiteral(assign); + Toy_freeLiteral(third); + Toy_freeLiteral(second); + Toy_freeLiteral(first); + Toy_freeLiteral(compound); + Toy_freeLiteral(value); return -1; } //start building a new array from the old one - LiteralArray* result = ALLOCATE(LiteralArray, 1); - initLiteralArray(result); + Toy_LiteralArray* result = TOY_ALLOCATE(Toy_LiteralArray, 1); + Toy_initLiteralArray(result); - int min = AS_INTEGER(third) > 0 ? AS_INTEGER(first) : AS_INTEGER(second); + int min = TOY_AS_INTEGER(third) > 0 ? TOY_AS_INTEGER(first) : TOY_AS_INTEGER(second); //copy compound into result - for (int i = min; i >= 0 && i <= AS_ARRAY(compound)->count && i >= AS_INTEGER(first) && i <= AS_INTEGER(second); i += AS_INTEGER(third)) { - Literal idx = TO_INTEGER_LITERAL(i); - Literal tmp = getLiteralArray(AS_ARRAY(compound), idx); - pushLiteralArray(result, tmp); + for (int i = min; i >= 0 && i <= TOY_AS_ARRAY(compound)->count && i >= TOY_AS_INTEGER(first) && i <= TOY_AS_INTEGER(second); i += TOY_AS_INTEGER(third)) { + Toy_Literal idx = TOY_TO_INTEGER_LITERAL(i); + Toy_Literal tmp = Toy_getLiteralArray(TOY_AS_ARRAY(compound), idx); + Toy_pushLiteralArray(result, tmp); - freeLiteral(idx); - freeLiteral(tmp); + Toy_freeLiteral(idx); + Toy_freeLiteral(tmp); } //finally, swap out the compound for the result - freeLiteral(compound); - compound = TO_ARRAY_LITERAL(result); + Toy_freeLiteral(compound); + compound = TOY_TO_ARRAY_LITERAL(result); } //array slice assignment - if (IS_STRING(op) && equalsRefStringCString(AS_STRING(op), "=")) { + if (TOY_IS_STRING(op) && Toy_equalsRefStringCString(TOY_AS_STRING(op), "=")) { //parse out the blanks & their defaults - if (!IS_NULL(first)) { - if (IS_INDEX_BLANK(first)) { - freeLiteral(first); - first = TO_INTEGER_LITERAL(0); + if (!TOY_IS_NULL(first)) { + if (TOY_IS_INDEX_BLANK(first)) { + Toy_freeLiteral(first); + first = TOY_TO_INTEGER_LITERAL(0); } - if (IS_IDENTIFIER(first)) { - Literal idn = first; - parseIdentifierToValue(interpreter, &first); - freeLiteral(idn); + if (TOY_IS_IDENTIFIER(first)) { + Toy_Literal idn = first; + Toy_parseIdentifierToValue(interpreter, &first); + Toy_freeLiteral(idn); } } - if (!IS_NULL(second)) { - if (IS_INDEX_BLANK(second)) { - freeLiteral(second); - second = TO_INTEGER_LITERAL(AS_INTEGER(first)); + if (!TOY_IS_NULL(second)) { + if (TOY_IS_INDEX_BLANK(second)) { + Toy_freeLiteral(second); + second = TOY_TO_INTEGER_LITERAL(TOY_AS_INTEGER(first)); } - if (IS_IDENTIFIER(second)) { - Literal idn = second; - parseIdentifierToValue(interpreter, &second); - freeLiteral(idn); + if (TOY_IS_IDENTIFIER(second)) { + Toy_Literal idn = second; + Toy_parseIdentifierToValue(interpreter, &second); + Toy_freeLiteral(idn); } } - if (IS_NULL(third) || IS_INDEX_BLANK(third)) { - freeLiteral(third); - third = TO_INTEGER_LITERAL(1); + if (TOY_IS_NULL(third) || TOY_IS_INDEX_BLANK(third)) { + Toy_freeLiteral(third); + third = TOY_TO_INTEGER_LITERAL(1); } - if (IS_IDENTIFIER(third)) { - Literal idn = third; - parseIdentifierToValue(interpreter, &third); - freeLiteral(idn); + if (TOY_IS_IDENTIFIER(third)) { + Toy_Literal idn = third; + Toy_parseIdentifierToValue(interpreter, &third); + Toy_freeLiteral(idn); } //handle each null case - if (IS_NULL(first) || !IS_INTEGER(first)) { + if (TOY_IS_NULL(first) || !TOY_IS_INTEGER(first)) { //something is weird - skip out - freeLiteral(op); - freeLiteral(assign); - freeLiteral(third); - freeLiteral(second); - freeLiteral(first); - freeLiteral(compound); - freeLiteral(value); + Toy_freeLiteral(op); + Toy_freeLiteral(assign); + Toy_freeLiteral(third); + Toy_freeLiteral(second); + Toy_freeLiteral(first); + Toy_freeLiteral(compound); + Toy_freeLiteral(value); return -1; } - if (IS_NULL(second)) { + if (TOY_IS_NULL(second)) { //set the "first" within the array, then skip out - if (!setLiteralArray(AS_ARRAY(compound), first, assign)) { + if (!Toy_setLiteralArray(TOY_AS_ARRAY(compound), first, assign)) { interpreter->errorOutput("Index assignment out of bounds\n"); - freeLiteral(op); - freeLiteral(assign); - freeLiteral(third); - freeLiteral(second); - freeLiteral(first); - freeLiteral(compound); - freeLiteral(value); + Toy_freeLiteral(op); + Toy_freeLiteral(assign); + Toy_freeLiteral(third); + Toy_freeLiteral(second); + Toy_freeLiteral(first); + Toy_freeLiteral(compound); + Toy_freeLiteral(value); return -1; } - pushLiteralArray(&interpreter->stack, compound); + Toy_pushLiteralArray(&interpreter->stack, compound); - freeLiteral(op); - freeLiteral(assign); - freeLiteral(third); - freeLiteral(second); - freeLiteral(first); - freeLiteral(compound); - freeLiteral(value); + Toy_freeLiteral(op); + Toy_freeLiteral(assign); + Toy_freeLiteral(third); + Toy_freeLiteral(second); + Toy_freeLiteral(first); + Toy_freeLiteral(compound); + Toy_freeLiteral(value); return 1; } - if (!IS_INTEGER(second) || (!IS_NULL(third) && !IS_INTEGER(third)) || AS_INTEGER(second) < 0 || AS_INTEGER(second) > AS_ARRAY(compound)->count || AS_INTEGER(third) == 0) { + if (!TOY_IS_INTEGER(second) || (!TOY_IS_NULL(third) && !TOY_IS_INTEGER(third)) || TOY_AS_INTEGER(second) < 0 || TOY_AS_INTEGER(second) > TOY_AS_ARRAY(compound)->count || TOY_AS_INTEGER(third) == 0) { //something is weird - skip out - freeLiteral(op); - freeLiteral(assign); - freeLiteral(third); - freeLiteral(second); - freeLiteral(first); - freeLiteral(compound); - freeLiteral(value); + Toy_freeLiteral(op); + Toy_freeLiteral(assign); + Toy_freeLiteral(third); + Toy_freeLiteral(second); + Toy_freeLiteral(first); + Toy_freeLiteral(compound); + Toy_freeLiteral(value); return -1; } //start building a new array from the old one - LiteralArray* result = ALLOCATE(LiteralArray, 1); - initLiteralArray(result); + Toy_LiteralArray* result = TOY_ALLOCATE(Toy_LiteralArray, 1); + Toy_initLiteralArray(result); //if third is abs(1), simply insert into the correct positions - if (AS_INTEGER(third) == 1 || AS_INTEGER(third) == -1) { - for (int i = 0; i < AS_INTEGER(first); i++) { - Literal idx = TO_INTEGER_LITERAL(i); - Literal tmp = getLiteralArray(AS_ARRAY(compound), idx); - pushLiteralArray(result, tmp); + if (TOY_AS_INTEGER(third) == 1 || TOY_AS_INTEGER(third) == -1) { + for (int i = 0; i < TOY_AS_INTEGER(first); i++) { + Toy_Literal idx = TOY_TO_INTEGER_LITERAL(i); + Toy_Literal tmp = Toy_getLiteralArray(TOY_AS_ARRAY(compound), idx); + Toy_pushLiteralArray(result, tmp); - freeLiteral(idx); - freeLiteral(tmp); + Toy_freeLiteral(idx); + Toy_freeLiteral(tmp); } - int min = AS_INTEGER(third) > 0 ? 0 : AS_ARRAY(assign)->count - 1; + int min = TOY_AS_INTEGER(third) > 0 ? 0 : TOY_AS_ARRAY(assign)->count - 1; - if (IS_ARRAY(assign)) { //push elements of an assigned array - for (int i = min; i >= 0 && i < AS_ARRAY(assign)->count; i += AS_INTEGER(third)) { - Literal idx = TO_INTEGER_LITERAL(i); - Literal tmp = getLiteralArray(AS_ARRAY(assign), idx); //backwards + if (TOY_IS_ARRAY(assign)) { //push elements of an assigned array + for (int i = min; i >= 0 && i < TOY_AS_ARRAY(assign)->count; i += TOY_AS_INTEGER(third)) { + Toy_Literal idx = TOY_TO_INTEGER_LITERAL(i); + Toy_Literal tmp = Toy_getLiteralArray(TOY_AS_ARRAY(assign), idx); //backwards //set result - pushLiteralArray(result, tmp); + Toy_pushLiteralArray(result, tmp); - freeLiteral(idx); - freeLiteral(tmp); + Toy_freeLiteral(idx); + Toy_freeLiteral(tmp); } } else { //push just one element into the array - pushLiteralArray(result, assign); + Toy_pushLiteralArray(result, assign); } - for (int i = AS_INTEGER(second) + 1; i < AS_ARRAY(compound)->count; i++) { - Literal idx = TO_INTEGER_LITERAL(i); - Literal tmp = getLiteralArray(AS_ARRAY(compound), idx); - pushLiteralArray(result, tmp); + for (int i = TOY_AS_INTEGER(second) + 1; i < TOY_AS_ARRAY(compound)->count; i++) { + Toy_Literal idx = TOY_TO_INTEGER_LITERAL(i); + Toy_Literal tmp = Toy_getLiteralArray(TOY_AS_ARRAY(compound), idx); + Toy_pushLiteralArray(result, tmp); - freeLiteral(idx); - freeLiteral(tmp); + Toy_freeLiteral(idx); + Toy_freeLiteral(tmp); } } //else override elements of the array instead else { //copy compound to result - for (int i = 0; i < AS_ARRAY(compound)->count; i++) { - Literal idx = TO_INTEGER_LITERAL(i); - Literal tmp = getLiteralArray(AS_ARRAY(compound), idx); + for (int i = 0; i < TOY_AS_ARRAY(compound)->count; i++) { + Toy_Literal idx = TOY_TO_INTEGER_LITERAL(i); + Toy_Literal tmp = Toy_getLiteralArray(TOY_AS_ARRAY(compound), idx); - pushLiteralArray(result, tmp); + Toy_pushLiteralArray(result, tmp); - freeLiteral(idx); - freeLiteral(tmp); + Toy_freeLiteral(idx); + Toy_freeLiteral(tmp); } - int min = AS_INTEGER(third) > 0 ? 0 : AS_ARRAY(compound)->count - 1; + int min = TOY_AS_INTEGER(third) > 0 ? 0 : TOY_AS_ARRAY(compound)->count - 1; int assignIndex = 0; - for (int i = min; i >= 0 && i < AS_ARRAY(compound)->count && assignIndex < AS_ARRAY(assign)->count; i += AS_INTEGER(third)) { - Literal idx = TO_INTEGER_LITERAL(i); - Literal ai = TO_INTEGER_LITERAL(assignIndex++); - Literal tmp = getLiteralArray(AS_ARRAY(assign), ai); + for (int i = min; i >= 0 && i < TOY_AS_ARRAY(compound)->count && assignIndex < TOY_AS_ARRAY(assign)->count; i += TOY_AS_INTEGER(third)) { + Toy_Literal idx = TOY_TO_INTEGER_LITERAL(i); + Toy_Literal ai = TOY_TO_INTEGER_LITERAL(assignIndex++); + Toy_Literal tmp = Toy_getLiteralArray(TOY_AS_ARRAY(assign), ai); - setLiteralArray(result, idx, tmp); + Toy_setLiteralArray(result, idx, tmp); - freeLiteral(idx); - freeLiteral(ai); - freeLiteral(tmp); + Toy_freeLiteral(idx); + Toy_freeLiteral(ai); + Toy_freeLiteral(tmp); } } //finally, swap out the compound for the result - freeLiteral(compound); - compound = TO_ARRAY_LITERAL(result); + Toy_freeLiteral(compound); + compound = TOY_TO_ARRAY_LITERAL(result); } - if (IS_IDENTIFIER(first)) { - Literal idn = first; - parseIdentifierToValue(interpreter, &first); - freeLiteral(idn); + if (TOY_IS_IDENTIFIER(first)) { + Toy_Literal idn = first; + Toy_parseIdentifierToValue(interpreter, &first); + Toy_freeLiteral(idn); } - value = getLiteralArray(AS_ARRAY(compound), first); + value = Toy_getLiteralArray(TOY_AS_ARRAY(compound), first); - if (IS_STRING(op) && equalsRefStringCString(AS_STRING(op), "+=")) { - Literal lit = addition(interpreter, value, assign); - setLiteralArray(AS_ARRAY(compound), first, lit); - freeLiteral(lit); + if (TOY_IS_STRING(op) && Toy_equalsRefStringCString(TOY_AS_STRING(op), "+=")) { + Toy_Literal lit = addition(interpreter, value, assign); + Toy_setLiteralArray(TOY_AS_ARRAY(compound), first, lit); + Toy_freeLiteral(lit); } - if (IS_STRING(op) && equalsRefStringCString(AS_STRING(op), "-=")) { - Literal lit = subtraction(interpreter, value, assign); - setLiteralArray(AS_ARRAY(compound), first, lit); - freeLiteral(lit); + if (TOY_IS_STRING(op) && Toy_equalsRefStringCString(TOY_AS_STRING(op), "-=")) { + Toy_Literal lit = subtraction(interpreter, value, assign); + Toy_setLiteralArray(TOY_AS_ARRAY(compound), first, lit); + Toy_freeLiteral(lit); } - if (IS_STRING(op) && equalsRefStringCString(AS_STRING(op), "*=")) { - Literal lit = multiplication(interpreter, value, assign); - setLiteralArray(AS_ARRAY(compound), first, lit); - freeLiteral(lit); + if (TOY_IS_STRING(op) && Toy_equalsRefStringCString(TOY_AS_STRING(op), "*=")) { + Toy_Literal lit = multiplication(interpreter, value, assign); + Toy_setLiteralArray(TOY_AS_ARRAY(compound), first, lit); + Toy_freeLiteral(lit); } - if (IS_STRING(op) && equalsRefStringCString(AS_STRING(op), "/=")) { - Literal lit = division(interpreter, value, assign); - setLiteralArray(AS_ARRAY(compound), first, lit); - freeLiteral(lit); + if (TOY_IS_STRING(op) && Toy_equalsRefStringCString(TOY_AS_STRING(op), "/=")) { + Toy_Literal lit = division(interpreter, value, assign); + Toy_setLiteralArray(TOY_AS_ARRAY(compound), first, lit); + Toy_freeLiteral(lit); } - if (IS_STRING(op) && equalsRefStringCString(AS_STRING(op), "%=")) { - Literal lit = modulo(interpreter, value, assign); - setLiteralArray(AS_ARRAY(compound), first, lit); - freeLiteral(lit); + if (TOY_IS_STRING(op) && Toy_equalsRefStringCString(TOY_AS_STRING(op), "%=")) { + Toy_Literal lit = modulo(interpreter, value, assign); + Toy_setLiteralArray(TOY_AS_ARRAY(compound), first, lit); + Toy_freeLiteral(lit); } } //string - slicing - if (IS_STRING(compound)) { + if (TOY_IS_STRING(compound)) { //string slice - if (IS_NULL(op)) { + if (TOY_IS_NULL(op)) { //parse out the blanks & their defaults - if (!IS_NULL(first)) { - if (IS_INDEX_BLANK(first)) { - freeLiteral(first); - first = TO_INTEGER_LITERAL(0); + if (!TOY_IS_NULL(first)) { + if (TOY_IS_INDEX_BLANK(first)) { + Toy_freeLiteral(first); + first = TOY_TO_INTEGER_LITERAL(0); } - if (IS_IDENTIFIER(first)) { - Literal idn = first; - parseIdentifierToValue(interpreter, &first); - freeLiteral(idn); + if (TOY_IS_IDENTIFIER(first)) { + Toy_Literal idn = first; + Toy_parseIdentifierToValue(interpreter, &first); + Toy_freeLiteral(idn); } } - int compoundLength = AS_STRING(compound)->length; - if (!IS_NULL(second)) { - if (IS_INDEX_BLANK(second)) { - freeLiteral(second); - second = TO_INTEGER_LITERAL(compoundLength); + int compoundLength = TOY_AS_STRING(compound)->length; + if (!TOY_IS_NULL(second)) { + if (TOY_IS_INDEX_BLANK(second)) { + Toy_freeLiteral(second); + second = TOY_TO_INTEGER_LITERAL(compoundLength); } - if (IS_IDENTIFIER(second)) { - Literal idn = second; - parseIdentifierToValue(interpreter, &second); - freeLiteral(idn); + if (TOY_IS_IDENTIFIER(second)) { + Toy_Literal idn = second; + Toy_parseIdentifierToValue(interpreter, &second); + Toy_freeLiteral(idn); } } - if (IS_NULL(third) || IS_INDEX_BLANK(third)) { - freeLiteral(third); - third = TO_INTEGER_LITERAL(1); + if (TOY_IS_NULL(third) || TOY_IS_INDEX_BLANK(third)) { + Toy_freeLiteral(third); + third = TOY_TO_INTEGER_LITERAL(1); } - if (IS_IDENTIFIER(third)) { - Literal idn = third; - parseIdentifierToValue(interpreter, &third); - freeLiteral(idn); + if (TOY_IS_IDENTIFIER(third)) { + Toy_Literal idn = third; + Toy_parseIdentifierToValue(interpreter, &third); + Toy_freeLiteral(idn); } //handle each null case - if (IS_NULL(first) || !IS_INTEGER(first)) { + if (TOY_IS_NULL(first) || !TOY_IS_INTEGER(first)) { //something is weird - skip out - freeLiteral(op); - freeLiteral(assign); - freeLiteral(third); - freeLiteral(second); - freeLiteral(first); - freeLiteral(compound); - freeLiteral(value); + Toy_freeLiteral(op); + Toy_freeLiteral(assign); + Toy_freeLiteral(third); + Toy_freeLiteral(second); + Toy_freeLiteral(first); + Toy_freeLiteral(compound); + Toy_freeLiteral(value); return -1; } - if (IS_NULL(second)) { //assign only a single character - char c = toCString(AS_STRING(compound))[AS_INTEGER(first)]; + if (TOY_IS_NULL(second)) { //assign only a single character + char c = Toy_toCString(TOY_AS_STRING(compound))[TOY_AS_INTEGER(first)]; char buffer[16]; snprintf(buffer, 16, "%c", c); - freeLiteral(value); + Toy_freeLiteral(value); int totalLength = strlen(buffer); - value = TO_STRING_LITERAL(createRefStringLength(buffer, totalLength)); + value = TOY_TO_STRING_LITERAL(Toy_createRefStringLength(buffer, totalLength)); - pushLiteralArray(&interpreter->stack, value); + Toy_pushLiteralArray(&interpreter->stack, value); - freeLiteral(op); - freeLiteral(assign); - freeLiteral(third); - freeLiteral(second); - freeLiteral(first); - freeLiteral(compound); - freeLiteral(value); + Toy_freeLiteral(op); + Toy_freeLiteral(assign); + Toy_freeLiteral(third); + Toy_freeLiteral(second); + Toy_freeLiteral(first); + Toy_freeLiteral(compound); + Toy_freeLiteral(value); return 1; } - if (!IS_INTEGER(second) || (!IS_NULL(third) && !IS_INTEGER(third)) || AS_INTEGER(second) < 0 || AS_INTEGER(second) > compoundLength || AS_INTEGER(third) == 0) { + if (!TOY_IS_INTEGER(second) || (!TOY_IS_NULL(third) && !TOY_IS_INTEGER(third)) || TOY_AS_INTEGER(second) < 0 || TOY_AS_INTEGER(second) > compoundLength || TOY_AS_INTEGER(third) == 0) { //something is weird - skip out - freeLiteral(op); - freeLiteral(assign); - freeLiteral(third); - freeLiteral(second); - freeLiteral(first); - freeLiteral(compound); - freeLiteral(value); + Toy_freeLiteral(op); + Toy_freeLiteral(assign); + Toy_freeLiteral(third); + Toy_freeLiteral(second); + Toy_freeLiteral(first); + Toy_freeLiteral(compound); + Toy_freeLiteral(value); return -1; } //start building a new string from the old one - char* result = ALLOCATE(char, MAX_STRING_LENGTH); + char* result = TOY_ALLOCATE(char, TOY_MAX_STRING_LENGTH); - int lower = AS_INTEGER(third) > 0 ? AS_INTEGER(first) : AS_INTEGER(first) -1; - int min = AS_INTEGER(third) > 0 ? AS_INTEGER(first) : AS_INTEGER(second) -1; - int max = AS_INTEGER(third) > 0 ? AS_INTEGER(second) + (AS_INTEGER(second) == compoundLength ? -1 : 0) : AS_INTEGER(second); + int lower = TOY_AS_INTEGER(third) > 0 ? TOY_AS_INTEGER(first) : TOY_AS_INTEGER(first) -1; + int min = TOY_AS_INTEGER(third) > 0 ? TOY_AS_INTEGER(first) : TOY_AS_INTEGER(second) -1; + int max = TOY_AS_INTEGER(third) > 0 ? TOY_AS_INTEGER(second) + (TOY_AS_INTEGER(second) == compoundLength ? -1 : 0) : TOY_AS_INTEGER(second); //copy compound into result int resultIndex = 0; - for (int i = min; i >= 0 && i >= lower && i <= max; i += AS_INTEGER(third)) { - result[ resultIndex++ ] = toCString(AS_STRING(compound))[ i ]; + for (int i = min; i >= 0 && i >= lower && i <= max; i += TOY_AS_INTEGER(third)) { + result[ resultIndex++ ] = Toy_toCString(TOY_AS_STRING(compound))[ i ]; } result[ resultIndex ] = '\0'; //finally, swap out the compound for the result - freeLiteral(compound); - compound = TO_STRING_LITERAL(createRefStringLength(result, resultIndex)); + Toy_freeLiteral(compound); + compound = TOY_TO_STRING_LITERAL(Toy_createRefStringLength(result, resultIndex)); - FREE_ARRAY(char, result, MAX_STRING_LENGTH); + TOY_FREE_ARRAY(char, result, TOY_MAX_STRING_LENGTH); } //string slice assignment - else if (IS_STRING(op) && equalsRefStringCString(AS_STRING(op), "=")) { + else if (TOY_IS_STRING(op) && Toy_equalsRefStringCString(TOY_AS_STRING(op), "=")) { //parse out the blanks & their defaults - if (!IS_NULL(first)) { - if (IS_INDEX_BLANK(first)) { - freeLiteral(first); - first = TO_INTEGER_LITERAL(0); + if (!TOY_IS_NULL(first)) { + if (TOY_IS_INDEX_BLANK(first)) { + Toy_freeLiteral(first); + first = TOY_TO_INTEGER_LITERAL(0); } - if (IS_IDENTIFIER(first)) { - Literal idn = first; - parseIdentifierToValue(interpreter, &first); - freeLiteral(idn); + if (TOY_IS_IDENTIFIER(first)) { + Toy_Literal idn = first; + Toy_parseIdentifierToValue(interpreter, &first); + Toy_freeLiteral(idn); } } - int compoundLength = AS_STRING(compound)->length; - if (!IS_NULL(second)) { - if (IS_INDEX_BLANK(second)) { - freeLiteral(second); - second = TO_INTEGER_LITERAL(compoundLength); + int compoundLength = TOY_AS_STRING(compound)->length; + if (!TOY_IS_NULL(second)) { + if (TOY_IS_INDEX_BLANK(second)) { + Toy_freeLiteral(second); + second = TOY_TO_INTEGER_LITERAL(compoundLength); } - if (IS_IDENTIFIER(second)) { - Literal idn = second; - parseIdentifierToValue(interpreter, &second); - freeLiteral(idn); + if (TOY_IS_IDENTIFIER(second)) { + Toy_Literal idn = second; + Toy_parseIdentifierToValue(interpreter, &second); + Toy_freeLiteral(idn); } } - if (IS_NULL(third) || IS_INDEX_BLANK(third)) { - freeLiteral(third); - third = TO_INTEGER_LITERAL(1); + if (TOY_IS_NULL(third) || TOY_IS_INDEX_BLANK(third)) { + Toy_freeLiteral(third); + third = TOY_TO_INTEGER_LITERAL(1); } - if (IS_IDENTIFIER(first)) { - Literal idn = first; - parseIdentifierToValue(interpreter, &first); - freeLiteral(idn); + if (TOY_IS_IDENTIFIER(first)) { + Toy_Literal idn = first; + Toy_parseIdentifierToValue(interpreter, &first); + Toy_freeLiteral(idn); } //handle each null case - if (IS_NULL(first) || !IS_INTEGER(first)) { + if (TOY_IS_NULL(first) || !TOY_IS_INTEGER(first)) { //something is weird - skip out - freeLiteral(op); - freeLiteral(assign); - freeLiteral(third); - freeLiteral(second); - freeLiteral(first); - freeLiteral(compound); - freeLiteral(value); + Toy_freeLiteral(op); + Toy_freeLiteral(assign); + Toy_freeLiteral(third); + Toy_freeLiteral(second); + Toy_freeLiteral(first); + Toy_freeLiteral(compound); + Toy_freeLiteral(value); return -1; } - if (IS_NULL(second)) { //assign only a single character + if (TOY_IS_NULL(second)) { //assign only a single character //set the "first" within the array, then skip out - if (AS_STRING(assign)->length != 1) { + if (TOY_AS_STRING(assign)->length != 1) { //something is weird - skip out - freeLiteral(op); - freeLiteral(assign); - freeLiteral(third); - freeLiteral(second); - freeLiteral(first); - freeLiteral(compound); - freeLiteral(value); + Toy_freeLiteral(op); + Toy_freeLiteral(assign); + Toy_freeLiteral(third); + Toy_freeLiteral(second); + Toy_freeLiteral(first); + Toy_freeLiteral(compound); + Toy_freeLiteral(value); return -1; } - Literal copiedCompound = TO_STRING_LITERAL(deepCopyRefString(AS_STRING(compound))); + Toy_Literal copiedCompound = TOY_TO_STRING_LITERAL(Toy_deepCopyRefString(TOY_AS_STRING(compound))); - AS_STRING(copiedCompound)->data[AS_INTEGER(first)] = toCString(AS_STRING(assign))[0]; + TOY_AS_STRING(copiedCompound)->data[TOY_AS_INTEGER(first)] = Toy_toCString(TOY_AS_STRING(assign))[0]; - pushLiteralArray(&interpreter->stack, copiedCompound); + Toy_pushLiteralArray(&interpreter->stack, copiedCompound); - freeLiteral(op); - freeLiteral(assign); - freeLiteral(third); - freeLiteral(second); - freeLiteral(first); - freeLiteral(compound); - freeLiteral(value); + Toy_freeLiteral(op); + Toy_freeLiteral(assign); + Toy_freeLiteral(third); + Toy_freeLiteral(second); + Toy_freeLiteral(first); + Toy_freeLiteral(compound); + Toy_freeLiteral(value); return 1; } - if (!IS_INTEGER(second) || (!IS_NULL(third) && !IS_INTEGER(third)) || AS_INTEGER(second) < 0 || AS_INTEGER(second) > compoundLength || AS_INTEGER(third) == 0) { + if (!TOY_IS_INTEGER(second) || (!TOY_IS_NULL(third) && !TOY_IS_INTEGER(third)) || TOY_AS_INTEGER(second) < 0 || TOY_AS_INTEGER(second) > compoundLength || TOY_AS_INTEGER(third) == 0) { //something is weird - skip out - freeLiteral(op); - freeLiteral(assign); - freeLiteral(third); - freeLiteral(second); - freeLiteral(first); - freeLiteral(compound); - freeLiteral(value); + Toy_freeLiteral(op); + Toy_freeLiteral(assign); + Toy_freeLiteral(third); + Toy_freeLiteral(second); + Toy_freeLiteral(first); + Toy_freeLiteral(compound); + Toy_freeLiteral(value); return -1; } //start building a new string from the old one - char* result = ALLOCATE(char, MAX_STRING_LENGTH); + char* result = TOY_ALLOCATE(char, TOY_MAX_STRING_LENGTH); //if third is abs(1), simply insert into the correct positions int resultIndex = 0; - if (AS_INTEGER(third) == 1 || AS_INTEGER(third) == -1) { - for (int i = 0; i < AS_INTEGER(first); i++) { - result[ resultIndex++ ] = toCString(AS_STRING(compound))[ i ]; + if (TOY_AS_INTEGER(third) == 1 || TOY_AS_INTEGER(third) == -1) { + for (int i = 0; i < TOY_AS_INTEGER(first); i++) { + result[ resultIndex++ ] = Toy_toCString(TOY_AS_STRING(compound))[ i ]; } - int assignLength = AS_STRING(assign)->length; - int min = AS_INTEGER(third) > 0 ? 0 : assignLength - 1; + int assignLength = TOY_AS_STRING(assign)->length; + int min = TOY_AS_INTEGER(third) > 0 ? 0 : assignLength - 1; - for (int i = min; i >= 0 && i < assignLength; i += AS_INTEGER(third)) { - result[ resultIndex++ ] = toCString(AS_STRING(assign))[ i ]; + for (int i = min; i >= 0 && i < assignLength; i += TOY_AS_INTEGER(third)) { + result[ resultIndex++ ] = Toy_toCString(TOY_AS_STRING(assign))[ i ]; } - for (int i = AS_INTEGER(second) + 1; i < compoundLength; i++) { - result[ resultIndex++ ] = toCString(AS_STRING(compound))[ i ]; + for (int i = TOY_AS_INTEGER(second) + 1; i < compoundLength; i++) { + result[ resultIndex++ ] = Toy_toCString(TOY_AS_STRING(compound))[ i ]; } result[ resultIndex ] = '\0'; @@ -894,107 +894,107 @@ int _index(Interpreter* interpreter, LiteralArray* arguments) { //else override elements of the array instead else { //copy compound to result - snprintf(result, MAX_STRING_LENGTH, "%s", toCString(AS_STRING(compound))); + snprintf(result, TOY_MAX_STRING_LENGTH, "%s", Toy_toCString(TOY_AS_STRING(compound))); - int assignLength = AS_STRING(assign)->length; - int min = AS_INTEGER(third) > 0 ? AS_INTEGER(first) : AS_INTEGER(second) - 1; + int assignLength = TOY_AS_STRING(assign)->length; + int min = TOY_AS_INTEGER(third) > 0 ? TOY_AS_INTEGER(first) : TOY_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 ] = toCString(AS_STRING(assign))[ assignIndex++ ]; + for (int i = min; i >= TOY_AS_INTEGER(first) && i <= TOY_AS_INTEGER(second) && assignIndex < assignLength; i += TOY_AS_INTEGER(third)) { + result[ i ] = Toy_toCString(TOY_AS_STRING(assign))[ assignIndex++ ]; } resultIndex = strlen(result); } //finally, swap out the compound for the result - freeLiteral(compound); - compound = TO_STRING_LITERAL(createRefStringLength(result, resultIndex)); + Toy_freeLiteral(compound); + compound = TOY_TO_STRING_LITERAL(Toy_createRefStringLength(result, resultIndex)); - FREE_ARRAY(char, result, MAX_STRING_LENGTH); + TOY_FREE_ARRAY(char, result, TOY_MAX_STRING_LENGTH); } - else if (IS_STRING(op) && equalsRefStringCString(AS_STRING(op), "+=")) { - Literal tmp = addition(interpreter, compound, assign); - freeLiteral(compound); + else if (TOY_IS_STRING(op) && Toy_equalsRefStringCString(TOY_AS_STRING(op), "+=")) { + Toy_Literal tmp = addition(interpreter, compound, assign); + Toy_freeLiteral(compound); compound = tmp; //don't clear tmp } } //leave the compound on the stack - pushLiteralArray(&interpreter->stack, compound); + Toy_pushLiteralArray(&interpreter->stack, compound); - freeLiteral(op); - freeLiteral(assign); - freeLiteral(third); - freeLiteral(second); - freeLiteral(first); - freeLiteral(compound); - freeLiteral(value); + Toy_freeLiteral(op); + Toy_freeLiteral(assign); + Toy_freeLiteral(third); + Toy_freeLiteral(second); + Toy_freeLiteral(first); + Toy_freeLiteral(compound); + Toy_freeLiteral(value); return 1; } -int _set(Interpreter* interpreter, LiteralArray* arguments) { +int _set(Toy_Interpreter* interpreter, Toy_LiteralArray* arguments) { //if wrong number of arguments, fail if (arguments->count != 3) { interpreter->errorOutput("Incorrect number of arguments to _set\n"); return -1; } - Literal idn = arguments->literals[0]; - Literal obj = arguments->literals[0]; - Literal key = arguments->literals[1]; - Literal val = arguments->literals[2]; + Toy_Literal idn = arguments->literals[0]; + Toy_Literal obj = arguments->literals[0]; + Toy_Literal key = arguments->literals[1]; + Toy_Literal val = arguments->literals[2]; - if (!IS_IDENTIFIER(idn)) { + if (!TOY_IS_IDENTIFIER(idn)) { interpreter->errorOutput("Expected identifier in _set\n"); return -1; } - parseIdentifierToValue(interpreter, &obj); + Toy_parseIdentifierToValue(interpreter, &obj); bool freeKey = false; - if (IS_IDENTIFIER(key)) { - parseIdentifierToValue(interpreter, &key); + if (TOY_IS_IDENTIFIER(key)) { + Toy_parseIdentifierToValue(interpreter, &key); freeKey = true; } bool freeVal = false; - if (IS_IDENTIFIER(val)) { - parseIdentifierToValue(interpreter, &val); + if (TOY_IS_IDENTIFIER(val)) { + Toy_parseIdentifierToValue(interpreter, &val); freeVal = true; } switch(obj.type) { - case LITERAL_ARRAY: { - Literal typeLiteral = getScopeType(interpreter->scope, key); + case TOY_LITERAL_ARRAY: { + Toy_Literal typeLiteral = Toy_getScopeType(interpreter->scope, key); - if (AS_TYPE(typeLiteral).typeOf == LITERAL_ARRAY) { - Literal subtypeLiteral = ((Literal*)(AS_TYPE(typeLiteral).subtypes))[0]; + if (TOY_AS_TYPE(typeLiteral).typeOf == TOY_LITERAL_ARRAY) { + Toy_Literal subtypeLiteral = ((Toy_Literal*)(TOY_AS_TYPE(typeLiteral).subtypes))[0]; - if (AS_TYPE(subtypeLiteral).typeOf != LITERAL_ANY && AS_TYPE(subtypeLiteral).typeOf != val.type) { + if (TOY_AS_TYPE(subtypeLiteral).typeOf != TOY_LITERAL_ANY && TOY_AS_TYPE(subtypeLiteral).typeOf != val.type) { interpreter->errorOutput("Bad argument type in _set\n"); return -1; } } - if (!IS_INTEGER(key)) { + if (!TOY_IS_INTEGER(key)) { interpreter->errorOutput("Expected integer index in _set\n"); return -1; } - if (AS_ARRAY(obj)->count <= AS_INTEGER(key) || AS_INTEGER(key) < 0) { + if (TOY_AS_ARRAY(obj)->count <= TOY_AS_INTEGER(key) || TOY_AS_INTEGER(key) < 0) { interpreter->errorOutput("Index out of bounds in _set\n"); return -1; } //don't use pushLiteralArray, since we're setting - freeLiteral(AS_ARRAY(obj)->literals[AS_INTEGER(key)]); //BUGFIX: clear any existing data first - AS_ARRAY(obj)->literals[AS_INTEGER(key)] = copyLiteral(val); + Toy_freeLiteral(TOY_AS_ARRAY(obj)->literals[TOY_AS_INTEGER(key)]); //BUGFIX: clear any existing data first + TOY_AS_ARRAY(obj)->literals[TOY_AS_INTEGER(key)] = Toy_copyLiteral(val); - if (!setScopeVariable(interpreter->scope, idn, obj, true)) { + if (!Toy_setScopeVariable(interpreter->scope, idn, obj, true)) { interpreter->errorOutput("Incorrect type assigned to array in _set: \""); - printLiteralCustom(val, interpreter->errorOutput); + Toy_printLiteralCustom(val, interpreter->errorOutput); interpreter->errorOutput("\"\n"); return -1; } @@ -1002,29 +1002,29 @@ int _set(Interpreter* interpreter, LiteralArray* arguments) { break; } - case LITERAL_DICTIONARY: { - Literal typeLiteral = getScopeType(interpreter->scope, key); + case TOY_LITERAL_DICTIONARY: { + Toy_Literal typeLiteral = Toy_getScopeType(interpreter->scope, key); - if (AS_TYPE(typeLiteral).typeOf == LITERAL_DICTIONARY) { - Literal keySubtypeLiteral = ((Literal*)(AS_TYPE(typeLiteral).subtypes))[0]; - Literal valSubtypeLiteral = ((Literal*)(AS_TYPE(typeLiteral).subtypes))[1]; + if (TOY_AS_TYPE(typeLiteral).typeOf == TOY_LITERAL_DICTIONARY) { + Toy_Literal keySubtypeLiteral = ((Toy_Literal*)(TOY_AS_TYPE(typeLiteral).subtypes))[0]; + Toy_Literal valSubtypeLiteral = ((Toy_Literal*)(TOY_AS_TYPE(typeLiteral).subtypes))[1]; - if (AS_TYPE(keySubtypeLiteral).typeOf != LITERAL_ANY && AS_TYPE(keySubtypeLiteral).typeOf != key.type) { + if (TOY_AS_TYPE(keySubtypeLiteral).typeOf != TOY_LITERAL_ANY && TOY_AS_TYPE(keySubtypeLiteral).typeOf != key.type) { interpreter->printOutput("bad argument type in _set\n"); return -1; } - if (AS_TYPE(valSubtypeLiteral).typeOf != LITERAL_ANY && AS_TYPE(valSubtypeLiteral).typeOf != val.type) { + if (TOY_AS_TYPE(valSubtypeLiteral).typeOf != TOY_LITERAL_ANY && TOY_AS_TYPE(valSubtypeLiteral).typeOf != val.type) { interpreter->printOutput("bad argument type in _set\n"); return -1; } } - setLiteralDictionary(AS_DICTIONARY(obj), key, val); + Toy_setLiteralDictionary(TOY_AS_DICTIONARY(obj), key, val); - if (!setScopeVariable(interpreter->scope, idn, obj, true)) { + if (!Toy_setScopeVariable(interpreter->scope, idn, obj, true)) { interpreter->errorOutput("Incorrect type assigned to dictionary in _set: \""); - printLiteralCustom(val, interpreter->errorOutput); + Toy_printLiteralCustom(val, interpreter->errorOutput); interpreter->errorOutput("\"\n"); return -1; } @@ -1034,82 +1034,82 @@ int _set(Interpreter* interpreter, LiteralArray* arguments) { default: interpreter->errorOutput("Incorrect compound type in _set: "); - printLiteralCustom(obj, interpreter->errorOutput); + Toy_printLiteralCustom(obj, interpreter->errorOutput); interpreter->errorOutput("\"\n"); return -1; } - freeLiteral(obj); + Toy_freeLiteral(obj); if (freeKey) { - freeLiteral(key); + Toy_freeLiteral(key); } if (freeVal) { - freeLiteral(val); + Toy_freeLiteral(val); } return 0; } -int _get(Interpreter* interpreter, LiteralArray* arguments) { +int _get(Toy_Interpreter* interpreter, Toy_LiteralArray* arguments) { //if wrong number of arguments, fail if (arguments->count != 2) { interpreter->errorOutput("Incorrect number of arguments to _get"); return -1; } - Literal obj = arguments->literals[0]; - Literal key = arguments->literals[1]; + Toy_Literal obj = arguments->literals[0]; + Toy_Literal key = arguments->literals[1]; bool freeObj = false; - if (IS_IDENTIFIER(obj)) { - parseIdentifierToValue(interpreter, &obj); + if (TOY_IS_IDENTIFIER(obj)) { + Toy_parseIdentifierToValue(interpreter, &obj); freeObj = true; } bool freeKey = false; - if (IS_IDENTIFIER(key)) { - parseIdentifierToValue(interpreter, &key); + if (TOY_IS_IDENTIFIER(key)) { + Toy_parseIdentifierToValue(interpreter, &key); freeKey = true; } switch(obj.type) { - case LITERAL_ARRAY: { - if (!IS_INTEGER(key)) { + case TOY_LITERAL_ARRAY: { + if (!TOY_IS_INTEGER(key)) { interpreter->errorOutput("Expected integer index in _get\n"); return -1; } - if (AS_ARRAY(obj)->count <= AS_INTEGER(key) || AS_INTEGER(key) < 0) { + if (TOY_AS_ARRAY(obj)->count <= TOY_AS_INTEGER(key) || TOY_AS_INTEGER(key) < 0) { interpreter->errorOutput("Index out of bounds in _get\n"); return -1; } - pushLiteralArray(&interpreter->stack, AS_ARRAY(obj)->literals[AS_INTEGER(key)]); + Toy_pushLiteralArray(&interpreter->stack, TOY_AS_ARRAY(obj)->literals[TOY_AS_INTEGER(key)]); if (freeObj) { - freeLiteral(obj); + Toy_freeLiteral(obj); } if (freeKey) { - freeLiteral(key); + Toy_freeLiteral(key); } return 1; } - case LITERAL_DICTIONARY: { - Literal dict = getLiteralDictionary(AS_DICTIONARY(obj), key); - pushLiteralArray(&interpreter->stack, dict); - freeLiteral(dict); + case TOY_LITERAL_DICTIONARY: { + Toy_Literal dict = Toy_getLiteralDictionary(TOY_AS_DICTIONARY(obj), key); + Toy_pushLiteralArray(&interpreter->stack, dict); + Toy_freeLiteral(dict); if (freeObj) { - freeLiteral(obj); + Toy_freeLiteral(obj); } if (freeKey) { - freeLiteral(key); + Toy_freeLiteral(key); } return 1; @@ -1117,62 +1117,62 @@ int _get(Interpreter* interpreter, LiteralArray* arguments) { default: interpreter->errorOutput("Incorrect compound type in _get \""); - printLiteralCustom(obj, interpreter->errorOutput); + Toy_printLiteralCustom(obj, interpreter->errorOutput); interpreter->errorOutput("\"\n"); return -1; } } -int _push(Interpreter* interpreter, LiteralArray* arguments) { +int _push(Toy_Interpreter* interpreter, Toy_LiteralArray* arguments) { //if wrong number of arguments, fail if (arguments->count != 2) { interpreter->errorOutput("Incorrect number of arguments to _push\n"); return -1; } - Literal idn = arguments->literals[0]; - Literal obj = arguments->literals[0]; - Literal val = arguments->literals[1]; + Toy_Literal idn = arguments->literals[0]; + Toy_Literal obj = arguments->literals[0]; + Toy_Literal val = arguments->literals[1]; - if (!IS_IDENTIFIER(idn)) { + if (!TOY_IS_IDENTIFIER(idn)) { interpreter->errorOutput("Expected identifier in _push\n"); return -1; } - parseIdentifierToValue(interpreter, &obj); + Toy_parseIdentifierToValue(interpreter, &obj); bool freeVal = false; - if (IS_IDENTIFIER(val)) { - parseIdentifierToValue(interpreter, &val); + if (TOY_IS_IDENTIFIER(val)) { + Toy_parseIdentifierToValue(interpreter, &val); freeVal = true; } switch(obj.type) { - case LITERAL_ARRAY: { - Literal typeLiteral = getScopeType(interpreter->scope, val); + case TOY_LITERAL_ARRAY: { + Toy_Literal typeLiteral = Toy_getScopeType(interpreter->scope, val); - if (AS_TYPE(typeLiteral).typeOf == LITERAL_ARRAY) { - Literal subtypeLiteral = ((Literal*)(AS_TYPE(typeLiteral).subtypes))[0]; + if (TOY_AS_TYPE(typeLiteral).typeOf == TOY_LITERAL_ARRAY) { + Toy_Literal subtypeLiteral = ((Toy_Literal*)(TOY_AS_TYPE(typeLiteral).subtypes))[0]; - if (AS_TYPE(subtypeLiteral).typeOf != LITERAL_ANY && AS_TYPE(subtypeLiteral).typeOf != val.type) { + if (TOY_AS_TYPE(subtypeLiteral).typeOf != TOY_LITERAL_ANY && TOY_AS_TYPE(subtypeLiteral).typeOf != val.type) { interpreter->errorOutput("Bad argument type in _push"); return -1; } } - pushLiteralArray(AS_ARRAY(obj), val); + Toy_pushLiteralArray(TOY_AS_ARRAY(obj), val); - if (!setScopeVariable(interpreter->scope, idn, obj, true)) { //TODO: could definitely be more efficient than overwriting the whole original object + if (!Toy_setScopeVariable(interpreter->scope, idn, obj, true)) { //TODO: could definitely be more efficient than overwriting the whole original object interpreter->errorOutput("Incorrect type assigned to array in _push: \""); - printLiteralCustom(val, interpreter->errorOutput); + Toy_printLiteralCustom(val, interpreter->errorOutput); interpreter->errorOutput("\"\n"); return -1; } - freeLiteral(obj); + Toy_freeLiteral(obj); if (freeVal) { - freeLiteral(val); + Toy_freeLiteral(val); } return 0; @@ -1180,169 +1180,169 @@ int _push(Interpreter* interpreter, LiteralArray* arguments) { default: interpreter->errorOutput("Incorrect compound type in _push: "); - printLiteralCustom(obj, interpreter->errorOutput); + Toy_printLiteralCustom(obj, interpreter->errorOutput); interpreter->errorOutput("\n"); return -1; } } -int _pop(Interpreter* interpreter, LiteralArray* arguments) { +int _pop(Toy_Interpreter* interpreter, Toy_LiteralArray* arguments) { //if wrong number of arguments, fail if (arguments->count != 1) { interpreter->errorOutput("Incorrect number of arguments to _pop\n"); return -1; } - Literal idn = arguments->literals[0]; - Literal obj = arguments->literals[0]; + Toy_Literal idn = arguments->literals[0]; + Toy_Literal obj = arguments->literals[0]; - if (!IS_IDENTIFIER(idn)) { + if (!TOY_IS_IDENTIFIER(idn)) { interpreter->errorOutput("Expected identifier in _pop\n"); return -1; } - parseIdentifierToValue(interpreter, &obj); + Toy_parseIdentifierToValue(interpreter, &obj); switch(obj.type) { - case LITERAL_ARRAY: { - Literal lit = popLiteralArray(AS_ARRAY(obj)); - pushLiteralArray(&interpreter->stack, lit); - freeLiteral(lit); + case TOY_LITERAL_ARRAY: { + Toy_Literal lit = Toy_popLiteralArray(TOY_AS_ARRAY(obj)); + Toy_pushLiteralArray(&interpreter->stack, lit); + Toy_freeLiteral(lit); - if (!setScopeVariable(interpreter->scope, idn, obj, true)) { //TODO: could definitely be more efficient than overwriting the whole original object + if (!Toy_setScopeVariable(interpreter->scope, idn, obj, true)) { //TODO: could definitely be more efficient than overwriting the whole original object interpreter->errorOutput("Incorrect type assigned to array in _pop: "); - printLiteralCustom(obj, interpreter->errorOutput); + Toy_printLiteralCustom(obj, interpreter->errorOutput); interpreter->errorOutput("\n"); return -1; } - freeLiteral(obj); + Toy_freeLiteral(obj); return 1; } default: interpreter->errorOutput("Incorrect compound type in _pop: "); - printLiteralCustom(obj, interpreter->errorOutput); + Toy_printLiteralCustom(obj, interpreter->errorOutput); interpreter->errorOutput("\n"); return -1; } } -int _length(Interpreter* interpreter, LiteralArray* arguments) { +int _length(Toy_Interpreter* interpreter, Toy_LiteralArray* arguments) { //if wrong number of arguments, fail if (arguments->count != 1) { interpreter->errorOutput("Incorrect number of arguments to _length\n"); return -1; } - Literal obj = arguments->literals[0]; + Toy_Literal obj = arguments->literals[0]; bool freeObj = false; - if (IS_IDENTIFIER(obj)) { - parseIdentifierToValue(interpreter, &obj); + if (TOY_IS_IDENTIFIER(obj)) { + Toy_parseIdentifierToValue(interpreter, &obj); freeObj = true; } switch(obj.type) { - case LITERAL_ARRAY: { - Literal lit = TO_INTEGER_LITERAL( AS_ARRAY(obj)->count ); - pushLiteralArray(&interpreter->stack, lit); - freeLiteral(lit); + case TOY_LITERAL_ARRAY: { + Toy_Literal lit = TOY_TO_INTEGER_LITERAL( TOY_AS_ARRAY(obj)->count ); + Toy_pushLiteralArray(&interpreter->stack, lit); + Toy_freeLiteral(lit); break; } - case LITERAL_DICTIONARY: { - Literal lit = TO_INTEGER_LITERAL( AS_DICTIONARY(obj)->count ); - pushLiteralArray(&interpreter->stack, lit); - freeLiteral(lit); + case TOY_LITERAL_DICTIONARY: { + Toy_Literal lit = TOY_TO_INTEGER_LITERAL( TOY_AS_DICTIONARY(obj)->count ); + Toy_pushLiteralArray(&interpreter->stack, lit); + Toy_freeLiteral(lit); break; } - case LITERAL_STRING: { - Literal lit = TO_INTEGER_LITERAL( AS_STRING(obj)->length ); - pushLiteralArray(&interpreter->stack, lit); - freeLiteral(lit); + case TOY_LITERAL_STRING: { + Toy_Literal lit = TOY_TO_INTEGER_LITERAL( TOY_AS_STRING(obj)->length ); + Toy_pushLiteralArray(&interpreter->stack, lit); + Toy_freeLiteral(lit); break; } default: interpreter->errorOutput("Incorrect compound type in _length: "); - printLiteralCustom(obj, interpreter->errorOutput); + Toy_printLiteralCustom(obj, interpreter->errorOutput); interpreter->errorOutput("\n"); return -1; } if (freeObj) { - freeLiteral(obj); + Toy_freeLiteral(obj); } return 1; } -int _clear(Interpreter* interpreter, LiteralArray* arguments) { +int _clear(Toy_Interpreter* interpreter, Toy_LiteralArray* arguments) { //if wrong number of arguments, fail if (arguments->count != 1) { interpreter->errorOutput("Incorrect number of arguments to _clear\n"); return -1; } - Literal idn = arguments->literals[0]; - Literal obj = arguments->literals[0]; + Toy_Literal idn = arguments->literals[0]; + Toy_Literal obj = arguments->literals[0]; - if (!IS_IDENTIFIER(idn)) { + if (!TOY_IS_IDENTIFIER(idn)) { interpreter->errorOutput("expected identifier in _clear\n"); return -1; } - parseIdentifierToValue(interpreter, &obj); + Toy_parseIdentifierToValue(interpreter, &obj); //NOTE: just pass in new compounds switch(obj.type) { - case LITERAL_ARRAY: { - LiteralArray* array = ALLOCATE(LiteralArray, 1); - initLiteralArray(array); + case TOY_LITERAL_ARRAY: { + Toy_LiteralArray* array = TOY_ALLOCATE(Toy_LiteralArray, 1); + Toy_initLiteralArray(array); - Literal obj = TO_ARRAY_LITERAL(array); + Toy_Literal obj = TOY_TO_ARRAY_LITERAL(array); - if (!setScopeVariable(interpreter->scope, idn, obj, true)) { + if (!Toy_setScopeVariable(interpreter->scope, idn, obj, true)) { interpreter->errorOutput("Incorrect type assigned to array in _clear: "); - printLiteralCustom(obj, interpreter->errorOutput); + Toy_printLiteralCustom(obj, interpreter->errorOutput); interpreter->errorOutput("\n"); return -1; } - freeLiteral(obj); + Toy_freeLiteral(obj); break; } - case LITERAL_DICTIONARY: { - LiteralDictionary* dictionary = ALLOCATE(LiteralDictionary, 1); - initLiteralDictionary(dictionary); + case TOY_LITERAL_DICTIONARY: { + Toy_LiteralDictionary* dictionary = TOY_ALLOCATE(Toy_LiteralDictionary, 1); + Toy_initLiteralDictionary(dictionary); - Literal obj = TO_DICTIONARY_LITERAL(dictionary); + Toy_Literal obj = TOY_TO_DICTIONARY_LITERAL(dictionary); - if (!setScopeVariable(interpreter->scope, idn, obj, true)) { + if (!Toy_setScopeVariable(interpreter->scope, idn, obj, true)) { interpreter->errorOutput("Incorrect type assigned to dictionary in _clear: "); - printLiteralCustom(obj, interpreter->errorOutput); + Toy_printLiteralCustom(obj, interpreter->errorOutput); interpreter->errorOutput("\n"); return -1; } - freeLiteral(obj); + Toy_freeLiteral(obj); break; } default: interpreter->errorOutput("Incorrect compound type in _clear: "); - printLiteralCustom(obj, interpreter->errorOutput); + Toy_printLiteralCustom(obj, interpreter->errorOutput); interpreter->errorOutput("\n"); return -1; } - freeLiteral(obj); + Toy_freeLiteral(obj); return 1; } diff --git a/source/toy_builtin.h b/source/toy_builtin.h index e12e81a..9510a7d 100644 --- a/source/toy_builtin.h +++ b/source/toy_builtin.h @@ -1,14 +1,14 @@ #pragma once -#include "interpreter.h" +#include "toy_interpreter.h" //the _index function is a historical oddity - it's used whenever a compound is indexed -int _index(Interpreter* interpreter, LiteralArray* arguments); +int _index(Toy_Interpreter* interpreter, Toy_LiteralArray* arguments); //globally available native functions -int _set(Interpreter* interpreter, LiteralArray* arguments); -int _get(Interpreter* interpreter, LiteralArray* arguments); -int _push(Interpreter* interpreter, LiteralArray* arguments); -int _pop(Interpreter* interpreter, LiteralArray* arguments); -int _length(Interpreter* interpreter, LiteralArray* arguments); -int _clear(Interpreter* interpreter, LiteralArray* arguments); +int _set(Toy_Interpreter* interpreter, Toy_LiteralArray* arguments); +int _get(Toy_Interpreter* interpreter, Toy_LiteralArray* arguments); +int _push(Toy_Interpreter* interpreter, Toy_LiteralArray* arguments); +int _pop(Toy_Interpreter* interpreter, Toy_LiteralArray* arguments); +int _length(Toy_Interpreter* interpreter, Toy_LiteralArray* arguments); +int _clear(Toy_Interpreter* interpreter, Toy_LiteralArray* arguments); diff --git a/source/toy_common.c b/source/toy_common.c index 75e1f4d..cfeac37 100644 --- a/source/toy_common.c +++ b/source/toy_common.c @@ -20,7 +20,7 @@ STATIC_ASSERT(sizeof(unsigned int) == 4); //declare the singleton Command command; -void initCommand(int argc, const char* argv[]) { +void Toy_initCommand(int argc, const char* argv[]) { //default values command.error = false; command.help = false; @@ -95,12 +95,12 @@ void initCommand(int argc, const char* argv[]) { } } -void usageCommand(int argc, const char* argv[]) { +void Toy_usageCommand(int argc, const char* argv[]) { printf("Usage: %s [ | -h | -v | [-d][-f file | -i source | -c file [-o outfile]]]\n\n", argv[0]); } -void helpCommand(int argc, const char* argv[]) { - usageCommand(argc, argv); +void Toy_helpCommand(int argc, const char* argv[]) { + Toy_usageCommand(argc, argv); printf("\t\t\tBinary input file in tb format, must be version %d.%d.%d.\n\n", TOY_VERSION_MAJOR, TOY_VERSION_MINOR, TOY_VERSION_PATCH); printf("-h\t| --help\t\tShow this help then exit.\n\n"); @@ -112,7 +112,7 @@ void helpCommand(int argc, const char* argv[]) { printf("-o\t| --output outfile\tName of the output file built with --compile (default: out.tb).\n\n"); } -void copyrightCommand(int argc, const char* argv[]) { +void Toy_copyrightCommand(int argc, const char* argv[]) { printf("Toy Programming Language Interpreter Version %d.%d.%d (built on %s)\n\n", TOY_VERSION_MAJOR, TOY_VERSION_MINOR, TOY_VERSION_PATCH, TOY_VERSION_BUILD); printf("Copyright (c) 2020-2022 Kayne Ruse, KR Game Studios\n\n"); printf("This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages arising from the use of this software.\n\n"); diff --git a/source/toy_common.h b/source/toy_common.h index 4410501..a593acd 100644 --- a/source/toy_common.h +++ b/source/toy_common.h @@ -5,8 +5,8 @@ #include #define TOY_VERSION_MAJOR 0 -#define TOY_VERSION_MINOR 7 -#define TOY_VERSION_PATCH 1 +#define TOY_VERSION_MINOR 8 +#define TOY_VERSION_PATCH 0 #define TOY_VERSION_BUILD __DATE__ " " __TIME__ //platform-specific specifications @@ -37,9 +37,9 @@ typedef struct { extern Command command; -void initCommand(int argc, const char* argv[]); +void Toy_initCommand(int argc, const char* argv[]); -void usageCommand(int argc, const char* argv[]); -void helpCommand(int argc, const char* argv[]); -void copyrightCommand(int argc, const char* argv[]); +void Toy_usageCommand(int argc, const char* argv[]); +void Toy_helpCommand(int argc, const char* argv[]); +void Toy_copyrightCommand(int argc, const char* argv[]); #endif diff --git a/source/toy_compiler.c b/source/toy_compiler.c index 63afcc6..f0e3c26 100644 --- a/source/toy_compiler.c +++ b/source/toy_compiler.c @@ -1,253 +1,253 @@ -#include "compiler.h" +#include "toy_compiler.h" -#include "memory.h" +#include "toy_memory.h" -#include "literal.h" -#include "literal_array.h" -#include "literal_dictionary.h" +#include "toy_literal.h" +#include "toy_literal_array.h" +#include "toy_literal_dictionary.h" -#include "console_colors.h" +#include "toy_console_colors.h" #include -void initCompiler(Compiler* compiler) { - initLiteralArray(&compiler->literalCache); +void Toy_initCompiler(Toy_Compiler* compiler) { + Toy_initLiteralArray(&compiler->literalCache); compiler->bytecode = NULL; compiler->capacity = 0; compiler->count = 0; } //separated out, so it can be recursive -static int writeLiteralTypeToCache(LiteralArray* literalCache, Literal literal) { +static int writeLiteralTypeToCache(Toy_LiteralArray* literalCache, Toy_Literal literal) { bool shouldFree = false; //if it's a compound type, recurse and store the results - if (AS_TYPE(literal).typeOf == LITERAL_ARRAY || AS_TYPE(literal).typeOf == LITERAL_DICTIONARY) { + if (TOY_AS_TYPE(literal).typeOf == TOY_LITERAL_ARRAY || TOY_AS_TYPE(literal).typeOf == TOY_LITERAL_DICTIONARY) { //I don't like storing types in an array, but it's the easiest and most straight forward method - LiteralArray* store = ALLOCATE(LiteralArray, 1); - initLiteralArray(store); + Toy_LiteralArray* store = TOY_ALLOCATE(Toy_LiteralArray, 1); + Toy_initLiteralArray(store); //store the base literal in the store - pushLiteralArray(store, literal); + Toy_pushLiteralArray(store, literal); - for (int i = 0; i < AS_TYPE(literal).count; i++) { + for (int i = 0; i < TOY_AS_TYPE(literal).count; i++) { //write the values to the cache, and the indexes to the store - int subIndex = writeLiteralTypeToCache(literalCache, ((Literal*)(AS_TYPE(literal).subtypes))[i]); + int subIndex = writeLiteralTypeToCache(literalCache, ((Toy_Literal*)(TOY_AS_TYPE(literal).subtypes))[i]); - Literal lit = TO_INTEGER_LITERAL(subIndex); - pushLiteralArray(store, lit); - freeLiteral(lit); + Toy_Literal lit = TOY_TO_INTEGER_LITERAL(subIndex); + Toy_pushLiteralArray(store, lit); + Toy_freeLiteral(lit); } //push the store to the cache, tweaking the type shouldFree = true; - literal = TO_ARRAY_LITERAL(store); - literal.type = LITERAL_TYPE_INTERMEDIATE; //NOTE: tweaking the type usually isn't a good idea + literal = TOY_TO_ARRAY_LITERAL(store); + literal.type = TOY_LITERAL_TYPE_INTERMEDIATE; //NOTE: tweaking the type usually isn't a good idea } //optimisation: check if exactly this literal array exists - int index = findLiteralIndex(literalCache, literal); + int index = Toy_findLiteralIndex(literalCache, literal); if (index < 0) { - index = pushLiteralArray(literalCache, literal); + index = Toy_pushLiteralArray(literalCache, literal); } if (shouldFree) { - freeLiteral(literal); + Toy_freeLiteral(literal); } return index; } -static int writeNodeCompoundToCache(Compiler* compiler, ASTNode* node) { +static int writeNodeCompoundToCache(Toy_Compiler* compiler, Toy_ASTNode* node) { int index = -1; //for both, stored as an array - LiteralArray* store = ALLOCATE(LiteralArray, 1); - initLiteralArray(store); + Toy_LiteralArray* store = TOY_ALLOCATE(Toy_LiteralArray, 1); + Toy_initLiteralArray(store); //emit an array or a dictionary definition - if (node->compound.literalType == LITERAL_DICTIONARY) { + if (node->compound.literalType == TOY_LITERAL_DICTIONARY) { //ensure each literal key and value are in the cache, individually for (int i = 0; i < node->compound.count; i++) { //keys switch(node->compound.nodes[i].pair.left->type) { - case AST_NODE_LITERAL: { + case TOY_AST_NODE_LITERAL: { //keys are literals - int key = findLiteralIndex(&compiler->literalCache, node->compound.nodes[i].pair.left->atomic.literal); + int key = Toy_findLiteralIndex(&compiler->literalCache, node->compound.nodes[i].pair.left->atomic.literal); if (key < 0) { - key = pushLiteralArray(&compiler->literalCache, node->compound.nodes[i].pair.left->atomic.literal); + key = Toy_pushLiteralArray(&compiler->literalCache, node->compound.nodes[i].pair.left->atomic.literal); } - Literal literal = TO_INTEGER_LITERAL(key); - pushLiteralArray(store, literal); - freeLiteral(literal); + Toy_Literal literal = TOY_TO_INTEGER_LITERAL(key); + Toy_pushLiteralArray(store, literal); + Toy_freeLiteral(literal); } break; - case AST_NODE_COMPOUND: { + case TOY_AST_NODE_COMPOUND: { int key = writeNodeCompoundToCache(compiler, node->compound.nodes[i].pair.left); - Literal literal = TO_INTEGER_LITERAL(key); - pushLiteralArray(store, literal); - freeLiteral(literal); + Toy_Literal literal = TOY_TO_INTEGER_LITERAL(key); + Toy_pushLiteralArray(store, literal); + Toy_freeLiteral(literal); } break; default: - fprintf(stderr, ERROR "[internal] Unrecognized key node type in writeNodeCompoundToCache()\n" RESET); + fprintf(stderr, TOY_CC_ERROR "[internal] Unrecognized key node type in writeNodeCompoundToCache()\n" TOY_CC_RESET); return -1; } //values switch(node->compound.nodes[i].pair.right->type) { - case AST_NODE_LITERAL: { + case TOY_AST_NODE_LITERAL: { //values are literals - int val = findLiteralIndex(&compiler->literalCache, node->compound.nodes[i].pair.right->atomic.literal); + int val = Toy_findLiteralIndex(&compiler->literalCache, node->compound.nodes[i].pair.right->atomic.literal); if (val < 0) { - val = pushLiteralArray(&compiler->literalCache, node->compound.nodes[i].pair.right->atomic.literal); + val = Toy_pushLiteralArray(&compiler->literalCache, node->compound.nodes[i].pair.right->atomic.literal); } - Literal literal = TO_INTEGER_LITERAL(val); - pushLiteralArray(store, literal); - freeLiteral(literal); + Toy_Literal literal = TOY_TO_INTEGER_LITERAL(val); + Toy_pushLiteralArray(store, literal); + Toy_freeLiteral(literal); } break; - case AST_NODE_COMPOUND: { + case TOY_AST_NODE_COMPOUND: { int val = writeNodeCompoundToCache(compiler, node->compound.nodes[i].pair.right); - Literal literal = TO_INTEGER_LITERAL(val); - pushLiteralArray(store, literal); - freeLiteral(literal); + Toy_Literal literal = TOY_TO_INTEGER_LITERAL(val); + Toy_pushLiteralArray(store, literal); + Toy_freeLiteral(literal); } break; default: - fprintf(stderr, ERROR "[internal] Unrecognized value node type in writeNodeCompoundToCache()\n" RESET); + fprintf(stderr, TOY_CC_ERROR "[internal] Unrecognized value node type in writeNodeCompoundToCache()\n" TOY_CC_RESET); return -1; } } //push the store to the cache, with instructions about how pack it - Literal literal = TO_DICTIONARY_LITERAL(store); - literal.type = LITERAL_DICTIONARY_INTERMEDIATE; //god damn it - index = pushLiteralArray(&compiler->literalCache, literal); - freeLiteral(literal); + Toy_Literal literal = TOY_TO_DICTIONARY_LITERAL(store); + literal.type = TOY_LITERAL_DICTIONARY_INTERMEDIATE; //god damn it + index = Toy_pushLiteralArray(&compiler->literalCache, literal); + Toy_freeLiteral(literal); } - else if (node->compound.literalType == LITERAL_ARRAY) { + else if (node->compound.literalType == TOY_LITERAL_ARRAY) { //ensure each literal value is in the cache, individually for (int i = 0; i < node->compound.count; i++) { switch(node->compound.nodes[i].type) { - case AST_NODE_LITERAL: { + case TOY_AST_NODE_LITERAL: { //values - int val = findLiteralIndex(&compiler->literalCache, node->compound.nodes[i].atomic.literal); + int val = Toy_findLiteralIndex(&compiler->literalCache, node->compound.nodes[i].atomic.literal); if (val < 0) { - val = pushLiteralArray(&compiler->literalCache, node->compound.nodes[i].atomic.literal); + val = Toy_pushLiteralArray(&compiler->literalCache, node->compound.nodes[i].atomic.literal); } - Literal literal = TO_INTEGER_LITERAL(val); - pushLiteralArray(store, literal); - freeLiteral(literal); + Toy_Literal literal = TOY_TO_INTEGER_LITERAL(val); + Toy_pushLiteralArray(store, literal); + Toy_freeLiteral(literal); } break; - case AST_NODE_COMPOUND: { + case TOY_AST_NODE_COMPOUND: { int val = writeNodeCompoundToCache(compiler, &node->compound.nodes[i]); - Literal literal = TO_INTEGER_LITERAL(val); - index = pushLiteralArray(store, literal); - freeLiteral(literal); + Toy_Literal literal = TOY_TO_INTEGER_LITERAL(val); + index = Toy_pushLiteralArray(store, literal); + Toy_freeLiteral(literal); } break; default: - fprintf(stderr, ERROR "[internal] Unrecognized node type in writeNodeCompoundToCache()" RESET); + fprintf(stderr, TOY_CC_ERROR "[internal] Unrecognized node type in writeNodeCompoundToCache()" TOY_CC_RESET); return -1; } } //push the store to the cache, with instructions about how pack it - Literal literal = TO_ARRAY_LITERAL(store); - index = pushLiteralArray(&compiler->literalCache, literal); - freeLiteral(literal); + Toy_Literal literal = TOY_TO_ARRAY_LITERAL(store); + index = Toy_pushLiteralArray(&compiler->literalCache, literal); + Toy_freeLiteral(literal); } else { - fprintf(stderr, ERROR "[internal] Unrecognized compound type in writeNodeCompoundToCache()" RESET); + fprintf(stderr, TOY_CC_ERROR "[internal] Unrecognized compound type in writeNodeCompoundToCache()" TOY_CC_RESET); } return index; } -static int writeNodeCollectionToCache(Compiler* compiler, ASTNode* node) { - LiteralArray* store = ALLOCATE(LiteralArray, 1); - initLiteralArray(store); +static int writeNodeCollectionToCache(Toy_Compiler* compiler, Toy_ASTNode* node) { + Toy_LiteralArray* store = TOY_ALLOCATE(Toy_LiteralArray, 1); + Toy_initLiteralArray(store); //ensure each literal value is in the cache, individually for (int i = 0; i < node->fnCollection.count; i++) { switch(node->fnCollection.nodes[i].type) { - case AST_NODE_VAR_DECL: { + case TOY_AST_NODE_VAR_DECL: { //write each piece of the declaration to the cache - int identifierIndex = pushLiteralArray(&compiler->literalCache, node->fnCollection.nodes[i].varDecl.identifier); //store without duplication optimisation + int identifierIndex = Toy_pushLiteralArray(&compiler->literalCache, node->fnCollection.nodes[i].varDecl.identifier); //store without duplication optimisation int typeIndex = writeLiteralTypeToCache(&compiler->literalCache, node->fnCollection.nodes[i].varDecl.typeLiteral); - Literal identifierLiteral = TO_INTEGER_LITERAL(identifierIndex); - pushLiteralArray(store, identifierLiteral); - freeLiteral(identifierLiteral); + Toy_Literal identifierLiteral = TOY_TO_INTEGER_LITERAL(identifierIndex); + Toy_pushLiteralArray(store, identifierLiteral); + Toy_freeLiteral(identifierLiteral); - Literal typeLiteral = TO_INTEGER_LITERAL(typeIndex); - pushLiteralArray(store, typeLiteral); - freeLiteral(typeLiteral); + Toy_Literal typeLiteral = TOY_TO_INTEGER_LITERAL(typeIndex); + Toy_pushLiteralArray(store, typeLiteral); + Toy_freeLiteral(typeLiteral); } break; - case AST_NODE_LITERAL: { + case TOY_AST_NODE_LITERAL: { //write each piece of the declaration to the cache int typeIndex = writeLiteralTypeToCache(&compiler->literalCache, node->fnCollection.nodes[i].atomic.literal); - Literal typeLiteral = TO_INTEGER_LITERAL(typeIndex); - pushLiteralArray(store, typeLiteral); - freeLiteral(typeLiteral); + Toy_Literal typeLiteral = TOY_TO_INTEGER_LITERAL(typeIndex); + Toy_pushLiteralArray(store, typeLiteral); + Toy_freeLiteral(typeLiteral); } break; default: - fprintf(stderr, ERROR "[internal] Unrecognized node type in writeNodeCollectionToCache()\n" RESET); + fprintf(stderr, TOY_CC_ERROR "[internal] Unrecognized node type in writeNodeCollectionToCache()\n" TOY_CC_RESET); return -1; } } //store the store - Literal literal = TO_ARRAY_LITERAL(store); - int storeIndex = pushLiteralArray(&compiler->literalCache, literal); - freeLiteral(literal); + Toy_Literal literal = TOY_TO_ARRAY_LITERAL(store); + int storeIndex = Toy_pushLiteralArray(&compiler->literalCache, literal); + Toy_freeLiteral(literal); return storeIndex; } -static int writeLiteralToCompiler(Compiler* compiler, Literal literal) { +static int writeLiteralToCompiler(Toy_Compiler* compiler, Toy_Literal literal) { //get the index - int index = findLiteralIndex(&compiler->literalCache, literal); + int index = Toy_findLiteralIndex(&compiler->literalCache, literal); if (index < 0) { - if (IS_TYPE(literal)) { + if (TOY_IS_TYPE(literal)) { //check for the type literal as value index = writeLiteralTypeToCache(&compiler->literalCache, literal); } else { - index = pushLiteralArray(&compiler->literalCache, literal); + index = Toy_pushLiteralArray(&compiler->literalCache, literal); } } //push the literal to the bytecode if (index >= 256) { //push a "long" index - compiler->bytecode[compiler->count++] = OP_LITERAL_LONG; //1 byte + compiler->bytecode[compiler->count++] = TOY_OP_LITERAL_LONG; //1 byte memcpy(compiler->bytecode + compiler->count, &index, sizeof(unsigned short)); //2 bytes compiler->count += sizeof(unsigned short); } else { //push the index - compiler->bytecode[compiler->count++] = OP_LITERAL; //1 byte + compiler->bytecode[compiler->count++] = TOY_OP_LITERAL; //1 byte compiler->bytecode[compiler->count++] = (unsigned char)index; //1 byte } @@ -256,33 +256,33 @@ static int writeLiteralToCompiler(Compiler* compiler, Literal literal) { //NOTE: jumpOfsets are included, because function arg and return indexes are embedded in the code body i.e. need to include their sizes in the jump //NOTE: rootNode should NOT include groupings and blocks -static Opcode writeCompilerWithJumps(Compiler* compiler, ASTNode* node, void* breakAddressesPtr, void* continueAddressesPtr, int jumpOffsets, ASTNode* rootNode) { +static Toy_Opcode Toy_writeCompilerWithJumps(Toy_Compiler* compiler, Toy_ASTNode* node, void* breakAddressesPtr, void* continueAddressesPtr, int jumpOffsets, Toy_ASTNode* rootNode) { //grow if the bytecode space is too small if (compiler->count + 32 > compiler->capacity) { int oldCapacity = compiler->capacity; - compiler->capacity = GROW_CAPACITY_FAST(oldCapacity); - compiler->bytecode = GROW_ARRAY(unsigned char, compiler->bytecode, oldCapacity, compiler->capacity); + compiler->capacity = TOY_GROW_CAPACITY_FAST(oldCapacity); + compiler->bytecode = TOY_GROW_ARRAY(unsigned char, compiler->bytecode, oldCapacity, compiler->capacity); } //determine node type switch(node->type) { - case AST_NODE_ERROR: { - fprintf(stderr, ERROR "[internal] AST_NODEERROR encountered in writeCompilerWithJumps()\n" RESET); - compiler->bytecode[compiler->count++] = OP_EOF; //1 byte + case TOY_AST_NODE_ERROR: { + fprintf(stderr, TOY_CC_ERROR "[internal] TOY_AST_NODEERROR encountered in Toy_writeCompilerWithJumps()\n" TOY_CC_RESET); + compiler->bytecode[compiler->count++] = TOY_OP_EOF; //1 byte } break; - case AST_NODE_LITERAL: { + case TOY_AST_NODE_LITERAL: { writeLiteralToCompiler(compiler, node->atomic.literal); } break; - case AST_NODE_UNARY: { + case TOY_AST_NODE_UNARY: { //pass to the child node, then embed the unary command (print, negate, etc.) - Opcode override = writeCompilerWithJumps(compiler, node->unary.child, breakAddressesPtr, continueAddressesPtr, jumpOffsets, rootNode); + Toy_Opcode override = Toy_writeCompilerWithJumps(compiler, node->unary.child, breakAddressesPtr, continueAddressesPtr, jumpOffsets, rootNode); - if (override != OP_EOF) {//compensate for indexing & dot notation being screwy + if (override != TOY_OP_EOF) {//compensate for indexing & dot notation being screwy compiler->bytecode[compiler->count++] = (unsigned char)override; //1 byte } @@ -291,38 +291,38 @@ static Opcode writeCompilerWithJumps(Compiler* compiler, ASTNode* node, void* br break; //all infixes come here - case AST_NODE_BINARY: { + case TOY_AST_NODE_BINARY: { //pass to the child nodes, then embed the binary command (math, etc.) - Opcode override = writeCompilerWithJumps(compiler, node->binary.left, breakAddressesPtr, continueAddressesPtr, jumpOffsets, rootNode); + Toy_Opcode override = Toy_writeCompilerWithJumps(compiler, node->binary.left, breakAddressesPtr, continueAddressesPtr, jumpOffsets, rootNode); //special case for when indexing and assigning - if (override != OP_EOF && node->binary.opcode >= OP_VAR_ASSIGN && node->binary.opcode <= OP_VAR_MODULO_ASSIGN) { - writeCompilerWithJumps(compiler, node->binary.right, breakAddressesPtr, continueAddressesPtr, jumpOffsets, rootNode); - compiler->bytecode[compiler->count++] = (unsigned char)OP_INDEX_ASSIGN; //1 byte WARNING: enum trickery + if (override != TOY_OP_EOF && node->binary.opcode >= TOY_OP_VAR_ASSIGN && node->binary.opcode <= TOY_OP_VAR_MODULO_ASSIGN) { + Toy_writeCompilerWithJumps(compiler, node->binary.right, breakAddressesPtr, continueAddressesPtr, jumpOffsets, rootNode); + compiler->bytecode[compiler->count++] = (unsigned char)TOY_OP_INDEX_ASSIGN; //1 byte WARNING: enum trickery compiler->bytecode[compiler->count++] = (unsigned char)node->binary.opcode; //1 byte - return OP_EOF; + return TOY_OP_EOF; } //compensate for... yikes - if (override != OP_EOF) { + if (override != TOY_OP_EOF) { compiler->bytecode[compiler->count++] = (unsigned char)override; //1 byte } //return this if... - Opcode ret = writeCompilerWithJumps(compiler, node->binary.right, breakAddressesPtr, continueAddressesPtr, jumpOffsets, rootNode); + Toy_Opcode ret = Toy_writeCompilerWithJumps(compiler, node->binary.right, breakAddressesPtr, continueAddressesPtr, jumpOffsets, rootNode); - if (node->binary.opcode == OP_INDEX && rootNode->type == AST_NODE_BINARY && rootNode->binary.opcode == OP_VAR_ASSIGN) { //why var assign? - return OP_INDEX_ASSIGN_INTERMEDIATE; + if (node->binary.opcode == TOY_OP_INDEX && rootNode->type == TOY_AST_NODE_BINARY && rootNode->binary.opcode == TOY_OP_VAR_ASSIGN) { //why var assign? + return TOY_OP_INDEX_ASSIGN_INTERMEDIATE; } //loopy logic - if opcode == index or dot - if (node->binary.opcode == OP_INDEX || node->binary.opcode == OP_DOT) { + if (node->binary.opcode == TOY_OP_INDEX || node->binary.opcode == TOY_OP_DOT) { return node->binary.opcode; } - if (ret != OP_EOF && (node->binary.opcode == OP_VAR_ASSIGN || node->binary.opcode == OP_AND || node->binary.opcode == OP_OR || (node->binary.opcode >= OP_COMPARE_EQUAL && node->binary.opcode <= OP_INVERT))) { + if (ret != TOY_OP_EOF && (node->binary.opcode == TOY_OP_VAR_ASSIGN || node->binary.opcode == TOY_OP_AND || node->binary.opcode == TOY_OP_OR || (node->binary.opcode >= TOY_OP_COMPARE_EQUAL && node->binary.opcode <= TOY_OP_INVERT))) { compiler->bytecode[compiler->count++] = (unsigned char)ret; //1 byte - ret = OP_EOF; //untangle in this case + ret = TOY_OP_EOF; //untangle in this case } compiler->bytecode[compiler->count++] = (unsigned char)node->binary.opcode; //1 byte @@ -331,30 +331,30 @@ static Opcode writeCompilerWithJumps(Compiler* compiler, ASTNode* node, void* br } break; - case AST_NODE_TERNARY: { + case TOY_AST_NODE_TERNARY: { // TODO //process the condition - Opcode override = writeCompilerWithJumps(compiler, node->ternary.condition, breakAddressesPtr, continueAddressesPtr, jumpOffsets, rootNode); - if (override != OP_EOF) {//compensate for indexing & dot notation being screwy + Toy_Opcode override = Toy_writeCompilerWithJumps(compiler, node->ternary.condition, breakAddressesPtr, continueAddressesPtr, jumpOffsets, rootNode); + if (override != TOY_OP_EOF) {//compensate for indexing & dot notation being screwy compiler->bytecode[compiler->count++] = (unsigned char)override; //1 byte } //cache the point to insert the jump distance at - compiler->bytecode[compiler->count++] = OP_IF_FALSE_JUMP; //1 byte + compiler->bytecode[compiler->count++] = TOY_OP_IF_FALSE_JUMP; //1 byte int jumpToElse = compiler->count; compiler->count += sizeof(unsigned short); //2 bytes //write the then path - override = writeCompilerWithJumps(compiler, node->pathIf.thenPath, breakAddressesPtr, continueAddressesPtr, jumpOffsets, rootNode); - if (override != OP_EOF) {//compensate for indexing & dot notation being screwy + override = Toy_writeCompilerWithJumps(compiler, node->pathIf.thenPath, breakAddressesPtr, continueAddressesPtr, jumpOffsets, rootNode); + if (override != TOY_OP_EOF) {//compensate for indexing & dot notation being screwy compiler->bytecode[compiler->count++] = (unsigned char)override; //1 byte } int jumpToEnd = 0; //insert jump to end - compiler->bytecode[compiler->count++] = OP_JUMP; //1 byte + compiler->bytecode[compiler->count++] = TOY_OP_JUMP; //1 byte jumpToEnd = compiler->count; compiler->count += sizeof(unsigned short); //2 bytes @@ -363,8 +363,8 @@ static Opcode writeCompilerWithJumps(Compiler* compiler, ASTNode* node, void* br memcpy(compiler->bytecode + jumpToElse, &tmpVal, sizeof(tmpVal)); //2 bytes //write the else path - Opcode override2 = writeCompilerWithJumps(compiler, node->pathIf.elsePath, breakAddressesPtr, continueAddressesPtr, jumpOffsets, rootNode); - if (override2 != OP_EOF) {//compensate for indexing & dot notation being screwy + Toy_Opcode override2 = Toy_writeCompilerWithJumps(compiler, node->pathIf.elsePath, breakAddressesPtr, continueAddressesPtr, jumpOffsets, rootNode); + if (override2 != TOY_OP_EOF) {//compensate for indexing & dot notation being screwy compiler->bytecode[compiler->count++] = (unsigned char)override; //1 byte } @@ -374,65 +374,65 @@ static Opcode writeCompilerWithJumps(Compiler* compiler, ASTNode* node, void* br } break; - case AST_NODE_GROUPING: { - compiler->bytecode[compiler->count++] = (unsigned char)OP_GROUPING_BEGIN; //1 byte - Opcode override = writeCompilerWithJumps(compiler, node->grouping.child, breakAddressesPtr, continueAddressesPtr, jumpOffsets, node->grouping.child); - if (override != OP_EOF) {//compensate for indexing & dot notation being screwy + case TOY_AST_NODE_GROUPING: { + compiler->bytecode[compiler->count++] = (unsigned char)TOY_OP_GROUPING_BEGIN; //1 byte + Toy_Opcode override = Toy_writeCompilerWithJumps(compiler, node->grouping.child, breakAddressesPtr, continueAddressesPtr, jumpOffsets, node->grouping.child); + if (override != TOY_OP_EOF) {//compensate for indexing & dot notation being screwy compiler->bytecode[compiler->count++] = (unsigned char)override; //1 byte } - compiler->bytecode[compiler->count++] = (unsigned char)OP_GROUPING_END; //1 byte + compiler->bytecode[compiler->count++] = (unsigned char)TOY_OP_GROUPING_END; //1 byte } break; - case AST_NODE_BLOCK: { - compiler->bytecode[compiler->count++] = (unsigned char)OP_SCOPE_BEGIN; //1 byte + case TOY_AST_NODE_BLOCK: { + compiler->bytecode[compiler->count++] = (unsigned char)TOY_OP_SCOPE_BEGIN; //1 byte for (int i = 0; i < node->block.count; i++) { - Opcode override = writeCompilerWithJumps(compiler, &(node->block.nodes[i]), breakAddressesPtr, continueAddressesPtr, jumpOffsets, &(node->block.nodes[i])); - if (override != OP_EOF) {//compensate for indexing & dot notation being screwy + Toy_Opcode override = Toy_writeCompilerWithJumps(compiler, &(node->block.nodes[i]), breakAddressesPtr, continueAddressesPtr, jumpOffsets, &(node->block.nodes[i])); + if (override != TOY_OP_EOF) {//compensate for indexing & dot notation being screwy compiler->bytecode[compiler->count++] = (unsigned char)override; //1 byte } } - compiler->bytecode[compiler->count++] = (unsigned char)OP_SCOPE_END; //1 byte + compiler->bytecode[compiler->count++] = (unsigned char)TOY_OP_SCOPE_END; //1 byte } break; - case AST_NODE_COMPOUND: { + case TOY_AST_NODE_COMPOUND: { int index = writeNodeCompoundToCache(compiler, node); //push the node opcode to the bytecode if (index >= 256) { //push a "long" index - compiler->bytecode[compiler->count++] = OP_LITERAL_LONG; //1 byte + compiler->bytecode[compiler->count++] = TOY_OP_LITERAL_LONG; //1 byte memcpy(compiler->bytecode + compiler->count, &index, sizeof(unsigned short)); compiler->count += sizeof(unsigned short); } else { //push the index - compiler->bytecode[compiler->count++] = OP_LITERAL; //1 byte + compiler->bytecode[compiler->count++] = TOY_OP_LITERAL; //1 byte compiler->bytecode[compiler->count++] = (unsigned char)index; //1 byte } } break; - case AST_NODE_PAIR: - fprintf(stderr, ERROR "[internal] AST_NODEPAIR encountered in writeCompilerWithJumps()\n" RESET); - compiler->bytecode[compiler->count++] = OP_EOF; //1 byte + case TOY_AST_NODE_PAIR: + fprintf(stderr, TOY_CC_ERROR "[internal] TOY_AST_NODEPAIR encountered in Toy_writeCompilerWithJumps()\n" TOY_CC_RESET); + compiler->bytecode[compiler->count++] = TOY_OP_EOF; //1 byte break; - case AST_NODE_VAR_DECL: { + case TOY_AST_NODE_VAR_DECL: { //first, embed the expression (leaves it on the stack) - Opcode override = writeCompilerWithJumps(compiler, node->varDecl.expression, breakAddressesPtr, continueAddressesPtr, jumpOffsets, rootNode); - if (override != OP_EOF) {//compensate for indexing & dot notation being screwy + Toy_Opcode override = Toy_writeCompilerWithJumps(compiler, node->varDecl.expression, breakAddressesPtr, continueAddressesPtr, jumpOffsets, rootNode); + if (override != TOY_OP_EOF) {//compensate for indexing & dot notation being screwy compiler->bytecode[compiler->count++] = (unsigned char)override; //1 byte } //write each piece of the declaration to the bytecode - int identifierIndex = findLiteralIndex(&compiler->literalCache, node->varDecl.identifier); + int identifierIndex = Toy_findLiteralIndex(&compiler->literalCache, node->varDecl.identifier); if (identifierIndex < 0) { - identifierIndex = pushLiteralArray(&compiler->literalCache, node->varDecl.identifier); + identifierIndex = Toy_pushLiteralArray(&compiler->literalCache, node->varDecl.identifier); } int typeIndex = writeLiteralTypeToCache(&compiler->literalCache, node->varDecl.typeLiteral); @@ -440,7 +440,7 @@ static Opcode writeCompilerWithJumps(Compiler* compiler, ASTNode* node, void* br //embed the info into the bytecode if (identifierIndex >= 256 || typeIndex >= 256) { //push a "long" declaration - compiler->bytecode[compiler->count++] = OP_VAR_DECL_LONG; //1 byte + compiler->bytecode[compiler->count++] = TOY_OP_VAR_DECL_LONG; //1 byte *((unsigned short*)(compiler->bytecode + compiler->count)) = (unsigned short)identifierIndex; //2 bytes compiler->count += sizeof(unsigned short); @@ -450,41 +450,41 @@ static Opcode writeCompilerWithJumps(Compiler* compiler, ASTNode* node, void* br } else { //push a declaration - compiler->bytecode[compiler->count++] = OP_VAR_DECL; //1 byte + compiler->bytecode[compiler->count++] = TOY_OP_VAR_DECL; //1 byte compiler->bytecode[compiler->count++] = (unsigned char)identifierIndex; //1 byte compiler->bytecode[compiler->count++] = (unsigned char)typeIndex; //1 byte } } break; - case AST_NODE_FN_DECL: { + case TOY_AST_NODE_FN_DECL: { //run a compiler over the function - Compiler* fnCompiler = ALLOCATE(Compiler, 1); - initCompiler(fnCompiler); - writeCompiler(fnCompiler, node->fnDecl.arguments); //can be empty, but not NULL - writeCompiler(fnCompiler, node->fnDecl.returns); //can be empty, but not NULL - Opcode override = writeCompilerWithJumps(fnCompiler, node->fnDecl.block, NULL, NULL, -4, rootNode); //can be empty, but not NULL - if (override != OP_EOF) {//compensate for indexing & dot notation being screwy + Toy_Compiler* fnCompiler = TOY_ALLOCATE(Toy_Compiler, 1); + Toy_initCompiler(fnCompiler); + Toy_writeCompiler(fnCompiler, node->fnDecl.arguments); //can be empty, but not NULL + Toy_writeCompiler(fnCompiler, node->fnDecl.returns); //can be empty, but not NULL + Toy_Opcode override = Toy_writeCompilerWithJumps(fnCompiler, node->fnDecl.block, NULL, NULL, -4, rootNode); //can be empty, but not NULL + if (override != TOY_OP_EOF) {//compensate for indexing & dot notation being screwy compiler->bytecode[compiler->count++] = (unsigned char)override; //1 byte } //create the function in the literal cache (by storing the compiler object) - Literal fnLiteral = TO_FUNCTION_LITERAL(fnCompiler, 0); - fnLiteral.type = LITERAL_FUNCTION_INTERMEDIATE; //NOTE: changing type + Toy_Literal fnLiteral = TOY_TO_FUNCTION_LITERAL(fnCompiler, 0); + fnLiteral.type = TOY_LITERAL_FUNCTION_INTERMEDIATE; //NOTE: changing type //push the name - int identifierIndex = findLiteralIndex(&compiler->literalCache, node->fnDecl.identifier); + int identifierIndex = Toy_findLiteralIndex(&compiler->literalCache, node->fnDecl.identifier); if (identifierIndex < 0) { - identifierIndex = pushLiteralArray(&compiler->literalCache, node->fnDecl.identifier); + identifierIndex = Toy_pushLiteralArray(&compiler->literalCache, node->fnDecl.identifier); } //push to function (functions are never equal) - int fnIndex = pushLiteralArray(&compiler->literalCache, fnLiteral); + int fnIndex = Toy_pushLiteralArray(&compiler->literalCache, fnLiteral); //embed the info into the bytecode if (identifierIndex >= 256 || fnIndex >= 256) { //push a "long" declaration - compiler->bytecode[compiler->count++] = OP_FN_DECL_LONG; //1 byte + compiler->bytecode[compiler->count++] = TOY_OP_FN_DECL_LONG; //1 byte *((unsigned short*)(compiler->bytecode + compiler->count)) = (unsigned short)identifierIndex; //2 bytes compiler->count += sizeof(unsigned short); @@ -494,14 +494,14 @@ static Opcode writeCompilerWithJumps(Compiler* compiler, ASTNode* node, void* br } else { //push a declaration - compiler->bytecode[compiler->count++] = OP_FN_DECL; //1 byte + compiler->bytecode[compiler->count++] = TOY_OP_FN_DECL; //1 byte compiler->bytecode[compiler->count++] = (unsigned char)identifierIndex; //1 byte compiler->bytecode[compiler->count++] = (unsigned char)fnIndex; //1 byte } } break; - case AST_NODE_FN_COLLECTION: { + case TOY_AST_NODE_FN_COLLECTION: { //embed these in the bytecode... unsigned short index = (unsigned short)writeNodeCollectionToCache(compiler, node); @@ -510,58 +510,58 @@ static Opcode writeCompilerWithJumps(Compiler* compiler, ASTNode* node, void* br } break; - case AST_NODE_FN_CALL: { + case TOY_AST_NODE_FN_CALL: { //NOTE: assume the function definition/name is above us for (int i = 0; i < node->fnCall.arguments->fnCollection.count; i++) { //reverse order, to count from the beginning in the interpreter //sub-calls - if (node->fnCall.arguments->fnCollection.nodes[i].type != AST_NODE_LITERAL) { - Opcode override = writeCompilerWithJumps(compiler, &node->fnCall.arguments->fnCollection.nodes[i], breakAddressesPtr, continueAddressesPtr, jumpOffsets, rootNode); - if (override != OP_EOF) {//compensate for indexing & dot notation being screwy + if (node->fnCall.arguments->fnCollection.nodes[i].type != TOY_AST_NODE_LITERAL) { + Toy_Opcode override = Toy_writeCompilerWithJumps(compiler, &node->fnCall.arguments->fnCollection.nodes[i], breakAddressesPtr, continueAddressesPtr, jumpOffsets, rootNode); + if (override != TOY_OP_EOF) {//compensate for indexing & dot notation being screwy compiler->bytecode[compiler->count++] = (unsigned char)override; //1 byte } continue; } //write each argument to the bytecode - int argumentsIndex = findLiteralIndex(&compiler->literalCache, node->fnCall.arguments->fnCollection.nodes[i].atomic.literal); + int argumentsIndex = Toy_findLiteralIndex(&compiler->literalCache, node->fnCall.arguments->fnCollection.nodes[i].atomic.literal); if (argumentsIndex < 0) { - argumentsIndex = pushLiteralArray(&compiler->literalCache, node->fnCall.arguments->fnCollection.nodes[i].atomic.literal); + argumentsIndex = Toy_pushLiteralArray(&compiler->literalCache, node->fnCall.arguments->fnCollection.nodes[i].atomic.literal); } //push the node opcode to the bytecode if (argumentsIndex >= 256) { //push a "long" index - compiler->bytecode[compiler->count++] = OP_LITERAL_LONG; //1 byte + compiler->bytecode[compiler->count++] = TOY_OP_LITERAL_LONG; //1 byte *((unsigned short*)(compiler->bytecode + compiler->count)) = (unsigned short)argumentsIndex; //2 bytes compiler->count += sizeof(unsigned short); } else { //push the index - compiler->bytecode[compiler->count++] = OP_LITERAL; //1 byte + compiler->bytecode[compiler->count++] = TOY_OP_LITERAL; //1 byte compiler->bytecode[compiler->count++] = (unsigned char)argumentsIndex; //1 byte } } //push the argument COUNT to the top of the stack - Literal argumentsCountLiteral = TO_INTEGER_LITERAL(node->fnCall.argumentCount); //argumentCount is set elsewhere to support dot operator - int argumentsCountIndex = findLiteralIndex(&compiler->literalCache, argumentsCountLiteral); + Toy_Literal argumentsCountLiteral = TOY_TO_INTEGER_LITERAL(node->fnCall.argumentCount); //argumentCount is set elsewhere to support dot operator + int argumentsCountIndex = Toy_findLiteralIndex(&compiler->literalCache, argumentsCountLiteral); if (argumentsCountIndex < 0) { - argumentsCountIndex = pushLiteralArray(&compiler->literalCache, argumentsCountLiteral); + argumentsCountIndex = Toy_pushLiteralArray(&compiler->literalCache, argumentsCountLiteral); } - freeLiteral(argumentsCountLiteral); + Toy_freeLiteral(argumentsCountLiteral); if (argumentsCountIndex >= 256) { //push a "long" index - compiler->bytecode[compiler->count++] = OP_LITERAL_LONG; //1 byte + compiler->bytecode[compiler->count++] = TOY_OP_LITERAL_LONG; //1 byte *((unsigned short*)(compiler->bytecode + compiler->count)) = (unsigned short)argumentsCountIndex; //2 bytes compiler->count += sizeof(unsigned short); } else { //push the index - compiler->bytecode[compiler->count++] = OP_LITERAL; //1 byte + compiler->bytecode[compiler->count++] = TOY_OP_LITERAL; //1 byte compiler->bytecode[compiler->count++] = (unsigned char)argumentsCountIndex; //1 byte } @@ -570,21 +570,21 @@ static Opcode writeCompilerWithJumps(Compiler* compiler, ASTNode* node, void* br } break; - case AST_NODE_IF: { + case TOY_AST_NODE_IF: { //process the condition - Opcode override = writeCompilerWithJumps(compiler, node->pathIf.condition, breakAddressesPtr, continueAddressesPtr, jumpOffsets, rootNode); - if (override != OP_EOF) {//compensate for indexing & dot notation being screwy + Toy_Opcode override = Toy_writeCompilerWithJumps(compiler, node->pathIf.condition, breakAddressesPtr, continueAddressesPtr, jumpOffsets, rootNode); + if (override != TOY_OP_EOF) {//compensate for indexing & dot notation being screwy compiler->bytecode[compiler->count++] = (unsigned char)override; //1 byte } //cache the point to insert the jump distance at - compiler->bytecode[compiler->count++] = OP_IF_FALSE_JUMP; //1 byte + compiler->bytecode[compiler->count++] = TOY_OP_IF_FALSE_JUMP; //1 byte int jumpToElse = compiler->count; compiler->count += sizeof(unsigned short); //2 bytes //write the then path - override = writeCompilerWithJumps(compiler, node->pathIf.thenPath, breakAddressesPtr, continueAddressesPtr, jumpOffsets, rootNode); - if (override != OP_EOF) {//compensate for indexing & dot notation being screwy + override = Toy_writeCompilerWithJumps(compiler, node->pathIf.thenPath, breakAddressesPtr, continueAddressesPtr, jumpOffsets, rootNode); + if (override != TOY_OP_EOF) {//compensate for indexing & dot notation being screwy compiler->bytecode[compiler->count++] = (unsigned char)override; //1 byte } @@ -592,7 +592,7 @@ static Opcode writeCompilerWithJumps(Compiler* compiler, ASTNode* node, void* br if (node->pathIf.elsePath) { //insert jump to end - compiler->bytecode[compiler->count++] = OP_JUMP; //1 byte + compiler->bytecode[compiler->count++] = TOY_OP_JUMP; //1 byte jumpToEnd = compiler->count; compiler->count += sizeof(unsigned short); //2 bytes } @@ -603,8 +603,8 @@ static Opcode writeCompilerWithJumps(Compiler* compiler, ASTNode* node, void* br if (node->pathIf.elsePath) { //if there's an else path, write it and - Opcode override = writeCompilerWithJumps(compiler, node->pathIf.elsePath, breakAddressesPtr, continueAddressesPtr, jumpOffsets, rootNode); - if (override != OP_EOF) {//compensate for indexing & dot notation being screwy + Toy_Opcode override = Toy_writeCompilerWithJumps(compiler, node->pathIf.elsePath, breakAddressesPtr, continueAddressesPtr, jumpOffsets, rootNode); + if (override != TOY_OP_EOF) {//compensate for indexing & dot notation being screwy compiler->bytecode[compiler->count++] = (unsigned char)override; //1 byte } @@ -615,36 +615,36 @@ static Opcode writeCompilerWithJumps(Compiler* compiler, ASTNode* node, void* br } break; - case AST_NODE_WHILE: { + case TOY_AST_NODE_WHILE: { //for breaks and continues - LiteralArray breakAddresses; - LiteralArray continueAddresses; + Toy_LiteralArray breakAddresses; + Toy_LiteralArray continueAddresses; - initLiteralArray(&breakAddresses); - initLiteralArray(&continueAddresses); + Toy_initLiteralArray(&breakAddresses); + Toy_initLiteralArray(&continueAddresses); //cache the jump point unsigned short jumpToStart = compiler->count; //process the condition - Opcode override = writeCompilerWithJumps(compiler, node->pathWhile.condition, &breakAddresses, &continueAddresses, jumpOffsets, rootNode); - if (override != OP_EOF) {//compensate for indexing & dot notation being screwy + Toy_Opcode override = Toy_writeCompilerWithJumps(compiler, node->pathWhile.condition, &breakAddresses, &continueAddresses, jumpOffsets, rootNode); + if (override != TOY_OP_EOF) {//compensate for indexing & dot notation being screwy compiler->bytecode[compiler->count++] = (unsigned char)override; //1 byte } //if false, jump to end - compiler->bytecode[compiler->count++] = OP_IF_FALSE_JUMP; //1 byte + compiler->bytecode[compiler->count++] = TOY_OP_IF_FALSE_JUMP; //1 byte unsigned short jumpToEnd = compiler->count; compiler->count += sizeof(unsigned short); //2 bytes //write the body - override = writeCompilerWithJumps(compiler, node->pathWhile.thenPath, &breakAddresses, &continueAddresses, jumpOffsets, rootNode); - if (override != OP_EOF) {//compensate for indexing & dot notation being screwy + override = Toy_writeCompilerWithJumps(compiler, node->pathWhile.thenPath, &breakAddresses, &continueAddresses, jumpOffsets, rootNode); + if (override != TOY_OP_EOF) {//compensate for indexing & dot notation being screwy compiler->bytecode[compiler->count++] = (unsigned char)override; //1 byte } //jump to condition - compiler->bytecode[compiler->count++] = OP_JUMP; //1 byte + compiler->bytecode[compiler->count++] = TOY_OP_JUMP; //1 byte unsigned short tmpVal = jumpToStart + jumpOffsets; memcpy(compiler->bytecode + compiler->count, &tmpVal, sizeof(tmpVal)); compiler->count += sizeof(unsigned short); //2 bytes @@ -655,72 +655,72 @@ static Opcode writeCompilerWithJumps(Compiler* compiler, ASTNode* node, void* br //set the breaks and continues for (int i = 0; i < breakAddresses.count; i++) { - int point = AS_INTEGER(breakAddresses.literals[i]); + int point = TOY_AS_INTEGER(breakAddresses.literals[i]); tmpVal = compiler->count + jumpOffsets; memcpy(compiler->bytecode + point, &tmpVal, sizeof(tmpVal)); } for (int i = 0; i < continueAddresses.count; i++) { - int point = AS_INTEGER(continueAddresses.literals[i]); + int point = TOY_AS_INTEGER(continueAddresses.literals[i]); tmpVal = jumpToStart + jumpOffsets; memcpy(compiler->bytecode + point, &tmpVal, sizeof(tmpVal)); } //clear the stack after use - compiler->bytecode[compiler->count++] = OP_POP_STACK; //1 byte + compiler->bytecode[compiler->count++] = TOY_OP_POP_STACK; //1 byte //cleanup - freeLiteralArray(&breakAddresses); - freeLiteralArray(&continueAddresses); + Toy_freeLiteralArray(&breakAddresses); + Toy_freeLiteralArray(&continueAddresses); } break; - case AST_NODE_FOR: { + case TOY_AST_NODE_FOR: { //for breaks and continues - LiteralArray breakAddresses; - LiteralArray continueAddresses; + Toy_LiteralArray breakAddresses; + Toy_LiteralArray continueAddresses; - initLiteralArray(&breakAddresses); - initLiteralArray(&continueAddresses); + Toy_initLiteralArray(&breakAddresses); + Toy_initLiteralArray(&continueAddresses); - compiler->bytecode[compiler->count++] = OP_SCOPE_BEGIN; //1 byte + compiler->bytecode[compiler->count++] = TOY_OP_SCOPE_BEGIN; //1 byte //initial setup - Opcode override = writeCompilerWithJumps(compiler, node->pathFor.preClause, &breakAddresses, &continueAddresses, jumpOffsets, rootNode); - if (override != OP_EOF) {//compensate for indexing & dot notation being screwy + Toy_Opcode override = Toy_writeCompilerWithJumps(compiler, node->pathFor.preClause, &breakAddresses, &continueAddresses, jumpOffsets, rootNode); + if (override != TOY_OP_EOF) {//compensate for indexing & dot notation being screwy compiler->bytecode[compiler->count++] = (unsigned char)override; //1 byte } //conditional unsigned short jumpToStart = compiler->count; - override = writeCompilerWithJumps(compiler, node->pathFor.condition, &breakAddresses, &continueAddresses, jumpOffsets, rootNode); - if (override != OP_EOF) {//compensate for indexing & dot notation being screwy + override = Toy_writeCompilerWithJumps(compiler, node->pathFor.condition, &breakAddresses, &continueAddresses, jumpOffsets, rootNode); + if (override != TOY_OP_EOF) {//compensate for indexing & dot notation being screwy compiler->bytecode[compiler->count++] = (unsigned char)override; //1 byte } //if false jump to end - compiler->bytecode[compiler->count++] = OP_IF_FALSE_JUMP; //1 byte + compiler->bytecode[compiler->count++] = TOY_OP_IF_FALSE_JUMP; //1 byte unsigned short jumpToEnd = compiler->count; compiler->count += sizeof(unsigned short); //2 bytes //write the body - compiler->bytecode[compiler->count++] = OP_SCOPE_BEGIN; //1 byte - override = writeCompilerWithJumps(compiler, node->pathFor.thenPath, &breakAddresses, &continueAddresses, jumpOffsets, rootNode); - if (override != OP_EOF) {//compensate for indexing & dot notation being screwy + compiler->bytecode[compiler->count++] = TOY_OP_SCOPE_BEGIN; //1 byte + override = Toy_writeCompilerWithJumps(compiler, node->pathFor.thenPath, &breakAddresses, &continueAddresses, jumpOffsets, rootNode); + if (override != TOY_OP_EOF) {//compensate for indexing & dot notation being screwy compiler->bytecode[compiler->count++] = (unsigned char)override; //1 byte } - compiler->bytecode[compiler->count++] = OP_SCOPE_END; //1 byte + compiler->bytecode[compiler->count++] = TOY_OP_SCOPE_END; //1 byte //for-breaks actually jump to the bottom int jumpToIncrement = compiler->count; //evaluate third clause, restart - override = writeCompilerWithJumps(compiler, node->pathFor.postClause, &breakAddresses, &continueAddresses, jumpOffsets, rootNode); - if (override != OP_EOF) {//compensate for indexing & dot notation being screwy + override = Toy_writeCompilerWithJumps(compiler, node->pathFor.postClause, &breakAddresses, &continueAddresses, jumpOffsets, rootNode); + if (override != TOY_OP_EOF) {//compensate for indexing & dot notation being screwy compiler->bytecode[compiler->count++] = (unsigned char)override; //1 byte } - compiler->bytecode[compiler->count++] = OP_JUMP; //1 byte + compiler->bytecode[compiler->count++] = TOY_OP_JUMP; //1 byte unsigned short tmpVal = jumpToStart + jumpOffsets; memcpy(compiler->bytecode + compiler->count, &tmpVal, sizeof(tmpVal)); compiler->count += sizeof(unsigned short); //2 bytes @@ -728,234 +728,234 @@ static Opcode writeCompilerWithJumps(Compiler* compiler, ASTNode* node, void* br tmpVal = compiler->count + jumpOffsets; memcpy(compiler->bytecode + jumpToEnd, &tmpVal, sizeof(tmpVal)); - compiler->bytecode[compiler->count++] = OP_SCOPE_END; //1 byte + compiler->bytecode[compiler->count++] = TOY_OP_SCOPE_END; //1 byte //set the breaks and continues for (int i = 0; i < breakAddresses.count; i++) { - int point = AS_INTEGER(breakAddresses.literals[i]); + int point = TOY_AS_INTEGER(breakAddresses.literals[i]); tmpVal = compiler->count + jumpOffsets; memcpy(compiler->bytecode + point, &tmpVal, sizeof(tmpVal)); } for (int i = 0; i < continueAddresses.count; i++) { - int point = AS_INTEGER(continueAddresses.literals[i]); + int point = TOY_AS_INTEGER(continueAddresses.literals[i]); tmpVal = jumpToIncrement + jumpOffsets; memcpy(compiler->bytecode + point, &tmpVal, sizeof(tmpVal)); } //clear the stack after use - compiler->bytecode[compiler->count++] = OP_POP_STACK; //1 byte + compiler->bytecode[compiler->count++] = TOY_OP_POP_STACK; //1 byte //cleanup - freeLiteralArray(&breakAddresses); - freeLiteralArray(&continueAddresses); + Toy_freeLiteralArray(&breakAddresses); + Toy_freeLiteralArray(&continueAddresses); } break; - case AST_NODE_BREAK: { + case TOY_AST_NODE_BREAK: { if (!breakAddressesPtr) { - fprintf(stderr, ERROR "ERROR: Can't place a break statement here\n" RESET); + fprintf(stderr, TOY_CC_ERROR "TOY_CC_ERROR: Can't place a break statement here\n" TOY_CC_RESET); break; } //insert into bytecode - compiler->bytecode[compiler->count++] = OP_JUMP; //1 byte + compiler->bytecode[compiler->count++] = TOY_OP_JUMP; //1 byte //push to the breakAddresses array - Literal literal = TO_INTEGER_LITERAL(compiler->count); - pushLiteralArray((LiteralArray*)breakAddressesPtr, literal); - freeLiteral(literal); + Toy_Literal literal = TOY_TO_INTEGER_LITERAL(compiler->count); + Toy_pushLiteralArray((Toy_LiteralArray*)breakAddressesPtr, literal); + Toy_freeLiteral(literal); compiler->count += sizeof(unsigned short); //2 bytes } break; - case AST_NODE_CONTINUE: { + case TOY_AST_NODE_CONTINUE: { if (!continueAddressesPtr) { - fprintf(stderr, ERROR "ERROR: Can't place a continue statement here\n" RESET); + fprintf(stderr, TOY_CC_ERROR "TOY_CC_ERROR: Can't place a continue statement here\n" TOY_CC_RESET); break; } //insert into bytecode - compiler->bytecode[compiler->count++] = OP_JUMP; //1 byte + compiler->bytecode[compiler->count++] = TOY_OP_JUMP; //1 byte //push to the continueAddresses array - Literal literal = TO_INTEGER_LITERAL(compiler->count); - pushLiteralArray((LiteralArray*)continueAddressesPtr, literal); - freeLiteral(literal); + Toy_Literal literal = TOY_TO_INTEGER_LITERAL(compiler->count); + Toy_pushLiteralArray((Toy_LiteralArray*)continueAddressesPtr, literal); + Toy_freeLiteral(literal); compiler->count += sizeof(unsigned short); //2 bytes } break; - case AST_NODE_FN_RETURN: { + case TOY_AST_NODE_FN_RETURN: { //read each returned literal onto the stack, and return the number of values to return for (int i = 0; i < node->returns.returns->fnCollection.count; i++) { - Opcode override = writeCompilerWithJumps(compiler, &node->returns.returns->fnCollection.nodes[i], breakAddressesPtr, continueAddressesPtr, jumpOffsets, rootNode); - if (override != OP_EOF) {//compensate for indexing & dot notation being screwy + Toy_Opcode override = Toy_writeCompilerWithJumps(compiler, &node->returns.returns->fnCollection.nodes[i], breakAddressesPtr, continueAddressesPtr, jumpOffsets, rootNode); + if (override != TOY_OP_EOF) {//compensate for indexing & dot notation being screwy compiler->bytecode[compiler->count++] = (unsigned char)override; //1 byte } } //push the return, with the number of literals - compiler->bytecode[compiler->count++] = OP_FN_RETURN; //1 byte + compiler->bytecode[compiler->count++] = TOY_OP_FN_RETURN; //1 byte memcpy(compiler->bytecode + compiler->count, &node->returns.returns->fnCollection.count, sizeof(unsigned short)); compiler->count += sizeof(unsigned short); } break; - case AST_NODE_PREFIX_INCREMENT: { + case TOY_AST_NODE_PREFIX_INCREMENT: { //push the literal to the stack (twice: add + assign) writeLiteralToCompiler(compiler, node->prefixIncrement.identifier); writeLiteralToCompiler(compiler, node->prefixIncrement.identifier); //push the increment / decrement - Literal increment = TO_INTEGER_LITERAL(1); + Toy_Literal increment = TOY_TO_INTEGER_LITERAL(1); writeLiteralToCompiler(compiler, increment); //push the add opcode - compiler->bytecode[compiler->count++] = (unsigned char)OP_ADDITION; //1 byte + compiler->bytecode[compiler->count++] = (unsigned char)TOY_OP_ADDITION; //1 byte //push the assign - compiler->bytecode[compiler->count++] = (unsigned char)OP_VAR_ASSIGN; //1 byte + compiler->bytecode[compiler->count++] = (unsigned char)TOY_OP_VAR_ASSIGN; //1 byte //leave the result on the stack writeLiteralToCompiler(compiler, node->prefixIncrement.identifier); - compiler->bytecode[compiler->count++] = (unsigned char)OP_LITERAL_RAW; //1 byte + compiler->bytecode[compiler->count++] = (unsigned char)TOY_OP_LITERAL_RAW; //1 byte } break; - case AST_NODE_PREFIX_DECREMENT: { + case TOY_AST_NODE_PREFIX_DECREMENT: { //push the literal to the stack (twice: add + assign) writeLiteralToCompiler(compiler, node->prefixDecrement.identifier); writeLiteralToCompiler(compiler, node->prefixDecrement.identifier); //push the increment / decrement - Literal increment = TO_INTEGER_LITERAL(1); + Toy_Literal increment = TOY_TO_INTEGER_LITERAL(1); writeLiteralToCompiler(compiler, increment); //push the subtract opcode - compiler->bytecode[compiler->count++] = (unsigned char)OP_SUBTRACTION; //1 byte + compiler->bytecode[compiler->count++] = (unsigned char)TOY_OP_SUBTRACTION; //1 byte //push the assign - compiler->bytecode[compiler->count++] = (unsigned char)OP_VAR_ASSIGN; //1 byte + compiler->bytecode[compiler->count++] = (unsigned char)TOY_OP_VAR_ASSIGN; //1 byte //leave the result on the stack writeLiteralToCompiler(compiler, node->prefixDecrement.identifier); - compiler->bytecode[compiler->count++] = (unsigned char)OP_LITERAL_RAW; //1 byte + compiler->bytecode[compiler->count++] = (unsigned char)TOY_OP_LITERAL_RAW; //1 byte } break; - case AST_NODE_POSTFIX_INCREMENT: { + case TOY_AST_NODE_POSTFIX_INCREMENT: { //push the identifier's VALUE to the stack writeLiteralToCompiler(compiler, node->postfixIncrement.identifier); - compiler->bytecode[compiler->count++] = (unsigned char)OP_LITERAL_RAW; //1 byte + compiler->bytecode[compiler->count++] = (unsigned char)TOY_OP_LITERAL_RAW; //1 byte //push the identifier (twice: add + assign) writeLiteralToCompiler(compiler, node->postfixIncrement.identifier); writeLiteralToCompiler(compiler, node->postfixIncrement.identifier); //push the increment / decrement - Literal increment = TO_INTEGER_LITERAL(1); + Toy_Literal increment = TOY_TO_INTEGER_LITERAL(1); writeLiteralToCompiler(compiler, increment); //push the add opcode - compiler->bytecode[compiler->count++] = (unsigned char)OP_ADDITION; //1 byte + compiler->bytecode[compiler->count++] = (unsigned char)TOY_OP_ADDITION; //1 byte //push the assign - compiler->bytecode[compiler->count++] = (unsigned char)OP_VAR_ASSIGN; //1 byte + compiler->bytecode[compiler->count++] = (unsigned char)TOY_OP_VAR_ASSIGN; //1 byte } break; - case AST_NODE_POSTFIX_DECREMENT: { + case TOY_AST_NODE_POSTFIX_DECREMENT: { //push the identifier's VALUE to the stack writeLiteralToCompiler(compiler, node->postfixDecrement.identifier); - compiler->bytecode[compiler->count++] = (unsigned char)OP_LITERAL_RAW; //1 byte + compiler->bytecode[compiler->count++] = (unsigned char)TOY_OP_LITERAL_RAW; //1 byte //push the identifier (twice: add + assign) writeLiteralToCompiler(compiler, node->postfixDecrement.identifier); writeLiteralToCompiler(compiler, node->postfixDecrement.identifier); //push the increment / decrement - Literal increment = TO_INTEGER_LITERAL(1); + Toy_Literal increment = TOY_TO_INTEGER_LITERAL(1); writeLiteralToCompiler(compiler, increment); //push the subtract opcode - compiler->bytecode[compiler->count++] = (unsigned char)OP_SUBTRACTION; //1 byte + compiler->bytecode[compiler->count++] = (unsigned char)TOY_OP_SUBTRACTION; //1 byte //push the assign - compiler->bytecode[compiler->count++] = (unsigned char)OP_VAR_ASSIGN; //1 byte + compiler->bytecode[compiler->count++] = (unsigned char)TOY_OP_VAR_ASSIGN; //1 byte } break; - case AST_NODE_IMPORT: { + case TOY_AST_NODE_IMPORT: { //push the identifier, and the alias writeLiteralToCompiler(compiler, node->import.identifier); writeLiteralToCompiler(compiler, node->import.alias); //push the import opcode - compiler->bytecode[compiler->count++] = (unsigned char)OP_IMPORT; //1 byte + compiler->bytecode[compiler->count++] = (unsigned char)TOY_OP_IMPORT; //1 byte } break; - case AST_NODE_INDEX: { + case TOY_AST_NODE_INDEX: { //pass to the child nodes, then embed the opcode //first if (!node->index.first) { - writeLiteralToCompiler(compiler, TO_NULL_LITERAL); + writeLiteralToCompiler(compiler, TOY_TO_NULL_LITERAL); } else { - Opcode override = writeCompilerWithJumps(compiler, node->index.first, breakAddressesPtr, continueAddressesPtr, jumpOffsets, rootNode); - if (override != OP_EOF) {//compensate for indexing & dot notation being screwy + Toy_Opcode override = Toy_writeCompilerWithJumps(compiler, node->index.first, breakAddressesPtr, continueAddressesPtr, jumpOffsets, rootNode); + if (override != TOY_OP_EOF) {//compensate for indexing & dot notation being screwy compiler->bytecode[compiler->count++] = (unsigned char)override; //1 byte } } //second if (!node->index.second) { - writeLiteralToCompiler(compiler, TO_NULL_LITERAL); + writeLiteralToCompiler(compiler, TOY_TO_NULL_LITERAL); } else { - Opcode override = writeCompilerWithJumps(compiler, node->index.second, breakAddressesPtr, continueAddressesPtr, jumpOffsets, rootNode); - if (override != OP_EOF) {//compensate for indexing & dot notation being screwy + Toy_Opcode override = Toy_writeCompilerWithJumps(compiler, node->index.second, breakAddressesPtr, continueAddressesPtr, jumpOffsets, rootNode); + if (override != TOY_OP_EOF) {//compensate for indexing & dot notation being screwy compiler->bytecode[compiler->count++] = (unsigned char)override; //1 byte } } //third if (!node->index.third) { - writeLiteralToCompiler(compiler, TO_NULL_LITERAL); + writeLiteralToCompiler(compiler, TOY_TO_NULL_LITERAL); } else { - Opcode override = writeCompilerWithJumps(compiler, node->index.third, breakAddressesPtr, continueAddressesPtr, jumpOffsets, rootNode); - if (override != OP_EOF) {//compensate for indexing & dot notation being screwy + Toy_Opcode override = Toy_writeCompilerWithJumps(compiler, node->index.third, breakAddressesPtr, continueAddressesPtr, jumpOffsets, rootNode); + if (override != TOY_OP_EOF) {//compensate for indexing & dot notation being screwy compiler->bytecode[compiler->count++] = (unsigned char)override; //1 byte } } // compiler->bytecode[compiler->count++] = (unsigned char)OP_INDEX; //1 byte - return OP_INDEX_ASSIGN; //override binary's instruction IF it is assign + return TOY_OP_INDEX_ASSIGN; //override binary's instruction IF it is assign } break; } - return OP_EOF; + return TOY_OP_EOF; } -void writeCompiler(Compiler* compiler, ASTNode* node) { - Opcode op = writeCompilerWithJumps(compiler, node, NULL, NULL, 0, node); //pass in "node" as the root node +void Toy_writeCompiler(Toy_Compiler* compiler, Toy_ASTNode* node) { + Toy_Opcode op = Toy_writeCompilerWithJumps(compiler, node, NULL, NULL, 0, node); //pass in "node" as the root node - if (op != OP_EOF) {//compensate for indexing & dot notation being screwy + if (op != TOY_OP_EOF) {//compensate for indexing & dot notation being screwy compiler->bytecode[compiler->count++] = (unsigned char)op; //1 byte } } -void freeCompiler(Compiler* compiler) { - freeLiteralArray(&compiler->literalCache); - FREE_ARRAY(unsigned char, compiler->bytecode, compiler->capacity); +void Toy_freeCompiler(Toy_Compiler* compiler) { + Toy_freeLiteralArray(&compiler->literalCache); + TOY_FREE_ARRAY(unsigned char, compiler->bytecode, compiler->capacity); compiler->bytecode = NULL; compiler->capacity = 0; compiler->count = 0; @@ -965,15 +965,15 @@ static void emitByte(unsigned char** collationPtr, int* capacityPtr, int* countP //grow the array if (*countPtr + 1 > *capacityPtr) { int oldCapacity = *capacityPtr; - *capacityPtr = GROW_CAPACITY(*capacityPtr); - *collationPtr = GROW_ARRAY(unsigned char, *collationPtr, oldCapacity, *capacityPtr); + *capacityPtr = TOY_GROW_CAPACITY(*capacityPtr); + *collationPtr = TOY_GROW_ARRAY(unsigned char, *collationPtr, oldCapacity, *capacityPtr); } //append to the collation (*collationPtr)[(*countPtr)++] = byte; } -static void emitShort(unsigned char** collationPtr, int* capacityPtr, int* countPtr, unsigned short bytes) { +static void Toy_emitShort(unsigned char** collationPtr, int* capacityPtr, int* countPtr, unsigned short bytes) { char* ptr = (char*)&bytes; emitByte(collationPtr, capacityPtr, countPtr, *ptr); @@ -1006,16 +1006,16 @@ static void emitFloat(unsigned char** collationPtr, int* capacityPtr, int* count } //return the result -static unsigned char* collateCompilerHeaderOpt(Compiler* compiler, int* size, bool embedHeader) { - int capacity = GROW_CAPACITY(0); +static unsigned char* collateCompilerHeaderOpt(Toy_Compiler* compiler, int* size, bool embedHeader) { + int capacity = TOY_GROW_CAPACITY(0); int count = 0; - unsigned char* collation = ALLOCATE(unsigned char, capacity); + unsigned char* collation = TOY_ALLOCATE(unsigned char, capacity); //for the function-section at the end of the main-collation int fnIndex = 0; //counts up for each fn - int fnCapacity = GROW_CAPACITY(0); + int fnCapacity = TOY_GROW_CAPACITY(0); int fnCount = 0; - unsigned char* fnCollation = ALLOCATE(unsigned char, fnCapacity); + unsigned char* fnCollation = TOY_ALLOCATE(unsigned char, fnCapacity); if (embedHeader) { //embed the header with version information @@ -1027,18 +1027,18 @@ static unsigned char* collateCompilerHeaderOpt(Compiler* compiler, int* size, bo if ((int)strlen(TOY_VERSION_BUILD) + count + 1 > capacity) { int oldCapacity = capacity; capacity = strlen(TOY_VERSION_BUILD) + count + 1; //full header size - collation = GROW_ARRAY(unsigned char, collation, oldCapacity, capacity); + collation = TOY_GROW_ARRAY(unsigned char, collation, oldCapacity, capacity); } memcpy(&collation[count], TOY_VERSION_BUILD, strlen(TOY_VERSION_BUILD)); count += strlen(TOY_VERSION_BUILD); collation[count++] = '\0'; //terminate the build string - emitByte(&collation, &capacity, &count, OP_SECTION_END); //terminate header + emitByte(&collation, &capacity, &count, TOY_OP_SECTION_END); //terminate header } //embed the data section (first short is the number of literals) - emitShort(&collation, &capacity, &count, compiler->literalCache.count); + Toy_emitShort(&collation, &capacity, &count, compiler->literalCache.count); //emit each literal by type for (int i = 0; i < compiler->literalCache.count; i++) { @@ -1047,189 +1047,189 @@ static unsigned char* collateCompilerHeaderOpt(Compiler* compiler, int* size, bo //literal type, followed by literal value switch(compiler->literalCache.literals[i].type) { - case LITERAL_NULL: - emitByte(&collation, &capacity, &count, LITERAL_NULL); + case TOY_LITERAL_NULL: + emitByte(&collation, &capacity, &count, TOY_LITERAL_NULL); //null has no following value break; - case LITERAL_BOOLEAN: - emitByte(&collation, &capacity, &count, LITERAL_BOOLEAN); - emitByte(&collation, &capacity, &count, AS_BOOLEAN(compiler->literalCache.literals[i])); + case TOY_LITERAL_BOOLEAN: + emitByte(&collation, &capacity, &count, TOY_LITERAL_BOOLEAN); + emitByte(&collation, &capacity, &count, TOY_AS_BOOLEAN(compiler->literalCache.literals[i])); break; - case LITERAL_INTEGER: - emitByte(&collation, &capacity, &count, LITERAL_INTEGER); - emitInt(&collation, &capacity, &count, AS_INTEGER(compiler->literalCache.literals[i])); + case TOY_LITERAL_INTEGER: + emitByte(&collation, &capacity, &count, TOY_LITERAL_INTEGER); + emitInt(&collation, &capacity, &count, TOY_AS_INTEGER(compiler->literalCache.literals[i])); break; - case LITERAL_FLOAT: - emitByte(&collation, &capacity, &count, LITERAL_FLOAT); - emitFloat(&collation, &capacity, &count, AS_FLOAT(compiler->literalCache.literals[i])); + case TOY_LITERAL_FLOAT: + emitByte(&collation, &capacity, &count, TOY_LITERAL_FLOAT); + emitFloat(&collation, &capacity, &count, TOY_AS_FLOAT(compiler->literalCache.literals[i])); break; - case LITERAL_STRING: { - emitByte(&collation, &capacity, &count, LITERAL_STRING); + case TOY_LITERAL_STRING: { + emitByte(&collation, &capacity, &count, TOY_LITERAL_STRING); - Literal str = compiler->literalCache.literals[i]; + Toy_Literal str = compiler->literalCache.literals[i]; - for (int c = 0; c < AS_STRING(str)->length; c++) { - emitByte(&collation, &capacity, &count, toCString(AS_STRING(str))[c]); + for (int c = 0; c < TOY_AS_STRING(str)->length; c++) { + emitByte(&collation, &capacity, &count, Toy_toCString(TOY_AS_STRING(str))[c]); } emitByte(&collation, &capacity, &count, '\0'); //terminate the string } break; - case LITERAL_ARRAY: { - emitByte(&collation, &capacity, &count, LITERAL_ARRAY); + case TOY_LITERAL_ARRAY: { + emitByte(&collation, &capacity, &count, TOY_LITERAL_ARRAY); - LiteralArray* ptr = AS_ARRAY(compiler->literalCache.literals[i]); + Toy_LiteralArray* ptr = TOY_AS_ARRAY(compiler->literalCache.literals[i]); //length of the array, as a short - emitShort(&collation, &capacity, &count, ptr->count); + Toy_emitShort(&collation, &capacity, &count, ptr->count); //each element of the array for (int i = 0; i < ptr->count; i++) { - emitShort(&collation, &capacity, &count, (unsigned short)AS_INTEGER(ptr->literals[i])); //shorts representing the indexes of the values + Toy_emitShort(&collation, &capacity, &count, (unsigned short)TOY_AS_INTEGER(ptr->literals[i])); //shorts representing the indexes of the values } } break; - case LITERAL_DICTIONARY_INTERMEDIATE: { - emitByte(&collation, &capacity, &count, LITERAL_DICTIONARY); + case TOY_LITERAL_DICTIONARY_INTERMEDIATE: { + emitByte(&collation, &capacity, &count, TOY_LITERAL_DICTIONARY); - LiteralArray* ptr = AS_ARRAY(compiler->literalCache.literals[i]); //used an array for storage above + Toy_LiteralArray* ptr = TOY_AS_ARRAY(compiler->literalCache.literals[i]); //used an array for storage above //length of the array, as a short - emitShort(&collation, &capacity, &count, ptr->count); //count is the array size, NOT the dictionary size + Toy_emitShort(&collation, &capacity, &count, ptr->count); //count is the array size, NOT the dictionary size //each element of the array for (int i = 0; i < ptr->count; i++) { - emitShort(&collation, &capacity, &count, (unsigned short)AS_INTEGER(ptr->literals[i])); //shorts representing the indexes of the values + Toy_emitShort(&collation, &capacity, &count, (unsigned short)TOY_AS_INTEGER(ptr->literals[i])); //shorts representing the indexes of the values } } break; - case LITERAL_FUNCTION_INTERMEDIATE: { + case TOY_LITERAL_FUNCTION_INTERMEDIATE: { //extract the compiler - Literal fn = compiler->literalCache.literals[i]; - void* fnCompiler = AS_FUNCTION(fn).bytecode; //store the compiler here for now + Toy_Literal fn = compiler->literalCache.literals[i]; + void* fnCompiler = TOY_AS_FUNCTION(fn).bytecode; //store the compiler here for now //collate the function into bytecode (without header) int size = 0; - unsigned char* bytes = collateCompilerHeaderOpt((Compiler*)fnCompiler, &size, false); + unsigned char* bytes = collateCompilerHeaderOpt((Toy_Compiler*)fnCompiler, &size, false); //emit how long this section is, +1 for ending mark - emitShort(&fnCollation, &fnCapacity, &fnCount, (unsigned short)size + 1); + Toy_emitShort(&fnCollation, &fnCapacity, &fnCount, (unsigned short)size + 1); //write the fn to the fn collation for (int i = 0; i < size; i++) { emitByte(&fnCollation, &fnCapacity, &fnCount, bytes[i]); } - emitByte(&fnCollation, &fnCapacity, &fnCount, OP_FN_END); //for marking the correct end-point of the function + emitByte(&fnCollation, &fnCapacity, &fnCount, TOY_OP_FN_END); //for marking the correct end-point of the function //embed the reference to the function implementation into the current collation (to be extracted later) - emitByte(&collation, &capacity, &count, LITERAL_FUNCTION); - emitShort(&collation, &capacity, &count, (unsigned short)(fnIndex++)); + emitByte(&collation, &capacity, &count, TOY_LITERAL_FUNCTION); + Toy_emitShort(&collation, &capacity, &count, (unsigned short)(fnIndex++)); - freeCompiler((Compiler*)fnCompiler); - FREE(compiler, fnCompiler); - FREE_ARRAY(unsigned char, bytes, size); + Toy_freeCompiler((Toy_Compiler*)fnCompiler); + TOY_FREE(compiler, fnCompiler); + TOY_FREE_ARRAY(unsigned char, bytes, size); } break; - case LITERAL_IDENTIFIER: { - emitByte(&collation, &capacity, &count, LITERAL_IDENTIFIER); + case TOY_LITERAL_IDENTIFIER: { + emitByte(&collation, &capacity, &count, TOY_LITERAL_IDENTIFIER); - Literal identifier = compiler->literalCache.literals[i]; + Toy_Literal identifier = compiler->literalCache.literals[i]; - for (int c = 0; c < AS_IDENTIFIER(identifier)->length; c++) { - emitByte(&collation, &capacity, &count, toCString(AS_IDENTIFIER(identifier))[c]); + for (int c = 0; c < TOY_AS_IDENTIFIER(identifier)->length; c++) { + emitByte(&collation, &capacity, &count, Toy_toCString(TOY_AS_IDENTIFIER(identifier))[c]); } emitByte(&collation, &capacity, &count, '\0'); //terminate the string } break; - case LITERAL_TYPE: { + case TOY_LITERAL_TYPE: { //push a raw type - emitByte(&collation, &capacity, &count, LITERAL_TYPE); + emitByte(&collation, &capacity, &count, TOY_LITERAL_TYPE); - Literal typeLiteral = compiler->literalCache.literals[i]; + Toy_Literal typeLiteral = compiler->literalCache.literals[i]; //what type this literal represents - emitByte(&collation, &capacity, &count, AS_TYPE(typeLiteral).typeOf); - emitByte(&collation, &capacity, &count, AS_TYPE(typeLiteral).constant); //if it's constant + emitByte(&collation, &capacity, &count, TOY_AS_TYPE(typeLiteral).typeOf); + emitByte(&collation, &capacity, &count, TOY_AS_TYPE(typeLiteral).constant); //if it's constant } break; - case LITERAL_TYPE_INTERMEDIATE: { - emitByte(&collation, &capacity, &count, LITERAL_TYPE_INTERMEDIATE); + case TOY_LITERAL_TYPE_INTERMEDIATE: { + emitByte(&collation, &capacity, &count, TOY_LITERAL_TYPE_INTERMEDIATE); - LiteralArray* ptr = AS_ARRAY(compiler->literalCache.literals[i]); //used an array for storage above + Toy_LiteralArray* ptr = TOY_AS_ARRAY(compiler->literalCache.literals[i]); //used an array for storage above //the base literal - Literal typeLiteral = copyLiteral(ptr->literals[0]); + Toy_Literal typeLiteral = Toy_copyLiteral(ptr->literals[0]); //what type this literal represents - emitByte(&collation, &capacity, &count, AS_TYPE(typeLiteral).typeOf); - emitByte(&collation, &capacity, &count, AS_TYPE(typeLiteral).constant); //if it's constant + emitByte(&collation, &capacity, &count, TOY_AS_TYPE(typeLiteral).typeOf); + emitByte(&collation, &capacity, &count, TOY_AS_TYPE(typeLiteral).constant); //if it's constant //each element of the array, If they exist, representing sub-types already in the cache - if (AS_TYPE(typeLiteral).typeOf == LITERAL_ARRAY || AS_TYPE(typeLiteral).typeOf == LITERAL_DICTIONARY) { + if (TOY_AS_TYPE(typeLiteral).typeOf == TOY_LITERAL_ARRAY || TOY_AS_TYPE(typeLiteral).typeOf == TOY_LITERAL_DICTIONARY) { //the type will represent how many to expect in the array for (int i = 1; i < ptr->count; i++) { - emitShort(&collation, &capacity, &count, (unsigned short)AS_INTEGER(ptr->literals[i])); //shorts representing the indexes of the types + Toy_emitShort(&collation, &capacity, &count, (unsigned short)TOY_AS_INTEGER(ptr->literals[i])); //shorts representing the indexes of the types } } - freeLiteral(typeLiteral); + Toy_freeLiteral(typeLiteral); } break; - case LITERAL_INDEX_BLANK: - emitByte(&collation, &capacity, &count, LITERAL_INDEX_BLANK); + case TOY_LITERAL_INDEX_BLANK: + emitByte(&collation, &capacity, &count, TOY_LITERAL_INDEX_BLANK); //blank has no following value break; default: - fprintf(stderr, ERROR "[internal] Unknown literal type encountered within literal cache: %d\n" RESET, compiler->literalCache.literals[i].type); + fprintf(stderr, TOY_CC_ERROR "[internal] Unknown literal type encountered within literal cache: %d\n" TOY_CC_RESET, compiler->literalCache.literals[i].type); return NULL; } } - emitByte(&collation, &capacity, &count, OP_SECTION_END); //terminate data + emitByte(&collation, &capacity, &count, TOY_OP_SECTION_END); //terminate data //embed the function section (beginning with function count, size) - emitShort(&collation, &capacity, &count, fnIndex); - emitShort(&collation, &capacity, &count, fnCount); + Toy_emitShort(&collation, &capacity, &count, fnIndex); + Toy_emitShort(&collation, &capacity, &count, fnCount); for (int i = 0; i < fnCount; i++) { emitByte(&collation, &capacity, &count, fnCollation[i]); } - emitByte(&collation, &capacity, &count, OP_SECTION_END); //terminate function section + emitByte(&collation, &capacity, &count, TOY_OP_SECTION_END); //terminate function section - FREE_ARRAY(unsigned char, fnCollation, fnCapacity); //clear the function stuff + TOY_FREE_ARRAY(unsigned char, fnCollation, fnCapacity); //clear the function stuff //code section for (int i = 0; i < compiler->count; i++) { emitByte(&collation, &capacity, &count, compiler->bytecode[i]); } - emitByte(&collation, &capacity, &count, OP_SECTION_END); //terminate code + emitByte(&collation, &capacity, &count, TOY_OP_SECTION_END); //terminate code - emitByte(&collation, &capacity, &count, OP_EOF); //terminate bytecode + emitByte(&collation, &capacity, &count, TOY_OP_EOF); //terminate bytecode //finalize - collation = SHRINK_ARRAY(unsigned char, collation, capacity, count); + collation = TOY_SHRINK_ARRAY(unsigned char, collation, capacity, count); *size = count; return collation; } -unsigned char* collateCompiler(Compiler* compiler, int* size) { +unsigned char* Toy_collateCompiler(Toy_Compiler* compiler, int* size) { return collateCompilerHeaderOpt(compiler, size, true); } diff --git a/source/toy_compiler.h b/source/toy_compiler.h index d0f7fa5..c206d5b 100644 --- a/source/toy_compiler.h +++ b/source/toy_compiler.h @@ -1,21 +1,21 @@ #pragma once #include "toy_common.h" -#include "opcodes.h" -#include "ast_node.h" -#include "literal_array.h" +#include "toy_opcodes.h" +#include "toy_ast_node.h" +#include "toy_literal_array.h" //the compiler takes the nodes, and turns them into sequential chunks of bytecode, saving literals to an external array -typedef struct Compiler { - LiteralArray literalCache; +typedef struct Toy_Compiler { + Toy_LiteralArray literalCache; unsigned char* bytecode; int capacity; int count; -} Compiler; +} Toy_Compiler; -TOY_API void initCompiler(Compiler* compiler); -TOY_API void writeCompiler(Compiler* compiler, ASTNode* node); -TOY_API void freeCompiler(Compiler* compiler); +TOY_API void Toy_initCompiler(Toy_Compiler* compiler); +TOY_API void Toy_writeCompiler(Toy_Compiler* compiler, Toy_ASTNode* node); +TOY_API void Toy_freeCompiler(Toy_Compiler* compiler); //embed the header, data section, code section, function section, etc. -TOY_API unsigned char* collateCompiler(Compiler* compiler, int* size); +TOY_API unsigned char* Toy_collateCompiler(Toy_Compiler* compiler, int* size); diff --git a/source/toy_console_colors.h b/source/toy_console_colors.h index ae7bfa8..400934a 100644 --- a/source/toy_console_colors.h +++ b/source/toy_console_colors.h @@ -3,28 +3,28 @@ //NOTE: you need both font AND background for these to work //fonts color -#define FONT_BLACK "\033[30;" -#define FONT_RED "\033[31;" -#define FONT_GREEN "\033[32;" -#define FONT_YELLOW "\033[33;" -#define FONT_BLUE "\033[34;" -#define FONT_PURPLE "\033[35;" -#define FONT_DGREEN "\033[6;" -#define FONT_WHITE "\033[7;" -#define FONT_CYAN "\x1b[36m" +#define TOY_CC_FONT_BLACK "\033[30;" +#define TOY_CC_FONT_RED "\033[31;" +#define TOY_CC_FONT_GREEN "\033[32;" +#define TOY_CC_FONT_YELLOW "\033[33;" +#define TOY_CC_FONT_BLUE "\033[34;" +#define TOY_CC_FONT_PURPLE "\033[35;" +#define TOY_CC_FONT_DGREEN "\033[6;" +#define TOY_CC_FONT_WHITE "\033[7;" +#define TOY_CC_FONT_CYAN "\x1b[36m" //background color -#define BACK_BLACK "40m" -#define BACK_RED "41m" -#define BACK_GREEN "42m" -#define BACK_YELLOW "43m" -#define BACK_BLUE "44m" -#define BACK_PURPLE "45m" -#define BACK_DGREEN "46m" -#define BACK_WHITE "47m" +#define TOY_CC_BACK_BLACK "40m" +#define TOY_CC_BACK_RED "41m" +#define TOY_CC_BACK_GREEN "42m" +#define TOY_CC_BACK_YELLOW "43m" +#define TOY_CC_BACK_BLUE "44m" +#define TOY_CC_BACK_PURPLE "45m" +#define TOY_CC_BACK_DGREEN "46m" +#define TOY_CC_BACK_WHITE "47m" //useful -#define NOTICE FONT_GREEN BACK_BLACK -#define WARN FONT_YELLOW BACK_BLACK -#define ERROR FONT_RED BACK_BLACK -#define RESET "\033[0m" +#define TOY_CC_NOTICE TOY_CC_FONT_GREEN TOY_CC_BACK_BLACK +#define TOY_CC_WARN TOY_CC_FONT_YELLOW TOY_CC_BACK_BLACK +#define TOY_CC_ERROR TOY_CC_FONT_RED TOY_CC_BACK_BLACK +#define TOY_CC_RESET "\033[0m" diff --git a/source/toy_interpreter.c b/source/toy_interpreter.c index 06d4ad5..3c32d82 100644 --- a/source/toy_interpreter.c +++ b/source/toy_interpreter.c @@ -1,12 +1,12 @@ -#include "interpreter.h" -#include "console_colors.h" +#include "toy_interpreter.h" +#include "toy_console_colors.h" #include "toy_common.h" -#include "memory.h" -#include "keyword_types.h" -#include "opcodes.h" +#include "toy_memory.h" +#include "toy_keyword_types.h" +#include "toy_opcodes.h" -#include "builtin.h" +#include "toy_builtin.h" #include #include @@ -17,158 +17,158 @@ static void printWrapper(const char* output) { } static void assertWrapper(const char* output) { - fprintf(stderr, ERROR "Assertion failure: "); + fprintf(stderr, TOY_CC_ERROR "Assertion failure: "); fprintf(stderr, "%s", output); - fprintf(stderr, "\n" RESET); //default new line + fprintf(stderr, "\n" TOY_CC_RESET); //default new line } static void errorWrapper(const char* output) { - fprintf(stderr, ERROR "%s" RESET, output); //no newline + fprintf(stderr, TOY_CC_ERROR "%s" TOY_CC_RESET, output); //no newline } -bool injectNativeFn(Interpreter* interpreter, char* name, NativeFn func) { +bool Toy_injectNativeFn(Toy_Interpreter* interpreter, char* name, Toy_NativeFn func) { //reject reserved words - if (findTypeByKeyword(name) != TOKEN_EOF) { + if (Toy_findTypeByKeyword(name) != TOY_TOKEN_EOF) { interpreter->errorOutput("Can't override an existing keyword\n"); return false; } int identifierLength = strlen(name); - Literal identifier = TO_IDENTIFIER_LITERAL(createRefStringLength(name, identifierLength)); + Toy_Literal identifier = TOY_TO_IDENTIFIER_LITERAL(Toy_createRefStringLength(name, identifierLength)); //make sure the name isn't taken - if (existsLiteralDictionary(&interpreter->scope->variables, identifier)) { + if (Toy_existsLiteralDictionary(&interpreter->scope->variables, identifier)) { interpreter->errorOutput("Can't override an existing variable\n"); return false; } - Literal fn = TO_FUNCTION_LITERAL((void*)func, 0); - fn.type = LITERAL_FUNCTION_NATIVE; + Toy_Literal fn = TOY_TO_FUNCTION_LITERAL((void*)func, 0); + fn.type = TOY_LITERAL_FUNCTION_NATIVE; - Literal type = TO_TYPE_LITERAL(fn.type, true); + Toy_Literal type = TOY_TO_TYPE_LITERAL(fn.type, true); - setLiteralDictionary(&interpreter->scope->variables, identifier, fn); - setLiteralDictionary(&interpreter->scope->types, identifier, type); + Toy_setLiteralDictionary(&interpreter->scope->variables, identifier, fn); + Toy_setLiteralDictionary(&interpreter->scope->types, identifier, type); - freeLiteral(identifier); - freeLiteral(type); + Toy_freeLiteral(identifier); + Toy_freeLiteral(type); return true; } -bool injectNativeHook(Interpreter* interpreter, char* name, HookFn hook) { +bool Toy_injectNativeHook(Toy_Interpreter* interpreter, char* name, Toy_HookFn hook) { //reject reserved words - if (findTypeByKeyword(name) != TOKEN_EOF) { + if (Toy_findTypeByKeyword(name) != TOY_TOKEN_EOF) { interpreter->errorOutput("Can't inject a hook on an existing keyword\n"); return false; } int identifierLength = strlen(name); - Literal identifier = TO_IDENTIFIER_LITERAL(createRefStringLength(name, identifierLength)); + Toy_Literal identifier = TOY_TO_IDENTIFIER_LITERAL(Toy_createRefStringLength(name, identifierLength)); //make sure the name isn't taken - if (existsLiteralDictionary(interpreter->hooks, identifier)) { + if (Toy_existsLiteralDictionary(interpreter->hooks, identifier)) { interpreter->errorOutput("Can't override an existing hook\n"); return false; } - Literal fn = TO_FUNCTION_LITERAL((void*)hook, 0); - fn.type = LITERAL_FUNCTION_NATIVE; + Toy_Literal fn = TOY_TO_FUNCTION_LITERAL((void*)hook, 0); + fn.type = TOY_LITERAL_FUNCTION_NATIVE; - setLiteralDictionary(interpreter->hooks, identifier, fn); + Toy_setLiteralDictionary(interpreter->hooks, identifier, fn); - freeLiteral(identifier); + Toy_freeLiteral(identifier); return true; } -void parseCompoundToPureValues(Interpreter* interpreter, Literal* literalPtr) { - if (IS_IDENTIFIER(*literalPtr)) { - parseIdentifierToValue(interpreter, literalPtr); +void Toy_parseCompoundToPureValues(Toy_Interpreter* interpreter, Toy_Literal* literalPtr) { + if (TOY_IS_IDENTIFIER(*literalPtr)) { + Toy_parseIdentifierToValue(interpreter, literalPtr); } //parse out an array - if (IS_ARRAY(*literalPtr)) { - for (int i = 0; i < AS_ARRAY(*literalPtr)->count; i++) { - Literal index = TO_INTEGER_LITERAL(i); - Literal entry = getLiteralArray(AS_ARRAY(*literalPtr), index); + if (TOY_IS_ARRAY(*literalPtr)) { + for (int i = 0; i < TOY_AS_ARRAY(*literalPtr)->count; i++) { + Toy_Literal index = TOY_TO_INTEGER_LITERAL(i); + Toy_Literal entry = Toy_getLiteralArray(TOY_AS_ARRAY(*literalPtr), index); - if (IS_IDENTIFIER( entry )) { - Literal idn = entry; - parseCompoundToPureValues(interpreter, &entry); + if (TOY_IS_IDENTIFIER( entry )) { + Toy_Literal idn = entry; + Toy_parseCompoundToPureValues(interpreter, &entry); - setLiteralArray(AS_ARRAY(*literalPtr), index, entry); + Toy_setLiteralArray(TOY_AS_ARRAY(*literalPtr), index, entry); - freeLiteral(idn); + Toy_freeLiteral(idn); } - freeLiteral(index); - freeLiteral(entry); + Toy_freeLiteral(index); + Toy_freeLiteral(entry); } } //parse out a dictionary - if (IS_DICTIONARY(*literalPtr)) { - LiteralDictionary* ret = ALLOCATE(LiteralDictionary, 1); - initLiteralDictionary(ret); + if (TOY_IS_DICTIONARY(*literalPtr)) { + Toy_LiteralDictionary* ret = TOY_ALLOCATE(Toy_LiteralDictionary, 1); + Toy_initLiteralDictionary(ret); - for (int i = 0; i < AS_DICTIONARY(*literalPtr)->capacity; i++) { - if ( IS_NULL(AS_DICTIONARY(*literalPtr)->entries[i].key) ) { + for (int i = 0; i < TOY_AS_DICTIONARY(*literalPtr)->capacity; i++) { + if ( TOY_IS_NULL(TOY_AS_DICTIONARY(*literalPtr)->entries[i].key) ) { continue; } - Literal key = TO_NULL_LITERAL; - Literal value = TO_NULL_LITERAL; + Toy_Literal key = TOY_TO_NULL_LITERAL; + Toy_Literal value = TOY_TO_NULL_LITERAL; - key = copyLiteral(AS_DICTIONARY(*literalPtr)->entries[i].key); - value = copyLiteral(AS_DICTIONARY(*literalPtr)->entries[i].value); + key = Toy_copyLiteral(TOY_AS_DICTIONARY(*literalPtr)->entries[i].key); + value = Toy_copyLiteral(TOY_AS_DICTIONARY(*literalPtr)->entries[i].value); // - if (IS_IDENTIFIER( key ) || IS_IDENTIFIER(value)) { - parseCompoundToPureValues(interpreter, &key); - parseCompoundToPureValues(interpreter, &value); + if (TOY_IS_IDENTIFIER( key ) || TOY_IS_IDENTIFIER(value)) { + Toy_parseCompoundToPureValues(interpreter, &key); + Toy_parseCompoundToPureValues(interpreter, &value); } - setLiteralDictionary(ret, key, value); + Toy_setLiteralDictionary(ret, key, value); // - freeLiteral(key); - freeLiteral(value); + Toy_freeLiteral(key); + Toy_freeLiteral(value); } - freeLiteral(*literalPtr); - *literalPtr = TO_DICTIONARY_LITERAL(ret); + Toy_freeLiteral(*literalPtr); + *literalPtr = TOY_TO_DICTIONARY_LITERAL(ret); } } -bool parseIdentifierToValue(Interpreter* interpreter, Literal* literalPtr) { +bool Toy_parseIdentifierToValue(Toy_Interpreter* interpreter, Toy_Literal* literalPtr) { //this converts identifiers to values - if (IS_IDENTIFIER(*literalPtr)) { - if (!getScopeVariable(interpreter->scope, *literalPtr, literalPtr)) { + if (TOY_IS_IDENTIFIER(*literalPtr)) { + if (!Toy_getScopeVariable(interpreter->scope, *literalPtr, literalPtr)) { interpreter->errorOutput("Undeclared variable "); - printLiteralCustom(*literalPtr, interpreter->errorOutput); + Toy_printLiteralCustom(*literalPtr, interpreter->errorOutput); interpreter->errorOutput("\n"); return false; } } - if (IS_ARRAY(*literalPtr) || IS_DICTIONARY(*literalPtr)) { - parseCompoundToPureValues(interpreter, literalPtr); + if (TOY_IS_ARRAY(*literalPtr) || TOY_IS_DICTIONARY(*literalPtr)) { + Toy_parseCompoundToPureValues(interpreter, literalPtr); } return true; } //utilities for the host program -void setInterpreterPrint(Interpreter* interpreter, PrintFn printOutput) { +void Toy_setInterpreterPrint(Toy_Interpreter* interpreter, Toy_PrintFn printOutput) { interpreter->printOutput = printOutput; } -void setInterpreterAssert(Interpreter* interpreter, PrintFn assertOutput) { +void Toy_setInterpreterAssert(Toy_Interpreter* interpreter, Toy_PrintFn assertOutput) { interpreter->assertOutput = assertOutput; } -void setInterpreterError(Interpreter* interpreter, PrintFn errorOutput) { +void Toy_setInterpreterError(Toy_Interpreter* interpreter, Toy_PrintFn errorOutput) { interpreter->errorOutput = errorOutput; } @@ -206,7 +206,7 @@ static char* readString(unsigned char* tb, int* count) { return (char*)ret; } -static void consumeByte(Interpreter* interpreter, unsigned char byte, unsigned char* tb, int* count) { +static void consumeByte(Toy_Interpreter* interpreter, unsigned char byte, unsigned char* tb, int* count) { if (byte != tb[*count]) { char buffer[512]; snprintf(buffer, 512, "[internal] Failed to consume the correct byte (expected %u, found %u)\n", byte, tb[*count]); @@ -215,7 +215,7 @@ static void consumeByte(Interpreter* interpreter, unsigned char byte, unsigned c *count += 1; } -static void consumeShort(Interpreter* interpreter, unsigned short bytes, unsigned char* tb, int* count) { +static void consumeShort(Toy_Interpreter* interpreter, unsigned short bytes, unsigned char* tb, int* count) { if (bytes != *(unsigned short*)(tb + *count)) { char buffer[512]; snprintf(buffer, 512, "[internal] Failed to consume the correct bytes (expected %u, found %u)\n", bytes, *(unsigned short*)(tb + *count)); @@ -225,51 +225,51 @@ static void consumeShort(Interpreter* interpreter, unsigned short bytes, unsigne } //each available statement -static bool execAssert(Interpreter* interpreter) { - Literal rhs = popLiteralArray(&interpreter->stack); - Literal lhs = popLiteralArray(&interpreter->stack); - parseIdentifierToValue(interpreter, &lhs); +static bool execAssert(Toy_Interpreter* interpreter) { + Toy_Literal rhs = Toy_popLiteralArray(&interpreter->stack); + Toy_Literal lhs = Toy_popLiteralArray(&interpreter->stack); + Toy_parseIdentifierToValue(interpreter, &lhs); - if (!IS_STRING(rhs)) { + if (!TOY_IS_STRING(rhs)) { interpreter->errorOutput("The assert keyword needs a string as the second argument, received: "); - printLiteralCustom(rhs, interpreter->errorOutput); + Toy_printLiteralCustom(rhs, interpreter->errorOutput); interpreter->errorOutput("\n"); return false; } - if (IS_NULL(lhs) || !IS_TRUTHY(lhs)) { - (*interpreter->assertOutput)(toCString(AS_STRING(rhs))); - freeLiteral(rhs); + if (TOY_IS_NULL(lhs) || !TOY_IS_TRUTHY(lhs)) { + (*interpreter->assertOutput)(Toy_toCString(TOY_AS_STRING(rhs))); + Toy_freeLiteral(rhs); interpreter->panic = true; return false; } - freeLiteral(lhs); - freeLiteral(rhs); + Toy_freeLiteral(lhs); + Toy_freeLiteral(rhs); return true; } -static bool execPrint(Interpreter* interpreter) { +static bool execPrint(Toy_Interpreter* interpreter) { //print what is on top of the stack, then pop it - Literal lit = popLiteralArray(&interpreter->stack); + Toy_Literal lit = Toy_popLiteralArray(&interpreter->stack); - if (IS_IDENTIFIER(lit)) { - Literal idn = lit; - if (!parseIdentifierToValue(interpreter, &lit)) { + if (TOY_IS_IDENTIFIER(lit)) { + Toy_Literal idn = lit; + if (!Toy_parseIdentifierToValue(interpreter, &lit)) { return false; } - freeLiteral(idn); + Toy_freeLiteral(idn); } - printLiteralCustom(lit, interpreter->printOutput); + Toy_printLiteralCustom(lit, interpreter->printOutput); - freeLiteral(lit); + Toy_freeLiteral(lit); return true; } -static bool execPushLiteral(Interpreter* interpreter, bool lng) { +static bool execPushLiteral(Toy_Interpreter* interpreter, bool lng) { //read the index in the cache int index = 0; @@ -281,178 +281,178 @@ static bool execPushLiteral(Interpreter* interpreter, bool lng) { } //push from cache to stack (DO NOT account for identifiers - will do that later) - pushLiteralArray(&interpreter->stack, interpreter->literalCache.literals[index]); + Toy_pushLiteralArray(&interpreter->stack, interpreter->literalCache.literals[index]); return true; } -static bool rawLiteral(Interpreter* interpreter) { - Literal lit = popLiteralArray(&interpreter->stack); +static bool rawLiteral(Toy_Interpreter* interpreter) { + Toy_Literal lit = Toy_popLiteralArray(&interpreter->stack); - if (IS_IDENTIFIER(lit)) { - Literal idn = lit; - if (!parseIdentifierToValue(interpreter, &lit)) { + if (TOY_IS_IDENTIFIER(lit)) { + Toy_Literal idn = lit; + if (!Toy_parseIdentifierToValue(interpreter, &lit)) { return false; } - freeLiteral(idn); + Toy_freeLiteral(idn); } - pushLiteralArray(&interpreter->stack, lit); + Toy_pushLiteralArray(&interpreter->stack, lit); - freeLiteral(lit); + Toy_freeLiteral(lit); return true; } -static bool execNegate(Interpreter* interpreter) { +static bool execNegate(Toy_Interpreter* interpreter) { //negate the top literal on the stack (numbers only) - Literal lit = popLiteralArray(&interpreter->stack); + Toy_Literal lit = Toy_popLiteralArray(&interpreter->stack); - if (IS_IDENTIFIER(lit)) { - Literal idn = lit; - if (!parseIdentifierToValue(interpreter, &lit)) { + if (TOY_IS_IDENTIFIER(lit)) { + Toy_Literal idn = lit; + if (!Toy_parseIdentifierToValue(interpreter, &lit)) { return false; } - freeLiteral(idn); + Toy_freeLiteral(idn); } - if (IS_INTEGER(lit)) { - lit = TO_INTEGER_LITERAL(-AS_INTEGER(lit)); + if (TOY_IS_INTEGER(lit)) { + lit = TOY_TO_INTEGER_LITERAL(-TOY_AS_INTEGER(lit)); } - else if (IS_FLOAT(lit)) { - lit = TO_FLOAT_LITERAL(-AS_FLOAT(lit)); + else if (TOY_IS_FLOAT(lit)) { + lit = TOY_TO_FLOAT_LITERAL(-TOY_AS_FLOAT(lit)); } else { interpreter->errorOutput("Can't negate that literal: "); - printLiteralCustom(lit, interpreter->errorOutput); + Toy_printLiteralCustom(lit, interpreter->errorOutput); interpreter->errorOutput("\n"); - freeLiteral(lit); + Toy_freeLiteral(lit); return false; } - pushLiteralArray(&interpreter->stack, lit); + Toy_pushLiteralArray(&interpreter->stack, lit); - freeLiteral(lit); + Toy_freeLiteral(lit); return true; } -static bool execInvert(Interpreter* interpreter) { +static bool execInvert(Toy_Interpreter* interpreter) { //negate the top literal on the stack (booleans only) - Literal lit = popLiteralArray(&interpreter->stack); + Toy_Literal lit = Toy_popLiteralArray(&interpreter->stack); - if (IS_IDENTIFIER(lit)) { - Literal idn = lit; - if (!parseIdentifierToValue(interpreter, &lit)) { + if (TOY_IS_IDENTIFIER(lit)) { + Toy_Literal idn = lit; + if (!Toy_parseIdentifierToValue(interpreter, &lit)) { return false; } - freeLiteral(idn); + Toy_freeLiteral(idn); } - if (IS_BOOLEAN(lit)) { - lit = TO_BOOLEAN_LITERAL(!AS_BOOLEAN(lit)); + if (TOY_IS_BOOLEAN(lit)) { + lit = TOY_TO_BOOLEAN_LITERAL(!TOY_AS_BOOLEAN(lit)); } else { interpreter->errorOutput("Can't invert that literal: "); - printLiteralCustom(lit, interpreter->errorOutput); + Toy_printLiteralCustom(lit, interpreter->errorOutput); interpreter->errorOutput("\n"); - freeLiteral(lit); + Toy_freeLiteral(lit); return false; } - pushLiteralArray(&interpreter->stack, lit); + Toy_pushLiteralArray(&interpreter->stack, lit); - freeLiteral(lit); + Toy_freeLiteral(lit); return true; } -static bool execArithmetic(Interpreter* interpreter, Opcode opcode) { - Literal rhs = popLiteralArray(&interpreter->stack); - Literal lhs = popLiteralArray(&interpreter->stack); +static bool execArithmetic(Toy_Interpreter* interpreter, Toy_Opcode opcode) { + Toy_Literal rhs = Toy_popLiteralArray(&interpreter->stack); + Toy_Literal lhs = Toy_popLiteralArray(&interpreter->stack); - if (IS_IDENTIFIER(rhs)) { - Literal idn = rhs; - parseIdentifierToValue(interpreter, &rhs); - freeLiteral(idn); + if (TOY_IS_IDENTIFIER(rhs)) { + Toy_Literal idn = rhs; + Toy_parseIdentifierToValue(interpreter, &rhs); + Toy_freeLiteral(idn); } - if (IS_IDENTIFIER(lhs)) { - Literal idn = lhs; - parseIdentifierToValue(interpreter, &lhs); - freeLiteral(idn); + if (TOY_IS_IDENTIFIER(lhs)) { + Toy_Literal idn = lhs; + Toy_parseIdentifierToValue(interpreter, &lhs); + Toy_freeLiteral(idn); } //special case for string concatenation ONLY - if (IS_STRING(lhs) && IS_STRING(rhs)) { + if (TOY_IS_STRING(lhs) && TOY_IS_STRING(rhs)) { //check for overflow - int totalLength = AS_STRING(lhs)->length + AS_STRING(rhs)->length; - if (totalLength > MAX_STRING_LENGTH) { + int totalLength = TOY_AS_STRING(lhs)->length + TOY_AS_STRING(rhs)->length; + if (totalLength > TOY_MAX_STRING_LENGTH) { interpreter->errorOutput("Can't concatenate these strings (result is too long)\n"); return false; } //concat the strings - char buffer[MAX_STRING_LENGTH]; - 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); + char buffer[TOY_MAX_STRING_LENGTH]; + snprintf(buffer, TOY_MAX_STRING_LENGTH, "%s%s", Toy_toCString(TOY_AS_STRING(lhs)), Toy_toCString(TOY_AS_STRING(rhs))); + Toy_Literal literal = TOY_TO_STRING_LITERAL(Toy_createRefStringLength(buffer, totalLength)); + Toy_pushLiteralArray(&interpreter->stack, literal); //cleanup - freeLiteral(literal); - freeLiteral(lhs); - freeLiteral(rhs); + Toy_freeLiteral(literal); + Toy_freeLiteral(lhs); + Toy_freeLiteral(rhs); return true; } //type coersion - if (IS_FLOAT(lhs) && IS_INTEGER(rhs)) { - rhs = TO_FLOAT_LITERAL(AS_INTEGER(rhs)); + if (TOY_IS_FLOAT(lhs) && TOY_IS_INTEGER(rhs)) { + rhs = TOY_TO_FLOAT_LITERAL(TOY_AS_INTEGER(rhs)); } - if (IS_INTEGER(lhs) && IS_FLOAT(rhs)) { - lhs = TO_FLOAT_LITERAL(AS_INTEGER(lhs)); + if (TOY_IS_INTEGER(lhs) && TOY_IS_FLOAT(rhs)) { + lhs = TOY_TO_FLOAT_LITERAL(TOY_AS_INTEGER(lhs)); } //maths based on types - if(IS_INTEGER(lhs) && IS_INTEGER(rhs)) { + if(TOY_IS_INTEGER(lhs) && TOY_IS_INTEGER(rhs)) { switch(opcode) { - case OP_ADDITION: - case OP_VAR_ADDITION_ASSIGN: - pushLiteralArray(&interpreter->stack, TO_INTEGER_LITERAL( AS_INTEGER(lhs) + AS_INTEGER(rhs) )); + case TOY_OP_ADDITION: + case TOY_OP_VAR_ADDITION_ASSIGN: + Toy_pushLiteralArray(&interpreter->stack, TOY_TO_INTEGER_LITERAL( TOY_AS_INTEGER(lhs) + TOY_AS_INTEGER(rhs) )); return true; - case OP_SUBTRACTION: - case OP_VAR_SUBTRACTION_ASSIGN: - pushLiteralArray(&interpreter->stack, TO_INTEGER_LITERAL( AS_INTEGER(lhs) - AS_INTEGER(rhs) )); + case TOY_OP_SUBTRACTION: + case TOY_OP_VAR_SUBTRACTION_ASSIGN: + Toy_pushLiteralArray(&interpreter->stack, TOY_TO_INTEGER_LITERAL( TOY_AS_INTEGER(lhs) - TOY_AS_INTEGER(rhs) )); return true; - case OP_MULTIPLICATION: - case OP_VAR_MULTIPLICATION_ASSIGN: - pushLiteralArray(&interpreter->stack, TO_INTEGER_LITERAL( AS_INTEGER(lhs) * AS_INTEGER(rhs) )); + case TOY_OP_MULTIPLICATION: + case TOY_OP_VAR_MULTIPLICATION_ASSIGN: + Toy_pushLiteralArray(&interpreter->stack, TOY_TO_INTEGER_LITERAL( TOY_AS_INTEGER(lhs) * TOY_AS_INTEGER(rhs) )); return true; - case OP_DIVISION: - case OP_VAR_DIVISION_ASSIGN: - if (AS_INTEGER(rhs) == 0) { + case TOY_OP_DIVISION: + case TOY_OP_VAR_DIVISION_ASSIGN: + if (TOY_AS_INTEGER(rhs) == 0) { interpreter->errorOutput("Can't divide by zero (error found in interpreter)"); return false; } - pushLiteralArray(&interpreter->stack, TO_INTEGER_LITERAL( AS_INTEGER(lhs) / AS_INTEGER(rhs) )); + Toy_pushLiteralArray(&interpreter->stack, TOY_TO_INTEGER_LITERAL( TOY_AS_INTEGER(lhs) / TOY_AS_INTEGER(rhs) )); return true; - case OP_MODULO: - case OP_VAR_MODULO_ASSIGN: - if (AS_INTEGER(rhs) == 0) { + case TOY_OP_MODULO: + case TOY_OP_VAR_MODULO_ASSIGN: + if (TOY_AS_INTEGER(rhs) == 0) { interpreter->errorOutput("Can't modulo by zero (error found in interpreter)"); return false; } - pushLiteralArray(&interpreter->stack, TO_INTEGER_LITERAL( AS_INTEGER(lhs) % AS_INTEGER(rhs) )); + Toy_pushLiteralArray(&interpreter->stack, TOY_TO_INTEGER_LITERAL( TOY_AS_INTEGER(lhs) % TOY_AS_INTEGER(rhs) )); return true; default: @@ -462,35 +462,35 @@ static bool execArithmetic(Interpreter* interpreter, Opcode opcode) { } //catch bad modulo - if (opcode == OP_MODULO || opcode == OP_VAR_MODULO_ASSIGN) { + if (opcode == TOY_OP_MODULO || opcode == TOY_OP_VAR_MODULO_ASSIGN) { interpreter->errorOutput("Bad arithmetic argument (modulo on floats not allowed)\n"); return false; } - if(IS_FLOAT(lhs) && IS_FLOAT(rhs)) { + if(TOY_IS_FLOAT(lhs) && TOY_IS_FLOAT(rhs)) { switch(opcode) { - case OP_ADDITION: - case OP_VAR_ADDITION_ASSIGN: - pushLiteralArray(&interpreter->stack, TO_FLOAT_LITERAL( AS_FLOAT(lhs) + AS_FLOAT(rhs) )); + case TOY_OP_ADDITION: + case TOY_OP_VAR_ADDITION_ASSIGN: + Toy_pushLiteralArray(&interpreter->stack, TOY_TO_FLOAT_LITERAL( TOY_AS_FLOAT(lhs) + TOY_AS_FLOAT(rhs) )); return true; - case OP_SUBTRACTION: - case OP_VAR_SUBTRACTION_ASSIGN: - pushLiteralArray(&interpreter->stack, TO_FLOAT_LITERAL( AS_FLOAT(lhs) - AS_FLOAT(rhs) )); + case TOY_OP_SUBTRACTION: + case TOY_OP_VAR_SUBTRACTION_ASSIGN: + Toy_pushLiteralArray(&interpreter->stack, TOY_TO_FLOAT_LITERAL( TOY_AS_FLOAT(lhs) - TOY_AS_FLOAT(rhs) )); return true; - case OP_MULTIPLICATION: - case OP_VAR_MULTIPLICATION_ASSIGN: - pushLiteralArray(&interpreter->stack, TO_FLOAT_LITERAL( AS_FLOAT(lhs) * AS_FLOAT(rhs) )); + case TOY_OP_MULTIPLICATION: + case TOY_OP_VAR_MULTIPLICATION_ASSIGN: + Toy_pushLiteralArray(&interpreter->stack, TOY_TO_FLOAT_LITERAL( TOY_AS_FLOAT(lhs) * TOY_AS_FLOAT(rhs) )); return true; - case OP_DIVISION: - case OP_VAR_DIVISION_ASSIGN: - if (AS_FLOAT(rhs) == 0) { + case TOY_OP_DIVISION: + case TOY_OP_VAR_DIVISION_ASSIGN: + if (TOY_AS_FLOAT(rhs) == 0) { interpreter->errorOutput("Can't divide by zero (error found in interpreter)"); return false; } - pushLiteralArray(&interpreter->stack, TO_FLOAT_LITERAL( AS_FLOAT(lhs) / AS_FLOAT(rhs) )); + Toy_pushLiteralArray(&interpreter->stack, TOY_TO_FLOAT_LITERAL( TOY_AS_FLOAT(lhs) / TOY_AS_FLOAT(rhs) )); return true; default: @@ -501,36 +501,36 @@ static bool execArithmetic(Interpreter* interpreter, Opcode opcode) { //wrong types interpreter->errorOutput("Bad arithmetic argument "); - printLiteralCustom(lhs, interpreter->errorOutput); + Toy_printLiteralCustom(lhs, interpreter->errorOutput); interpreter->errorOutput(" and "); - printLiteralCustom(rhs, interpreter->errorOutput); + Toy_printLiteralCustom(rhs, interpreter->errorOutput); interpreter->errorOutput("\n"); - freeLiteral(lhs); - freeLiteral(rhs); + Toy_freeLiteral(lhs); + Toy_freeLiteral(rhs); return false; } -static Literal parseTypeToValue(Interpreter* interpreter, Literal type) { +static Toy_Literal parseTypeToValue(Toy_Interpreter* interpreter, Toy_Literal type) { //if an identifier is embedded in the type, figure out what it iss - if (IS_IDENTIFIER(type)) { - Literal idn = type; - parseIdentifierToValue(interpreter, &type); - freeLiteral(idn); + if (TOY_IS_IDENTIFIER(type)) { + Toy_Literal idn = type; + Toy_parseIdentifierToValue(interpreter, &type); + Toy_freeLiteral(idn); } //if this is an array or dictionary, continue to the subtypes - if (IS_TYPE(type) && (AS_TYPE(type).typeOf == LITERAL_ARRAY || AS_TYPE(type).typeOf == LITERAL_DICTIONARY)) { - for (int i = 0; i < AS_TYPE(type).count; i++) { - ((Literal*)(AS_TYPE(type).subtypes))[i] = parseTypeToValue(interpreter, ((Literal*)(AS_TYPE(type).subtypes))[i]); + 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++) { + ((Toy_Literal*)(TOY_AS_TYPE(type).subtypes))[i] = parseTypeToValue(interpreter, ((Toy_Literal*)(TOY_AS_TYPE(type).subtypes))[i]); } } //BUGFIX: make sure it actually is a type - if (!IS_TYPE(type)) { + if (!TOY_IS_TYPE(type)) { interpreter->errorOutput("Bad type encountered: "); - printLiteralCustom(type, interpreter->errorOutput); + Toy_printLiteralCustom(type, interpreter->errorOutput); interpreter->errorOutput("\n"); //TODO: would be better to return an int here... } @@ -538,7 +538,7 @@ static Literal parseTypeToValue(Interpreter* interpreter, Literal type) { return type; } -static bool execVarDecl(Interpreter* interpreter, bool lng) { +static bool execVarDecl(Toy_Interpreter* interpreter, bool lng) { //read the index in the cache int identifierIndex = 0; int typeIndex = 0; @@ -552,62 +552,62 @@ static bool execVarDecl(Interpreter* interpreter, bool lng) { typeIndex = (int)readByte(interpreter->bytecode, &interpreter->count); } - Literal identifier = interpreter->literalCache.literals[identifierIndex]; - Literal type = copyLiteral(interpreter->literalCache.literals[typeIndex]); + Toy_Literal identifier = interpreter->literalCache.literals[identifierIndex]; + Toy_Literal type = Toy_copyLiteral(interpreter->literalCache.literals[typeIndex]); - if (IS_IDENTIFIER(type)) { - Literal orig = type; - parseIdentifierToValue(interpreter, &type); - freeLiteral(orig); + if (TOY_IS_IDENTIFIER(type)) { + Toy_Literal orig = type; + Toy_parseIdentifierToValue(interpreter, &type); + Toy_freeLiteral(orig); } //BUGFIX: because identifiers are getting embedded in type definitions type = parseTypeToValue(interpreter, type); - if (!declareScopeVariable(interpreter->scope, identifier, type)) { + if (!Toy_declareScopeVariable(interpreter->scope, identifier, type)) { interpreter->errorOutput("Can't redefine the variable \""); - printLiteralCustom(identifier, interpreter->errorOutput); + Toy_printLiteralCustom(identifier, interpreter->errorOutput); interpreter->errorOutput("\"\n"); return false; } - Literal val = popLiteralArray(&interpreter->stack); + Toy_Literal val = Toy_popLiteralArray(&interpreter->stack); - if (IS_IDENTIFIER(val)) { - Literal idn = val; - parseIdentifierToValue(interpreter, &val); - freeLiteral(idn); + if (TOY_IS_IDENTIFIER(val)) { + Toy_Literal idn = val; + Toy_parseIdentifierToValue(interpreter, &val); + Toy_freeLiteral(idn); } - if (IS_ARRAY(val) || IS_DICTIONARY(val)) { - parseCompoundToPureValues(interpreter, &val); + if (TOY_IS_ARRAY(val) || TOY_IS_DICTIONARY(val)) { + Toy_parseCompoundToPureValues(interpreter, &val); } //TODO: could restrict opaque data to only opaque variables //BUGFIX: allow easy coercion on decl - if (AS_TYPE(type).typeOf == LITERAL_FLOAT && IS_INTEGER(val)) { - val = TO_FLOAT_LITERAL(AS_INTEGER(val)); + if (TOY_AS_TYPE(type).typeOf == TOY_LITERAL_FLOAT && TOY_IS_INTEGER(val)) { + val = TOY_TO_FLOAT_LITERAL(TOY_AS_INTEGER(val)); } - if (!IS_NULL(val) && !setScopeVariable(interpreter->scope, identifier, val, false)) { + if (!TOY_IS_NULL(val) && !Toy_setScopeVariable(interpreter->scope, identifier, val, false)) { interpreter->errorOutput("Incorrect type assigned to variable \""); - printLiteralCustom(identifier, interpreter->errorOutput); + Toy_printLiteralCustom(identifier, interpreter->errorOutput); interpreter->errorOutput("\"\n"); - freeLiteral(type); - freeLiteral(val); + Toy_freeLiteral(type); + Toy_freeLiteral(val); return false; } - freeLiteral(val); - freeLiteral(type); + Toy_freeLiteral(val); + Toy_freeLiteral(type); return true; } -static bool execFnDecl(Interpreter* interpreter, bool lng) { +static bool execFnDecl(Toy_Interpreter* interpreter, bool lng) { //read the index in the cache int identifierIndex = 0; int functionIndex = 0; @@ -621,451 +621,451 @@ static bool execFnDecl(Interpreter* interpreter, bool lng) { functionIndex = (int)readByte(interpreter->bytecode, &interpreter->count); } - Literal identifier = interpreter->literalCache.literals[identifierIndex]; - Literal function = interpreter->literalCache.literals[functionIndex]; + Toy_Literal identifier = interpreter->literalCache.literals[identifierIndex]; + Toy_Literal function = interpreter->literalCache.literals[functionIndex]; - AS_FUNCTION(function).scope = pushScope(interpreter->scope); //hacked in (needed for closure persistance) + TOY_AS_FUNCTION(function).scope = Toy_pushScope(interpreter->scope); //hacked in (needed for closure persistance) - Literal type = TO_TYPE_LITERAL(LITERAL_FUNCTION, true); + Toy_Literal type = TOY_TO_TYPE_LITERAL(TOY_LITERAL_FUNCTION, true); - if (!declareScopeVariable(interpreter->scope, identifier, type)) { + if (!Toy_declareScopeVariable(interpreter->scope, identifier, type)) { interpreter->errorOutput("Can't redefine the function \""); - printLiteralCustom(identifier, interpreter->errorOutput); + Toy_printLiteralCustom(identifier, interpreter->errorOutput); interpreter->errorOutput("\"\n"); return false; } - if (!setScopeVariable(interpreter->scope, identifier, function, false)) { //scope gets copied here + if (!Toy_setScopeVariable(interpreter->scope, identifier, function, false)) { //scope gets copied here interpreter->errorOutput("Incorrect type assigned to variable \""); - printLiteralCustom(identifier, interpreter->errorOutput); + Toy_printLiteralCustom(identifier, interpreter->errorOutput); interpreter->errorOutput("\"\n"); return false; } - popScope(AS_FUNCTION(function).scope); //hacked out - AS_FUNCTION(function).scope = NULL; + Toy_popScope(TOY_AS_FUNCTION(function).scope); //hacked out + TOY_AS_FUNCTION(function).scope = NULL; - freeLiteral(type); + Toy_freeLiteral(type); return true; } -static bool execVarAssign(Interpreter* interpreter) { - Literal rhs = popLiteralArray(&interpreter->stack); - Literal lhs = popLiteralArray(&interpreter->stack); +static bool execVarAssign(Toy_Interpreter* interpreter) { + Toy_Literal rhs = Toy_popLiteralArray(&interpreter->stack); + Toy_Literal lhs = Toy_popLiteralArray(&interpreter->stack); - if (IS_IDENTIFIER(rhs)) { - Literal idn = rhs; - parseIdentifierToValue(interpreter, &rhs); - freeLiteral(idn); + if (TOY_IS_IDENTIFIER(rhs)) { + Toy_Literal idn = rhs; + Toy_parseIdentifierToValue(interpreter, &rhs); + Toy_freeLiteral(idn); } - if (IS_ARRAY(rhs) || IS_DICTIONARY(rhs)) { - parseCompoundToPureValues(interpreter, &rhs); + if (TOY_IS_ARRAY(rhs) || TOY_IS_DICTIONARY(rhs)) { + Toy_parseCompoundToPureValues(interpreter, &rhs); } - if (!IS_IDENTIFIER(lhs)) { + if (!TOY_IS_IDENTIFIER(lhs)) { interpreter->errorOutput("Can't assign to a non-variable \""); - printLiteralCustom(lhs, interpreter->errorOutput); + Toy_printLiteralCustom(lhs, interpreter->errorOutput); interpreter->errorOutput("\"\n"); return false; } - if (!isDelcaredScopeVariable(interpreter->scope, lhs)) { + if (!Toy_isDelcaredScopeVariable(interpreter->scope, lhs)) { interpreter->errorOutput("Undeclared variable \""); - printLiteralCustom(lhs, interpreter->errorOutput); + Toy_printLiteralCustom(lhs, interpreter->errorOutput); interpreter->errorOutput("\"\n"); - freeLiteral(lhs); - freeLiteral(rhs); + Toy_freeLiteral(lhs); + Toy_freeLiteral(rhs); return false; } //BUGFIX: allow easy coercion on assign - Literal type = getScopeType(interpreter->scope, lhs); - if (AS_TYPE(type).typeOf == LITERAL_FLOAT && IS_INTEGER(rhs)) { - rhs = TO_FLOAT_LITERAL(AS_INTEGER(rhs)); + Toy_Literal type = Toy_getScopeType(interpreter->scope, lhs); + if (TOY_AS_TYPE(type).typeOf == TOY_LITERAL_FLOAT && TOY_IS_INTEGER(rhs)) { + rhs = TOY_TO_FLOAT_LITERAL(TOY_AS_INTEGER(rhs)); } - if (!setScopeVariable(interpreter->scope, lhs, rhs, true)) { + if (!Toy_setScopeVariable(interpreter->scope, lhs, rhs, true)) { interpreter->errorOutput("Incorrect type assigned to variable \""); - printLiteralCustom(lhs, interpreter->errorOutput); + Toy_printLiteralCustom(lhs, interpreter->errorOutput); interpreter->errorOutput("\"\n"); - freeLiteral(lhs); - freeLiteral(rhs); - freeLiteral(type); + Toy_freeLiteral(lhs); + Toy_freeLiteral(rhs); + Toy_freeLiteral(type); return false; } - freeLiteral(lhs); - freeLiteral(rhs); - freeLiteral(type); + Toy_freeLiteral(lhs); + Toy_freeLiteral(rhs); + Toy_freeLiteral(type); return true; } -static bool execVarArithmeticAssign(Interpreter* interpreter) { - Literal rhs = popLiteralArray(&interpreter->stack); - Literal lhs = popLiteralArray(&interpreter->stack); +static bool execVarArithmeticAssign(Toy_Interpreter* interpreter) { + Toy_Literal rhs = Toy_popLiteralArray(&interpreter->stack); + Toy_Literal lhs = Toy_popLiteralArray(&interpreter->stack); //duplicate the name - pushLiteralArray(&interpreter->stack, lhs); - pushLiteralArray(&interpreter->stack, lhs); - pushLiteralArray(&interpreter->stack, rhs); + Toy_pushLiteralArray(&interpreter->stack, lhs); + Toy_pushLiteralArray(&interpreter->stack, lhs); + Toy_pushLiteralArray(&interpreter->stack, rhs); - freeLiteral(lhs); - freeLiteral(rhs); + Toy_freeLiteral(lhs); + Toy_freeLiteral(rhs); return true; } -static bool execValCast(Interpreter* interpreter) { - Literal value = popLiteralArray(&interpreter->stack); - Literal type = popLiteralArray(&interpreter->stack); +static bool execValCast(Toy_Interpreter* interpreter) { + Toy_Literal value = Toy_popLiteralArray(&interpreter->stack); + Toy_Literal type = Toy_popLiteralArray(&interpreter->stack); - if (IS_IDENTIFIER(value)) { - Literal idn = value; - if (!parseIdentifierToValue(interpreter, &value)) { + if (TOY_IS_IDENTIFIER(value)) { + Toy_Literal idn = value; + if (!Toy_parseIdentifierToValue(interpreter, &value)) { return false; } - freeLiteral(idn); + Toy_freeLiteral(idn); } - Literal result = TO_NULL_LITERAL; + Toy_Literal result = TOY_TO_NULL_LITERAL; - if (IS_NULL(value)) { + if (TOY_IS_NULL(value)) { interpreter->errorOutput("Can't cast a null value\n"); - freeLiteral(value); - freeLiteral(type); + Toy_freeLiteral(value); + Toy_freeLiteral(type); return false; } //cast the rhs to the type represented by lhs - switch(AS_TYPE(type).typeOf) { - case LITERAL_BOOLEAN: - result = TO_BOOLEAN_LITERAL(IS_TRUTHY(value)); + switch(TOY_AS_TYPE(type).typeOf) { + case TOY_LITERAL_BOOLEAN: + result = TOY_TO_BOOLEAN_LITERAL(TOY_IS_TRUTHY(value)); break; - case LITERAL_INTEGER: - if (IS_BOOLEAN(value)) { - result = TO_INTEGER_LITERAL(AS_BOOLEAN(value) ? 1 : 0); + case TOY_LITERAL_INTEGER: + if (TOY_IS_BOOLEAN(value)) { + result = TOY_TO_INTEGER_LITERAL(TOY_AS_BOOLEAN(value) ? 1 : 0); } - if (IS_INTEGER(value)) { - result = copyLiteral(value); + if (TOY_IS_INTEGER(value)) { + result = Toy_copyLiteral(value); } - if (IS_FLOAT(value)) { - result = TO_INTEGER_LITERAL(AS_FLOAT(value)); + if (TOY_IS_FLOAT(value)) { + result = TOY_TO_INTEGER_LITERAL(TOY_AS_FLOAT(value)); } - if (IS_STRING(value)) { + if (TOY_IS_STRING(value)) { int val = 0; - sscanf(toCString(AS_STRING(value)), "%d", &val); - result = TO_INTEGER_LITERAL(val); + sscanf(Toy_toCString(TOY_AS_STRING(value)), "%d", &val); + result = TOY_TO_INTEGER_LITERAL(val); } break; - case LITERAL_FLOAT: - if (IS_BOOLEAN(value)) { - result = TO_FLOAT_LITERAL(AS_BOOLEAN(value) ? 1 : 0); + case TOY_LITERAL_FLOAT: + if (TOY_IS_BOOLEAN(value)) { + result = TOY_TO_FLOAT_LITERAL(TOY_AS_BOOLEAN(value) ? 1 : 0); } - if (IS_INTEGER(value)) { - result = TO_FLOAT_LITERAL(AS_INTEGER(value)); + if (TOY_IS_INTEGER(value)) { + result = TOY_TO_FLOAT_LITERAL(TOY_AS_INTEGER(value)); } - if (IS_FLOAT(value)) { - result = copyLiteral(value); + if (TOY_IS_FLOAT(value)) { + result = Toy_copyLiteral(value); } - if (IS_STRING(value)) { + if (TOY_IS_STRING(value)) { float val = 0; - sscanf(toCString(AS_STRING(value)), "%f", &val); - result = TO_FLOAT_LITERAL(val); + sscanf(Toy_toCString(TOY_AS_STRING(value)), "%f", &val); + result = TOY_TO_FLOAT_LITERAL(val); } break; - case LITERAL_STRING: - if (IS_BOOLEAN(value)) { - char* str = AS_BOOLEAN(value) ? "true" : "false"; + case TOY_LITERAL_STRING: + if (TOY_IS_BOOLEAN(value)) { + char* str = TOY_AS_BOOLEAN(value) ? "true" : "false"; int length = strlen(str); - result = TO_STRING_LITERAL(createRefStringLength(str, length)); //TODO: static reference optimisation? + result = TOY_TO_STRING_LITERAL(Toy_createRefStringLength(str, length)); //TODO: static reference optimisation? } - if (IS_INTEGER(value)) { + if (TOY_IS_INTEGER(value)) { char buffer[128]; - snprintf(buffer, 128, "%d", AS_INTEGER(value)); + snprintf(buffer, 128, "%d", TOY_AS_INTEGER(value)); int length = strlen(buffer); - result = TO_STRING_LITERAL(createRefStringLength(buffer, length)); + result = TOY_TO_STRING_LITERAL(Toy_createRefStringLength(buffer, length)); } - if (IS_FLOAT(value)) { + if (TOY_IS_FLOAT(value)) { char buffer[128]; - snprintf(buffer, 128, "%g", AS_FLOAT(value)); + snprintf(buffer, 128, "%g", TOY_AS_FLOAT(value)); int length = strlen(buffer); - result = TO_STRING_LITERAL(createRefStringLength(buffer, length)); + result = TOY_TO_STRING_LITERAL(Toy_createRefStringLength(buffer, length)); } - if (IS_STRING(value)) { - result = copyLiteral(value); + if (TOY_IS_STRING(value)) { + result = Toy_copyLiteral(value); } break; default: interpreter->errorOutput("Unknown cast type found: "); - printLiteralCustom(type, interpreter->errorOutput); + Toy_printLiteralCustom(type, interpreter->errorOutput); interpreter->errorOutput("\n"); return false; } //leave the new value on the stack - pushLiteralArray(&interpreter->stack, result); + Toy_pushLiteralArray(&interpreter->stack, result); - freeLiteral(result); - freeLiteral(value); - freeLiteral(type); + Toy_freeLiteral(result); + Toy_freeLiteral(value); + Toy_freeLiteral(type); return true; } -static bool execTypeOf(Interpreter* interpreter) { - Literal rhs = popLiteralArray(&interpreter->stack); - Literal type = TO_NULL_LITERAL; +static bool execTypeOf(Toy_Interpreter* interpreter) { + Toy_Literal rhs = Toy_popLiteralArray(&interpreter->stack); + Toy_Literal type = TOY_TO_NULL_LITERAL; - if (IS_IDENTIFIER(rhs)) { - type = getScopeType(interpreter->scope, rhs); + if (TOY_IS_IDENTIFIER(rhs)) { + type = Toy_getScopeType(interpreter->scope, rhs); } else { - type = TO_TYPE_LITERAL(rhs.type, false); + type = TOY_TO_TYPE_LITERAL(rhs.type, false); } - pushLiteralArray(&interpreter->stack, type); + Toy_pushLiteralArray(&interpreter->stack, type); - freeLiteral(rhs); - freeLiteral(type); + Toy_freeLiteral(rhs); + Toy_freeLiteral(type); return true; } -static bool execCompareEqual(Interpreter* interpreter, bool invert) { - Literal rhs = popLiteralArray(&interpreter->stack); - Literal lhs = popLiteralArray(&interpreter->stack); +static bool execCompareEqual(Toy_Interpreter* interpreter, bool invert) { + Toy_Literal rhs = Toy_popLiteralArray(&interpreter->stack); + Toy_Literal lhs = Toy_popLiteralArray(&interpreter->stack); - if (IS_IDENTIFIER(rhs)) { - Literal idn = rhs; - parseIdentifierToValue(interpreter, &rhs); - freeLiteral(idn); + if (TOY_IS_IDENTIFIER(rhs)) { + Toy_Literal idn = rhs; + Toy_parseIdentifierToValue(interpreter, &rhs); + Toy_freeLiteral(idn); } - if (IS_IDENTIFIER(lhs)) { - Literal idn = lhs; - parseIdentifierToValue(interpreter, &lhs); - freeLiteral(idn); + if (TOY_IS_IDENTIFIER(lhs)) { + Toy_Literal idn = lhs; + Toy_parseIdentifierToValue(interpreter, &lhs); + Toy_freeLiteral(idn); } - bool result = literalsAreEqual(lhs, rhs); + bool result = Toy_literalsAreEqual(lhs, rhs); if (invert) { result = !result; } - pushLiteralArray(&interpreter->stack, TO_BOOLEAN_LITERAL(result)); + Toy_pushLiteralArray(&interpreter->stack, TOY_TO_BOOLEAN_LITERAL(result)); - freeLiteral(lhs); - freeLiteral(rhs); + Toy_freeLiteral(lhs); + Toy_freeLiteral(rhs); return true; } -static bool execCompareLess(Interpreter* interpreter, bool invert) { - Literal rhs = popLiteralArray(&interpreter->stack); - Literal lhs = popLiteralArray(&interpreter->stack); +static bool execCompareLess(Toy_Interpreter* interpreter, bool invert) { + Toy_Literal rhs = Toy_popLiteralArray(&interpreter->stack); + Toy_Literal lhs = Toy_popLiteralArray(&interpreter->stack); - if (IS_IDENTIFIER(rhs)) { - Literal idn = rhs; - parseIdentifierToValue(interpreter, &rhs); - freeLiteral(idn); + if (TOY_IS_IDENTIFIER(rhs)) { + Toy_Literal idn = rhs; + Toy_parseIdentifierToValue(interpreter, &rhs); + Toy_freeLiteral(idn); } - if (IS_IDENTIFIER(lhs)) { - Literal idn = lhs; - parseIdentifierToValue(interpreter, &lhs); - freeLiteral(idn); + if (TOY_IS_IDENTIFIER(lhs)) { + Toy_Literal idn = lhs; + Toy_parseIdentifierToValue(interpreter, &lhs); + Toy_freeLiteral(idn); } //not a number, return falure - if (!(IS_INTEGER(lhs) || IS_FLOAT(lhs))) { + if (!(TOY_IS_INTEGER(lhs) || TOY_IS_FLOAT(lhs))) { interpreter->errorOutput("Incorrect type in comparison, value \""); - printLiteralCustom(lhs, interpreter->errorOutput); + Toy_printLiteralCustom(lhs, interpreter->errorOutput); interpreter->errorOutput("\"\n"); - freeLiteral(lhs); - freeLiteral(rhs); + Toy_freeLiteral(lhs); + Toy_freeLiteral(rhs); return false; } - if (!(IS_INTEGER(rhs) || IS_FLOAT(rhs))) { + if (!(TOY_IS_INTEGER(rhs) || TOY_IS_FLOAT(rhs))) { interpreter->errorOutput("Incorrect type in comparison, value \""); - printLiteralCustom(rhs, interpreter->errorOutput); + Toy_printLiteralCustom(rhs, interpreter->errorOutput); interpreter->errorOutput("\"\n"); - freeLiteral(lhs); - freeLiteral(rhs); + Toy_freeLiteral(lhs); + Toy_freeLiteral(rhs); return false; } //convert to floats - easier - if (IS_INTEGER(lhs)) { - lhs = TO_FLOAT_LITERAL(AS_INTEGER(lhs)); + if (TOY_IS_INTEGER(lhs)) { + lhs = TOY_TO_FLOAT_LITERAL(TOY_AS_INTEGER(lhs)); } - if (IS_INTEGER(rhs)) { - rhs = TO_FLOAT_LITERAL(AS_INTEGER(rhs)); + if (TOY_IS_INTEGER(rhs)) { + rhs = TOY_TO_FLOAT_LITERAL(TOY_AS_INTEGER(rhs)); } bool result; if (!invert) { - result = (AS_FLOAT(lhs) < AS_FLOAT(rhs)); + result = (TOY_AS_FLOAT(lhs) < TOY_AS_FLOAT(rhs)); } else { - result = (AS_FLOAT(lhs) > AS_FLOAT(rhs)); + result = (TOY_AS_FLOAT(lhs) > TOY_AS_FLOAT(rhs)); } - pushLiteralArray(&interpreter->stack, TO_BOOLEAN_LITERAL(result)); + Toy_pushLiteralArray(&interpreter->stack, TOY_TO_BOOLEAN_LITERAL(result)); - freeLiteral(lhs); - freeLiteral(rhs); + Toy_freeLiteral(lhs); + Toy_freeLiteral(rhs); return true; } -static bool execCompareLessEqual(Interpreter* interpreter, bool invert) { - Literal rhs = popLiteralArray(&interpreter->stack); - Literal lhs = popLiteralArray(&interpreter->stack); +static bool execCompareLessEqual(Toy_Interpreter* interpreter, bool invert) { + Toy_Literal rhs = Toy_popLiteralArray(&interpreter->stack); + Toy_Literal lhs = Toy_popLiteralArray(&interpreter->stack); - if (IS_IDENTIFIER(rhs)) { - Literal idn = rhs; - parseIdentifierToValue(interpreter, &rhs); - freeLiteral(idn); + if (TOY_IS_IDENTIFIER(rhs)) { + Toy_Literal idn = rhs; + Toy_parseIdentifierToValue(interpreter, &rhs); + Toy_freeLiteral(idn); } - if (IS_IDENTIFIER(lhs)) { - Literal idn = lhs; - parseIdentifierToValue(interpreter, &lhs); - freeLiteral(idn); + if (TOY_IS_IDENTIFIER(lhs)) { + Toy_Literal idn = lhs; + Toy_parseIdentifierToValue(interpreter, &lhs); + Toy_freeLiteral(idn); } //not a number, return falure - if (!(IS_INTEGER(lhs) || IS_FLOAT(lhs))) { + if (!(TOY_IS_INTEGER(lhs) || TOY_IS_FLOAT(lhs))) { interpreter->errorOutput("Incorrect type in comparison, value \""); - printLiteralCustom(lhs, interpreter->errorOutput); + Toy_printLiteralCustom(lhs, interpreter->errorOutput); interpreter->errorOutput("\"\n"); - freeLiteral(lhs); - freeLiteral(rhs); + Toy_freeLiteral(lhs); + Toy_freeLiteral(rhs); return false; } - if (!(IS_INTEGER(rhs) || IS_FLOAT(rhs))) { + if (!(TOY_IS_INTEGER(rhs) || TOY_IS_FLOAT(rhs))) { interpreter->errorOutput("Incorrect type in comparison, value \""); - printLiteralCustom(rhs, interpreter->errorOutput); + Toy_printLiteralCustom(rhs, interpreter->errorOutput); interpreter->errorOutput("\"\n"); - freeLiteral(lhs); - freeLiteral(rhs); + Toy_freeLiteral(lhs); + Toy_freeLiteral(rhs); return false; } //convert to floats - easier - if (IS_INTEGER(lhs)) { - lhs = TO_FLOAT_LITERAL(AS_INTEGER(lhs)); + if (TOY_IS_INTEGER(lhs)) { + lhs = TOY_TO_FLOAT_LITERAL(TOY_AS_INTEGER(lhs)); } - if (IS_INTEGER(rhs)) { - rhs = TO_FLOAT_LITERAL(AS_INTEGER(rhs)); + if (TOY_IS_INTEGER(rhs)) { + rhs = TOY_TO_FLOAT_LITERAL(TOY_AS_INTEGER(rhs)); } bool result; if (!invert) { - result = (AS_FLOAT(lhs) < AS_FLOAT(rhs)) || literalsAreEqual(lhs, rhs); + result = (TOY_AS_FLOAT(lhs) < TOY_AS_FLOAT(rhs)) || Toy_literalsAreEqual(lhs, rhs); } else { - result = (AS_FLOAT(lhs) > AS_FLOAT(rhs)) || literalsAreEqual(lhs, rhs); + result = (TOY_AS_FLOAT(lhs) > TOY_AS_FLOAT(rhs)) || Toy_literalsAreEqual(lhs, rhs); } - pushLiteralArray(&interpreter->stack, TO_BOOLEAN_LITERAL(result)); + Toy_pushLiteralArray(&interpreter->stack, TOY_TO_BOOLEAN_LITERAL(result)); - freeLiteral(lhs); - freeLiteral(rhs); + Toy_freeLiteral(lhs); + Toy_freeLiteral(rhs); return true; } -static bool execAnd(Interpreter* interpreter) { - Literal rhs = popLiteralArray(&interpreter->stack); - Literal lhs = popLiteralArray(&interpreter->stack); +static bool execAnd(Toy_Interpreter* interpreter) { + Toy_Literal rhs = Toy_popLiteralArray(&interpreter->stack); + Toy_Literal lhs = Toy_popLiteralArray(&interpreter->stack); - if (IS_IDENTIFIER(rhs)) { - Literal idn = rhs; - parseIdentifierToValue(interpreter, &rhs); - freeLiteral(idn); + if (TOY_IS_IDENTIFIER(rhs)) { + Toy_Literal idn = rhs; + Toy_parseIdentifierToValue(interpreter, &rhs); + Toy_freeLiteral(idn); } - if (IS_IDENTIFIER(lhs)) { - Literal idn = lhs; - parseIdentifierToValue(interpreter, &lhs); - freeLiteral(idn); + if (TOY_IS_IDENTIFIER(lhs)) { + Toy_Literal idn = lhs; + Toy_parseIdentifierToValue(interpreter, &lhs); + Toy_freeLiteral(idn); } - if (IS_TRUTHY(lhs) && IS_TRUTHY(rhs)) { - pushLiteralArray(&interpreter->stack, TO_BOOLEAN_LITERAL(true)); + if (TOY_IS_TRUTHY(lhs) && TOY_IS_TRUTHY(rhs)) { + Toy_pushLiteralArray(&interpreter->stack, TOY_TO_BOOLEAN_LITERAL(true)); } else { - pushLiteralArray(&interpreter->stack, TO_BOOLEAN_LITERAL(false)); + Toy_pushLiteralArray(&interpreter->stack, TOY_TO_BOOLEAN_LITERAL(false)); } - freeLiteral(lhs); - freeLiteral(rhs); + Toy_freeLiteral(lhs); + Toy_freeLiteral(rhs); return true; } -static bool execOr(Interpreter* interpreter) { - Literal rhs = popLiteralArray(&interpreter->stack); - Literal lhs = popLiteralArray(&interpreter->stack); +static bool execOr(Toy_Interpreter* interpreter) { + Toy_Literal rhs = Toy_popLiteralArray(&interpreter->stack); + Toy_Literal lhs = Toy_popLiteralArray(&interpreter->stack); - if (IS_IDENTIFIER(rhs)) { - Literal idn = rhs; - parseIdentifierToValue(interpreter, &rhs); - freeLiteral(idn); + if (TOY_IS_IDENTIFIER(rhs)) { + Toy_Literal idn = rhs; + Toy_parseIdentifierToValue(interpreter, &rhs); + Toy_freeLiteral(idn); } - if (IS_IDENTIFIER(lhs)) { - Literal idn = lhs; - parseIdentifierToValue(interpreter, &lhs); - freeLiteral(idn); + if (TOY_IS_IDENTIFIER(lhs)) { + Toy_Literal idn = lhs; + Toy_parseIdentifierToValue(interpreter, &lhs); + Toy_freeLiteral(idn); } - if (IS_TRUTHY(lhs) || IS_TRUTHY(rhs)) { - pushLiteralArray(&interpreter->stack, TO_BOOLEAN_LITERAL(true)); + if (TOY_IS_TRUTHY(lhs) || TOY_IS_TRUTHY(rhs)) { + Toy_pushLiteralArray(&interpreter->stack, TOY_TO_BOOLEAN_LITERAL(true)); } else { - pushLiteralArray(&interpreter->stack, TO_BOOLEAN_LITERAL(false)); + Toy_pushLiteralArray(&interpreter->stack, TOY_TO_BOOLEAN_LITERAL(false)); } - freeLiteral(lhs); - freeLiteral(rhs); + Toy_freeLiteral(lhs); + Toy_freeLiteral(rhs); return true; } -static bool execJump(Interpreter* interpreter) { +static bool execJump(Toy_Interpreter* interpreter) { int target = (int)readShort(interpreter->bytecode, &interpreter->count); if (target + interpreter->codeStart > interpreter->length) { @@ -1079,7 +1079,7 @@ static bool execJump(Interpreter* interpreter) { return true; } -static bool execFalseJump(Interpreter* interpreter) { +static bool execFalseJump(Toy_Interpreter* interpreter) { int target = (int)readShort(interpreter->bytecode, &interpreter->count); if (target + interpreter->codeStart > interpreter->length) { @@ -1088,37 +1088,37 @@ static bool execFalseJump(Interpreter* interpreter) { } //actually jump - Literal lit = popLiteralArray(&interpreter->stack); + Toy_Literal lit = Toy_popLiteralArray(&interpreter->stack); bool freeLit = false; - if (IS_IDENTIFIER(lit)) { - Literal idn = lit; - parseIdentifierToValue(interpreter, &lit); - freeLiteral(idn); + if (TOY_IS_IDENTIFIER(lit)) { + Toy_Literal idn = lit; + Toy_parseIdentifierToValue(interpreter, &lit); + Toy_freeLiteral(idn); freeLit = true; } - if (IS_NULL(lit)) { + if (TOY_IS_NULL(lit)) { interpreter->errorOutput("Null detected in comparison\n"); return false; } - if (!IS_TRUTHY(lit)) { + if (!TOY_IS_TRUTHY(lit)) { interpreter->count = target + interpreter->codeStart; } if (freeLit) { - freeLiteral(lit); + Toy_freeLiteral(lit); } return true; } //forward declare -static void execInterpreter(Interpreter*); -static void readInterpreterSections(Interpreter* interpreter); +static void execInterpreter(Toy_Interpreter*); +static void readInterpreterSections(Toy_Interpreter* interpreter); -static bool execFnCall(Interpreter* interpreter, bool looseFirstArgument) { +static bool execFnCall(Toy_Interpreter* interpreter, bool looseFirstArgument) { //BUGFIX: depth check - don't drown! if (interpreter->depth >= 200) { interpreter->errorOutput("Infinite recursion detected - panicking\n"); @@ -1126,234 +1126,234 @@ static bool execFnCall(Interpreter* interpreter, bool looseFirstArgument) { return false; } - LiteralArray arguments; - initLiteralArray(&arguments); + Toy_LiteralArray arguments; + Toy_initLiteralArray(&arguments); - Literal stackSize = popLiteralArray(&interpreter->stack); + Toy_Literal stackSize = Toy_popLiteralArray(&interpreter->stack); //unpack the stack of arguments - for (int i = 0; i < AS_INTEGER(stackSize) - 1; i++) { - Literal lit = popLiteralArray(&interpreter->stack); - pushLiteralArray(&arguments, lit); //NOTE: also reverses the order - freeLiteral(lit); + for (int i = 0; i < TOY_AS_INTEGER(stackSize) - 1; i++) { + Toy_Literal lit = Toy_popLiteralArray(&interpreter->stack); + Toy_pushLiteralArray(&arguments, lit); //NOTE: also reverses the order + Toy_freeLiteral(lit); } //collect one more argument - if (!looseFirstArgument && AS_INTEGER(stackSize) > 0) { - Literal lit = popLiteralArray(&interpreter->stack); - pushLiteralArray(&arguments, lit); //NOTE: also reverses the order - freeLiteral(lit); + if (!looseFirstArgument && TOY_AS_INTEGER(stackSize) > 0) { + Toy_Literal lit = Toy_popLiteralArray(&interpreter->stack); + Toy_pushLiteralArray(&arguments, lit); //NOTE: also reverses the order + Toy_freeLiteral(lit); } - Literal identifier = popLiteralArray(&interpreter->stack); + Toy_Literal identifier = Toy_popLiteralArray(&interpreter->stack); //collect one more argument if (looseFirstArgument) { - Literal lit = popLiteralArray(&interpreter->stack); - pushLiteralArray(&arguments, lit); //NOTE: also reverses the order - freeLiteral(lit); + Toy_Literal lit = Toy_popLiteralArray(&interpreter->stack); + Toy_pushLiteralArray(&arguments, lit); //NOTE: also reverses the order + Toy_freeLiteral(lit); } //let's screw with the fn name, too if (looseFirstArgument) { - int length = AS_IDENTIFIER(identifier)->length + 1; - char buffer[MAX_STRING_LENGTH]; - snprintf(buffer, MAX_STRING_LENGTH, "_%s", toCString(AS_IDENTIFIER(identifier))); //prepend an underscore + int length = TOY_AS_IDENTIFIER(identifier)->length + 1; + char buffer[TOY_MAX_STRING_LENGTH]; + snprintf(buffer, TOY_MAX_STRING_LENGTH, "_%s", Toy_toCString(TOY_AS_IDENTIFIER(identifier))); //prepend an underscore - freeLiteral(identifier); - identifier = TO_IDENTIFIER_LITERAL(createRefStringLength(buffer, length)); + Toy_freeLiteral(identifier); + identifier = TOY_TO_IDENTIFIER_LITERAL(Toy_createRefStringLength(buffer, length)); } - Literal func = identifier; + Toy_Literal func = identifier; - if (!parseIdentifierToValue(interpreter, &func)) { - freeLiteralArray(&arguments); - freeLiteral(identifier); + if (!Toy_parseIdentifierToValue(interpreter, &func)) { + Toy_freeLiteralArray(&arguments); + Toy_freeLiteral(identifier); return false; } //check for side-loaded native functions - if (IS_FUNCTION_NATIVE(func)) { + if (TOY_IS_FUNCTION_NATIVE(func)) { //reverse the order to the correct order - LiteralArray correct; - initLiteralArray(&correct); + Toy_LiteralArray correct; + Toy_initLiteralArray(&correct); while(arguments.count) { - Literal lit = popLiteralArray(&arguments); - pushLiteralArray(&correct, lit); - freeLiteral(lit); + Toy_Literal lit = Toy_popLiteralArray(&arguments); + Toy_pushLiteralArray(&correct, lit); + Toy_freeLiteral(lit); } - freeLiteralArray(&arguments); + Toy_freeLiteralArray(&arguments); //call the native function - ((NativeFn) AS_FUNCTION(func).bytecode )(interpreter, &correct); + ((Toy_NativeFn) TOY_AS_FUNCTION(func).bytecode )(interpreter, &correct); - freeLiteralArray(&correct); - freeLiteral(identifier); + Toy_freeLiteralArray(&correct); + Toy_freeLiteral(identifier); return true; } - if (!IS_FUNCTION(func)) { + if (!TOY_IS_FUNCTION(func)) { interpreter->errorOutput("Function not found: "); - printLiteralCustom(identifier, interpreter->errorOutput); + Toy_printLiteralCustom(identifier, interpreter->errorOutput); interpreter->errorOutput("\n"); - freeLiteral(identifier); - freeLiteralArray(&arguments); + Toy_freeLiteral(identifier); + Toy_freeLiteralArray(&arguments); return false; } - bool ret = callLiteralFn(interpreter, func, &arguments, &interpreter->stack); + bool ret = Toy_callLiteralFn(interpreter, func, &arguments, &interpreter->stack); if (!ret) { interpreter->errorOutput("Error encountered in function \""); - printLiteralCustom(identifier, interpreter->errorOutput); + Toy_printLiteralCustom(identifier, interpreter->errorOutput); interpreter->errorOutput("\"\n"); } - freeLiteralArray(&arguments); - freeLiteral(func); - freeLiteral(identifier); + Toy_freeLiteralArray(&arguments); + Toy_freeLiteral(func); + Toy_freeLiteral(identifier); return ret; } -bool callLiteralFn(Interpreter* interpreter, Literal func, LiteralArray* arguments, LiteralArray* returns) { - if (!IS_FUNCTION(func)) { - interpreter->errorOutput("Function required in callLiteralFn()\n"); +bool Toy_callLiteralFn(Toy_Interpreter* interpreter, Toy_Literal func, Toy_LiteralArray* arguments, Toy_LiteralArray* returns) { + if (!TOY_IS_FUNCTION(func)) { + interpreter->errorOutput("Function required in Toy_callLiteralFn()\n"); return false; } //set up a new interpreter - Interpreter inner; + Toy_Interpreter inner; //init the inner interpreter manually - initLiteralArray(&inner.literalCache); - inner.scope = pushScope(func.as.function.scope); - inner.bytecode = AS_FUNCTION(func).bytecode; - inner.length = AS_FUNCTION(func).length; + Toy_initLiteralArray(&inner.literalCache); + inner.scope = Toy_pushScope(func.as.function.scope); + inner.bytecode = TOY_AS_FUNCTION(func).bytecode; + inner.length = TOY_AS_FUNCTION(func).length; inner.count = 0; inner.codeStart = -1; inner.depth = interpreter->depth + 1; inner.panic = false; - initLiteralArray(&inner.stack); + Toy_initLiteralArray(&inner.stack); inner.hooks = interpreter->hooks; - setInterpreterPrint(&inner, interpreter->printOutput); - setInterpreterAssert(&inner, interpreter->assertOutput); - setInterpreterError(&inner, interpreter->errorOutput); + Toy_setInterpreterPrint(&inner, interpreter->printOutput); + Toy_setInterpreterAssert(&inner, interpreter->assertOutput); + Toy_setInterpreterError(&inner, interpreter->errorOutput); //prep the sections readInterpreterSections(&inner); //prep the arguments - LiteralArray* paramArray = AS_ARRAY(inner.literalCache.literals[ readShort(inner.bytecode, &inner.count) ]); - LiteralArray* returnArray = AS_ARRAY(inner.literalCache.literals[ readShort(inner.bytecode, &inner.count) ]); + Toy_LiteralArray* paramArray = TOY_AS_ARRAY(inner.literalCache.literals[ readShort(inner.bytecode, &inner.count) ]); + Toy_LiteralArray* returnArray = TOY_AS_ARRAY(inner.literalCache.literals[ readShort(inner.bytecode, &inner.count) ]); //get the rest param, if it exists - Literal restParam = TO_NULL_LITERAL; - if (paramArray->count >= 2 && AS_TYPE(paramArray->literals[ paramArray->count -1 ]).typeOf == LITERAL_FUNCTION_ARG_REST) { + Toy_Literal restParam = TOY_TO_NULL_LITERAL; + if (paramArray->count >= 2 && TOY_AS_TYPE(paramArray->literals[ paramArray->count -1 ]).typeOf == TOY_LITERAL_FUNCTION_ARG_REST) { restParam = paramArray->literals[ paramArray->count -2 ]; } //check the param total is correct - if ((IS_NULL(restParam) && paramArray->count != arguments->count * 2) || (!IS_NULL(restParam) && paramArray->count -2 > arguments->count * 2)) { + if ((TOY_IS_NULL(restParam) && paramArray->count != arguments->count * 2) || (!TOY_IS_NULL(restParam) && paramArray->count -2 > arguments->count * 2)) { interpreter->errorOutput("Incorrect number of arguments passed to a function\n"); //free, and skip out - popScope(inner.scope); + Toy_popScope(inner.scope); - freeLiteralArray(&inner.stack); - freeLiteralArray(&inner.literalCache); + Toy_freeLiteralArray(&inner.stack); + Toy_freeLiteralArray(&inner.literalCache); return false; } //contents is the indexes of identifier & type - for (int i = 0; i < paramArray->count - (IS_NULL(restParam) ? 0 : 2); i += 2) { //don't count the rest parameter, if present + for (int i = 0; i < paramArray->count - (TOY_IS_NULL(restParam) ? 0 : 2); i += 2) { //don't count the rest parameter, if present //declare and define each entry in the scope - if (!declareScopeVariable(inner.scope, paramArray->literals[i], paramArray->literals[i + 1])) { + if (!Toy_declareScopeVariable(inner.scope, paramArray->literals[i], paramArray->literals[i + 1])) { interpreter->errorOutput("[internal] Could not re-declare parameter\n"); //free, and skip out - popScope(inner.scope); + Toy_popScope(inner.scope); - freeLiteralArray(&inner.stack); - freeLiteralArray(&inner.literalCache); + Toy_freeLiteralArray(&inner.stack); + Toy_freeLiteralArray(&inner.literalCache); return false; } - Literal arg = popLiteralArray(arguments); + Toy_Literal arg = Toy_popLiteralArray(arguments); - if (IS_IDENTIFIER(arg)) { - Literal idn = arg; - parseIdentifierToValue(interpreter, &arg); - freeLiteral(idn); + if (TOY_IS_IDENTIFIER(arg)) { + Toy_Literal idn = arg; + Toy_parseIdentifierToValue(interpreter, &arg); + Toy_freeLiteral(idn); } - if (!setScopeVariable(inner.scope, paramArray->literals[i], arg, false)) { + if (!Toy_setScopeVariable(inner.scope, paramArray->literals[i], arg, false)) { interpreter->errorOutput("[internal] Could not define parameter (bad type?)\n"); //free, and skip out - freeLiteral(arg); - popScope(inner.scope); + Toy_freeLiteral(arg); + Toy_popScope(inner.scope); - freeLiteralArray(&inner.stack); - freeLiteralArray(&inner.literalCache); + Toy_freeLiteralArray(&inner.stack); + Toy_freeLiteralArray(&inner.literalCache); return false; } - freeLiteral(arg); + Toy_freeLiteral(arg); } //if using rest, pack the optional extra arguments into the rest parameter (array) - if (!IS_NULL(restParam)) { - LiteralArray rest; - initLiteralArray(&rest); + if (!TOY_IS_NULL(restParam)) { + Toy_LiteralArray rest; + Toy_initLiteralArray(&rest); while (arguments->count > 0) { - Literal lit = popLiteralArray(arguments); - pushLiteralArray(&rest, lit); - freeLiteral(lit); + Toy_Literal lit = Toy_popLiteralArray(arguments); + Toy_pushLiteralArray(&rest, lit); + Toy_freeLiteral(lit); } - Literal restType = TO_TYPE_LITERAL(LITERAL_ARRAY, true); - Literal any = TO_TYPE_LITERAL(LITERAL_ANY, false); - TYPE_PUSH_SUBTYPE(&restType, any); + Toy_Literal restType = TOY_TO_TYPE_LITERAL(TOY_LITERAL_ARRAY, true); + Toy_Literal any = TOY_TO_TYPE_LITERAL(TOY_LITERAL_ANY, false); + TOY_TYPE_PUSH_SUBTYPE(&restType, any); //declare & define the rest parameter - if (!declareScopeVariable(inner.scope, restParam, restType)) { + if (!Toy_declareScopeVariable(inner.scope, restParam, restType)) { interpreter->errorOutput("[internal] Could not declare rest parameter\n"); //free, and skip out - freeLiteral(restType); - freeLiteralArray(&rest); - popScope(inner.scope); + Toy_freeLiteral(restType); + Toy_freeLiteralArray(&rest); + Toy_popScope(inner.scope); - freeLiteralArray(&inner.stack); - freeLiteralArray(&inner.literalCache); + Toy_freeLiteralArray(&inner.stack); + Toy_freeLiteralArray(&inner.literalCache); return false; } - Literal lit = TO_ARRAY_LITERAL(&rest); - if (!setScopeVariable(inner.scope, restParam, lit, false)) { + Toy_Literal lit = TOY_TO_ARRAY_LITERAL(&rest); + if (!Toy_setScopeVariable(inner.scope, restParam, lit, false)) { interpreter->errorOutput("[internal] Could not define rest parameter\n"); //free, and skip out - freeLiteral(restType); - freeLiteral(lit); - popScope(inner.scope); + Toy_freeLiteral(restType); + Toy_freeLiteral(lit); + Toy_popScope(inner.scope); - freeLiteralArray(&inner.stack); - freeLiteralArray(&inner.literalCache); + Toy_freeLiteralArray(&inner.stack); + Toy_freeLiteralArray(&inner.literalCache); return false; } - freeLiteral(restType); - freeLiteralArray(&rest); + Toy_freeLiteral(restType); + Toy_freeLiteralArray(&rest); } //execute the interpreter @@ -1363,14 +1363,14 @@ bool callLiteralFn(Interpreter* interpreter, Literal func, LiteralArray* argumen interpreter->panic = inner.panic; //accept the stack as the results - LiteralArray returnsFromInner; - initLiteralArray(&returnsFromInner); + Toy_LiteralArray returnsFromInner; + Toy_initLiteralArray(&returnsFromInner); //unpack the results for (int i = 0; i < (returnArray->count || 1); i++) { - Literal lit = popLiteralArray(&inner.stack); - pushLiteralArray(&returnsFromInner, lit); //NOTE: also reverses the order - freeLiteral(lit); + Toy_Literal lit = Toy_popLiteralArray(&inner.stack); + Toy_pushLiteralArray(&returnsFromInner, lit); //NOTE: also reverses the order + Toy_freeLiteral(lit); } bool returnValue = true; @@ -1383,10 +1383,10 @@ bool callLiteralFn(Interpreter* interpreter, Literal func, LiteralArray* argumen } for (int i = 0; i < returnsFromInner.count && returnValue; i++) { - Literal ret = popLiteralArray(&returnsFromInner); + Toy_Literal ret = Toy_popLiteralArray(&returnsFromInner); //check the return types - if (returnArray->count > 0 && AS_TYPE(returnArray->literals[i]).typeOf != ret.type) { + if (returnArray->count > 0 && TOY_AS_TYPE(returnArray->literals[i]).typeOf != ret.type) { interpreter->errorOutput("Bad type found in return value\n"); //free, and skip out @@ -1394,250 +1394,250 @@ bool callLiteralFn(Interpreter* interpreter, Literal func, LiteralArray* argumen break; } - pushLiteralArray(returns, ret); //NOTE: reverses again - freeLiteral(ret); + Toy_pushLiteralArray(returns, ret); //NOTE: reverses again + Toy_freeLiteral(ret); } //manual free //BUGFIX: handle scopes of functions, which refer to the parent scope (leaking memory) - while(inner.scope != AS_FUNCTION(func).scope) { + while(inner.scope != TOY_AS_FUNCTION(func).scope) { for (int i = 0; i < inner.scope->variables.capacity; i++) { //handle keys, just in case - if (IS_FUNCTION(inner.scope->variables.entries[i].key)) { - popScope(AS_FUNCTION(inner.scope->variables.entries[i].key).scope); - AS_FUNCTION(inner.scope->variables.entries[i].key).scope = NULL; + if (TOY_IS_FUNCTION(inner.scope->variables.entries[i].key)) { + Toy_popScope(TOY_AS_FUNCTION(inner.scope->variables.entries[i].key).scope); + TOY_AS_FUNCTION(inner.scope->variables.entries[i].key).scope = NULL; } - if (IS_FUNCTION(inner.scope->variables.entries[i].value)) { - popScope(AS_FUNCTION(inner.scope->variables.entries[i].value).scope); - AS_FUNCTION(inner.scope->variables.entries[i].value).scope = NULL; + if (TOY_IS_FUNCTION(inner.scope->variables.entries[i].value)) { + Toy_popScope(TOY_AS_FUNCTION(inner.scope->variables.entries[i].value).scope); + TOY_AS_FUNCTION(inner.scope->variables.entries[i].value).scope = NULL; } } - inner.scope = popScope(inner.scope); + inner.scope = Toy_popScope(inner.scope); } - freeLiteralArray(&returnsFromInner); - freeLiteralArray(&inner.stack); - freeLiteralArray(&inner.literalCache); + Toy_freeLiteralArray(&returnsFromInner); + Toy_freeLiteralArray(&inner.stack); + Toy_freeLiteralArray(&inner.literalCache); //actual bytecode persists until next call return true; } -bool callFn(Interpreter* interpreter, char* name, LiteralArray* arguments, LiteralArray* returns) { - Literal key = TO_IDENTIFIER_LITERAL(createRefStringLength(name, strlen(name))); - Literal val = TO_NULL_LITERAL; +bool Toy_callFn(Toy_Interpreter* interpreter, char* name, Toy_LiteralArray* arguments, Toy_LiteralArray* returns) { + Toy_Literal key = TOY_TO_IDENTIFIER_LITERAL(Toy_createRefStringLength(name, strlen(name))); + Toy_Literal val = TOY_TO_NULL_LITERAL; - if (!isDelcaredScopeVariable(interpreter->scope, key)) { + if (!Toy_isDelcaredScopeVariable(interpreter->scope, key)) { interpreter->errorOutput("No function with that name\n"); return false; } - getScopeVariable(interpreter->scope, key, &val); + Toy_getScopeVariable(interpreter->scope, key, &val); - bool ret = callLiteralFn(interpreter, val, arguments, returns); + bool ret = Toy_callLiteralFn(interpreter, val, arguments, returns); - freeLiteral(key); - freeLiteral(val); + Toy_freeLiteral(key); + Toy_freeLiteral(val); return ret; } -static bool execFnReturn(Interpreter* interpreter) { - LiteralArray returns; - initLiteralArray(&returns); +static bool execFnReturn(Toy_Interpreter* interpreter) { + Toy_LiteralArray returns; + Toy_initLiteralArray(&returns); //get the values of everything on the stack while (interpreter->stack.count > 0) { - Literal lit = popLiteralArray(&interpreter->stack); - if (IS_IDENTIFIER(lit)) { - Literal idn = lit; - parseIdentifierToValue(interpreter, &lit); - freeLiteral(idn); + Toy_Literal lit = Toy_popLiteralArray(&interpreter->stack); + if (TOY_IS_IDENTIFIER(lit)) { + Toy_Literal idn = lit; + Toy_parseIdentifierToValue(interpreter, &lit); + Toy_freeLiteral(idn); } - if (IS_ARRAY(lit) || IS_DICTIONARY(lit)) { - parseCompoundToPureValues(interpreter, &lit); + if (TOY_IS_ARRAY(lit) || TOY_IS_DICTIONARY(lit)) { + Toy_parseCompoundToPureValues(interpreter, &lit); } - pushLiteralArray(&returns, lit); //reverses the order - freeLiteral(lit); + Toy_pushLiteralArray(&returns, lit); //reverses the order + Toy_freeLiteral(lit); } //and back again while (returns.count > 0) { - Literal lit = popLiteralArray(&returns); - pushLiteralArray(&interpreter->stack, lit); - freeLiteral(lit); + Toy_Literal lit = Toy_popLiteralArray(&returns); + Toy_pushLiteralArray(&interpreter->stack, lit); + Toy_freeLiteral(lit); } - freeLiteralArray(&returns); + Toy_freeLiteralArray(&returns); //finally return false; } -static bool execImport(Interpreter* interpreter) { - Literal alias = popLiteralArray(&interpreter->stack); - Literal identifier = popLiteralArray(&interpreter->stack); +static bool execImport(Toy_Interpreter* interpreter) { + Toy_Literal alias = Toy_popLiteralArray(&interpreter->stack); + Toy_Literal identifier = Toy_popLiteralArray(&interpreter->stack); //access the hooks - if (!existsLiteralDictionary(interpreter->hooks, identifier)) { + if (!Toy_existsLiteralDictionary(interpreter->hooks, identifier)) { interpreter->errorOutput("Unknown library name in import statement: "); - printLiteralCustom(identifier, interpreter->errorOutput); + Toy_printLiteralCustom(identifier, interpreter->errorOutput); interpreter->errorOutput("\"\n"); - freeLiteral(alias); - freeLiteral(identifier); + Toy_freeLiteral(alias); + Toy_freeLiteral(identifier); return false; } - Literal func = getLiteralDictionary(interpreter->hooks, identifier); + Toy_Literal func = Toy_getLiteralDictionary(interpreter->hooks, identifier); - if (!IS_FUNCTION_NATIVE(func)) { + if (!TOY_IS_FUNCTION_NATIVE(func)) { interpreter->errorOutput("Expected native function for a hook: "); - printLiteralCustom(identifier, interpreter->errorOutput); + Toy_printLiteralCustom(identifier, interpreter->errorOutput); interpreter->errorOutput("\"\n"); - freeLiteral(func); - freeLiteral(alias); - freeLiteral(identifier); + Toy_freeLiteral(func); + Toy_freeLiteral(alias); + Toy_freeLiteral(identifier); return false; } - HookFn fn = (HookFn)AS_FUNCTION(func).bytecode; + Toy_HookFn fn = (Toy_HookFn)TOY_AS_FUNCTION(func).bytecode; fn(interpreter, identifier, alias); - freeLiteral(func); - freeLiteral(alias); - freeLiteral(identifier); + Toy_freeLiteral(func); + Toy_freeLiteral(alias); + Toy_freeLiteral(identifier); return true; } -static bool execIndex(Interpreter* interpreter, bool assignIntermediate) { +static bool execIndex(Toy_Interpreter* interpreter, bool assignIntermediate) { //assume -> compound, first, second, third are all on the stack - Literal third = popLiteralArray(&interpreter->stack); - Literal second = popLiteralArray(&interpreter->stack); - Literal first = popLiteralArray(&interpreter->stack); - Literal compound = popLiteralArray(&interpreter->stack); + Toy_Literal third = Toy_popLiteralArray(&interpreter->stack); + Toy_Literal second = Toy_popLiteralArray(&interpreter->stack); + Toy_Literal first = Toy_popLiteralArray(&interpreter->stack); + Toy_Literal compound = Toy_popLiteralArray(&interpreter->stack); - Literal idn = compound; + Toy_Literal idn = compound; bool freeIdn = false; - if (IS_IDENTIFIER(compound)) { + if (TOY_IS_IDENTIFIER(compound)) { freeIdn = true; - if (!parseIdentifierToValue(interpreter, &compound)) { - freeLiteral(third); - freeLiteral(second); - freeLiteral(first); - freeLiteral(compound); + if (!Toy_parseIdentifierToValue(interpreter, &compound)) { + Toy_freeLiteral(third); + Toy_freeLiteral(second); + Toy_freeLiteral(first); + Toy_freeLiteral(compound); //freeLiteral(idn); //since compound is freed, idn is still pointing there return false; } } - if (!IS_ARRAY(compound) && !IS_DICTIONARY(compound) && !IS_STRING(compound)) { + if (!TOY_IS_ARRAY(compound) && !TOY_IS_DICTIONARY(compound) && !TOY_IS_STRING(compound)) { interpreter->errorOutput("Unknown compound found in indexing notation: "); - printLiteralCustom(compound, interpreter->errorOutput); - freeLiteral(third); - freeLiteral(second); - freeLiteral(first); - freeLiteral(compound); + Toy_printLiteralCustom(compound, interpreter->errorOutput); + Toy_freeLiteral(third); + Toy_freeLiteral(second); + Toy_freeLiteral(first); + Toy_freeLiteral(compound); if (freeIdn) { - freeLiteral(idn); + Toy_freeLiteral(idn); } return false; } //build the argument list - LiteralArray arguments; - initLiteralArray(&arguments); + Toy_LiteralArray arguments; + Toy_initLiteralArray(&arguments); - pushLiteralArray(&arguments, compound); - pushLiteralArray(&arguments, first); - pushLiteralArray(&arguments, second); - pushLiteralArray(&arguments, third); - pushLiteralArray(&arguments, TO_NULL_LITERAL); //it expects an assignment command - pushLiteralArray(&arguments, TO_NULL_LITERAL); //it expects an assignment "opcode" + Toy_pushLiteralArray(&arguments, compound); + Toy_pushLiteralArray(&arguments, first); + Toy_pushLiteralArray(&arguments, second); + Toy_pushLiteralArray(&arguments, third); + Toy_pushLiteralArray(&arguments, TOY_TO_NULL_LITERAL); //it expects an assignment command + Toy_pushLiteralArray(&arguments, TOY_TO_NULL_LITERAL); //it expects an assignment "opcode" //leave the idn and compound on the stack if (assignIntermediate) { - if (IS_IDENTIFIER(idn)) { - pushLiteralArray(&interpreter->stack, idn); + if (TOY_IS_IDENTIFIER(idn)) { + Toy_pushLiteralArray(&interpreter->stack, idn); } - pushLiteralArray(&interpreter->stack, compound); - pushLiteralArray(&interpreter->stack, first); - pushLiteralArray(&interpreter->stack, second); - pushLiteralArray(&interpreter->stack, third); + Toy_pushLiteralArray(&interpreter->stack, compound); + Toy_pushLiteralArray(&interpreter->stack, first); + Toy_pushLiteralArray(&interpreter->stack, second); + Toy_pushLiteralArray(&interpreter->stack, third); } //call the _index function if (_index(interpreter, &arguments) < 0) { interpreter->errorOutput("Something went wrong while indexing: "); - printLiteralCustom(idn, interpreter->errorOutput); + Toy_printLiteralCustom(idn, interpreter->errorOutput); interpreter->errorOutput("\n"); //clean up - freeLiteral(third); - freeLiteral(second); - freeLiteral(first); - freeLiteral(compound); + Toy_freeLiteral(third); + Toy_freeLiteral(second); + Toy_freeLiteral(first); + Toy_freeLiteral(compound); if (freeIdn) { - freeLiteral(idn); + Toy_freeLiteral(idn); } - freeLiteralArray(&arguments); + Toy_freeLiteralArray(&arguments); return false; } //clean up - freeLiteral(third); - freeLiteral(second); - freeLiteral(first); - freeLiteral(compound); + Toy_freeLiteral(third); + Toy_freeLiteral(second); + Toy_freeLiteral(first); + Toy_freeLiteral(compound); if (freeIdn) { - freeLiteral(idn); + Toy_freeLiteral(idn); } - freeLiteralArray(&arguments); + Toy_freeLiteralArray(&arguments); return true; } -static bool execIndexAssign(Interpreter* interpreter) { +static bool execIndexAssign(Toy_Interpreter* interpreter) { //assume -> compound, first, second, third, assign are all on the stack - Literal assign = popLiteralArray(&interpreter->stack); - Literal third = popLiteralArray(&interpreter->stack); - Literal second = popLiteralArray(&interpreter->stack); - Literal first = popLiteralArray(&interpreter->stack); - Literal compound = popLiteralArray(&interpreter->stack); + Toy_Literal assign = Toy_popLiteralArray(&interpreter->stack); + Toy_Literal third = Toy_popLiteralArray(&interpreter->stack); + Toy_Literal second = Toy_popLiteralArray(&interpreter->stack); + Toy_Literal first = Toy_popLiteralArray(&interpreter->stack); + Toy_Literal compound = Toy_popLiteralArray(&interpreter->stack); - Literal idn = compound; + Toy_Literal idn = compound; bool freeIdn = false; - if (IS_IDENTIFIER(compound)) { + if (TOY_IS_IDENTIFIER(compound)) { freeIdn = true; - if (!parseIdentifierToValue(interpreter, &compound)) { - freeLiteral(assign); - freeLiteral(third); - freeLiteral(second); - freeLiteral(first); - freeLiteral(compound); - freeLiteral(idn); + if (!Toy_parseIdentifierToValue(interpreter, &compound)) { + Toy_freeLiteral(assign); + Toy_freeLiteral(third); + Toy_freeLiteral(second); + Toy_freeLiteral(first); + Toy_freeLiteral(compound); + Toy_freeLiteral(idn); return false; } } - if (!IS_ARRAY(compound) && !IS_DICTIONARY(compound) && !IS_STRING(compound)) { + if (!TOY_IS_ARRAY(compound) && !TOY_IS_DICTIONARY(compound) && !TOY_IS_STRING(compound)) { interpreter->errorOutput("Unknown compound found in index assigning notation\n"); - freeLiteral(assign); - freeLiteral(third); - freeLiteral(second); - freeLiteral(first); - freeLiteral(compound); + Toy_freeLiteral(assign); + Toy_freeLiteral(third); + Toy_freeLiteral(second); + Toy_freeLiteral(first); + Toy_freeLiteral(compound); if (freeIdn) { - freeLiteral(idn); + Toy_freeLiteral(idn); } return false; } @@ -1646,168 +1646,168 @@ static bool execIndexAssign(Interpreter* interpreter) { unsigned char opcode = readByte(interpreter->bytecode, &interpreter->count); char* opStr = ""; switch(opcode) { - case OP_VAR_ASSIGN: + case TOY_OP_VAR_ASSIGN: opStr = "="; break; - case OP_VAR_ADDITION_ASSIGN: + case TOY_OP_VAR_ADDITION_ASSIGN: opStr = "+="; break; - case OP_VAR_SUBTRACTION_ASSIGN: + case TOY_OP_VAR_SUBTRACTION_ASSIGN: opStr = "-="; break; - case OP_VAR_MULTIPLICATION_ASSIGN: + case TOY_OP_VAR_MULTIPLICATION_ASSIGN: opStr = "*="; break; - case OP_VAR_DIVISION_ASSIGN: + case TOY_OP_VAR_DIVISION_ASSIGN: opStr = "/="; break; - case OP_VAR_MODULO_ASSIGN: + case TOY_OP_VAR_MODULO_ASSIGN: opStr = "%="; break; default: interpreter->errorOutput("bad opcode in index assigning notation\n"); - freeLiteral(assign); - freeLiteral(third); - freeLiteral(second); - freeLiteral(first); - freeLiteral(compound); + Toy_freeLiteral(assign); + Toy_freeLiteral(third); + Toy_freeLiteral(second); + Toy_freeLiteral(first); + Toy_freeLiteral(compound); if (freeIdn) { - freeLiteral(idn); + Toy_freeLiteral(idn); } return false; } int opLength = strlen(opStr); - Literal op = TO_STRING_LITERAL(createRefStringLength(opStr, opLength)); //TODO: static reference optimisation? + Toy_Literal op = TOY_TO_STRING_LITERAL(Toy_createRefStringLength(opStr, opLength)); //TODO: static reference optimisation? //build the argument list - LiteralArray arguments; - initLiteralArray(&arguments); + Toy_LiteralArray arguments; + Toy_initLiteralArray(&arguments); - pushLiteralArray(&arguments, compound); - pushLiteralArray(&arguments, first); - pushLiteralArray(&arguments, second); - pushLiteralArray(&arguments, third); - pushLiteralArray(&arguments, assign); //it expects an assignment command - pushLiteralArray(&arguments, op); //it expects an assignment "opcode" + Toy_pushLiteralArray(&arguments, compound); + Toy_pushLiteralArray(&arguments, first); + Toy_pushLiteralArray(&arguments, second); + Toy_pushLiteralArray(&arguments, third); + Toy_pushLiteralArray(&arguments, assign); //it expects an assignment command + Toy_pushLiteralArray(&arguments, op); //it expects an assignment "opcode" //call the _index function if (_index(interpreter, &arguments) < 0) { //clean up - freeLiteral(assign); - freeLiteral(third); - freeLiteral(second); - freeLiteral(first); - freeLiteral(compound); + Toy_freeLiteral(assign); + Toy_freeLiteral(third); + Toy_freeLiteral(second); + Toy_freeLiteral(first); + Toy_freeLiteral(compound); if (freeIdn) { - freeLiteral(idn); + Toy_freeLiteral(idn); } - freeLiteral(op); - freeLiteralArray(&arguments); + Toy_freeLiteral(op); + Toy_freeLiteralArray(&arguments); return false; } //save the result (assume top of the interpreter stack is the new compound value) - Literal result = popLiteralArray(&interpreter->stack); + Toy_Literal result = Toy_popLiteralArray(&interpreter->stack); //if idn is NOT an identifier, assign backwards while there are things on the stack (inner-compound assignment, BIG assumptions here) - if (!IS_IDENTIFIER(idn)) { + if (!TOY_IS_IDENTIFIER(idn)) { while (interpreter->stack.count > 1) { //read the new values - freeLiteral(idn); - freeLiteral(third); - freeLiteral(second); - freeLiteral(first); - freeLiteralArray(&arguments); - initLiteralArray(&arguments); - freeLiteral(op); + Toy_freeLiteral(idn); + Toy_freeLiteral(third); + Toy_freeLiteral(second); + Toy_freeLiteral(first); + Toy_freeLiteralArray(&arguments); + Toy_initLiteralArray(&arguments); + Toy_freeLiteral(op); - third = popLiteralArray(&interpreter->stack); - second = popLiteralArray(&interpreter->stack); - first = popLiteralArray(&interpreter->stack); - idn = popLiteralArray(&interpreter->stack); + third = Toy_popLiteralArray(&interpreter->stack); + second = Toy_popLiteralArray(&interpreter->stack); + first = Toy_popLiteralArray(&interpreter->stack); + idn = Toy_popLiteralArray(&interpreter->stack); char* opStr = "="; //shadow, but force assignment int opLength = strlen(opStr); - op = TO_STRING_LITERAL(createRefStringLength(opStr, opLength)); //TODO: static reference optimisation? + op = TOY_TO_STRING_LITERAL(Toy_createRefStringLength(opStr, opLength)); //TODO: static reference optimisation? //assign to the idn / compound - with _index - pushLiteralArray(&arguments, idn); - pushLiteralArray(&arguments, first); - pushLiteralArray(&arguments, second); - pushLiteralArray(&arguments, third); - pushLiteralArray(&arguments, result); - pushLiteralArray(&arguments, op); + Toy_pushLiteralArray(&arguments, idn); + Toy_pushLiteralArray(&arguments, first); + Toy_pushLiteralArray(&arguments, second); + Toy_pushLiteralArray(&arguments, third); + Toy_pushLiteralArray(&arguments, result); + Toy_pushLiteralArray(&arguments, op); if (_index(interpreter, &arguments) < 0) { interpreter->errorOutput("Something went wrong while indexing: "); - printLiteralCustom(idn, interpreter->errorOutput); + Toy_printLiteralCustom(idn, interpreter->errorOutput); interpreter->errorOutput("\n"); //clean up - freeLiteral(assign); - freeLiteral(third); - freeLiteral(second); - freeLiteral(first); - freeLiteral(compound); + Toy_freeLiteral(assign); + Toy_freeLiteral(third); + Toy_freeLiteral(second); + Toy_freeLiteral(first); + Toy_freeLiteral(compound); if (freeIdn) { - freeLiteral(idn); + Toy_freeLiteral(idn); } - freeLiteral(op); - freeLiteralArray(&arguments); - freeLiteral(result); + Toy_freeLiteral(op); + Toy_freeLiteralArray(&arguments); + Toy_freeLiteral(result); return false; } - freeLiteral(result); - result = popLiteralArray(&interpreter->stack); + Toy_freeLiteral(result); + result = Toy_popLiteralArray(&interpreter->stack); } - freeLiteral(idn); - idn = popLiteralArray(&interpreter->stack); + Toy_freeLiteral(idn); + idn = Toy_popLiteralArray(&interpreter->stack); compound = idn; } - if (IS_IDENTIFIER(idn) && !setScopeVariable(interpreter->scope, idn, result, true)) { + if (TOY_IS_IDENTIFIER(idn) && !Toy_setScopeVariable(interpreter->scope, idn, result, true)) { interpreter->errorOutput("Incorrect type assigned to compound member "); - printLiteralCustom(idn, interpreter->errorOutput); + Toy_printLiteralCustom(idn, interpreter->errorOutput); interpreter->errorOutput("\n"); //clean up - freeLiteral(assign); - freeLiteral(third); - freeLiteral(second); - freeLiteral(first); - freeLiteral(compound); + Toy_freeLiteral(assign); + Toy_freeLiteral(third); + Toy_freeLiteral(second); + Toy_freeLiteral(first); + Toy_freeLiteral(compound); if (freeIdn) { - freeLiteral(idn); + Toy_freeLiteral(idn); } - freeLiteral(op); - freeLiteralArray(&arguments); - freeLiteral(result); + Toy_freeLiteral(op); + Toy_freeLiteralArray(&arguments); + Toy_freeLiteral(result); return false; } //clean up - freeLiteral(assign); - freeLiteral(third); - freeLiteral(second); - freeLiteral(first); - freeLiteral(compound); + Toy_freeLiteral(assign); + Toy_freeLiteral(third); + Toy_freeLiteral(second); + Toy_freeLiteral(first); + Toy_freeLiteral(compound); if (freeIdn) { - freeLiteral(idn); + Toy_freeLiteral(idn); } - freeLiteral(op); - freeLiteralArray(&arguments); - freeLiteral(result); + Toy_freeLiteral(op); + Toy_freeLiteralArray(&arguments); + Toy_freeLiteral(result); return true; } //the heart of toy -static void execInterpreter(Interpreter* interpreter) { +static void execInterpreter(Toy_Interpreter* interpreter) { //set the starting point for the interpreter if (interpreter->codeStart == -1) { interpreter->codeStart = interpreter->count; @@ -1815,57 +1815,57 @@ static void execInterpreter(Interpreter* interpreter) { unsigned char opcode = readByte(interpreter->bytecode, &interpreter->count); - while(opcode != OP_EOF && opcode != OP_SECTION_END && !interpreter->panic) { + while(opcode != TOY_OP_EOF && opcode != TOY_OP_SECTION_END && !interpreter->panic) { switch(opcode) { - case OP_ASSERT: + case TOY_OP_ASSERT: if (!execAssert(interpreter)) { return; } break; - case OP_PRINT: + case TOY_OP_PRINT: if (!execPrint(interpreter)) { return; } break; - case OP_LITERAL: - case OP_LITERAL_LONG: - if (!execPushLiteral(interpreter, opcode == OP_LITERAL_LONG)) { + case TOY_OP_LITERAL: + case TOY_OP_LITERAL_LONG: + if (!execPushLiteral(interpreter, opcode == TOY_OP_LITERAL_LONG)) { return; } break; - case OP_LITERAL_RAW: + case TOY_OP_LITERAL_RAW: if (!rawLiteral(interpreter)) { return; } break; - case OP_NEGATE: + case TOY_OP_NEGATE: if (!execNegate(interpreter)) { return; } break; - case OP_ADDITION: - case OP_SUBTRACTION: - case OP_MULTIPLICATION: - case OP_DIVISION: - case OP_MODULO: + case TOY_OP_ADDITION: + case TOY_OP_SUBTRACTION: + case TOY_OP_MULTIPLICATION: + case TOY_OP_DIVISION: + case TOY_OP_MODULO: if (!execArithmetic(interpreter, opcode)) { return; } break; - case OP_VAR_ADDITION_ASSIGN: - case OP_VAR_SUBTRACTION_ASSIGN: - case OP_VAR_MULTIPLICATION_ASSIGN: - case OP_VAR_DIVISION_ASSIGN: - case OP_VAR_MODULO_ASSIGN: + case TOY_OP_VAR_ADDITION_ASSIGN: + case TOY_OP_VAR_SUBTRACTION_ASSIGN: + case TOY_OP_VAR_MULTIPLICATION_ASSIGN: + case TOY_OP_VAR_DIVISION_ASSIGN: + case TOY_OP_VAR_MODULO_ASSIGN: execVarArithmeticAssign(interpreter); if (!execArithmetic(interpreter, opcode)) { - freeLiteral(popLiteralArray(&interpreter->stack)); + Toy_freeLiteral(Toy_popLiteralArray(&interpreter->stack)); return; } if (!execVarAssign(interpreter)) { @@ -1873,168 +1873,168 @@ static void execInterpreter(Interpreter* interpreter) { } break; - case OP_GROUPING_BEGIN: + case TOY_OP_GROUPING_BEGIN: execInterpreter(interpreter); break; - case OP_GROUPING_END: + case TOY_OP_GROUPING_END: return; //scope - case OP_SCOPE_BEGIN: - interpreter->scope = pushScope(interpreter->scope); + case TOY_OP_SCOPE_BEGIN: + interpreter->scope = Toy_pushScope(interpreter->scope); break; - case OP_SCOPE_END: - interpreter->scope = popScope(interpreter->scope); + case TOY_OP_SCOPE_END: + interpreter->scope = Toy_popScope(interpreter->scope); break; //TODO: custom type declarations? - case OP_VAR_DECL: - case OP_VAR_DECL_LONG: - if (!execVarDecl(interpreter, opcode == OP_VAR_DECL_LONG)) { + case TOY_OP_VAR_DECL: + case TOY_OP_VAR_DECL_LONG: + if (!execVarDecl(interpreter, opcode == TOY_OP_VAR_DECL_LONG)) { return; } break; - case OP_FN_DECL: - case OP_FN_DECL_LONG: - if (!execFnDecl(interpreter, opcode == OP_FN_DECL_LONG)) { + case TOY_OP_FN_DECL: + case TOY_OP_FN_DECL_LONG: + if (!execFnDecl(interpreter, opcode == TOY_OP_FN_DECL_LONG)) { return; } break; - case OP_VAR_ASSIGN: + case TOY_OP_VAR_ASSIGN: if (!execVarAssign(interpreter)) { return; } break; - case OP_TYPE_CAST: + case TOY_OP_TYPE_CAST: if (!execValCast(interpreter)) { return; } break; - case OP_TYPE_OF: + case TOY_OP_TYPE_OF: if (!execTypeOf(interpreter)) { return; } break; - case OP_COMPARE_EQUAL: + case TOY_OP_COMPARE_EQUAL: if (!execCompareEqual(interpreter, false)) { return; } break; - case OP_COMPARE_NOT_EQUAL: + case TOY_OP_COMPARE_NOT_EQUAL: if (!execCompareEqual(interpreter, true)) { return; } break; - case OP_COMPARE_LESS: + case TOY_OP_COMPARE_LESS: if (!execCompareLess(interpreter, false)) { return; } break; - case OP_COMPARE_LESS_EQUAL: + case TOY_OP_COMPARE_LESS_EQUAL: if (!execCompareLessEqual(interpreter, false)) { return; } break; - case OP_COMPARE_GREATER: + case TOY_OP_COMPARE_GREATER: if (!execCompareLess(interpreter, true)) { return; } break; - case OP_COMPARE_GREATER_EQUAL: + case TOY_OP_COMPARE_GREATER_EQUAL: if (!execCompareLessEqual(interpreter, true)) { return; } break; - case OP_INVERT: + case TOY_OP_INVERT: if (!execInvert(interpreter)) { return; } break; - case OP_AND: + case TOY_OP_AND: if (!execAnd(interpreter)) { return; } break; - case OP_OR: + case TOY_OP_OR: if (!execOr(interpreter)) { return; } break; - case OP_JUMP: + case TOY_OP_JUMP: if (!execJump(interpreter)) { return; } break; - case OP_IF_FALSE_JUMP: + case TOY_OP_IF_FALSE_JUMP: if (!execFalseJump(interpreter)) { return; } break; - case OP_FN_CALL: + case TOY_OP_FN_CALL: if (!execFnCall(interpreter, false)) { return; } break; - case OP_DOT: + case TOY_OP_DOT: if (!execFnCall(interpreter, true)) { //compensate for the out-of-order arguments return; } break; - case OP_FN_RETURN: + case TOY_OP_FN_RETURN: if (!execFnReturn(interpreter)) { return; } break; - case OP_IMPORT: + case TOY_OP_IMPORT: if (!execImport(interpreter)) { return; } break; - case OP_INDEX: + case TOY_OP_INDEX: if (!execIndex(interpreter, false)) { return; } break; - case OP_INDEX_ASSIGN_INTERMEDIATE: + case TOY_OP_INDEX_ASSIGN_INTERMEDIATE: if (!execIndex(interpreter, true)) { return; } break; - case OP_INDEX_ASSIGN: + case TOY_OP_INDEX_ASSIGN: if (!execIndexAssign(interpreter)) { return; } break; - case OP_POP_STACK: + case TOY_OP_POP_STACK: while (interpreter->stack.count > 0) { - freeLiteral(popLiteralArray(&interpreter->stack)); + Toy_freeLiteral(Toy_popLiteralArray(&interpreter->stack)); } break; @@ -2047,13 +2047,13 @@ static void execInterpreter(Interpreter* interpreter) { } } -static void readInterpreterSections(Interpreter* interpreter) { +static void readInterpreterSections(Toy_Interpreter* interpreter) { //data section const unsigned short literalCount = readShort(interpreter->bytecode, &interpreter->count); #ifndef TOY_EXPORT if (command.verbose) { - printf(NOTICE "Reading %d literals\n" RESET, literalCount); + printf(TOY_CC_NOTICE "Reading %d literals\n" TOY_CC_RESET, literalCount); } #endif @@ -2061,9 +2061,9 @@ static void readInterpreterSections(Interpreter* interpreter) { const unsigned char literalType = readByte(interpreter->bytecode, &interpreter->count); switch(literalType) { - case LITERAL_NULL: + case TOY_LITERAL_NULL: //read the null - pushLiteralArray(&interpreter->literalCache, TO_NULL_LITERAL); + Toy_pushLiteralArray(&interpreter->literalCache, TOY_TO_NULL_LITERAL); #ifndef TOY_EXPORT if (command.verbose) { @@ -2072,12 +2072,12 @@ static void readInterpreterSections(Interpreter* interpreter) { #endif break; - case LITERAL_BOOLEAN: { + case TOY_LITERAL_BOOLEAN: { //read the booleans const bool b = readByte(interpreter->bytecode, &interpreter->count); - Literal literal = TO_BOOLEAN_LITERAL(b); - pushLiteralArray(&interpreter->literalCache, literal); - freeLiteral(literal); + Toy_Literal literal = TOY_TO_BOOLEAN_LITERAL(b); + Toy_pushLiteralArray(&interpreter->literalCache, literal); + Toy_freeLiteral(literal); #ifndef TOY_EXPORT if (command.verbose) { @@ -2087,11 +2087,11 @@ static void readInterpreterSections(Interpreter* interpreter) { } break; - case LITERAL_INTEGER: { + case TOY_LITERAL_INTEGER: { const int d = readInt(interpreter->bytecode, &interpreter->count); - Literal literal = TO_INTEGER_LITERAL(d); - pushLiteralArray(&interpreter->literalCache, literal); - freeLiteral(literal); + Toy_Literal literal = TOY_TO_INTEGER_LITERAL(d); + Toy_pushLiteralArray(&interpreter->literalCache, literal); + Toy_freeLiteral(literal); #ifndef TOY_EXPORT if (command.verbose) { @@ -2101,11 +2101,11 @@ static void readInterpreterSections(Interpreter* interpreter) { } break; - case LITERAL_FLOAT: { + case TOY_LITERAL_FLOAT: { const float f = readFloat(interpreter->bytecode, &interpreter->count); - Literal literal = TO_FLOAT_LITERAL(f); - pushLiteralArray(&interpreter->literalCache, literal); - freeLiteral(literal); + Toy_Literal literal = TOY_TO_FLOAT_LITERAL(f); + Toy_pushLiteralArray(&interpreter->literalCache, literal); + Toy_freeLiteral(literal); #ifndef TOY_EXPORT if (command.verbose) { @@ -2115,12 +2115,12 @@ static void readInterpreterSections(Interpreter* interpreter) { } break; - case LITERAL_STRING: { + case TOY_LITERAL_STRING: { char* s = readString(interpreter->bytecode, &interpreter->count); int length = strlen(s); - Literal literal = TO_STRING_LITERAL(createRefStringLength(s, length)); - pushLiteralArray(&interpreter->literalCache, literal); - freeLiteral(literal); + Toy_Literal literal = TOY_TO_STRING_LITERAL(Toy_createRefStringLength(s, length)); + Toy_pushLiteralArray(&interpreter->literalCache, literal); + Toy_freeLiteral(literal); #ifndef TOY_EXPORT if (command.verbose) { @@ -2130,39 +2130,39 @@ static void readInterpreterSections(Interpreter* interpreter) { } break; - case LITERAL_ARRAY: { - LiteralArray* array = ALLOCATE(LiteralArray, 1); - initLiteralArray(array); + case TOY_LITERAL_ARRAY: { + Toy_LiteralArray* array = TOY_ALLOCATE(Toy_LiteralArray, 1); + Toy_initLiteralArray(array); unsigned short length = readShort(interpreter->bytecode, &interpreter->count); //read each index, then unpack the value from the existing literal cache for (int i = 0; i < length; i++) { int index = readShort(interpreter->bytecode, &interpreter->count); - pushLiteralArray(array, interpreter->literalCache.literals[index]); + Toy_pushLiteralArray(array, interpreter->literalCache.literals[index]); } #ifndef TOY_EXPORT if (command.verbose) { printf("(array "); - Literal literal = TO_ARRAY_LITERAL(array); - printLiteral(literal); + Toy_Literal literal = TOY_TO_ARRAY_LITERAL(array); + Toy_printLiteral(literal); printf(")\n"); } #endif //finally, push the array proper - Literal literal = TO_ARRAY_LITERAL(array); - pushLiteralArray(&interpreter->literalCache, literal); //copied + Toy_Literal literal = TOY_TO_ARRAY_LITERAL(array); + Toy_pushLiteralArray(&interpreter->literalCache, literal); //copied - freeLiteralArray(array); - FREE(LiteralArray, array); + Toy_freeLiteralArray(array); + TOY_FREE(Toy_LiteralArray, array); } break; - case LITERAL_DICTIONARY: { - LiteralDictionary* dictionary = ALLOCATE(LiteralDictionary, 1); - initLiteralDictionary(dictionary); + case TOY_LITERAL_DICTIONARY: { + Toy_LiteralDictionary* dictionary = TOY_ALLOCATE(Toy_LiteralDictionary, 1); + Toy_initLiteralDictionary(dictionary); unsigned short length = readShort(interpreter->bytecode, &interpreter->count); @@ -2170,37 +2170,37 @@ static void readInterpreterSections(Interpreter* interpreter) { for (int i = 0; i < length / 2; i++) { int key = readShort(interpreter->bytecode, &interpreter->count); int val = readShort(interpreter->bytecode, &interpreter->count); - setLiteralDictionary(dictionary, interpreter->literalCache.literals[key], interpreter->literalCache.literals[val]); + Toy_setLiteralDictionary(dictionary, interpreter->literalCache.literals[key], interpreter->literalCache.literals[val]); } #ifndef TOY_EXPORT if (command.verbose) { printf("(dictionary "); - Literal literal = TO_DICTIONARY_LITERAL(dictionary); - printLiteral(literal); + Toy_Literal literal = TOY_TO_DICTIONARY_LITERAL(dictionary); + Toy_printLiteral(literal); printf(")\n"); } #endif //finally, push the dictionary proper - Literal literal = TO_DICTIONARY_LITERAL(dictionary); - pushLiteralArray(&interpreter->literalCache, literal); //copied + Toy_Literal literal = TOY_TO_DICTIONARY_LITERAL(dictionary); + Toy_pushLiteralArray(&interpreter->literalCache, literal); //copied - freeLiteralDictionary(dictionary); - FREE(LiteralDictionary, dictionary); + Toy_freeLiteralDictionary(dictionary); + TOY_FREE(Toy_LiteralDictionary, dictionary); } break; - case LITERAL_FUNCTION: { + case TOY_LITERAL_FUNCTION: { //read the index unsigned short index = readShort(interpreter->bytecode, &interpreter->count); - Literal literal = TO_INTEGER_LITERAL(index); + Toy_Literal literal = TOY_TO_INTEGER_LITERAL(index); //change the type, to read it PROPERLY below - literal.type = LITERAL_FUNCTION_INTERMEDIATE; + literal.type = TOY_LITERAL_FUNCTION_INTERMEDIATE; //push to the literal cache - pushLiteralArray(&interpreter->literalCache, literal); + Toy_pushLiteralArray(&interpreter->literalCache, literal); #ifndef TOY_EXPORT if (command.verbose) { @@ -2210,84 +2210,84 @@ static void readInterpreterSections(Interpreter* interpreter) { } break; - case LITERAL_IDENTIFIER: { + case TOY_LITERAL_IDENTIFIER: { char* str = readString(interpreter->bytecode, &interpreter->count); int length = strlen(str); - Literal identifier = TO_IDENTIFIER_LITERAL(createRefStringLength(str, length)); + Toy_Literal identifier = TOY_TO_IDENTIFIER_LITERAL(Toy_createRefStringLength(str, length)); - pushLiteralArray(&interpreter->literalCache, identifier); + Toy_pushLiteralArray(&interpreter->literalCache, identifier); #ifndef TOY_EXPORT if (command.verbose) { - printf("(identifier %s (hash: %x))\n", toCString(AS_IDENTIFIER(identifier)), identifier.as.identifier.hash); + printf("(identifier %s (hash: %x))\n", Toy_toCString(TOY_AS_IDENTIFIER(identifier)), identifier.as.identifier.hash); } #endif - freeLiteral(identifier); + Toy_freeLiteral(identifier); } break; - case LITERAL_TYPE: { + case TOY_LITERAL_TYPE: { //what the literal is - LiteralType literalType = (LiteralType)readByte(interpreter->bytecode, &interpreter->count); + Toy_LiteralType literalType = (Toy_LiteralType)readByte(interpreter->bytecode, &interpreter->count); unsigned char constant = readByte(interpreter->bytecode, &interpreter->count); - Literal typeLiteral = TO_TYPE_LITERAL(literalType, constant); + Toy_Literal typeLiteral = TOY_TO_TYPE_LITERAL(literalType, constant); //save the type - pushLiteralArray(&interpreter->literalCache, typeLiteral); + Toy_pushLiteralArray(&interpreter->literalCache, typeLiteral); #ifndef TOY_EXPORT if (command.verbose) { printf("(type "); - printLiteral(typeLiteral); + Toy_printLiteral(typeLiteral); printf(")\n"); } #endif } break; - case LITERAL_TYPE_INTERMEDIATE: { + case TOY_LITERAL_TYPE_INTERMEDIATE: { //what the literal represents - LiteralType literalType = (LiteralType)readByte(interpreter->bytecode, &interpreter->count); + Toy_LiteralType literalType = (Toy_LiteralType)readByte(interpreter->bytecode, &interpreter->count); unsigned char constant = readByte(interpreter->bytecode, &interpreter->count); - Literal typeLiteral = TO_TYPE_LITERAL(literalType, constant); + Toy_Literal typeLiteral = TOY_TO_TYPE_LITERAL(literalType, constant); //if it's an array type - if (AS_TYPE(typeLiteral).typeOf == LITERAL_ARRAY) { + if (TOY_AS_TYPE(typeLiteral).typeOf == TOY_LITERAL_ARRAY) { unsigned short vt = readShort(interpreter->bytecode, &interpreter->count); - TYPE_PUSH_SUBTYPE(&typeLiteral, copyLiteral(interpreter->literalCache.literals[vt])); + TOY_TYPE_PUSH_SUBTYPE(&typeLiteral, Toy_copyLiteral(interpreter->literalCache.literals[vt])); } - if (AS_TYPE(typeLiteral).typeOf == LITERAL_DICTIONARY) { + if (TOY_AS_TYPE(typeLiteral).typeOf == TOY_LITERAL_DICTIONARY) { unsigned short kt = readShort(interpreter->bytecode, &interpreter->count); unsigned short vt = readShort(interpreter->bytecode, &interpreter->count); - TYPE_PUSH_SUBTYPE(&typeLiteral, copyLiteral(interpreter->literalCache.literals[kt])); - TYPE_PUSH_SUBTYPE(&typeLiteral, copyLiteral(interpreter->literalCache.literals[vt])); + TOY_TYPE_PUSH_SUBTYPE(&typeLiteral, Toy_copyLiteral(interpreter->literalCache.literals[kt])); + TOY_TYPE_PUSH_SUBTYPE(&typeLiteral, Toy_copyLiteral(interpreter->literalCache.literals[vt])); } //save the type - pushLiteralArray(&interpreter->literalCache, typeLiteral); //copied + Toy_pushLiteralArray(&interpreter->literalCache, typeLiteral); //copied #ifndef TOY_EXPORT if (command.verbose) { printf("(type "); - printLiteral(typeLiteral); + Toy_printLiteral(typeLiteral); printf(")\n"); } #endif - freeLiteral(typeLiteral); + Toy_freeLiteral(typeLiteral); } break; - case LITERAL_INDEX_BLANK: + case TOY_LITERAL_INDEX_BLANK: //read the blank - pushLiteralArray(&interpreter->literalCache, TO_INDEX_BLANK_LITERAL); + Toy_pushLiteralArray(&interpreter->literalCache, TOY_TO_INDEX_BLANK_LITERAL); #ifndef TOY_EXPORT if (command.verbose) { @@ -2298,7 +2298,7 @@ static void readInterpreterSections(Interpreter* interpreter) { } } - consumeByte(interpreter, OP_SECTION_END, interpreter->bytecode, &interpreter->count); //terminate the literal section + consumeByte(interpreter, TOY_OP_SECTION_END, interpreter->bytecode, &interpreter->count); //terminate the literal section //read the function metadata int functionCount = readShort(interpreter->bytecode, &interpreter->count); @@ -2306,54 +2306,54 @@ static void readInterpreterSections(Interpreter* interpreter) { //read in the functions for (int i = 0; i < interpreter->literalCache.count; i++) { - if (interpreter->literalCache.literals[i].type == LITERAL_FUNCTION_INTERMEDIATE) { + if (interpreter->literalCache.literals[i].type == TOY_LITERAL_FUNCTION_INTERMEDIATE) { //get the size of the function size_t size = (size_t)readShort(interpreter->bytecode, &interpreter->count); //read the function code (literal cache and all) - unsigned char* bytes = ALLOCATE(unsigned char, size); + unsigned char* bytes = TOY_ALLOCATE(unsigned char, size); memcpy(bytes, interpreter->bytecode + interpreter->count, size); //TODO: -1 for the ending mark interpreter->count += size; //assert that the last memory slot is function end - if (bytes[size - 1] != OP_FN_END) { + if (bytes[size - 1] != TOY_OP_FN_END) { interpreter->errorOutput("[internal] Failed to find function end"); - FREE_ARRAY(unsigned char, bytes, size); + TOY_FREE_ARRAY(unsigned char, bytes, size); return; } //change the type to normal - interpreter->literalCache.literals[i] = TO_FUNCTION_LITERAL(bytes, size); - AS_FUNCTION(interpreter->literalCache.literals[i]).scope = NULL; + interpreter->literalCache.literals[i] = TOY_TO_FUNCTION_LITERAL(bytes, size); + TOY_AS_FUNCTION(interpreter->literalCache.literals[i]).scope = NULL; } } - consumeByte(interpreter, OP_SECTION_END, interpreter->bytecode, &interpreter->count); //terminate the function section + consumeByte(interpreter, TOY_OP_SECTION_END, interpreter->bytecode, &interpreter->count); //terminate the function section } //exposed functions -void initInterpreter(Interpreter* interpreter) { - interpreter->hooks = ALLOCATE(LiteralDictionary, 1); - initLiteralDictionary(interpreter->hooks); +void Toy_initInterpreter(Toy_Interpreter* interpreter) { + interpreter->hooks = TOY_ALLOCATE(Toy_LiteralDictionary, 1); + Toy_initLiteralDictionary(interpreter->hooks); //set up the output streams - setInterpreterPrint(interpreter, printWrapper); - setInterpreterAssert(interpreter, assertWrapper); - setInterpreterError(interpreter, errorWrapper); + Toy_setInterpreterPrint(interpreter, printWrapper); + Toy_setInterpreterAssert(interpreter, assertWrapper); + Toy_setInterpreterError(interpreter, errorWrapper); interpreter->scope = NULL; - resetInterpreter(interpreter); + Toy_resetInterpreter(interpreter); } -void runInterpreter(Interpreter* interpreter, unsigned char* bytecode, int length) { +void Toy_runInterpreter(Toy_Interpreter* interpreter, unsigned char* bytecode, int length) { //initialize here instead of initInterpreter() - initLiteralArray(&interpreter->literalCache); + Toy_initLiteralArray(&interpreter->literalCache); interpreter->bytecode = NULL; interpreter->length = 0; interpreter->count = 0; interpreter->codeStart = -1; - initLiteralArray(&interpreter->stack); + Toy_initLiteralArray(&interpreter->stack); interpreter->depth = 0; interpreter->panic = false; @@ -2370,7 +2370,7 @@ void runInterpreter(Interpreter* interpreter, unsigned char* bytecode, int lengt //prep the literal cache if (interpreter->literalCache.count > 0) { - freeLiteralArray(&interpreter->literalCache); //automatically inits + Toy_freeLiteralArray(&interpreter->literalCache); //automatically inits } //header section @@ -2379,8 +2379,8 @@ void runInterpreter(Interpreter* interpreter, unsigned char* bytecode, int lengt const unsigned char patch = readByte(interpreter->bytecode, &interpreter->count); if (major != TOY_VERSION_MAJOR || minor > TOY_VERSION_MINOR) { - char buffer[MAX_STRING_LENGTH]; - snprintf(buffer, MAX_STRING_LENGTH, "Interpreter/bytecode version mismatch (expected %d.%d.%d or earlier, given %d.%d.%d)\n", TOY_VERSION_MAJOR, TOY_VERSION_MINOR, TOY_VERSION_PATCH, major, minor, patch); + char buffer[TOY_MAX_STRING_LENGTH]; + snprintf(buffer, TOY_MAX_STRING_LENGTH, "Interpreter/bytecode version mismatch (expected %d.%d.%d or earlier, given %d.%d.%d)\n", TOY_VERSION_MAJOR, TOY_VERSION_MINOR, TOY_VERSION_PATCH, major, minor, patch); interpreter->errorOutput(buffer); return; } @@ -2390,12 +2390,12 @@ void runInterpreter(Interpreter* interpreter, unsigned char* bytecode, int lengt #ifndef TOY_EXPORT if (command.verbose) { if (strncmp(build, TOY_VERSION_BUILD, strlen(TOY_VERSION_BUILD))) { - printf(WARN "Warning: interpreter/bytecode build mismatch\n" RESET); + printf(TOY_CC_WARN "Warning: interpreter/bytecode build mismatch\n" TOY_CC_RESET); } } #endif - consumeByte(interpreter, OP_SECTION_END, interpreter->bytecode, &interpreter->count); + consumeByte(interpreter, TOY_OP_SECTION_END, interpreter->bytecode, &interpreter->count); //read the sections of the bytecode readInterpreterSections(interpreter); @@ -2403,7 +2403,7 @@ void runInterpreter(Interpreter* interpreter, unsigned char* bytecode, int lengt //code section #ifndef TOY_EXPORT if (command.verbose) { - printf(NOTICE "executing bytecode\n" RESET); + printf(TOY_CC_NOTICE "executing bytecode\n" TOY_CC_RESET); } #endif @@ -2412,45 +2412,45 @@ void runInterpreter(Interpreter* interpreter, unsigned char* bytecode, int lengt //BUGFIX: clear the stack (for repl - stack must be balanced) while(interpreter->stack.count > 0) { - Literal lit = popLiteralArray(&interpreter->stack); - freeLiteral(lit); + Toy_Literal lit = Toy_popLiteralArray(&interpreter->stack); + Toy_freeLiteral(lit); } //free the bytecode immediately after use TODO: because why? - FREE_ARRAY(unsigned char, interpreter->bytecode, interpreter->length); + TOY_FREE_ARRAY(unsigned char, interpreter->bytecode, interpreter->length); //free the associated data - freeLiteralArray(&interpreter->literalCache); - freeLiteralArray(&interpreter->stack); + Toy_freeLiteralArray(&interpreter->literalCache); + Toy_freeLiteralArray(&interpreter->stack); } -void resetInterpreter(Interpreter* interpreter) { +void Toy_resetInterpreter(Toy_Interpreter* interpreter) { //free the interpreter scope while(interpreter->scope != NULL) { - interpreter->scope = popScope(interpreter->scope); + interpreter->scope = Toy_popScope(interpreter->scope); } //prep the scope - interpreter->scope = pushScope(NULL); + interpreter->scope = Toy_pushScope(NULL); //globally available functions - injectNativeFn(interpreter, "_set", _set); - injectNativeFn(interpreter, "_get", _get); - injectNativeFn(interpreter, "_push", _push); - injectNativeFn(interpreter, "_pop", _pop); - injectNativeFn(interpreter, "_length", _length); - injectNativeFn(interpreter, "_clear", _clear); + Toy_injectNativeFn(interpreter, "_set", _set); + Toy_injectNativeFn(interpreter, "_get", _get); + Toy_injectNativeFn(interpreter, "_push", _push); + Toy_injectNativeFn(interpreter, "_pop", _pop); + Toy_injectNativeFn(interpreter, "_length", _length); + Toy_injectNativeFn(interpreter, "_clear", _clear); } -void freeInterpreter(Interpreter* interpreter) { +void Toy_freeInterpreter(Toy_Interpreter* interpreter) { //free the interpreter scope while(interpreter->scope != NULL) { - interpreter->scope = popScope(interpreter->scope); + interpreter->scope = Toy_popScope(interpreter->scope); } if (interpreter->hooks) { - freeLiteralDictionary(interpreter->hooks); - FREE(LiteralDictionary, interpreter->hooks); + Toy_freeLiteralDictionary(interpreter->hooks); + TOY_FREE(Toy_LiteralDictionary, interpreter->hooks); } interpreter->hooks = NULL; diff --git a/source/toy_interpreter.h b/source/toy_interpreter.h index 2b1c809..9ab71c3 100644 --- a/source/toy_interpreter.h +++ b/source/toy_interpreter.h @@ -1,56 +1,56 @@ #pragma once #include "toy_common.h" -#include "literal.h" -#include "literal_array.h" -#include "literal_dictionary.h" -#include "scope.h" +#include "toy_literal.h" +#include "toy_literal_array.h" +#include "toy_literal_dictionary.h" +#include "toy_scope.h" -typedef void (*PrintFn)(const char*); +typedef void (*Toy_PrintFn)(const char*); //the interpreter acts depending on the bytecode instructions -typedef struct Interpreter { +typedef struct Toy_Interpreter { //input unsigned char* bytecode; int length; int count; int codeStart; //BUGFIX: for jumps, must be initialized to -1 - LiteralArray literalCache; //read-only - built from the bytecode, refreshed each time new bytecode is provided + Toy_LiteralArray literalCache; //read-only - built from the bytecode, refreshed each time new bytecode is provided //operation - Scope* scope; - LiteralArray stack; + Toy_Scope* scope; + Toy_LiteralArray stack; //Library APIs - LiteralDictionary* hooks; + Toy_LiteralDictionary* hooks; //debug outputs - PrintFn printOutput; - PrintFn assertOutput; - PrintFn errorOutput; + Toy_PrintFn printOutput; + Toy_PrintFn assertOutput; + Toy_PrintFn errorOutput; int depth; //don't overflow bool panic; -} Interpreter; +} Toy_Interpreter; //native API -typedef int (*NativeFn)(Interpreter* interpreter, LiteralArray* arguments); -TOY_API bool injectNativeFn(Interpreter* interpreter, char* name, NativeFn func); +typedef int (*Toy_NativeFn)(Toy_Interpreter* interpreter, Toy_LiteralArray* arguments); +TOY_API bool Toy_injectNativeFn(Toy_Interpreter* interpreter, char* name, Toy_NativeFn func); -typedef int (*HookFn)(Interpreter* interpreter, Literal identifier, Literal alias); -TOY_API bool injectNativeHook(Interpreter* interpreter, char* name, HookFn hook); +typedef int (*Toy_HookFn)(Toy_Interpreter* interpreter, Toy_Literal identifier, Toy_Literal alias); +TOY_API bool Toy_injectNativeHook(Toy_Interpreter* interpreter, char* name, Toy_HookFn hook); -TOY_API bool callLiteralFn(Interpreter* interpreter, Literal func, LiteralArray* arguments, LiteralArray* returns); -TOY_API bool callFn(Interpreter* interpreter, char* name, LiteralArray* arguments, LiteralArray* returns); +TOY_API bool Toy_callLiteralFn(Toy_Interpreter* interpreter, Toy_Literal func, Toy_LiteralArray* arguments, Toy_LiteralArray* returns); +TOY_API bool Toy_callFn(Toy_Interpreter* interpreter, char* name, Toy_LiteralArray* arguments, Toy_LiteralArray* returns); //utilities for the host program -TOY_API bool parseIdentifierToValue(Interpreter* interpreter, Literal* literalPtr); -TOY_API void setInterpreterPrint(Interpreter* interpreter, PrintFn printOutput); -TOY_API void setInterpreterAssert(Interpreter* interpreter, PrintFn assertOutput); -TOY_API void setInterpreterError(Interpreter* interpreter, PrintFn errorOutput); +TOY_API bool Toy_parseIdentifierToValue(Toy_Interpreter* interpreter, Toy_Literal* literalPtr); +TOY_API void Toy_setInterpreterPrint(Toy_Interpreter* interpreter, Toy_PrintFn printOutput); +TOY_API void Toy_setInterpreterAssert(Toy_Interpreter* interpreter, Toy_PrintFn assertOutput); +TOY_API void Toy_setInterpreterError(Toy_Interpreter* interpreter, Toy_PrintFn errorOutput); //main access -TOY_API void initInterpreter(Interpreter* interpreter); //start of program -TOY_API void runInterpreter(Interpreter* interpreter, unsigned char* bytecode, int length); //run the code -TOY_API void resetInterpreter(Interpreter* interpreter); //use this to reset the interpreter's environment between runs -TOY_API void freeInterpreter(Interpreter* interpreter); //end of program +TOY_API void Toy_initInterpreter(Toy_Interpreter* interpreter); //start of program +TOY_API void Toy_runInterpreter(Toy_Interpreter* interpreter, unsigned char* bytecode, int length); //run the code +TOY_API void Toy_resetInterpreter(Toy_Interpreter* interpreter); //use this to reset the interpreter's environment between runs +TOY_API void Toy_freeInterpreter(Toy_Interpreter* interpreter); //end of program diff --git a/source/toy_keyword_types.c b/source/toy_keyword_types.c index f20bb55..2e5aa75 100644 --- a/source/toy_keyword_types.c +++ b/source/toy_keyword_types.c @@ -1,77 +1,77 @@ -#include "keyword_types.h" +#include "toy_keyword_types.h" #include "toy_common.h" #include -KeywordType keywordTypes[] = { +Toy_KeywordType Toy_keywordTypes[] = { //type keywords - {TOKEN_NULL, "null"}, - {TOKEN_BOOLEAN, "bool"}, - {TOKEN_INTEGER, "int"}, - {TOKEN_FLOAT, "float"}, - {TOKEN_STRING, "string"}, - {TOKEN_FUNCTION, "fn"}, - {TOKEN_OPAQUE, "opaque"}, - {TOKEN_ANY, "any"}, + {TOY_TOKEN_NULL, "null"}, + {TOY_TOKEN_BOOLEAN, "bool"}, + {TOY_TOKEN_INTEGER, "int"}, + {TOY_TOKEN_FLOAT, "float"}, + {TOY_TOKEN_STRING, "string"}, + {TOY_TOKEN_FUNCTION, "fn"}, + {TOY_TOKEN_OPAQUE, "opaque"}, + {TOY_TOKEN_ANY, "any"}, //other keywords - {TOKEN_AS, "as"}, - {TOKEN_ASSERT, "assert"}, - {TOKEN_BREAK, "break"}, - {TOKEN_CLASS, "class"}, - {TOKEN_CONST, "const"}, - {TOKEN_CONTINUE, "continue"}, - {TOKEN_DO, "do"}, - {TOKEN_ELSE, "else"}, - {TOKEN_EXPORT, "export"}, - {TOKEN_FOR, "for"}, - {TOKEN_FOREACH, "foreach"}, - {TOKEN_IF, "if"}, - {TOKEN_IMPORT, "import"}, - {TOKEN_IN, "in"}, - {TOKEN_OF, "of"}, - {TOKEN_PRINT, "print"}, - {TOKEN_RETURN, "return"}, - {TOKEN_TYPE, "type"}, - {TOKEN_ASTYPE, "astype"}, - {TOKEN_TYPEOF, "typeof"}, - {TOKEN_VAR, "var"}, - {TOKEN_WHILE, "while"}, + {TOY_TOKEN_AS, "as"}, + {TOY_TOKEN_ASSERT, "assert"}, + {TOY_TOKEN_BREAK, "break"}, + {TOY_TOKEN_CLASS, "class"}, + {TOY_TOKEN_CONST, "const"}, + {TOY_TOKEN_CONTINUE, "continue"}, + {TOY_TOKEN_DO, "do"}, + {TOY_TOKEN_ELSE, "else"}, + {TOY_TOKEN_EXPORT, "export"}, + {TOY_TOKEN_FOR, "for"}, + {TOY_TOKEN_FOREACH, "foreach"}, + {TOY_TOKEN_IF, "if"}, + {TOY_TOKEN_IMPORT, "import"}, + {TOY_TOKEN_IN, "in"}, + {TOY_TOKEN_OF, "of"}, + {TOY_TOKEN_PRINT, "print"}, + {TOY_TOKEN_RETURN, "return"}, + {TOY_TOKEN_TYPE, "type"}, + {TOY_TOKEN_ASTYPE, "astype"}, + {TOY_TOKEN_TYPEOF, "typeof"}, + {TOY_TOKEN_VAR, "var"}, + {TOY_TOKEN_WHILE, "while"}, //literal values - {TOKEN_LITERAL_TRUE, "true"}, - {TOKEN_LITERAL_FALSE, "false"}, + {TOY_TOKEN_LITERAL_TRUE, "true"}, + {TOY_TOKEN_LITERAL_FALSE, "false"}, //meta tokens - {TOKEN_PASS, NULL}, - {TOKEN_ERROR, NULL}, + {TOY_TOKEN_PASS, NULL}, + {TOY_TOKEN_ERROR, NULL}, - {TOKEN_EOF, NULL}, + {TOY_TOKEN_EOF, NULL}, }; -char* findKeywordByType(TokenType type) { - if (type == TOKEN_EOF) { +char* Toy_findKeywordByType(Toy_TokenType type) { + if (type == TOY_TOKEN_EOF) { return "EOF"; } - for(int i = 0; keywordTypes[i].keyword; i++) { - if (keywordTypes[i].type == type) { - return keywordTypes[i].keyword; + for(int i = 0; Toy_keywordTypes[i].keyword; i++) { + if (Toy_keywordTypes[i].type == type) { + return Toy_keywordTypes[i].keyword; } } return NULL; } -TokenType findTypeByKeyword(const char* keyword) { +Toy_TokenType Toy_findTypeByKeyword(const char* keyword) { const int length = strlen(keyword); - for (int i = 0; keywordTypes[i].keyword; i++) { - if (!strncmp(keyword, keywordTypes[i].keyword, length)) { - return keywordTypes[i].type; + for (int i = 0; Toy_keywordTypes[i].keyword; i++) { + if (!strncmp(keyword, Toy_keywordTypes[i].keyword, length)) { + return Toy_keywordTypes[i].type; } } - return TOKEN_EOF; + return TOY_TOKEN_EOF; } diff --git a/source/toy_keyword_types.h b/source/toy_keyword_types.h index a691910..438f578 100644 --- a/source/toy_keyword_types.h +++ b/source/toy_keyword_types.h @@ -1,14 +1,14 @@ #pragma once -#include "token_types.h" +#include "toy_token_types.h" typedef struct { - TokenType type; + Toy_TokenType type; char* keyword; -} KeywordType; +} Toy_KeywordType; -extern KeywordType keywordTypes[]; +extern Toy_KeywordType Toy_keywordTypes[]; -char* findKeywordByType(TokenType type); +char* Toy_findKeywordByType(Toy_TokenType type); -TokenType findTypeByKeyword(const char* keyword); +Toy_TokenType Toy_findTypeByKeyword(const char* keyword); diff --git a/source/toy_lexer.c b/source/toy_lexer.c index 15a769e..5c0c6bf 100644 --- a/source/toy_lexer.c +++ b/source/toy_lexer.c @@ -1,33 +1,33 @@ -#include "lexer.h" -#include "console_colors.h" -#include "keyword_types.h" +#include "toy_lexer.h" +#include "toy_console_colors.h" +#include "toy_keyword_types.h" #include #include #include //static generic utility functions -static void cleanLexer(Lexer* lexer) { +static void cleanLexer(Toy_Lexer* lexer) { lexer->source = NULL; lexer->start = 0; lexer->current = 0; lexer->line = 1; } -static bool isAtEnd(Lexer* lexer) { +static bool isAtEnd(Toy_Lexer* lexer) { return lexer->source[lexer->current] == '\0'; } -static char peek(Lexer* lexer) { +static char peek(Toy_Lexer* lexer) { return lexer->source[lexer->current]; } -static char peekNext(Lexer* lexer) { +static char peekNext(Toy_Lexer* lexer) { if (isAtEnd(lexer)) return '\0'; return lexer->source[lexer->current + 1]; } -static char advance(Lexer* lexer) { +static char advance(Toy_Lexer* lexer) { if (isAtEnd(lexer)) { return '\0'; } @@ -41,7 +41,7 @@ static char advance(Lexer* lexer) { return lexer->source[lexer->current - 1]; } -static void eatWhitespace(Lexer* lexer) { +static void eatWhitespace(Toy_Lexer* lexer) { const char c = peek(lexer); switch(c) { @@ -79,11 +79,11 @@ static void eatWhitespace(Lexer* lexer) { eatWhitespace(lexer); } -static bool isDigit(Lexer* lexer) { +static bool isDigit(Toy_Lexer* lexer) { return peek(lexer) >= '0' && peek(lexer) <= '9'; } -static bool isAlpha(Lexer* lexer) { +static bool isAlpha(Toy_Lexer* lexer) { return (peek(lexer) >= 'A' && peek(lexer) <= 'Z') || (peek(lexer) >= 'a' && peek(lexer) <= 'z') || @@ -91,7 +91,7 @@ static bool isAlpha(Lexer* lexer) { ; } -static bool match(Lexer* lexer, char c) { +static bool match(Toy_Lexer* lexer, char c) { if (peek(lexer) == c) { advance(lexer); return true; @@ -101,10 +101,10 @@ static bool match(Lexer* lexer, char c) { } //token generators -static Token makeErrorToken(Lexer* lexer, char* msg) { - Token token; +static Toy_Token makeErrorToken(Toy_Lexer* lexer, char* msg) { + Toy_Token token; - token.type = TOKEN_ERROR; + token.type = TOY_TOKEN_ERROR; token.lexeme = msg; token.length = strlen(msg); token.line = lexer->line; @@ -112,15 +112,15 @@ static Token makeErrorToken(Lexer* lexer, char* msg) { #ifndef TOY_EXPORT if (command.verbose) { printf("err:"); - printToken(&token); + Toy_printToken(&token); } #endif return token; } -static Token makeToken(Lexer* lexer, TokenType type) { - Token token; +static Toy_Token makeToken(Toy_Lexer* lexer, Toy_TokenType type) { + Toy_Token token; token.type = type; token.length = lexer->current - lexer->start; @@ -131,25 +131,25 @@ static Token makeToken(Lexer* lexer, TokenType type) { //BUG #10: this shows TOKEN_EOF twice due to the overarching structure of the program - can't be fixed if (command.verbose) { printf("tok:"); - printToken(&token); + Toy_printToken(&token); } #endif return token; } -static Token makeIntegerOrFloat(Lexer* lexer) { - TokenType type = TOKEN_LITERAL_INTEGER; //what am I making? +static Toy_Token makeIntegerOrFloat(Toy_Lexer* lexer) { + Toy_TokenType type = TOY_TOKEN_LITERAL_INTEGER; //what am I making? while(isDigit(lexer)) advance(lexer); if (peek(lexer) == '.' && (peekNext(lexer) >= '0' && peekNext(lexer) <= '9')) { //BUGFIX: peekNext == digit - type = TOKEN_LITERAL_FLOAT; + type = TOY_TOKEN_LITERAL_FLOAT; advance(lexer); while(isDigit(lexer)) advance(lexer); } - Token token; + Toy_Token token; token.type = type; token.lexeme = &lexer->source[lexer->start]; @@ -158,19 +158,19 @@ static Token makeIntegerOrFloat(Lexer* lexer) { #ifndef TOY_EXPORT if (command.verbose) { - if (type == TOKEN_LITERAL_INTEGER) { + if (type == TOY_TOKEN_LITERAL_INTEGER) { printf("int:"); } else { printf("flt:"); } - printToken(&token); + Toy_printToken(&token); } #endif return token; } -static Token makeString(Lexer* lexer, char terminator) { +static Toy_Token makeString(Toy_Lexer* lexer, char terminator) { while (!isAtEnd(lexer) && peek(lexer) != terminator) { advance(lexer); } @@ -181,9 +181,9 @@ static Token makeString(Lexer* lexer, char terminator) { return makeErrorToken(lexer, "Unterminated string"); } - Token token; + Toy_Token token; - token.type = TOKEN_LITERAL_STRING; + token.type = TOY_TOKEN_LITERAL_STRING; token.lexeme = &lexer->source[lexer->start + 1]; token.length = lexer->current - lexer->start - 2; token.line = lexer->line; @@ -191,14 +191,14 @@ static Token makeString(Lexer* lexer, char terminator) { #ifndef TOY_EXPORT if (command.verbose) { printf("str:"); - printToken(&token); + Toy_printToken(&token); } #endif return token; } -static Token makeKeywordOrIdentifier(Lexer* lexer) { +static Toy_Token makeKeywordOrIdentifier(Toy_Lexer* lexer) { advance(lexer); //first letter can only be alpha while(isDigit(lexer) || isAlpha(lexer)) { @@ -206,11 +206,11 @@ static Token makeKeywordOrIdentifier(Lexer* lexer) { } //scan for a keyword - for (int i = 0; keywordTypes[i].keyword; i++) { - if (strlen(keywordTypes[i].keyword) == (long unsigned int)(lexer->current - lexer->start) && !strncmp(keywordTypes[i].keyword, &lexer->source[lexer->start], lexer->current - lexer->start)) { - Token token; + for (int i = 0; Toy_keywordTypes[i].keyword; i++) { + if (strlen(Toy_keywordTypes[i].keyword) == (long unsigned int)(lexer->current - lexer->start) && !strncmp(Toy_keywordTypes[i].keyword, &lexer->source[lexer->start], lexer->current - lexer->start)) { + Toy_Token token; - token.type = keywordTypes[i].type; + token.type = Toy_keywordTypes[i].type; token.lexeme = &lexer->source[lexer->start]; token.length = lexer->current - lexer->start; token.line = lexer->line; @@ -218,7 +218,7 @@ static Token makeKeywordOrIdentifier(Lexer* lexer) { #ifndef TOY_EXPORT if (command.verbose) { printf("kwd:"); - printToken(&token); + Toy_printToken(&token); } #endif @@ -227,9 +227,9 @@ static Token makeKeywordOrIdentifier(Lexer* lexer) { } //return an identifier - Token token; + Toy_Token token; - token.type = TOKEN_IDENTIFIER; + token.type = TOY_TOKEN_IDENTIFIER; token.lexeme = &lexer->source[lexer->start]; token.length = lexer->current - lexer->start; token.line = lexer->line; @@ -237,7 +237,7 @@ static Token makeKeywordOrIdentifier(Lexer* lexer) { #ifndef TOY_EXPORT if (command.verbose) { printf("idf:"); - printToken(&token); + Toy_printToken(&token); } #endif @@ -245,18 +245,18 @@ static Token makeKeywordOrIdentifier(Lexer* lexer) { } //exposed functions -void initLexer(Lexer* lexer, char* source) { +void Toy_initLexer(Toy_Lexer* lexer, char* source) { cleanLexer(lexer); lexer->source = source; } -Token scanLexer(Lexer* lexer) { +Toy_Token Toy_scanLexer(Toy_Lexer* lexer) { eatWhitespace(lexer); lexer->start = lexer->current; - if (isAtEnd(lexer)) return makeToken(lexer, TOKEN_EOF); + if (isAtEnd(lexer)) return makeToken(lexer, TOY_TOKEN_EOF); if (isDigit(lexer)) return makeIntegerOrFloat(lexer); if (isAlpha(lexer)) return makeKeywordOrIdentifier(lexer); @@ -264,45 +264,45 @@ Token scanLexer(Lexer* lexer) { char c = advance(lexer); switch(c) { - case '(': return makeToken(lexer, TOKEN_PAREN_LEFT); - case ')': return makeToken(lexer, TOKEN_PAREN_RIGHT); - case '{': return makeToken(lexer, TOKEN_BRACE_LEFT); - case '}': return makeToken(lexer, TOKEN_BRACE_RIGHT); - case '[': return makeToken(lexer, TOKEN_BRACKET_LEFT); - case ']': return makeToken(lexer, TOKEN_BRACKET_RIGHT); + case '(': return makeToken(lexer, TOY_TOKEN_PAREN_LEFT); + case ')': return makeToken(lexer, TOY_TOKEN_PAREN_RIGHT); + case '{': return makeToken(lexer, TOY_TOKEN_BRACE_LEFT); + case '}': return makeToken(lexer, TOY_TOKEN_BRACE_RIGHT); + case '[': return makeToken(lexer, TOY_TOKEN_BRACKET_LEFT); + case ']': return makeToken(lexer, TOY_TOKEN_BRACKET_RIGHT); - case '+': return makeToken(lexer, match(lexer, '=') ? TOKEN_PLUS_ASSIGN : match(lexer, '+') ? TOKEN_PLUS_PLUS: TOKEN_PLUS); - case '-': return makeToken(lexer, match(lexer, '=') ? TOKEN_MINUS_ASSIGN : match(lexer, '-') ? TOKEN_MINUS_MINUS: TOKEN_MINUS); - case '*': return makeToken(lexer, match(lexer, '=') ? TOKEN_MULTIPLY_ASSIGN : TOKEN_MULTIPLY); - case '/': return makeToken(lexer, match(lexer, '=') ? TOKEN_DIVIDE_ASSIGN : TOKEN_DIVIDE); - case '%': return makeToken(lexer, match(lexer, '=') ? TOKEN_MODULO_ASSIGN : TOKEN_MODULO); + case '+': return makeToken(lexer, match(lexer, '=') ? TOY_TOKEN_PLUS_ASSIGN : match(lexer, '+') ? TOY_TOKEN_PLUS_PLUS: TOY_TOKEN_PLUS); + case '-': return makeToken(lexer, match(lexer, '=') ? TOY_TOKEN_MINUS_ASSIGN : match(lexer, '-') ? TOY_TOKEN_MINUS_MINUS: TOY_TOKEN_MINUS); + case '*': return makeToken(lexer, match(lexer, '=') ? TOY_TOKEN_MULTIPLY_ASSIGN : TOY_TOKEN_MULTIPLY); + case '/': return makeToken(lexer, match(lexer, '=') ? TOY_TOKEN_DIVIDE_ASSIGN : TOY_TOKEN_DIVIDE); + case '%': return makeToken(lexer, match(lexer, '=') ? TOY_TOKEN_MODULO_ASSIGN : TOY_TOKEN_MODULO); - case '!': return makeToken(lexer, match(lexer, '=') ? TOKEN_NOT_EQUAL : TOKEN_NOT); - case '=': return makeToken(lexer, match(lexer, '=') ? TOKEN_EQUAL : TOKEN_ASSIGN); + case '!': return makeToken(lexer, match(lexer, '=') ? TOY_TOKEN_NOT_EQUAL : TOY_TOKEN_NOT); + case '=': return makeToken(lexer, match(lexer, '=') ? TOY_TOKEN_EQUAL : TOY_TOKEN_ASSIGN); - case '<': return makeToken(lexer, match(lexer, '=') ? TOKEN_LESS_EQUAL : TOKEN_LESS); - case '>': return makeToken(lexer, match(lexer, '=') ? TOKEN_GREATER_EQUAL : TOKEN_GREATER); + case '<': return makeToken(lexer, match(lexer, '=') ? TOY_TOKEN_LESS_EQUAL : TOY_TOKEN_LESS); + case '>': return makeToken(lexer, match(lexer, '=') ? TOY_TOKEN_GREATER_EQUAL : TOY_TOKEN_GREATER); case '&': //TOKEN_AND not used if (advance(lexer) != '&') { return makeErrorToken(lexer, "Unexpected '&'"); } else { - return makeToken(lexer, TOKEN_AND); + return makeToken(lexer, TOY_TOKEN_AND); } - case '|': return makeToken(lexer, match(lexer, '|') ? TOKEN_OR : TOKEN_PIPE); + case '|': return makeToken(lexer, match(lexer, '|') ? TOY_TOKEN_OR : TOY_TOKEN_PIPE); - case '?': return makeToken(lexer, TOKEN_QUESTION); - case ':': return makeToken(lexer, TOKEN_COLON); - case ';': return makeToken(lexer, TOKEN_SEMICOLON); - case ',': return makeToken(lexer, TOKEN_COMMA); + case '?': return makeToken(lexer, TOY_TOKEN_QUESTION); + case ':': return makeToken(lexer, TOY_TOKEN_COLON); + case ';': return makeToken(lexer, TOY_TOKEN_SEMICOLON); + case ',': return makeToken(lexer, TOY_TOKEN_COMMA); case '.': if (peek(lexer) == '.' && peekNext(lexer) == '.') { advance(lexer); advance(lexer); - return makeToken(lexer, TOKEN_REST); + return makeToken(lexer, TOY_TOKEN_REST); } - return makeToken(lexer, TOKEN_DOT); + return makeToken(lexer, TOY_TOKEN_DOT); case '"': return makeString(lexer, c); @@ -322,18 +322,18 @@ static void trim(char** s, int* l) { //all this to remove a newline? } //for debugging -void printToken(Token* token) { - if (token->type == TOKEN_ERROR) { - printf(ERROR "Error\t%d\t%.*s\n" RESET, token->line, token->length, token->lexeme); +void Toy_printToken(Toy_Token* token) { + if (token->type == TOY_TOKEN_ERROR) { + printf(TOY_CC_ERROR "Error\t%d\t%.*s\n" TOY_CC_RESET, token->line, token->length, token->lexeme); return; } printf("\t%d\t%d\t", token->type, token->line); - if (token->type == TOKEN_IDENTIFIER || token->type == TOKEN_LITERAL_INTEGER || token->type == TOKEN_LITERAL_FLOAT || token->type == TOKEN_LITERAL_STRING) { + if (token->type == TOY_TOKEN_IDENTIFIER || token->type == TOY_TOKEN_LITERAL_INTEGER || token->type == TOY_TOKEN_LITERAL_FLOAT || token->type == TOY_TOKEN_LITERAL_STRING) { printf("%.*s\t", token->length, token->lexeme); } else { - char* keyword = findKeywordByType(token->type); + char* keyword = Toy_findKeywordByType(token->type); if (keyword != NULL) { printf("%s", keyword); diff --git a/source/toy_lexer.h b/source/toy_lexer.h index 187fa61..41a60bc 100644 --- a/source/toy_lexer.h +++ b/source/toy_lexer.h @@ -1,7 +1,7 @@ #pragma once #include "toy_common.h" -#include "token_types.h" +#include "toy_token_types.h" //lexers are bound to a string of code, and return a single token every time scan is called typedef struct { @@ -9,18 +9,18 @@ typedef struct { int start; //start of the token int current; //current position of the lexer int line; //track this for error handling -} Lexer; +} Toy_Lexer; //tokens are intermediaries between lexers and parsers typedef struct { - TokenType type; + Toy_TokenType type; char* lexeme; int length; int line; -} Token; +} Toy_Token; -TOY_API void initLexer(Lexer* lexer, char* source); -Token scanLexer(Lexer* lexer); +TOY_API void Toy_initLexer(Toy_Lexer* lexer, char* source); +Toy_Token Toy_scanLexer(Toy_Lexer* lexer); //for debugging -void printToken(Token* token); +void Toy_printToken(Toy_Token* token); diff --git a/source/toy_literal.c b/source/toy_literal.c index fca4c02..74bff89 100644 --- a/source/toy_literal.c +++ b/source/toy_literal.c @@ -1,11 +1,11 @@ -#include "literal.h" -#include "memory.h" +#include "toy_literal.h" +#include "toy_memory.h" -#include "literal_array.h" -#include "literal_dictionary.h" -#include "scope.h" +#include "toy_literal_array.h" +#include "toy_literal_dictionary.h" +#include "toy_scope.h" -#include "console_colors.h" +#include "toy_console_colors.h" #include @@ -29,203 +29,203 @@ static unsigned int hashUInt(unsigned int x) { } //exposed functions -void freeLiteral(Literal literal) { +void Toy_freeLiteral(Toy_Literal literal) { //refstrings - if (IS_STRING(literal)) { - deleteRefString(AS_STRING(literal)); + if (TOY_IS_STRING(literal)) { + Toy_deleteRefString(TOY_AS_STRING(literal)); return; } - if (IS_IDENTIFIER(literal)) { - deleteRefString(AS_IDENTIFIER(literal)); + if (TOY_IS_IDENTIFIER(literal)) { + Toy_deleteRefString(TOY_AS_IDENTIFIER(literal)); return; } //compounds - if (IS_ARRAY(literal) || literal.type == LITERAL_DICTIONARY_INTERMEDIATE || literal.type == LITERAL_TYPE_INTERMEDIATE) { - freeLiteralArray(AS_ARRAY(literal)); - FREE(LiteralArray, AS_ARRAY(literal)); + if (TOY_IS_ARRAY(literal) || literal.type == TOY_LITERAL_DICTIONARY_INTERMEDIATE || literal.type == TOY_LITERAL_TYPE_INTERMEDIATE) { + Toy_freeLiteralArray(TOY_AS_ARRAY(literal)); + TOY_FREE(Toy_LiteralArray, TOY_AS_ARRAY(literal)); return; } - if (IS_DICTIONARY(literal)) { - freeLiteralDictionary(AS_DICTIONARY(literal)); - FREE(LiteralDictionary, AS_DICTIONARY(literal)); + if (TOY_IS_DICTIONARY(literal)) { + Toy_freeLiteralDictionary(TOY_AS_DICTIONARY(literal)); + TOY_FREE(Toy_LiteralDictionary, TOY_AS_DICTIONARY(literal)); return; } //complex literals - if (IS_FUNCTION(literal)) { - popScope(AS_FUNCTION(literal).scope); - AS_FUNCTION(literal).scope = NULL; - FREE_ARRAY(unsigned char, AS_FUNCTION(literal).bytecode, AS_FUNCTION(literal).length); + if (TOY_IS_FUNCTION(literal)) { + Toy_popScope(TOY_AS_FUNCTION(literal).scope); + TOY_AS_FUNCTION(literal).scope = NULL; + TOY_FREE_ARRAY(unsigned char, TOY_AS_FUNCTION(literal).bytecode, TOY_AS_FUNCTION(literal).length); } - if (IS_TYPE(literal)) { - for (int i = 0; i < AS_TYPE(literal).count; i++) { - freeLiteral(((Literal*)(AS_TYPE(literal).subtypes))[i]); + if (TOY_IS_TYPE(literal)) { + for (int i = 0; i < TOY_AS_TYPE(literal).count; i++) { + Toy_freeLiteral(((Toy_Literal*)(TOY_AS_TYPE(literal).subtypes))[i]); } - FREE_ARRAY(Literal, AS_TYPE(literal).subtypes, AS_TYPE(literal).capacity); + TOY_FREE_ARRAY(Toy_Literal, TOY_AS_TYPE(literal).subtypes, TOY_AS_TYPE(literal).capacity); return; } } -bool _isTruthy(Literal x) { - if (IS_NULL(x)) { - fprintf(stderr, ERROR "ERROR: Null is neither true nor false\n" RESET); +bool Toy_private_isTruthy(Toy_Literal x) { + if (TOY_IS_NULL(x)) { + fprintf(stderr, TOY_CC_ERROR "TOY_CC_ERROR: Null is neither true nor false\n" TOY_CC_RESET); return false; } - if (IS_BOOLEAN(x)) { - return AS_BOOLEAN(x); + if (TOY_IS_BOOLEAN(x)) { + return TOY_AS_BOOLEAN(x); } return true; } -Literal _toStringLiteral(RefString* ptr) { - return ((Literal){LITERAL_STRING, { .string.ptr = ptr }}); +Toy_Literal Toy_private_toStringLiteral(Toy_RefString* ptr) { + return ((Toy_Literal){TOY_LITERAL_STRING, { .string.ptr = ptr }}); } -Literal _toIdentifierLiteral(RefString* ptr) { - return ((Literal){LITERAL_IDENTIFIER,{ .identifier.ptr = ptr, .identifier.hash = hashString(toCString(ptr), lengthRefString(ptr)) }}); +Toy_Literal Toy_private_toIdentifierLiteral(Toy_RefString* ptr) { + return ((Toy_Literal){TOY_LITERAL_IDENTIFIER,{ .identifier.ptr = ptr, .identifier.hash = hashString(Toy_toCString(ptr), Toy_lengthRefString(ptr)) }}); } -Literal* _typePushSubtype(Literal* lit, Literal subtype) { +Toy_Literal* Toy_private_typePushSubtype(Toy_Literal* lit, Toy_Literal subtype) { //grow the subtype array - if (AS_TYPE(*lit).count + 1 > AS_TYPE(*lit).capacity) { - int oldCapacity = AS_TYPE(*lit).capacity; + if (TOY_AS_TYPE(*lit).count + 1 > TOY_AS_TYPE(*lit).capacity) { + int oldCapacity = TOY_AS_TYPE(*lit).capacity; - AS_TYPE(*lit).capacity = GROW_CAPACITY(oldCapacity); - AS_TYPE(*lit).subtypes = GROW_ARRAY(Literal, AS_TYPE(*lit).subtypes, oldCapacity, AS_TYPE(*lit).capacity); + TOY_AS_TYPE(*lit).capacity = TOY_GROW_CAPACITY(oldCapacity); + TOY_AS_TYPE(*lit).subtypes = TOY_GROW_ARRAY(Toy_Literal, TOY_AS_TYPE(*lit).subtypes, oldCapacity, TOY_AS_TYPE(*lit).capacity); } //actually push - ((Literal*)(AS_TYPE(*lit).subtypes))[ AS_TYPE(*lit).count++ ] = subtype; - return &((Literal*)(AS_TYPE(*lit).subtypes))[ AS_TYPE(*lit).count - 1 ]; + ((Toy_Literal*)(TOY_AS_TYPE(*lit).subtypes))[ TOY_AS_TYPE(*lit).count++ ] = subtype; + return &((Toy_Literal*)(TOY_AS_TYPE(*lit).subtypes))[ TOY_AS_TYPE(*lit).count - 1 ]; } -Literal copyLiteral(Literal original) { +Toy_Literal Toy_copyLiteral(Toy_Literal original) { switch(original.type) { - case LITERAL_NULL: - case LITERAL_BOOLEAN: - case LITERAL_INTEGER: - case LITERAL_FLOAT: + case TOY_LITERAL_NULL: + case TOY_LITERAL_BOOLEAN: + case TOY_LITERAL_INTEGER: + case TOY_LITERAL_FLOAT: //no copying needed return original; - case LITERAL_STRING: { - return TO_STRING_LITERAL(copyRefString(AS_STRING(original))); + case TOY_LITERAL_STRING: { + return TOY_TO_STRING_LITERAL(Toy_copyRefString(TOY_AS_STRING(original))); } - case LITERAL_ARRAY: { - LiteralArray* array = ALLOCATE(LiteralArray, 1); - initLiteralArray(array); + case TOY_LITERAL_ARRAY: { + Toy_LiteralArray* array = TOY_ALLOCATE(Toy_LiteralArray, 1); + Toy_initLiteralArray(array); //copy each element - for (int i = 0; i < AS_ARRAY(original)->count; i++) { - pushLiteralArray(array, AS_ARRAY(original)->literals[i]); + for (int i = 0; i < TOY_AS_ARRAY(original)->count; i++) { + Toy_pushLiteralArray(array, TOY_AS_ARRAY(original)->literals[i]); } - return TO_ARRAY_LITERAL(array); + return TOY_TO_ARRAY_LITERAL(array); } - case LITERAL_DICTIONARY: { - LiteralDictionary* dictionary = ALLOCATE(LiteralDictionary, 1); - initLiteralDictionary(dictionary); + case TOY_LITERAL_DICTIONARY: { + Toy_LiteralDictionary* dictionary = TOY_ALLOCATE(Toy_LiteralDictionary, 1); + Toy_initLiteralDictionary(dictionary); //copy each entry - for (int i = 0; i < AS_DICTIONARY(original)->capacity; i++) { - if ( !IS_NULL(AS_DICTIONARY(original)->entries[i].key) ) { - setLiteralDictionary(dictionary, AS_DICTIONARY(original)->entries[i].key, AS_DICTIONARY(original)->entries[i].value); + for (int i = 0; i < TOY_AS_DICTIONARY(original)->capacity; i++) { + if ( !TOY_IS_NULL(TOY_AS_DICTIONARY(original)->entries[i].key) ) { + Toy_setLiteralDictionary(dictionary, TOY_AS_DICTIONARY(original)->entries[i].key, TOY_AS_DICTIONARY(original)->entries[i].value); } } - return TO_DICTIONARY_LITERAL(dictionary); + return TOY_TO_DICTIONARY_LITERAL(dictionary); } - case LITERAL_FUNCTION: { - unsigned char* buffer = ALLOCATE(unsigned char, AS_FUNCTION(original).length); - memcpy(buffer, AS_FUNCTION(original).bytecode, AS_FUNCTION(original).length); + case TOY_LITERAL_FUNCTION: { + unsigned char* buffer = TOY_ALLOCATE(unsigned char, TOY_AS_FUNCTION(original).length); + memcpy(buffer, TOY_AS_FUNCTION(original).bytecode, TOY_AS_FUNCTION(original).length); - Literal literal = TO_FUNCTION_LITERAL(buffer, AS_FUNCTION(original).length); - AS_FUNCTION(literal).scope = copyScope(AS_FUNCTION(original).scope); + Toy_Literal literal = TOY_TO_FUNCTION_LITERAL(buffer, TOY_AS_FUNCTION(original).length); + TOY_AS_FUNCTION(literal).scope = Toy_copyScope(TOY_AS_FUNCTION(original).scope); return literal; } - case LITERAL_IDENTIFIER: { - return TO_IDENTIFIER_LITERAL(copyRefString(AS_IDENTIFIER(original))); + case TOY_LITERAL_IDENTIFIER: { + return TOY_TO_IDENTIFIER_LITERAL(Toy_copyRefString(TOY_AS_IDENTIFIER(original))); } - case LITERAL_TYPE: { - Literal lit = TO_TYPE_LITERAL(AS_TYPE(original).typeOf, AS_TYPE(original).constant); + case TOY_LITERAL_TYPE: { + Toy_Literal lit = TOY_TO_TYPE_LITERAL(TOY_AS_TYPE(original).typeOf, TOY_AS_TYPE(original).constant); - for (int i = 0; i < AS_TYPE(original).count; i++) { - TYPE_PUSH_SUBTYPE(&lit, copyLiteral( ((Literal*)(AS_TYPE(original).subtypes))[i] )); + for (int i = 0; i < TOY_AS_TYPE(original).count; i++) { + TOY_TYPE_PUSH_SUBTYPE(&lit, Toy_copyLiteral( ((Toy_Literal*)(TOY_AS_TYPE(original).subtypes))[i] )); } return lit; } - case LITERAL_OPAQUE: { + case TOY_LITERAL_OPAQUE: { return original; //literally a shallow copy } - case LITERAL_DICTIONARY_INTERMEDIATE: { - LiteralArray* array = ALLOCATE(LiteralArray, 1); - initLiteralArray(array); + case TOY_LITERAL_DICTIONARY_INTERMEDIATE: { + Toy_LiteralArray* array = TOY_ALLOCATE(Toy_LiteralArray, 1); + Toy_initLiteralArray(array); //copy each element - for (int i = 0; i < AS_ARRAY(original)->count; i++) { - Literal literal = copyLiteral(AS_ARRAY(original)->literals[i]); - pushLiteralArray(array, literal); - freeLiteral(literal); + for (int i = 0; i < TOY_AS_ARRAY(original)->count; i++) { + Toy_Literal literal = Toy_copyLiteral(TOY_AS_ARRAY(original)->literals[i]); + Toy_pushLiteralArray(array, literal); + Toy_freeLiteral(literal); } - Literal ret = TO_ARRAY_LITERAL(array); - ret.type = LITERAL_DICTIONARY_INTERMEDIATE; + Toy_Literal ret = TOY_TO_ARRAY_LITERAL(array); + ret.type = TOY_LITERAL_DICTIONARY_INTERMEDIATE; return ret; } - case LITERAL_TYPE_INTERMEDIATE: { - LiteralArray* array = ALLOCATE(LiteralArray, 1); - initLiteralArray(array); + case TOY_LITERAL_TYPE_INTERMEDIATE: { + Toy_LiteralArray* array = TOY_ALLOCATE(Toy_LiteralArray, 1); + Toy_initLiteralArray(array); //copy each element - for (int i = 0; i < AS_ARRAY(original)->count; i++) { - Literal literal = copyLiteral(AS_ARRAY(original)->literals[i]); - pushLiteralArray(array, literal); - freeLiteral(literal); + for (int i = 0; i < TOY_AS_ARRAY(original)->count; i++) { + Toy_Literal literal = Toy_copyLiteral(TOY_AS_ARRAY(original)->literals[i]); + Toy_pushLiteralArray(array, literal); + Toy_freeLiteral(literal); } - Literal ret = TO_ARRAY_LITERAL(array); - ret.type = LITERAL_TYPE_INTERMEDIATE; + Toy_Literal ret = TOY_TO_ARRAY_LITERAL(array); + ret.type = TOY_LITERAL_TYPE_INTERMEDIATE; return ret; } - case LITERAL_FUNCTION_INTERMEDIATE: //caries a compiler - case LITERAL_FUNCTION_NATIVE: - case LITERAL_INDEX_BLANK: + case TOY_LITERAL_FUNCTION_INTERMEDIATE: //caries a compiler + case TOY_LITERAL_FUNCTION_NATIVE: + case TOY_LITERAL_INDEX_BLANK: //no copying possible return original; default: - fprintf(stderr, ERROR "ERROR: Can't copy that literal type: %d\n" RESET, original.type); - return TO_NULL_LITERAL; + fprintf(stderr, TOY_CC_ERROR "TOY_CC_ERROR: Can't copy that literal type: %d\n" TOY_CC_RESET, original.type); + return TOY_TO_NULL_LITERAL; } } -bool literalsAreEqual(Literal lhs, Literal rhs) { +bool Toy_literalsAreEqual(Toy_Literal lhs, Toy_Literal rhs) { //utility for other things if (lhs.type != rhs.type) { // ints and floats are compatible - if ((IS_INTEGER(lhs) || IS_FLOAT(lhs)) && (IS_INTEGER(rhs) || IS_FLOAT(rhs))) { - if (IS_INTEGER(lhs)) { - return AS_INTEGER(lhs) + AS_FLOAT(rhs); + if ((TOY_IS_INTEGER(lhs) || TOY_IS_FLOAT(lhs)) && (TOY_IS_INTEGER(rhs) || TOY_IS_FLOAT(rhs))) { + if (TOY_IS_INTEGER(lhs)) { + return TOY_AS_INTEGER(lhs) + TOY_AS_FLOAT(rhs); } else { - return AS_FLOAT(lhs) + AS_INTEGER(rhs); + return TOY_AS_FLOAT(lhs) + TOY_AS_INTEGER(rhs); } } @@ -233,172 +233,172 @@ bool literalsAreEqual(Literal lhs, Literal rhs) { } switch(lhs.type) { - case LITERAL_NULL: + case TOY_LITERAL_NULL: return true; //can only be true because of the check above - case LITERAL_BOOLEAN: - return AS_BOOLEAN(lhs) == AS_BOOLEAN(rhs); + case TOY_LITERAL_BOOLEAN: + return TOY_AS_BOOLEAN(lhs) == TOY_AS_BOOLEAN(rhs); - case LITERAL_INTEGER: - return AS_INTEGER(lhs) == AS_INTEGER(rhs); + case TOY_LITERAL_INTEGER: + return TOY_AS_INTEGER(lhs) == TOY_AS_INTEGER(rhs); - case LITERAL_FLOAT: - return AS_FLOAT(lhs) == AS_FLOAT(rhs); + case TOY_LITERAL_FLOAT: + return TOY_AS_FLOAT(lhs) == TOY_AS_FLOAT(rhs); - case LITERAL_STRING: - return equalsRefString(AS_STRING(lhs), AS_STRING(rhs)); + case TOY_LITERAL_STRING: + return Toy_equalsRefString(TOY_AS_STRING(lhs), TOY_AS_STRING(rhs)); - case LITERAL_ARRAY: - case LITERAL_DICTIONARY_INTERMEDIATE: //BUGFIX - case LITERAL_TYPE_INTERMEDIATE: //BUGFIX: used for storing types as an array + case TOY_LITERAL_ARRAY: + case TOY_LITERAL_DICTIONARY_INTERMEDIATE: //BUGFIX + case TOY_LITERAL_TYPE_INTERMEDIATE: //BUGFIX: used for storing types as an array //mismatched sizes - if (AS_ARRAY(lhs)->count != AS_ARRAY(rhs)->count) { + if (TOY_AS_ARRAY(lhs)->count != TOY_AS_ARRAY(rhs)->count) { return false; } //mismatched elements (in order) - for (int i = 0; i < AS_ARRAY(lhs)->count; i++) { - if (!literalsAreEqual( AS_ARRAY(lhs)->literals[i], AS_ARRAY(rhs)->literals[i] )) { + for (int i = 0; i < TOY_AS_ARRAY(lhs)->count; i++) { + if (!Toy_literalsAreEqual( TOY_AS_ARRAY(lhs)->literals[i], TOY_AS_ARRAY(rhs)->literals[i] )) { return false; } } return true; - case LITERAL_DICTIONARY: + case TOY_LITERAL_DICTIONARY: //relatively slow, especially when nested - for (int i = 0; i < AS_DICTIONARY(lhs)->capacity; i++) { - if (!IS_NULL(AS_DICTIONARY(lhs)->entries[i].key)) { //only compare non-null keys + for (int i = 0; i < TOY_AS_DICTIONARY(lhs)->capacity; i++) { + if (!TOY_IS_NULL(TOY_AS_DICTIONARY(lhs)->entries[i].key)) { //only compare non-null keys //check it exists in rhs - if (!existsLiteralDictionary(AS_DICTIONARY(rhs), AS_DICTIONARY(lhs)->entries[i].key)) { + if (!Toy_existsLiteralDictionary(TOY_AS_DICTIONARY(rhs), TOY_AS_DICTIONARY(lhs)->entries[i].key)) { return false; } //compare the values - Literal val = getLiteralDictionary(AS_DICTIONARY(rhs), AS_DICTIONARY(lhs)->entries[i].key); //TODO: could be more efficient - if (!literalsAreEqual(AS_DICTIONARY(lhs)->entries[i].value, val)) { - freeLiteral(val); + Toy_Literal val = Toy_getLiteralDictionary(TOY_AS_DICTIONARY(rhs), TOY_AS_DICTIONARY(lhs)->entries[i].key); //TODO: could be more efficient + if (!Toy_literalsAreEqual(TOY_AS_DICTIONARY(lhs)->entries[i].value, val)) { + Toy_freeLiteral(val); return false; } - freeLiteral(val); + Toy_freeLiteral(val); } } return true; - case LITERAL_FUNCTION: - case LITERAL_FUNCTION_NATIVE: + case TOY_LITERAL_FUNCTION: + case TOY_LITERAL_FUNCTION_NATIVE: return false; //functions are never equal break; - case LITERAL_IDENTIFIER: + case TOY_LITERAL_IDENTIFIER: //check shortcuts - if (HASH_I(lhs) != HASH_I(rhs)) { + if (TOY_HASH_I(lhs) != TOY_HASH_I(rhs)) { return false; } - return equalsRefString(AS_IDENTIFIER(lhs), AS_IDENTIFIER(rhs)); + return Toy_equalsRefString(TOY_AS_IDENTIFIER(lhs), TOY_AS_IDENTIFIER(rhs)); - case LITERAL_TYPE: + case TOY_LITERAL_TYPE: //check types - if (AS_TYPE(lhs).typeOf != AS_TYPE(rhs).typeOf) { + if (TOY_AS_TYPE(lhs).typeOf != TOY_AS_TYPE(rhs).typeOf) { return false; } //const don't match - if (AS_TYPE(lhs).constant != AS_TYPE(rhs).constant) { + if (TOY_AS_TYPE(lhs).constant != TOY_AS_TYPE(rhs).constant) { return false; } //check subtypes - if (AS_TYPE(lhs).count != AS_TYPE(rhs).count) { + if (TOY_AS_TYPE(lhs).count != TOY_AS_TYPE(rhs).count) { return false; } //check array|dictionary signatures are the same (in order) - if (AS_TYPE(lhs).typeOf == LITERAL_ARRAY || AS_TYPE(lhs).typeOf == LITERAL_DICTIONARY) { - for (int i = 0; i < AS_TYPE(lhs).count; i++) { - if (!literalsAreEqual(((Literal*)(AS_TYPE(lhs).subtypes))[i], ((Literal*)(AS_TYPE(rhs).subtypes))[i])) { + if (TOY_AS_TYPE(lhs).typeOf == TOY_LITERAL_ARRAY || TOY_AS_TYPE(lhs).typeOf == TOY_LITERAL_DICTIONARY) { + for (int i = 0; i < TOY_AS_TYPE(lhs).count; i++) { + if (!Toy_literalsAreEqual(((Toy_Literal*)(TOY_AS_TYPE(lhs).subtypes))[i], ((Toy_Literal*)(TOY_AS_TYPE(rhs).subtypes))[i])) { return false; } } } return true; - case LITERAL_OPAQUE: + case TOY_LITERAL_OPAQUE: return false; //IDK what this is! - case LITERAL_ANY: + case TOY_LITERAL_ANY: return true; - case LITERAL_FUNCTION_INTERMEDIATE: - fprintf(stderr, ERROR "[internal] Can't compare intermediate functions\n" RESET); + case TOY_LITERAL_FUNCTION_INTERMEDIATE: + fprintf(stderr, TOY_CC_ERROR "[internal] Can't compare intermediate functions\n" TOY_CC_RESET); return false; - case LITERAL_INDEX_BLANK: + case TOY_LITERAL_INDEX_BLANK: return false; default: //should never be seen - fprintf(stderr, ERROR "[internal] Unrecognized literal type in equality: %d\n" RESET, lhs.type); + fprintf(stderr, TOY_CC_ERROR "[internal] Unrecognized literal type in equality: %d\n" TOY_CC_RESET, lhs.type); return false; } return false; } -int hashLiteral(Literal lit) { +int Toy_hashLiteral(Toy_Literal lit) { switch(lit.type) { - case LITERAL_NULL: + case TOY_LITERAL_NULL: return 0; - case LITERAL_BOOLEAN: - return AS_BOOLEAN(lit) ? 1 : 0; + case TOY_LITERAL_BOOLEAN: + return TOY_AS_BOOLEAN(lit) ? 1 : 0; - case LITERAL_INTEGER: - return hashUInt((unsigned int)AS_INTEGER(lit)); + case TOY_LITERAL_INTEGER: + return hashUInt((unsigned int)TOY_AS_INTEGER(lit)); - case LITERAL_FLOAT: - return hashUInt(*(unsigned int*)(&AS_FLOAT(lit))); + case TOY_LITERAL_FLOAT: + return hashUInt(*(unsigned int*)(&TOY_AS_FLOAT(lit))); - case LITERAL_STRING: - return hashString(toCString(AS_STRING(lit)), lengthRefString(AS_STRING(lit))); + case TOY_LITERAL_STRING: + return hashString(Toy_toCString(TOY_AS_STRING(lit)), Toy_lengthRefString(TOY_AS_STRING(lit))); - case LITERAL_ARRAY: { + case TOY_LITERAL_ARRAY: { unsigned int res = 0; - for (int i = 0; i < AS_ARRAY(lit)->count; i++) { - res += hashLiteral(AS_ARRAY(lit)->literals[i]); + for (int i = 0; i < TOY_AS_ARRAY(lit)->count; i++) { + res += Toy_hashLiteral(TOY_AS_ARRAY(lit)->literals[i]); } return hashUInt(res); } - case LITERAL_DICTIONARY: { + case TOY_LITERAL_DICTIONARY: { unsigned int res = 0; - for (int i = 0; i < AS_DICTIONARY(lit)->capacity; i++) { - if (!IS_NULL(AS_DICTIONARY(lit)->entries[i].key)) { //only hash non-null keys - res += hashLiteral(AS_DICTIONARY(lit)->entries[i].key); - res += hashLiteral(AS_DICTIONARY(lit)->entries[i].value); + for (int i = 0; i < TOY_AS_DICTIONARY(lit)->capacity; i++) { + if (!TOY_IS_NULL(TOY_AS_DICTIONARY(lit)->entries[i].key)) { //only hash non-null keys + res += Toy_hashLiteral(TOY_AS_DICTIONARY(lit)->entries[i].key); + res += Toy_hashLiteral(TOY_AS_DICTIONARY(lit)->entries[i].value); } } return hashUInt(res); } - case LITERAL_FUNCTION: - case LITERAL_FUNCTION_NATIVE: + case TOY_LITERAL_FUNCTION: + case TOY_LITERAL_FUNCTION_NATIVE: return 0; //can't hash these - case LITERAL_IDENTIFIER: - return HASH_I(lit); //pre-computed + case TOY_LITERAL_IDENTIFIER: + return TOY_HASH_I(lit); //pre-computed - case LITERAL_TYPE: - return AS_TYPE(lit).typeOf; //nothing else I can do + case TOY_LITERAL_TYPE: + return TOY_AS_TYPE(lit).typeOf; //nothing else I can do - case LITERAL_OPAQUE: - case LITERAL_ANY: + case TOY_LITERAL_OPAQUE: + case TOY_LITERAL_ANY: return -1; default: //should never bee seen - fprintf(stderr, ERROR "[internal] Unrecognized literal type in hash: %d\n" RESET, lit.type); + fprintf(stderr, TOY_CC_ERROR "[internal] Unrecognized literal type in hash: %d\n" TOY_CC_RESET, lit.type); return 0; } } @@ -420,8 +420,8 @@ static void printToBuffer(const char* str) { while (strlen(str) + globalPrintCount + 1 > globalPrintCapacity) { int oldCapacity = globalPrintCapacity; - globalPrintCapacity = GROW_CAPACITY(globalPrintCapacity); - globalPrintBuffer = GROW_ARRAY(char, globalPrintBuffer, oldCapacity, globalPrintCapacity); + globalPrintCapacity = TOY_GROW_CAPACITY(globalPrintCapacity); + globalPrintBuffer = TOY_GROW_ARRAY(char, globalPrintBuffer, oldCapacity, globalPrintCapacity); } snprintf(globalPrintBuffer + globalPrintCount, strlen(str) + 1, "%s", str); @@ -429,55 +429,55 @@ static void printToBuffer(const char* str) { } //exposed functions -void printLiteral(Literal literal) { - printLiteralCustom(literal, stdoutWrapper); +void Toy_printLiteral(Toy_Literal literal) { + Toy_printLiteralCustom(literal, stdoutWrapper); } -void printLiteralCustom(Literal literal, void (printFn)(const char*)) { +void Toy_printLiteralCustom(Toy_Literal literal, void (printFn)(const char*)) { switch(literal.type) { - case LITERAL_NULL: + case TOY_LITERAL_NULL: printFn("null"); break; - case LITERAL_BOOLEAN: - printFn(AS_BOOLEAN(literal) ? "true" : "false"); + case TOY_LITERAL_BOOLEAN: + printFn(TOY_AS_BOOLEAN(literal) ? "true" : "false"); break; - case LITERAL_INTEGER: { + case TOY_LITERAL_INTEGER: { char buffer[256]; - snprintf(buffer, 256, "%d", AS_INTEGER(literal)); + snprintf(buffer, 256, "%d", TOY_AS_INTEGER(literal)); printFn(buffer); } break; - case LITERAL_FLOAT: { + case TOY_LITERAL_FLOAT: { char buffer[256]; - if (AS_FLOAT(literal) - (int)AS_FLOAT(literal)) { - snprintf(buffer, 256, "%g", AS_FLOAT(literal)); + if (TOY_AS_FLOAT(literal) - (int)TOY_AS_FLOAT(literal)) { + snprintf(buffer, 256, "%g", TOY_AS_FLOAT(literal)); } else { - snprintf(buffer, 256, "%.1f", AS_FLOAT(literal)); + snprintf(buffer, 256, "%.1f", TOY_AS_FLOAT(literal)); } printFn(buffer); } break; - case LITERAL_STRING: { - char buffer[MAX_STRING_LENGTH]; + case TOY_LITERAL_STRING: { + char buffer[TOY_MAX_STRING_LENGTH]; if (!quotes) { - snprintf(buffer, MAX_STRING_LENGTH, "%.*s", lengthRefString(AS_STRING(literal)), toCString(AS_STRING(literal))); + snprintf(buffer, TOY_MAX_STRING_LENGTH, "%.*s", Toy_lengthRefString(TOY_AS_STRING(literal)), Toy_toCString(TOY_AS_STRING(literal))); } else { - snprintf(buffer, MAX_STRING_LENGTH, "%c%.*s%c", quotes, lengthRefString(AS_STRING(literal)), toCString(AS_STRING(literal)), quotes); + snprintf(buffer, TOY_MAX_STRING_LENGTH, "%c%.*s%c", quotes, Toy_lengthRefString(TOY_AS_STRING(literal)), Toy_toCString(TOY_AS_STRING(literal)), quotes); } printFn(buffer); } break; - case LITERAL_ARRAY: { - LiteralArray* ptr = AS_ARRAY(literal); + case TOY_LITERAL_ARRAY: { + Toy_LiteralArray* ptr = TOY_AS_ARRAY(literal); //hold potential parent-call buffers on the C stack char* cacheBuffer = globalPrintBuffer; @@ -491,7 +491,7 @@ void printLiteralCustom(Literal literal, void (printFn)(const char*)) { printToBuffer("["); for (int i = 0; i < ptr->count; i++) { quotes = '"'; - printLiteralCustom(ptr->literals[i], printToBuffer); + Toy_printLiteralCustom(ptr->literals[i], printToBuffer); if (i + 1 < ptr->count) { printToBuffer(","); @@ -510,13 +510,13 @@ void printLiteralCustom(Literal literal, void (printFn)(const char*)) { //finally, output and cleanup printFn(printBuffer); - FREE_ARRAY(char, printBuffer, printCapacity); + TOY_FREE_ARRAY(char, printBuffer, printCapacity); quotes = 0; } break; - case LITERAL_DICTIONARY: { - LiteralDictionary* ptr = AS_DICTIONARY(literal); + case TOY_LITERAL_DICTIONARY: { + Toy_LiteralDictionary* ptr = TOY_AS_DICTIONARY(literal); //hold potential parent-call buffers on the C stack char* cacheBuffer = globalPrintBuffer; @@ -530,7 +530,7 @@ void printLiteralCustom(Literal literal, void (printFn)(const char*)) { int delimCount = 0; printToBuffer("["); for (int i = 0; i < ptr->capacity; i++) { - if (IS_NULL(ptr->entries[i].key)) { + if (TOY_IS_NULL(ptr->entries[i].key)) { continue; } @@ -539,10 +539,10 @@ void printLiteralCustom(Literal literal, void (printFn)(const char*)) { } quotes = '"'; - printLiteralCustom(ptr->entries[i].key, printToBuffer); + Toy_printLiteralCustom(ptr->entries[i].key, printToBuffer); printToBuffer(":"); quotes = '"'; - printLiteralCustom(ptr->entries[i].value, printToBuffer); + Toy_printLiteralCustom(ptr->entries[i].value, printToBuffer); } //empty dicts MUST have a ":" printed @@ -563,24 +563,24 @@ void printLiteralCustom(Literal literal, void (printFn)(const char*)) { //finally, output and cleanup printFn(printBuffer); - FREE_ARRAY(char, printBuffer, printCapacity); + TOY_FREE_ARRAY(char, printBuffer, printCapacity); quotes = 0; } break; - case LITERAL_FUNCTION: - case LITERAL_FUNCTION_NATIVE: + case TOY_LITERAL_FUNCTION: + case TOY_LITERAL_FUNCTION_NATIVE: printFn("(function)"); break; - case LITERAL_IDENTIFIER: { + case TOY_LITERAL_IDENTIFIER: { char buffer[256]; - snprintf(buffer, 256, "%.*s", lengthRefString(AS_IDENTIFIER(literal)), toCString(AS_IDENTIFIER(literal))); + snprintf(buffer, 256, "%.*s", Toy_lengthRefString(TOY_AS_IDENTIFIER(literal)), Toy_toCString(TOY_AS_IDENTIFIER(literal))); printFn(buffer); } break; - case LITERAL_TYPE: { + case TOY_LITERAL_TYPE: { //hold potential parent-call buffers on the C stack char* cacheBuffer = globalPrintBuffer; globalPrintBuffer = NULL; @@ -592,78 +592,78 @@ void printLiteralCustom(Literal literal, void (printFn)(const char*)) { //print the type correctly printToBuffer("<"); - switch(AS_TYPE(literal).typeOf) { - case LITERAL_NULL: + switch(TOY_AS_TYPE(literal).typeOf) { + case TOY_LITERAL_NULL: printToBuffer("null"); break; - case LITERAL_BOOLEAN: + case TOY_LITERAL_BOOLEAN: printToBuffer("bool"); break; - case LITERAL_INTEGER: + case TOY_LITERAL_INTEGER: printToBuffer("int"); break; - case LITERAL_FLOAT: + case TOY_LITERAL_FLOAT: printToBuffer("float"); break; - case LITERAL_STRING: + case TOY_LITERAL_STRING: printToBuffer("string"); break; - case LITERAL_ARRAY: + case TOY_LITERAL_ARRAY: //print all in the array printToBuffer("["); - for (int i = 0; i < AS_TYPE(literal).count; i++) { - printLiteralCustom(((Literal*)(AS_TYPE(literal).subtypes))[i], printToBuffer); + for (int i = 0; i < TOY_AS_TYPE(literal).count; i++) { + Toy_printLiteralCustom(((Toy_Literal*)(TOY_AS_TYPE(literal).subtypes))[i], printToBuffer); } printToBuffer("]"); break; - case LITERAL_DICTIONARY: + case TOY_LITERAL_DICTIONARY: printToBuffer("["); - for (int i = 0; i < AS_TYPE(literal).count; i += 2) { - printLiteralCustom(((Literal*)(AS_TYPE(literal).subtypes))[i], printToBuffer); + for (int i = 0; i < TOY_AS_TYPE(literal).count; i += 2) { + Toy_printLiteralCustom(((Toy_Literal*)(TOY_AS_TYPE(literal).subtypes))[i], printToBuffer); printToBuffer(":"); - printLiteralCustom(((Literal*)(AS_TYPE(literal).subtypes))[i + 1], printToBuffer); + Toy_printLiteralCustom(((Toy_Literal*)(TOY_AS_TYPE(literal).subtypes))[i + 1], printToBuffer); } printToBuffer("]"); break; - case LITERAL_FUNCTION: + case TOY_LITERAL_FUNCTION: printToBuffer("function"); break; - case LITERAL_FUNCTION_NATIVE: + case TOY_LITERAL_FUNCTION_NATIVE: printToBuffer("native"); break; - case LITERAL_IDENTIFIER: + case TOY_LITERAL_IDENTIFIER: printToBuffer("identifier"); break; - case LITERAL_TYPE: + case TOY_LITERAL_TYPE: printToBuffer("type"); break; - case LITERAL_OPAQUE: + case TOY_LITERAL_OPAQUE: printToBuffer("opaque"); break; - case LITERAL_ANY: + case TOY_LITERAL_ANY: printToBuffer("any"); break; default: //should never be seen - fprintf(stderr, ERROR "[internal] Unrecognized literal type in print type: %d\n" RESET, AS_TYPE(literal).typeOf); + fprintf(stderr, TOY_CC_ERROR "[internal] Unrecognized literal type in print type: %d\n" TOY_CC_RESET, TOY_AS_TYPE(literal).typeOf); } //const (printed last) - if (AS_TYPE(literal).constant) { + if (TOY_AS_TYPE(literal).constant) { printToBuffer(" const"); } @@ -680,26 +680,26 @@ void printLiteralCustom(Literal literal, void (printFn)(const char*)) { //finally, output and cleanup printFn(printBuffer); - FREE_ARRAY(char, printBuffer, printCapacity); + TOY_FREE_ARRAY(char, printBuffer, printCapacity); quotes = 0; } break; - case LITERAL_TYPE_INTERMEDIATE: - case LITERAL_FUNCTION_INTERMEDIATE: + case TOY_LITERAL_TYPE_INTERMEDIATE: + case TOY_LITERAL_FUNCTION_INTERMEDIATE: printFn("Unprintable literal found"); break; - case LITERAL_OPAQUE: + case TOY_LITERAL_OPAQUE: printFn("(opaque)"); break; - case LITERAL_ANY: + case TOY_LITERAL_ANY: printFn("(any)"); break; default: //should never be seen - fprintf(stderr, ERROR "[internal] Unrecognized literal type in print: %d\n" RESET, literal.type); + fprintf(stderr, TOY_CC_ERROR "[internal] Unrecognized literal type in print: %d\n" TOY_CC_RESET, literal.type); } } diff --git a/source/toy_literal.h b/source/toy_literal.h index ed6594a..cfded87 100644 --- a/source/toy_literal.h +++ b/source/toy_literal.h @@ -2,41 +2,41 @@ #include "toy_common.h" -#include "refstring.h" +#include "toy_refstring.h" #include typedef enum { - LITERAL_NULL, - LITERAL_BOOLEAN, - LITERAL_INTEGER, - LITERAL_FLOAT, - LITERAL_STRING, - LITERAL_ARRAY, - LITERAL_DICTIONARY, - LITERAL_FUNCTION, - LITERAL_IDENTIFIER, - LITERAL_TYPE, - LITERAL_OPAQUE, - LITERAL_ANY, + TOY_LITERAL_NULL, + TOY_LITERAL_BOOLEAN, + TOY_LITERAL_INTEGER, + TOY_LITERAL_FLOAT, + TOY_LITERAL_STRING, + TOY_LITERAL_ARRAY, + TOY_LITERAL_DICTIONARY, + TOY_LITERAL_FUNCTION, + TOY_LITERAL_IDENTIFIER, + TOY_LITERAL_TYPE, + TOY_LITERAL_OPAQUE, + TOY_LITERAL_ANY, //these are meta-level types - not for general use - LITERAL_TYPE_INTERMEDIATE, //used to process types in the compiler only - LITERAL_DICTIONARY_INTERMEDIATE, //used to process dictionaries in the compiler only - LITERAL_FUNCTION_INTERMEDIATE, //used to process functions in the compiler only - LITERAL_FUNCTION_ARG_REST, //used to process function rest parameters only - LITERAL_FUNCTION_NATIVE, //for handling native functions only - LITERAL_INDEX_BLANK, //for blank indexing i.e. arr[:] -} LiteralType; + TOY_LITERAL_TYPE_INTERMEDIATE, //used to process types in the compiler only + TOY_LITERAL_DICTIONARY_INTERMEDIATE, //used to process dictionaries in the compiler only + TOY_LITERAL_FUNCTION_INTERMEDIATE, //used to process functions in the compiler only + TOY_LITERAL_FUNCTION_ARG_REST, //used to process function rest parameters only + TOY_LITERAL_FUNCTION_NATIVE, //for handling native functions only + TOY_LITERAL_INDEX_BLANK, //for blank indexing i.e. arr[:] +} Toy_LiteralType; typedef struct { - LiteralType type; + Toy_LiteralType type; union { bool boolean; int integer; float number; struct { - RefString* ptr; + Toy_RefString* ptr; //string hash? } string; @@ -50,12 +50,12 @@ typedef struct { } function; struct { //for variable names - RefString* ptr; + Toy_RefString* ptr; int hash; } identifier; struct { - LiteralType typeOf; //no longer a mask + Toy_LiteralType typeOf; //no longer a mask bool constant; void* subtypes; //for nested types caused by compounds int capacity; @@ -67,67 +67,67 @@ typedef struct { int tag; //TODO: remove tags? } opaque; } as; -} Literal; +} Toy_Literal; -#define IS_NULL(value) ((value).type == LITERAL_NULL) -#define IS_BOOLEAN(value) ((value).type == LITERAL_BOOLEAN) -#define IS_INTEGER(value) ((value).type == LITERAL_INTEGER) -#define IS_FLOAT(value) ((value).type == LITERAL_FLOAT) -#define IS_STRING(value) ((value).type == LITERAL_STRING) -#define IS_ARRAY(value) ((value).type == LITERAL_ARRAY) -#define IS_DICTIONARY(value) ((value).type == LITERAL_DICTIONARY) -#define IS_FUNCTION(value) ((value).type == LITERAL_FUNCTION) -#define IS_FUNCTION_NATIVE(value) ((value).type == LITERAL_FUNCTION_NATIVE) -#define IS_IDENTIFIER(value) ((value).type == LITERAL_IDENTIFIER) -#define IS_TYPE(value) ((value).type == LITERAL_TYPE) -#define IS_OPAQUE(value) ((value).type == LITERAL_OPAQUE) +#define TOY_IS_NULL(value) ((value).type == TOY_LITERAL_NULL) +#define TOY_IS_BOOLEAN(value) ((value).type == TOY_LITERAL_BOOLEAN) +#define TOY_IS_INTEGER(value) ((value).type == TOY_LITERAL_INTEGER) +#define TOY_IS_FLOAT(value) ((value).type == TOY_LITERAL_FLOAT) +#define TOY_IS_STRING(value) ((value).type == TOY_LITERAL_STRING) +#define TOY_IS_ARRAY(value) ((value).type == TOY_LITERAL_ARRAY) +#define TOY_IS_DICTIONARY(value) ((value).type == TOY_LITERAL_DICTIONARY) +#define TOY_IS_FUNCTION(value) ((value).type == TOY_LITERAL_FUNCTION) +#define TOY_IS_FUNCTION_NATIVE(value) ((value).type == TOY_LITERAL_FUNCTION_NATIVE) +#define TOY_IS_IDENTIFIER(value) ((value).type == TOY_LITERAL_IDENTIFIER) +#define TOY_IS_TYPE(value) ((value).type == TOY_LITERAL_TYPE) +#define TOY_IS_OPAQUE(value) ((value).type == TOY_LITERAL_OPAQUE) -#define AS_BOOLEAN(value) ((value).as.boolean) -#define AS_INTEGER(value) ((value).as.integer) -#define AS_FLOAT(value) ((value).as.number) -#define AS_STRING(value) ((value).as.string.ptr) -#define AS_ARRAY(value) ((LiteralArray*)((value).as.array)) -#define AS_DICTIONARY(value) ((LiteralDictionary*)((value).as.dictionary)) -#define AS_FUNCTION(value) ((value).as.function) -#define AS_IDENTIFIER(value) ((value).as.identifier.ptr) -#define AS_TYPE(value) ((value).as.type) -#define AS_OPAQUE(value) ((value).as.opaque.ptr) +#define TOY_AS_BOOLEAN(value) ((value).as.boolean) +#define TOY_AS_INTEGER(value) ((value).as.integer) +#define TOY_AS_FLOAT(value) ((value).as.number) +#define TOY_AS_STRING(value) ((value).as.string.ptr) +#define TOY_AS_ARRAY(value) ((Toy_LiteralArray*)((value).as.array)) +#define TOY_AS_DICTIONARY(value) ((Toy_LiteralDictionary*)((value).as.dictionary)) +#define TOY_AS_FUNCTION(value) ((value).as.function) +#define TOY_AS_IDENTIFIER(value) ((value).as.identifier.ptr) +#define TOY_AS_TYPE(value) ((value).as.type) +#define TOY_AS_OPAQUE(value) ((value).as.opaque.ptr) -#define TO_NULL_LITERAL ((Literal){LITERAL_NULL, { .integer = 0 }}) -#define TO_BOOLEAN_LITERAL(value) ((Literal){LITERAL_BOOLEAN, { .boolean = value }}) -#define TO_INTEGER_LITERAL(value) ((Literal){LITERAL_INTEGER, { .integer = value }}) -#define TO_FLOAT_LITERAL(value) ((Literal){LITERAL_FLOAT, { .number = value }}) -#define TO_STRING_LITERAL(value) _toStringLiteral(value) -#define TO_ARRAY_LITERAL(value) ((Literal){LITERAL_ARRAY, { .array = value }}) -#define TO_DICTIONARY_LITERAL(value) ((Literal){LITERAL_DICTIONARY, { .dictionary = value }}) -#define TO_FUNCTION_LITERAL(value, l) ((Literal){LITERAL_FUNCTION, { .function.bytecode = value, .function.scope = NULL, .function.length = l }}) -#define TO_IDENTIFIER_LITERAL(value) _toIdentifierLiteral(value) -#define TO_TYPE_LITERAL(value, c) ((Literal){ LITERAL_TYPE, { .type.typeOf = value, .type.constant = c, .type.subtypes = NULL, .type.capacity = 0, .type.count = 0 }}) -#define TO_OPAQUE_LITERAL(value, t) ((Literal){ LITERAL_OPAQUE, { .opaque.ptr = value, .opaque.tag = t }}) +#define TOY_TO_NULL_LITERAL ((Toy_Literal){TOY_LITERAL_NULL, { .integer = 0 }}) +#define TOY_TO_BOOLEAN_LITERAL(value) ((Toy_Literal){TOY_LITERAL_BOOLEAN, { .boolean = value }}) +#define TOY_TO_INTEGER_LITERAL(value) ((Toy_Literal){TOY_LITERAL_INTEGER, { .integer = value }}) +#define TOY_TO_FLOAT_LITERAL(value) ((Toy_Literal){TOY_LITERAL_FLOAT, { .number = value }}) +#define TOY_TO_STRING_LITERAL(value) Toy_private_toStringLiteral(value) +#define TOY_TO_ARRAY_LITERAL(value) ((Toy_Literal){TOY_LITERAL_ARRAY, { .array = value }}) +#define TOY_TO_DICTIONARY_LITERAL(value) ((Toy_Literal){TOY_LITERAL_DICTIONARY, { .dictionary = value }}) +#define TOY_TO_FUNCTION_LITERAL(value, l) ((Toy_Literal){TOY_LITERAL_FUNCTION, { .function.bytecode = value, .function.scope = NULL, .function.length = l }}) +#define TOY_TO_IDENTIFIER_LITERAL(value) Toy_private_toIdentifierLiteral(value) +#define TOY_TO_TYPE_LITERAL(value, c) ((Toy_Literal){ TOY_LITERAL_TYPE, { .type.typeOf = value, .type.constant = c, .type.subtypes = NULL, .type.capacity = 0, .type.count = 0 }}) +#define TOY_TO_OPAQUE_LITERAL(value, t) ((Toy_Literal){ TOY_LITERAL_OPAQUE, { .opaque.ptr = value, .opaque.tag = t }}) //BUGFIX: For blank indexing -#define IS_INDEX_BLANK(value) ((value).type == LITERAL_INDEX_BLANK) -#define TO_INDEX_BLANK_LITERAL ((Literal){LITERAL_INDEX_BLANK, { .integer = 0 }}) +#define TOY_IS_INDEX_BLANK(value) ((value).type == TOY_LITERAL_INDEX_BLANK) +#define TOY_TO_INDEX_BLANK_LITERAL ((Toy_Literal){TOY_LITERAL_INDEX_BLANK, { .integer = 0 }}) -TOY_API void freeLiteral(Literal literal); +TOY_API void Toy_freeLiteral(Toy_Literal literal); -#define IS_TRUTHY(x) _isTruthy(x) +#define TOY_IS_TRUTHY(x) Toy_private_isTruthy(x) -#define MAX_STRING_LENGTH 4096 -#define HASH_I(lit) ((lit).as.identifier.hash) -#define TYPE_PUSH_SUBTYPE(lit, subtype) _typePushSubtype(lit, subtype) -#define OPAQUE_TAG(o) o.as.opaque.tag +#define TOY_MAX_STRING_LENGTH 4096 +#define TOY_HASH_I(lit) ((lit).as.identifier.hash) +#define TOY_TYPE_PUSH_SUBTYPE(lit, subtype) Toy_private_typePushSubtype(lit, subtype) +#define TOY_GET_OPAQUE_TAG(o) o.as.opaque.tag //BUGFIX: macros are not functions -TOY_API bool _isTruthy(Literal x); -TOY_API Literal _toStringLiteral(RefString* ptr); -TOY_API Literal _toIdentifierLiteral(RefString* ptr); -TOY_API Literal* _typePushSubtype(Literal* lit, Literal subtype); +TOY_API bool Toy_private_isTruthy(Toy_Literal x); +TOY_API Toy_Literal Toy_private_toStringLiteral(Toy_RefString* ptr); +TOY_API Toy_Literal Toy_private_toIdentifierLiteral(Toy_RefString* ptr); +TOY_API Toy_Literal* Toy_private_typePushSubtype(Toy_Literal* lit, Toy_Literal subtype); //utils -TOY_API Literal copyLiteral(Literal original); -TOY_API bool literalsAreEqual(Literal lhs, Literal rhs); -TOY_API int hashLiteral(Literal lit); +TOY_API Toy_Literal Toy_copyLiteral(Toy_Literal original); +TOY_API bool Toy_literalsAreEqual(Toy_Literal lhs, Toy_Literal rhs); +TOY_API int Toy_hashLiteral(Toy_Literal lit); -TOY_API void printLiteral(Literal literal); -TOY_API void printLiteralCustom(Literal literal, void (printFn)(const char*)); +TOY_API void Toy_printLiteral(Toy_Literal literal); +TOY_API void Toy_printLiteralCustom(Toy_Literal literal, void (printFn)(const char*)); diff --git a/source/toy_literal_array.c b/source/toy_literal_array.c index 8493fd2..10c4b50 100644 --- a/source/toy_literal_array.c +++ b/source/toy_literal_array.c @@ -1,56 +1,56 @@ -#include "literal_array.h" +#include "toy_literal_array.h" -#include "memory.h" +#include "toy_memory.h" #include #include //exposed functions -void initLiteralArray(LiteralArray* array) { +void Toy_initLiteralArray(Toy_LiteralArray* array) { array->capacity = 0; array->count = 0; array->literals = NULL; } -void freeLiteralArray(LiteralArray* array) { +void Toy_freeLiteralArray(Toy_LiteralArray* array) { //clean up memory for(int i = 0; i < array->count; i++) { - freeLiteral(array->literals[i]); + Toy_freeLiteral(array->literals[i]); } - FREE_ARRAY(Literal, array->literals, array->capacity); - initLiteralArray(array); + TOY_FREE_ARRAY(Toy_Literal, array->literals, array->capacity); + Toy_initLiteralArray(array); } -int pushLiteralArray(LiteralArray* array, Literal literal) { +int Toy_pushLiteralArray(Toy_LiteralArray* array, Toy_Literal literal) { if (array->capacity < array->count + 1) { int oldCapacity = array->capacity; - array->capacity = GROW_CAPACITY(oldCapacity); - array->literals = GROW_ARRAY(Literal, array->literals, oldCapacity, array->capacity); + array->capacity = TOY_GROW_CAPACITY(oldCapacity); + array->literals = TOY_GROW_ARRAY(Toy_Literal, array->literals, oldCapacity, array->capacity); } - array->literals[array->count] = copyLiteral(literal); + array->literals[array->count] = Toy_copyLiteral(literal); return array->count++; } -Literal popLiteralArray(LiteralArray* array) { +Toy_Literal Toy_popLiteralArray(Toy_LiteralArray* array) { if (array->count <= 0) { - return TO_NULL_LITERAL; + return TOY_TO_NULL_LITERAL; } //get the return - Literal ret = array->literals[array->count-1]; + Toy_Literal ret = array->literals[array->count-1]; //null the existing data - array->literals[array->count-1] = TO_NULL_LITERAL; + array->literals[array->count-1] = TOY_TO_NULL_LITERAL; array->count--; return ret; } //find a literal in the array that matches the "literal" argument -int findLiteralIndex(LiteralArray* array, Literal literal) { +int Toy_findLiteralIndex(Toy_LiteralArray* array, Toy_Literal literal) { for (int i = 0; i < array->count; i++) { //not the same type if (array->literals[i].type != literal.type) { @@ -58,7 +58,7 @@ int findLiteralIndex(LiteralArray* array, Literal literal) { } //types match? - if (literalsAreEqual(array->literals[i], literal)) { + if (Toy_literalsAreEqual(array->literals[i], literal)) { return i; } } @@ -66,33 +66,33 @@ int findLiteralIndex(LiteralArray* array, Literal literal) { return -1; } -bool setLiteralArray(LiteralArray* array, Literal index, Literal value) { - if (!IS_INTEGER(index)) { +bool Toy_setLiteralArray(Toy_LiteralArray* array, Toy_Literal index, Toy_Literal value) { + if (!TOY_IS_INTEGER(index)) { return false; } - int idx = AS_INTEGER(index); + int idx = TOY_AS_INTEGER(index); if (idx < 0 || idx >= array->count) { return false; } - freeLiteral(array->literals[idx]); - array->literals[idx] = copyLiteral(value); + Toy_freeLiteral(array->literals[idx]); + array->literals[idx] = Toy_copyLiteral(value); return true; } -Literal getLiteralArray(LiteralArray* array, Literal index) { - if (!IS_INTEGER(index)) { - return TO_NULL_LITERAL; +Toy_Literal Toy_getLiteralArray(Toy_LiteralArray* array, Toy_Literal index) { + if (!TOY_IS_INTEGER(index)) { + return TOY_TO_NULL_LITERAL; } - int idx = AS_INTEGER(index); + int idx = TOY_AS_INTEGER(index); if (idx < 0 || idx >= array->count) { - return TO_NULL_LITERAL; + return TOY_TO_NULL_LITERAL; } - return copyLiteral(array->literals[idx]); + return Toy_copyLiteral(array->literals[idx]); } diff --git a/source/toy_literal_array.h b/source/toy_literal_array.h index b877528..8d98fbd 100644 --- a/source/toy_literal_array.h +++ b/source/toy_literal_array.h @@ -2,19 +2,19 @@ #include "toy_common.h" -#include "literal.h" +#include "toy_literal.h" -typedef struct LiteralArray { - Literal* literals; +typedef struct Toy_LiteralArray { + Toy_Literal* literals; int capacity; int count; -} LiteralArray; +} Toy_LiteralArray; -TOY_API void initLiteralArray(LiteralArray* array); -TOY_API void freeLiteralArray(LiteralArray* array); -TOY_API int pushLiteralArray(LiteralArray* array, Literal literal); -TOY_API Literal popLiteralArray(LiteralArray* array); -TOY_API bool setLiteralArray(LiteralArray* array, Literal index, Literal value); -TOY_API Literal getLiteralArray(LiteralArray* array, Literal index); +TOY_API void Toy_initLiteralArray(Toy_LiteralArray* array); +TOY_API void Toy_freeLiteralArray(Toy_LiteralArray* array); +TOY_API int Toy_pushLiteralArray(Toy_LiteralArray* array, Toy_Literal literal); +TOY_API Toy_Literal Toy_popLiteralArray(Toy_LiteralArray* array); +TOY_API bool Toy_setLiteralArray(Toy_LiteralArray* array, Toy_Literal index, Toy_Literal value); +TOY_API Toy_Literal Toy_getLiteralArray(Toy_LiteralArray* array, Toy_Literal index); -int findLiteralIndex(LiteralArray* array, Literal literal); +int Toy_findLiteralIndex(Toy_LiteralArray* array, Toy_Literal literal); diff --git a/source/toy_literal_dictionary.c b/source/toy_literal_dictionary.c index 8eda7d5..7857c42 100644 --- a/source/toy_literal_dictionary.c +++ b/source/toy_literal_dictionary.c @@ -1,22 +1,22 @@ -#include "literal_dictionary.h" +#include "toy_literal_dictionary.h" -#include "memory.h" +#include "toy_memory.h" -#include "console_colors.h" +#include "toy_console_colors.h" #include //util functions -static void setEntryValues(_entry* entry, Literal key, Literal value) { +static void setEntryValues(Toy_private_entry* entry, Toy_Literal key, Toy_Literal value) { //much simpler now - freeLiteral(entry->key); - entry->key = copyLiteral(key); + Toy_freeLiteral(entry->key); + entry->key = Toy_copyLiteral(key); - freeLiteral(entry->value); - entry->value = copyLiteral(value); + Toy_freeLiteral(entry->value); + entry->value = Toy_copyLiteral(value); } -static _entry* getEntryArray(_entry* array, int capacity, Literal key, unsigned int hash, bool mustExist) { +static Toy_private_entry* getEntryArray(Toy_private_entry* array, int capacity, Toy_Literal key, unsigned int hash, bool mustExist) { //find "key", starting at index unsigned int index = hash % capacity; unsigned int start = index; @@ -26,16 +26,16 @@ static _entry* getEntryArray(_entry* array, int capacity, Literal key, unsigned //literal probing and collision checking while (index != start) { //WARNING: this is the only function allowed to retrieve an entry from the array - _entry* entry = &array[index]; + Toy_private_entry* entry = &array[index]; - if (IS_NULL(entry->key)) { //if key is empty, it's either empty or tombstone - if (IS_NULL(entry->value) && !mustExist) { + if (TOY_IS_NULL(entry->key)) { //if key is empty, it's either empty or tombstone + if (TOY_IS_NULL(entry->value) && !mustExist) { //found a truly empty bucket return entry; } //else it's a tombstone - ignore } else { - if (literalsAreEqual(key, entry->key)) { + if (Toy_literalsAreEqual(key, entry->key)) { return entry; } } @@ -46,46 +46,46 @@ static _entry* getEntryArray(_entry* array, int capacity, Literal key, unsigned return NULL; } -static void adjustEntryCapacity(_entry** dictionaryHandle, int oldCapacity, int capacity) { +static void adjustEntryCapacity(Toy_private_entry** dictionaryHandle, int oldCapacity, int capacity) { //new entry space - _entry* newEntries = ALLOCATE(_entry, capacity); + Toy_private_entry* newEntries = TOY_ALLOCATE(Toy_private_entry, capacity); for (int i = 0; i < capacity; i++) { - newEntries[i].key = TO_NULL_LITERAL; - newEntries[i].value = TO_NULL_LITERAL; + newEntries[i].key = TOY_TO_NULL_LITERAL; + newEntries[i].value = TOY_TO_NULL_LITERAL; } //move the old array into the new one for (int i = 0; i < oldCapacity; i++) { - if (IS_NULL((*dictionaryHandle)[i].key)) { + if (TOY_IS_NULL((*dictionaryHandle)[i].key)) { continue; } //place the key and value in the new array (reusing string memory) - _entry* entry = getEntryArray(newEntries, capacity, TO_NULL_LITERAL, hashLiteral((*dictionaryHandle)[i].key), false); + Toy_private_entry* entry = getEntryArray(newEntries, capacity, TOY_TO_NULL_LITERAL, Toy_hashLiteral((*dictionaryHandle)[i].key), false); entry->key = (*dictionaryHandle)[i].key; entry->value = (*dictionaryHandle)[i].value; } //clear the old array - FREE_ARRAY(_entry, *dictionaryHandle, oldCapacity); + TOY_FREE_ARRAY(Toy_private_entry, *dictionaryHandle, oldCapacity); *dictionaryHandle = newEntries; } -static bool setEntryArray(_entry** dictionaryHandle, int* capacityPtr, int contains, Literal key, Literal value, int hash) { +static bool setEntryArray(Toy_private_entry** dictionaryHandle, int* capacityPtr, int contains, Toy_Literal key, Toy_Literal value, int hash) { //expand array if needed - if (contains + 1 > *capacityPtr * DICTIONARY_MAX_LOAD) { + if (contains + 1 > *capacityPtr * TOY_DICTIONARY_MAX_LOAD) { int oldCapacity = *capacityPtr; - *capacityPtr = GROW_CAPACITY(*capacityPtr); + *capacityPtr = TOY_GROW_CAPACITY(*capacityPtr); adjustEntryCapacity(dictionaryHandle, oldCapacity, *capacityPtr); //custom rather than automatic reallocation } - _entry* entry = getEntryArray(*dictionaryHandle, *capacityPtr, key, hash, false); + Toy_private_entry* entry = getEntryArray(*dictionaryHandle, *capacityPtr, key, hash, false); //true = contains increase - if (IS_NULL(entry->key)) { + if (TOY_IS_NULL(entry->key)) { setEntryValues(entry, key, value); return true; } @@ -97,61 +97,61 @@ static bool setEntryArray(_entry** dictionaryHandle, int* capacityPtr, int conta return false; } -static void freeEntry(_entry* entry) { - freeLiteral(entry->key); - freeLiteral(entry->value); - entry->key = TO_NULL_LITERAL; - entry->value = TO_NULL_LITERAL; +static void freeEntry(Toy_private_entry* entry) { + Toy_freeLiteral(entry->key); + Toy_freeLiteral(entry->value); + entry->key = TOY_TO_NULL_LITERAL; + entry->value = TOY_TO_NULL_LITERAL; } -static void freeEntryArray(_entry* array, int capacity) { +static void freeEntryArray(Toy_private_entry* array, int capacity) { if (array == NULL) { return; } for (int i = 0; i < capacity; i++) { - if (!IS_NULL(array[i].key)) { + if (!TOY_IS_NULL(array[i].key)) { freeEntry(&array[i]); } } - FREE_ARRAY(_entry, array, capacity); + TOY_FREE_ARRAY(Toy_private_entry, array, capacity); } //exposed functions -void initLiteralDictionary(LiteralDictionary* dictionary) { +void Toy_initLiteralDictionary(Toy_LiteralDictionary* dictionary) { //HACK: because modulo by 0 is undefined, set the capacity to a non-zero value (and allocate the arrays) dictionary->entries = NULL; - dictionary->capacity = GROW_CAPACITY(0); + dictionary->capacity = TOY_GROW_CAPACITY(0); dictionary->contains = 0; dictionary->count = 0; adjustEntryCapacity(&dictionary->entries, 0, dictionary->capacity); } -void freeLiteralDictionary(LiteralDictionary* dictionary) { +void Toy_freeLiteralDictionary(Toy_LiteralDictionary* dictionary) { freeEntryArray(dictionary->entries, dictionary->capacity); dictionary->capacity = 0; dictionary->contains = 0; } -void setLiteralDictionary(LiteralDictionary* dictionary, Literal key, Literal value) { - if (IS_NULL(key)) { - fprintf(stderr, ERROR "Dictionaries can't have null keys (set)\n" RESET); +void Toy_setLiteralDictionary(Toy_LiteralDictionary* dictionary, Toy_Literal key, Toy_Literal value) { + if (TOY_IS_NULL(key)) { + fprintf(stderr, TOY_CC_ERROR "Dictionaries can't have null keys (set)\n" TOY_CC_RESET); return; } //BUGFIX: Can't hash a function - if (IS_FUNCTION(key) || IS_FUNCTION_NATIVE(key)) { - fprintf(stderr, ERROR "Dictionaries can't have function keys (set)\n" RESET); + if (TOY_IS_FUNCTION(key) || TOY_IS_FUNCTION_NATIVE(key)) { + fprintf(stderr, TOY_CC_ERROR "Dictionaries can't have function keys (set)\n" TOY_CC_RESET); return; } - if (IS_OPAQUE(key)) { - fprintf(stderr, ERROR "Dictionaries can't have opaque keys (set)\n" RESET); + if (TOY_IS_OPAQUE(key)) { + fprintf(stderr, TOY_CC_ERROR "Dictionaries can't have opaque keys (set)\n" TOY_CC_RESET); return; } - const int increment = setEntryArray(&dictionary->entries, &dictionary->capacity, dictionary->contains, key, value, hashLiteral(key)); + const int increment = setEntryArray(&dictionary->entries, &dictionary->capacity, dictionary->contains, key, value, Toy_hashLiteral(key)); if (increment) { dictionary->contains++; @@ -159,61 +159,61 @@ void setLiteralDictionary(LiteralDictionary* dictionary, Literal key, Literal va } } -Literal getLiteralDictionary(LiteralDictionary* dictionary, Literal key) { - if (IS_NULL(key)) { - fprintf(stderr, ERROR "Dictionaries can't have null keys (get)\n" RESET); - return TO_NULL_LITERAL; +Toy_Literal Toy_getLiteralDictionary(Toy_LiteralDictionary* dictionary, Toy_Literal key) { + if (TOY_IS_NULL(key)) { + fprintf(stderr, TOY_CC_ERROR "Dictionaries can't have null keys (get)\n" TOY_CC_RESET); + return TOY_TO_NULL_LITERAL; } //BUGFIX: Can't hash a function - if (IS_FUNCTION(key) || IS_FUNCTION_NATIVE(key)) { - fprintf(stderr, ERROR "Dictionaries can't have function keys (get)\n" RESET); - return TO_NULL_LITERAL; + if (TOY_IS_FUNCTION(key) || TOY_IS_FUNCTION_NATIVE(key)) { + fprintf(stderr, TOY_CC_ERROR "Dictionaries can't have function keys (get)\n" TOY_CC_RESET); + return TOY_TO_NULL_LITERAL; } - if (IS_OPAQUE(key)) { - fprintf(stderr, ERROR "Dictionaries can't have opaque keys (get)\n" RESET); - return TO_NULL_LITERAL; + if (TOY_IS_OPAQUE(key)) { + fprintf(stderr, TOY_CC_ERROR "Dictionaries can't have opaque keys (get)\n" TOY_CC_RESET); + return TOY_TO_NULL_LITERAL; } - _entry* entry = getEntryArray(dictionary->entries, dictionary->capacity, key, hashLiteral(key), true); + Toy_private_entry* entry = getEntryArray(dictionary->entries, dictionary->capacity, key, Toy_hashLiteral(key), true); if (entry != NULL) { - return copyLiteral(entry->value); + return Toy_copyLiteral(entry->value); } else { - return TO_NULL_LITERAL; + return TOY_TO_NULL_LITERAL; } } -void removeLiteralDictionary(LiteralDictionary* dictionary, Literal key) { - if (IS_NULL(key)) { - fprintf(stderr, ERROR "Dictionaries can't have null keys (remove)\n" RESET); +void Toy_removeLiteralDictionary(Toy_LiteralDictionary* dictionary, Toy_Literal key) { + if (TOY_IS_NULL(key)) { + fprintf(stderr, TOY_CC_ERROR "Dictionaries can't have null keys (remove)\n" TOY_CC_RESET); return; } //BUGFIX: Can't hash a function - if (IS_FUNCTION(key) || IS_FUNCTION_NATIVE(key)) { - fprintf(stderr, ERROR "Dictionaries can't have function keys (remove)\n" RESET); + if (TOY_IS_FUNCTION(key) || TOY_IS_FUNCTION_NATIVE(key)) { + fprintf(stderr, TOY_CC_ERROR "Dictionaries can't have function keys (remove)\n" TOY_CC_RESET); return; } - if (IS_OPAQUE(key)) { - fprintf(stderr, ERROR "Dictionaries can't have opaque keys (remove)\n" RESET); + if (TOY_IS_OPAQUE(key)) { + fprintf(stderr, TOY_CC_ERROR "Dictionaries can't have opaque keys (remove)\n" TOY_CC_RESET); return; } - _entry* entry = getEntryArray(dictionary->entries, dictionary->capacity, key, hashLiteral(key), true); + Toy_private_entry* entry = getEntryArray(dictionary->entries, dictionary->capacity, key, Toy_hashLiteral(key), true); if (entry != NULL) { freeEntry(entry); - entry->value = TO_BOOLEAN_LITERAL(true); //tombstone + entry->value = TOY_TO_BOOLEAN_LITERAL(true); //tombstone dictionary->count--; } } -bool existsLiteralDictionary(LiteralDictionary* dictionary, Literal key) { +bool Toy_existsLiteralDictionary(Toy_LiteralDictionary* dictionary, Toy_Literal key) { //null & not tombstoned - _entry* entry = getEntryArray(dictionary->entries, dictionary->capacity, key, hashLiteral(key), false); - return !(IS_NULL(entry->key) && IS_NULL(entry->value)); + Toy_private_entry* entry = getEntryArray(dictionary->entries, dictionary->capacity, key, Toy_hashLiteral(key), false); + return !(TOY_IS_NULL(entry->key) && TOY_IS_NULL(entry->value)); } diff --git a/source/toy_literal_dictionary.h b/source/toy_literal_dictionary.h index 37f2275..3929c20 100644 --- a/source/toy_literal_dictionary.h +++ b/source/toy_literal_dictionary.h @@ -2,28 +2,28 @@ #include "toy_common.h" -#include "literal.h" +#include "toy_literal.h" //TODO: benchmark this -#define DICTIONARY_MAX_LOAD 0.75 +#define TOY_DICTIONARY_MAX_LOAD 0.75 -typedef struct _entry { - Literal key; - Literal value; -} _entry; +typedef struct Toy_private_entry { + Toy_Literal key; + Toy_Literal value; +} Toy_private_entry; -typedef struct LiteralDictionary { - _entry* entries; +typedef struct Toy_LiteralDictionary { + Toy_private_entry* entries; int capacity; int count; int contains; //count + tombstones, for internal use -} LiteralDictionary; +} Toy_LiteralDictionary; -TOY_API void initLiteralDictionary(LiteralDictionary* dictionary); -TOY_API void freeLiteralDictionary(LiteralDictionary* dictionary); +TOY_API void Toy_initLiteralDictionary(Toy_LiteralDictionary* dictionary); +TOY_API void Toy_freeLiteralDictionary(Toy_LiteralDictionary* dictionary); -TOY_API void setLiteralDictionary(LiteralDictionary* dictionary, Literal key, Literal value); -TOY_API Literal getLiteralDictionary(LiteralDictionary* dictionary, Literal key); -TOY_API void removeLiteralDictionary(LiteralDictionary* dictionary, Literal key); +TOY_API void Toy_setLiteralDictionary(Toy_LiteralDictionary* dictionary, Toy_Literal key, Toy_Literal value); +TOY_API Toy_Literal Toy_getLiteralDictionary(Toy_LiteralDictionary* dictionary, Toy_Literal key); +TOY_API void Toy_removeLiteralDictionary(Toy_LiteralDictionary* dictionary, Toy_Literal key); -TOY_API bool existsLiteralDictionary(LiteralDictionary* dictionary, Literal key); +TOY_API bool Toy_existsLiteralDictionary(Toy_LiteralDictionary* dictionary, Toy_Literal key); diff --git a/source/toy_memory.c b/source/toy_memory.c index 98efd61..c70d978 100644 --- a/source/toy_memory.c +++ b/source/toy_memory.c @@ -1,13 +1,13 @@ -#include "memory.h" -#include "refstring.h" +#include "toy_memory.h" +#include "toy_refstring.h" -#include "console_colors.h" +#include "toy_console_colors.h" #include #include //default allocator -void* defaultMemoryAllocator(void* pointer, size_t oldSize, size_t newSize) { +static void* defaultMemoryAllocator(void* pointer, size_t oldSize, size_t newSize) { if (newSize == 0 && oldSize == 0) { //causes issues, so just skip out with a NO-OP return NULL; @@ -22,7 +22,7 @@ void* defaultMemoryAllocator(void* pointer, size_t oldSize, size_t newSize) { void* mem = realloc(pointer, newSize); if (mem == NULL) { - fprintf(stderr, ERROR "[internal] Memory allocation error (requested %d for %ld, replacing %d)\n" RESET, (int)newSize, (long int)pointer, (int)oldSize); + fprintf(stderr, TOY_CC_ERROR "[internal] Memory allocation error (requested %d for %ld, replacing %d)\n" TOY_CC_RESET, (int)newSize, (long int)pointer, (int)oldSize); exit(-1); } @@ -30,29 +30,29 @@ void* defaultMemoryAllocator(void* pointer, size_t oldSize, size_t newSize) { } //static variables -static MemoryAllocatorFn allocator; +static Toy_MemoryAllocatorFn allocator; //preload static void __attribute__((constructor)) preloadMemoryAllocator() { - setMemoryAllocator(defaultMemoryAllocator); + Toy_setMemoryAllocator(defaultMemoryAllocator); } //exposed API -void* reallocate(void* pointer, size_t oldSize, size_t newSize) { +void* Toy_reallocate(void* pointer, size_t oldSize, size_t newSize) { return allocator(pointer, oldSize, newSize); } -void setMemoryAllocator(MemoryAllocatorFn fn) { +void Toy_setMemoryAllocator(Toy_MemoryAllocatorFn fn) { if (fn == NULL) { - fprintf(stderr, ERROR "[internal] Memory allocator error (can't be null)\n" RESET); + fprintf(stderr, TOY_CC_ERROR "[internal] Memory allocator error (can't be null)\n" TOY_CC_RESET); exit(-1); } - if (fn == reallocate) { - fprintf(stderr, ERROR "[internal] Memory allocator error (can't loop the reallocate function)\n" RESET); + if (fn == Toy_reallocate) { + fprintf(stderr, TOY_CC_ERROR "[internal] Memory allocator error (can't loop the Toy_reallocate function)\n" TOY_CC_RESET); exit(-1); } allocator = fn; - setRefStringAllocatorFn(fn); + Toy_setRefStringAllocatorFn(fn); } diff --git a/source/toy_memory.h b/source/toy_memory.h index 9d35eb2..c2f797d 100644 --- a/source/toy_memory.h +++ b/source/toy_memory.h @@ -2,17 +2,17 @@ #include "toy_common.h" -#define ALLOCATE(type, count) ((type*)reallocate(NULL, 0, sizeof(type) * (count))) -#define FREE(type, pointer) reallocate(pointer, sizeof(type), 0) -#define GROW_CAPACITY(capacity) ((capacity) < 8 ? 8 : (capacity) * 2) -#define GROW_CAPACITY_FAST(capacity) ((capacity) < 32 ? 32 : (capacity) * 2) -#define GROW_ARRAY(type, pointer, oldCount, count) (type*)reallocate((type*)pointer, sizeof(type) * (oldCount), sizeof(type) * (count)) -#define SHRINK_ARRAY(type, pointer, oldCount, count) (type*)reallocate((type*)pointer, sizeof(type) * (oldCount), sizeof(type) * (count)) -#define FREE_ARRAY(type, pointer, oldCount) reallocate((type*)pointer, sizeof(type) * (oldCount), 0) +#define TOY_ALLOCATE(type, count) ((type*)Toy_reallocate(NULL, 0, sizeof(type) * (count))) +#define TOY_FREE(type, pointer) Toy_reallocate(pointer, sizeof(type), 0) +#define TOY_GROW_CAPACITY(capacity) ((capacity) < 8 ? 8 : (capacity) * 2) +#define TOY_GROW_CAPACITY_FAST(capacity) ((capacity) < 32 ? 32 : (capacity) * 2) +#define TOY_GROW_ARRAY(type, pointer, oldCount, count) (type*)Toy_reallocate((type*)pointer, sizeof(type) * (oldCount), sizeof(type) * (count)) +#define TOY_SHRINK_ARRAY(type, pointer, oldCount, count) (type*)Toy_reallocate((type*)pointer, sizeof(type) * (oldCount), sizeof(type) * (count)) +#define TOY_FREE_ARRAY(type, pointer, oldCount) Toy_reallocate((type*)pointer, sizeof(type) * (oldCount), 0) //implementation details -void* reallocate(void* pointer, size_t oldSize, size_t newSize); +void* Toy_reallocate(void* pointer, size_t oldSize, size_t newSize); //assign the memory allocator -typedef void* (*MemoryAllocatorFn)(void* pointer, size_t oldSize, size_t newSize); -TOY_API void setMemoryAllocator(MemoryAllocatorFn); +typedef void* (*Toy_MemoryAllocatorFn)(void* pointer, size_t oldSize, size_t newSize); +TOY_API void Toy_setMemoryAllocator(Toy_MemoryAllocatorFn); diff --git a/source/toy_opcodes.h b/source/toy_opcodes.h index f0d4f4e..b7ceedf 100644 --- a/source/toy_opcodes.h +++ b/source/toy_opcodes.h @@ -1,87 +1,87 @@ #pragma once -typedef enum Opcode { - OP_EOF, +typedef enum Toy_Opcode { + TOY_OP_EOF, //basic statements - OP_ASSERT, - OP_PRINT, + TOY_OP_ASSERT, + TOY_OP_PRINT, //data - OP_LITERAL, - OP_LITERAL_LONG, //for more than 256 literals in a chunk - OP_LITERAL_RAW, //forcibly get the raw value of the literal + TOY_OP_LITERAL, + TOY_OP_LITERAL_LONG, //for more than 256 literals in a chunk + TOY_OP_LITERAL_RAW, //forcibly get the raw value of the literal //arithmetic operators - OP_NEGATE, - OP_ADDITION, - OP_SUBTRACTION, - OP_MULTIPLICATION, - OP_DIVISION, - OP_MODULO, - OP_GROUPING_BEGIN, - OP_GROUPING_END, + TOY_OP_NEGATE, + TOY_OP_ADDITION, + TOY_OP_SUBTRACTION, + TOY_OP_MULTIPLICATION, + TOY_OP_DIVISION, + TOY_OP_MODULO, + TOY_OP_GROUPING_BEGIN, + TOY_OP_GROUPING_END, //variable stuff - OP_SCOPE_BEGIN, - OP_SCOPE_END, + TOY_OP_SCOPE_BEGIN, + TOY_OP_SCOPE_END, - OP_TYPE_DECL, //declare a type to be used (as a literal) - OP_TYPE_DECL_LONG, //declare a type to be used (as a long literal) + TOY_OP_TYPE_DECL, //declare a type to be used (as a literal) + TOY_OP_TYPE_DECL_LONG, //declare a type to be used (as a long literal) - OP_VAR_DECL, //declare a variable to be used (as a literal) - OP_VAR_DECL_LONG, //declare a variable to be used (as a long literal) + TOY_OP_VAR_DECL, //declare a variable to be used (as a literal) + TOY_OP_VAR_DECL_LONG, //declare a variable to be used (as a long literal) - OP_FN_DECL, //declare a function to be used (as a literal) - OP_FN_DECL_LONG, //declare a function to be used (as a long literal) + TOY_OP_FN_DECL, //declare a function to be used (as a literal) + TOY_OP_FN_DECL_LONG, //declare a function to be used (as a long literal) - OP_VAR_ASSIGN, //assign to a literal - OP_VAR_ADDITION_ASSIGN, - OP_VAR_SUBTRACTION_ASSIGN, - OP_VAR_MULTIPLICATION_ASSIGN, - OP_VAR_DIVISION_ASSIGN, - OP_VAR_MODULO_ASSIGN, + TOY_OP_VAR_ASSIGN, //assign to a literal + TOY_OP_VAR_ADDITION_ASSIGN, + TOY_OP_VAR_SUBTRACTION_ASSIGN, + TOY_OP_VAR_MULTIPLICATION_ASSIGN, + TOY_OP_VAR_DIVISION_ASSIGN, + TOY_OP_VAR_MODULO_ASSIGN, - OP_TYPE_CAST, //temporarily change a type of an atomic value - OP_TYPE_OF, //get the type of a variable + TOY_OP_TYPE_CAST, //temporarily change a type of an atomic value + TOY_OP_TYPE_OF, //get the type of a variable - OP_IMPORT, - OP_EXPORT_removed, + TOY_OP_IMPORT, + TOY_OP_EXPORT_removed, //for indexing - OP_INDEX, - OP_INDEX_ASSIGN, - OP_INDEX_ASSIGN_INTERMEDIATE, - OP_DOT, + TOY_OP_INDEX, + TOY_OP_INDEX_ASSIGN, + TOY_OP_INDEX_ASSIGN_INTERMEDIATE, + TOY_OP_DOT, //comparison of values - OP_COMPARE_EQUAL, - OP_COMPARE_NOT_EQUAL, - OP_COMPARE_LESS, - OP_COMPARE_LESS_EQUAL, - OP_COMPARE_GREATER, - OP_COMPARE_GREATER_EQUAL, - OP_INVERT, //for booleans + TOY_OP_COMPARE_EQUAL, + TOY_OP_COMPARE_NOT_EQUAL, + TOY_OP_COMPARE_LESS, + TOY_OP_COMPARE_LESS_EQUAL, + TOY_OP_COMPARE_GREATER, + TOY_OP_COMPARE_GREATER_EQUAL, + TOY_OP_INVERT, //for booleans //logical operators - OP_AND, - OP_OR, + TOY_OP_AND, + TOY_OP_OR, //jumps, and conditional jumps (absolute) - OP_JUMP, - OP_IF_FALSE_JUMP, - OP_FN_CALL, - OP_FN_RETURN, + TOY_OP_JUMP, + TOY_OP_IF_FALSE_JUMP, + TOY_OP_FN_CALL, + TOY_OP_FN_RETURN, //pop the stack at the end of a complex statement - OP_POP_STACK, + TOY_OP_POP_STACK, //ternary shorthand - OP_TERNARY, + TOY_OP_TERNARY, //meta - OP_FN_END, //different from SECTION_END - OP_SECTION_END = 255, + TOY_OP_FN_END, //different from SECTION_END + TOY_OP_SECTION_END = 255, //TODO: add more -} Opcode; +} Toy_Opcode; diff --git a/source/toy_parser.c b/source/toy_parser.c index 217ca71..36aa991 100644 --- a/source/toy_parser.c +++ b/source/toy_parser.c @@ -1,22 +1,22 @@ -#include "parser.h" +#include "toy_parser.h" -#include "memory.h" -#include "literal.h" -#include "opcodes.h" +#include "toy_memory.h" +#include "toy_literal.h" +#include "toy_opcodes.h" -#include "console_colors.h" +#include "toy_console_colors.h" #include //utility functions -static void error(Parser* parser, Token token, const char* message) { +static void error(Toy_Parser* parser, Toy_Token token, const char* message) { //keep going while panicing if (parser->panic) return; - fprintf(stderr, ERROR "[Line %d] Error", token.line); + fprintf(stderr, TOY_CC_ERROR "[Line %d] Error", token.line); //check type - if (token.type == TOKEN_EOF) { + if (token.type == TOY_TOKEN_EOF) { fprintf(stderr, " at end"); } @@ -25,21 +25,21 @@ static void error(Parser* parser, Token token, const char* message) { } //finally - fprintf(stderr, ": %s\n" RESET, message); + fprintf(stderr, ": %s\n" TOY_CC_RESET, message); parser->error = true; parser->panic = true; } -static void advance(Parser* parser) { +static void advance(Toy_Parser* parser) { parser->previous = parser->current; - parser->current = scanLexer(parser->lexer); + parser->current = Toy_scanLexer(parser->lexer); - if (parser->current.type == TOKEN_ERROR) { - error(parser, parser->current, "Lexer error"); + if (parser->current.type == TOY_TOKEN_ERROR) { + error(parser, parser->current, "Toy_Lexer error"); } } -static bool match(Parser* parser, TokenType tokenType) { +static bool match(Toy_Parser* parser, Toy_TokenType tokenType) { if (parser->current.type == tokenType) { advance(parser); return true; @@ -47,7 +47,7 @@ static bool match(Parser* parser, TokenType tokenType) { return false; } -static void consume(Parser* parser, TokenType tokenType, const char* msg) { +static void consume(Toy_Parser* parser, Toy_TokenType tokenType, const char* msg) { if (parser->current.type != tokenType) { error(parser, parser->current, msg); return; @@ -56,30 +56,30 @@ static void consume(Parser* parser, TokenType tokenType, const char* msg) { advance(parser); } -static void synchronize(Parser* parser) { +static void synchronize(Toy_Parser* parser) { #ifndef TOY_EXPORT if (command.verbose) { - fprintf(stderr, ERROR "synchronizing\n" RESET); + fprintf(stderr, TOY_CC_ERROR "synchronizing\n" TOY_CC_RESET); } #endif - while (parser->current.type != TOKEN_EOF) { + while (parser->current.type != TOY_TOKEN_EOF) { switch(parser->current.type) { //these tokens can start a line - case TOKEN_ASSERT: - case TOKEN_BREAK: - case TOKEN_CLASS: - case TOKEN_CONTINUE: - case TOKEN_DO: - case TOKEN_EXPORT: - case TOKEN_FOR: - case TOKEN_FOREACH: - case TOKEN_IF: - case TOKEN_IMPORT: - case TOKEN_PRINT: - case TOKEN_RETURN: - case TOKEN_VAR: - case TOKEN_WHILE: + case TOY_TOKEN_ASSERT: + case TOY_TOKEN_BREAK: + case TOY_TOKEN_CLASS: + case TOY_TOKEN_CONTINUE: + case TOY_TOKEN_DO: + case TOY_TOKEN_EXPORT: + case TOY_TOKEN_FOR: + case TOY_TOKEN_FOREACH: + case TOY_TOKEN_IF: + case TOY_TOKEN_IMPORT: + case TOY_TOKEN_PRINT: + case TOY_TOKEN_RETURN: + case TOY_TOKEN_VAR: + case TOY_TOKEN_WHILE: parser->panic = false; return; @@ -104,7 +104,7 @@ typedef enum { PREC_PRIMARY, } PrecedenceRule; -typedef Opcode (*ParseFn)(Parser* parser, ASTNode** nodeHandle); +typedef Toy_Opcode (*ParseFn)(Toy_Parser* parser, Toy_ASTNode** nodeHandle); typedef struct { ParseFn prefix; @@ -115,126 +115,126 @@ typedef struct { ParseRule parseRules[]; //forward declarations -static void declaration(Parser* parser, ASTNode** nodeHandle); -static void parsePrecedence(Parser* parser, ASTNode** nodeHandle, PrecedenceRule rule); -static Literal readTypeToLiteral(Parser* parser); +static void declaration(Toy_Parser* parser, Toy_ASTNode** nodeHandle); +static void parsePrecedence(Toy_Parser* parser, Toy_ASTNode** nodeHandle, PrecedenceRule rule); +static Toy_Literal readTypeToLiteral(Toy_Parser* parser); //TODO: resolve the messy order of these //the expression rules -static Opcode asType(Parser* parser, ASTNode** nodeHandle) { - Literal literal = readTypeToLiteral(parser); +static Toy_Opcode asType(Toy_Parser* parser, Toy_ASTNode** nodeHandle) { + Toy_Literal literal = readTypeToLiteral(parser); - if (!IS_TYPE(literal)) { + if (!TOY_IS_TYPE(literal)) { error(parser, parser->previous, "Expected type after 'astype' keyword"); - freeLiteral(literal); - return OP_EOF; + Toy_freeLiteral(literal); + return TOY_OP_EOF; } - emitASTNodeLiteral(nodeHandle, literal); + Toy_emitASTNodeLiteral(nodeHandle, literal); - freeLiteral(literal); + Toy_freeLiteral(literal); - return OP_EOF; + return TOY_OP_EOF; } -static Opcode typeOf(Parser* parser, ASTNode** nodeHandle) { - ASTNode* rhs = NULL; +static Toy_Opcode typeOf(Toy_Parser* parser, Toy_ASTNode** nodeHandle) { + Toy_ASTNode* rhs = NULL; parsePrecedence(parser, &rhs, PREC_TERNARY); - emitASTNodeUnary(nodeHandle, OP_TYPE_OF, rhs); - return OP_EOF; + Toy_emitASTNodeUnary(nodeHandle, TOY_OP_TYPE_OF, rhs); + return TOY_OP_EOF; } -static Opcode compound(Parser* parser, ASTNode** nodeHandle) { +static Toy_Opcode compound(Toy_Parser* parser, Toy_ASTNode** nodeHandle) { //read either an array or a dictionary into a literal node int iterations = 0; //count the number of entries iterated over //compound nodes to store what is read - ASTNode* array = NULL; - ASTNode* dictionary = NULL; + Toy_ASTNode* array = NULL; + Toy_ASTNode* dictionary = NULL; - while (!match(parser, TOKEN_BRACKET_RIGHT)) { + while (!match(parser, TOY_TOKEN_BRACKET_RIGHT)) { //if empty dictionary, there will be a colon between the brackets - if (iterations == 0 && match(parser, TOKEN_COLON)) { - consume(parser, TOKEN_BRACKET_RIGHT, "Expected ']' at the end of empty dictionary definition"); + if (iterations == 0 && match(parser, TOY_TOKEN_COLON)) { + consume(parser, TOY_TOKEN_BRACKET_RIGHT, "Expected ']' at the end of empty dictionary definition"); //emit an empty dictionary and finish - emitASTNodeCompound(&dictionary, LITERAL_DICTIONARY); + Toy_emitASTNodeCompound(&dictionary, TOY_LITERAL_DICTIONARY); break; } if (iterations > 0) { - consume(parser, TOKEN_COMMA, "Expected ',' in array or dictionary"); + consume(parser, TOY_TOKEN_COMMA, "Expected ',' in array or dictionary"); } iterations++; - ASTNode* left = NULL; - ASTNode* right = NULL; + Toy_ASTNode* left = NULL; + Toy_ASTNode* right = NULL; //store the left parsePrecedence(parser, &left, PREC_PRIMARY); if (!left) { //error - return OP_EOF; + return TOY_OP_EOF; } //detect a dictionary - if (match(parser, TOKEN_COLON)) { + if (match(parser, TOY_TOKEN_COLON)) { parsePrecedence(parser, &right, PREC_PRIMARY); if (!right) { //error - freeASTNode(left); - return OP_EOF; + Toy_freeASTNode(left); + return TOY_OP_EOF; } //check we ARE defining a dictionary if (array) { error(parser, parser->previous, "Incorrect detection between array and dictionary"); - freeASTNode(array); - return OP_EOF; + Toy_freeASTNode(array); + return TOY_OP_EOF; } //init the dictionary if (!dictionary) { - emitASTNodeCompound(&dictionary, LITERAL_DICTIONARY); + Toy_emitASTNodeCompound(&dictionary, TOY_LITERAL_DICTIONARY); } //grow the node if needed if (dictionary->compound.capacity < dictionary->compound.count + 1) { int oldCapacity = dictionary->compound.capacity; - dictionary->compound.capacity = GROW_CAPACITY(oldCapacity); - dictionary->compound.nodes = GROW_ARRAY(ASTNode, dictionary->compound.nodes, oldCapacity, dictionary->compound.capacity); + dictionary->compound.capacity = TOY_GROW_CAPACITY(oldCapacity); + dictionary->compound.nodes = TOY_GROW_ARRAY(Toy_ASTNode, dictionary->compound.nodes, oldCapacity, dictionary->compound.capacity); } //store the left and right in the node - setASTNodePair(&dictionary->compound.nodes[dictionary->compound.count++], left, right); + Toy_setASTNodePair(&dictionary->compound.nodes[dictionary->compound.count++], left, right); } //detect an array else { //check we ARE defining an array if (dictionary) { error(parser, parser->current, "Incorrect detection between array and dictionary"); - freeASTNode(dictionary); - return OP_EOF; + Toy_freeASTNode(dictionary); + return TOY_OP_EOF; } //init the array if (!array) { - emitASTNodeCompound(&array, LITERAL_ARRAY); + Toy_emitASTNodeCompound(&array, TOY_LITERAL_ARRAY); } //grow the node if needed if (array->compound.capacity < array->compound.count + 1) { int oldCapacity = array->compound.capacity; - array->compound.capacity = GROW_CAPACITY(oldCapacity); - array->compound.nodes = GROW_ARRAY(ASTNode, array->compound.nodes, oldCapacity, array->compound.capacity); + array->compound.capacity = TOY_GROW_CAPACITY(oldCapacity); + array->compound.nodes = TOY_GROW_ARRAY(Toy_ASTNode, array->compound.nodes, oldCapacity, array->compound.capacity); } //copy into the array, and manually free the temp node array->compound.nodes[array->compound.count++] = *left; - FREE(ASTNode, left); + TOY_FREE(Toy_ASTNode, left); } } @@ -247,287 +247,287 @@ static Opcode compound(Parser* parser, ASTNode** nodeHandle) { } else { //both are null, must be an array (because reasons) - emitASTNodeCompound(&array, LITERAL_ARRAY); + Toy_emitASTNodeCompound(&array, TOY_LITERAL_ARRAY); (*nodeHandle) = array; } //ignored - return OP_EOF; + return TOY_OP_EOF; } -static Opcode string(Parser* parser, ASTNode** nodeHandle) { +static Toy_Opcode string(Toy_Parser* parser, Toy_ASTNode** nodeHandle) { //handle strings switch(parser->previous.type) { - case TOKEN_LITERAL_STRING: { + case TOY_TOKEN_LITERAL_STRING: { int length = parser->previous.length; //for safety - if (length > MAX_STRING_LENGTH) { - length = MAX_STRING_LENGTH; + if (length > TOY_MAX_STRING_LENGTH) { + length = TOY_MAX_STRING_LENGTH; char buffer[256]; - snprintf(buffer, 256, ERROR "Strings can only be a maximum of %d characters long" RESET, MAX_STRING_LENGTH); + snprintf(buffer, 256, TOY_CC_ERROR "Strings can only be a maximum of %d characters long" TOY_CC_RESET, TOY_MAX_STRING_LENGTH); error(parser, parser->previous, buffer); } - Literal literal = TO_STRING_LITERAL(createRefStringLength(parser->previous.lexeme, length)); - emitASTNodeLiteral(nodeHandle, literal); - freeLiteral(literal); - return OP_EOF; + Toy_Literal literal = TOY_TO_STRING_LITERAL(Toy_createRefStringLength(parser->previous.lexeme, length)); + Toy_emitASTNodeLiteral(nodeHandle, literal); + Toy_freeLiteral(literal); + return TOY_OP_EOF; } //TODO: interpolated strings default: error(parser, parser->previous, "Unexpected token passed to string precedence rule"); - return OP_EOF; + return TOY_OP_EOF; } } -static Opcode grouping(Parser* parser, ASTNode** nodeHandle) { +static Toy_Opcode grouping(Toy_Parser* parser, Toy_ASTNode** nodeHandle) { //handle groupings with () switch(parser->previous.type) { - case TOKEN_PAREN_LEFT: { + case TOY_TOKEN_PAREN_LEFT: { parsePrecedence(parser, nodeHandle, PREC_TERNARY); - consume(parser, TOKEN_PAREN_RIGHT, "Expected ')' at end of grouping"); + consume(parser, TOY_TOKEN_PAREN_RIGHT, "Expected ')' at end of grouping"); //process the result without optimisations - emitASTNodeGrouping(nodeHandle); - return OP_EOF; + Toy_emitASTNodeGrouping(nodeHandle); + return TOY_OP_EOF; } default: error(parser, parser->previous, "Unexpected token passed to grouping precedence rule"); - return OP_EOF; + return TOY_OP_EOF; } } -static Opcode binary(Parser* parser, ASTNode** nodeHandle) { +static Toy_Opcode binary(Toy_Parser* parser, Toy_ASTNode** nodeHandle) { advance(parser); //binary() is an infix rule - so only get the RHS of the operator switch(parser->previous.type) { //arithmetic - case TOKEN_PLUS: { + case TOY_TOKEN_PLUS: { parsePrecedence(parser, nodeHandle, PREC_TERM); - return OP_ADDITION; + return TOY_OP_ADDITION; } - case TOKEN_MINUS: { + case TOY_TOKEN_MINUS: { parsePrecedence(parser, nodeHandle, PREC_TERM); - return OP_SUBTRACTION; + return TOY_OP_SUBTRACTION; } - case TOKEN_MULTIPLY: { + case TOY_TOKEN_MULTIPLY: { parsePrecedence(parser, nodeHandle, PREC_FACTOR); - return OP_MULTIPLICATION; + return TOY_OP_MULTIPLICATION; } - case TOKEN_DIVIDE: { + case TOY_TOKEN_DIVIDE: { parsePrecedence(parser, nodeHandle, PREC_FACTOR); - return OP_DIVISION; + return TOY_OP_DIVISION; } - case TOKEN_MODULO: { + case TOY_TOKEN_MODULO: { parsePrecedence(parser, nodeHandle, PREC_FACTOR); - return OP_MODULO; + return TOY_OP_MODULO; } //assignment - case TOKEN_ASSIGN: { + case TOY_TOKEN_ASSIGN: { parsePrecedence(parser, nodeHandle, PREC_ASSIGNMENT); - return OP_VAR_ASSIGN; + return TOY_OP_VAR_ASSIGN; } - case TOKEN_PLUS_ASSIGN: { + case TOY_TOKEN_PLUS_ASSIGN: { parsePrecedence(parser, nodeHandle, PREC_ASSIGNMENT); - return OP_VAR_ADDITION_ASSIGN; + return TOY_OP_VAR_ADDITION_ASSIGN; } - case TOKEN_MINUS_ASSIGN: { + case TOY_TOKEN_MINUS_ASSIGN: { parsePrecedence(parser, nodeHandle, PREC_ASSIGNMENT); - return OP_VAR_SUBTRACTION_ASSIGN; + return TOY_OP_VAR_SUBTRACTION_ASSIGN; } - case TOKEN_MULTIPLY_ASSIGN: { + case TOY_TOKEN_MULTIPLY_ASSIGN: { parsePrecedence(parser, nodeHandle, PREC_ASSIGNMENT); - return OP_VAR_MULTIPLICATION_ASSIGN; + return TOY_OP_VAR_MULTIPLICATION_ASSIGN; } - case TOKEN_DIVIDE_ASSIGN: { + case TOY_TOKEN_DIVIDE_ASSIGN: { parsePrecedence(parser, nodeHandle, PREC_ASSIGNMENT); - return OP_VAR_DIVISION_ASSIGN; + return TOY_OP_VAR_DIVISION_ASSIGN; } - case TOKEN_MODULO_ASSIGN: { + case TOY_TOKEN_MODULO_ASSIGN: { parsePrecedence(parser, nodeHandle, PREC_ASSIGNMENT); - return OP_VAR_MODULO_ASSIGN; + return TOY_OP_VAR_MODULO_ASSIGN; } //comparison - case TOKEN_EQUAL: { + case TOY_TOKEN_EQUAL: { parsePrecedence(parser, nodeHandle, PREC_COMPARISON); - return OP_COMPARE_EQUAL; + return TOY_OP_COMPARE_EQUAL; } - case TOKEN_NOT_EQUAL: { + case TOY_TOKEN_NOT_EQUAL: { parsePrecedence(parser, nodeHandle, PREC_COMPARISON); - return OP_COMPARE_NOT_EQUAL; + return TOY_OP_COMPARE_NOT_EQUAL; } - case TOKEN_LESS: { + case TOY_TOKEN_LESS: { parsePrecedence(parser, nodeHandle, PREC_COMPARISON); - return OP_COMPARE_LESS; + return TOY_OP_COMPARE_LESS; } - case TOKEN_LESS_EQUAL: { + case TOY_TOKEN_LESS_EQUAL: { parsePrecedence(parser, nodeHandle, PREC_COMPARISON); - return OP_COMPARE_LESS_EQUAL; + return TOY_OP_COMPARE_LESS_EQUAL; } - case TOKEN_GREATER: { + case TOY_TOKEN_GREATER: { parsePrecedence(parser, nodeHandle, PREC_COMPARISON); - return OP_COMPARE_GREATER; + return TOY_OP_COMPARE_GREATER; } - case TOKEN_GREATER_EQUAL: { + case TOY_TOKEN_GREATER_EQUAL: { parsePrecedence(parser, nodeHandle, PREC_COMPARISON); - return OP_COMPARE_GREATER_EQUAL; + return TOY_OP_COMPARE_GREATER_EQUAL; } - case TOKEN_AND: { + case TOY_TOKEN_AND: { parsePrecedence(parser, nodeHandle, PREC_COMPARISON); - return OP_AND; + return TOY_OP_AND; } - case TOKEN_OR: { + case TOY_TOKEN_OR: { parsePrecedence(parser, nodeHandle, PREC_COMPARISON); - return OP_OR; + return TOY_OP_OR; } default: error(parser, parser->previous, "Unexpected token passed to binary precedence rule"); - return OP_EOF; + return TOY_OP_EOF; } } -static Opcode unary(Parser* parser, ASTNode** nodeHandle) { - ASTNode* tmpNode = NULL; +static Toy_Opcode unary(Toy_Parser* parser, Toy_ASTNode** nodeHandle) { + Toy_ASTNode* tmpNode = NULL; - if (parser->previous.type == TOKEN_MINUS) { + if (parser->previous.type == TOY_TOKEN_MINUS) { //temp handle to potentially negate values parsePrecedence(parser, &tmpNode, PREC_TERNARY); //can be a literal //optimisation: check for negative literals - if (tmpNode != NULL && tmpNode->type == AST_NODE_LITERAL && (IS_INTEGER(tmpNode->atomic.literal) || IS_FLOAT(tmpNode->atomic.literal))) { + if (tmpNode != NULL && tmpNode->type == TOY_AST_NODE_LITERAL && (TOY_IS_INTEGER(tmpNode->atomic.literal) || TOY_IS_FLOAT(tmpNode->atomic.literal))) { //negate directly, if int or float - Literal lit = tmpNode->atomic.literal; + Toy_Literal lit = tmpNode->atomic.literal; - if (IS_INTEGER(lit)) { - lit = TO_INTEGER_LITERAL(-AS_INTEGER(lit)); + if (TOY_IS_INTEGER(lit)) { + lit = TOY_TO_INTEGER_LITERAL(-TOY_AS_INTEGER(lit)); } - if (IS_FLOAT(lit)) { - lit = TO_FLOAT_LITERAL(-AS_FLOAT(lit)); + if (TOY_IS_FLOAT(lit)) { + lit = TOY_TO_FLOAT_LITERAL(-TOY_AS_FLOAT(lit)); } tmpNode->atomic.literal = lit; *nodeHandle = tmpNode; - return OP_EOF; + return TOY_OP_EOF; } //check for negated boolean errors - if (tmpNode != NULL && tmpNode->type == AST_NODE_LITERAL && IS_BOOLEAN(tmpNode->atomic.literal)) { + if (tmpNode != NULL && tmpNode->type == TOY_AST_NODE_LITERAL && TOY_IS_BOOLEAN(tmpNode->atomic.literal)) { error(parser, parser->previous, "Negative booleans are not allowed"); - return OP_EOF; + return TOY_OP_EOF; } //actually emit the negation node - emitASTNodeUnary(nodeHandle, OP_NEGATE, tmpNode); + Toy_emitASTNodeUnary(nodeHandle, TOY_OP_NEGATE, tmpNode); } - else if (parser->previous.type == TOKEN_NOT) { + else if (parser->previous.type == TOY_TOKEN_NOT) { //temp handle to potentially negate values parsePrecedence(parser, &tmpNode, PREC_CALL); //can be a literal, grouping, fn call, etc. //optimisation: check for inverted booleans - if (tmpNode != NULL && tmpNode->type == AST_NODE_LITERAL && IS_BOOLEAN(tmpNode->atomic.literal)) { + if (tmpNode != NULL && tmpNode->type == TOY_AST_NODE_LITERAL && TOY_IS_BOOLEAN(tmpNode->atomic.literal)) { //negate directly, if boolean - Literal lit = tmpNode->atomic.literal; + Toy_Literal lit = tmpNode->atomic.literal; - lit = TO_BOOLEAN_LITERAL(!AS_BOOLEAN(lit)); + lit = TOY_TO_BOOLEAN_LITERAL(!TOY_AS_BOOLEAN(lit)); tmpNode->atomic.literal = lit; *nodeHandle = tmpNode; - return OP_EOF; + return TOY_OP_EOF; } //actually emit the negation - emitASTNodeUnary(nodeHandle, OP_INVERT, tmpNode); + Toy_emitASTNodeUnary(nodeHandle, TOY_OP_INVERT, tmpNode); } else { error(parser, parser->previous, "Unexpected token passed to unary precedence rule"); - return OP_EOF; + return TOY_OP_EOF; } - return OP_EOF; + return TOY_OP_EOF; } -static Opcode atomic(Parser* parser, ASTNode** nodeHandle) { +static Toy_Opcode atomic(Toy_Parser* parser, Toy_ASTNode** nodeHandle) { switch(parser->previous.type) { - case TOKEN_NULL: - emitASTNodeLiteral(nodeHandle, TO_NULL_LITERAL); - return OP_EOF; + case TOY_TOKEN_NULL: + Toy_emitASTNodeLiteral(nodeHandle, TOY_TO_NULL_LITERAL); + return TOY_OP_EOF; - case TOKEN_LITERAL_TRUE: - emitASTNodeLiteral(nodeHandle, TO_BOOLEAN_LITERAL(true)); - return OP_EOF; + case TOY_TOKEN_LITERAL_TRUE: + Toy_emitASTNodeLiteral(nodeHandle, TOY_TO_BOOLEAN_LITERAL(true)); + return TOY_OP_EOF; - case TOKEN_LITERAL_FALSE: - emitASTNodeLiteral(nodeHandle, TO_BOOLEAN_LITERAL(false)); - return OP_EOF; + case TOY_TOKEN_LITERAL_FALSE: + Toy_emitASTNodeLiteral(nodeHandle, TOY_TO_BOOLEAN_LITERAL(false)); + return TOY_OP_EOF; - case TOKEN_LITERAL_INTEGER: { + case TOY_TOKEN_LITERAL_INTEGER: { int value = 0; sscanf(parser->previous.lexeme, "%d", &value); - emitASTNodeLiteral(nodeHandle, TO_INTEGER_LITERAL(value)); - return OP_EOF; + Toy_emitASTNodeLiteral(nodeHandle, TOY_TO_INTEGER_LITERAL(value)); + return TOY_OP_EOF; } - case TOKEN_LITERAL_FLOAT: { + case TOY_TOKEN_LITERAL_FLOAT: { float value = 0; sscanf(parser->previous.lexeme, "%f", &value); - emitASTNodeLiteral(nodeHandle, TO_FLOAT_LITERAL(value)); - return OP_EOF; + Toy_emitASTNodeLiteral(nodeHandle, TOY_TO_FLOAT_LITERAL(value)); + return TOY_OP_EOF; } - case TOKEN_TYPE: { - if (match(parser, TOKEN_CONST)) { - emitASTNodeLiteral(nodeHandle, TO_TYPE_LITERAL(LITERAL_TYPE, true)); + case TOY_TOKEN_TYPE: { + if (match(parser, TOY_TOKEN_CONST)) { + Toy_emitASTNodeLiteral(nodeHandle, TOY_TO_TYPE_LITERAL(TOY_LITERAL_TYPE, true)); } else { - emitASTNodeLiteral(nodeHandle, TO_TYPE_LITERAL(LITERAL_TYPE, false)); + Toy_emitASTNodeLiteral(nodeHandle, TOY_TO_TYPE_LITERAL(TOY_LITERAL_TYPE, false)); } - return OP_EOF; + return TOY_OP_EOF; } default: error(parser, parser->previous, "Unexpected token passed to atomic precedence rule"); - return OP_EOF; + return TOY_OP_EOF; } } -static Opcode identifier(Parser* parser, ASTNode** nodeHandle) { +static Toy_Opcode identifier(Toy_Parser* parser, Toy_ASTNode** nodeHandle) { //make a copy of the string - Token identifierToken = parser->previous; + Toy_Token identifierToken = parser->previous; - if (identifierToken.type != TOKEN_IDENTIFIER) { + if (identifierToken.type != TOY_TOKEN_IDENTIFIER) { error(parser, parser->previous, "Expected identifier"); - return OP_EOF; + return TOY_OP_EOF; } int length = identifierToken.length; @@ -538,281 +538,281 @@ static Opcode identifier(Parser* parser, ASTNode** nodeHandle) { error(parser, parser->previous, "Identifiers can only be a maximum of 256 characters long"); } - Literal identifier = TO_IDENTIFIER_LITERAL(createRefStringLength(identifierToken.lexeme, length)); - emitASTNodeLiteral(nodeHandle, identifier); - freeLiteral(identifier); + Toy_Literal identifier = TOY_TO_IDENTIFIER_LITERAL(Toy_createRefStringLength(identifierToken.lexeme, length)); + Toy_emitASTNodeLiteral(nodeHandle, identifier); + Toy_freeLiteral(identifier); - return OP_EOF; + return TOY_OP_EOF; } -static Opcode castingPrefix(Parser* parser, ASTNode** nodeHandle) { +static Toy_Opcode castingPrefix(Toy_Parser* parser, Toy_ASTNode** nodeHandle) { switch(parser->previous.type) { - case TOKEN_BOOLEAN: { - Literal literal = TO_TYPE_LITERAL(LITERAL_BOOLEAN, false); - emitASTNodeLiteral(nodeHandle, literal); - freeLiteral(literal); + case TOY_TOKEN_BOOLEAN: { + Toy_Literal literal = TOY_TO_TYPE_LITERAL(TOY_LITERAL_BOOLEAN, false); + Toy_emitASTNodeLiteral(nodeHandle, literal); + Toy_freeLiteral(literal); } break; - case TOKEN_INTEGER: { - Literal literal = TO_TYPE_LITERAL(LITERAL_INTEGER, false); - emitASTNodeLiteral(nodeHandle, literal); - freeLiteral(literal); + case TOY_TOKEN_INTEGER: { + Toy_Literal literal = TOY_TO_TYPE_LITERAL(TOY_LITERAL_INTEGER, false); + Toy_emitASTNodeLiteral(nodeHandle, literal); + Toy_freeLiteral(literal); } break; - case TOKEN_FLOAT: { - Literal literal = TO_TYPE_LITERAL(LITERAL_FLOAT, false); - emitASTNodeLiteral(nodeHandle, literal); - freeLiteral(literal); + case TOY_TOKEN_FLOAT: { + Toy_Literal literal = TOY_TO_TYPE_LITERAL(TOY_LITERAL_FLOAT, false); + Toy_emitASTNodeLiteral(nodeHandle, literal); + Toy_freeLiteral(literal); } break; - case TOKEN_STRING: { - Literal literal = TO_TYPE_LITERAL(LITERAL_STRING, false); - emitASTNodeLiteral(nodeHandle, literal); - freeLiteral(literal); + case TOY_TOKEN_STRING: { + Toy_Literal literal = TOY_TO_TYPE_LITERAL(TOY_LITERAL_STRING, false); + Toy_emitASTNodeLiteral(nodeHandle, literal); + Toy_freeLiteral(literal); } break; default: error(parser, parser->previous, "Unexpected token passed to casting precedence rule"); - return OP_EOF; + return TOY_OP_EOF; } - return OP_EOF; + return TOY_OP_EOF; } -static Opcode castingInfix(Parser* parser, ASTNode** nodeHandle) { +static Toy_Opcode castingInfix(Toy_Parser* parser, Toy_ASTNode** nodeHandle) { advance(parser); //NOTE: using the precedence rules here switch(parser->previous.type) { - case TOKEN_IDENTIFIER: + case TOY_TOKEN_IDENTIFIER: identifier(parser, nodeHandle); break; - case TOKEN_LITERAL_TRUE: - case TOKEN_LITERAL_FALSE: + case TOY_TOKEN_LITERAL_TRUE: + case TOY_TOKEN_LITERAL_FALSE: atomic(parser, nodeHandle); break; - case TOKEN_LITERAL_INTEGER: + case TOY_TOKEN_LITERAL_INTEGER: atomic(parser, nodeHandle); break; - case TOKEN_LITERAL_FLOAT: + case TOY_TOKEN_LITERAL_FLOAT: atomic(parser, nodeHandle); break; - case TOKEN_LITERAL_STRING: + case TOY_TOKEN_LITERAL_STRING: atomic(parser, nodeHandle); break; default: error(parser, parser->previous, "Unexpected token passed to casting infix precedence rule"); - return OP_EOF; + return TOY_OP_EOF; } - return OP_TYPE_CAST; + return TOY_OP_TYPE_CAST; } //TODO: fix these screwy names -static Opcode incrementPrefix(Parser* parser, ASTNode** nodeHandle) { +static Toy_Opcode incrementPrefix(Toy_Parser* parser, Toy_ASTNode** nodeHandle) { advance(parser); - ASTNode* tmpNode = NULL; + Toy_ASTNode* tmpNode = NULL; identifier(parser, &tmpNode); - emitASTNodePrefixIncrement(nodeHandle, tmpNode->atomic.literal); + Toy_emitASTNodePrefixIncrement(nodeHandle, tmpNode->atomic.literal); - freeASTNode(tmpNode); + Toy_freeASTNode(tmpNode); - return OP_EOF; + return TOY_OP_EOF; } -static Opcode incrementInfix(Parser* parser, ASTNode** nodeHandle) { - ASTNode* tmpNode = NULL; +static Toy_Opcode incrementInfix(Toy_Parser* parser, Toy_ASTNode** nodeHandle) { + Toy_ASTNode* tmpNode = NULL; identifier(parser, &tmpNode); advance(parser); - emitASTNodePostfixIncrement(nodeHandle, tmpNode->atomic.literal); + Toy_emitASTNodePostfixIncrement(nodeHandle, tmpNode->atomic.literal); - freeASTNode(tmpNode); + Toy_freeASTNode(tmpNode); - return OP_EOF; + return TOY_OP_EOF; } -static Opcode decrementPrefix(Parser* parser, ASTNode** nodeHandle) { +static Toy_Opcode decrementPrefix(Toy_Parser* parser, Toy_ASTNode** nodeHandle) { advance(parser); - ASTNode* tmpNode = NULL; + Toy_ASTNode* tmpNode = NULL; identifier(parser, &tmpNode); //weird - emitASTNodePrefixDecrement(nodeHandle, tmpNode->atomic.literal); + Toy_emitASTNodePrefixDecrement(nodeHandle, tmpNode->atomic.literal); - freeASTNode(tmpNode); + Toy_freeASTNode(tmpNode); - return OP_EOF; + return TOY_OP_EOF; } -static Opcode decrementInfix(Parser* parser, ASTNode** nodeHandle) { - ASTNode* tmpNode = NULL; +static Toy_Opcode decrementInfix(Toy_Parser* parser, Toy_ASTNode** nodeHandle) { + Toy_ASTNode* tmpNode = NULL; identifier(parser, &tmpNode); advance(parser); - emitASTNodePostfixDecrement(nodeHandle, tmpNode->atomic.literal); + Toy_emitASTNodePostfixDecrement(nodeHandle, tmpNode->atomic.literal); - freeASTNode(tmpNode); + Toy_freeASTNode(tmpNode); - return OP_EOF; + return TOY_OP_EOF; } -static Opcode fnCall(Parser* parser, ASTNode** nodeHandle) { +static Toy_Opcode fnCall(Toy_Parser* parser, Toy_ASTNode** nodeHandle) { advance(parser); //skip the left paren //binary() is an infix rule - so only get the RHS of the operator switch(parser->previous.type) { //arithmetic - case TOKEN_PAREN_LEFT: { - ASTNode* arguments = NULL; - emitASTNodeFnCollection(&arguments); + case TOY_TOKEN_PAREN_LEFT: { + Toy_ASTNode* arguments = NULL; + Toy_emitASTNodeFnCollection(&arguments); //if there's arguments - if (!match(parser, TOKEN_PAREN_RIGHT)) { + if (!match(parser, TOY_TOKEN_PAREN_RIGHT)) { //read each argument do { //emit the node to the argument list (grow the node if needed) if (arguments->fnCollection.capacity < arguments->fnCollection.count + 1) { int oldCapacity = arguments->fnCollection.capacity; - arguments->fnCollection.capacity = GROW_CAPACITY(oldCapacity); - arguments->fnCollection.nodes = GROW_ARRAY(ASTNode, arguments->fnCollection.nodes, oldCapacity, arguments->fnCollection.capacity); + arguments->fnCollection.capacity = TOY_GROW_CAPACITY(oldCapacity); + arguments->fnCollection.nodes = TOY_GROW_ARRAY(Toy_ASTNode, arguments->fnCollection.nodes, oldCapacity, arguments->fnCollection.capacity); } - ASTNode* tmpNode = NULL; + Toy_ASTNode* tmpNode = NULL; parsePrecedence(parser, &tmpNode, PREC_TERNARY); //BUGFIX if (!tmpNode) { error(parser, parser->previous, "[internal] No token found in fnCall"); - return OP_EOF; + return TOY_OP_EOF; } arguments->fnCollection.nodes[arguments->fnCollection.count++] = *tmpNode; - FREE(ASTNode, tmpNode); //simply free the tmpNode, so you don't free the children - } while(match(parser, TOKEN_COMMA)); + TOY_FREE(Toy_ASTNode, tmpNode); //simply free the tmpNode, so you don't free the children + } while(match(parser, TOY_TOKEN_COMMA)); - consume(parser, TOKEN_PAREN_RIGHT, "Expected ')' at end of argument list"); + consume(parser, TOY_TOKEN_PAREN_RIGHT, "Expected ')' at end of argument list"); } //emit the call - emitASTNodeFnCall(nodeHandle, arguments); + Toy_emitASTNodeFnCall(nodeHandle, arguments); - return OP_FN_CALL; + return TOY_OP_FN_CALL; } break; default: error(parser, parser->previous, "Unexpected token passed to function call precedence rule"); - return OP_EOF; + return TOY_OP_EOF; } - return OP_EOF; + return TOY_OP_EOF; } -static Opcode indexAccess(Parser* parser, ASTNode** nodeHandle) { //TODO: fix indexing signalling +static Toy_Opcode indexAccess(Toy_Parser* parser, Toy_ASTNode** nodeHandle) { //TODO: fix indexing signalling advance(parser); //val[first : second : third] - ASTNode* first = NULL; - ASTNode* second = NULL; - ASTNode* third = NULL; + Toy_ASTNode* first = NULL; + Toy_ASTNode* second = NULL; + Toy_ASTNode* third = NULL; //booleans indicate blank slice indexing - emitASTNodeLiteral(&first, TO_INDEX_BLANK_LITERAL); - emitASTNodeLiteral(&second, TO_INDEX_BLANK_LITERAL); - emitASTNodeLiteral(&third, TO_INDEX_BLANK_LITERAL); + Toy_emitASTNodeLiteral(&first, TOY_TO_INDEX_BLANK_LITERAL); + Toy_emitASTNodeLiteral(&second, TOY_TO_INDEX_BLANK_LITERAL); + Toy_emitASTNodeLiteral(&third, TOY_TO_INDEX_BLANK_LITERAL); bool readFirst = false; //pattern matching is bullcrap //eat the first - if (!match(parser, TOKEN_COLON)) { - freeASTNode(first); + if (!match(parser, TOY_TOKEN_COLON)) { + Toy_freeASTNode(first); parsePrecedence(parser, &first, PREC_TERNARY); - match(parser, TOKEN_COLON); + match(parser, TOY_TOKEN_COLON); readFirst = true; } - if (match(parser, TOKEN_BRACKET_RIGHT)) { + if (match(parser, TOY_TOKEN_BRACKET_RIGHT)) { if (readFirst) { - freeASTNode(second); + Toy_freeASTNode(second); second = NULL; } - freeASTNode(third); + Toy_freeASTNode(third); third = NULL; - emitASTNodeIndex(nodeHandle, first, second, third); - return OP_INDEX; + Toy_emitASTNodeIndex(nodeHandle, first, second, third); + return TOY_OP_INDEX; } //eat the second - if (!match(parser, TOKEN_COLON)) { - freeASTNode(second); + if (!match(parser, TOY_TOKEN_COLON)) { + Toy_freeASTNode(second); parsePrecedence(parser, &second, PREC_TERNARY); - match(parser, TOKEN_COLON); + match(parser, TOY_TOKEN_COLON); } - if (match(parser, TOKEN_BRACKET_RIGHT)) { - freeASTNode(third); + if (match(parser, TOY_TOKEN_BRACKET_RIGHT)) { + Toy_freeASTNode(third); third = NULL; - emitASTNodeIndex(nodeHandle, first, second, third); - return OP_INDEX; + Toy_emitASTNodeIndex(nodeHandle, first, second, third); + return TOY_OP_INDEX; } //eat the third - freeASTNode(third); + Toy_freeASTNode(third); parsePrecedence(parser, &third, PREC_TERNARY); - emitASTNodeIndex(nodeHandle, first, second, third); + Toy_emitASTNodeIndex(nodeHandle, first, second, third); - consume(parser, TOKEN_BRACKET_RIGHT, "Expected ']' in index notation"); + consume(parser, TOY_TOKEN_BRACKET_RIGHT, "Expected ']' in index notation"); - return OP_INDEX; + return TOY_OP_INDEX; } -static Opcode question(Parser* parser, ASTNode** nodeHandle) { +static Toy_Opcode question(Toy_Parser* parser, Toy_ASTNode** nodeHandle) { advance(parser); //for the question mark - ASTNode* thenPath = NULL; - ASTNode* elsePath = NULL; + Toy_ASTNode* thenPath = NULL; + Toy_ASTNode* elsePath = NULL; parsePrecedence(parser, &thenPath, PREC_TERNARY); - consume(parser, TOKEN_COLON, "Expected ':' in ternary expression"); + consume(parser, TOY_TOKEN_COLON, "Expected ':' in ternary expression"); parsePrecedence(parser, &elsePath, PREC_TERNARY); - emitASTNodeTernary(nodeHandle, NULL, thenPath, elsePath); + Toy_emitASTNodeTernary(nodeHandle, NULL, thenPath, elsePath); - return OP_TERNARY; + return TOY_OP_TERNARY; } -static Opcode dot(Parser* parser, ASTNode** nodeHandle) { +static Toy_Opcode dot(Toy_Parser* parser, Toy_ASTNode** nodeHandle) { advance(parser); //for the dot - ASTNode* tmpNode = NULL; + Toy_ASTNode* tmpNode = NULL; parsePrecedence(parser, &tmpNode, PREC_CALL); if (tmpNode == NULL || tmpNode->binary.right == NULL) { error(parser, parser->previous, "Expected function call after dot operator"); - return OP_EOF; + return TOY_OP_EOF; } (*nodeHandle) = tmpNode; - return OP_DOT; //signal that the function name and arguments are in the wrong order + return TOY_OP_DOT; //signal that the function name and arguments are in the wrong order } ParseRule parseRules[] = { //must match the token types @@ -907,24 +907,24 @@ ParseRule parseRules[] = { //must match the token types {NULL, NULL, PREC_NONE},// TOKEN_EOF, }; -ParseRule* getRule(TokenType type) { +ParseRule* getRule(Toy_TokenType type) { return &parseRules[type]; } //optimisation: constant folding -static bool calcStaticBinaryArithmetic(Parser* parser, ASTNode** nodeHandle) { +static bool calcStaticBinaryArithmetic(Toy_Parser* parser, Toy_ASTNode** nodeHandle) { switch((*nodeHandle)->binary.opcode) { - case OP_ADDITION: - case OP_SUBTRACTION: - case OP_MULTIPLICATION: - case OP_DIVISION: - case OP_MODULO: - case OP_COMPARE_EQUAL: - case OP_COMPARE_NOT_EQUAL: - case OP_COMPARE_LESS: - case OP_COMPARE_LESS_EQUAL: - case OP_COMPARE_GREATER: - case OP_COMPARE_GREATER_EQUAL: + case TOY_OP_ADDITION: + case TOY_OP_SUBTRACTION: + case TOY_OP_MULTIPLICATION: + case TOY_OP_DIVISION: + case TOY_OP_MODULO: + case TOY_OP_COMPARE_EQUAL: + case TOY_OP_COMPARE_NOT_EQUAL: + case TOY_OP_COMPARE_LESS: + case TOY_OP_COMPARE_LESS_EQUAL: + case TOY_OP_COMPARE_GREATER: + case TOY_OP_COMPARE_GREATER_EQUAL: break; default: @@ -932,86 +932,86 @@ static bool calcStaticBinaryArithmetic(Parser* parser, ASTNode** nodeHandle) { } //recurse to the left and right - if ((*nodeHandle)->binary.left->type == AST_NODE_BINARY) { + if ((*nodeHandle)->binary.left->type == TOY_AST_NODE_BINARY) { calcStaticBinaryArithmetic(parser, &(*nodeHandle)->binary.left); } - if ((*nodeHandle)->binary.right->type == AST_NODE_BINARY) { + if ((*nodeHandle)->binary.right->type == TOY_AST_NODE_BINARY) { calcStaticBinaryArithmetic(parser, &(*nodeHandle)->binary.right); } //make sure left and right are both literals - if (!((*nodeHandle)->binary.left->type == AST_NODE_LITERAL && (*nodeHandle)->binary.right->type == AST_NODE_LITERAL)) { + if (!((*nodeHandle)->binary.left->type == TOY_AST_NODE_LITERAL && (*nodeHandle)->binary.right->type == TOY_AST_NODE_LITERAL)) { return true; } //evaluate - Literal lhs = (*nodeHandle)->binary.left->atomic.literal; - Literal rhs = (*nodeHandle)->binary.right->atomic.literal; - Literal result = TO_NULL_LITERAL; + Toy_Literal lhs = (*nodeHandle)->binary.left->atomic.literal; + Toy_Literal rhs = (*nodeHandle)->binary.right->atomic.literal; + Toy_Literal result = TOY_TO_NULL_LITERAL; //type coersion - if (IS_FLOAT(lhs) && IS_INTEGER(rhs)) { - rhs = TO_FLOAT_LITERAL(AS_INTEGER(rhs)); + if (TOY_IS_FLOAT(lhs) && TOY_IS_INTEGER(rhs)) { + rhs = TOY_TO_FLOAT_LITERAL(TOY_AS_INTEGER(rhs)); } - if (IS_INTEGER(lhs) && IS_FLOAT(rhs)) { - lhs = TO_FLOAT_LITERAL(AS_INTEGER(lhs)); + if (TOY_IS_INTEGER(lhs) && TOY_IS_FLOAT(rhs)) { + lhs = TOY_TO_FLOAT_LITERAL(TOY_AS_INTEGER(lhs)); } //maths based on types - if(IS_INTEGER(lhs) && IS_INTEGER(rhs)) { + if(TOY_IS_INTEGER(lhs) && TOY_IS_INTEGER(rhs)) { switch((*nodeHandle)->binary.opcode) { - case OP_ADDITION: - result = TO_INTEGER_LITERAL( AS_INTEGER(lhs) + AS_INTEGER(rhs) ); + case TOY_OP_ADDITION: + result = TOY_TO_INTEGER_LITERAL( TOY_AS_INTEGER(lhs) + TOY_AS_INTEGER(rhs) ); break; - case OP_SUBTRACTION: - result = TO_INTEGER_LITERAL( AS_INTEGER(lhs) - AS_INTEGER(rhs) ); + case TOY_OP_SUBTRACTION: + result = TOY_TO_INTEGER_LITERAL( TOY_AS_INTEGER(lhs) - TOY_AS_INTEGER(rhs) ); break; - case OP_MULTIPLICATION: - result = TO_INTEGER_LITERAL( AS_INTEGER(lhs) * AS_INTEGER(rhs) ); + case TOY_OP_MULTIPLICATION: + result = TOY_TO_INTEGER_LITERAL( TOY_AS_INTEGER(lhs) * TOY_AS_INTEGER(rhs) ); break; - case OP_DIVISION: - if (AS_INTEGER(rhs) == 0) { + case TOY_OP_DIVISION: + if (TOY_AS_INTEGER(rhs) == 0) { error(parser, parser->previous, "Can't divide by zero (error found in constant folding)"); return false; } - result = TO_INTEGER_LITERAL( AS_INTEGER(lhs) / AS_INTEGER(rhs) ); + result = TOY_TO_INTEGER_LITERAL( TOY_AS_INTEGER(lhs) / TOY_AS_INTEGER(rhs) ); break; - case OP_MODULO: - if (AS_INTEGER(rhs) == 0) { + case TOY_OP_MODULO: + if (TOY_AS_INTEGER(rhs) == 0) { error(parser, parser->previous, "Can't modulo by zero (error found in constant folding)"); return false; } - result = TO_INTEGER_LITERAL( AS_INTEGER(lhs) % AS_INTEGER(rhs) ); + result = TOY_TO_INTEGER_LITERAL( TOY_AS_INTEGER(lhs) % TOY_AS_INTEGER(rhs) ); break; - case OP_COMPARE_EQUAL: - result = TO_BOOLEAN_LITERAL( AS_INTEGER(lhs) == AS_INTEGER(rhs) ); + case TOY_OP_COMPARE_EQUAL: + result = TOY_TO_BOOLEAN_LITERAL( TOY_AS_INTEGER(lhs) == TOY_AS_INTEGER(rhs) ); break; - case OP_COMPARE_NOT_EQUAL: - result = TO_BOOLEAN_LITERAL( AS_INTEGER(lhs) != AS_INTEGER(rhs) ); + case TOY_OP_COMPARE_NOT_EQUAL: + result = TOY_TO_BOOLEAN_LITERAL( TOY_AS_INTEGER(lhs) != TOY_AS_INTEGER(rhs) ); break; - case OP_COMPARE_LESS: - result = TO_BOOLEAN_LITERAL( AS_INTEGER(lhs) < AS_INTEGER(rhs) ); + case TOY_OP_COMPARE_LESS: + result = TOY_TO_BOOLEAN_LITERAL( TOY_AS_INTEGER(lhs) < TOY_AS_INTEGER(rhs) ); break; - case OP_COMPARE_LESS_EQUAL: - result = TO_BOOLEAN_LITERAL( AS_INTEGER(lhs) <= AS_INTEGER(rhs) ); + case TOY_OP_COMPARE_LESS_EQUAL: + result = TOY_TO_BOOLEAN_LITERAL( TOY_AS_INTEGER(lhs) <= TOY_AS_INTEGER(rhs) ); break; - case OP_COMPARE_GREATER: - result = TO_BOOLEAN_LITERAL( AS_INTEGER(lhs) > AS_INTEGER(rhs) ); + case TOY_OP_COMPARE_GREATER: + result = TOY_TO_BOOLEAN_LITERAL( TOY_AS_INTEGER(lhs) > TOY_AS_INTEGER(rhs) ); break; - case OP_COMPARE_GREATER_EQUAL: - result = TO_BOOLEAN_LITERAL( AS_INTEGER(lhs) >= AS_INTEGER(rhs) ); + case TOY_OP_COMPARE_GREATER_EQUAL: + result = TOY_TO_BOOLEAN_LITERAL( TOY_AS_INTEGER(lhs) >= TOY_AS_INTEGER(rhs) ); break; default: @@ -1021,55 +1021,55 @@ static bool calcStaticBinaryArithmetic(Parser* parser, ASTNode** nodeHandle) { } //catch bad modulo - if ((IS_FLOAT(lhs) || IS_FLOAT(rhs)) && (*nodeHandle)->binary.opcode == OP_MODULO) { + if ((TOY_IS_FLOAT(lhs) || TOY_IS_FLOAT(rhs)) && (*nodeHandle)->binary.opcode == TOY_OP_MODULO) { error(parser, parser->previous, "Bad arithmetic argument (modulo on floats not allowed)"); return false; } - if(IS_FLOAT(lhs) && IS_FLOAT(rhs)) { + if(TOY_IS_FLOAT(lhs) && TOY_IS_FLOAT(rhs)) { switch((*nodeHandle)->binary.opcode) { - case OP_ADDITION: - result = TO_FLOAT_LITERAL( AS_FLOAT(lhs) + AS_FLOAT(rhs) ); + case TOY_OP_ADDITION: + result = TOY_TO_FLOAT_LITERAL( TOY_AS_FLOAT(lhs) + TOY_AS_FLOAT(rhs) ); break; - case OP_SUBTRACTION: - result = TO_FLOAT_LITERAL( AS_FLOAT(lhs) - AS_FLOAT(rhs) ); + case TOY_OP_SUBTRACTION: + result = TOY_TO_FLOAT_LITERAL( TOY_AS_FLOAT(lhs) - TOY_AS_FLOAT(rhs) ); break; - case OP_MULTIPLICATION: - result = TO_FLOAT_LITERAL( AS_FLOAT(lhs) * AS_FLOAT(rhs) ); + case TOY_OP_MULTIPLICATION: + result = TOY_TO_FLOAT_LITERAL( TOY_AS_FLOAT(lhs) * TOY_AS_FLOAT(rhs) ); break; - case OP_DIVISION: - if (AS_FLOAT(rhs) == 0) { + case TOY_OP_DIVISION: + if (TOY_AS_FLOAT(rhs) == 0) { error(parser, parser->previous, "Can't divide by zero (error found in constant folding)"); return false; } - result = TO_FLOAT_LITERAL( AS_FLOAT(lhs) / AS_FLOAT(rhs) ); + result = TOY_TO_FLOAT_LITERAL( TOY_AS_FLOAT(lhs) / TOY_AS_FLOAT(rhs) ); break; - case OP_COMPARE_EQUAL: - result = TO_BOOLEAN_LITERAL( AS_FLOAT(lhs) == AS_FLOAT(rhs) ); + case TOY_OP_COMPARE_EQUAL: + result = TOY_TO_BOOLEAN_LITERAL( TOY_AS_FLOAT(lhs) == TOY_AS_FLOAT(rhs) ); break; - case OP_COMPARE_NOT_EQUAL: - result = TO_BOOLEAN_LITERAL( AS_FLOAT(lhs) != AS_FLOAT(rhs) ); + case TOY_OP_COMPARE_NOT_EQUAL: + result = TOY_TO_BOOLEAN_LITERAL( TOY_AS_FLOAT(lhs) != TOY_AS_FLOAT(rhs) ); break; - case OP_COMPARE_LESS: - result = TO_BOOLEAN_LITERAL( AS_FLOAT(lhs) < AS_FLOAT(rhs) ); + case TOY_OP_COMPARE_LESS: + result = TOY_TO_BOOLEAN_LITERAL( TOY_AS_FLOAT(lhs) < TOY_AS_FLOAT(rhs) ); break; - case OP_COMPARE_LESS_EQUAL: - result = TO_BOOLEAN_LITERAL( AS_FLOAT(lhs) <= AS_FLOAT(rhs) ); + case TOY_OP_COMPARE_LESS_EQUAL: + result = TOY_TO_BOOLEAN_LITERAL( TOY_AS_FLOAT(lhs) <= TOY_AS_FLOAT(rhs) ); break; - case OP_COMPARE_GREATER: - result = TO_BOOLEAN_LITERAL( AS_FLOAT(lhs) > AS_FLOAT(rhs) ); + case TOY_OP_COMPARE_GREATER: + result = TOY_TO_BOOLEAN_LITERAL( TOY_AS_FLOAT(lhs) > TOY_AS_FLOAT(rhs) ); break; - case OP_COMPARE_GREATER_EQUAL: - result = TO_BOOLEAN_LITERAL( AS_FLOAT(lhs) >= AS_FLOAT(rhs) ); + case TOY_OP_COMPARE_GREATER_EQUAL: + result = TOY_TO_BOOLEAN_LITERAL( TOY_AS_FLOAT(lhs) >= TOY_AS_FLOAT(rhs) ); break; default: @@ -1079,25 +1079,25 @@ static bool calcStaticBinaryArithmetic(Parser* parser, ASTNode** nodeHandle) { } //nothing can be done to optimize - if (IS_NULL(result)) { + if (TOY_IS_NULL(result)) { return true; } //optimize by converting this node into a literal node - freeASTNode((*nodeHandle)->binary.left); - freeASTNode((*nodeHandle)->binary.right); + Toy_freeASTNode((*nodeHandle)->binary.left); + Toy_freeASTNode((*nodeHandle)->binary.right); - (*nodeHandle)->type = AST_NODE_LITERAL; + (*nodeHandle)->type = TOY_AST_NODE_LITERAL; (*nodeHandle)->atomic.literal = result; return true; } -static void dottify(Parser* parser, ASTNode** nodeHandle) { //TODO: remove dot from the compiler entirely +static void dottify(Toy_Parser* parser, Toy_ASTNode** nodeHandle) { //TODO: remove dot from the compiler entirely //only if this is chained from a higher binary "fn call" - if ((*nodeHandle)->type == AST_NODE_BINARY) { - if ((*nodeHandle)->binary.opcode == OP_FN_CALL) { - (*nodeHandle)->binary.opcode = OP_DOT; + if ((*nodeHandle)->type == TOY_AST_NODE_BINARY) { + if ((*nodeHandle)->binary.opcode == TOY_OP_FN_CALL) { + (*nodeHandle)->binary.opcode = TOY_OP_DOT; (*nodeHandle)->binary.right->fnCall.argumentCount++; } dottify(parser, &(*nodeHandle)->binary.left); @@ -1105,7 +1105,7 @@ static void dottify(Parser* parser, ASTNode** nodeHandle) { //TODO: remove dot f } } -static void parsePrecedence(Parser* parser, ASTNode** nodeHandle, PrecedenceRule rule) { +static void parsePrecedence(Toy_Parser* parser, Toy_ASTNode** nodeHandle, PrecedenceRule rule) { //every valid expression has a prefix rule advance(parser); ParseFn prefixRule = getRule(parser->previous.type)->prefix; @@ -1129,28 +1129,28 @@ static void parsePrecedence(Parser* parser, ASTNode** nodeHandle, PrecedenceRule return; } - ASTNode* rhsNode = NULL; - const Opcode opcode = infixRule(parser, &rhsNode); //NOTE: infix rule must advance the parser + Toy_ASTNode* rhsNode = NULL; + const Toy_Opcode opcode = infixRule(parser, &rhsNode); //NOTE: infix rule must advance the parser - if (opcode == OP_EOF) { - freeASTNode(*nodeHandle); + if (opcode == TOY_OP_EOF) { + Toy_freeASTNode(*nodeHandle); *nodeHandle = rhsNode; return; //we're done here } //BUGFIX: dot-chaining - if (opcode == OP_DOT) { + if (opcode == TOY_OP_DOT) { dottify(parser, &rhsNode); } //BUGFIX: ternary shorthand - if (opcode == OP_TERNARY) { + if (opcode == TOY_OP_TERNARY) { rhsNode->ternary.condition = *nodeHandle; *nodeHandle = rhsNode; continue; } - emitASTNodeBinary(nodeHandle, rhsNode, opcode); + Toy_emitASTNodeBinary(nodeHandle, rhsNode, opcode); //optimise away the constants if (!calcStaticBinaryArithmetic(parser, nodeHandle)) { @@ -1159,32 +1159,32 @@ static void parsePrecedence(Parser* parser, ASTNode** nodeHandle, PrecedenceRule } //if your precedence is below "assignment" - if (canBeAssigned && match(parser, TOKEN_ASSIGN)) { + if (canBeAssigned && match(parser, TOY_TOKEN_ASSIGN)) { error(parser, parser->current, "Invalid assignment target"); } } //expressions -static void expression(Parser* parser, ASTNode** nodeHandle) { +static void expression(Toy_Parser* parser, Toy_ASTNode** nodeHandle) { //delegate to the pratt table for expression precedence parsePrecedence(parser, nodeHandle, PREC_ASSIGNMENT); } //statements -static void blockStmt(Parser* parser, ASTNode** nodeHandle) { +static void blockStmt(Toy_Parser* parser, Toy_ASTNode** nodeHandle) { //init - emitASTNodeBlock(nodeHandle); + Toy_emitASTNodeBlock(nodeHandle); //sub-scope, compile it and push it up in a node - while (!match(parser, TOKEN_BRACE_RIGHT)) { + while (!match(parser, TOY_TOKEN_BRACE_RIGHT)) { if ((*nodeHandle)->block.capacity < (*nodeHandle)->block.count + 1) { int oldCapacity = (*nodeHandle)->block.capacity; - (*nodeHandle)->block.capacity = GROW_CAPACITY(oldCapacity); - (*nodeHandle)->block.nodes = GROW_ARRAY(ASTNode, (*nodeHandle)->block.nodes, oldCapacity, (*nodeHandle)->block.capacity); + (*nodeHandle)->block.capacity = TOY_GROW_CAPACITY(oldCapacity); + (*nodeHandle)->block.nodes = TOY_GROW_ARRAY(Toy_ASTNode, (*nodeHandle)->block.nodes, oldCapacity, (*nodeHandle)->block.capacity); } - ASTNode* tmpNode = NULL; + Toy_ASTNode* tmpNode = NULL; //process the grammar rule for this line declaration(parser, &tmpNode); @@ -1196,118 +1196,118 @@ static void blockStmt(Parser* parser, ASTNode** nodeHandle) { //BUGFIX: statements no longer require the existing node ((*nodeHandle)->block.nodes[(*nodeHandle)->block.count++]) = *tmpNode; - FREE(ASTNode, tmpNode); //simply free the tmpNode, so you don't free the children + TOY_FREE(Toy_ASTNode, tmpNode); //simply free the tmpNode, so you don't free the children } } -static void printStmt(Parser* parser, ASTNode** nodeHandle) { +static void printStmt(Toy_Parser* parser, Toy_ASTNode** nodeHandle) { //set the node info - ASTNode* node = NULL; + Toy_ASTNode* node = NULL; expression(parser, &node); - emitASTNodeUnary(nodeHandle, OP_PRINT, node); + Toy_emitASTNodeUnary(nodeHandle, TOY_OP_PRINT, node); - consume(parser, TOKEN_SEMICOLON, "Expected ';' at end of print statement"); + consume(parser, TOY_TOKEN_SEMICOLON, "Expected ';' at end of print statement"); } -static void assertStmt(Parser* parser, ASTNode** nodeHandle) { +static void assertStmt(Toy_Parser* parser, Toy_ASTNode** nodeHandle) { //set the node info - (*nodeHandle) = ALLOCATE(ASTNode, 1); //special case, because I'm lazy - (*nodeHandle)->type = AST_NODE_BINARY; - (*nodeHandle)->binary.opcode = OP_ASSERT; + (*nodeHandle) = TOY_ALLOCATE(Toy_ASTNode, 1); //special case, because I'm lazy + (*nodeHandle)->type = TOY_AST_NODE_BINARY; + (*nodeHandle)->binary.opcode = TOY_OP_ASSERT; parsePrecedence(parser, &((*nodeHandle)->binary.left), PREC_TERNARY); - consume(parser, TOKEN_COMMA, "Expected ',' in assert statement"); + consume(parser, TOY_TOKEN_COMMA, "Expected ',' in assert statement"); parsePrecedence(parser, &((*nodeHandle)->binary.right), PREC_TERNARY); - consume(parser, TOKEN_SEMICOLON, "Expected ';' at end of assert statement"); + consume(parser, TOY_TOKEN_SEMICOLON, "Expected ';' at end of assert statement"); } -static void ifStmt(Parser* parser, ASTNode** nodeHandle) { - ASTNode* condition = NULL; - ASTNode* thenPath = NULL; - ASTNode* elsePath = NULL; +static void ifStmt(Toy_Parser* parser, Toy_ASTNode** nodeHandle) { + Toy_ASTNode* condition = NULL; + Toy_ASTNode* thenPath = NULL; + Toy_ASTNode* elsePath = NULL; //read the condition - consume(parser, TOKEN_PAREN_LEFT, "Expected '(' at beginning of if clause"); + consume(parser, TOY_TOKEN_PAREN_LEFT, "Expected '(' at beginning of if clause"); parsePrecedence(parser, &condition, PREC_TERNARY); //read the then path - consume(parser, TOKEN_PAREN_RIGHT, "Expected ')' at end of if clause"); + consume(parser, TOY_TOKEN_PAREN_RIGHT, "Expected ')' at end of if clause"); declaration(parser, &thenPath); //read the optional else path - if (match(parser, TOKEN_ELSE)) { + if (match(parser, TOY_TOKEN_ELSE)) { declaration(parser, &elsePath); } - emitASTNodeIf(nodeHandle, condition, thenPath, elsePath); + Toy_emitASTNodeIf(nodeHandle, condition, thenPath, elsePath); } -static void whileStmt(Parser* parser, ASTNode** nodeHandle) { - ASTNode* condition = NULL; - ASTNode* thenPath = NULL; +static void whileStmt(Toy_Parser* parser, Toy_ASTNode** nodeHandle) { + Toy_ASTNode* condition = NULL; + Toy_ASTNode* thenPath = NULL; //read the condition - consume(parser, TOKEN_PAREN_LEFT, "Expected '(' at beginning of while clause"); + consume(parser, TOY_TOKEN_PAREN_LEFT, "Expected '(' at beginning of while clause"); parsePrecedence(parser, &condition, PREC_TERNARY); //read the then path - consume(parser, TOKEN_PAREN_RIGHT, "Expected ')' at end of while clause"); + consume(parser, TOY_TOKEN_PAREN_RIGHT, "Expected ')' at end of while clause"); declaration(parser, &thenPath); - emitASTNodeWhile(nodeHandle, condition, thenPath); + Toy_emitASTNodeWhile(nodeHandle, condition, thenPath); } -static void forStmt(Parser* parser, ASTNode** nodeHandle) { - ASTNode* preClause = NULL; - ASTNode* condition = NULL; - ASTNode* postClause = NULL; - ASTNode* thenPath = NULL; +static void forStmt(Toy_Parser* parser, Toy_ASTNode** nodeHandle) { + Toy_ASTNode* preClause = NULL; + Toy_ASTNode* condition = NULL; + Toy_ASTNode* postClause = NULL; + Toy_ASTNode* thenPath = NULL; //read the clauses - consume(parser, TOKEN_PAREN_LEFT, "Expected '(' at beginning of for clause"); + consume(parser, TOY_TOKEN_PAREN_LEFT, "Expected '(' at beginning of for clause"); declaration(parser, &preClause); //allow defining variables in the pre-clause parsePrecedence(parser, &condition, PREC_TERNARY); - consume(parser, TOKEN_SEMICOLON, "Expected ';' after condition of for clause"); + consume(parser, TOY_TOKEN_SEMICOLON, "Expected ';' after condition of for clause"); parsePrecedence(parser, &postClause, PREC_ASSIGNMENT); - consume(parser, TOKEN_PAREN_RIGHT, "Expected ')' at end of for clause"); + consume(parser, TOY_TOKEN_PAREN_RIGHT, "Expected ')' at end of for clause"); //read the path declaration(parser, &thenPath); - emitASTNodeFor(nodeHandle, preClause, condition, postClause, thenPath); + Toy_emitASTNodeFor(nodeHandle, preClause, condition, postClause, thenPath); } -static void breakStmt(Parser* parser, ASTNode** nodeHandle) { - emitASTNodeBreak(nodeHandle); +static void breakStmt(Toy_Parser* parser, Toy_ASTNode** nodeHandle) { + Toy_emitASTNodeBreak(nodeHandle); - consume(parser, TOKEN_SEMICOLON, "Expected ';' at end of break statement"); + consume(parser, TOY_TOKEN_SEMICOLON, "Expected ';' at end of break statement"); } -static void continueStmt(Parser* parser, ASTNode** nodeHandle) { - emitASTNodeContinue(nodeHandle); +static void continueStmt(Toy_Parser* parser, Toy_ASTNode** nodeHandle) { + Toy_emitASTNodeContinue(nodeHandle); - consume(parser, TOKEN_SEMICOLON, "Expected ';' at end of continue statement"); + consume(parser, TOY_TOKEN_SEMICOLON, "Expected ';' at end of continue statement"); } -static void returnStmt(Parser* parser, ASTNode** nodeHandle) { - ASTNode* returnValues = NULL; - emitASTNodeFnCollection(&returnValues); +static void returnStmt(Toy_Parser* parser, Toy_ASTNode** nodeHandle) { + Toy_ASTNode* returnValues = NULL; + Toy_emitASTNodeFnCollection(&returnValues); - if (!match(parser, TOKEN_SEMICOLON)) { + if (!match(parser, TOY_TOKEN_SEMICOLON)) { do { //loop for multiple returns (disabled later in the pipeline) //append the node to the return list (grow the node if needed) if (returnValues->fnCollection.capacity < returnValues->fnCollection.count + 1) { int oldCapacity = returnValues->fnCollection.capacity; - returnValues->fnCollection.capacity = GROW_CAPACITY(oldCapacity); - returnValues->fnCollection.nodes = GROW_ARRAY(ASTNode, returnValues->fnCollection.nodes, oldCapacity, returnValues->fnCollection.capacity); + returnValues->fnCollection.capacity = TOY_GROW_CAPACITY(oldCapacity); + returnValues->fnCollection.nodes = TOY_GROW_ARRAY(Toy_ASTNode, returnValues->fnCollection.nodes, oldCapacity, returnValues->fnCollection.capacity); } - ASTNode* node = NULL; + Toy_ASTNode* node = NULL; parsePrecedence(parser, &node, PREC_TERNARY); //BUGFIX @@ -1317,18 +1317,18 @@ static void returnStmt(Parser* parser, ASTNode** nodeHandle) { } returnValues->fnCollection.nodes[returnValues->fnCollection.count++] = *node; - FREE(ASTNode, node); //free manually - } while(match(parser, TOKEN_COMMA)); + TOY_FREE(Toy_ASTNode, node); //free manually + } while(match(parser, TOY_TOKEN_COMMA)); - consume(parser, TOKEN_SEMICOLON, "Expected ';' at end of return statement"); + consume(parser, TOY_TOKEN_SEMICOLON, "Expected ';' at end of return statement"); } - emitASTNodeFnReturn(nodeHandle, returnValues); + Toy_emitASTNodeFnReturn(nodeHandle, returnValues); } -static void importStmt(Parser* parser, ASTNode** nodeHandle) { +static void importStmt(Toy_Parser* parser, Toy_ASTNode** nodeHandle) { //read the identifier - ASTNode* node = NULL; + Toy_ASTNode* node = NULL; advance(parser); identifier(parser, &node); @@ -1336,102 +1336,102 @@ static void importStmt(Parser* parser, ASTNode** nodeHandle) { return; } - Literal idn = copyLiteral(node->atomic.literal); - freeASTNode(node); + Toy_Literal idn = Toy_copyLiteral(node->atomic.literal); + Toy_freeASTNode(node); - Literal alias = TO_NULL_LITERAL; + Toy_Literal alias = TOY_TO_NULL_LITERAL; - if (match(parser, TOKEN_AS)) { - ASTNode* node = NULL; + if (match(parser, TOY_TOKEN_AS)) { + Toy_ASTNode* node = NULL; advance(parser); identifier(parser, &node); - alias = copyLiteral(node->atomic.literal); - freeASTNode(node); + alias = Toy_copyLiteral(node->atomic.literal); + Toy_freeASTNode(node); } - emitASTNodeImport(nodeHandle, idn, alias); + Toy_emitASTNodeImport(nodeHandle, idn, alias); - consume(parser, TOKEN_SEMICOLON, "Expected ';' at end of import statement"); + consume(parser, TOY_TOKEN_SEMICOLON, "Expected ';' at end of import statement"); - freeLiteral(idn); - freeLiteral(alias); + Toy_freeLiteral(idn); + Toy_freeLiteral(alias); } //precedence functions -static void expressionStmt(Parser* parser, ASTNode** nodeHandle) { +static void expressionStmt(Toy_Parser* parser, Toy_ASTNode** nodeHandle) { //BUGFIX: check for empty statements - if (match(parser, TOKEN_SEMICOLON)) { - emitASTNodeLiteral(nodeHandle, TO_NULL_LITERAL); + if (match(parser, TOY_TOKEN_SEMICOLON)) { + Toy_emitASTNodeLiteral(nodeHandle, TOY_TO_NULL_LITERAL); return; } - ASTNode* ptr = NULL; + Toy_ASTNode* ptr = NULL; expression(parser, &ptr); if (ptr != NULL) { *nodeHandle = ptr; } - consume(parser, TOKEN_SEMICOLON, "Expected ';' at the end of expression statement"); + consume(parser, TOY_TOKEN_SEMICOLON, "Expected ';' at the end of expression statement"); } -static void statement(Parser* parser, ASTNode** nodeHandle) { +static void statement(Toy_Parser* parser, Toy_ASTNode** nodeHandle) { //block - if (match(parser, TOKEN_BRACE_LEFT)) { + if (match(parser, TOY_TOKEN_BRACE_LEFT)) { blockStmt(parser, nodeHandle); return; } //print - if (match(parser, TOKEN_PRINT)) { + if (match(parser, TOY_TOKEN_PRINT)) { printStmt(parser, nodeHandle); return; } //assert - if (match(parser, TOKEN_ASSERT)) { + if (match(parser, TOY_TOKEN_ASSERT)) { assertStmt(parser, nodeHandle); return; } //if-then-else - if (match(parser, TOKEN_IF)) { + if (match(parser, TOY_TOKEN_IF)) { ifStmt(parser, nodeHandle); return; } //while-then - if (match(parser, TOKEN_WHILE)) { + if (match(parser, TOY_TOKEN_WHILE)) { whileStmt(parser, nodeHandle); return; } //for-pre-clause-post-then - if (match(parser, TOKEN_FOR)) { + if (match(parser, TOY_TOKEN_FOR)) { forStmt(parser, nodeHandle); return; } //break - if (match(parser, TOKEN_BREAK)) { + if (match(parser, TOY_TOKEN_BREAK)) { breakStmt(parser, nodeHandle); return; } //continue - if (match(parser, TOKEN_CONTINUE)) { + if (match(parser, TOY_TOKEN_CONTINUE)) { continueStmt(parser, nodeHandle); return; } //return - if (match(parser, TOKEN_RETURN)) { + if (match(parser, TOY_TOKEN_RETURN)) { returnStmt(parser, nodeHandle); return; } //import - if (match(parser, TOKEN_IMPORT)) { + if (match(parser, TOY_TOKEN_IMPORT)) { importStmt(parser, nodeHandle); return; } @@ -1441,102 +1441,102 @@ static void statement(Parser* parser, ASTNode** nodeHandle) { } //declarations and definitions -static Literal readTypeToLiteral(Parser* parser) { +static Toy_Literal readTypeToLiteral(Toy_Parser* parser) { advance(parser); - Literal literal = TO_TYPE_LITERAL(LITERAL_NULL, false); + Toy_Literal literal = TOY_TO_TYPE_LITERAL(TOY_LITERAL_NULL, false); switch(parser->previous.type) { - case TOKEN_NULL: + case TOY_TOKEN_NULL: //NO-OP break; - case TOKEN_BOOLEAN: - AS_TYPE(literal).typeOf = LITERAL_BOOLEAN; + case TOY_TOKEN_BOOLEAN: + TOY_AS_TYPE(literal).typeOf = TOY_LITERAL_BOOLEAN; break; - case TOKEN_INTEGER: - AS_TYPE(literal).typeOf = LITERAL_INTEGER; + case TOY_TOKEN_INTEGER: + TOY_AS_TYPE(literal).typeOf = TOY_LITERAL_INTEGER; break; - case TOKEN_FLOAT: - AS_TYPE(literal).typeOf = LITERAL_FLOAT; + case TOY_TOKEN_FLOAT: + TOY_AS_TYPE(literal).typeOf = TOY_LITERAL_FLOAT; break; - case TOKEN_STRING: - AS_TYPE(literal).typeOf = LITERAL_STRING; + case TOY_TOKEN_STRING: + TOY_AS_TYPE(literal).typeOf = TOY_LITERAL_STRING; break; //array, dictionary - read the sub-types - case TOKEN_BRACKET_LEFT: { - Literal l = readTypeToLiteral(parser); + case TOY_TOKEN_BRACKET_LEFT: { + Toy_Literal l = readTypeToLiteral(parser); - if (match(parser, TOKEN_COLON)) { - Literal r = readTypeToLiteral(parser); + if (match(parser, TOY_TOKEN_COLON)) { + Toy_Literal r = readTypeToLiteral(parser); - TYPE_PUSH_SUBTYPE(&literal, l); - TYPE_PUSH_SUBTYPE(&literal, r); + TOY_TYPE_PUSH_SUBTYPE(&literal, l); + TOY_TYPE_PUSH_SUBTYPE(&literal, r); - AS_TYPE(literal).typeOf = LITERAL_DICTIONARY; + TOY_AS_TYPE(literal).typeOf = TOY_LITERAL_DICTIONARY; } else { - TYPE_PUSH_SUBTYPE(&literal, l); + TOY_TYPE_PUSH_SUBTYPE(&literal, l); - AS_TYPE(literal).typeOf = LITERAL_ARRAY; + TOY_AS_TYPE(literal).typeOf = TOY_LITERAL_ARRAY; } - consume(parser, TOKEN_BRACKET_RIGHT, "Expected ']' at end of type definition"); + consume(parser, TOY_TOKEN_BRACKET_RIGHT, "Expected ']' at end of type definition"); } break; - case TOKEN_FUNCTION: - AS_TYPE(literal).typeOf = LITERAL_FUNCTION; + case TOY_TOKEN_FUNCTION: + TOY_AS_TYPE(literal).typeOf = TOY_LITERAL_FUNCTION; break; - case TOKEN_OPAQUE: - AS_TYPE(literal).typeOf = LITERAL_OPAQUE; + case TOY_TOKEN_OPAQUE: + TOY_AS_TYPE(literal).typeOf = TOY_LITERAL_OPAQUE; break; - case TOKEN_ANY: - AS_TYPE(literal).typeOf = LITERAL_ANY; + case TOY_TOKEN_ANY: + TOY_AS_TYPE(literal).typeOf = TOY_LITERAL_ANY; break; //wtf - case TOKEN_IDENTIFIER: { + case TOY_TOKEN_IDENTIFIER: { //duplicated from identifier() - Token identifierToken = parser->previous; + Toy_Token identifierToken = parser->previous; int length = identifierToken.length; //for safety if (length > 256) { length = 256; error(parser, parser->previous, "Identifiers can only be a maximum of 256 characters long"); } - literal = TO_IDENTIFIER_LITERAL(createRefStringLength(identifierToken.lexeme, length)); + literal = TOY_TO_IDENTIFIER_LITERAL(Toy_createRefStringLength(identifierToken.lexeme, length)); } break; //WTF - case TOKEN_TYPE: - AS_TYPE(literal).typeOf = LITERAL_TYPE; + case TOY_TOKEN_TYPE: + TOY_AS_TYPE(literal).typeOf = TOY_LITERAL_TYPE; break; default: error(parser, parser->previous, "Bad type signature"); - return TO_NULL_LITERAL; + return TOY_TO_NULL_LITERAL; } //const follows the type - if (match(parser, TOKEN_CONST)) { - AS_TYPE(literal).constant = true; + if (match(parser, TOY_TOKEN_CONST)) { + TOY_AS_TYPE(literal).constant = true; } return literal; } -static void varDecl(Parser* parser, ASTNode** nodeHandle) { +static void varDecl(Toy_Parser* parser, Toy_ASTNode** nodeHandle) { //read the identifier - consume(parser, TOKEN_IDENTIFIER, "Expected identifier after var keyword"); - Token identifierToken = parser->previous; + consume(parser, TOY_TOKEN_IDENTIFIER, "Expected identifier after var keyword"); + Toy_Token identifierToken = parser->previous; int length = identifierToken.length; @@ -1546,40 +1546,40 @@ static void varDecl(Parser* parser, ASTNode** nodeHandle) { error(parser, parser->previous, "Identifiers can only be a maximum of 256 characters long"); } - Literal identifier = TO_IDENTIFIER_LITERAL(createRefStringLength(identifierToken.lexeme, length)); + Toy_Literal identifier = TOY_TO_IDENTIFIER_LITERAL(Toy_createRefStringLength(identifierToken.lexeme, length)); //read the type, if present - Literal typeLiteral; - if (match(parser, TOKEN_COLON)) { + Toy_Literal typeLiteral; + if (match(parser, TOY_TOKEN_COLON)) { typeLiteral = readTypeToLiteral(parser); } else { //default to non-const any - typeLiteral = TO_TYPE_LITERAL(LITERAL_ANY, false); + typeLiteral = TOY_TO_TYPE_LITERAL(TOY_LITERAL_ANY, false); } //variable definition is an expression - ASTNode* expressionNode = NULL; - if (match(parser, TOKEN_ASSIGN)) { + Toy_ASTNode* expressionNode = NULL; + if (match(parser, TOY_TOKEN_ASSIGN)) { expression(parser, &expressionNode); } else { //values are null by default - emitASTNodeLiteral(&expressionNode, TO_NULL_LITERAL); + Toy_emitASTNodeLiteral(&expressionNode, TOY_TO_NULL_LITERAL); } //TODO: static type checking? //declare it - emitASTNodeVarDecl(nodeHandle, identifier, typeLiteral, expressionNode); + Toy_emitASTNodeVarDecl(nodeHandle, identifier, typeLiteral, expressionNode); - consume(parser, TOKEN_SEMICOLON, "Expected ';' at end of var declaration"); + consume(parser, TOY_TOKEN_SEMICOLON, "Expected ';' at end of var declaration"); } -static void fnDecl(Parser* parser, ASTNode** nodeHandle) { +static void fnDecl(Toy_Parser* parser, Toy_ASTNode** nodeHandle) { //read the identifier - consume(parser, TOKEN_IDENTIFIER, "Expected identifier after fn keyword"); - Token identifierToken = parser->previous; + consume(parser, TOY_TOKEN_IDENTIFIER, "Expected identifier after fn keyword"); + Toy_Token identifierToken = parser->previous; int length = identifierToken.length; @@ -1589,23 +1589,23 @@ static void fnDecl(Parser* parser, ASTNode** nodeHandle) { error(parser, parser->previous, "Identifiers can only be a maximum of 256 characters long"); } - Literal identifier = TO_IDENTIFIER_LITERAL(createRefStringLength(identifierToken.lexeme, length)); + Toy_Literal identifier = TOY_TO_IDENTIFIER_LITERAL(Toy_createRefStringLength(identifierToken.lexeme, length)); //read the parameters and arity - consume(parser, TOKEN_PAREN_LEFT, "Expected '(' after function identifier"); + consume(parser, TOY_TOKEN_PAREN_LEFT, "Expected '(' after function identifier"); //for holding the array of arguments - ASTNode* argumentNode = NULL; - emitASTNodeFnCollection(&argumentNode); + Toy_ASTNode* argumentNode = NULL; + Toy_emitASTNodeFnCollection(&argumentNode); //read args - if (!match(parser, TOKEN_PAREN_RIGHT)) { + if (!match(parser, TOY_TOKEN_PAREN_RIGHT)) { do { //check for rest parameter - if (match(parser, TOKEN_REST)) { + if (match(parser, TOY_TOKEN_REST)) { //read the argument identifier - consume(parser, TOKEN_IDENTIFIER, "Expected identifier as function argument"); - Token argIdentifierToken = parser->previous; + consume(parser, TOY_TOKEN_IDENTIFIER, "Expected identifier as function argument"); + Toy_Token argIdentifierToken = parser->previous; int length = argIdentifierToken.length; @@ -1615,32 +1615,32 @@ 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(argIdentifierToken.lexeme, length)); + Toy_Literal argIdentifier = TOY_TO_IDENTIFIER_LITERAL(Toy_createRefStringLength(argIdentifierToken.lexeme, length)); //set the type (array of any types) - Literal argTypeLiteral = TO_TYPE_LITERAL(LITERAL_FUNCTION_ARG_REST, false); + Toy_Literal argTypeLiteral = TOY_TO_TYPE_LITERAL(TOY_LITERAL_FUNCTION_ARG_REST, false); //emit the node to the argument list (grow the node if needed) if (argumentNode->fnCollection.capacity < argumentNode->fnCollection.count + 1) { int oldCapacity = argumentNode->fnCollection.capacity; - argumentNode->fnCollection.capacity = GROW_CAPACITY(oldCapacity); - argumentNode->fnCollection.nodes = GROW_ARRAY(ASTNode, argumentNode->fnCollection.nodes, oldCapacity, argumentNode->fnCollection.capacity); + argumentNode->fnCollection.capacity = TOY_GROW_CAPACITY(oldCapacity); + argumentNode->fnCollection.nodes = TOY_GROW_ARRAY(Toy_ASTNode, argumentNode->fnCollection.nodes, oldCapacity, argumentNode->fnCollection.capacity); } //store the arg in the array - ASTNode* literalNode = NULL; - emitASTNodeVarDecl(&literalNode, argIdentifier, argTypeLiteral, NULL); + Toy_ASTNode* literalNode = NULL; + Toy_emitASTNodeVarDecl(&literalNode, argIdentifier, argTypeLiteral, NULL); argumentNode->fnCollection.nodes[argumentNode->fnCollection.count++] = *literalNode; - FREE(ASTNode, literalNode); + TOY_FREE(Toy_ASTNode, literalNode); break; } //read the argument identifier - consume(parser, TOKEN_IDENTIFIER, "Expected identifier as function argument"); - Token argIdentifierToken = parser->previous; + consume(parser, TOY_TOKEN_IDENTIFIER, "Expected identifier as function argument"); + Toy_Token argIdentifierToken = parser->previous; int length = argIdentifierToken.length; @@ -1650,76 +1650,76 @@ 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(argIdentifierToken.lexeme, length)); + Toy_Literal argIdentifier = TOY_TO_IDENTIFIER_LITERAL(Toy_createRefStringLength(argIdentifierToken.lexeme, length)); //read optional type of the identifier - Literal argTypeLiteral; - if (match(parser, TOKEN_COLON)) { + Toy_Literal argTypeLiteral; + if (match(parser, TOY_TOKEN_COLON)) { argTypeLiteral = readTypeToLiteral(parser); } else { //default to non-const any - argTypeLiteral = TO_TYPE_LITERAL(LITERAL_ANY, false); + argTypeLiteral = TOY_TO_TYPE_LITERAL(TOY_LITERAL_ANY, false); } //emit the node to the argument list (grow the node if needed) if (argumentNode->fnCollection.capacity < argumentNode->fnCollection.count + 1) { int oldCapacity = argumentNode->fnCollection.capacity; - argumentNode->fnCollection.capacity = GROW_CAPACITY(oldCapacity); - argumentNode->fnCollection.nodes = GROW_ARRAY(ASTNode, argumentNode->fnCollection.nodes, oldCapacity, argumentNode->fnCollection.capacity); + argumentNode->fnCollection.capacity = TOY_GROW_CAPACITY(oldCapacity); + argumentNode->fnCollection.nodes = TOY_GROW_ARRAY(Toy_ASTNode, argumentNode->fnCollection.nodes, oldCapacity, argumentNode->fnCollection.capacity); } //store the arg in the array - ASTNode* literalNode = NULL; - emitASTNodeVarDecl(&literalNode, argIdentifier, argTypeLiteral, NULL); + Toy_ASTNode* literalNode = NULL; + Toy_emitASTNodeVarDecl(&literalNode, argIdentifier, argTypeLiteral, NULL); argumentNode->fnCollection.nodes[argumentNode->fnCollection.count++] = *literalNode; - FREE(ASTNode, literalNode); + TOY_FREE(Toy_ASTNode, literalNode); - } while (match(parser, TOKEN_COMMA)); //if comma is read, continue + } while (match(parser, TOY_TOKEN_COMMA)); //if comma is read, continue - consume(parser, TOKEN_PAREN_RIGHT, "Expected ')' after function argument list"); + consume(parser, TOY_TOKEN_PAREN_RIGHT, "Expected ')' after function argument list"); } //read the return types, if present - ASTNode* returnNode = NULL; - emitASTNodeFnCollection(&returnNode); + Toy_ASTNode* returnNode = NULL; + Toy_emitASTNodeFnCollection(&returnNode); - if (match(parser, TOKEN_COLON)) { + if (match(parser, TOY_TOKEN_COLON)) { do { //append the node to the return list (grow the node if needed) if (returnNode->fnCollection.capacity < returnNode->fnCollection.count + 1) { int oldCapacity = returnNode->fnCollection.capacity; - returnNode->fnCollection.capacity = GROW_CAPACITY(oldCapacity); - returnNode->fnCollection.nodes = GROW_ARRAY(ASTNode, returnNode->fnCollection.nodes, oldCapacity, returnNode->fnCollection.capacity); + returnNode->fnCollection.capacity = TOY_GROW_CAPACITY(oldCapacity); + returnNode->fnCollection.nodes = TOY_GROW_ARRAY(Toy_ASTNode, returnNode->fnCollection.nodes, oldCapacity, returnNode->fnCollection.capacity); } - ASTNode* literalNode = NULL; - emitASTNodeLiteral(&literalNode, readTypeToLiteral(parser)); + Toy_ASTNode* literalNode = NULL; + Toy_emitASTNodeLiteral(&literalNode, readTypeToLiteral(parser)); returnNode->fnCollection.nodes[returnNode->fnCollection.count++] = *literalNode; - FREE(ASTNode, literalNode); - } while(match(parser, TOKEN_COMMA)); + TOY_FREE(Toy_ASTNode, literalNode); + } while(match(parser, TOY_TOKEN_COMMA)); } //read the function body - consume(parser, TOKEN_BRACE_LEFT, "Expected '{' after return list"); + consume(parser, TOY_TOKEN_BRACE_LEFT, "Expected '{' after return list"); - ASTNode* blockNode = NULL; + Toy_ASTNode* blockNode = NULL; blockStmt(parser, &blockNode); //declare it - emitASTNodeFnDecl(nodeHandle, identifier, argumentNode, returnNode, blockNode); + Toy_emitASTNodeFnDecl(nodeHandle, identifier, argumentNode, returnNode, blockNode); } -static void declaration(Parser* parser, ASTNode** nodeHandle) { //assume nodeHandle holds a blank node +static void declaration(Toy_Parser* parser, Toy_ASTNode** nodeHandle) { //assume nodeHandle holds a blank node //variable declarations - if (match(parser, TOKEN_VAR)) { + if (match(parser, TOY_TOKEN_VAR)) { varDecl(parser, nodeHandle); } - else if (match(parser, TOKEN_FUNCTION)) { + else if (match(parser, TOY_TOKEN_FUNCTION)) { fnDecl(parser, nodeHandle); } else { @@ -1728,33 +1728,33 @@ static void declaration(Parser* parser, ASTNode** nodeHandle) { //assume nodeHan } //exposed functions -void initParser(Parser* parser, Lexer* lexer) { +void Toy_initParser(Toy_Parser* parser, Toy_Lexer* lexer) { parser->lexer = lexer; parser->error = false; parser->panic = false; - parser->previous.type = TOKEN_NULL; - parser->current.type = TOKEN_NULL; + parser->previous.type = TOY_TOKEN_NULL; + parser->current.type = TOY_TOKEN_NULL; advance(parser); } -void freeParser(Parser* parser) { +void Toy_freeParser(Toy_Parser* parser) { parser->lexer = NULL; parser->error = false; parser->panic = false; - parser->previous.type = TOKEN_NULL; - parser->current.type = TOKEN_NULL; + parser->previous.type = TOY_TOKEN_NULL; + parser->current.type = TOY_TOKEN_NULL; } -ASTNode* scanParser(Parser* parser) { +Toy_ASTNode* Toy_scanParser(Toy_Parser* parser) { //check for EOF - if (match(parser, TOKEN_EOF)) { + if (match(parser, TOY_TOKEN_EOF)) { return NULL; } //returns nodes on the heap - ASTNode* node = NULL; + Toy_ASTNode* node = NULL; //process the grammar rule for this line declaration(parser, &node); @@ -1762,9 +1762,9 @@ ASTNode* scanParser(Parser* parser) { if (parser->panic) { synchronize(parser); //return an error node for this iteration - freeASTNode(node); - node = ALLOCATE(ASTNode, 1); - node->type = AST_NODE_ERROR; + Toy_freeASTNode(node); + node = TOY_ALLOCATE(Toy_ASTNode, 1); + node->type = TOY_AST_NODE_ERROR; } return node; diff --git a/source/toy_parser.h b/source/toy_parser.h index 58356a7..314d6f7 100644 --- a/source/toy_parser.h +++ b/source/toy_parser.h @@ -1,20 +1,20 @@ #pragma once #include "toy_common.h" -#include "lexer.h" -#include "ast_node.h" +#include "toy_lexer.h" +#include "toy_ast_node.h" //DOCS: parsers are bound to a lexer, and turn the outputted tokens into AST nodes typedef struct { - Lexer* lexer; + Toy_Lexer* lexer; bool error; //I've had an error bool panic; //I am processing an error //track the last two outputs from the lexer - Token current; - Token previous; -} Parser; + Toy_Token current; + Toy_Token previous; +} Toy_Parser; -TOY_API void initParser(Parser* parser, Lexer* lexer); -TOY_API void freeParser(Parser* parser); -TOY_API ASTNode* scanParser(Parser* parser); +TOY_API void Toy_initParser(Toy_Parser* parser, Toy_Lexer* lexer); +TOY_API void Toy_freeParser(Toy_Parser* parser); +TOY_API Toy_ASTNode* Toy_scanParser(Toy_Parser* parser); diff --git a/source/toy_refstring.c b/source/toy_refstring.c index edfd2b7..5ff3d12 100644 --- a/source/toy_refstring.c +++ b/source/toy_refstring.c @@ -1,4 +1,4 @@ -#include "refstring.h" +#include "toy_refstring.h" #include #include @@ -6,27 +6,27 @@ //test variable sizes based on platform (safety) #define STATIC_ASSERT(test_for_true) static_assert((test_for_true), "(" #test_for_true ") failed") -STATIC_ASSERT(sizeof(RefString) == 12); +STATIC_ASSERT(sizeof(Toy_RefString) == 12); STATIC_ASSERT(sizeof(int) == 4); STATIC_ASSERT(sizeof(char) == 1); //memory allocation -static RefStringAllocatorFn allocate; +static Toy_RefStringAllocatorFn allocate; -void setRefStringAllocatorFn(RefStringAllocatorFn allocator) { +void Toy_setRefStringAllocatorFn(Toy_RefStringAllocatorFn allocator) { allocate = allocator; } //API -RefString* createRefString(char* cstring) { +Toy_RefString* Toy_createRefString(char* cstring) { int length = strnlen(cstring, 4096); - return createRefStringLength(cstring, length); + return Toy_createRefStringLength(cstring, length); } -RefString* createRefStringLength(char* cstring, int length) { +Toy_RefString* Toy_createRefStringLength(char* cstring, int length) { //allocate the memory area (including metadata space) - RefString* refString = (RefString*)allocate(NULL, 0, sizeof(int) * 2 + sizeof(char) * length + 1); + Toy_RefString* refString = (Toy_RefString*)allocate(NULL, 0, sizeof(int) * 2 + sizeof(char) * length + 1); //set the data refString->refcount = 1; @@ -38,7 +38,7 @@ RefString* createRefStringLength(char* cstring, int length) { return refString; } -void deleteRefString(RefString* refString) { +void Toy_deleteRefString(Toy_RefString* refString) { //decrement, then check refString->refcount--; if (refString->refcount <= 0) { @@ -46,30 +46,30 @@ void deleteRefString(RefString* refString) { } } -int countRefString(RefString* refString) { +int Toy_countRefString(Toy_RefString* refString) { return refString->refcount; } -int lengthRefString(RefString* refString) { +int Toy_lengthRefString(Toy_RefString* refString) { return refString->length; } -RefString* copyRefString(RefString* refString) { +Toy_RefString* Toy_copyRefString(Toy_RefString* refString) { //Cheaty McCheater Face refString->refcount++; return refString; } -RefString* deepCopyRefString(RefString* refString) { +Toy_RefString* Toy_deepCopyRefString(Toy_RefString* refString) { //create a new string, with a new refcount - return createRefStringLength(refString->data, refString->length); + return Toy_createRefStringLength(refString->data, refString->length); } -char* toCString(RefString* refString) { +char* Toy_toCString(Toy_RefString* refString) { return refString->data; } -bool equalsRefString(RefString* lhs, RefString* rhs) { +bool Toy_equalsRefString(Toy_RefString* lhs, Toy_RefString* rhs) { //same pointer if (lhs == rhs) { return true; @@ -84,7 +84,7 @@ bool equalsRefString(RefString* lhs, RefString* rhs) { return strncmp(lhs->data, rhs->data, lhs->length) == 0; } -bool equalsRefStringCString(RefString* lhs, char* cstring) { +bool Toy_equalsRefStringCString(Toy_RefString* lhs, char* cstring) { //get the rhs length int length = strnlen(cstring, 4096); diff --git a/source/toy_refstring.h b/source/toy_refstring.h index a09ce8f..30c8f67 100644 --- a/source/toy_refstring.h +++ b/source/toy_refstring.h @@ -4,24 +4,24 @@ #include //memory allocation hook -typedef void* (*RefStringAllocatorFn)(void* pointer, size_t oldSize, size_t newSize); -void setRefStringAllocatorFn(RefStringAllocatorFn); +typedef void* (*Toy_RefStringAllocatorFn)(void* pointer, size_t oldSize, size_t newSize); +void Toy_setRefStringAllocatorFn(Toy_RefStringAllocatorFn); //the RefString structure -typedef struct RefString { +typedef struct Toy_RefString { int refcount; int length; char data[1]; -} RefString; +} Toy_RefString; //API -RefString* createRefString(char* cstring); -RefString* createRefStringLength(char* cstring, int length); -void deleteRefString(RefString* refString); -int countRefString(RefString* refString); -int lengthRefString(RefString* refString); -RefString* copyRefString(RefString* refString); -RefString* deepCopyRefString(RefString* refString); -char* toCString(RefString* refString); -bool equalsRefString(RefString* lhs, RefString* rhs); -bool equalsRefStringCString(RefString* lhs, char* cstring); +Toy_RefString* Toy_createRefString(char* cstring); +Toy_RefString* Toy_createRefStringLength(char* cstring, int length); +void Toy_deleteRefString(Toy_RefString* refString); +int Toy_countRefString(Toy_RefString* refString); +int Toy_lengthRefString(Toy_RefString* refString); +Toy_RefString* Toy_copyRefString(Toy_RefString* refString); +Toy_RefString* Toy_deepCopyRefString(Toy_RefString* refString); +char* Toy_toCString(Toy_RefString* refString); +bool Toy_equalsRefString(Toy_RefString* lhs, Toy_RefString* rhs); +bool Toy_equalsRefStringCString(Toy_RefString* lhs, char* cstring); diff --git a/source/toy_scope.c b/source/toy_scope.c index eefb266..f33e4e7 100644 --- a/source/toy_scope.c +++ b/source/toy_scope.c @@ -1,9 +1,9 @@ -#include "scope.h" +#include "toy_scope.h" -#include "memory.h" +#include "toy_memory.h" //run up the ancestor chain, freeing anything with 0 references left -static void freeAncestorChain(Scope* scope) { +static void freeAncestorChain(Toy_Scope* scope) { scope->references--; //free scope chain @@ -15,65 +15,65 @@ static void freeAncestorChain(Scope* scope) { return; } - freeLiteralDictionary(&scope->variables); - freeLiteralDictionary(&scope->types); + Toy_freeLiteralDictionary(&scope->variables); + Toy_freeLiteralDictionary(&scope->types); - FREE(Scope, scope); + TOY_FREE(Toy_Scope, scope); } //return false if invalid type -static bool checkType(Literal typeLiteral, Literal original, Literal value, bool constCheck) { +static bool checkType(Toy_Literal typeLiteral, Toy_Literal original, Toy_Literal value, bool constCheck) { //for constants, fail if original != value - if (constCheck && AS_TYPE(typeLiteral).constant && !literalsAreEqual(original, value)) { + if (constCheck && TOY_AS_TYPE(typeLiteral).constant && !Toy_literalsAreEqual(original, value)) { return false; } //for any types - if (AS_TYPE(typeLiteral).typeOf == LITERAL_ANY) { + if (TOY_AS_TYPE(typeLiteral).typeOf == TOY_LITERAL_ANY) { return true; } //don't allow null types - if (AS_TYPE(typeLiteral).typeOf == LITERAL_NULL) { + if (TOY_AS_TYPE(typeLiteral).typeOf == TOY_LITERAL_NULL) { return false; } //always allow null values - if (IS_NULL(value)) { + if (TOY_IS_NULL(value)) { return true; } //for each type, if a mismatch is found, return false - if (AS_TYPE(typeLiteral).typeOf == LITERAL_BOOLEAN && !IS_BOOLEAN(value)) { + if (TOY_AS_TYPE(typeLiteral).typeOf == TOY_LITERAL_BOOLEAN && !TOY_IS_BOOLEAN(value)) { return false; } - if (AS_TYPE(typeLiteral).typeOf == LITERAL_INTEGER && !IS_INTEGER(value)) { + if (TOY_AS_TYPE(typeLiteral).typeOf == TOY_LITERAL_INTEGER && !TOY_IS_INTEGER(value)) { return false; } - if (AS_TYPE(typeLiteral).typeOf == LITERAL_FLOAT && !IS_FLOAT(value)) { + if (TOY_AS_TYPE(typeLiteral).typeOf == TOY_LITERAL_FLOAT && !TOY_IS_FLOAT(value)) { return false; } - if (AS_TYPE(typeLiteral).typeOf == LITERAL_STRING && !IS_STRING(value)) { + if (TOY_AS_TYPE(typeLiteral).typeOf == TOY_LITERAL_STRING && !TOY_IS_STRING(value)) { return false; } - if (AS_TYPE(typeLiteral).typeOf == LITERAL_ARRAY && !IS_ARRAY(value)) { + if (TOY_AS_TYPE(typeLiteral).typeOf == TOY_LITERAL_ARRAY && !TOY_IS_ARRAY(value)) { return false; } - if (IS_ARRAY(value)) { + if (TOY_IS_ARRAY(value)) { //check value's type - if (AS_TYPE(typeLiteral).typeOf != LITERAL_ARRAY) { + if (TOY_AS_TYPE(typeLiteral).typeOf != TOY_LITERAL_ARRAY) { return false; } //if null, assume it's a new array variable that needs checking - if (IS_NULL(original)) { - for (int i = 0; i < AS_ARRAY(value)->count; i++) { - if (!checkType( ((Literal*)(AS_TYPE(typeLiteral).subtypes))[0], TO_NULL_LITERAL, AS_ARRAY(value)->literals[i], constCheck)) { + if (TOY_IS_NULL(original)) { + for (int i = 0; i < TOY_AS_ARRAY(value)->count; i++) { + if (!checkType( ((Toy_Literal*)(TOY_AS_TYPE(typeLiteral).subtypes))[0], TOY_TO_NULL_LITERAL, TOY_AS_ARRAY(value)->literals[i], constCheck)) { return false; } } @@ -82,36 +82,36 @@ static bool checkType(Literal typeLiteral, Literal original, Literal value, bool } //check children - for (int i = 0; i < AS_ARRAY(value)->count; i++) { - if (AS_ARRAY(original)->count <= i) { + for (int i = 0; i < TOY_AS_ARRAY(value)->count; i++) { + if (TOY_AS_ARRAY(original)->count <= i) { return true; //assume new entry pushed } - if (!checkType(((Literal*)(AS_TYPE(typeLiteral).subtypes))[0], AS_ARRAY(original)->literals[i], AS_ARRAY(value)->literals[i], constCheck)) { + if (!checkType(((Toy_Literal*)(TOY_AS_TYPE(typeLiteral).subtypes))[0], TOY_AS_ARRAY(original)->literals[i], TOY_AS_ARRAY(value)->literals[i], constCheck)) { return false; } } } - if (AS_TYPE(typeLiteral).typeOf == LITERAL_DICTIONARY && !IS_DICTIONARY(value)) { + if (TOY_AS_TYPE(typeLiteral).typeOf == TOY_LITERAL_DICTIONARY && !TOY_IS_DICTIONARY(value)) { return false; } - if (IS_DICTIONARY(value)) { + if (TOY_IS_DICTIONARY(value)) { //check value's type - if (AS_TYPE(typeLiteral).typeOf != LITERAL_DICTIONARY) { + if (TOY_AS_TYPE(typeLiteral).typeOf != TOY_LITERAL_DICTIONARY) { return false; } //if null, assume it's a new dictionary variable that needs checking - if (IS_NULL(original)) { - for (int i = 0; i < AS_DICTIONARY(value)->capacity; i++) { + if (TOY_IS_NULL(original)) { + for (int i = 0; i < TOY_AS_DICTIONARY(value)->capacity; i++) { //check the type of key and value - if (!checkType(((Literal*)(AS_TYPE(typeLiteral).subtypes))[0], TO_NULL_LITERAL, AS_DICTIONARY(value)->entries[i].key, constCheck)) { + if (!checkType(((Toy_Literal*)(TOY_AS_TYPE(typeLiteral).subtypes))[0], TOY_TO_NULL_LITERAL, TOY_AS_DICTIONARY(value)->entries[i].key, constCheck)) { return false; } - if (!checkType(((Literal*)(AS_TYPE(typeLiteral).subtypes))[1], TO_NULL_LITERAL, AS_DICTIONARY(value)->entries[i].value, constCheck)) { + if (!checkType(((Toy_Literal*)(TOY_AS_TYPE(typeLiteral).subtypes))[1], TOY_TO_NULL_LITERAL, TOY_AS_DICTIONARY(value)->entries[i].value, constCheck)) { return false; } } @@ -120,17 +120,17 @@ static bool checkType(Literal typeLiteral, Literal original, Literal value, bool } //check each child of value against the child of original - for (int i = 0; i < AS_DICTIONARY(value)->capacity; i++) { - if (IS_NULL(AS_DICTIONARY(value)->entries[i].key)) { //only non-tombstones + for (int i = 0; i < TOY_AS_DICTIONARY(value)->capacity; i++) { + if (TOY_IS_NULL(TOY_AS_DICTIONARY(value)->entries[i].key)) { //only non-tombstones continue; } //find the internal child of original that matches this child of value - _entry* ptr = NULL; + Toy_private_entry* ptr = NULL; - for (int j = 0; j < AS_DICTIONARY(original)->capacity; j++) { - if (literalsAreEqual(AS_DICTIONARY(original)->entries[j].key, AS_DICTIONARY(value)->entries[i].key)) { - ptr = &AS_DICTIONARY(original)->entries[j]; + for (int j = 0; j < TOY_AS_DICTIONARY(original)->capacity; j++) { + if (Toy_literalsAreEqual(TOY_AS_DICTIONARY(original)->entries[j].key, TOY_AS_DICTIONARY(value)->entries[i].key)) { + ptr = &TOY_AS_DICTIONARY(original)->entries[j]; break; } } @@ -141,21 +141,21 @@ static bool checkType(Literal typeLiteral, Literal original, Literal value, bool } //check the type of key and value - if (!checkType(((Literal*)(AS_TYPE(typeLiteral).subtypes))[0], ptr->key, AS_DICTIONARY(value)->entries[i].key, constCheck)) { + if (!checkType(((Toy_Literal*)(TOY_AS_TYPE(typeLiteral).subtypes))[0], ptr->key, TOY_AS_DICTIONARY(value)->entries[i].key, constCheck)) { return false; } - if (!checkType(((Literal*)(AS_TYPE(typeLiteral).subtypes))[1], ptr->value, AS_DICTIONARY(value)->entries[i].value, constCheck)) { + if (!checkType(((Toy_Literal*)(TOY_AS_TYPE(typeLiteral).subtypes))[1], ptr->value, TOY_AS_DICTIONARY(value)->entries[i].value, constCheck)) { return false; } } } - if (AS_TYPE(typeLiteral).typeOf == LITERAL_FUNCTION && !IS_FUNCTION(value)) { + if (TOY_AS_TYPE(typeLiteral).typeOf == TOY_LITERAL_FUNCTION && !TOY_IS_FUNCTION(value)) { return false; } - if (AS_TYPE(typeLiteral).typeOf == LITERAL_TYPE && !IS_TYPE(value)) { + if (TOY_AS_TYPE(typeLiteral).typeOf == TOY_LITERAL_TYPE && !TOY_IS_TYPE(value)) { return false; } @@ -163,39 +163,39 @@ static bool checkType(Literal typeLiteral, Literal original, Literal value, bool } //exposed functions -Scope* pushScope(Scope* ancestor) { - Scope* scope = ALLOCATE(Scope, 1); +Toy_Scope* Toy_pushScope(Toy_Scope* ancestor) { + Toy_Scope* scope = TOY_ALLOCATE(Toy_Scope, 1); scope->ancestor = ancestor; - initLiteralDictionary(&scope->variables); - initLiteralDictionary(&scope->types); + Toy_initLiteralDictionary(&scope->variables); + Toy_initLiteralDictionary(&scope->types); //tick up all scope reference counts scope->references = 0; - for (Scope* ptr = scope; ptr != NULL; ptr = ptr->ancestor) { + for (Toy_Scope* ptr = scope; ptr != NULL; ptr = ptr->ancestor) { ptr->references++; } return scope; } -Scope* popScope(Scope* scope) { +Toy_Scope* Toy_popScope(Toy_Scope* scope) { if (scope == NULL) { //CAN pop a null return NULL; } - Scope* ret = scope->ancestor; + Toy_Scope* ret = scope->ancestor; //BUGFIX: when freeing a scope, free the function's scopes manually for (int i = 0; i < scope->variables.capacity; i++) { //handle keys, just in case - if (IS_FUNCTION(scope->variables.entries[i].key)) { - popScope(AS_FUNCTION(scope->variables.entries[i].key).scope); - AS_FUNCTION(scope->variables.entries[i].key).scope = NULL; + if (TOY_IS_FUNCTION(scope->variables.entries[i].key)) { + Toy_popScope(TOY_AS_FUNCTION(scope->variables.entries[i].key).scope); + TOY_AS_FUNCTION(scope->variables.entries[i].key).scope = NULL; } - if (IS_FUNCTION(scope->variables.entries[i].value)) { - popScope(AS_FUNCTION(scope->variables.entries[i].value).scope); - AS_FUNCTION(scope->variables.entries[i].value).scope = NULL; + if (TOY_IS_FUNCTION(scope->variables.entries[i].value)) { + Toy_popScope(TOY_AS_FUNCTION(scope->variables.entries[i].value).scope); + TOY_AS_FUNCTION(scope->variables.entries[i].value).scope = NULL; } } @@ -204,28 +204,28 @@ Scope* popScope(Scope* scope) { return ret; } -Scope* copyScope(Scope* original) { - Scope* scope = ALLOCATE(Scope, 1); +Toy_Scope* Toy_copyScope(Toy_Scope* original) { + Toy_Scope* scope = TOY_ALLOCATE(Toy_Scope, 1); scope->ancestor = original->ancestor; - initLiteralDictionary(&scope->variables); - initLiteralDictionary(&scope->types); + Toy_initLiteralDictionary(&scope->variables); + Toy_initLiteralDictionary(&scope->types); //tick up all scope reference counts scope->references = 0; - for (Scope* ptr = scope; ptr != NULL; ptr = ptr->ancestor) { + for (Toy_Scope* ptr = scope; ptr != NULL; ptr = ptr->ancestor) { ptr->references++; } //copy the contents of the dictionaries for (int i = 0; i < original->variables.capacity; i++) { - if (!IS_NULL(original->variables.entries[i].key)) { - setLiteralDictionary(&scope->variables, original->variables.entries[i].key, original->variables.entries[i].value); + if (!TOY_IS_NULL(original->variables.entries[i].key)) { + Toy_setLiteralDictionary(&scope->variables, original->variables.entries[i].key, original->variables.entries[i].value); } } for (int i = 0; i < original->types.capacity; i++) { - if (!IS_NULL(original->types.entries[i].key)) { - setLiteralDictionary(&scope->types, original->types.entries[i].key, original->types.entries[i].value); + if (!TOY_IS_NULL(original->types.entries[i].key)) { + Toy_setLiteralDictionary(&scope->types, original->types.entries[i].key, original->types.entries[i].value); } } @@ -233,92 +233,92 @@ Scope* copyScope(Scope* original) { } //returns false if error -bool declareScopeVariable(Scope* scope, Literal key, Literal type) { +bool Toy_declareScopeVariable(Toy_Scope* scope, Toy_Literal key, Toy_Literal type) { //don't redefine a variable within this scope - if (existsLiteralDictionary(&scope->variables, key)) { + if (Toy_existsLiteralDictionary(&scope->variables, key)) { return false; } - if (!IS_TYPE(type)) { + if (!TOY_IS_TYPE(type)) { return false; } //store the type, for later checking on assignment - setLiteralDictionary(&scope->types, key, type); + Toy_setLiteralDictionary(&scope->types, key, type); - setLiteralDictionary(&scope->variables, key, TO_NULL_LITERAL); + Toy_setLiteralDictionary(&scope->variables, key, TOY_TO_NULL_LITERAL); return true; } -bool isDelcaredScopeVariable(Scope* scope, Literal key) { +bool Toy_isDelcaredScopeVariable(Toy_Scope* scope, Toy_Literal key) { if (scope == NULL) { return false; } //if it's not in this scope, keep searching up the chain - if (!existsLiteralDictionary(&scope->variables, key)) { - return isDelcaredScopeVariable(scope->ancestor, key); + if (!Toy_existsLiteralDictionary(&scope->variables, key)) { + return Toy_isDelcaredScopeVariable(scope->ancestor, key); } return true; } //return false if undefined, or can't be assigned -bool setScopeVariable(Scope* scope, Literal key, Literal value, bool constCheck) { +bool Toy_setScopeVariable(Toy_Scope* scope, Toy_Literal key, Toy_Literal value, bool constCheck) { //dead end if (scope == NULL) { return false; } //if it's not in this scope, keep searching up the chain - if (!existsLiteralDictionary(&scope->variables, key)) { - return setScopeVariable(scope->ancestor, key, value, constCheck); + if (!Toy_existsLiteralDictionary(&scope->variables, key)) { + return Toy_setScopeVariable(scope->ancestor, key, value, constCheck); } //type checking - Literal typeLiteral = getLiteralDictionary(&scope->types, key); - Literal original = getLiteralDictionary(&scope->variables, key); + Toy_Literal typeLiteral = Toy_getLiteralDictionary(&scope->types, key); + Toy_Literal original = Toy_getLiteralDictionary(&scope->variables, key); if (!checkType(typeLiteral, original, value, constCheck)) { - freeLiteral(typeLiteral); - freeLiteral(original); + Toy_freeLiteral(typeLiteral); + Toy_freeLiteral(original); return false; } //actually assign - setLiteralDictionary(&scope->variables, key, value); + Toy_setLiteralDictionary(&scope->variables, key, value); - freeLiteral(typeLiteral); - freeLiteral(original); + Toy_freeLiteral(typeLiteral); + Toy_freeLiteral(original); return true; } -bool getScopeVariable(Scope* scope, Literal key, Literal* valueHandle) { +bool Toy_getScopeVariable(Toy_Scope* scope, Toy_Literal key, Toy_Literal* valueHandle) { //dead end if (scope == NULL) { return false; } //if it's not in this scope, keep searching up the chain - if (!existsLiteralDictionary(&scope->variables, key)) { - return getScopeVariable(scope->ancestor, key, valueHandle); + if (!Toy_existsLiteralDictionary(&scope->variables, key)) { + return Toy_getScopeVariable(scope->ancestor, key, valueHandle); } - *valueHandle = getLiteralDictionary(&scope->variables, key); + *valueHandle = Toy_getLiteralDictionary(&scope->variables, key); return true; } -Literal getScopeType(Scope* scope, Literal key) { +Toy_Literal Toy_getScopeType(Toy_Scope* scope, Toy_Literal key) { //dead end if (scope == NULL) { - return TO_NULL_LITERAL; + return TOY_TO_NULL_LITERAL; } //if it's not in this scope, keep searching up the chain - if (!existsLiteralDictionary(&scope->types, key)) { - return getScopeType(scope->ancestor, key); + if (!Toy_existsLiteralDictionary(&scope->types, key)) { + return Toy_getScopeType(scope->ancestor, key); } - return getLiteralDictionary(&scope->types, key); + return Toy_getLiteralDictionary(&scope->types, key); } diff --git a/source/toy_scope.h b/source/toy_scope.h index 153d837..8407af1 100644 --- a/source/toy_scope.h +++ b/source/toy_scope.h @@ -1,25 +1,25 @@ #pragma once -#include "literal_array.h" -#include "literal_dictionary.h" +#include "toy_literal_array.h" +#include "toy_literal_dictionary.h" -typedef struct Scope { - LiteralDictionary variables; //only allow identifiers as the keys - LiteralDictionary types; //the types, indexed by identifiers - struct Scope* ancestor; +typedef struct Toy_Scope { + Toy_LiteralDictionary variables; //only allow identifiers as the keys + Toy_LiteralDictionary types; //the types, indexed by identifiers + struct Toy_Scope* ancestor; int references; //how many scopes point here -} Scope; +} Toy_Scope; -Scope* pushScope(Scope* scope); -Scope* popScope(Scope* scope); -Scope* copyScope(Scope* original); +Toy_Scope* Toy_pushScope(Toy_Scope* scope); +Toy_Scope* Toy_popScope(Toy_Scope* scope); +Toy_Scope* Toy_copyScope(Toy_Scope* original); //returns false if error -bool declareScopeVariable(Scope* scope, Literal key, Literal type); -bool isDelcaredScopeVariable(Scope* scope, Literal key); +bool Toy_declareScopeVariable(Toy_Scope* scope, Toy_Literal key, Toy_Literal type); +bool Toy_isDelcaredScopeVariable(Toy_Scope* scope, Toy_Literal key); //return false if undefined -bool setScopeVariable(Scope* scope, Literal key, Literal value, bool constCheck); -bool getScopeVariable(Scope* scope, Literal key, Literal* value); +bool Toy_setScopeVariable(Toy_Scope* scope, Toy_Literal key, Toy_Literal value, bool constCheck); +bool Toy_getScopeVariable(Toy_Scope* scope, Toy_Literal key, Toy_Literal* value); -Literal getScopeType(Scope* scope, Literal key); +Toy_Literal Toy_getScopeType(Toy_Scope* scope, Toy_Literal key); diff --git a/source/toy_token_types.h b/source/toy_token_types.h index 896a315..2de0b3f 100644 --- a/source/toy_token_types.h +++ b/source/toy_token_types.h @@ -1,93 +1,93 @@ #pragma once -typedef enum TokenType { +typedef enum Toy_TokenType { //types - TOKEN_NULL, - TOKEN_BOOLEAN, - TOKEN_INTEGER, - TOKEN_FLOAT, - TOKEN_STRING, - TOKEN_ARRAY, - TOKEN_DICTIONARY, - TOKEN_FUNCTION, - TOKEN_OPAQUE, - TOKEN_ANY, + TOY_TOKEN_NULL, + TOY_TOKEN_BOOLEAN, + TOY_TOKEN_INTEGER, + TOY_TOKEN_FLOAT, + TOY_TOKEN_STRING, + TOY_TOKEN_ARRAY, + TOY_TOKEN_DICTIONARY, + TOY_TOKEN_FUNCTION, + TOY_TOKEN_OPAQUE, + TOY_TOKEN_ANY, //keywords and reserved words - TOKEN_AS, - TOKEN_ASSERT, - TOKEN_BREAK, - TOKEN_CLASS, - TOKEN_CONST, - TOKEN_CONTINUE, - TOKEN_DO, - TOKEN_ELSE, - TOKEN_EXPORT, - TOKEN_FOR, - TOKEN_FOREACH, - TOKEN_IF, - TOKEN_IMPORT, - TOKEN_IN, - TOKEN_OF, - TOKEN_PRINT, - TOKEN_RETURN, - TOKEN_TYPE, - TOKEN_ASTYPE, - TOKEN_TYPEOF, - TOKEN_VAR, - TOKEN_WHILE, + TOY_TOKEN_AS, + TOY_TOKEN_ASSERT, + TOY_TOKEN_BREAK, + TOY_TOKEN_CLASS, + TOY_TOKEN_CONST, + TOY_TOKEN_CONTINUE, + TOY_TOKEN_DO, + TOY_TOKEN_ELSE, + TOY_TOKEN_EXPORT, + TOY_TOKEN_FOR, + TOY_TOKEN_FOREACH, + TOY_TOKEN_IF, + TOY_TOKEN_IMPORT, + TOY_TOKEN_IN, + TOY_TOKEN_OF, + TOY_TOKEN_PRINT, + TOY_TOKEN_RETURN, + TOY_TOKEN_TYPE, + TOY_TOKEN_ASTYPE, + TOY_TOKEN_TYPEOF, + TOY_TOKEN_VAR, + TOY_TOKEN_WHILE, //literal values - TOKEN_IDENTIFIER, - TOKEN_LITERAL_TRUE, - TOKEN_LITERAL_FALSE, - TOKEN_LITERAL_INTEGER, - TOKEN_LITERAL_FLOAT, - TOKEN_LITERAL_STRING, + TOY_TOKEN_IDENTIFIER, + TOY_TOKEN_LITERAL_TRUE, + TOY_TOKEN_LITERAL_FALSE, + TOY_TOKEN_LITERAL_INTEGER, + TOY_TOKEN_LITERAL_FLOAT, + TOY_TOKEN_LITERAL_STRING, //math operators - TOKEN_PLUS, - TOKEN_MINUS, - TOKEN_MULTIPLY, - TOKEN_DIVIDE, - TOKEN_MODULO, - TOKEN_PLUS_ASSIGN, - TOKEN_MINUS_ASSIGN, - TOKEN_MULTIPLY_ASSIGN, - TOKEN_DIVIDE_ASSIGN, - TOKEN_MODULO_ASSIGN, - TOKEN_PLUS_PLUS, - TOKEN_MINUS_MINUS, - TOKEN_ASSIGN, + TOY_TOKEN_PLUS, + TOY_TOKEN_MINUS, + TOY_TOKEN_MULTIPLY, + TOY_TOKEN_DIVIDE, + TOY_TOKEN_MODULO, + TOY_TOKEN_PLUS_ASSIGN, + TOY_TOKEN_MINUS_ASSIGN, + TOY_TOKEN_MULTIPLY_ASSIGN, + TOY_TOKEN_DIVIDE_ASSIGN, + TOY_TOKEN_MODULO_ASSIGN, + TOY_TOKEN_PLUS_PLUS, + TOY_TOKEN_MINUS_MINUS, + TOY_TOKEN_ASSIGN, //logical operators - TOKEN_PAREN_LEFT, - TOKEN_PAREN_RIGHT, - TOKEN_BRACKET_LEFT, - TOKEN_BRACKET_RIGHT, - TOKEN_BRACE_LEFT, - TOKEN_BRACE_RIGHT, - TOKEN_NOT, - TOKEN_NOT_EQUAL, - TOKEN_EQUAL, - TOKEN_LESS, - TOKEN_GREATER, - TOKEN_LESS_EQUAL, - TOKEN_GREATER_EQUAL, - TOKEN_AND, - TOKEN_OR, + TOY_TOKEN_PAREN_LEFT, + TOY_TOKEN_PAREN_RIGHT, + TOY_TOKEN_BRACKET_LEFT, + TOY_TOKEN_BRACKET_RIGHT, + TOY_TOKEN_BRACE_LEFT, + TOY_TOKEN_BRACE_RIGHT, + TOY_TOKEN_NOT, + TOY_TOKEN_NOT_EQUAL, + TOY_TOKEN_EQUAL, + TOY_TOKEN_LESS, + TOY_TOKEN_GREATER, + TOY_TOKEN_LESS_EQUAL, + TOY_TOKEN_GREATER_EQUAL, + TOY_TOKEN_AND, + TOY_TOKEN_OR, //other operators - TOKEN_QUESTION, - TOKEN_COLON, - TOKEN_SEMICOLON, - TOKEN_COMMA, - TOKEN_DOT, - TOKEN_PIPE, - TOKEN_REST, + TOY_TOKEN_QUESTION, + TOY_TOKEN_COLON, + TOY_TOKEN_SEMICOLON, + TOY_TOKEN_COMMA, + TOY_TOKEN_DOT, + TOY_TOKEN_PIPE, + TOY_TOKEN_REST, //meta tokens - TOKEN_PASS, - TOKEN_ERROR, - TOKEN_EOF, -} TokenType; + TOY_TOKEN_PASS, + TOY_TOKEN_ERROR, + TOY_TOKEN_EOF, +} Toy_TokenType; diff --git a/test/test_ast_node.c b/test/test_ast_node.c index 5245362..ce0fa8c 100644 --- a/test/test_ast_node.c +++ b/test/test_ast_node.c @@ -1,14 +1,14 @@ -#include "ast_node.h" +#include "toy_ast_node.h" -#include "memory.h" -#include "console_colors.h" +#include "toy_memory.h" +#include "toy_console_colors.h" #include #include //lazy #define ASSERT(test_for_true) if (!(test_for_true)) {\ - fprintf(stderr, ERROR "assert failed: %s\n" RESET, #test_for_true); \ + fprintf(stderr, TOY_CC_ERROR "assert failed: %s\n" TOY_CC_RESET, #test_for_true); \ exit(-1); \ } @@ -17,61 +17,61 @@ int main() { { //test literals char* str = "foobar"; - Literal literal = TO_STRING_LITERAL(createRefString(str)); + Toy_Literal literal = TOY_TO_STRING_LITERAL(Toy_createRefString(str)); //generate the node - ASTNode* node = NULL; - emitASTNodeLiteral(&node, literal); + Toy_ASTNode* node = NULL; + Toy_emitASTNodeLiteral(&node, literal); //check node type - ASSERT(node->type == AST_NODE_LITERAL); + ASSERT(node->type == TOY_AST_NODE_LITERAL); //cleanup - freeLiteral(literal); - freeASTNode(node); + Toy_freeLiteral(literal); + Toy_freeASTNode(node); } //test unary { //generate the child node char* str = "foobar"; - Literal literal = TO_STRING_LITERAL(createRefString(str)); - ASTNode* childNode = NULL; - emitASTNodeLiteral(&childNode, literal); + Toy_Literal literal = TOY_TO_STRING_LITERAL(Toy_createRefString(str)); + Toy_ASTNode* childNode = NULL; + Toy_emitASTNodeLiteral(&childNode, literal); //generate the unary node - ASTNode* unary = NULL; - emitASTNodeUnary(&unary, OP_PRINT, childNode); + Toy_ASTNode* unary = NULL; + Toy_emitASTNodeUnary(&unary, TOY_OP_PRINT, childNode); //check node type - ASSERT(unary->type == AST_NODE_UNARY); + ASSERT(unary->type == TOY_AST_NODE_UNARY); //cleanup - freeLiteral(literal); - freeASTNode(unary); + Toy_freeLiteral(literal); + Toy_freeASTNode(unary); } //test binary { //generate the child node char* str = "foobar"; - Literal literal = TO_STRING_LITERAL(createRefString(str)); - ASTNode* nodeHandle = NULL; - emitASTNodeLiteral(&nodeHandle, literal); + Toy_Literal literal = TOY_TO_STRING_LITERAL(Toy_createRefString(str)); + Toy_ASTNode* nodeHandle = NULL; + Toy_emitASTNodeLiteral(&nodeHandle, literal); - ASTNode* rhsChildNode = NULL; - emitASTNodeLiteral(&rhsChildNode, literal); + Toy_ASTNode* rhsChildNode = NULL; + Toy_emitASTNodeLiteral(&rhsChildNode, literal); //generate the unary node - emitASTNodeBinary(&nodeHandle, rhsChildNode, OP_PRINT); + Toy_emitASTNodeBinary(&nodeHandle, rhsChildNode, TOY_OP_PRINT); //check node type - ASSERT(nodeHandle->type == AST_NODE_BINARY); - ASSERT(nodeHandle->binary.opcode == OP_PRINT); + ASSERT(nodeHandle->type == TOY_AST_NODE_BINARY); + ASSERT(nodeHandle->binary.opcode == TOY_OP_PRINT); //cleanup - freeLiteral(literal); - freeASTNode(nodeHandle); + Toy_freeLiteral(literal); + Toy_freeASTNode(nodeHandle); } //TODO: more tests for other AST node types @@ -82,35 +82,35 @@ int main() { char* idn = "foobar"; char* str = "hello world"; - ASTNode* dictionary; - ASTNode* left; - ASTNode* right; + Toy_ASTNode* dictionary; + Toy_ASTNode* left; + Toy_ASTNode* right; - Literal identifier = TO_IDENTIFIER_LITERAL(createRefString(idn)); - Literal string = TO_STRING_LITERAL(createRefString(str)); + Toy_Literal identifier = TOY_TO_IDENTIFIER_LITERAL(Toy_createRefString(idn)); + Toy_Literal string = TOY_TO_STRING_LITERAL(Toy_createRefString(str)); - emitASTNodeCompound(&dictionary, LITERAL_DICTIONARY); - emitASTNodeLiteral(&left, identifier); - emitASTNodeLiteral(&right, string); + Toy_emitASTNodeCompound(&dictionary, TOY_LITERAL_DICTIONARY); + Toy_emitASTNodeLiteral(&left, identifier); + Toy_emitASTNodeLiteral(&right, string); //grow the node if needed if (dictionary->compound.capacity < dictionary->compound.count + 1) { int oldCapacity = dictionary->compound.capacity; - dictionary->compound.capacity = GROW_CAPACITY(oldCapacity); - dictionary->compound.nodes = GROW_ARRAY(ASTNode, dictionary->compound.nodes, oldCapacity, dictionary->compound.capacity); + dictionary->compound.capacity = TOY_GROW_CAPACITY(oldCapacity); + dictionary->compound.nodes = TOY_GROW_ARRAY(Toy_ASTNode, dictionary->compound.nodes, oldCapacity, dictionary->compound.capacity); } //store the left and right in the node - setASTNodePair(&dictionary->compound.nodes[dictionary->compound.count++], left, right); + Toy_setASTNodePair(&dictionary->compound.nodes[dictionary->compound.count++], left, right); //the real test - freeASTNode(dictionary); - freeLiteral(identifier); - freeLiteral(string); + Toy_freeASTNode(dictionary); + Toy_freeLiteral(identifier); + Toy_freeLiteral(string); } - printf(NOTICE "All good\n" RESET); + printf(TOY_CC_NOTICE "All good\n" TOY_CC_RESET); return 0; } diff --git a/test/test_call_from_host.c b/test/test_call_from_host.c index 8dc36eb..1a2b8c2 100644 --- a/test/test_call_from_host.c +++ b/test/test_call_from_host.c @@ -1,11 +1,11 @@ -#include "lexer.h" -#include "parser.h" -#include "compiler.h" -#include "interpreter.h" +#include "toy_lexer.h" +#include "toy_parser.h" +#include "toy_compiler.h" +#include "toy_interpreter.h" -#include "console_colors.h" +#include "toy_console_colors.h" -#include "memory.h" +#include "toy_memory.h" #include "../repl/repl_tools.h" @@ -27,28 +27,28 @@ void error(char* msg) { int main() { { size_t size = 0; - char* source = readFile("scripts/call-from-host.toy", &size); - unsigned char* tb = compileString(source, &size); + char* source = Toy_readFile("scripts/call-from-host.toy", &size); + unsigned char* tb = Toy_compileString(source, &size); free((void*)source); if (!tb) { return -1; } - Interpreter interpreter; - initInterpreter(&interpreter); - runInterpreter(&interpreter, tb, size); + Toy_Interpreter interpreter; + Toy_initInterpreter(&interpreter); + Toy_runInterpreter(&interpreter, tb, size); //test answer { interpreter.printOutput("Testing answer"); - LiteralArray arguments; - initLiteralArray(&arguments); - LiteralArray returns; - initLiteralArray(&returns); + Toy_LiteralArray arguments; + Toy_initLiteralArray(&arguments); + Toy_LiteralArray returns; + Toy_initLiteralArray(&returns); - callFn(&interpreter, "answer", &arguments, &returns); + Toy_callFn(&interpreter, "answer", &arguments, &returns); //check the results if (arguments.count != 0) { @@ -59,29 +59,29 @@ int main() { error("Returns has the wrong number of members\n"); } - if (!IS_INTEGER(returns.literals[0]) || AS_INTEGER(returns.literals[0]) != 42) { + if (!TOY_IS_INTEGER(returns.literals[0]) || TOY_AS_INTEGER(returns.literals[0]) != 42) { error("Returned value is incorrect\n"); } - freeLiteralArray(&arguments); - freeLiteralArray(&returns); + Toy_freeLiteralArray(&arguments); + Toy_freeLiteralArray(&returns); } //test identity { interpreter.printOutput("Testing identity"); - LiteralArray arguments; - initLiteralArray(&arguments); - LiteralArray returns; - initLiteralArray(&returns); + Toy_LiteralArray arguments; + Toy_initLiteralArray(&arguments); + Toy_LiteralArray returns; + Toy_initLiteralArray(&returns); //push an argument float pi = 3.14; - Literal arg = TO_FLOAT_LITERAL(pi); - pushLiteralArray(&arguments, arg); + Toy_Literal arg = TOY_TO_FLOAT_LITERAL(pi); + Toy_pushLiteralArray(&arguments, arg); - callFn(&interpreter, "identity", &arguments, &returns); + Toy_callFn(&interpreter, "identity", &arguments, &returns); //check the results if (arguments.count != 0) { @@ -94,24 +94,24 @@ int main() { float epsilon = 0.1; //because floats are evil - if (!IS_FLOAT(returns.literals[0]) || fabs(AS_FLOAT(returns.literals[0]) - pi) > epsilon) { + if (!TOY_IS_FLOAT(returns.literals[0]) || fabs(TOY_AS_FLOAT(returns.literals[0]) - pi) > epsilon) { error("Returned value is incorrect\n"); } - freeLiteralArray(&arguments); - freeLiteralArray(&returns); + Toy_freeLiteralArray(&arguments); + Toy_freeLiteralArray(&returns); } //test makeCounter (closures) { interpreter.printOutput("Testing makeCounter (closures)"); - LiteralArray arguments; - initLiteralArray(&arguments); - LiteralArray returns; - initLiteralArray(&returns); + Toy_LiteralArray arguments; + Toy_initLiteralArray(&arguments); + Toy_LiteralArray returns; + Toy_initLiteralArray(&returns); - callFn(&interpreter, "makeCounter", &arguments, &returns); + Toy_callFn(&interpreter, "makeCounter", &arguments, &returns); //check the results if (arguments.count != 0) { @@ -123,19 +123,19 @@ int main() { } //grab the resulting literal - Literal counter = popLiteralArray(&returns); + Toy_Literal counter = Toy_popLiteralArray(&returns); - freeLiteralArray(&arguments); - freeLiteralArray(&returns); + Toy_freeLiteralArray(&arguments); + Toy_freeLiteralArray(&returns); //call counter repeatedly { - LiteralArray arguments; - initLiteralArray(&arguments); - LiteralArray returns; - initLiteralArray(&returns); + Toy_LiteralArray arguments; + Toy_initLiteralArray(&arguments); + Toy_LiteralArray returns; + Toy_initLiteralArray(&returns); - callLiteralFn(&interpreter, counter, &arguments, &returns); + Toy_callLiteralFn(&interpreter, counter, &arguments, &returns); //check the results if (arguments.count != 0) { @@ -146,21 +146,21 @@ int main() { error("Returns (1) has the wrong number of members\n"); } - if (!IS_INTEGER(returns.literals[0]) || AS_INTEGER(returns.literals[0]) != 1) { + if (!TOY_IS_INTEGER(returns.literals[0]) || TOY_AS_INTEGER(returns.literals[0]) != 1) { error("Returned value (1) is incorrect\n"); } - freeLiteralArray(&arguments); - freeLiteralArray(&returns); + Toy_freeLiteralArray(&arguments); + Toy_freeLiteralArray(&returns); } { - LiteralArray arguments; - initLiteralArray(&arguments); - LiteralArray returns; - initLiteralArray(&returns); + Toy_LiteralArray arguments; + Toy_initLiteralArray(&arguments); + Toy_LiteralArray returns; + Toy_initLiteralArray(&returns); - callLiteralFn(&interpreter, counter, &arguments, &returns); + Toy_callLiteralFn(&interpreter, counter, &arguments, &returns); //check the results if (arguments.count != 0) { @@ -171,21 +171,21 @@ int main() { error("Returns (2) has the wrong number of members\n"); } - if (!IS_INTEGER(returns.literals[0]) || AS_INTEGER(returns.literals[0]) != 2) { + if (!TOY_IS_INTEGER(returns.literals[0]) || TOY_AS_INTEGER(returns.literals[0]) != 2) { error("Returned value (2) is incorrect\n"); } - freeLiteralArray(&arguments); - freeLiteralArray(&returns); + Toy_freeLiteralArray(&arguments); + Toy_freeLiteralArray(&returns); } { - LiteralArray arguments; - initLiteralArray(&arguments); - LiteralArray returns; - initLiteralArray(&returns); + Toy_LiteralArray arguments; + Toy_initLiteralArray(&arguments); + Toy_LiteralArray returns; + Toy_initLiteralArray(&returns); - callLiteralFn(&interpreter, counter, &arguments, &returns); + Toy_callLiteralFn(&interpreter, counter, &arguments, &returns); //check the results if (arguments.count != 0) { @@ -196,36 +196,36 @@ int main() { error("Returns (3) has the wrong number of members\n"); } - if (!IS_INTEGER(returns.literals[0]) || AS_INTEGER(returns.literals[0]) != 3) { + if (!TOY_IS_INTEGER(returns.literals[0]) || TOY_AS_INTEGER(returns.literals[0]) != 3) { error("Returned value (3) is incorrect\n"); } - freeLiteralArray(&arguments); - freeLiteralArray(&returns); + Toy_freeLiteralArray(&arguments); + Toy_freeLiteralArray(&returns); } - freeLiteral(counter); + Toy_freeLiteral(counter); } //test assertion failure { interpreter.printOutput("Testing assertion failure"); - setInterpreterAssert(&interpreter, noPrintFn); + Toy_setInterpreterAssert(&interpreter, noPrintFn); - LiteralArray arguments; - initLiteralArray(&arguments); - LiteralArray returns; - initLiteralArray(&returns); + Toy_LiteralArray arguments; + Toy_initLiteralArray(&arguments); + Toy_LiteralArray returns; + Toy_initLiteralArray(&returns); - bool ret = callFn(&interpreter, "fail", &arguments, &returns); + bool ret = Toy_callFn(&interpreter, "fail", &arguments, &returns); //check the results if (arguments.count != 0) { error("Arguments has the wrong number of members\n"); } - if (returns.count != 1 || !IS_NULL(returns.literals[0])) { + if (returns.count != 1 || !TOY_IS_NULL(returns.literals[0])) { error("Returns has the wrong number of members\n"); } @@ -233,15 +233,15 @@ int main() { error("Assertion gives the wrong return value\n"); } - freeLiteralArray(&arguments); - freeLiteralArray(&returns); + Toy_freeLiteralArray(&arguments); + Toy_freeLiteralArray(&returns); } //clean up - freeInterpreter(&interpreter); + Toy_freeInterpreter(&interpreter); } - printf(NOTICE "All good\n" RESET); + printf(TOY_CC_NOTICE "All good\n" TOY_CC_RESET); return 0; } diff --git a/test/test_compiler.c b/test/test_compiler.c index 54cffcc..0b8e16f 100644 --- a/test/test_compiler.c +++ b/test/test_compiler.c @@ -1,10 +1,10 @@ -#include "lexer.h" -#include "parser.h" -#include "compiler.h" +#include "toy_lexer.h" +#include "toy_parser.h" +#include "toy_compiler.h" -#include "console_colors.h" +#include "toy_console_colors.h" -#include "memory.h" +#include "toy_memory.h" #include "../repl/repl_tools.h" @@ -15,9 +15,9 @@ int main() { { //test init & free - Compiler compiler; - initCompiler(&compiler); - freeCompiler(&compiler); + Toy_Compiler compiler; + Toy_initCompiler(&compiler); + Toy_freeCompiler(&compiler); } { @@ -25,70 +25,70 @@ int main() { char* source = "print null;"; //test basic compilation & collation - Lexer lexer; - Parser parser; - Compiler compiler; + Toy_Lexer lexer; + Toy_Parser parser; + Toy_Compiler compiler; - initLexer(&lexer, source); - initParser(&parser, &lexer); - initCompiler(&compiler); + Toy_initLexer(&lexer, source); + Toy_initParser(&parser, &lexer); + Toy_initCompiler(&compiler); - ASTNode* node = scanParser(&parser); + Toy_ASTNode* node = Toy_scanParser(&parser); //write - writeCompiler(&compiler, node); + Toy_writeCompiler(&compiler, node); //collate int size = 0; - unsigned char* bytecode = collateCompiler(&compiler, &size); + unsigned char* bytecode = Toy_collateCompiler(&compiler, &size); //cleanup - FREE_ARRAY(unsigned char, bytecode, size); - freeASTNode(node); - freeParser(&parser); - freeCompiler(&compiler); + TOY_FREE_ARRAY(unsigned char, bytecode, size); + Toy_freeASTNode(node); + Toy_freeParser(&parser); + Toy_freeCompiler(&compiler); } { //source size_t sourceLength = 0; - char* source = readFile("scripts/compiler_sample_code.toy", &sourceLength); + char* source = Toy_readFile("scripts/compiler_sample_code.toy", &sourceLength); //test basic compilation & collation - Lexer lexer; - Parser parser; - Compiler compiler; + Toy_Lexer lexer; + Toy_Parser parser; + Toy_Compiler compiler; - initLexer(&lexer, source); - initParser(&parser, &lexer); - initCompiler(&compiler); + Toy_initLexer(&lexer, source); + Toy_initParser(&parser, &lexer); + Toy_initCompiler(&compiler); - ASTNode* node = scanParser(&parser); + Toy_ASTNode* node = Toy_scanParser(&parser); while (node != NULL) { - if (node->type == AST_NODE_ERROR) { - fprintf(stderr, ERROR "ERROR: Error node found" RESET); + if (node->type == TOY_AST_NODE_ERROR) { + fprintf(stderr, TOY_CC_ERROR "ERROR: Error node found" TOY_CC_RESET); return -1; } //write - writeCompiler(&compiler, node); - freeASTNode(node); + Toy_writeCompiler(&compiler, node); + Toy_freeASTNode(node); - node = scanParser(&parser); + node = Toy_scanParser(&parser); } //collate int size = 0; - unsigned char* bytecode = collateCompiler(&compiler, &size); + unsigned char* bytecode = Toy_collateCompiler(&compiler, &size); //cleanup - FREE_ARRAY(char, source, sourceLength); - FREE_ARRAY(unsigned char, bytecode, size); - freeParser(&parser); - freeCompiler(&compiler); + TOY_FREE_ARRAY(char, source, sourceLength); + TOY_FREE_ARRAY(unsigned char, bytecode, size); + Toy_freeParser(&parser); + Toy_freeCompiler(&compiler); } - printf(NOTICE "All good\n" RESET); + printf(TOY_CC_NOTICE "All good\n" TOY_CC_RESET); return 0; } diff --git a/test/test_interpreter.c b/test/test_interpreter.c index b41fece..7e06580 100644 --- a/test/test_interpreter.c +++ b/test/test_interpreter.c @@ -1,11 +1,11 @@ -#include "lexer.h" -#include "parser.h" -#include "compiler.h" -#include "interpreter.h" +#include "toy_lexer.h" +#include "toy_parser.h" +#include "toy_compiler.h" +#include "toy_interpreter.h" -#include "console_colors.h" +#include "toy_console_colors.h" -#include "memory.h" +#include "toy_memory.h" #include "../repl/repl_tools.h" @@ -24,27 +24,27 @@ static void noAssertFn(const char* output) { ignoredAssertions++; } else { - fprintf(stderr, ERROR "Assertion failure: "); + fprintf(stderr, TOY_CC_ERROR "Assertion failure: "); fprintf(stderr, "%s", output); - fprintf(stderr, "\n" RESET); //default new line + fprintf(stderr, "\n" TOY_CC_RESET); //default new line } } void runBinaryCustom(unsigned char* tb, size_t size) { - Interpreter interpreter; - initInterpreter(&interpreter); + Toy_Interpreter interpreter; + Toy_initInterpreter(&interpreter); //NOTE: suppress print output for testing - setInterpreterPrint(&interpreter, noPrintFn); - setInterpreterAssert(&interpreter, noAssertFn); + Toy_setInterpreterPrint(&interpreter, noPrintFn); + Toy_setInterpreterAssert(&interpreter, noAssertFn); - runInterpreter(&interpreter, tb, size); - freeInterpreter(&interpreter); + Toy_runInterpreter(&interpreter, tb, size); + Toy_freeInterpreter(&interpreter); } void runSourceCustom(char* source) { size_t size = 0; - unsigned char* tb = compileString(source, &size); + unsigned char* tb = Toy_compileString(source, &size); if (!tb) { return; } @@ -53,7 +53,7 @@ void runSourceCustom(char* source) { void runSourceFileCustom(char* fname) { size_t size = 0; //not used - char* source = readFile(fname, &size); + char* source = Toy_readFile(fname, &size); runSourceCustom(source); free((void*)source); } @@ -61,9 +61,9 @@ void runSourceFileCustom(char* fname) { int main() { { //test init & free - Interpreter interpreter; - initInterpreter(&interpreter); - freeInterpreter(&interpreter); + Toy_Interpreter interpreter; + Toy_initInterpreter(&interpreter); + Toy_freeInterpreter(&interpreter); } { @@ -71,37 +71,37 @@ int main() { char* source = "print null;"; //test basic compilation & collation - Lexer lexer; - Parser parser; - Compiler compiler; - Interpreter interpreter; + Toy_Lexer lexer; + Toy_Parser parser; + Toy_Compiler compiler; + Toy_Interpreter interpreter; - initLexer(&lexer, source); - initParser(&parser, &lexer); - initCompiler(&compiler); - initInterpreter(&interpreter); + Toy_initLexer(&lexer, source); + Toy_initParser(&parser, &lexer); + Toy_initCompiler(&compiler); + Toy_initInterpreter(&interpreter); - ASTNode* node = scanParser(&parser); + Toy_ASTNode* node = Toy_scanParser(&parser); //write - writeCompiler(&compiler, node); + Toy_writeCompiler(&compiler, node); //collate int size = 0; - unsigned char* bytecode = collateCompiler(&compiler, &size); + unsigned char* bytecode = Toy_collateCompiler(&compiler, &size); //NOTE: suppress print output for testing - setInterpreterPrint(&interpreter, noPrintFn); - setInterpreterAssert(&interpreter, noAssertFn); + Toy_setInterpreterPrint(&interpreter, noPrintFn); + Toy_setInterpreterAssert(&interpreter, noAssertFn); //run - runInterpreter(&interpreter, bytecode, size); + Toy_runInterpreter(&interpreter, bytecode, size); //cleanup - freeASTNode(node); - freeParser(&parser); - freeCompiler(&compiler); - freeInterpreter(&interpreter); + Toy_freeASTNode(node); + Toy_freeParser(&parser); + Toy_freeCompiler(&compiler); + Toy_freeInterpreter(&interpreter); } { @@ -144,11 +144,11 @@ int main() { //1, to allow for the assertion test if (ignoredAssertions > 1) { - fprintf(stderr, ERROR "Assertions hidden: %d\n", ignoredAssertions); + fprintf(stderr, TOY_CC_ERROR "Assertions hidden: %d\n", ignoredAssertions); return -1; } - printf(NOTICE "All good\n" RESET); + printf(TOY_CC_NOTICE "All good\n" TOY_CC_RESET); return 0; } diff --git a/test/test_lexer.c b/test/test_lexer.c index 334fe53..41bd34c 100644 --- a/test/test_lexer.c +++ b/test/test_lexer.c @@ -1,6 +1,6 @@ -#include "lexer.h" +#include "toy_lexer.h" -#include "console_colors.h" +#include "toy_console_colors.h" #include #include @@ -11,39 +11,39 @@ int main() { char* source = "print null;"; //test init & quit - Lexer lexer; - initLexer(&lexer, source); + Toy_Lexer lexer; + Toy_initLexer(&lexer, source); //get each token - Token print = scanLexer(&lexer); - Token null = scanLexer(&lexer); - Token semi = scanLexer(&lexer); - Token eof = scanLexer(&lexer); + Toy_Token print = Toy_scanLexer(&lexer); + Toy_Token null = Toy_scanLexer(&lexer); + Toy_Token semi = Toy_scanLexer(&lexer); + Toy_Token eof = Toy_scanLexer(&lexer); //test each token is correct if (strncmp(print.lexeme, "print", print.length)) { - fprintf(stderr, ERROR "ERROR: print lexeme is wrong: %s" RESET, print.lexeme); + fprintf(stderr, TOY_CC_ERROR "ERROR: print lexeme is wrong: %s" TOY_CC_RESET, print.lexeme); return -1; } if (strncmp(null.lexeme, "null", null.length)) { - fprintf(stderr, ERROR "ERROR: null lexeme is wrong: %s" RESET, null.lexeme); + fprintf(stderr, TOY_CC_ERROR "ERROR: null lexeme is wrong: %s" TOY_CC_RESET, null.lexeme); return -1; } if (strncmp(semi.lexeme, ";", semi.length)) { - fprintf(stderr, ERROR "ERROR: semicolon lexeme is wrong: %s" RESET, semi.lexeme); + fprintf(stderr, TOY_CC_ERROR "ERROR: semicolon lexeme is wrong: %s" TOY_CC_RESET, semi.lexeme); return -1; } - if (eof.type != TOKEN_EOF) { - fprintf(stderr, ERROR "ERROR: Failed to find EOF token" RESET); + if (eof.type != TOY_TOKEN_EOF) { + fprintf(stderr, TOY_CC_ERROR "ERROR: Failed to find EOF token" TOY_CC_RESET); return -1; } } - printf(NOTICE "All good\n" RESET); + printf(TOY_CC_NOTICE "All good\n" TOY_CC_RESET); return 0; } diff --git a/test/test_libraries.c b/test/test_libraries.c index bb40aba..6413c20 100644 --- a/test/test_libraries.c +++ b/test/test_libraries.c @@ -1,11 +1,11 @@ -#include "lexer.h" -#include "parser.h" -#include "compiler.h" -#include "interpreter.h" +#include "toy_lexer.h" +#include "toy_parser.h" +#include "toy_compiler.h" +#include "toy_interpreter.h" -#include "console_colors.h" +#include "toy_console_colors.h" -#include "memory.h" +#include "toy_memory.h" #include #include @@ -25,57 +25,57 @@ static void noPrintFn(const char* output) { static int failedAsserts = 0; static void assertWrapper(const char* output) { failedAsserts++; - fprintf(stderr, ERROR "Assertion failure: "); + fprintf(stderr, TOY_CC_ERROR "Assertion failure: "); fprintf(stderr, "%s", output); - fprintf(stderr, "\n" RESET); //default new line + fprintf(stderr, "\n" TOY_CC_RESET); //default new line } static void errorWrapper(const char* output) { failedAsserts++; - fprintf(stderr, ERROR "%s" RESET, output); + fprintf(stderr, TOY_CC_ERROR "%s" TOY_CC_RESET, output); } -void runBinaryWithLibrary(unsigned char* tb, size_t size, char* library, HookFn hook) { - Interpreter interpreter; - initInterpreter(&interpreter); +void runBinaryWithLibrary(unsigned char* tb, size_t size, char* library, Toy_HookFn hook) { + Toy_Interpreter interpreter; + Toy_initInterpreter(&interpreter); //NOTE: supress print output for testing - setInterpreterPrint(&interpreter, noPrintFn); - setInterpreterAssert(&interpreter, assertWrapper); - setInterpreterError(&interpreter, errorWrapper); + Toy_setInterpreterPrint(&interpreter, noPrintFn); + Toy_setInterpreterAssert(&interpreter, assertWrapper); + Toy_setInterpreterError(&interpreter, errorWrapper); //inject the standard libraries into this interpreter - injectNativeHook(&interpreter, library, hook); + Toy_injectNativeHook(&interpreter, library, hook); - runInterpreter(&interpreter, tb, size); - freeInterpreter(&interpreter); + Toy_runInterpreter(&interpreter, tb, size); + Toy_freeInterpreter(&interpreter); } typedef struct Payload { char* fname; char* libname; - HookFn hook; + Toy_HookFn hook; } Payload; int main() { //setup the runner filesystem (hacky) - initDriveDictionary(); + Toy_initDriveDictionary(); - Literal driveLiteral = TO_STRING_LITERAL(createRefString("scripts")); - Literal pathLiteral = TO_STRING_LITERAL(createRefString("scripts")); + Toy_Literal driveLiteral = TOY_TO_STRING_LITERAL(Toy_createRefString("scripts")); + Toy_Literal pathLiteral = TOY_TO_STRING_LITERAL(Toy_createRefString("scripts")); - setLiteralDictionary(getDriveDictionary(), driveLiteral, pathLiteral); + Toy_setLiteralDictionary(Toy_getDriveDictionary(), driveLiteral, pathLiteral); - freeLiteral(driveLiteral); - freeLiteral(pathLiteral); + Toy_freeLiteral(driveLiteral); + Toy_freeLiteral(pathLiteral); { //run each file in test/scripts Payload payloads[] = { - {"interactions.toy", "standard", hookStandard}, //interactions needs standard - {"standard.toy", "standard", hookStandard}, - {"timer.toy", "timer", hookTimer}, - {"runner.toy", "runner", hookRunner}, + {"interactions.toy", "standard", Toy_hookStandard}, //interactions needs standard + {"standard.toy", "standard", Toy_hookStandard}, + {"timer.toy", "timer", Toy_hookTimer}, + {"runner.toy", "runner", Toy_hookRunner}, {NULL, NULL, NULL} }; @@ -87,18 +87,18 @@ int main() { //compile the source size_t size = 0; - char* source = readFile(fname, &size); + char* source = Toy_readFile(fname, &size); if (!source) { - printf(ERROR "Failed to load file: %s\n" RESET, fname); + printf(TOY_CC_ERROR "Failed to load file: %s\n" TOY_CC_RESET, fname); failedAsserts++; continue; } - unsigned char* tb = compileString(source, &size); + unsigned char* tb = Toy_compileString(source, &size); free((void*)source); if (!tb) { - printf(ERROR "Failed to compile file: %s\n" RESET, fname); + printf(TOY_CC_ERROR "Failed to compile file: %s\n" TOY_CC_RESET, fname); failedAsserts++; continue; } @@ -108,13 +108,13 @@ int main() { } //lib cleanup - freeDriveDictionary(); + Toy_freeDriveDictionary(); if (!failedAsserts) { - printf(NOTICE "All good\n" RESET); + printf(TOY_CC_NOTICE "All good\n" TOY_CC_RESET); } else { - printf(WARN "Problems detected in libraries\n" RESET); + printf(TOY_CC_WARN "Problems detected in libraries\n" TOY_CC_RESET); } return failedAsserts; diff --git a/test/test_literal.c b/test/test_literal.c index 08c5df4..30aa083 100644 --- a/test/test_literal.c +++ b/test/test_literal.c @@ -1,28 +1,28 @@ -#include "literal.h" +#include "toy_literal.h" -#include "memory.h" -#include "console_colors.h" +#include "toy_memory.h" +#include "toy_console_colors.h" #include int main() { { //test a single null literal - Literal literal = TO_NULL_LITERAL; + Toy_Literal literal = TOY_TO_NULL_LITERAL; - if (!IS_NULL(literal)) { - fprintf(stderr, ERROR "ERROR: null literal failed\n" RESET); + if (!TOY_IS_NULL(literal)) { + fprintf(stderr, TOY_CC_ERROR "ERROR: null literal failed\n" TOY_CC_RESET); return -1; } } { //test boolean literals - Literal t = TO_BOOLEAN_LITERAL(true); - Literal f = TO_BOOLEAN_LITERAL(false); + Toy_Literal t = TOY_TO_BOOLEAN_LITERAL(true); + Toy_Literal f = TOY_TO_BOOLEAN_LITERAL(false); - if (!IS_TRUTHY(t) || IS_TRUTHY(f)) { - fprintf(stderr, ERROR "ERROR: boolean literal failed\n" RESET); + if (!TOY_IS_TRUTHY(t) || TOY_IS_TRUTHY(f)) { + fprintf(stderr, TOY_CC_ERROR "ERROR: boolean literal failed\n" TOY_CC_RESET); return -1; } } @@ -31,20 +31,20 @@ int main() { //test string literals char* buffer = "Hello world"; - Literal literal = TO_STRING_LITERAL(createRefString(buffer)); + Toy_Literal literal = TOY_TO_STRING_LITERAL(Toy_createRefString(buffer)); - freeLiteral(literal); + Toy_freeLiteral(literal); } { //test identifier literals char buffer[] = "Hello world"; - Literal literal = TO_IDENTIFIER_LITERAL(createRefString(buffer)); + Toy_Literal literal = TOY_TO_IDENTIFIER_LITERAL(Toy_createRefString(buffer)); - freeLiteral(literal); + Toy_freeLiteral(literal); } - printf(NOTICE "All good\n" RESET); + printf(TOY_CC_NOTICE "All good\n" TOY_CC_RESET); return 0; } diff --git a/test/test_literal_array.c b/test/test_literal_array.c index 9649b57..a8063c5 100644 --- a/test/test_literal_array.c +++ b/test/test_literal_array.c @@ -1,72 +1,72 @@ -#include "literal_array.h" +#include "toy_literal_array.h" -#include "memory.h" -#include "console_colors.h" +#include "toy_memory.h" +#include "toy_console_colors.h" #include int main() { { //test init & cleanup - LiteralArray array; - initLiteralArray(&array); - freeLiteralArray(&array); + Toy_LiteralArray array; + Toy_initLiteralArray(&array); + Toy_freeLiteralArray(&array); } { //test pushing and pulling - LiteralArray array; - initLiteralArray(&array); + Toy_LiteralArray array; + Toy_initLiteralArray(&array); for (int i = 0; i < 100; i++) { - pushLiteralArray(&array, TO_INTEGER_LITERAL(i)); + Toy_pushLiteralArray(&array, TOY_TO_INTEGER_LITERAL(i)); } for (int i = 0; i < 90; i++) { - Literal lit = popLiteralArray(&array); + Toy_Literal lit = Toy_popLiteralArray(&array); - freeLiteral(lit); + Toy_freeLiteral(lit); } if (array.count != 10) { - fprintf(stderr, ERROR "ERROR: Array didn't clear the correct number of literal integers\n" RESET); - freeLiteralArray(&array); + fprintf(stderr, TOY_CC_ERROR "ERROR: Array didn't clear the correct number of literal integers\n" TOY_CC_RESET); + Toy_freeLiteralArray(&array); return -1; } - freeLiteralArray(&array); + Toy_freeLiteralArray(&array); } { //check string, identifier and compound type behaviours - LiteralArray array; - initLiteralArray(&array); + Toy_LiteralArray array; + Toy_initLiteralArray(&array); //raw char* str_raw = "hello world"; char* idn_raw = "foobar"; - Literal string = TO_STRING_LITERAL(createRefString(str_raw)); - Literal identifier = TO_IDENTIFIER_LITERAL(createRefString(idn_raw)); + Toy_Literal string = TOY_TO_STRING_LITERAL(Toy_createRefString(str_raw)); + Toy_Literal identifier = TOY_TO_IDENTIFIER_LITERAL(Toy_createRefString(idn_raw)); //[string : string] - Literal type = TO_TYPE_LITERAL(LITERAL_DICTIONARY, false); - TYPE_PUSH_SUBTYPE(&type, TO_TYPE_LITERAL(LITERAL_STRING, false)); - TYPE_PUSH_SUBTYPE(&type, TO_TYPE_LITERAL(LITERAL_STRING, false)); + Toy_Literal type = TOY_TO_TYPE_LITERAL(TOY_LITERAL_DICTIONARY, false); + TOY_TYPE_PUSH_SUBTYPE(&type, TOY_TO_TYPE_LITERAL(TOY_LITERAL_STRING, false)); + TOY_TYPE_PUSH_SUBTYPE(&type, TOY_TO_TYPE_LITERAL(TOY_LITERAL_STRING, false)); //push - pushLiteralArray(&array, string); - pushLiteralArray(&array, identifier); - pushLiteralArray(&array, type); + Toy_pushLiteralArray(&array, string); + Toy_pushLiteralArray(&array, identifier); + Toy_pushLiteralArray(&array, type); //free the local literals - freeLiteral(string); - freeLiteral(identifier); - freeLiteral(type); + Toy_freeLiteral(string); + Toy_freeLiteral(identifier); + Toy_freeLiteral(type); - freeLiteralArray(&array); + Toy_freeLiteralArray(&array); } - printf(NOTICE "All good\n" RESET); + printf(TOY_CC_NOTICE "All good\n" TOY_CC_RESET); return 0; } diff --git a/test/test_literal_dictionary.c b/test/test_literal_dictionary.c index 77f6f20..32a031e 100644 --- a/test/test_literal_dictionary.c +++ b/test/test_literal_dictionary.c @@ -1,16 +1,16 @@ -#include "literal_dictionary.h" +#include "toy_literal_dictionary.h" -#include "memory.h" -#include "console_colors.h" +#include "toy_memory.h" +#include "toy_console_colors.h" #include int main() { { //test init & cleanup - LiteralDictionary dictionary; - initLiteralDictionary(&dictionary); - freeLiteralDictionary(&dictionary); + Toy_LiteralDictionary dictionary; + Toy_initLiteralDictionary(&dictionary); + Toy_freeLiteralDictionary(&dictionary); } { @@ -18,21 +18,21 @@ int main() { char* idn_raw = "foobar"; char* str_raw = "hello world"; - Literal identifier = TO_IDENTIFIER_LITERAL(createRefString(idn_raw)); - Literal string = TO_STRING_LITERAL(createRefString(str_raw)); + Toy_Literal identifier = TOY_TO_IDENTIFIER_LITERAL(Toy_createRefString(idn_raw)); + Toy_Literal string = TOY_TO_STRING_LITERAL(Toy_createRefString(str_raw)); - LiteralDictionary dictionary; - initLiteralDictionary(&dictionary); + Toy_LiteralDictionary dictionary; + Toy_initLiteralDictionary(&dictionary); - setLiteralDictionary(&dictionary, identifier, string); + Toy_setLiteralDictionary(&dictionary, identifier, string); - freeLiteral(identifier); - freeLiteral(string); + Toy_freeLiteral(identifier); + Toy_freeLiteral(string); - freeLiteralDictionary(&dictionary); + Toy_freeLiteralDictionary(&dictionary); } - printf(NOTICE "All good\n" RESET); + printf(TOY_CC_NOTICE "All good\n" TOY_CC_RESET); return 0; } diff --git a/test/test_memory.c b/test/test_memory.c index 4ef503b..878a020 100644 --- a/test/test_memory.c +++ b/test/test_memory.c @@ -1,6 +1,6 @@ -#include "memory.h" +#include "toy_memory.h" -#include "console_colors.h" +#include "toy_console_colors.h" #include #include @@ -32,29 +32,29 @@ void* allocator(void* pointer, size_t oldSize, size_t newSize) { void testMemoryAllocation() { { //test single pointer - int* integer = ALLOCATE(int, 1); - FREE(int, integer); + int* integer = TOY_ALLOCATE(int, 1); + TOY_FREE(int, integer); } { //test single pointer array - int* array = ALLOCATE(int, 10); + int* array = TOY_ALLOCATE(int, 10); array[1] = 42; //access the given memory - FREE_ARRAY(int, array, 10); + TOY_FREE_ARRAY(int, array, 10); } { //test multiple pointer arrays - int* array1 = ALLOCATE(int, 10); - int* array2 = ALLOCATE(int, 10); + int* array1 = TOY_ALLOCATE(int, 10); + int* array2 = TOY_ALLOCATE(int, 10); array1[1] = 42; //access the given memory array2[1] = 42; //access the given memory - FREE_ARRAY(int, array1, 10); - FREE_ARRAY(int, array2, 10); + TOY_FREE_ARRAY(int, array1, 10); + TOY_FREE_ARRAY(int, array2, 10); } } @@ -63,14 +63,14 @@ int main() { testMemoryAllocation(); //test the custom allocator - setMemoryAllocator(allocator); + Toy_setMemoryAllocator(allocator); testMemoryAllocation(); if (callCount != 8) { - fprintf(stderr, ERROR "Unexpected call count for custom allocator; was called %d times" RESET, callCount); + fprintf(stderr, TOY_CC_ERROR "Unexpected call count for custom allocator; was called %d times" TOY_CC_RESET, callCount); return -1; } - printf(NOTICE "All good\n" RESET); + printf(TOY_CC_NOTICE "All good\n" TOY_CC_RESET); return 0; } diff --git a/test/test_mustfail.c b/test/test_mustfail.c index a1ab29f..087bcf7 100644 --- a/test/test_mustfail.c +++ b/test/test_mustfail.c @@ -1,11 +1,11 @@ -#include "lexer.h" -#include "parser.h" -#include "compiler.h" -#include "interpreter.h" +#include "toy_lexer.h" +#include "toy_parser.h" +#include "toy_compiler.h" +#include "toy_interpreter.h" -#include "console_colors.h" +#include "toy_console_colors.h" -#include "memory.h" +#include "toy_memory.h" #include "../repl/repl_tools.h" @@ -24,37 +24,37 @@ static void noErrorFn(const char* output) { } unsigned char* compileStringCustom(char* source, size_t* size) { - Lexer lexer; - Parser parser; - Compiler compiler; + Toy_Lexer lexer; + Toy_Parser parser; + Toy_Compiler compiler; - initLexer(&lexer, source); - initParser(&parser, &lexer); - initCompiler(&compiler); + Toy_initLexer(&lexer, source); + Toy_initParser(&parser, &lexer); + Toy_initCompiler(&compiler); //run the parser until the end of the source - ASTNode* node = scanParser(&parser); + Toy_ASTNode* node = Toy_scanParser(&parser); while(node != NULL) { //pack up and leave - if (node->type == AST_NODE_ERROR) { + if (node->type == TOY_AST_NODE_ERROR) { errorsTriggered++; //custom error catch - freeASTNode(node); - freeCompiler(&compiler); - freeParser(&parser); + Toy_freeASTNode(node); + Toy_freeCompiler(&compiler); + Toy_freeParser(&parser); return NULL; } - writeCompiler(&compiler, node); - freeASTNode(node); - node = scanParser(&parser); + Toy_writeCompiler(&compiler, node); + Toy_freeASTNode(node); + node = Toy_scanParser(&parser); } //get the bytecode dump - unsigned char* tb = collateCompiler(&compiler, (int*)(size)); + unsigned char* tb = Toy_collateCompiler(&compiler, (int*)(size)); //cleanup - freeCompiler(&compiler); - freeParser(&parser); + Toy_freeCompiler(&compiler); + Toy_freeParser(&parser); //no lexer to clean up //finally @@ -62,15 +62,15 @@ unsigned char* compileStringCustom(char* source, size_t* size) { } void runBinaryCustom(unsigned char* tb, size_t size) { - Interpreter interpreter; - initInterpreter(&interpreter); + Toy_Interpreter interpreter; + Toy_initInterpreter(&interpreter); //NOTE: suppress print output for testing - setInterpreterPrint(&interpreter, noPrintFn); - setInterpreterError(&interpreter, noErrorFn); + Toy_setInterpreterPrint(&interpreter, noPrintFn); + Toy_setInterpreterError(&interpreter, noErrorFn); - runInterpreter(&interpreter, tb, size); - freeInterpreter(&interpreter); + Toy_runInterpreter(&interpreter, tb, size); + Toy_freeInterpreter(&interpreter); } void runSourceCustom(char* source) { @@ -84,7 +84,7 @@ void runSourceCustom(char* source) { void runSourceFileCustom(char* fname) { size_t size = 0; //not used - char* source = readFile(fname, &size); + char* source = Toy_readFile(fname, &size); runSourceCustom(source); free((void*)source); } @@ -114,7 +114,7 @@ int main() { runSourceFileCustom(buffer); if (errorsTriggered == 0) { - printf(ERROR "Expected error did not occur in %s\n" RESET, filenames[i]); + printf(TOY_CC_ERROR "Expected error did not occur in %s\n" TOY_CC_RESET, filenames[i]); success = false; } @@ -126,7 +126,7 @@ int main() { return -1; } - printf(NOTICE "All good\n" RESET); + printf(TOY_CC_NOTICE "All good\n" TOY_CC_RESET); return 0; } diff --git a/test/test_opaque_data_type.c b/test/test_opaque_data_type.c index eec546f..64a314e 100644 --- a/test/test_opaque_data_type.c +++ b/test/test_opaque_data_type.c @@ -1,11 +1,11 @@ -#include "lexer.h" -#include "parser.h" -#include "compiler.h" -#include "interpreter.h" +#include "toy_lexer.h" +#include "toy_parser.h" +#include "toy_compiler.h" +#include "toy_interpreter.h" -#include "console_colors.h" +#include "toy_console_colors.h" -#include "memory.h" +#include "toy_memory.h" #include "../repl/repl_tools.h" @@ -27,39 +27,39 @@ typedef struct ArbitraryData { int value; } ArbitraryData; -static int produce(Interpreter* interpreter, LiteralArray* arguments) { - ArbitraryData* data = ALLOCATE(ArbitraryData, 1); +static int produce(Toy_Interpreter* interpreter, Toy_LiteralArray* arguments) { + ArbitraryData* data = TOY_ALLOCATE(ArbitraryData, 1); data->value = 42; - Literal o = TO_OPAQUE_LITERAL(data, 0); + Toy_Literal o = TOY_TO_OPAQUE_LITERAL(data, 0); - pushLiteralArray(&interpreter->stack, o); + Toy_pushLiteralArray(&interpreter->stack, o); - freeLiteral(o); + Toy_freeLiteral(o); return 1; } -static int consume(Interpreter* interpreter, LiteralArray* arguments) { - Literal o = popLiteralArray(arguments); +static int consume(Toy_Interpreter* interpreter, Toy_LiteralArray* arguments) { + Toy_Literal o = Toy_popLiteralArray(arguments); - Literal idn = o; + Toy_Literal idn = o; - if (parseIdentifierToValue(interpreter, &o)) { - freeLiteral(idn); + if (Toy_parseIdentifierToValue(interpreter, &o)) { + Toy_freeLiteral(idn); } - if (IS_OPAQUE(o) && ((ArbitraryData*)(AS_OPAQUE(o)))->value == 42) { - ArbitraryData* data = (ArbitraryData*)AS_OPAQUE(o); + if (TOY_IS_OPAQUE(o) && ((ArbitraryData*)(TOY_AS_OPAQUE(o)))->value == 42) { + ArbitraryData* data = (ArbitraryData*)TOY_AS_OPAQUE(o); - FREE(ArbitraryData, data); + TOY_FREE(ArbitraryData, data); //all went well - freeLiteral(o); + Toy_freeLiteral(o); return 0; } - printf(ERROR "opaque failed: %d\n" RESET, IS_OPAQUE(o)); + printf(TOY_CC_ERROR "opaque failed: %d\n" TOY_CC_RESET, TOY_IS_OPAQUE(o)); exit(-1); return -1; @@ -68,28 +68,28 @@ static int consume(Interpreter* interpreter, LiteralArray* arguments) { int main() { { size_t size = 0; - char* source = readFile("scripts/opaque-data-type.toy", &size); - unsigned char* tb = compileString(source, &size); + char* source = Toy_readFile("scripts/opaque-data-type.toy", &size); + unsigned char* tb = Toy_compileString(source, &size); free((void*)source); if (!tb) { return -1; } - Interpreter interpreter; - initInterpreter(&interpreter); + Toy_Interpreter interpreter; + Toy_initInterpreter(&interpreter); - injectNativeFn(&interpreter, "produce", produce); - injectNativeFn(&interpreter, "consume", consume); + Toy_injectNativeFn(&interpreter, "produce", produce); + Toy_injectNativeFn(&interpreter, "consume", consume); //run teh script - runInterpreter(&interpreter, tb, size); + Toy_runInterpreter(&interpreter, tb, size); //clean up - freeInterpreter(&interpreter); + Toy_freeInterpreter(&interpreter); } - printf(NOTICE "All good\n" RESET); + printf(TOY_CC_NOTICE "All good\n" TOY_CC_RESET); return 0; } diff --git a/test/test_parser.c b/test/test_parser.c index b7aaa22..65b518c 100644 --- a/test/test_parser.c +++ b/test/test_parser.c @@ -1,6 +1,6 @@ -#include "parser.h" +#include "toy_parser.h" -#include "console_colors.h" +#include "toy_console_colors.h" #include "../repl/repl_tools.h" @@ -14,12 +14,12 @@ int main() { char* source = "print null;"; //test init & quit - Lexer lexer; - Parser parser; - initLexer(&lexer, source); - initParser(&parser, &lexer); + Toy_Lexer lexer; + Toy_Parser parser; + Toy_initLexer(&lexer, source); + Toy_initParser(&parser, &lexer); - freeParser(&parser); + Toy_freeParser(&parser); } { @@ -27,63 +27,63 @@ int main() { char* source = "print null;"; //test parsing - Lexer lexer; - Parser parser; - initLexer(&lexer, source); - initParser(&parser, &lexer); + Toy_Lexer lexer; + Toy_Parser parser; + Toy_initLexer(&lexer, source); + Toy_initParser(&parser, &lexer); - ASTNode* node = scanParser(&parser); + Toy_ASTNode* node = Toy_scanParser(&parser); //inspect the node if (node == NULL) { - fprintf(stderr, ERROR "ERROR: ASTNode is null" RESET); + fprintf(stderr, TOY_CC_ERROR "ERROR: ASTNode is null" TOY_CC_RESET); return -1; } - if (node->type != AST_NODE_UNARY || node->unary.opcode != OP_PRINT) { - fprintf(stderr, ERROR "ERROR: ASTNode is not a unary print instruction" RESET); + if (node->type != TOY_AST_NODE_UNARY || node->unary.opcode != TOY_OP_PRINT) { + fprintf(stderr, TOY_CC_ERROR "ERROR: ASTNode is not a unary print instruction" TOY_CC_RESET); return -1; } - if (node->unary.child->type != AST_NODE_LITERAL || !IS_NULL(node->unary.child->atomic.literal)) { - fprintf(stderr, ERROR "ERROR: ASTNode to be printed is not a null literal" RESET); + if (node->unary.child->type != TOY_AST_NODE_LITERAL || !TOY_IS_NULL(node->unary.child->atomic.literal)) { + fprintf(stderr, TOY_CC_ERROR "ERROR: ASTNode to be printed is not a null literal" TOY_CC_RESET); return -1; } //cleanup - freeASTNode(node); - freeParser(&parser); + Toy_freeASTNode(node); + Toy_freeParser(&parser); } { //get the source file size_t size = 0; - char* source = readFile("scripts/parser_sample_code.toy", &size); + char* source = Toy_readFile("scripts/parser_sample_code.toy", &size); //test parsing a chunk of junk (valgrind will find leaks) - Lexer lexer; - Parser parser; - initLexer(&lexer, source); - initParser(&parser, &lexer); + Toy_Lexer lexer; + Toy_Parser parser; + Toy_initLexer(&lexer, source); + Toy_initParser(&parser, &lexer); - ASTNode* node = scanParser(&parser); + Toy_ASTNode* node = Toy_scanParser(&parser); while (node != NULL) { - if (node->type == AST_NODE_ERROR) { - fprintf(stderr, ERROR "ERROR: Error node detected" RESET); + if (node->type == TOY_AST_NODE_ERROR) { + fprintf(stderr, TOY_CC_ERROR "ERROR: Error node detected" TOY_CC_RESET); return -1; } - freeASTNode(node); - node = scanParser(&parser); + Toy_freeASTNode(node); + node = Toy_scanParser(&parser); } //cleanup - freeParser(&parser); + Toy_freeParser(&parser); free((void*)source); } - printf(NOTICE "All good\n" RESET); + printf(TOY_CC_NOTICE "All good\n" TOY_CC_RESET); return 0; } diff --git a/test/test_scope.c b/test/test_scope.c index bdafcf5..102a99c 100644 --- a/test/test_scope.c +++ b/test/test_scope.c @@ -1,124 +1,124 @@ -#include "scope.h" +#include "toy_scope.h" -#include "memory.h" -#include "console_colors.h" +#include "toy_memory.h" +#include "toy_console_colors.h" #include int main() { { //test init & quit - Scope* scope = pushScope(NULL); - scope = popScope(scope); + Toy_Scope* scope = Toy_pushScope(NULL); + scope = Toy_popScope(scope); } { //prerequisites char* idn_raw = "foobar"; - Literal identifier = TO_IDENTIFIER_LITERAL(createRefString(idn_raw)); - Literal value = TO_INTEGER_LITERAL(42); - Literal type = TO_TYPE_LITERAL(value.type, false); + Toy_Literal identifier = TOY_TO_IDENTIFIER_LITERAL(Toy_createRefString(idn_raw)); + Toy_Literal value = TOY_TO_INTEGER_LITERAL(42); + Toy_Literal type = TOY_TO_TYPE_LITERAL(value.type, false); //test declarations & assignments - Scope* scope = pushScope(NULL); + Toy_Scope* scope = Toy_pushScope(NULL); //declare & assign - if (!declareScopeVariable(scope, identifier, type)) { - printf(ERROR "Failed to declare scope variable" RESET); + if (!Toy_declareScopeVariable(scope, identifier, type)) { + printf(TOY_CC_ERROR "Failed to declare scope variable" TOY_CC_RESET); return -1; } - if (!setScopeVariable(scope, identifier, value, true)) { - printf(ERROR "Failed to sete scope variable" RESET); + if (!Toy_setScopeVariable(scope, identifier, value, true)) { + printf(TOY_CC_ERROR "Failed to sete scope variable" TOY_CC_RESET); return -1; } //cleanup - scope = popScope(scope); + scope = Toy_popScope(scope); - freeLiteral(identifier); - freeLiteral(value); - freeLiteral(type); + Toy_freeLiteral(identifier); + Toy_freeLiteral(value); + Toy_freeLiteral(type); } { //prerequisites char* idn_raw = "foobar"; - Literal identifier = TO_IDENTIFIER_LITERAL(createRefString(idn_raw)); - Literal type = TO_TYPE_LITERAL(LITERAL_INTEGER, false); + Toy_Literal identifier = TOY_TO_IDENTIFIER_LITERAL(Toy_createRefString(idn_raw)); + Toy_Literal type = TOY_TO_TYPE_LITERAL(TOY_LITERAL_INTEGER, false); //test declarations & assignments - Scope* scope = pushScope(NULL); + Toy_Scope* scope = Toy_pushScope(NULL); //declare & assign - if (!declareScopeVariable(scope, identifier, type)) { - printf(ERROR "Failed to declare the scope variable" RESET); + if (!Toy_declareScopeVariable(scope, identifier, type)) { + printf(TOY_CC_ERROR "Failed to declare the scope variable" TOY_CC_RESET); return -1; } - if (!setScopeVariable(scope, identifier, TO_INTEGER_LITERAL(42), true)) { - printf(ERROR "Failed to set the scope variable" RESET); + if (!Toy_setScopeVariable(scope, identifier, TOY_TO_INTEGER_LITERAL(42), true)) { + printf(TOY_CC_ERROR "Failed to set the scope variable" TOY_CC_RESET); return -1; } //deeper scope - scope = pushScope(scope); + scope = Toy_pushScope(scope); //test shadowing - Literal ref; - if (!getScopeVariable(scope, identifier, &ref)) { - printf(ERROR "Failed to get the scope variable" RESET); + Toy_Literal ref; + if (!Toy_getScopeVariable(scope, identifier, &ref)) { + printf(TOY_CC_ERROR "Failed to get the scope variable" TOY_CC_RESET); return -1; } - if (AS_INTEGER(ref) != 42) { - printf(ERROR "Failed to retreive the correct variable value" RESET); + if (TOY_AS_INTEGER(ref) != 42) { + printf(TOY_CC_ERROR "Failed to retreive the correct variable value" TOY_CC_RESET); return -1; } - if (!declareScopeVariable(scope, identifier, type)) { - printf(ERROR "Failed to declare the scope variable (shadowing)" RESET); + if (!Toy_declareScopeVariable(scope, identifier, type)) { + printf(TOY_CC_ERROR "Failed to declare the scope variable (shadowing)" TOY_CC_RESET); return -1; } - if (!setScopeVariable(scope, identifier, TO_INTEGER_LITERAL(69), true)) { - printf(ERROR "Failed to set the scope variable (shadowing)" RESET); + if (!Toy_setScopeVariable(scope, identifier, TOY_TO_INTEGER_LITERAL(69), true)) { + printf(TOY_CC_ERROR "Failed to set the scope variable (shadowing)" TOY_CC_RESET); return -1; } - if (!getScopeVariable(scope, identifier, &ref)) { - printf(ERROR "Failed to get the scope variable (shadowing)" RESET); + if (!Toy_getScopeVariable(scope, identifier, &ref)) { + printf(TOY_CC_ERROR "Failed to get the scope variable (shadowing)" TOY_CC_RESET); return -1; } - if (AS_INTEGER(ref) != 69) { - printf(ERROR "Failed to retreive the correct variable value (shadowing)" RESET); + if (TOY_AS_INTEGER(ref) != 69) { + printf(TOY_CC_ERROR "Failed to retreive the correct variable value (shadowing)" TOY_CC_RESET); return -1; } //unwind - scope = popScope(scope); + scope = Toy_popScope(scope); - if (!getScopeVariable(scope, identifier, &ref)) { - printf(ERROR "Failed to get the scope variable" RESET); + if (!Toy_getScopeVariable(scope, identifier, &ref)) { + printf(TOY_CC_ERROR "Failed to get the scope variable" TOY_CC_RESET); return -1; } - if (AS_INTEGER(ref) != 42) { - printf(ERROR "Failed to retreive the correct variable value" RESET); + if (TOY_AS_INTEGER(ref) != 42) { + printf(TOY_CC_ERROR "Failed to retreive the correct variable value" TOY_CC_RESET); return -1; } //cleanup - scope = popScope(scope); + scope = Toy_popScope(scope); - freeLiteral(identifier); - freeLiteral(type); + Toy_freeLiteral(identifier); + Toy_freeLiteral(type); } - printf(NOTICE "All good\n" RESET); + printf(TOY_CC_NOTICE "All good\n" TOY_CC_RESET); return 0; } diff --git a/tools/uptown.cpp b/tools/uptown.cpp new file mode 100644 index 0000000..6a9a6ff --- /dev/null +++ b/tools/uptown.cpp @@ -0,0 +1,130 @@ +//UPTOWN: Utility to Prepend Text Of Whatever Next + +#include +#include +#include +#include + +//protip: This gets more efficient the more files passed in +//protip: pass in the headers first + +bool is_alpha(char c) { + return (c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z') || c == '_'; +} + +int main(int argc, char** argv) { + if (argc <= 1) { + return -1; + } + + //cache replacements for all files + std::map replacements; + + for (int fileCounter = 1; fileCounter < argc; fileCounter++) { + std::ifstream is; //input stream + std::string buffer; //store file + + //open + is.open(argv[fileCounter]); + if (!is.is_open()) { + return -1; + } + + while (!is.eof()) { + char c = is.peek(); + + //skip comments (make it easier) + if (c == '/') { + buffer += is.get(); + + //single lines + if (is.peek() == '/') { + do { + buffer += is.get(); + } while(is.peek() != '\n'); + continue; + } + + //multi-line + if (is.peek() == '*') { + while (true) { + do { + buffer += is.get(); + } while(is.peek() != '*'); + + if (is.eof()) { //just in case + return -1; + } else { + buffer += is.get(); + if (is.peek() == '/') { + buffer += is.get(); + break; + } + } + } + continue; + } + } + + //skip strings (causes issues) + if (c == '"') { + do { + buffer += is.get(); + } while (is.peek() != '"'); + buffer += is.get(); + continue; + } + + //skip non-words + if (!is_alpha(c)) { + buffer += is.get(); + continue; + } + + //read word + std::string word = ""; + while(is_alpha(is.peek())) { + word += is.get(); + } + + //get replacement word, if it doesn't exist + if (replacements.find(word) == replacements.end()) { + std::cout << word << " : "; + std::string prepend = ""; + + getline(std::cin, prepend); + + if (prepend.length() == 0) { + replacements[word] = word; + } + else { + replacements[word] = prepend + word; + } + } + + //append the replacement + buffer += replacements[word]; + } + + //finally + is.close(); + + std::ofstream os; + + os.open(argv[fileCounter]); + if (!os.is_open()) { + return -1; + } + + //bugfix + if (!buffer.empty()) { + buffer.pop_back(); + } + + os << buffer; + + os.close(); + } + + return 0; +} \ No newline at end of file