From 978e7cfac4f8571dfb58e3455c4e055e66195846 Mon Sep 17 00:00:00 2001 From: Kayne Ruse Date: Sun, 18 Sep 2022 06:52:00 +0100 Subject: [PATCH] wrote a simple test for libs --- scripts/test/imports-and-exports.toy | 4 + scripts/test/lib/standard.toy | 10 ++ test/makefile | 2 +- test/test_libraries.c | 143 +++++++++++++++++++++++++++ 4 files changed, 158 insertions(+), 1 deletion(-) create mode 100644 scripts/test/lib/standard.toy create mode 100644 test/test_libraries.c diff --git a/scripts/test/imports-and-exports.toy b/scripts/test/imports-and-exports.toy index e05bf03..eb105a4 100644 --- a/scripts/test/imports-and-exports.toy +++ b/scripts/test/imports-and-exports.toy @@ -9,6 +9,7 @@ assert value == 42, "import/export failed"; } + //test functions using import/export { fn f() { @@ -18,6 +19,7 @@ } } + //test importing/exporting of functions { fn func() { @@ -32,6 +34,7 @@ assert func() == 69, "import/export of functions failed"; } + //test that variables retain their types with the typeof keyword { var t: type = int; @@ -45,4 +48,5 @@ assert typeof t == type, "type retention failed"; } + print "All good"; diff --git a/scripts/test/lib/standard.toy b/scripts/test/lib/standard.toy new file mode 100644 index 0000000..a813969 --- /dev/null +++ b/scripts/test/lib/standard.toy @@ -0,0 +1,10 @@ +//test the standard library +{ + import standard; + + //this depends on external factors, so only check the length + assert clock().length() == 24, "clock() import failed"; +} + + +print "All good"; diff --git a/test/makefile b/test/makefile index 9b87749..3ca95d4 100644 --- a/test/makefile +++ b/test/makefile @@ -5,7 +5,7 @@ CFLAGS +=$(addprefix -I,$(IDIR)) -g -Wall -W -pedantic -Wno-unused-parameter -Wn LIBS += ODIR = obj -TARGETS = $(filter-out $(wildcard ../source/*main.c),$(wildcard ../source/*.c)) +TARGETS = $(wildcard ../source/*.c) $(filter-out $(wildcard ../repl/*main.c),$(wildcard ../repl/*.c)) TESTS = $(wildcard *.c) OBJ = $(addprefix $(ODIR)/,$(TARGETS:../source/%.c=%.o)) $(addprefix $(ODIR)/,$(TESTS:.c=.o)) diff --git a/test/test_libraries.c b/test/test_libraries.c new file mode 100644 index 0000000..e97cbba --- /dev/null +++ b/test/test_libraries.c @@ -0,0 +1,143 @@ +#include "lexer.h" +#include "parser.h" +#include "compiler.h" +#include "interpreter.h" + +#include "console_colors.h" + +#include "memory.h" + +#include +#include +#include + +#include "../repl/lib_standard.h" + +//supress the print output +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 + Node* node = scanParser(&parser); + while(node != NULL) { + //pack up and leave + if (node->type == NODE_ERROR) { + printf(ERROR "error node detected\n" RESET); + freeNode(node); + freeCompiler(&compiler); + freeParser(&parser); + return NULL; + } + + writeCompiler(&compiler, node); + freeNode(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) { + Interpreter interpreter; + initInterpreter(&interpreter); + + //NOTE: supress print output for testing +// setInterpreterPrint(&interpreter, noPrintFn); + + injectNativeHook(&interpreter, "standard", hookStandard); + + runInterpreter(&interpreter, tb, size); + freeInterpreter(&interpreter); +} + +void runSource(char* source) { + size_t size = 0; + unsigned char* tb = compileString(source, &size); + if (!tb) { + return; + } + runBinary(tb, size); +} + +void runSourceFile(char* fname) { + size_t size = 0; //not used + char* source = readFile(fname, &size); + runSource(source); + free((void*)source); +} + +int main() { + { + //run each file in ../scripts/test/ + char* filenames[] = { + "standard.toy", + NULL + }; + + for (int i = 0; filenames[i]; i++) { + printf("Running %s\n", filenames[i]); + + char buffer[128]; + snprintf(buffer, 128, "../scripts/test/lib/%s", filenames[i]); + + runSourceFile(buffer); + } + } + + printf(NOTICE "All good\n" RESET); + return 0; +} +