From e6e24ca19f0995672c67554e85da9eb40e1da458 Mon Sep 17 00:00:00 2001 From: Kayne Ruse Date: Fri, 20 Jan 2023 13:42:45 +0000 Subject: [PATCH] Began working on runner library --- repl/lib_runner.c | 275 ++++++++++++++++++++++++++ repl/lib_runner.h | 12 ++ repl/repl_main.c | 28 +++ repl/repl_tools.c | 17 +- repl/repl_tools.h | 2 +- test/makefile | 2 +- test/scripts/compiler_sample_code.toy | 12 ++ test/scripts/lib/runner.toy | 16 ++ test/scripts/parser_sample_code.toy | 12 ++ test/scripts/runner_sample_code.toy | 12 ++ test/scripts/sample_code.toy | 9 - test/test_call_from_host.c | 74 +------ test/test_compiler.c | 38 +--- test/test_interpreter.c | 86 +------- test/test_libraries.c | 100 +++------- test/test_mustfail.c | 54 ++--- test/test_opaque_data_type.c | 74 +------ test/test_parser.c | 38 +--- 18 files changed, 435 insertions(+), 426 deletions(-) create mode 100644 repl/lib_runner.c create mode 100644 repl/lib_runner.h create mode 100644 test/scripts/compiler_sample_code.toy create mode 100644 test/scripts/lib/runner.toy create mode 100644 test/scripts/parser_sample_code.toy create mode 100644 test/scripts/runner_sample_code.toy delete mode 100644 test/scripts/sample_code.toy diff --git a/repl/lib_runner.c b/repl/lib_runner.c new file mode 100644 index 0000000..eb59132 --- /dev/null +++ b/repl/lib_runner.c @@ -0,0 +1,275 @@ +#include "lib_runner.h" + +#include "memory.h" +#include "interpreter.h" + +#include "repl_tools.h" + +#include +#include + +typedef struct Runner { + Interpreter interpreter; + unsigned char* bytecode; + size_t size; + + // +} Runner; + +//Toy native functions +static int nativeLoadScript(Interpreter* interpreter, LiteralArray* arguments) { + //arguments + if (arguments->count != 1) { + interpreter->errorOutput("Incorrect number of arguments to loadScript\n"); + return -1; + } + + //get the argument + Literal drivePathLiteral = popLiteralArray(arguments); + RefString* drivePath = copyRefString(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)) { + interpreter->errorOutput("Incorrect drive path format given to loadScript\n"); + deleteRefString(drivePath); + freeLiteral(drivePathLiteral); + return -1; + } + + driveLength++; + } + + RefString* drive = createRefStringLength(toCString(drivePath), driveLength); + RefString* path = createRefStringLength( &toCString(drivePath)[driveLength + 1], lengthRefString(drivePath) - driveLength ); + + //get the real drive file path + Literal driveLiteral = TO_STRING_LITERAL(drive); + Literal realDriveLiteral = getLiteralDictionary(getDriveDictionary(), driveLiteral); + + if (!IS_STRING(realDriveLiteral)) { + interpreter->errorOutput("Incorrect literal type found for drive: "); + printLiteralCustom(realDriveLiteral, interpreter->errorOutput); + interpreter->errorOutput("\n"); + freeLiteral(realDriveLiteral); + freeLiteral(driveLiteral); + deleteRefString(drive); + deleteRefString(path); + deleteRefString(drivePath); + 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); + + char* filePath = ALLOCATE(char, realLength) +1 + 1; //+1 for null + snprintf(filePath, realLength, "%s%s", toCString(realDrive), toCString(path)); + + //clean up the drivepath stuff + FREE_ARRAY(char, filePath, realLength); + deleteRefString(realDrive); + freeLiteral(realDriveLiteral); + freeLiteral(driveLiteral); + deleteRefString(drive); + deleteRefString(path); + deleteRefString(drivePath); + freeLiteral(drivePathLiteral); + + //load and compile the bytecode + size_t fileSize = 0; + char* source = readFile(filePath, &fileSize); + + if (!source) { + interpreter->errorOutput("Failed to load source file\n"); + return -1; + } + + unsigned char* bytecode = compileString(source, &fileSize); + free((void*)source); + + if (!bytecode) { + interpreter->errorOutput("Failed to compile source file\n"); + return -1; + } + + //build the runner object + Runner* runner = ALLOCATE(Runner, 1); + initInterpreter(&runner->interpreter); + runner->bytecode = bytecode; + runner->size = fileSize; + + //build the opaque object, and push it to the stack + Literal runnerLiteral = TO_OPAQUE_LITERAL(runner, OPAQUE_TAG_RUNNER); + pushLiteralArray(&interpreter->stack, runnerLiteral); + + return 1; +} + +static int nativeRunScript(Interpreter* interpreter, LiteralArray* arguments) { + //no arguments + if (arguments->count != 0) { + interpreter->errorOutput("Incorrect number of arguments to _runScript\n"); + return -1; + } + + // + + return 1; +} + +static int nativeGetScriptVar(Interpreter* interpreter, LiteralArray* arguments) { + //no arguments + if (arguments->count != 0) { + interpreter->errorOutput("Incorrect number of arguments to _getScriptVar\n"); + return -1; + } + + // + + return 1; +} + +static int nativeCallScriptFn(Interpreter* interpreter, LiteralArray* arguments) { + //no arguments + if (arguments->count != 0) { + interpreter->errorOutput("Incorrect number of arguments to _callScriptFn\n"); + return -1; + } + + // + + return 1; +} + +static int nativeResetScript(Interpreter* interpreter, LiteralArray* arguments) { + //no arguments + if (arguments->count != 0) { + interpreter->errorOutput("Incorrect number of arguments to _resetScript\n"); + return -1; + } + + // + + return 0; +} + +static int nativeFreeScript(Interpreter* interpreter, LiteralArray* arguments) { + //no arguments + if (arguments->count != 1) { + interpreter->errorOutput("Incorrect number of arguments to _freeScript\n"); + return -1; + } + + //get the runner object + Literal runnerLiteral = popLiteralArray(arguments); + + if (IS_IDENTIFIER(runnerLiteral)) { + Literal idn = runnerLiteral; + parseIdentifierToValue(interpreter, &runnerLiteral); + freeLiteral(idn); + } + + if (OPAQUE_TAG(runnerLiteral) != OPAQUE_TAG_RUNNER) { + interpreter->errorOutput("Unrecognized opaque literal in _freeScript\n"); + return -1; + } + + Runner* runner = AS_OPAQUE(runnerLiteral); + + //clear out the runner object + freeInterpreter(&runner->interpreter); + FREE_ARRAY(unsigned char, runner->bytecode, runner->size); + + FREE(Runner, runner); + + freeLiteral(runnerLiteral); + + return 0; +} + +//call the hook +typedef struct Natives { + char* name; + NativeFn fn; +} Natives; + +int hookRunner(Interpreter* interpreter, Literal identifier, Literal alias) { + //build the natives list + Natives natives[] = { + {"loadScript", nativeLoadScript}, + {"_runScript", nativeRunScript}, + {"_getScriptVar", nativeGetScriptVar}, + {"_callScriptFn", nativeCallScriptFn}, + {"_resetScript", nativeResetScript}, + {"_freeScript", nativeFreeScript}, + {NULL, NULL} + }; + + //store the library in an aliased dictionary + if (!IS_NULL(alias)) { + //make sure the name isn't taken + if (isDelcaredScopeVariable(interpreter->scope, alias)) { + interpreter->errorOutput("Can't override an existing variable\n"); + freeLiteral(alias); + return false; + } + + //create the dictionary to load up with functions + LiteralDictionary* dictionary = ALLOCATE(LiteralDictionary, 1); + 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; + + setLiteralDictionary(dictionary, name, func); + + freeLiteral(name); + 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); + + //set scope + Literal dict = TO_DICTIONARY_LITERAL(dictionary); + declareScopeVariable(interpreter->scope, alias, type); + setScopeVariable(interpreter->scope, alias, dict, false); + + //cleanup + freeLiteral(dict); + freeLiteral(type); + return 0; + } + + //default + for (int i = 0; natives[i].name; i++) { + injectNativeFn(interpreter, natives[i].name, natives[i].fn); + } + + return 0; +} + +//file system API +static LiteralDictionary driveDictionary; + +void initDriveDictionary() { + initLiteralDictionary(&driveDictionary); +} + +void freeDriveDictionary() { + freeLiteralDictionary(&driveDictionary); +} + +LiteralDictionary* getDriveDictionary() { + return &driveDictionary; +} \ No newline at end of file diff --git a/repl/lib_runner.h b/repl/lib_runner.h new file mode 100644 index 0000000..e7d2c13 --- /dev/null +++ b/repl/lib_runner.h @@ -0,0 +1,12 @@ +#pragma once + +#include "interpreter.h" + +int hookRunner(Interpreter* interpreter, Literal identifier, Literal alias); + +//file system API - these need to be set by the host +void initDriveDictionary(); +void freeDriveDictionary(); +LiteralDictionary* getDriveDictionary(); + +#define OPAQUE_TAG_RUNNER 100 diff --git a/repl/repl_main.c b/repl/repl_main.c index 5aae83c..19e579a 100644 --- a/repl/repl_main.c +++ b/repl/repl_main.c @@ -1,6 +1,7 @@ #include "repl_tools.h" #include "lib_standard.h" #include "lib_timer.h" +#include "lib_runner.h" #include "console_colors.h" @@ -27,6 +28,7 @@ void repl() { //inject the libs injectNativeHook(&interpreter, "standard", hookStandard); injectNativeHook(&interpreter, "timer", hookTimer); + injectNativeHook(&interpreter, "runner", hookRunner); for(;;) { printf("> "); @@ -88,6 +90,17 @@ void repl() { int main(int argc, const char* argv[]) { initCommand(argc, argv); + //lib setup (hacky - only really for this program) + initDriveDictionary(); + + Literal driveLiteral = TO_STRING_LITERAL(createRefString("scripts")); + Literal pathLiteral = TO_STRING_LITERAL(createRefString("scripts")); + + setLiteralDictionary(getDriveDictionary(), driveLiteral, pathLiteral); + + freeLiteral(driveLiteral); + freeLiteral(pathLiteral); + //command specific actions if (command.error) { usageCommand(argc, argv); @@ -112,12 +125,20 @@ int main(int argc, const char* argv[]) { //run source file if (command.sourcefile) { runSourceFile(command.sourcefile); + + //lib cleanup + freeDriveDictionary(); + return 0; } //run from stdin if (command.source) { runSource(command.source); + + //lib cleanup + freeDriveDictionary(); + return 0; } @@ -136,10 +157,17 @@ int main(int argc, const char* argv[]) { //run binary if (command.binaryfile) { runBinaryFile(command.binaryfile); + + //lib cleanup + freeDriveDictionary(); + return 0; } repl(); + //lib cleanup + freeDriveDictionary(); + return 0; } diff --git a/repl/repl_tools.c b/repl/repl_tools.c index df3fd2c..17b12ff 100644 --- a/repl/repl_tools.c +++ b/repl/repl_tools.c @@ -1,6 +1,7 @@ #include "repl_tools.h" #include "lib_standard.h" #include "lib_timer.h" +#include "lib_runner.h" #include "console_colors.h" @@ -18,7 +19,7 @@ char* readFile(char* path, size_t* fileSize) { if (file == NULL) { fprintf(stderr, ERROR "Could not open file \"%s\"\n" RESET, path); - exit(-1); + return NULL; } fseek(file, 0L, SEEK_END); @@ -29,7 +30,7 @@ char* readFile(char* path, size_t* fileSize) { if (buffer == NULL) { fprintf(stderr, ERROR "Not enough memory to read \"%s\"\n" RESET, path); - exit(-1); + return NULL; } size_t bytesRead = fread(buffer, sizeof(char), *fileSize, file); @@ -38,7 +39,7 @@ char* readFile(char* path, size_t* fileSize) { if (bytesRead < *fileSize) { fprintf(stderr, ERROR "Could not read file \"%s\"\n" RESET, path); - exit(-1); + return NULL; } fclose(file); @@ -46,22 +47,24 @@ char* readFile(char* path, size_t* fileSize) { return buffer; } -void writeFile(char* path, unsigned char* bytes, size_t size) { +int 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); - exit(-1); + return -1; } int written = fwrite(bytes, size, 1, file); if (written != 1) { fprintf(stderr, ERROR "Could not write file \"%s\"\n" RESET, path); - exit(-1); + return -1; } fclose(file); + + return 0; } //repl functions @@ -79,7 +82,6 @@ unsigned char* compileString(char* source, size_t* size) { while(node != NULL) { //pack up and leave if (node->type == AST_NODE_ERROR) { - printf(ERROR "error node detected\n" RESET); freeASTNode(node); freeCompiler(&compiler); freeParser(&parser); @@ -110,6 +112,7 @@ void runBinary(unsigned char* tb, size_t size) { //inject the libs injectNativeHook(&interpreter, "standard", hookStandard); injectNativeHook(&interpreter, "timer", hookTimer); + injectNativeHook(&interpreter, "runner", hookRunner); runInterpreter(&interpreter, tb, size); freeInterpreter(&interpreter); diff --git a/repl/repl_tools.h b/repl/repl_tools.h index e61a1ed..289abd1 100644 --- a/repl/repl_tools.h +++ b/repl/repl_tools.h @@ -3,7 +3,7 @@ #include "toy_common.h" char* readFile(char* path, size_t* fileSize); -void writeFile(char* path, unsigned char* bytes, size_t size); +int writeFile(char* path, unsigned char* bytes, size_t size); unsigned char* compileString(char* source, size_t* size); diff --git a/test/makefile b/test/makefile index acde163..dad42c4 100644 --- a/test/makefile +++ b/test/makefile @@ -4,7 +4,7 @@ IDIR +=. ../source ../repl CFLAGS +=$(addprefix -I,$(IDIR)) -g -Wall -W -Wno-unused-parameter -Wno-unused-function -Wno-unused-variable LIBS += ODIR = obj -TARGETS = $(wildcard ../source/*.c) $(wildcard ../repl/lib_*.c) +TARGETS = $(wildcard ../source/*.c) $(wildcard ../repl/lib_*.c) ../repl/repl_tools.c TESTS = $(wildcard test_*.c) OBJ = $(addprefix $(ODIR)/,$(TARGETS:../source/%.c=%.o)) $(addprefix $(ODIR)/,$(TESTS:.c=.o)) diff --git a/test/scripts/compiler_sample_code.toy b/test/scripts/compiler_sample_code.toy new file mode 100644 index 0000000..0c3e342 --- /dev/null +++ b/test/scripts/compiler_sample_code.toy @@ -0,0 +1,12 @@ +fn fib(n : int) { + if (n < 2) { + return n; + } + + return fib(n-1) + fib(n-2); +} + +for (var i = 0; i < 20; i++) { + var res = fib(i); + print string i + ": " + string res; +} \ No newline at end of file diff --git a/test/scripts/lib/runner.toy b/test/scripts/lib/runner.toy new file mode 100644 index 0000000..630acf2 --- /dev/null +++ b/test/scripts/lib/runner.toy @@ -0,0 +1,16 @@ +import runner; + +//test basic loading and freeing of code +{ + var s = loadScript("scripts:/runner_sample_code.toy"); + + s.freeScript(); +} + +//TODO: test running an external script +//TODO: test resetting an external script +//TODO: test retrieving a script variable +//TODO: test calling a script function + + +print "All good"; diff --git a/test/scripts/parser_sample_code.toy b/test/scripts/parser_sample_code.toy new file mode 100644 index 0000000..0c3e342 --- /dev/null +++ b/test/scripts/parser_sample_code.toy @@ -0,0 +1,12 @@ +fn fib(n : int) { + if (n < 2) { + return n; + } + + return fib(n-1) + fib(n-2); +} + +for (var i = 0; i < 20; i++) { + var res = fib(i); + print string i + ": " + string res; +} \ No newline at end of file diff --git a/test/scripts/runner_sample_code.toy b/test/scripts/runner_sample_code.toy new file mode 100644 index 0000000..0c3e342 --- /dev/null +++ b/test/scripts/runner_sample_code.toy @@ -0,0 +1,12 @@ +fn fib(n : int) { + if (n < 2) { + return n; + } + + return fib(n-1) + fib(n-2); +} + +for (var i = 0; i < 20; i++) { + var res = fib(i); + print string i + ": " + string res; +} \ No newline at end of file diff --git a/test/scripts/sample_code.toy b/test/scripts/sample_code.toy deleted file mode 100644 index 9afff30..0000000 --- a/test/scripts/sample_code.toy +++ /dev/null @@ -1,9 +0,0 @@ - - - -var complex: type = astype [string: [int]]; -var deep: type = astype [[[ int ]]]; - - - - diff --git a/test/test_call_from_host.c b/test/test_call_from_host.c index dca9797..8dc36eb 100644 --- a/test/test_call_from_host.c +++ b/test/test_call_from_host.c @@ -7,6 +7,8 @@ #include "memory.h" +#include "../repl/repl_tools.h" + #include #include #include @@ -17,78 +19,6 @@ static void noPrintFn(const char* output) { //NO OP } -//compilation functions -char* 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); - exit(-1); - } - - fseek(file, 0L, SEEK_END); - *fileSize = ftell(file); - rewind(file); - - char* buffer = (char*)malloc(*fileSize + 1); - - if (buffer == NULL) { - fprintf(stderr, ERROR "Not enough memory to read \"%s\"\n" RESET, path); - exit(-1); - } - - size_t bytesRead = fread(buffer, sizeof(char), *fileSize, file); - - buffer[*fileSize] = '\0'; //NOTE: fread doesn't append this - - if (bytesRead < *fileSize) { - fprintf(stderr, ERROR "Could not read file \"%s\"\n" RESET, path); - exit(-1); - } - - fclose(file); - - return buffer; -} - -unsigned char* compileString(char* source, size_t* size) { - Lexer lexer; - Parser parser; - Compiler compiler; - - initLexer(&lexer, source); - initParser(&parser, &lexer); - initCompiler(&compiler); - - //run the parser until the end of the source - ASTNode* node = scanParser(&parser); - while(node != NULL) { - //pack up and leave - if (node->type == AST_NODE_ERROR) { - printf(ERROR "error node detected\n" RESET); - freeASTNode(node); - freeCompiler(&compiler); - freeParser(&parser); - return NULL; - } - - writeCompiler(&compiler, node); - freeASTNode(node); - node = scanParser(&parser); - } - - //get the bytecode dump - unsigned char* tb = collateCompiler(&compiler, (int*)(size)); - - //cleanup - freeCompiler(&compiler); - freeParser(&parser); - //no lexer to clean up - - //finally - return tb; -} - void error(char* msg) { printf("%s", msg); exit(-1); diff --git a/test/test_compiler.c b/test/test_compiler.c index d50f443..54cffcc 100644 --- a/test/test_compiler.c +++ b/test/test_compiler.c @@ -6,44 +6,12 @@ #include "memory.h" +#include "../repl/repl_tools.h" + #include #include #include -//IO functions -char* 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); - exit(-1); - } - - fseek(file, 0L, SEEK_END); - *fileSize = ftell(file); - rewind(file); - - char* buffer = (char*)malloc(*fileSize + 1); - - if (buffer == NULL) { - fprintf(stderr, ERROR "Not enough memory to read \"%s\"\n" RESET, path); - exit(-1); - } - - size_t bytesRead = fread(buffer, sizeof(char), *fileSize, file); - - buffer[*fileSize] = '\0'; //NOTE: fread doesn't append this - - if (bytesRead < *fileSize) { - fprintf(stderr, ERROR "Could not read file \"%s\"\n" RESET, path); - exit(-1); - } - - fclose(file); - - return buffer; -} - int main() { { //test init & free @@ -84,7 +52,7 @@ int main() { { //source size_t sourceLength = 0; - char* source = readFile("scripts/sample_code.toy", &sourceLength); + char* source = readFile("scripts/compiler_sample_code.toy", &sourceLength); //test basic compilation & collation Lexer lexer; diff --git a/test/test_interpreter.c b/test/test_interpreter.c index 31d181c..b41fece 100644 --- a/test/test_interpreter.c +++ b/test/test_interpreter.c @@ -7,6 +7,8 @@ #include "memory.h" +#include "../repl/repl_tools.h" + #include #include #include @@ -28,79 +30,7 @@ static void noAssertFn(const char* output) { } } -//compilation functions -char* 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); - exit(-1); - } - - fseek(file, 0L, SEEK_END); - *fileSize = ftell(file); - rewind(file); - - char* buffer = (char*)malloc(*fileSize + 1); - - if (buffer == NULL) { - fprintf(stderr, ERROR "Not enough memory to read \"%s\"\n" RESET, path); - exit(-1); - } - - size_t bytesRead = fread(buffer, sizeof(char), *fileSize, file); - - buffer[*fileSize] = '\0'; //NOTE: fread doesn't append this - - if (bytesRead < *fileSize) { - fprintf(stderr, ERROR "Could not read file \"%s\"\n" RESET, path); - exit(-1); - } - - fclose(file); - - return buffer; -} - -unsigned char* compileString(char* source, size_t* size) { - Lexer lexer; - Parser parser; - Compiler compiler; - - initLexer(&lexer, source); - initParser(&parser, &lexer); - initCompiler(&compiler); - - //run the parser until the end of the source - ASTNode* node = scanParser(&parser); - while(node != NULL) { - //pack up and leave - if (node->type == AST_NODE_ERROR) { - printf(ERROR "error node detected\n" RESET); - freeASTNode(node); - freeCompiler(&compiler); - freeParser(&parser); - return NULL; - } - - writeCompiler(&compiler, node); - freeASTNode(node); - node = scanParser(&parser); - } - - //get the bytecode dump - unsigned char* tb = collateCompiler(&compiler, (int*)(size)); - - //cleanup - freeCompiler(&compiler); - freeParser(&parser); - //no lexer to clean up - - //finally - return tb; -} - -void runBinary(unsigned char* tb, size_t size) { +void runBinaryCustom(unsigned char* tb, size_t size) { Interpreter interpreter; initInterpreter(&interpreter); @@ -112,19 +42,19 @@ void runBinary(unsigned char* tb, size_t size) { freeInterpreter(&interpreter); } -void runSource(char* source) { +void runSourceCustom(char* source) { size_t size = 0; unsigned char* tb = compileString(source, &size); if (!tb) { return; } - runBinary(tb, size); + runBinaryCustom(tb, size); } -void runSourceFile(char* fname) { +void runSourceFileCustom(char* fname) { size_t size = 0; //not used char* source = readFile(fname, &size); - runSource(source); + runSourceCustom(source); free((void*)source); } @@ -208,7 +138,7 @@ int main() { char buffer[128]; snprintf(buffer, 128, "scripts/%s", filenames[i]); - runSourceFile(buffer); + runSourceFileCustom(buffer); } } diff --git a/test/test_libraries.c b/test/test_libraries.c index 0fdf458..bb40aba 100644 --- a/test/test_libraries.c +++ b/test/test_libraries.c @@ -11,8 +11,11 @@ #include #include +#include "../repl/repl_tools.h" + #include "../repl/lib_standard.h" #include "../repl/lib_timer.h" +#include "../repl/lib_runner.h" //supress the print output static void noPrintFn(const char* output) { @@ -32,78 +35,6 @@ static void errorWrapper(const char* output) { fprintf(stderr, ERROR "%s" RESET, output); } -//compilation functions -char* 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); - exit(-1); - } - - fseek(file, 0L, SEEK_END); - *fileSize = ftell(file); - rewind(file); - - char* buffer = (char*)malloc(*fileSize + 1); - - if (buffer == NULL) { - fprintf(stderr, ERROR "Not enough memory to read \"%s\"\n" RESET, path); - exit(-1); - } - - size_t bytesRead = fread(buffer, sizeof(char), *fileSize, file); - - buffer[*fileSize] = '\0'; //NOTE: fread doesn't append this - - if (bytesRead < *fileSize) { - fprintf(stderr, ERROR "Could not read file \"%s\"\n" RESET, path); - exit(-1); - } - - fclose(file); - - return buffer; -} - -unsigned char* compileString(char* source, size_t* size) { - Lexer lexer; - Parser parser; - Compiler compiler; - - initLexer(&lexer, source); - initParser(&parser, &lexer); - initCompiler(&compiler); - - //run the parser until the end of the source - ASTNode* node = scanParser(&parser); - while(node != NULL) { - //pack up and leave - if (node->type == AST_NODE_ERROR) { - printf(ERROR "error node detected\n" RESET); - freeASTNode(node); - freeCompiler(&compiler); - freeParser(&parser); - return NULL; - } - - writeCompiler(&compiler, node); - freeASTNode(node); - node = scanParser(&parser); - } - - //get the bytecode dump - unsigned char* tb = collateCompiler(&compiler, (int*)(size)); - - //cleanup - freeCompiler(&compiler); - freeParser(&parser); - //no lexer to clean up - - //finally - return tb; -} - void runBinaryWithLibrary(unsigned char* tb, size_t size, char* library, HookFn hook) { Interpreter interpreter; initInterpreter(&interpreter); @@ -127,12 +58,24 @@ typedef struct Payload { } Payload; int main() { + //setup the runner filesystem (hacky) + initDriveDictionary(); + + Literal driveLiteral = TO_STRING_LITERAL(createRefString("scripts")); + Literal pathLiteral = TO_STRING_LITERAL(createRefString("scripts")); + + setLiteralDictionary(getDriveDictionary(), driveLiteral, pathLiteral); + + freeLiteral(driveLiteral); + 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}, {NULL, NULL, NULL} }; @@ -145,17 +88,28 @@ int main() { //compile the source size_t size = 0; char* source = readFile(fname, &size); + if (!source) { + printf(ERROR "Failed to load file: %s\n" RESET, fname); + failedAsserts++; + continue; + } + unsigned char* tb = compileString(source, &size); free((void*)source); if (!tb) { - printf(ERROR "Failed to compile file: %s" RESET, fname); + printf(ERROR "Failed to compile file: %s\n" RESET, fname); + failedAsserts++; + continue; } runBinaryWithLibrary(tb, size, payloads[i].libname, payloads[i].hook); } } + //lib cleanup + freeDriveDictionary(); + if (!failedAsserts) { printf(NOTICE "All good\n" RESET); } diff --git a/test/test_mustfail.c b/test/test_mustfail.c index e53edce..bf2850e 100644 --- a/test/test_mustfail.c +++ b/test/test_mustfail.c @@ -7,6 +7,8 @@ #include "memory.h" +#include "../repl/repl_tools.h" + #include #include #include @@ -21,41 +23,7 @@ static void noErrorFn(const char* output) { errorsTriggered++; } -//compilation functions -char* 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); - exit(-1); - } - - fseek(file, 0L, SEEK_END); - *fileSize = ftell(file); - rewind(file); - - char* buffer = (char*)malloc(*fileSize + 1); - - if (buffer == NULL) { - fprintf(stderr, ERROR "Not enough memory to read \"%s\"\n" RESET, path); - exit(-1); - } - - size_t bytesRead = fread(buffer, sizeof(char), *fileSize, file); - - buffer[*fileSize] = '\0'; //NOTE: fread doesn't append this - - if (bytesRead < *fileSize) { - fprintf(stderr, ERROR "Could not read file \"%s\"\n" RESET, path); - exit(-1); - } - - fclose(file); - - return buffer; -} - -unsigned char* compileString(char* source, size_t* size) { +unsigned char* compileStringCustom(char* source, size_t* size) { Lexer lexer; Parser parser; Compiler compiler; @@ -69,7 +37,7 @@ unsigned char* compileString(char* source, size_t* size) { while(node != NULL) { //pack up and leave if (node->type == AST_NODE_ERROR) { - errorsTriggered++; + errorsTriggered++; //custom error catch freeASTNode(node); freeCompiler(&compiler); freeParser(&parser); @@ -93,7 +61,7 @@ unsigned char* compileString(char* source, size_t* size) { return tb; } -void runBinary(unsigned char* tb, size_t size) { +void runBinaryCustom(unsigned char* tb, size_t size) { Interpreter interpreter; initInterpreter(&interpreter); @@ -105,19 +73,19 @@ void runBinary(unsigned char* tb, size_t size) { freeInterpreter(&interpreter); } -void runSource(char* source) { +void runSourceCustom(char* source) { size_t size = 0; - unsigned char* tb = compileString(source, &size); + unsigned char* tb = compileStringCustom(source, &size); if (!tb) { return; } - runBinary(tb, size); + runBinaryCustom(tb, size); } -void runSourceFile(char* fname) { +void runSourceFileCustom(char* fname) { size_t size = 0; //not used char* source = readFile(fname, &size); - runSource(source); + runSourceCustom(source); free((void*)source); } @@ -142,7 +110,7 @@ int main() { char buffer[128]; snprintf(buffer, 128, "scripts/mustfail/%s", filenames[i]); - runSourceFile(buffer); + runSourceFileCustom(buffer); if (errorsTriggered == 0) { printf(ERROR "Expected error did not occur in %s\n" RESET, filenames[i]); diff --git a/test/test_opaque_data_type.c b/test/test_opaque_data_type.c index 2977bc9..eec546f 100644 --- a/test/test_opaque_data_type.c +++ b/test/test_opaque_data_type.c @@ -7,6 +7,8 @@ #include "memory.h" +#include "../repl/repl_tools.h" + #include #include @@ -15,78 +17,6 @@ static void noPrintFn(const char* output) { //NO OP } -//compilation functions -char* 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); - exit(-1); - } - - fseek(file, 0L, SEEK_END); - *fileSize = ftell(file); - rewind(file); - - char* buffer = (char*)malloc(*fileSize + 1); - - if (buffer == NULL) { - fprintf(stderr, ERROR "Not enough memory to read \"%s\"\n" RESET, path); - exit(-1); - } - - size_t bytesRead = fread(buffer, sizeof(char), *fileSize, file); - - buffer[*fileSize] = '\0'; //NOTE: fread doesn't append this - - if (bytesRead < *fileSize) { - fprintf(stderr, ERROR "Could not read file \"%s\"\n" RESET, path); - exit(-1); - } - - fclose(file); - - return buffer; -} - -unsigned char* compileString(char* source, size_t* size) { - Lexer lexer; - Parser parser; - Compiler compiler; - - initLexer(&lexer, source); - initParser(&parser, &lexer); - initCompiler(&compiler); - - //run the parser until the end of the source - ASTNode* node = scanParser(&parser); - while(node != NULL) { - //pack up and leave - if (node->type == AST_NODE_ERROR) { - printf(ERROR "error node detected\n" RESET); - freeASTNode(node); - freeCompiler(&compiler); - freeParser(&parser); - return NULL; - } - - writeCompiler(&compiler, node); - freeASTNode(node); - node = scanParser(&parser); - } - - //get the bytecode dump - unsigned char* tb = collateCompiler(&compiler, (int*)(size)); - - //cleanup - freeCompiler(&compiler); - freeParser(&parser); - //no lexer to clean up - - //finally - return tb; -} - void error(char* msg) { printf("%s", msg); exit(-1); diff --git a/test/test_parser.c b/test/test_parser.c index 3ad9732..b7aaa22 100644 --- a/test/test_parser.c +++ b/test/test_parser.c @@ -2,44 +2,12 @@ #include "console_colors.h" +#include "../repl/repl_tools.h" + #include #include #include -//IO functions -char* 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); - exit(-1); - } - - fseek(file, 0L, SEEK_END); - *fileSize = ftell(file); - rewind(file); - - char* buffer = (char*)malloc(*fileSize + 1); - - if (buffer == NULL) { - fprintf(stderr, ERROR "Not enough memory to read \"%s\"\n" RESET, path); - exit(-1); - } - - size_t bytesRead = fread(buffer, sizeof(char), *fileSize, file); - - buffer[*fileSize] = '\0'; //NOTE: fread doesn't append this - - if (bytesRead < *fileSize) { - fprintf(stderr, ERROR "Could not read file \"%s\"\n" RESET, path); - exit(-1); - } - - fclose(file); - - return buffer; -} - int main() { { //source @@ -90,7 +58,7 @@ int main() { { //get the source file size_t size = 0; - char* source = readFile("scripts/sample_code.toy", &size); + char* source = readFile("scripts/parser_sample_code.toy", &size); //test parsing a chunk of junk (valgrind will find leaks) Lexer lexer;