From ee226ea426b31d08dddb22d73e25f0f9e76e0488 Mon Sep 17 00:00:00 2001 From: Kayne Ruse Date: Fri, 10 Feb 2023 08:52:38 +0000 Subject: [PATCH] Strengthened constness for cstrings and bytecode --- README.md | 1 - repl/lib_compound.c | 32 ++++++++++++++--------------- repl/lib_runner.c | 14 ++++++------- repl/repl_main.c | 4 ++-- repl/repl_tools.c | 22 ++++++++++---------- repl/repl_tools.h | 14 ++++++------- scripts/small.toy | 1 - source/toy_builtin.c | 10 ++++----- source/toy_compiler.c | 5 +++-- source/toy_interpreter.c | 30 +++++++++++++-------------- source/toy_interpreter.h | 10 ++++----- source/toy_lexer.c | 4 ++-- source/toy_lexer.h | 6 +++--- source/toy_literal.c | 6 +++--- source/toy_parser.c | 6 +++--- source/toy_refstring.c | 40 ++++++++++++++++-------------------- source/toy_refstring.h | 14 ++++++------- test/test_call_from_host.c | 4 ++-- test/test_compiler.c | 2 +- test/test_interpreter.c | 16 +++++++-------- test/test_libraries.c | 12 +++++------ test/test_mustfail.c | 14 ++++++------- test/test_opaque_data_type.c | 4 ++-- test/test_parser.c | 10 ++++----- 24 files changed, 138 insertions(+), 143 deletions(-) diff --git a/README.md b/README.md index dca91a0..7853d44 100644 --- a/README.md +++ b/README.md @@ -36,7 +36,6 @@ Run `make install-tools` to install a number of tools, including: ``` import standard; //for a bunch of utility functions - print "Hello world"; //"print" is a keyword var msg = "foobar"; //declare a variable like this diff --git a/repl/lib_compound.c b/repl/lib_compound.c index d101b77..52eedc4 100644 --- a/repl/lib_compound.c +++ b/repl/lib_compound.c @@ -506,13 +506,13 @@ static int nativeToLower(Toy_Interpreter* interpreter, Toy_LiteralArray* argumen } Toy_RefString* selfRefString = TOY_AS_STRING(selfLiteral); - char* self = Toy_toCString(selfRefString); + const char* self = Toy_toCString(selfRefString); //allocate buffer space for the result char* result = TOY_ALLOCATE(char, Toy_lengthRefString(selfRefString) + 1); //set each new character - for (int i = 0; i < Toy_lengthRefString(selfRefString); i++) { + for (int i = 0; i < (int)Toy_lengthRefString(selfRefString); i++) { result[i] = tolower(self[i]); } result[Toy_lengthRefString(selfRefString)] = '\0'; //end the string @@ -533,7 +533,7 @@ static int nativeToLower(Toy_Interpreter* interpreter, Toy_LiteralArray* argumen static char* toStringUtilObject = NULL; static void toStringUtil(const char* input) { - int len = strlen(input) + 1; + size_t len = strlen(input) + 1; if (len > TOY_MAX_STRING_LENGTH) { len = TOY_MAX_STRING_LENGTH; //TODO: don't truncate @@ -606,13 +606,13 @@ static int nativeToUpper(Toy_Interpreter* interpreter, Toy_LiteralArray* argumen } Toy_RefString* selfRefString = TOY_AS_STRING(selfLiteral); - char* self = Toy_toCString(selfRefString); + const char* self = Toy_toCString(selfRefString); //allocate buffer space for the result char* result = TOY_ALLOCATE(char, Toy_lengthRefString(selfRefString) + 1); //set each new character - for (int i = 0; i < Toy_lengthRefString(selfRefString); i++) { + for (int i = 0; i < (int)Toy_lengthRefString(selfRefString); i++) { result[i] = toupper(self[i]); } result[Toy_lengthRefString(selfRefString)] = '\0'; //end the string @@ -675,10 +675,10 @@ static int nativeTrim(Toy_Interpreter* interpreter, Toy_LiteralArray* arguments) int bufferEnd = Toy_lengthRefString(selfRefString); //for each character in self, check it against each character in trimChars - on a fail, go to end - for (int i = 0; i < Toy_lengthRefString(selfRefString); i++) { + for (int i = 0; i < (int)Toy_lengthRefString(selfRefString); i++) { int trimIndex = 0; - while (trimIndex < Toy_lengthRefString(trimCharsRefString)) { + while (trimIndex < (int)Toy_lengthRefString(trimCharsRefString)) { //there is a match - DON'T increment anymore if (Toy_toCString(selfRefString)[i] == Toy_toCString(trimCharsRefString)[trimIndex]) { break; @@ -688,7 +688,7 @@ static int nativeTrim(Toy_Interpreter* interpreter, Toy_LiteralArray* arguments) } //if the match is found, increment buffer begin - if (trimIndex < Toy_lengthRefString(trimCharsRefString)) { + if (trimIndex < (int)Toy_lengthRefString(trimCharsRefString)) { bufferBegin++; continue; } @@ -701,7 +701,7 @@ static int nativeTrim(Toy_Interpreter* interpreter, Toy_LiteralArray* arguments) for (int i = Toy_lengthRefString(selfRefString); i >= 0; i--) { int trimIndex = 0; - while (trimIndex < Toy_lengthRefString(trimCharsRefString)) { + while (trimIndex < (int)Toy_lengthRefString(trimCharsRefString)) { //there is a match - DON'T increment anymore if (Toy_toCString(selfRefString)[i-1] == Toy_toCString(trimCharsRefString)[trimIndex]) { break; @@ -711,7 +711,7 @@ static int nativeTrim(Toy_Interpreter* interpreter, Toy_LiteralArray* arguments) } //if the match is found, increment buffer begin - if (trimIndex < Toy_lengthRefString(trimCharsRefString)) { + if (trimIndex < (int)Toy_lengthRefString(trimCharsRefString)) { bufferEnd--; continue; } @@ -786,10 +786,10 @@ static int nativeTrimBegin(Toy_Interpreter* interpreter, Toy_LiteralArray* argum int bufferEnd = Toy_lengthRefString(selfRefString); //for each character in self, check it against each character in trimChars - on a fail, go to end - for (int i = 0; i < Toy_lengthRefString(selfRefString); i++) { + for (int i = 0; i < (int)Toy_lengthRefString(selfRefString); i++) { int trimIndex = 0; - while (trimIndex < Toy_lengthRefString(trimCharsRefString)) { + while (trimIndex < (int)Toy_lengthRefString(trimCharsRefString)) { //there is a match - DON'T increment anymore if (Toy_toCString(selfRefString)[i] == Toy_toCString(trimCharsRefString)[trimIndex]) { break; @@ -799,7 +799,7 @@ static int nativeTrimBegin(Toy_Interpreter* interpreter, Toy_LiteralArray* argum } //if the match is found, increment buffer begin - if (trimIndex < Toy_lengthRefString(trimCharsRefString)) { + if (trimIndex < (int)Toy_lengthRefString(trimCharsRefString)) { bufferBegin++; continue; } @@ -874,10 +874,10 @@ static int nativeTrimEnd(Toy_Interpreter* interpreter, Toy_LiteralArray* argumen int bufferEnd = Toy_lengthRefString(selfRefString); //again, from the back - for (int i = Toy_lengthRefString(selfRefString); i >= 0; i--) { + for (int i = (int)Toy_lengthRefString(selfRefString); i >= 0; i--) { int trimIndex = 0; - while (trimIndex < Toy_lengthRefString(trimCharsRefString)) { + while (trimIndex < (int)Toy_lengthRefString(trimCharsRefString)) { //there is a match - DON'T increment anymore if (Toy_toCString(selfRefString)[i-1] == Toy_toCString(trimCharsRefString)[trimIndex]) { break; @@ -887,7 +887,7 @@ static int nativeTrimEnd(Toy_Interpreter* interpreter, Toy_LiteralArray* argumen } //if the match is found, increment buffer begin - if (trimIndex < Toy_lengthRefString(trimCharsRefString)) { + if (trimIndex < (int)Toy_lengthRefString(trimCharsRefString)) { bufferEnd--; continue; } diff --git a/repl/lib_runner.c b/repl/lib_runner.c index 1f5104f..186b6d3 100644 --- a/repl/lib_runner.c +++ b/repl/lib_runner.c @@ -10,7 +10,7 @@ typedef struct Toy_Runner { Toy_Interpreter interpreter; - unsigned char* bytecode; + const unsigned char* bytecode; size_t size; bool dirty; @@ -43,12 +43,12 @@ static int nativeLoadScript(Toy_Interpreter* interpreter, Toy_LiteralArray* argu Toy_freeLiteral(drivePathLiteral); //use raw types - easier - char* filePath = Toy_toCString(TOY_AS_STRING(filePathLiteral)); + const char* filePath = Toy_toCString(TOY_AS_STRING(filePathLiteral)); int filePathLength = Toy_lengthRefString(TOY_AS_STRING(filePathLiteral)); //load and compile the bytecode size_t fileSize = 0; - char* source = Toy_readFile(filePath, &fileSize); + const char* source = Toy_readFile(filePath, &fileSize); if (!source) { interpreter->errorOutput("Failed to load source file\n"); @@ -56,7 +56,7 @@ static int nativeLoadScript(Toy_Interpreter* interpreter, Toy_LiteralArray* argu return -1; } - unsigned char* bytecode = Toy_compileString(source, &fileSize); + const unsigned char* bytecode = Toy_compileString(source, &fileSize); free((void*)source); if (!bytecode) { @@ -105,7 +105,7 @@ static int nativeLoadScriptBytecode(Toy_Interpreter* interpreter, Toy_LiteralArr 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; + size_t driveLength = 0; while (Toy_toCString(drivePath)[driveLength] != ':') { if (driveLength >= Toy_lengthRefString(drivePath)) { interpreter->errorOutput("Incorrect drive path format given to loadScriptBytecode\n"); @@ -492,7 +492,7 @@ static int nativeCheckScriptDirty(Toy_Interpreter* interpreter, Toy_LiteralArray //call the hook typedef struct Natives { - char* name; + const char* name; Toy_NativeFn fn; } Natives; @@ -585,7 +585,7 @@ Toy_Literal Toy_getFilePathLiteral(Toy_Interpreter* interpreter, Toy_Literal* dr 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; + size_t driveLength = 0; while (Toy_toCString(drivePath)[driveLength] != ':') { if (driveLength >= Toy_lengthRefString(drivePath)) { interpreter->errorOutput("Incorrect drive path format given to Toy_getFilePathLiteral\n"); diff --git a/repl/repl_main.c b/repl/repl_main.c index 8104392..3d539f5 100644 --- a/repl/repl_main.c +++ b/repl/repl_main.c @@ -151,11 +151,11 @@ int main(int argc, const char* argv[]) { //compile source file if (Toy_commandLine.compilefile && Toy_commandLine.outfile) { size_t size = 0; - char* source = Toy_readFile(Toy_commandLine.compilefile, &size); + const char* source = Toy_readFile(Toy_commandLine.compilefile, &size); if (!source) { return 1; } - unsigned char* tb = Toy_compileString(source, &size); + const unsigned char* tb = Toy_compileString(source, &size); if (!tb) { return 1; } diff --git a/repl/repl_tools.c b/repl/repl_tools.c index cce3bfc..7018e93 100644 --- a/repl/repl_tools.c +++ b/repl/repl_tools.c @@ -16,7 +16,7 @@ #include //IO functions -char* Toy_readFile(char* path, size_t* fileSize) { +const char* Toy_readFile(const char* path, size_t* fileSize) { FILE* file = fopen(path, "rb"); if (file == NULL) { @@ -49,7 +49,7 @@ char* Toy_readFile(char* path, size_t* fileSize) { return buffer; } -int Toy_writeFile(char* path, unsigned char* bytes, size_t size) { +int Toy_writeFile(const char* path, const unsigned char* bytes, size_t size) { FILE* file = fopen(path, "wb"); if (file == NULL) { @@ -70,7 +70,7 @@ int Toy_writeFile(char* path, unsigned char* bytes, size_t size) { } //repl functions -unsigned char* Toy_compileString(char* source, size_t* size) { +const unsigned char* Toy_compileString(const char* source, size_t* size) { Toy_Lexer lexer; Toy_Parser parser; Toy_Compiler compiler; @@ -96,7 +96,7 @@ unsigned char* Toy_compileString(char* source, size_t* size) { } //get the bytecode dump - unsigned char* tb = Toy_collateCompiler(&compiler, (int*)(size)); + const unsigned char* tb = Toy_collateCompiler(&compiler, (int*)(size)); //cleanup Toy_freeCompiler(&compiler); @@ -107,7 +107,7 @@ unsigned char* Toy_compileString(char* source, size_t* size) { return tb; } -void Toy_runBinary(unsigned char* tb, size_t size) { +void Toy_runBinary(const unsigned char* tb, size_t size) { Toy_Interpreter interpreter; Toy_initInterpreter(&interpreter); @@ -122,9 +122,9 @@ void Toy_runBinary(unsigned char* tb, size_t size) { Toy_freeInterpreter(&interpreter); } -void Toy_runBinaryFile(char* fname) { +void Toy_runBinaryFile(const char* fname) { size_t size = 0; //not used - unsigned char* tb = (unsigned char*)Toy_readFile(fname, &size); + const unsigned char* tb = (const unsigned char*)Toy_readFile(fname, &size); if (!tb) { return; } @@ -132,9 +132,9 @@ void Toy_runBinaryFile(char* fname) { //interpreter takes ownership of the binary data } -void Toy_runSource(char* source) { +void Toy_runSource(const char* source) { size_t size = 0; - unsigned char* tb = Toy_compileString(source, &size); + const unsigned char* tb = Toy_compileString(source, &size); if (!tb) { return; } @@ -142,9 +142,9 @@ void Toy_runSource(char* source) { Toy_runBinary(tb, size); } -void Toy_runSourceFile(char* fname) { +void Toy_runSourceFile(const char* fname) { size_t size = 0; //not used - char* source = Toy_readFile(fname, &size); + const char* source = Toy_readFile(fname, &size); if (!source) { return; } diff --git a/repl/repl_tools.h b/repl/repl_tools.h index 57f5605..819f752 100644 --- a/repl/repl_tools.h +++ b/repl/repl_tools.h @@ -2,13 +2,13 @@ #include "toy_common.h" -char* Toy_readFile(char* path, size_t* fileSize); -int Toy_writeFile(char* path, unsigned char* bytes, size_t size); +const char* Toy_readFile(const char* path, size_t* fileSize); +int Toy_writeFile(const char* path, const unsigned char* bytes, size_t size); -unsigned char* Toy_compileString(char* source, size_t* size); +const unsigned char* Toy_compileString(const char* source, size_t* size); -void Toy_runBinary(unsigned char* tb, size_t size); -void Toy_runBinaryFile(char* fname); -void Toy_runSource(char* source); -void Toy_runSourceFile(char* fname); +void Toy_runBinary(const unsigned char* tb, size_t size); +void Toy_runBinaryFile(const char* fname); +void Toy_runSource(const char* source); +void Toy_runSourceFile(const char* fname); diff --git a/scripts/small.toy b/scripts/small.toy index fd04de0..8070b92 100644 --- a/scripts/small.toy +++ b/scripts/small.toy @@ -1,6 +1,5 @@ import standard; //for a bunch of utility functions - print "Hello world"; //"print" is a keyword var msg = "foobar"; //declare a variable like this diff --git a/source/toy_builtin.c b/source/toy_builtin.c index 32d1a9c..399a57e 100644 --- a/source/toy_builtin.c +++ b/source/toy_builtin.c @@ -793,7 +793,7 @@ int Toy_private_index(Toy_Interpreter* interpreter, Toy_LiteralArray* arguments) } //handle each error case - if (!TOY_IS_INTEGER(first) || TOY_AS_INTEGER(first) < 0 || TOY_AS_INTEGER(first) >= TOY_AS_STRING(compound)->length) { + if (!TOY_IS_INTEGER(first) || TOY_AS_INTEGER(first) < 0 || TOY_AS_INTEGER(first) >= (int)Toy_lengthRefString(TOY_AS_STRING(compound))) { interpreter->errorOutput("Bad first indexing in string\n"); //something is weird - skip out @@ -807,7 +807,7 @@ int Toy_private_index(Toy_Interpreter* interpreter, Toy_LiteralArray* arguments) return -1; } - if ((!TOY_IS_NULL(second) && !TOY_IS_INTEGER(second)) || TOY_AS_INTEGER(second) < 0 || TOY_AS_INTEGER(second) >= TOY_AS_STRING(compound)->length) { + if ((!TOY_IS_NULL(second) && !TOY_IS_INTEGER(second)) || TOY_AS_INTEGER(second) < 0 || TOY_AS_INTEGER(second) >= (int)Toy_lengthRefString(TOY_AS_STRING(compound))) { interpreter->errorOutput("Bad second indexing in string\n"); //something is weird - skip out @@ -838,7 +838,7 @@ int Toy_private_index(Toy_Interpreter* interpreter, Toy_LiteralArray* arguments) //simple indexing if second is null if (TOY_IS_NULL(second)) { - char* cstr = Toy_toCString(TOY_AS_STRING(compound)); + const char* cstr = Toy_toCString(TOY_AS_STRING(compound)); char buf[16]; snprintf(buf, 16, "%s", &(cstr[ TOY_AS_INTEGER(first) ]) ); @@ -937,7 +937,7 @@ int Toy_private_index(Toy_Interpreter* interpreter, Toy_LiteralArray* arguments) } //handle each error case - if (!TOY_IS_INTEGER(first) || TOY_AS_INTEGER(first) < 0 || TOY_AS_INTEGER(first) >= TOY_AS_STRING(compound)->length) { + if (!TOY_IS_INTEGER(first) || TOY_AS_INTEGER(first) < 0 || TOY_AS_INTEGER(first) >= (int)Toy_lengthRefString(TOY_AS_STRING(compound))) { interpreter->errorOutput("Bad first indexing in string assignment\n"); //something is weird - skip out @@ -951,7 +951,7 @@ int Toy_private_index(Toy_Interpreter* interpreter, Toy_LiteralArray* arguments) return -1; } - if ((!TOY_IS_NULL(second) && !TOY_IS_INTEGER(second)) || TOY_AS_INTEGER(second) < 0 || TOY_AS_INTEGER(second) >= TOY_AS_STRING(compound)->length) { + if ((!TOY_IS_NULL(second) && !TOY_IS_INTEGER(second)) || TOY_AS_INTEGER(second) < 0 || TOY_AS_INTEGER(second) >= (int)Toy_lengthRefString(TOY_AS_STRING(compound))) { interpreter->errorOutput("Bad second indexing in string assignment\n"); //something is weird - skip out diff --git a/source/toy_compiler.c b/source/toy_compiler.c index 335c453..38786fb 100644 --- a/source/toy_compiler.c +++ b/source/toy_compiler.c @@ -1096,7 +1096,7 @@ static unsigned char* collateCompilerHeaderOpt(Toy_Compiler* compiler, int* size Toy_Literal str = compiler->literalCache.literals[i]; - for (int c = 0; c < TOY_AS_STRING(str)->length; c++) { + for (int c = 0; c < (int)Toy_lengthRefString(TOY_AS_STRING(str)); c++) { emitByte(&collation, &capacity, &count, Toy_toCString(TOY_AS_STRING(str))[c]); } @@ -1198,7 +1198,7 @@ static unsigned char* collateCompilerHeaderOpt(Toy_Compiler* compiler, int* size Toy_Literal identifier = compiler->literalCache.literals[i]; - for (int c = 0; c < TOY_AS_IDENTIFIER(identifier)->length; c++) { + for (int c = 0; c < (int)Toy_lengthRefString(TOY_AS_IDENTIFIER(identifier)); c++) { emitByte(&collation, &capacity, &count, Toy_toCString(TOY_AS_IDENTIFIER(identifier))[c]); } @@ -1284,6 +1284,7 @@ static unsigned char* collateCompilerHeaderOpt(Toy_Compiler* compiler, int* size return collation; } +//the whole point of the compiler is to alter bytecode, so leave it as non-const unsigned char* Toy_collateCompiler(Toy_Compiler* compiler, int* size) { return collateCompilerHeaderOpt(compiler, size, true); } diff --git a/source/toy_interpreter.c b/source/toy_interpreter.c index 3d64617..d5b28c9 100644 --- a/source/toy_interpreter.c +++ b/source/toy_interpreter.c @@ -26,7 +26,7 @@ static void errorWrapper(const char* output) { fprintf(stderr, TOY_CC_ERROR "%s" TOY_CC_RESET, output); //no newline } -bool Toy_injectNativeFn(Toy_Interpreter* interpreter, char* name, Toy_NativeFn func) { +bool Toy_injectNativeFn(Toy_Interpreter* interpreter, const char* name, Toy_NativeFn func) { //reject reserved words if (Toy_findTypeByKeyword(name) != TOY_TOKEN_EOF) { interpreter->errorOutput("Can't override an existing keyword\n"); @@ -54,7 +54,7 @@ bool Toy_injectNativeFn(Toy_Interpreter* interpreter, char* name, Toy_NativeFn f return true; } -bool Toy_injectNativeHook(Toy_Interpreter* interpreter, char* name, Toy_HookFn hook) { +bool Toy_injectNativeHook(Toy_Interpreter* interpreter, const char* name, Toy_HookFn hook) { //reject reserved words if (Toy_findTypeByKeyword(name) != TOY_TOKEN_EOF) { interpreter->errorOutput("Can't inject a hook on an existing keyword\n"); @@ -169,40 +169,40 @@ void Toy_setInterpreterError(Toy_Interpreter* interpreter, Toy_PrintFn errorOutp } //utils -static unsigned char readByte(unsigned char* tb, int* count) { +static unsigned char readByte(const unsigned char* tb, int* count) { unsigned char ret = *(unsigned char*)(tb + *count); *count += 1; return ret; } -static unsigned short readShort(unsigned char* tb, int* count) { +static unsigned short readShort(const unsigned char* tb, int* count) { unsigned short ret = 0; memcpy(&ret, tb + *count, 2); *count += 2; return ret; } -static int readInt(unsigned char* tb, int* count) { +static int readInt(const unsigned char* tb, int* count) { int ret = 0; memcpy(&ret, tb + *count, 4); *count += 4; return ret; } -static float readFloat(unsigned char* tb, int* count) { +static float readFloat(const unsigned char* tb, int* count) { float ret = 0; memcpy(&ret, tb + *count, 4); *count += 4; return ret; } -static char* readString(unsigned char* tb, int* count) { - unsigned char* ret = tb + *count; +static const char* readString(const unsigned char* tb, int* count) { + const unsigned char* ret = tb + *count; *count += strlen((char*)ret) + 1; //+1 for null character - return (char*)ret; + return (const char*)ret; } -static void consumeByte(Toy_Interpreter* interpreter, unsigned char byte, unsigned char* tb, int* count) { +static void consumeByte(Toy_Interpreter* interpreter, unsigned char byte, const 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]); @@ -211,7 +211,7 @@ static void consumeByte(Toy_Interpreter* interpreter, unsigned char byte, unsign *count += 1; } -static void consumeShort(Toy_Interpreter* interpreter, unsigned short bytes, unsigned char* tb, int* count) { +static void consumeShort(Toy_Interpreter* interpreter, unsigned short bytes, const 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)); @@ -1446,7 +1446,7 @@ bool Toy_callLiteralFn(Toy_Interpreter* interpreter, Toy_Literal func, Toy_Liter return true; } -bool Toy_callFn(Toy_Interpreter* interpreter, char* name, Toy_LiteralArray* arguments, Toy_LiteralArray* returns) { +bool Toy_callFn(Toy_Interpreter* interpreter, const 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; @@ -2125,7 +2125,7 @@ static void readInterpreterSections(Toy_Interpreter* interpreter) { break; case TOY_LITERAL_STRING: { - char* s = readString(interpreter->bytecode, &interpreter->count); + const char* s = readString(interpreter->bytecode, &interpreter->count); int length = strlen(s); Toy_Literal literal = TOY_TO_STRING_LITERAL(Toy_createRefStringLength(s, length)); Toy_pushLiteralArray(&interpreter->literalCache, literal); @@ -2222,7 +2222,7 @@ static void readInterpreterSections(Toy_Interpreter* interpreter) { break; case TOY_LITERAL_IDENTIFIER: { - char* str = readString(interpreter->bytecode, &interpreter->count); + const char* str = readString(interpreter->bytecode, &interpreter->count); int length = strlen(str); Toy_Literal identifier = TOY_TO_IDENTIFIER_LITERAL(Toy_createRefStringLength(str, length)); @@ -2356,7 +2356,7 @@ void Toy_initInterpreter(Toy_Interpreter* interpreter) { Toy_resetInterpreter(interpreter); } -void Toy_runInterpreter(Toy_Interpreter* interpreter, unsigned char* bytecode, int length) { +void Toy_runInterpreter(Toy_Interpreter* interpreter, const unsigned char* bytecode, int length) { //initialize here instead of initInterpreter() Toy_initLiteralArray(&interpreter->literalCache); interpreter->bytecode = NULL; diff --git a/source/toy_interpreter.h b/source/toy_interpreter.h index 323627f..53d0f4d 100644 --- a/source/toy_interpreter.h +++ b/source/toy_interpreter.h @@ -11,7 +11,7 @@ typedef void (*Toy_PrintFn)(const char*); //the interpreter acts depending on the bytecode instructions typedef struct Toy_Interpreter { //input - unsigned char* bytecode; + const unsigned char* bytecode; int length; int count; int codeStart; //BUGFIX: for jumps, must be initialized to -1 @@ -34,11 +34,11 @@ typedef struct Toy_Interpreter { } Toy_Interpreter; //native API -TOY_API bool Toy_injectNativeFn(Toy_Interpreter* interpreter, char* name, Toy_NativeFn func); -TOY_API bool Toy_injectNativeHook(Toy_Interpreter* interpreter, char* name, Toy_HookFn hook); +TOY_API bool Toy_injectNativeFn(Toy_Interpreter* interpreter, const char* name, Toy_NativeFn func); +TOY_API bool Toy_injectNativeHook(Toy_Interpreter* interpreter, const char* name, Toy_HookFn hook); 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); +TOY_API bool Toy_callFn(Toy_Interpreter* interpreter, const char* name, Toy_LiteralArray* arguments, Toy_LiteralArray* returns); //utilities for the host program TOY_API bool Toy_parseIdentifierToValue(Toy_Interpreter* interpreter, Toy_Literal* literalPtr); @@ -48,6 +48,6 @@ TOY_API void Toy_setInterpreterError(Toy_Interpreter* interpreter, Toy_PrintFn e //main access 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_runInterpreter(Toy_Interpreter* interpreter, const 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_lexer.c b/source/toy_lexer.c index 92b4ba5..af24bbe 100644 --- a/source/toy_lexer.c +++ b/source/toy_lexer.c @@ -270,7 +270,7 @@ static Toy_Token makeKeywordOrIdentifier(Toy_Lexer* lexer) { } //exposed functions -void Toy_initLexer(Toy_Lexer* lexer, char* source) { +void Toy_initLexer(Toy_Lexer* lexer, const char* source) { cleanLexer(lexer); lexer->source = source; @@ -363,7 +363,7 @@ void Toy_printToken(Toy_Token* token) { if (keyword != NULL) { printf("%s", keyword); } else { - char* str = token->lexeme; + char* str = (char*)token->lexeme; //strip const-ness for trimming int length = token->length; trim(&str, &length); printf("%.*s", length, str); diff --git a/source/toy_lexer.h b/source/toy_lexer.h index 41a60bc..c7b544d 100644 --- a/source/toy_lexer.h +++ b/source/toy_lexer.h @@ -5,7 +5,7 @@ //lexers are bound to a string of code, and return a single token every time scan is called typedef struct { - char* source; + const char* source; int start; //start of the token int current; //current position of the lexer int line; //track this for error handling @@ -14,12 +14,12 @@ typedef struct { //tokens are intermediaries between lexers and parsers typedef struct { Toy_TokenType type; - char* lexeme; + const char* lexeme; int length; int line; } Toy_Token; -TOY_API void Toy_initLexer(Toy_Lexer* lexer, char* source); +TOY_API void Toy_initLexer(Toy_Lexer* lexer, const char* source); Toy_Token Toy_scanLexer(Toy_Lexer* lexer); //for debugging diff --git a/source/toy_literal.c b/source/toy_literal.c index 2d129c4..813c5b5 100644 --- a/source/toy_literal.c +++ b/source/toy_literal.c @@ -487,10 +487,10 @@ void Toy_printLiteralCustom(Toy_Literal literal, void (printFn)(const char*)) { case TOY_LITERAL_STRING: { char buffer[TOY_MAX_STRING_LENGTH]; if (!quotes) { - snprintf(buffer, TOY_MAX_STRING_LENGTH, "%.*s", Toy_lengthRefString(TOY_AS_STRING(literal)), Toy_toCString(TOY_AS_STRING(literal))); + snprintf(buffer, TOY_MAX_STRING_LENGTH, "%.*s", (int)Toy_lengthRefString(TOY_AS_STRING(literal)), Toy_toCString(TOY_AS_STRING(literal))); } else { - snprintf(buffer, TOY_MAX_STRING_LENGTH, "%c%.*s%c", quotes, Toy_lengthRefString(TOY_AS_STRING(literal)), Toy_toCString(TOY_AS_STRING(literal)), quotes); + snprintf(buffer, TOY_MAX_STRING_LENGTH, "%c%.*s%c", quotes, (int)Toy_lengthRefString(TOY_AS_STRING(literal)), Toy_toCString(TOY_AS_STRING(literal)), quotes); } printFn(buffer); } @@ -596,7 +596,7 @@ void Toy_printLiteralCustom(Toy_Literal literal, void (printFn)(const char*)) { case TOY_LITERAL_IDENTIFIER: { char buffer[256]; - snprintf(buffer, 256, "%.*s", Toy_lengthRefString(TOY_AS_IDENTIFIER(literal)), Toy_toCString(TOY_AS_IDENTIFIER(literal))); + snprintf(buffer, 256, "%.*s", (int)Toy_lengthRefString(TOY_AS_IDENTIFIER(literal)), Toy_toCString(TOY_AS_IDENTIFIER(literal))); printFn(buffer); } break; diff --git a/source/toy_parser.c b/source/toy_parser.c index 1bf4d1f..b1a2f85 100644 --- a/source/toy_parser.c +++ b/source/toy_parser.c @@ -508,7 +508,7 @@ static Toy_Opcode unary(Toy_Parser* parser, Toy_ASTNode** nodeHandle) { return TOY_OP_EOF; } -static char* removeChar(char* lexeme, int length, char c) { +static char* removeChar(const char* lexeme, int length, char c) { int resPos = 0; char* result = TOY_ALLOCATE(char, length + 1); @@ -540,7 +540,7 @@ static Toy_Opcode atomic(Toy_Parser* parser, Toy_ASTNode** nodeHandle) { case TOY_TOKEN_LITERAL_INTEGER: { int value = 0; - char* lexeme = removeChar(parser->previous.lexeme, parser->previous.length, '_'); + const char* lexeme = removeChar(parser->previous.lexeme, parser->previous.length, '_'); sscanf(lexeme, "%d", &value); TOY_FREE_ARRAY(char, lexeme, parser->previous.length + 1); Toy_emitASTNodeLiteral(nodeHandle, TOY_TO_INTEGER_LITERAL(value)); @@ -549,7 +549,7 @@ static Toy_Opcode atomic(Toy_Parser* parser, Toy_ASTNode** nodeHandle) { case TOY_TOKEN_LITERAL_FLOAT: { float value = 0; - char* lexeme = removeChar(parser->previous.lexeme, parser->previous.length, '_'); + const char* lexeme = removeChar(parser->previous.lexeme, parser->previous.length, '_'); sscanf(lexeme, "%f", &value); TOY_FREE_ARRAY(char, lexeme, parser->previous.length + 1); Toy_emitASTNodeLiteral(nodeHandle, TOY_TO_FLOAT_LITERAL(value)); diff --git a/source/toy_refstring.c b/source/toy_refstring.c index 716d291..6ddb576 100644 --- a/source/toy_refstring.c +++ b/source/toy_refstring.c @@ -1,14 +1,6 @@ #include "toy_refstring.h" #include -#include - -//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(Toy_RefString) == 12); -STATIC_ASSERT(sizeof(int) == 4); -STATIC_ASSERT(sizeof(char) == 1); //memory allocation extern void* Toy_private_defaultMemoryAllocator(void* pointer, size_t oldSize, size_t newSize); @@ -19,18 +11,22 @@ void Toy_setRefStringAllocatorFn(Toy_RefStringAllocatorFn allocator) { } //API -Toy_RefString* Toy_createRefString(char* cstring) { - int length = strlen(cstring); +Toy_RefString* Toy_createRefString(const char* cstring) { + size_t length = strlen(cstring); return Toy_createRefStringLength(cstring, length); } -Toy_RefString* Toy_createRefStringLength(char* cstring, int length) { +Toy_RefString* Toy_createRefStringLength(const char* cstring, size_t length) { //allocate the memory area (including metadata space) - Toy_RefString* refString = (Toy_RefString*)allocate(NULL, 0, sizeof(int) * 2 + sizeof(char) * length + 1); + Toy_RefString* refString = allocate(NULL, 0, sizeof(size_t) + sizeof(int) + sizeof(char) * (length + 1)); + + if (refString == NULL) { + return NULL; + } //set the data - refString->refcount = 1; + refString->refCount = 1; refString->length = length; strncpy(refString->data, cstring, refString->length); @@ -41,32 +37,32 @@ Toy_RefString* Toy_createRefStringLength(char* cstring, int length) { void Toy_deleteRefString(Toy_RefString* refString) { //decrement, then check - refString->refcount--; - if (refString->refcount <= 0) { - allocate(refString, sizeof(int) * 2 + sizeof(char) * refString->length + 1, 0); + refString->refCount--; + if (refString->refCount <= 0) { + allocate(refString, sizeof(size_t) + sizeof(int) + sizeof(char) * (refString->length + 1), 0); } } int Toy_countRefString(Toy_RefString* refString) { - return refString->refcount; + return refString->refCount; } -int Toy_lengthRefString(Toy_RefString* refString) { +size_t Toy_lengthRefString(Toy_RefString* refString) { return refString->length; } Toy_RefString* Toy_copyRefString(Toy_RefString* refString) { //Cheaty McCheater Face - refString->refcount++; + refString->refCount++; return refString; } Toy_RefString* Toy_deepCopyRefString(Toy_RefString* refString) { - //create a new string, with a new refcount + //create a new string, with a new refCount return Toy_createRefStringLength(refString->data, refString->length); } -char* Toy_toCString(Toy_RefString* refString) { +const char* Toy_toCString(Toy_RefString* refString) { return refString->data; } @@ -87,7 +83,7 @@ bool Toy_equalsRefString(Toy_RefString* lhs, Toy_RefString* rhs) { bool Toy_equalsRefStringCString(Toy_RefString* lhs, char* cstring) { //get the rhs length - int length = strlen(cstring); + size_t length = strlen(cstring); //different length if (lhs->length != length) { diff --git a/source/toy_refstring.h b/source/toy_refstring.h index 30c8f67..9a4eba7 100644 --- a/source/toy_refstring.h +++ b/source/toy_refstring.h @@ -9,19 +9,19 @@ void Toy_setRefStringAllocatorFn(Toy_RefStringAllocatorFn); //the RefString structure typedef struct Toy_RefString { - int refcount; - int length; - char data[1]; + size_t length; + int refCount; + char data[]; } Toy_RefString; //API -Toy_RefString* Toy_createRefString(char* cstring); -Toy_RefString* Toy_createRefStringLength(char* cstring, int length); +Toy_RefString* Toy_createRefString(const char* cstring); +Toy_RefString* Toy_createRefStringLength(const char* cstring, size_t length); void Toy_deleteRefString(Toy_RefString* refString); int Toy_countRefString(Toy_RefString* refString); -int Toy_lengthRefString(Toy_RefString* refString); +size_t 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); +const 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/test/test_call_from_host.c b/test/test_call_from_host.c index 1a2b8c2..8bb1aba 100644 --- a/test/test_call_from_host.c +++ b/test/test_call_from_host.c @@ -27,8 +27,8 @@ void error(char* msg) { int main() { { size_t size = 0; - char* source = Toy_readFile("scripts/call-from-host.toy", &size); - unsigned char* tb = Toy_compileString(source, &size); + const char* source = Toy_readFile("scripts/call-from-host.toy", &size); + const unsigned char* tb = Toy_compileString(source, &size); free((void*)source); if (!tb) { diff --git a/test/test_compiler.c b/test/test_compiler.c index 0b8e16f..d4b0a9f 100644 --- a/test/test_compiler.c +++ b/test/test_compiler.c @@ -52,7 +52,7 @@ int main() { { //source size_t sourceLength = 0; - char* source = Toy_readFile("scripts/compiler_sample_code.toy", &sourceLength); + const char* source = Toy_readFile("scripts/compiler_sample_code.toy", &sourceLength); //test basic compilation & collation Toy_Lexer lexer; diff --git a/test/test_interpreter.c b/test/test_interpreter.c index 7e06580..b5a2ffe 100644 --- a/test/test_interpreter.c +++ b/test/test_interpreter.c @@ -30,7 +30,7 @@ static void noAssertFn(const char* output) { } } -void runBinaryCustom(unsigned char* tb, size_t size) { +void runBinaryCustom(const unsigned char* tb, size_t size) { Toy_Interpreter interpreter; Toy_initInterpreter(&interpreter); @@ -42,18 +42,18 @@ void runBinaryCustom(unsigned char* tb, size_t size) { Toy_freeInterpreter(&interpreter); } -void runSourceCustom(char* source) { +void runSourceCustom(const char* source) { size_t size = 0; - unsigned char* tb = Toy_compileString(source, &size); + const unsigned char* tb = Toy_compileString(source, &size); if (!tb) { return; } runBinaryCustom(tb, size); } -void runSourceFileCustom(char* fname) { +void runSourceFileCustom(const char* fname) { size_t size = 0; //not used - char* source = Toy_readFile(fname, &size); + const char* source = Toy_readFile(fname, &size); runSourceCustom(source); free((void*)source); } @@ -68,7 +68,7 @@ int main() { { //source - char* source = "print null;"; + const char* source = "print null;"; //test basic compilation & collation Toy_Lexer lexer; @@ -88,7 +88,7 @@ int main() { //collate int size = 0; - unsigned char* bytecode = Toy_collateCompiler(&compiler, &size); + const unsigned char* bytecode = Toy_collateCompiler(&compiler, &size); //NOTE: suppress print output for testing Toy_setInterpreterPrint(&interpreter, noPrintFn); @@ -106,7 +106,7 @@ int main() { { //run each file in tests/scripts/ - char* filenames[] = { + const char* filenames[] = { "arithmetic.toy", "casting.toy", "coercions.toy", diff --git a/test/test_libraries.c b/test/test_libraries.c index 40ac5b6..7dde861 100644 --- a/test/test_libraries.c +++ b/test/test_libraries.c @@ -37,7 +37,7 @@ static void errorWrapper(const char* output) { fprintf(stderr, TOY_CC_ERROR "%s" TOY_CC_RESET, output); } -void runBinaryWithLibrary(unsigned char* tb, size_t size, char* library, Toy_HookFn hook) { +void runBinaryWithLibrary(const unsigned char* tb, size_t size, const char* library, Toy_HookFn hook) { Toy_Interpreter interpreter; Toy_initInterpreter(&interpreter); @@ -53,7 +53,7 @@ void runBinaryWithLibrary(unsigned char* tb, size_t size, char* library, Toy_Hoo Toy_freeInterpreter(&interpreter); } -void runBinaryQuietly(unsigned char* tb, size_t size) { +void runBinaryQuietly(const unsigned char* tb, size_t size) { Toy_Interpreter interpreter; Toy_initInterpreter(&interpreter); @@ -111,14 +111,14 @@ int main() { //compile the source size_t size = 0; - char* source = Toy_readFile(fname, &size); + const char* source = Toy_readFile(fname, &size); if (!source) { printf(TOY_CC_ERROR "Failed to load file: %s\n" TOY_CC_RESET, fname); failedAsserts++; continue; } - unsigned char* tb = Toy_compileString(source, &size); + const unsigned char* tb = Toy_compileString(source, &size); free((void*)source); if (!tb) { @@ -146,14 +146,14 @@ int main() { //compile the source size_t size = 0; - char* source = Toy_readFile(fname, &size); + const char* source = Toy_readFile(fname, &size); if (!source) { printf(TOY_CC_ERROR "Failed to load file: %s\n" TOY_CC_RESET, fname); failedAsserts++; continue; } - unsigned char* tb = Toy_compileString(source, &size); + const unsigned char* tb = Toy_compileString(source, &size); free((void*)source); if (!tb) { diff --git a/test/test_mustfail.c b/test/test_mustfail.c index 8a0a68d..42997ae 100644 --- a/test/test_mustfail.c +++ b/test/test_mustfail.c @@ -23,7 +23,7 @@ static void noErrorFn(const char* output) { errorsTriggered++; } -unsigned char* compileStringCustom(char* source, size_t* size) { +const unsigned char* compileStringCustom(const char* source, size_t* size) { Toy_Lexer lexer; Toy_Parser parser; Toy_Compiler compiler; @@ -50,7 +50,7 @@ unsigned char* compileStringCustom(char* source, size_t* size) { } //get the bytecode dump - unsigned char* tb = Toy_collateCompiler(&compiler, (int*)(size)); + const unsigned char* tb = Toy_collateCompiler(&compiler, (int*)(size)); //cleanup Toy_freeCompiler(&compiler); @@ -61,7 +61,7 @@ unsigned char* compileStringCustom(char* source, size_t* size) { return tb; } -void runBinaryCustom(unsigned char* tb, size_t size) { +void runBinaryCustom(const unsigned char* tb, size_t size) { Toy_Interpreter interpreter; Toy_initInterpreter(&interpreter); @@ -73,18 +73,18 @@ void runBinaryCustom(unsigned char* tb, size_t size) { Toy_freeInterpreter(&interpreter); } -void runSourceCustom(char* source) { +void runSourceCustom(const char* source) { size_t size = 0; - unsigned char* tb = compileStringCustom(source, &size); + const unsigned char* tb = compileStringCustom(source, &size); if (!tb) { return; } runBinaryCustom(tb, size); } -void runSourceFileCustom(char* fname) { +void runSourceFileCustom(const char* fname) { size_t size = 0; //not used - char* source = Toy_readFile(fname, &size); + const char* source = Toy_readFile(fname, &size); runSourceCustom(source); free((void*)source); } diff --git a/test/test_opaque_data_type.c b/test/test_opaque_data_type.c index 64a314e..ab8a299 100644 --- a/test/test_opaque_data_type.c +++ b/test/test_opaque_data_type.c @@ -68,8 +68,8 @@ static int consume(Toy_Interpreter* interpreter, Toy_LiteralArray* arguments) { int main() { { size_t size = 0; - char* source = Toy_readFile("scripts/opaque-data-type.toy", &size); - unsigned char* tb = Toy_compileString(source, &size); + const char* source = Toy_readFile("scripts/opaque-data-type.toy", &size); + const unsigned char* tb = Toy_compileString(source, &size); free((void*)source); if (!tb) { diff --git a/test/test_parser.c b/test/test_parser.c index de3cdd3..ccaee6d 100644 --- a/test/test_parser.c +++ b/test/test_parser.c @@ -11,7 +11,7 @@ int main() { { //source - char* source = "print null;"; + const char* source = "print null;"; //test init & quit Toy_Lexer lexer; @@ -24,7 +24,7 @@ int main() { { //source - char* source = "print null;"; + const char* source = "print null;"; //test parsing Toy_Lexer lexer; @@ -58,7 +58,7 @@ int main() { { //get the source file size_t size = 0; - char* source = Toy_readFile("scripts/parser_sample_code.toy", &size); + const char* source = Toy_readFile("scripts/parser_sample_code.toy", &size); //test parsing a chunk of junk (valgrind will find leaks) Toy_Lexer lexer; @@ -85,7 +85,7 @@ int main() { { //test parsing of escaped characters - char* source = "print \"\\\"\";"; //NOTE: this string goes through two layers of escaping + const char* source = "print \"\\\"\";"; //NOTE: this string goes through two layers of escaping //test parsing Toy_Lexer lexer; @@ -123,7 +123,7 @@ int main() { { //test parsing of underscored numbers - char* source = "print 1_000_000;"; + const char* source = "print 1_000_000;"; //test parsing Toy_Lexer lexer;