diff --git a/examples/http_server/main.noja b/examples/http_server/main.noja old mode 100755 new mode 100644 index d0235af..5c9aa14 --- a/examples/http_server/main.noja +++ b/examples/http_server/main.noja @@ -168,4 +168,4 @@ router->plug("/logout", { } }); -error(serve("127.0.0.1", 8080, router)); +error(serve("127.0.0.1", 8080, router)); \ No newline at end of file diff --git a/report_test_suite_coverage.sh b/report_test_suite_coverage.sh index 8331060..5e7e52f 100755 --- a/report_test_suite_coverage.sh +++ b/report_test_suite_coverage.sh @@ -1,4 +1,4 @@ make -B BUILD_MODE=COVERAGE CC=gcc -./test tests/suite +./test tests/compiler/ tests/runtime/ make report firefox report/index.html \ No newline at end of file diff --git a/src/lib/assembler/assemble.c b/src/lib/assembler/assemble.c index 89ec85c..1fd15ee 100644 --- a/src/lib/assembler/assemble.c +++ b/src/lib/assembler/assemble.c @@ -107,12 +107,57 @@ static bool parseStringOperand(Context *ctx, Error *error, BPAlloc *alloc, Opera assert(ctx->cur < ctx->len && ctx->str[ctx->cur] == '"'); ctx->cur += 1; - size_t literal_offset = ctx->cur; + char buffer[1024]; + size_t used = 0; - // For now do a dumb copy into the buffer - // without considering special characters. - while(ctx->cur < ctx->len && ctx->str[ctx->cur] != '"') - ctx->cur += 1; + do { + + size_t offset = ctx->cur; + while (ctx->cur < ctx->len && ctx->str[ctx->cur] != '\\' && ctx->str[ctx->cur] != '"') + ctx->cur++; + size_t length = ctx->cur - offset; + + if (used + length > sizeof(buffer)) { + *ctx->error_offset = ctx->cur; + Error_Report(error, ErrorType_INTERNAL, "Buffer is too short to hold string literal"); + return false; + } + memcpy(buffer + used, ctx->str + offset, length); + used += length; + + if (ctx->cur < ctx->len && ctx->str[ctx->cur] == '\\') { + + ctx->cur++; + if (ctx->cur == ctx->len) { + *ctx->error_offset = ctx->cur; + Error_Report(error, ErrorType_SYNTAX, "End of source inside a string literal"); + return false; + } + + char c; + switch (ctx->str[ctx->cur]) { + case 'n': c = '\n'; break; + case 't': c = '\t'; break; + case 'r': c = '\r'; break; + case '"': c = '"'; break; + case '\\': c = '\\'; break; + default: + *ctx->error_offset = ctx->cur; + Error_Report(error, ErrorType_SYNTAX, "End of source inside a string literal"); + return false; + } + + if (used + 1 > sizeof(buffer)) { + *ctx->error_offset = ctx->cur; + Error_Report(error, ErrorType_INTERNAL, "Buffer is too short to hold string literal"); + return false; + } + buffer[used++] = c; + + ctx->cur++; + } + + } while (ctx->cur < ctx->len && ctx->str[ctx->cur] != '"'); if(ctx->cur == ctx->len) { *ctx->error_offset = ctx->cur; @@ -120,21 +165,18 @@ static bool parseStringOperand(Context *ctx, Error *error, BPAlloc *alloc, Opera return false; } - size_t literal_length = ctx->cur - literal_offset; - // Skip the ending double quotes. assert(ctx->cur < ctx->len && ctx->str[ctx->cur] == '"'); ctx->cur += 1; - char *copy = BPAlloc_Malloc(alloc, literal_length+1); + char *copy = BPAlloc_Malloc(alloc, used+1); if(copy == NULL) { *ctx->error_offset = ctx->cur; Error_Report(error, ErrorType_INTERNAL, "No memory"); return false; } - - memcpy(copy, ctx->str + literal_offset, literal_length); - copy[literal_length] = '\0'; + memcpy(copy, buffer, used); + copy[used] = '\0'; op->type = OPTP_STRING; op->as_string = copy; diff --git a/src/lib/builtins/basic.c b/src/lib/builtins/basic.c index 3d2ca18..789947f 100644 --- a/src/lib/builtins/basic.c +++ b/src/lib/builtins/basic.c @@ -115,7 +115,7 @@ static int bin_print(Runtime *runtime, Object **argv, unsigned int argc, Object UNUSED(error); for(int i = 0; i < (int) argc; i += 1) - Object_Print(argv[i], stdout); + Object_Print(argv[i], Runtime_GetOutputStream(runtime)); return 0; } @@ -178,7 +178,7 @@ static int bin_input(Runtime *runtime, Object **argv, unsigned int argc, Object while(1) { - char c = getc(stdin); + char c = getc(Runtime_GetInputStream(runtime)); if(c == '\n') break; diff --git a/src/lib/compiler/parse.c b/src/lib/compiler/parse.c index e459e20..b5b0267 100644 --- a/src/lib/compiler/parse.c +++ b/src/lib/compiler/parse.c @@ -446,7 +446,7 @@ AST *parse(Source *src, BPAlloc *alloc, Error *error, int *error_offset) #ifdef DEBUG token_dest = fopen("tokens.txt", "wb"); #endif - + AST *ast = BPAlloc_Malloc(alloc, sizeof(AST)); if(ast == NULL) diff --git a/src/lib/runtime.c b/src/lib/runtime.c index b7dc696..3f1110a 100644 --- a/src/lib/runtime.c +++ b/src/lib/runtime.c @@ -82,6 +82,10 @@ struct xRuntime { Heap *heap; TimingTable *timing; + FILE *stdin; + FILE *stdout; + FILE *stderr; + FailedFrame failed_frame; }; @@ -112,12 +116,15 @@ RuntimeConfig Runtime_GetDefaultConfigs() .stack = 1024, .callback = { .func = NULL, .data = NULL }, .time = false, + .stdin = stdin, + .stdout = stdout, + .stderr = stderr, }; } Stack *Runtime_GetStack(Runtime *runtime) { - return Stack_Copy(runtime->stack, 1); + return runtime->stack; } Heap *Runtime_GetHeap(Runtime *runtime) @@ -352,6 +359,10 @@ Runtime *Runtime_New(RuntimeConfig config) runtime->builtins = NULL; runtime->frame = NULL; runtime->depth = 0; + + runtime->stdin = config.stdin; + runtime->stderr = config.stderr; + runtime->stdout = config.stdout; return runtime; } @@ -367,6 +378,21 @@ void Runtime_Free(Runtime *runtime) free(runtime); } +FILE *Runtime_GetErrorStream(Runtime *runtime) +{ + return runtime->stderr; +} + +FILE *Runtime_GetOutputStream(Runtime *runtime) +{ + return runtime->stdout; +} + +FILE *Runtime_GetInputStream(Runtime *runtime) +{ + return runtime->stdin; +} + _Bool Runtime_Push(Runtime *runtime, Error *error, Object *obj) { ASSERT(runtime != NULL); diff --git a/src/lib/runtime.h b/src/lib/runtime.h index e563fd8..eeb1d56 100644 --- a/src/lib/runtime.h +++ b/src/lib/runtime.h @@ -51,12 +51,17 @@ typedef struct { bool time; size_t heap; size_t stack; + FILE *stdin; + FILE *stderr; + FILE *stdout; RuntimeCallback callback; } RuntimeConfig; Runtime* Runtime_New(RuntimeConfig config); void Runtime_Free(Runtime *runtime); - +FILE *Runtime_GetErrorStream(Runtime *runtime); +FILE *Runtime_GetInputStream(Runtime *runtime); +FILE *Runtime_GetOutputStream(Runtime *runtime); bool Runtime_plugDefaultBuiltins(Runtime *runtime, Error *error); bool Runtime_plugBuiltinsFromString(Runtime *runtime, const char *string, Error *error); bool Runtime_plugBuiltinsFromFile(Runtime *runtime, const char *file, Error *error); diff --git a/src/lib/utils/stack.c b/src/lib/utils/stack.c index 27fbec7..f6c5ad9 100644 --- a/src/lib/utils/stack.c +++ b/src/lib/utils/stack.c @@ -40,11 +40,6 @@ struct xStack { void *body[]; }; -_Bool Stack_IsReadOnlyCopy(Stack *s) -{ - return (uintptr_t) s & (uintptr_t) 1; -} - void *Stack_New(int size) { if(size < 0) @@ -63,18 +58,10 @@ void *Stack_New(int size) return s; } -static Stack *unmark(Stack *s) -{ - return (Stack*) ((intptr_t) s & ~ (intptr_t) 1); -} - void *Stack_Top(Stack *s, int n) { ASSERT(n <= 0); - // Remove readonly bit. - s = unmark(s); - if(s->used == 0) return NULL; @@ -88,12 +75,6 @@ void **Stack_TopRef(Stack *s, int n) { ASSERT(n <= 0); - if(Stack_IsReadOnlyCopy(s)) - return NULL; - - // Remove readonly bit. - s = unmark(s); - if(s->used == 0) return NULL; @@ -106,9 +87,6 @@ void **Stack_TopRef(Stack *s, int n) _Bool Stack_Pop(Stack *s, unsigned int n) { - if(Stack_IsReadOnlyCopy(s)) - return 0; - if(s->used < n) return 0; @@ -121,9 +99,6 @@ _Bool Stack_Push(Stack *s, void *item) ASSERT(s != NULL); ASSERT(item != NULL); - if(Stack_IsReadOnlyCopy(s)) - return 0; - if(s->used == s->size) return 0; @@ -132,51 +107,26 @@ _Bool Stack_Push(Stack *s, void *item) return 1; } -Stack *Stack_Copy(Stack *s, _Bool readonly) +Stack *Stack_Copy(Stack *s) { - if(Stack_IsReadOnlyCopy(s)) - { - // Reference is readonly, - // so the copy must be - // readonly. - readonly = 1; - - // Remove readonly bit. - s = unmark(s); - } - s->refs += 1; - - if(readonly) - return (Stack*) ((uintptr_t) s | (intptr_t) 1); - else - return s; + return s; } void Stack_Free(Stack *s) { - // Remove readonly bit. - s = unmark(s); - s->refs -= 1; ASSERT(s->refs >= 0); - if(s->refs == 0) free(s); } unsigned int Stack_Size(Stack *s) { - // Remove readonly bit. - s = unmark(s); - return s->used; } unsigned int Stack_Capacity(Stack *s) { - // Remove readonly bit. - s = unmark(s); - return s->size; } \ No newline at end of file diff --git a/src/lib/utils/stack.h b/src/lib/utils/stack.h index 8f85d9b..564138f 100644 --- a/src/lib/utils/stack.h +++ b/src/lib/utils/stack.h @@ -37,8 +37,7 @@ _Bool Stack_Pop(Stack *s, unsigned int n); _Bool Stack_Push(Stack *s, void *item); void Stack_Free(Stack *s); unsigned int Stack_Size(Stack *s); -Stack *Stack_Copy(Stack *s, _Bool readonly); +Stack *Stack_Copy(Stack *s); void **Stack_TopRef(Stack *s, int n); unsigned int Stack_Capacity(Stack *s); -_Bool Stack_IsReadOnlyCopy(Stack *s); #endif \ No newline at end of file diff --git a/src/test/error.c b/src/test/error.c new file mode 100644 index 0000000..4b1cca4 --- /dev/null +++ b/src/test/error.c @@ -0,0 +1,14 @@ +#include "error.h" + +const char *getErrorString(ErrorID error) +{ + switch (error) { + case ErrorID_VOID: return "No error"; + case ErrorID_OUTOFMEMORY: return "Out of memory"; + case ErrorID_DUPLFIELD: return "Duplicate field"; + case ErrorID_BADSYNTAX_NOAT: return "Missing '@' character"; + case ErrorID_BADSYNTAX_NONAME: return "Missing field name"; + case ErrorID_BADSYNTAX_NOFIELD: return "Missing field"; + } + return "???"; +} \ No newline at end of file diff --git a/src/test/error.h b/src/test/error.h new file mode 100644 index 0000000..c01f739 --- /dev/null +++ b/src/test/error.h @@ -0,0 +1,14 @@ +#ifndef TEST_ERROR_H +#define TEST_ERROR_H + +typedef enum { + ErrorID_VOID, + ErrorID_OUTOFMEMORY, + ErrorID_DUPLFIELD, + ErrorID_BADSYNTAX_NONAME, + ErrorID_BADSYNTAX_NOAT, + ErrorID_BADSYNTAX_NOFIELD, +} ErrorID; + +const char *getErrorString(ErrorID error); +#endif \ No newline at end of file diff --git a/src/test/error.o b/src/test/error.o new file mode 100644 index 0000000..1e7b974 Binary files /dev/null and b/src/test/error.o differ diff --git a/src/test/field.c b/src/test/field.c new file mode 100644 index 0000000..488072a --- /dev/null +++ b/src/test/field.c @@ -0,0 +1,140 @@ +#include +#include +#include +#include +#include "field.h" + +static void freeFieldName(NojaTestField *field) +{ + if (field->name != field->name_maybe) + free(field->name); +} + +static void freeFieldBody(NojaTestField *field) +{ + if (field->body != field->body_maybe) + free(field->body); +} + +void freeField(NojaTestField *field) +{ + freeFieldName(field); + freeFieldBody(field); +} + +static ErrorID setFieldName(NojaTestField *field, const char *str, size_t len) +{ + if (len < sizeof(field->name_maybe)) + field->name = field->name_maybe; + else { + field->name = malloc(len+1); + if (field->name == NULL) + return ErrorID_OUTOFMEMORY; + } + memcpy(field->name, str, len); + field->name[len] = '\0'; + return ErrorID_VOID; +} + +static ErrorID setFieldBody(NojaTestField *field, const char *str, size_t len) +{ + if (len < sizeof(field->body_maybe)) + field->body = field->body_maybe; + else { + field->body = malloc(len+1); + if (field->body == NULL) + return ErrorID_OUTOFMEMORY; + } + memcpy(field->body, str, len); + field->body[len] = '\0'; + return ErrorID_VOID; +} + +static int isFieldNameCharacter(int c) +{ + return isalpha(c) || c == '_'; +} + +static ErrorID parseFieldName(NojaTestScanner *scanner, NojaTestField *field) +{ + size_t offset; + size_t length; + + offset = scanner->cur; + consumeCharactersThat(scanner, isFieldNameCharacter); + length = scanner->cur - offset; + + if (length == 0) + return ErrorID_BADSYNTAX_NONAME; // Missing field name token after '@' + + ErrorID error = setFieldName(field, scanner->src + offset, length); + if (error != ErrorID_VOID) return error; + + return ErrorID_VOID; +} + +static bool parseFieldBody(NojaTestScanner *scanner, NojaTestField *field) +{ + size_t offset; + size_t length; + + consumeCharactersThat(scanner, isspace); + + bool no_term; + char term; + + if (ifFollowsConsumeCharacter(scanner, '[')) { + no_term = false; + term = ']'; + } else if (ifFollowsConsumeCharacter(scanner, '{')) { + no_term = false; + term = '}'; + } else + no_term = true; + + offset = scanner->cur; + while (!noMoreCharacters(scanner) && !followsCharacter(scanner, '@') && (no_term || !followsCharacter(scanner, term))) + scanner->cur++; + length = scanner->cur - offset; + if (!no_term) + ifFollowsConsumeCharacter(scanner, term); + + return setFieldBody(field, scanner->src + offset, length); +} + +ErrorID findField(NojaTestScanner *scanner) +{ + consumeCharactersThat(scanner, isspace); + bool at_follows = ifFollowsConsumeCharacter(scanner, '@'); + if (!at_follows) { + if (noMoreCharacters(scanner)) + return ErrorID_BADSYNTAX_NOFIELD; + return ErrorID_BADSYNTAX_NOAT; + } + return ErrorID_VOID; +} + +// Returns: +// 0 if there are no more fields +// -1 on error +// 1 if a field was parsed +ErrorID parseField(NojaTestScanner *scanner, NojaTestField *field) +{ + ErrorID error; + + error = findField(scanner); + if (error != ErrorID_VOID) + return error; + + error = parseFieldName(scanner, field); + if (error != ErrorID_VOID) + return error; + + error = parseFieldBody(scanner, field); + if (error != ErrorID_VOID) { + freeFieldName(field); + return error; + } + + return ErrorID_VOID; +} diff --git a/src/test/field.h b/src/test/field.h new file mode 100644 index 0000000..237a965 --- /dev/null +++ b/src/test/field.h @@ -0,0 +1,20 @@ +#ifndef TEST_FIELD_H +#define TEST_FIELD_H + +#include +#include "error.h" +#include "scanner.h" + +typedef struct { + char name_maybe[128]; + char body_maybe[512]; + char *name; + char *body; + size_t name_len; + size_t body_len; +} NojaTestField; + +void freeField(NojaTestField *field); +ErrorID parseField(NojaTestScanner *scanner, NojaTestField *field); + +#endif \ No newline at end of file diff --git a/src/test/field.o b/src/test/field.o new file mode 100644 index 0000000..91bb310 Binary files /dev/null and b/src/test/field.o differ diff --git a/src/test/main.c b/src/test/main.c index 5f0f9ad..5fd5b4f 100644 --- a/src/test/main.c +++ b/src/test/main.c @@ -1,497 +1,140 @@ -#include -#include -#include -#include -#include -#include -#include "../lib/executable.h" -#include "../lib/utils/source.h" -#include "../lib/compiler/compile.h" -#include "../lib/assembler/assemble.h" - -//Regular text -#define BLK "\e[0;30m" -#define RED "\e[0;31m" -#define GRN "\e[0;32m" -#define YEL "\e[0;33m" -#define BLU "\e[0;34m" -#define MAG "\e[0;35m" -#define CYN "\e[0;36m" -#define WHT "\e[0;37m" - -//Regular bold text -#define BBLK "\e[1;30m" -#define BRED "\e[1;31m" -#define BGRN "\e[1;32m" -#define BYEL "\e[1;33m" -#define BBLU "\e[1;34m" -#define BMAG "\e[1;35m" -#define BCYN "\e[1;36m" -#define BWHT "\e[1;37m" - -//Regular underline text -#define UBLK "\e[4;30m" -#define URED "\e[4;31m" -#define UGRN "\e[4;32m" -#define UYEL "\e[4;33m" -#define UBLU "\e[4;34m" -#define UMAG "\e[4;35m" -#define UCYN "\e[4;36m" -#define UWHT "\e[4;37m" - -//Regular background -#define BLKB "\e[40m" -#define REDB "\e[41m" -#define GRNB "\e[42m" -#define YELB "\e[43m" -#define BLUB "\e[44m" -#define MAGB "\e[45m" -#define CYNB "\e[46m" -#define WHTB "\e[47m" - -//High intensty background -#define BLKHB "\e[0;100m" -#define REDHB "\e[0;101m" -#define GRNHB "\e[0;102m" -#define YELHB "\e[0;103m" -#define BLUHB "\e[0;104m" -#define MAGHB "\e[0;105m" -#define CYNHB "\e[0;106m" -#define WHTHB "\e[0;107m" - -//High intensty text -#define HBLK "\e[0;90m" -#define HRED "\e[0;91m" -#define HGRN "\e[0;92m" -#define HYEL "\e[0;93m" -#define HBLU "\e[0;94m" -#define HMAG "\e[0;95m" -#define HCYN "\e[0;96m" -#define HWHT "\e[0;97m" - -//Bold high intensity text -#define BHBLK "\e[1;90m" -#define BHRED "\e[1;91m" -#define BHGRN "\e[1;92m" -#define BHYEL "\e[1;93m" -#define BHBLU "\e[1;94m" -#define BHMAG "\e[1;95m" -#define BHCYN "\e[1;96m" -#define BHWHT "\e[1;97m" - -//Reset -#define reset "\e[0m" -#define CRESET "\e[0m" -#define COLOR_RESET "\e[0m" - -// NOTE: From https://gist.github.com/RabaDabaDoba/145049536f815903c79944599c6f952a - -typedef enum { - TokenType_END, - TokenType_TEXT, - TokenType_DIRECTIVE_SOURCE, - TokenType_DIRECTIVE_BYTECODE, -} TokenType; - -typedef struct { - TokenType type; - size_t offset; - size_t length; -} Token; - -static bool startsWithSourceDirective(const char *str, size_t len) -{ - return (((7 < len && !isalpha(str[7])) || 7 == len) - && str[0] == '#' && str[1] == 's' - && str[2] == 'o' && str[3] == 'u' - && str[4] == 'r' && str[5] == 'c' - && str[6] == 'e'); -} - -static bool startsWithBytecodeDirective(const char *str, size_t len) -{ - return (((9 < len && !isalpha(str[9])) || 9 == len) - && str[0] == '#' && str[1] == 'b' - && str[2] == 'y' && str[3] == 't' - && str[4] == 'e' && str[5] == 'c' - && str[6] == 'o' && str[7] == 'd' - && str[8] == 'e'); -} - -static bool startsWithDirective(const char *str, size_t len) -{ - return startsWithSourceDirective(str, len) - || startsWithBytecodeDirective(str, len); -} - -static Token nextToken(const char *str, size_t len, size_t *cur_) -{ - size_t cur = *cur_; - - while(cur < len && isspace(str[cur])) - cur += 1; - - Token token; - if(cur == len) { - token.type = TokenType_END; - token.offset = cur; - token.length = 0; - } else if(startsWithSourceDirective(str + cur, len - cur)) { - token.type = TokenType_DIRECTIVE_SOURCE; - token.offset = cur; - cur += strlen("#source"); - token.length = cur - token.offset; - } else if(startsWithBytecodeDirective(str + cur, len - cur)) { - token.type = TokenType_DIRECTIVE_BYTECODE; - token.offset = cur; - cur += strlen("#bytecode"); - token.length = cur - token.offset; - } else { - token.type = TokenType_TEXT; - token.offset = cur; - - while(1) { - // Consume all characters until - // the next '#'. - while(cur < len && str[cur] != '#') - cur += 1; - - if(cur == len) - break; - - // If it's the start of a directive, - // stop the loop. If it was not, skip - // the '#'. - - if(startsWithDirective(str + cur, len - cur)) - break; - - cur += 1; // Skip the '#' - } - - token.length = cur - token.offset; - } - *cur_ = cur; - return token; -} - -typedef struct { - Source *source; - Source *bytecode; -} TestCase; - -static bool parseTestCaseSource(Source *source, TestCase *testcase) -{ - const char *str = Source_GetBody(source); - size_t len = Source_GetSize(source); - assert(str != NULL); - - bool no_source = true; - size_t source_offset; - size_t source_length; - - bool no_bytecode = true; - size_t bytecode_offset; - size_t bytecode_length; - - size_t cur = 0; - while(1) { - Token token = nextToken(str, len, &cur); - - if(token.type == TokenType_END) - break; - - if(token.type == TokenType_TEXT) { - fprintf(stderr, RED "Error" CRESET " :: Expected a directive at offset %ld\n", token.offset); - return false; - } - - assert(token.type == TokenType_DIRECTIVE_SOURCE - || token.type == TokenType_DIRECTIVE_BYTECODE); - - Token directive = token; - - size_t directive_body_offset; - size_t directive_body_length; - - size_t backup = cur; - token = nextToken(str, len, &cur); - switch(token.type) { - case TokenType_END: - case TokenType_DIRECTIVE_SOURCE: - case TokenType_DIRECTIVE_BYTECODE: - // Right after the previous directive - // there's either the end of the file - // or another directive. We assume - // that the directive is followed by - // and empty string. - directive_body_offset = token.offset; - directive_body_length = 0; - - // Put the cursor back so that this - // token is tokenized again at the - // start of the next iteration. - cur = backup; - break; - - case TokenType_TEXT: - directive_body_offset = token.offset; - directive_body_length = token.length; - break; - } - - if(directive.type == TokenType_DIRECTIVE_SOURCE) { - - if(no_source == false) { - fprintf(stderr, RED "Error" CRESET " :: #source directive specified twice.\n"); - return false; - } - - no_source = false; - source_offset = directive_body_offset; - source_length = directive_body_length; - - } else { - assert(directive.type == TokenType_DIRECTIVE_BYTECODE); - - if(no_bytecode == false) { - fprintf(stderr, RED "Error" CRESET " :: #bytecode directive specified twice.\n"); - return false; - } - - no_bytecode = false; - bytecode_offset = directive_body_offset; - bytecode_length = directive_body_length; - } - } - - if(no_source == true && no_bytecode == true) { - fprintf(stderr, RED "Error" CRESET " :: Missing both #source and #bytecode directives.\n"); - return false; - } - if(no_source == true) { - fprintf(stderr, RED "Error" CRESET " :: Missing #source directive.\n"); - return false; - } - if(no_bytecode == true) { - fprintf(stderr, RED "Error" CRESET " :: Missing #bytecode directive.\n"); - return false; - } - - { - Error error; - Error_Init(&error); - - testcase->source = Source_FromString("", str + source_offset, source_length, &error); - if(testcase->source == NULL) { - Error_Print(&error, ErrorType_UNSPECIFIED, stderr); - Error_Free(&error); - return false; - } - - testcase->bytecode = Source_FromString("", str + bytecode_offset, bytecode_length, &error); - if(testcase->bytecode == NULL) { - Error_Print(&error, ErrorType_UNSPECIFIED, stderr); - Source_Free(testcase->source); - Error_Free(&error); - return false; - } - Error_Free(&error); - } - return true; -} - -static Executable *compile_source_and_print_error_on_failure(Source *src) -{ - int error_offset; - Error error; - Error_Init(&error); - Executable *exe = compile(src, &error, &error_offset); - if(exe == NULL) { - Error_Print(&error, ErrorType_UNSPECIFIED, stderr); - Error_Free(&error); - return NULL; - } - Error_Free(&error); - return exe; -} - -typedef enum { - TestResult_PASSED, - TestResult_FAILED, - TestResult_ABORT, -} TestResult; - -static TestResult runTest(const char *file) -{ - Source *source; - { - Error error; - Error_Init(&error); - - source = Source_FromFile(file, &error); - if(source == NULL) { - Error_Print(&error, ErrorType_UNSPECIFIED, stderr); - Error_Free(&error); - return TestResult_ABORT; - } - Error_Free(&error); - } - - TestCase testcase; - { - if(!parseTestCaseSource(source, &testcase)) { - Source_Free(source); - return TestResult_ABORT; - } - } - - Source_Free(source); - - Executable *exe1 = compile_source_and_print_error_on_failure(testcase.source); - if(exe1 == NULL) { - Source_Free(testcase.source); - Source_Free(testcase.bytecode); - return TestResult_ABORT; - } - - Executable *exe2; - { - Error error; - Error_Init(&error); - int error_offset; - exe2 = assemble(testcase.bytecode, &error, &error_offset); - if(exe2 == NULL) { - Error_Print(&error, ErrorType_UNSPECIFIED, stderr); - Error_Free(&error); - Executable_Free(exe1); - Source_Free(testcase.source); - Source_Free(testcase.bytecode); - return TestResult_ABORT; - } - - Error_Free(&error); - } - - bool passed = Executable_Equiv(exe1, exe2, stderr, " " WHT "Log" CRESET " :: "); - - Executable_Free(exe1); - Executable_Free(exe2); - Source_Free(testcase.source); - Source_Free(testcase.bytecode); - - return passed - ? TestResult_PASSED - : TestResult_FAILED; -} - -static void runTestSuite(const char *folder) -{ - DIR *handle = opendir(folder); - if(handle == NULL) { - fprintf(stderr, RED "Error" CRESET " :: Failed to open folder '%s'.\n", folder); - return; - } - - size_t total_tests = 0; - size_t passed_tests = 0; - size_t failed_tests = 0; - size_t aborted_tests = 0; - size_t skipped_files = 0; - - size_t folder_len = strlen(folder); - - // If the folder path ends with a "/", - // but it's not the first character, - // then pop it. - if(folder_len > 0 && folder[folder_len-1] == '/') - folder_len -= 1; - - // Now we know for sure that the provided - // folder needs a trailing "/". - - char test_path[1024]; - - // Make sure the buffer can contain the - // folder's name (plus the trailing "/" - // and the null byte). - if(folder_len+2 > sizeof(test_path)) { - fprintf(stderr, RED "Error" CRESET " :: Suite folder name is too long\n"); - return; - } - memcpy(test_path, folder, folder_len); - test_path[folder_len] = '/'; - test_path[folder_len+1] = '\0'; - - // Now count the "/". - folder_len += 1; - - struct dirent *dir; - while((dir = readdir(handle)) != NULL) { - - const char *name = dir->d_name; - size_t name_len = strlen(name); - - if(dir->d_type != DT_REG) { - fprintf(stderr, " " WHT "Log" CRESET " :: Skipping '%s' (not a regular file).\n", name); - skipped_files += 1; - continue; - } - - if(folder_len + name_len >= sizeof(test_path)) { - fprintf(stderr, " " WHT "Log" CRESET " :: Skipping '%s' (path is too long).\n", name); - skipped_files += 1; - continue; - } - - // Remove the previous file's name - // by truncating the parent folder - // name with a null byte. - test_path[folder_len] = '\0'; - strcat(test_path, name); - - TestResult res = runTest(test_path); - switch(res) { - - case TestResult_PASSED: - fprintf(stdout, " " BLU "Test" CRESET " :: Passed (%s)\n", name); - passed_tests += 1; - break; - - case TestResult_FAILED: - fprintf(stdout, " " YEL "Test" CRESET " :: Failed (%s)\n", name); - failed_tests += 1; - break; - - case TestResult_ABORT: - fprintf(stdout, " " RED "Test" CRESET " :: Aborted (%s)\n", name); - aborted_tests += 1; - break; - } - total_tests += 1; - } - - fprintf(stdout, "\n"); - fprintf(stdout, "@-----SUMMARY-----@\n"); - fprintf(stdout, "| Total : %-3ld |\n", total_tests); - fprintf(stdout, "| Passed : %-3ld |\n", passed_tests); - fprintf(stdout, "| Failed : %-3ld |\n", failed_tests); - fprintf(stdout, "| Aborted : %-3ld |\n", aborted_tests); - fprintf(stdout, "| Skipped : %-3ld |\n", skipped_files); - fprintf(stdout, "@-----------------@\n"); - - closedir(handle); -} - -int main(int argc, char **argv) -{ - if(argc < 2) { - fprintf(stderr, RED "Error" CRESET " :: No test suite folder name was provided.\n"); - fprintf(stderr, WHT "Usage" CRESET " :: %s \n", argv[0]); - return -1; - } - - const char *folder = argv[1]; - runTestSuite(folder); - return 0; +#include +#include +#include +#include "main.h" +#include "run.h" +#include "../lib/run.h" +#include "../lib/runtime.h" +#include "../lib/executable.h" +#include "../lib/compiler/compile.h" +#include "../lib/assembler/assemble.h" + +static TestResult runCompilerTest(const char *inputs[static 2], FILE *log_stream); +static TestResult runRuntimeTest(const char *inputs[static 2], FILE *log_stream); + +static const TestType test_types[] = { + {.name="compiler", .routine=runCompilerTest, .fields=(const char*[]){"source", "bytecode", NULL}}, + {.name="runtime", .routine=runRuntimeTest, .fields=(const char*[]){"bytecode", "output", NULL}}, + {.name=NULL, .fields=NULL, .routine=NULL}, +}; + +int main(int argc, char **argv) +{ + TestBatchResults results = {.passed=0, .failed=0, .aborted=0, .batch_aborted=false}; + for (int i = 1; i < argc; i++) { + + const char *dir_name = argv[i]; + + TestBatchResults temp = runTestDirectory(test_types, dir_name, stderr); + if (temp.batch_aborted) + fprintf(stderr, "Error: Failed to run test batch\n"); + else { + results.passed += temp.passed; + results.failed += temp.failed; + results.aborted += temp.aborted; + } + } + fprintf(stderr, "SUMMARY: %ld passed, %ld failed, %ld aborted\n", + results.passed, results.failed, results.aborted); + return 0; +} + +static TestResult runCompilerTest(const char *inputs[static 2], FILE *log_stream) +{ + Error error; + Error_Init(&error); + + Source *srcA = Source_FromString("", inputs[0], -1, &error); + if (srcA == NULL) { + Error_Print(&error, ErrorType_UNSPECIFIED, log_stream); + Error_Free(&error); + return TestResult_ABORTED; + } + Source *srcB = Source_FromString("", inputs[1], -1, &error); + if (srcA == NULL) { + Error_Print(&error, ErrorType_UNSPECIFIED, log_stream); + Error_Free(&error); + Source_Free(srcA); + return TestResult_ABORTED; + } + + int error_offset; + Executable *exeA = compile(srcA, &error, &error_offset); + if (exeA == NULL) { + Error_Print(&error, ErrorType_UNSPECIFIED, log_stream); + Error_Free(&error); + Source_Free(srcA); + Source_Free(srcB); + return TestResult_ABORTED; + } + + Executable *exeB = assemble(srcB, &error, &error_offset); + if (exeB == NULL) { + Error_Print(&error, ErrorType_UNSPECIFIED, log_stream); + Error_Free(&error); + Source_Free(srcA); + Source_Free(srcB); + Executable_Free(exeA); + return TestResult_ABORTED; + } + + bool passed = Executable_Equiv(exeA, exeB, log_stream, "Info: "); + + Source_Free(srcA); + Source_Free(srcB); + Executable_Free(exeA); + Executable_Free(exeB); + return passed ? TestResult_PASSED : TestResult_FAILED; +} + +static TestResult runRuntimeTest(const char *inputs[static 2], FILE *log_stream) +{ + char buffer[1024]; + + FILE *output_stream = fmemopen(buffer, sizeof(buffer), "wb"); + if (output_stream == NULL) + return TestResult_ABORTED; + + RuntimeConfig config = Runtime_GetDefaultConfigs(); + config.stdout = output_stream; + + Runtime *runtime = Runtime_New(config); + if (runtime == NULL) { + fclose(output_stream); + return TestResult_ABORTED; + } + + Error error; + Error_Init(&error); + + if (!Runtime_plugDefaultBuiltins(runtime, &error)) { + Error_Print(&error, ErrorType_UNSPECIFIED, log_stream); + Error_Free(&error); + Runtime_PrintStackTrace(runtime, log_stream); + Runtime_Free(runtime); + fclose(output_stream); + return TestResult_ABORTED; + } + + if (!runBytecodeString(runtime, inputs[0], &error)) { + Error_Print(&error, ErrorType_UNSPECIFIED, log_stream); + Error_Free(&error); + Runtime_PrintStackTrace(runtime, log_stream); + Runtime_Free(runtime); + fclose(output_stream); + return TestResult_ABORTED; + } + fclose(output_stream); + + TestResult result; + if (!strcmp(buffer, inputs[1])) // No bounds checks + result = TestResult_PASSED; + else { + result = TestResult_FAILED; + fprintf(stderr, "Error: Expected output [%s] but got [%s]\n", inputs[1], buffer); + } + + Error_Free(&error); + Runtime_Free(runtime); + return result; } \ No newline at end of file diff --git a/src/test/main.h b/src/test/main.h new file mode 100644 index 0000000..7a349e2 --- /dev/null +++ b/src/test/main.h @@ -0,0 +1,8 @@ +#ifndef MAIN_H +#define MAIN_H +typedef enum { + TestResult_ABORTED, + TestResult_FAILED, + TestResult_PASSED, +} TestResult; +#endif \ No newline at end of file diff --git a/src/test/main.o b/src/test/main.o new file mode 100644 index 0000000..7fa37a5 Binary files /dev/null and b/src/test/main.o differ diff --git a/src/test/run.c b/src/test/run.c new file mode 100644 index 0000000..a3467b7 --- /dev/null +++ b/src/test/run.c @@ -0,0 +1,210 @@ +#include +#include +#include +#include +#include "run.h" +#include "test.h" + +static const TestType *findTestType(const TestType *test_types, const char *name) +{ + for (size_t i = 0; test_types[i].name != NULL; i++) + if (!strcmp(name, test_types[i].name)) + return test_types + i; + return NULL; +} + +TestResult runTestString(const TestType *test_types, const char *src, FILE *log_stream) +{ + NojaTest test; + ErrorID error = parseTest(src, &test); + if (error != ErrorID_VOID) { + fprintf(log_stream, "Error: %s\n", getErrorString(error)); + return TestResult_ABORTED; + } + + const char *type = queryTest(&test, "type"); + if (type == NULL) { + fprintf(log_stream, "Error: Test is missing the \"type\" field\n"); + return TestResult_ABORTED; + } + + const TestType *info = findTestType(test_types, type); + if (info == NULL) { + fprintf(log_stream, "Error: Invalid test type \"%s\"\n", type); + return TestResult_ABORTED; + } + + bool uses_type = false; + const char *ordered_fields[8]; + + size_t i = 0; + while (info->fields[i] != NULL) { + + uses_type = uses_type || !strcmp(info->fields[i], "type"); + + const char *field = queryTest(&test, info->fields[i]); + if (field == NULL) { + fprintf(log_stream, "Error: Test is missing the \"%s\" field, necessary for \"%s\" tests\n", info->fields[i], info->name); + return TestResult_ABORTED; + } + + if (i == sizeof(ordered_fields)/sizeof(ordered_fields[0])) + abort(); + + ordered_fields[i] = field; + i++; + } + size_t used_fields = i; + + size_t unused_fields = test.fields_count - used_fields; + if (!uses_type) unused_fields--; + + if (unused_fields > 0) + fprintf(log_stream, "Warning: %ld field of the test weren't used\n", unused_fields); + + TestResult result = info->routine(ordered_fields, log_stream); + + freeTest(&test); + return result; +} + +static char *getStreamData(FILE *file_stream, FILE *log_stream) +{ + size_t copied = 0, just_copied; + size_t capacity = 512; + char *content = NULL; + do { + + capacity *= 2; + + content = realloc(content, capacity); + if (content == NULL) { + fprintf(log_stream, "Error: Out of memory\n"); + return NULL; + } + + just_copied = fread(content + copied, 1, capacity - copied, file_stream); + copied += just_copied; + + } while (just_copied > 0); + + if (ferror(file_stream)) { + free(content); + fprintf(log_stream, "Error: Couldn't read file contents\n"); + return NULL; + } + + if (copied+1 >= capacity) { + content = realloc(content, capacity+1); + if (content == NULL) { + fprintf(log_stream, "Error: Out of memory"); + return NULL; + } + } + content[copied] = '\0'; + + return content; +} + +TestResult runTestFile(const TestType *test_types, const char *file, FILE *log_stream) +{ + FILE *file_stream = fopen(file, "rb"); + if (file_stream == NULL) { + fprintf(log_stream, "Error: Couldn't open file \"%s\" (%s)\n", file, strerror(errno)); + return TestResult_ABORTED; + } + + char *data = getStreamData(file_stream, log_stream); + if (data == NULL) { + fclose(file_stream); + return TestResult_ABORTED; + } + + TestResult result = runTestString(test_types, data, log_stream); + + free(data); + fclose(file_stream); + return result; +} + +static const char *getExtension(const char *file) +{ + int dot = -1; + for (int i = 0; file[i] != '\0'; i++) + if (file[i] == '.') + dot = i; + + return (dot == -1) ? "" : file + dot; +} + +TestBatchResults runTestDirectory(const TestType *test_types, const char *dir_name, FILE *log_stream) +{ + TestBatchResults results = {.passed=0, .failed=0, .aborted=0, .batch_aborted=false}; + + DIR *d = opendir(dir_name); + if (d == NULL) { + results.batch_aborted = true; + return results; + } + + struct dirent *ent; + while ((ent = readdir(d)) != NULL) { + + if (ent->d_name[0] == '.') { + //fprintf(log_stream, "Info: Ignoring file \"%s\"\n", ent->d_name); + continue; + } + + char full[1024]; + strcpy(full, dir_name); + if (dir_name[strlen(dir_name)-1] != '/') + strcat(full, "/"); + strcat(full, ent->d_name); + + if (ent->d_type == DT_DIR) { + TestBatchResults sub_results = runTestDirectory(test_types, full, log_stream); + if (!sub_results.batch_aborted) { + results.passed += sub_results.passed; + results.failed += sub_results.failed; + results.aborted += sub_results.aborted; + } + continue; + } + + if (ent->d_type == DT_UNKNOWN) { + abort(); + } + + if (ent->d_type != DT_REG) { + //fprintf(log_stream, "Info: Ignoring file \"%s\"\n", ent->d_name); + continue; + } + + const char *ext = getExtension(ent->d_name); + if (strcmp(ext, ".noja-test")) { + //fprintf(log_stream, "Info: Ignoring file \"%s\"\n", ent->d_name); + continue; + } + + TestResult result = runTestFile(test_types, full, log_stream); + switch (result) { + case TestResult_PASSED: + fprintf(log_stream, "Test %s .. PASSED\n", full); + results.passed++; + break; + + case TestResult_FAILED: + fprintf(log_stream, "Test %s .. FAILED\n", full); + results.failed++; + break; + + case TestResult_ABORTED: + fprintf(log_stream, "Test %s .. ABORTED\n", full); + results.aborted++; + break; + } + } + + closedir(d); + return results; +} diff --git a/src/test/run.h b/src/test/run.h new file mode 100644 index 0000000..5f8f9c8 --- /dev/null +++ b/src/test/run.h @@ -0,0 +1,21 @@ +#include +#include +#include +#include "main.h" + +typedef struct { + const char *name; + const char **fields; + TestResult (*routine)(const char **fields, FILE *log_stream); +} TestType; + +typedef struct { + size_t passed; + size_t failed; + size_t aborted; + bool batch_aborted; +} TestBatchResults; + +TestResult runTestFile(const TestType *test_types, const char *file, FILE *log_stream); +TestResult runTestString(const TestType *test_types, const char *src, FILE *log_stream); +TestBatchResults runTestDirectory(const TestType *test_types, const char *dir_name, FILE *log_stream); diff --git a/src/test/run.o b/src/test/run.o new file mode 100644 index 0000000..c9d2477 Binary files /dev/null and b/src/test/run.o differ diff --git a/src/test/scanner.c b/src/test/scanner.c new file mode 100644 index 0000000..099ff84 --- /dev/null +++ b/src/test/scanner.c @@ -0,0 +1,65 @@ +#include "scanner.h" + +bool followsCharacterThat(NojaTestScanner *scanner, int (*testfn)(int c)) +{ + return scanner->cur < scanner->len && testfn(scanner->src[scanner->cur]); +} + +bool followsCharacter(NojaTestScanner *scanner, char c) +{ + return scanner->cur < scanner->len && scanner->src[scanner->cur] == c; +} + +bool noMoreCharacters(NojaTestScanner *scanner) +{ + return scanner->cur == scanner->len; +} + +bool ifFollowsConsumeCharacter(NojaTestScanner *scanner, char c) +{ + bool follows = followsCharacter(scanner, c); + if (follows) + scanner->cur++; + return follows; +} + +void consumeCharactersThat(NojaTestScanner *scanner, int (*testfn)(int c)) +{ + while (followsCharacterThat(scanner, testfn)) + scanner->cur++; +} +/* +#ifndef NDEBUG + +bool noMoreCharacters__wrapped(NojaTestScanner *scanner, const char *file, size_t line) +{ + fprintf(stderr, "noMoreCharacters(%p) - %s:%ld\n", scanner, file, line); + return noMoreCharacters(scanner); +} + +bool followsCharacter__wrapped(NojaTestScanner *scanner, char c, const char *file, size_t line) +{ + fprintf(stderr, "followsCharacter(%p, '%c') - %s:%ld\n", scanner, c, file, line); + return followsCharacter(scanner, c); +} + +bool followsCharacterThat__wrapped(NojaTestScanner *scanner, int (*testfn)(int c), const char *file, size_t line) +{ + fprintf(stderr, "followsCharacterThat(%p, %p) - %s:%ld\n", scanner, testfn, file, line); + return followsCharacterThat(scanner); +} + +void consumeCharactersThat__wrapped(NojaTestScanner *scanner, int (*testfn)(int c), const char *file, size_t line) +{ + fprintf(stderr, "consumeCharactersThat(%p, %p) - %s:%ld\n", scanner, testfn, file, line); + return consumeCharactersThat(scanner); +} + +bool ifFollowsConsumeCharacter__wrapped(NojaTestScanner *scanner, char c, const char *file, size_t line) +{ + fprintf(stderr, "ifFollowsConsumeCharacter(%p, '%c') - %s:%ld\n", scanner, c, file, line); + return ifFollowsConsumeCharacter(scanner); +} + +#endif +*/ \ No newline at end of file diff --git a/src/test/scanner.h b/src/test/scanner.h new file mode 100644 index 0000000..245e157 --- /dev/null +++ b/src/test/scanner.h @@ -0,0 +1,32 @@ +#ifndef TEST_SCANNER_H +#define TEST_SCANNER_H + +#include +#include + +typedef struct { + const char *src; + size_t cur, len; +} NojaTestScanner; + +bool noMoreCharacters(NojaTestScanner *scanner); +bool followsCharacter(NojaTestScanner *scanner, char c); +bool followsCharacterThat(NojaTestScanner *scanner, int (*testfn)(int c)); +void consumeCharactersThat(NojaTestScanner *scanner, int (*testfn)(int c)); +bool ifFollowsConsumeCharacter(NojaTestScanner *scanner, char c); +/* +#ifndef NDEBUG +bool noMoreCharacters__wrapped(NojaTestScanner *scanner, const char *file, size_t line); +bool followsCharacter__wrapped(NojaTestScanner *scanner, char c, const char *file, size_t line); +bool followsCharacterThat__wrapped(NojaTestScanner *scanner, int (*testfn)(int c), const char *file, size_t line); +void consumeCharactersThat__wrapped(NojaTestScanner *scanner, int (*testfn)(int c), const char *file, size_t line); +bool ifFollowsConsumeCharacter__wrapped(NojaTestScanner *scanner, char c, const char *file, size_t line); + +#define noMoreCharacters(scanner) noMoreCharacters__wrapped(scanner, __FILE__, __LINE__) +#define followsCharacter(scanner, c) followsCharacter__wrapped(scanner, c, __FILE__, __LINE__) +#define followsCharacterThat(scanner, testfn) followsCharacterThat__wrapped(scanner, testfn, __FILE__, __LINE__) +#define consumeCharactersThat(scanner, testfn) consumeCharacterThat__wrapped(scanner, testfn, __FILE__, __LINE__) +#define ifFollowsConsumeCharacter(scanner, c) ifFollowsConsumeCharacter__wrapped(scanner, c, __FILE__, __LINE__) +#endif +*/ +#endif \ No newline at end of file diff --git a/src/test/scanner.o b/src/test/scanner.o new file mode 100644 index 0000000..f9be169 Binary files /dev/null and b/src/test/scanner.o differ diff --git a/src/test/test.c b/src/test/test.c new file mode 100644 index 0000000..d6343d6 --- /dev/null +++ b/src/test/test.c @@ -0,0 +1,86 @@ +#include +#include + +#include "test.h" +#include "error.h" +#include "field.h" + +static bool growFieldsArray(NojaTest *test) +{ + size_t new_capacity = 2 * test->fields_capacity; + + NojaTestField *new_fields; + if (test->fields == test->fields_maybe) { + new_fields = malloc(new_capacity * sizeof(NojaTestField)); + if (new_fields != NULL) + memcpy(new_fields, test->fields, test->fields_count * sizeof(NojaTestField)); + } else + new_fields = realloc(test->fields, new_capacity * sizeof(NojaTestField)); + + if (new_fields == NULL) + return false; + + test->fields = new_fields; + test->fields_capacity = new_capacity; + return true; +} + +void freeTest(NojaTest *test) +{ + for (size_t i = 0; i < test->fields_count; i++) + freeField(test->fields + i); + if (test->fields != test->fields_maybe) + free(test->fields); +} + +const char *queryTest(NojaTest *test, const char *name) +{ + for (size_t i = 0; i < test->fields_count; i++) + if (!strcmp(name, test->fields[i].name)) + return test->fields[i].body; + return NULL; +} + +ErrorID parseTest(const char *src, NojaTest *test) +{ + NojaTestScanner scanner = {.src=src, .len=strlen(src), .cur=0}; + + test->fields = test->fields_maybe; + test->fields_count = 0; + test->fields_capacity = sizeof(test->fields_maybe)/sizeof(test->fields_maybe[0]); + + bool done = false; + do { + + if (test->fields_count == test->fields_capacity) + if (!growFieldsArray(test)) { + freeTest(test); + return ErrorID_OUTOFMEMORY; + } + + NojaTestField *field = test->fields + test->fields_count; + + ErrorID error = parseField(&scanner, field); + switch (error) { + + case ErrorID_VOID: + // Before acknowledging the insertion + // by incrementing the field counter, + // check that the new field doesn't have + // a duplicate name + if (queryTest(test, field->name)) + return ErrorID_DUPLFIELD; + test->fields_count++; + break; + + case ErrorID_BADSYNTAX_NOFIELD: + done = true; + break; + + default: + freeTest(test); + return error; + } + } while (!done); + return ErrorID_VOID; +} \ No newline at end of file diff --git a/src/test/test.h b/src/test/test.h new file mode 100644 index 0000000..1c21295 --- /dev/null +++ b/src/test/test.h @@ -0,0 +1,12 @@ +#include "field.h" +#include "error.h" + +typedef struct { + NojaTestField fields_maybe[8]; + NojaTestField *fields; + size_t fields_count; + size_t fields_capacity; +} NojaTest; +ErrorID parseTest(const char *src, NojaTest *test); +const char *queryTest(NojaTest *test, const char *name); +void freeTest(NojaTest *test); diff --git a/src/test/test.o b/src/test/test.o new file mode 100644 index 0000000..d7c0562 Binary files /dev/null and b/src/test/test.o differ diff --git a/test_bytecode b/test_bytecode new file mode 100755 index 0000000..8d78b09 Binary files /dev/null and b/test_bytecode differ diff --git a/tests/suite/Testcase_010_000 b/tests/compiler/dowhile/Testcase_010_000.noja-test similarity index 67% rename from tests/suite/Testcase_010_000 rename to tests/compiler/dowhile/Testcase_010_000.noja-test index c581cd0..8b34f6f 100644 --- a/tests/suite/Testcase_010_000 +++ b/tests/compiler/dowhile/Testcase_010_000.noja-test @@ -1,11 +1,12 @@ -#source +@type [compiler] +@source do {} while none; -#bytecode +@bytecode begin: PUSHNNE; diff --git a/tests/suite/Testcase_010_001 b/tests/compiler/dowhile/Testcase_010_001.noja-test similarity index 77% rename from tests/suite/Testcase_010_001 rename to tests/compiler/dowhile/Testcase_010_001.noja-test index cc874b5..ae250cc 100644 --- a/tests/suite/Testcase_010_001 +++ b/tests/compiler/dowhile/Testcase_010_001.noja-test @@ -1,12 +1,13 @@ -#source +@type [compiler] +@source do true; while none; false; -#bytecode +@bytecode begin: PUSHTRU; diff --git a/tests/suite/Testcase_010_002 b/tests/compiler/dowhile/Testcase_010_002.noja-test similarity index 83% rename from tests/suite/Testcase_010_002 rename to tests/compiler/dowhile/Testcase_010_002.noja-test index 86700e5..abcaac6 100644 --- a/tests/suite/Testcase_010_002 +++ b/tests/compiler/dowhile/Testcase_010_002.noja-test @@ -1,5 +1,6 @@ -#source +@type [compiler] +@source do { true; @@ -7,7 +8,7 @@ } while none; false; -#bytecode +@bytecode begin: PUSHTRU; diff --git a/tests/suite/Testcase_010_003 b/tests/compiler/dowhile/Testcase_010_003.noja-test similarity index 85% rename from tests/suite/Testcase_010_003 rename to tests/compiler/dowhile/Testcase_010_003.noja-test index e1629c6..b028200 100644 --- a/tests/suite/Testcase_010_003 +++ b/tests/compiler/dowhile/Testcase_010_003.noja-test @@ -1,5 +1,6 @@ -#source +@type [compiler] +@source do { true; @@ -8,7 +9,7 @@ } while none; false; -#bytecode +@bytecode begin: PUSHTRU; diff --git a/tests/suite/Testcase_010_004 b/tests/compiler/dowhile/Testcase_010_004.noja-test similarity index 77% rename from tests/suite/Testcase_010_004 rename to tests/compiler/dowhile/Testcase_010_004.noja-test index 460d40e..a02b65d 100644 --- a/tests/suite/Testcase_010_004 +++ b/tests/compiler/dowhile/Testcase_010_004.noja-test @@ -1,12 +1,13 @@ -#source +@type [compiler] +@source do break; while none; false; -#bytecode +@bytecode begin: JUMP end; diff --git a/tests/suite/Testcase_002_000 b/tests/compiler/expr/arithmetic/Testcase_002_000.noja-test similarity index 61% rename from tests/suite/Testcase_002_000 rename to tests/compiler/expr/arithmetic/Testcase_002_000.noja-test index d44c598..e57aaaf 100644 --- a/tests/suite/Testcase_002_000 +++ b/tests/compiler/expr/arithmetic/Testcase_002_000.noja-test @@ -1,9 +1,10 @@ -#source +@type [compiler] +@source 1 + 7; -#bytecode +@bytecode PUSHINT 1; PUSHINT 7; diff --git a/tests/suite/Testcase_002_001 b/tests/compiler/expr/arithmetic/Testcase_002_001.noja-test similarity index 62% rename from tests/suite/Testcase_002_001 rename to tests/compiler/expr/arithmetic/Testcase_002_001.noja-test index a956da0..d408e7c 100644 --- a/tests/suite/Testcase_002_001 +++ b/tests/compiler/expr/arithmetic/Testcase_002_001.noja-test @@ -1,9 +1,10 @@ -#source +@type [compiler] +@source 1 - 7; -#bytecode +@bytecode PUSHINT 1; PUSHINT 7; diff --git a/tests/suite/Testcase_002_002 b/tests/compiler/expr/arithmetic/Testcase_002_002.noja-test similarity index 59% rename from tests/suite/Testcase_002_002 rename to tests/compiler/expr/arithmetic/Testcase_002_002.noja-test index b860c58..a046e31 100644 --- a/tests/suite/Testcase_002_002 +++ b/tests/compiler/expr/arithmetic/Testcase_002_002.noja-test @@ -1,9 +1,10 @@ -#source +@type [compiler] +@source 1 * 7; -#bytecode +@bytecode PUSHINT 1; PUSHINT 7; diff --git a/tests/suite/Testcase_002_003 b/tests/compiler/expr/arithmetic/Testcase_002_003.noja-test similarity index 61% rename from tests/suite/Testcase_002_003 rename to tests/compiler/expr/arithmetic/Testcase_002_003.noja-test index f958c90..9c84fad 100644 --- a/tests/suite/Testcase_002_003 +++ b/tests/compiler/expr/arithmetic/Testcase_002_003.noja-test @@ -1,9 +1,10 @@ -#source +@type [compiler] +@source 1 / 7; -#bytecode +@bytecode PUSHINT 1; PUSHINT 7; diff --git a/tests/suite/Testcase_002_004 b/tests/compiler/expr/arithmetic/Testcase_002_004.noja-test similarity index 61% rename from tests/suite/Testcase_002_004 rename to tests/compiler/expr/arithmetic/Testcase_002_004.noja-test index bcf0202..9e7b143 100644 --- a/tests/suite/Testcase_002_004 +++ b/tests/compiler/expr/arithmetic/Testcase_002_004.noja-test @@ -1,12 +1,13 @@ -#source - +@type [compiler] +@source + 1.0 + 7; -#bytecode +@bytecode PUSHFLT 1.0; PUSHINT 7; ADD; POP 1; - EXIT; \ No newline at end of file + EXIT; diff --git a/tests/suite/Testcase_002_005 b/tests/compiler/expr/arithmetic/Testcase_002_005.noja-test similarity index 63% rename from tests/suite/Testcase_002_005 rename to tests/compiler/expr/arithmetic/Testcase_002_005.noja-test index 96dd5ed..4fdcede 100644 --- a/tests/suite/Testcase_002_005 +++ b/tests/compiler/expr/arithmetic/Testcase_002_005.noja-test @@ -1,9 +1,10 @@ -#source +@type [compiler] +@source 1.0 - 7; -#bytecode +@bytecode PUSHFLT 1.0; PUSHINT 7; diff --git a/tests/suite/Testcase_002_006 b/tests/compiler/expr/arithmetic/Testcase_002_006.noja-test similarity index 63% rename from tests/suite/Testcase_002_006 rename to tests/compiler/expr/arithmetic/Testcase_002_006.noja-test index 5b276fb..5a06d5e 100644 --- a/tests/suite/Testcase_002_006 +++ b/tests/compiler/expr/arithmetic/Testcase_002_006.noja-test @@ -1,9 +1,10 @@ -#source +@type [compiler] +@source 1.0 * 7; -#bytecode +@bytecode PUSHFLT 1.0; PUSHINT 7; diff --git a/tests/suite/Testcase_002_007 b/tests/compiler/expr/arithmetic/Testcase_002_007.noja-test similarity index 63% rename from tests/suite/Testcase_002_007 rename to tests/compiler/expr/arithmetic/Testcase_002_007.noja-test index fc3fa54..752f8db 100644 --- a/tests/suite/Testcase_002_007 +++ b/tests/compiler/expr/arithmetic/Testcase_002_007.noja-test @@ -1,9 +1,10 @@ -#source +@type [compiler] +@source 1.0 / 7; -#bytecode +@bytecode PUSHFLT 1.0; PUSHINT 7; diff --git a/tests/suite/Testcase_002_008 b/tests/compiler/expr/arithmetic/Testcase_002_008.noja-test similarity index 63% rename from tests/suite/Testcase_002_008 rename to tests/compiler/expr/arithmetic/Testcase_002_008.noja-test index 433bdaa..64312d8 100644 --- a/tests/suite/Testcase_002_008 +++ b/tests/compiler/expr/arithmetic/Testcase_002_008.noja-test @@ -1,9 +1,10 @@ -#source +@type [compiler] +@source 1 + 7.0; -#bytecode +@bytecode PUSHINT 1; PUSHFLT 7.0; diff --git a/tests/suite/Testcase_002_009 b/tests/compiler/expr/arithmetic/Testcase_002_009.noja-test similarity index 63% rename from tests/suite/Testcase_002_009 rename to tests/compiler/expr/arithmetic/Testcase_002_009.noja-test index cc5f3ac..c8a1005 100644 --- a/tests/suite/Testcase_002_009 +++ b/tests/compiler/expr/arithmetic/Testcase_002_009.noja-test @@ -1,9 +1,10 @@ -#source +@type [compiler] +@source 1 - 7.0; -#bytecode +@bytecode PUSHINT 1; PUSHFLT 7.0; diff --git a/tests/suite/Testcase_002_010 b/tests/compiler/expr/arithmetic/Testcase_002_010.noja-test similarity index 63% rename from tests/suite/Testcase_002_010 rename to tests/compiler/expr/arithmetic/Testcase_002_010.noja-test index a1ba078..42d3f9f 100644 --- a/tests/suite/Testcase_002_010 +++ b/tests/compiler/expr/arithmetic/Testcase_002_010.noja-test @@ -1,9 +1,10 @@ -#source +@type [compiler] +@source 1 * 7.0; -#bytecode +@bytecode PUSHINT 1; PUSHFLT 7.0; diff --git a/tests/suite/Testcase_002_011 b/tests/compiler/expr/arithmetic/Testcase_002_011.noja-test similarity index 63% rename from tests/suite/Testcase_002_011 rename to tests/compiler/expr/arithmetic/Testcase_002_011.noja-test index fec4177..d83ff28 100644 --- a/tests/suite/Testcase_002_011 +++ b/tests/compiler/expr/arithmetic/Testcase_002_011.noja-test @@ -1,9 +1,10 @@ -#source +@type [compiler] +@source 1 / 7.0; -#bytecode +@bytecode PUSHINT 1; PUSHFLT 7.0; diff --git a/tests/suite/Testcase_002_023 b/tests/compiler/expr/arithmetic/Testcase_002_023.noja-test similarity index 69% rename from tests/suite/Testcase_002_023 rename to tests/compiler/expr/arithmetic/Testcase_002_023.noja-test index ccf42a6..5341a6b 100644 --- a/tests/suite/Testcase_002_023 +++ b/tests/compiler/expr/arithmetic/Testcase_002_023.noja-test @@ -1,9 +1,10 @@ -#source +@type [compiler] +@source 1 + 2 * 3; -#bytecode +@bytecode PUSHINT 1; PUSHINT 2; diff --git a/tests/suite/Testcase_002_024 b/tests/compiler/expr/arithmetic/Testcase_002_024.noja-test similarity index 69% rename from tests/suite/Testcase_002_024 rename to tests/compiler/expr/arithmetic/Testcase_002_024.noja-test index 89a4bd9..24e4a62 100644 --- a/tests/suite/Testcase_002_024 +++ b/tests/compiler/expr/arithmetic/Testcase_002_024.noja-test @@ -1,9 +1,10 @@ -#source +@type [compiler] +@source 1 * 2 + 3; -#bytecode +@bytecode PUSHINT 1; PUSHINT 2; diff --git a/tests/suite/Testcase_002_025 b/tests/compiler/expr/arithmetic/Testcase_002_025.noja-test similarity index 69% rename from tests/suite/Testcase_002_025 rename to tests/compiler/expr/arithmetic/Testcase_002_025.noja-test index 9b384ff..961045d 100644 --- a/tests/suite/Testcase_002_025 +++ b/tests/compiler/expr/arithmetic/Testcase_002_025.noja-test @@ -1,9 +1,10 @@ -#source +@type [compiler] +@source (1 + 2) * 3; -#bytecode +@bytecode PUSHINT 1; PUSHINT 2; diff --git a/tests/suite/Testcase_002_026 b/tests/compiler/expr/arithmetic/Testcase_002_026.noja-test similarity index 70% rename from tests/suite/Testcase_002_026 rename to tests/compiler/expr/arithmetic/Testcase_002_026.noja-test index 00949dc..faed49f 100644 --- a/tests/suite/Testcase_002_026 +++ b/tests/compiler/expr/arithmetic/Testcase_002_026.noja-test @@ -1,9 +1,10 @@ -#source +@type [compiler] +@source 1 + (2 * 3); -#bytecode +@bytecode PUSHINT 1; PUSHINT 2; diff --git a/tests/suite/Testcase_002_027 b/tests/compiler/expr/arithmetic/Testcase_002_027.noja-test similarity index 76% rename from tests/suite/Testcase_002_027 rename to tests/compiler/expr/arithmetic/Testcase_002_027.noja-test index 2b8bdc9..9051178 100644 --- a/tests/suite/Testcase_002_027 +++ b/tests/compiler/expr/arithmetic/Testcase_002_027.noja-test @@ -1,9 +1,10 @@ -#source +@type [compiler] +@source 1 * 2 * 3 * 4; -#bytecode +@bytecode PUSHINT 1; PUSHINT 2; diff --git a/tests/suite/Testcase_002_028 b/tests/compiler/expr/arithmetic/Testcase_002_028.noja-test similarity index 75% rename from tests/suite/Testcase_002_028 rename to tests/compiler/expr/arithmetic/Testcase_002_028.noja-test index 16f4264..8f6bf86 100644 --- a/tests/suite/Testcase_002_028 +++ b/tests/compiler/expr/arithmetic/Testcase_002_028.noja-test @@ -1,9 +1,10 @@ -#source +@type [compiler] +@source 1 * (2 * (3 * 4)); -#bytecode +@bytecode PUSHINT 1; PUSHINT 2; diff --git a/tests/suite/Testcase_002_029 b/tests/compiler/expr/arithmetic/Testcase_002_029.noja-test similarity index 74% rename from tests/suite/Testcase_002_029 rename to tests/compiler/expr/arithmetic/Testcase_002_029.noja-test index ad38c5e..1d64e0c 100644 --- a/tests/suite/Testcase_002_029 +++ b/tests/compiler/expr/arithmetic/Testcase_002_029.noja-test @@ -1,9 +1,10 @@ -#source +@type [compiler] +@source 1 + 2 * 3 + 4; -#bytecode +@bytecode PUSHINT 1; PUSHINT 2; diff --git a/tests/suite/Testcase_002_030 b/tests/compiler/expr/arithmetic/Testcase_002_030.noja-test similarity index 75% rename from tests/suite/Testcase_002_030 rename to tests/compiler/expr/arithmetic/Testcase_002_030.noja-test index 4b97dfd..6a765f5 100644 --- a/tests/suite/Testcase_002_030 +++ b/tests/compiler/expr/arithmetic/Testcase_002_030.noja-test @@ -1,9 +1,10 @@ -#source +@type [compiler] +@source 1 * 2 + 3 * 4; -#bytecode +@bytecode PUSHINT 1; PUSHINT 2; diff --git a/tests/suite/Testcase_002_031 b/tests/compiler/expr/arithmetic/Testcase_002_031.noja-test similarity index 82% rename from tests/suite/Testcase_002_031 rename to tests/compiler/expr/arithmetic/Testcase_002_031.noja-test index 435bb40..0264e10 100644 --- a/tests/suite/Testcase_002_031 +++ b/tests/compiler/expr/arithmetic/Testcase_002_031.noja-test @@ -1,10 +1,11 @@ -#source +@type [compiler] +@source A - B - C; A - B * C; -#bytecode +@bytecode PUSHVAR "A"; PUSHVAR "B"; diff --git a/tests/compiler/expr/array/Testcase_003_000.noja-test b/tests/compiler/expr/array/Testcase_003_000.noja-test new file mode 100644 index 0000000..2fa8dfd --- /dev/null +++ b/tests/compiler/expr/array/Testcase_003_000.noja-test @@ -0,0 +1,16 @@ +@type [compiler] + +@source + # This comment is because there + # can't be a '[' right before a + # tag. + [1]; + +@bytecode + + PUSHLST 1; + PUSHINT 0; + PUSHINT 1; + INSERT; + POP 1; + EXIT; \ No newline at end of file diff --git a/tests/suite/Testcase_003_001 b/tests/compiler/expr/array/Testcase_003_001.noja-test similarity index 56% rename from tests/suite/Testcase_003_001 rename to tests/compiler/expr/array/Testcase_003_001.noja-test index 1bb73a7..6789c7c 100644 --- a/tests/suite/Testcase_003_001 +++ b/tests/compiler/expr/array/Testcase_003_001.noja-test @@ -1,9 +1,12 @@ -#source - +@type [compiler] +@source + # This comment is because there + # can't be a '[' right before a + # tag. [true, false]; -#bytecode +@bytecode PUSHLST 2; diff --git a/tests/suite/Testcase_005_000 b/tests/compiler/expr/assignment/Testcase_005_000.noja-test similarity index 59% rename from tests/suite/Testcase_005_000 rename to tests/compiler/expr/assignment/Testcase_005_000.noja-test index 4d9fe79..e05f136 100644 --- a/tests/suite/Testcase_005_000 +++ b/tests/compiler/expr/assignment/Testcase_005_000.noja-test @@ -1,9 +1,10 @@ -#source +@type [compiler] +@source var = none; -#bytecode +@bytecode PUSHNNE; ASS "var"; diff --git a/tests/suite/Testcase_005_001 b/tests/compiler/expr/assignment/Testcase_005_001.noja-test similarity index 77% rename from tests/suite/Testcase_005_001 rename to tests/compiler/expr/assignment/Testcase_005_001.noja-test index 5139330..6463ed8 100644 --- a/tests/suite/Testcase_005_001 +++ b/tests/compiler/expr/assignment/Testcase_005_001.noja-test @@ -1,9 +1,10 @@ -#source +@type [compiler] +@source var[key] = none; -#bytecode +@bytecode PUSHNNE; PUSHVAR "var"; diff --git a/tests/suite/Testcase_005_002 b/tests/compiler/expr/assignment/Testcase_005_002.noja-test similarity index 71% rename from tests/suite/Testcase_005_002 rename to tests/compiler/expr/assignment/Testcase_005_002.noja-test index 1ce459e..5810e8b 100644 --- a/tests/suite/Testcase_005_002 +++ b/tests/compiler/expr/assignment/Testcase_005_002.noja-test @@ -1,9 +1,10 @@ -#source +@type [compiler] +@source A, B = func(); -#bytecode +@bytecode PUSHVAR "func"; CALL 0, 2; diff --git a/tests/suite/Testcase_005_003 b/tests/compiler/expr/assignment/Testcase_005_003.noja-test similarity index 76% rename from tests/suite/Testcase_005_003 rename to tests/compiler/expr/assignment/Testcase_005_003.noja-test index 54bb3c6..0c7d8ca 100644 --- a/tests/suite/Testcase_005_003 +++ b/tests/compiler/expr/assignment/Testcase_005_003.noja-test @@ -1,9 +1,10 @@ -#source +@type [compiler] +@source var.key = none; -#bytecode +@bytecode PUSHNNE; PUSHVAR "var"; diff --git a/tests/suite/Testcase_002_021 b/tests/compiler/expr/logical/Testcase_002_021.noja-test similarity index 79% rename from tests/suite/Testcase_002_021 rename to tests/compiler/expr/logical/Testcase_002_021.noja-test index 6ec054e..5f06a9a 100644 --- a/tests/suite/Testcase_002_021 +++ b/tests/compiler/expr/logical/Testcase_002_021.noja-test @@ -1,9 +1,10 @@ -#source +@type [compiler] +@source 1 and 2; -#bytecode +@bytecode PUSHINT 1; JUMPIFNOTANDPOP false; diff --git a/tests/suite/Testcase_002_022 b/tests/compiler/expr/logical/Testcase_002_022.noja-test similarity index 77% rename from tests/suite/Testcase_002_022 rename to tests/compiler/expr/logical/Testcase_002_022.noja-test index 2445bf8..2686549 100644 --- a/tests/suite/Testcase_002_022 +++ b/tests/compiler/expr/logical/Testcase_002_022.noja-test @@ -1,9 +1,10 @@ -#source +@type [compiler] +@source 1 or 2; -#bytecode +@bytecode PUSHINT 1; JUMPIFANDPOP true; diff --git a/tests/suite/Testcase_002_032 b/tests/compiler/expr/logical/Testcase_002_032.noja-test similarity index 91% rename from tests/suite/Testcase_002_032 rename to tests/compiler/expr/logical/Testcase_002_032.noja-test index 73c8208..1a45894 100644 --- a/tests/suite/Testcase_002_032 +++ b/tests/compiler/expr/logical/Testcase_002_032.noja-test @@ -1,9 +1,10 @@ -#source +@type [compiler] +@source A and B or C and D; -#bytecode +@bytecode PUSHVAR "A"; JUMPIFNOTANDPOP false_0; diff --git a/tests/suite/Testcase_002_033 b/tests/compiler/expr/logical/Testcase_002_033.noja-test similarity index 90% rename from tests/suite/Testcase_002_033 rename to tests/compiler/expr/logical/Testcase_002_033.noja-test index f2081e1..19aaff2 100644 --- a/tests/suite/Testcase_002_033 +++ b/tests/compiler/expr/logical/Testcase_002_033.noja-test @@ -1,9 +1,10 @@ -#source +@type [compiler] +@source X or Y and Z or W; -#bytecode +@bytecode PUSHVAR "X"; JUMPIFANDPOP true_0; diff --git a/tests/suite/Testcase_004_000 b/tests/compiler/expr/map/Testcase_004_000.noja-test similarity index 73% rename from tests/suite/Testcase_004_000 rename to tests/compiler/expr/map/Testcase_004_000.noja-test index cccccbd..4a95617 100644 --- a/tests/suite/Testcase_004_000 +++ b/tests/compiler/expr/map/Testcase_004_000.noja-test @@ -1,9 +1,10 @@ -#source +@type [compiler] +@source ({'name': 'Francesco'}); -#bytecode +@bytecode PUSHMAP 1; PUSHSTR "name"; diff --git a/tests/suite/Testcase_004_001 b/tests/compiler/expr/map/Testcase_004_001.noja-test similarity index 81% rename from tests/suite/Testcase_004_001 rename to tests/compiler/expr/map/Testcase_004_001.noja-test index c269970..387e6cb 100644 --- a/tests/suite/Testcase_004_001 +++ b/tests/compiler/expr/map/Testcase_004_001.noja-test @@ -1,9 +1,10 @@ -#source +@type [compiler] +@source ({'name': 'Francesco', 'age': 25}); -#bytecode +@bytecode PUSHMAP 2; diff --git a/tests/suite/Testcase_004_002 b/tests/compiler/expr/map/Testcase_004_002.noja-test similarity index 73% rename from tests/suite/Testcase_004_002 rename to tests/compiler/expr/map/Testcase_004_002.noja-test index 64b1b5d..f7a6ab4 100644 --- a/tests/suite/Testcase_004_002 +++ b/tests/compiler/expr/map/Testcase_004_002.noja-test @@ -1,9 +1,10 @@ -#source +@type [compiler] +@source ({name: 'Francesco'}); -#bytecode +@bytecode PUSHMAP 1; PUSHSTR "name"; diff --git a/tests/suite/Testcase_004_003 b/tests/compiler/expr/map/Testcase_004_003.noja-test similarity index 80% rename from tests/suite/Testcase_004_003 rename to tests/compiler/expr/map/Testcase_004_003.noja-test index 93aa640..093df67 100644 --- a/tests/suite/Testcase_004_003 +++ b/tests/compiler/expr/map/Testcase_004_003.noja-test @@ -1,9 +1,10 @@ -#source +@type [compiler] +@source ({name: 'Francesco', age: 25}); -#bytecode +@bytecode PUSHMAP 2; diff --git a/tests/suite/Testcase_004_005 b/tests/compiler/expr/map/Testcase_004_004.noja-test similarity index 75% rename from tests/suite/Testcase_004_005 rename to tests/compiler/expr/map/Testcase_004_004.noja-test index 803f8c5..cf87d59 100644 --- a/tests/suite/Testcase_004_005 +++ b/tests/compiler/expr/map/Testcase_004_004.noja-test @@ -1,9 +1,10 @@ -#source +@type [compiler] +@source ({+name: 'Francesco'}); -#bytecode +@bytecode PUSHMAP 1; PUSHVAR "name"; diff --git a/tests/suite/Testcase_004_004 b/tests/compiler/expr/map/Testcase_004_005.noja-test similarity index 75% rename from tests/suite/Testcase_004_004 rename to tests/compiler/expr/map/Testcase_004_005.noja-test index 803f8c5..cf87d59 100644 --- a/tests/suite/Testcase_004_004 +++ b/tests/compiler/expr/map/Testcase_004_005.noja-test @@ -1,9 +1,10 @@ -#source +@type [compiler] +@source ({+name: 'Francesco'}); -#bytecode +@bytecode PUSHMAP 1; PUSHVAR "name"; diff --git a/tests/suite/Testcase_006_000 b/tests/compiler/expr/postfix/Testcase_006_000.noja-test similarity index 62% rename from tests/suite/Testcase_006_000 rename to tests/compiler/expr/postfix/Testcase_006_000.noja-test index 57e10cd..0b7676f 100644 --- a/tests/suite/Testcase_006_000 +++ b/tests/compiler/expr/postfix/Testcase_006_000.noja-test @@ -1,9 +1,10 @@ -#source +@type [compiler] +@source func(); -#bytecode +@bytecode PUSHVAR "func"; CALL 0, 1; diff --git a/tests/suite/Testcase_006_001 b/tests/compiler/expr/postfix/Testcase_006_001.noja-test similarity index 67% rename from tests/suite/Testcase_006_001 rename to tests/compiler/expr/postfix/Testcase_006_001.noja-test index eb87b5a..2e59e9b 100644 --- a/tests/suite/Testcase_006_001 +++ b/tests/compiler/expr/postfix/Testcase_006_001.noja-test @@ -1,9 +1,10 @@ -#source +@type [compiler] +@source func(none); -#bytecode +@bytecode PUSHNNE; PUSHVAR "func"; diff --git a/tests/suite/Testcase_006_002 b/tests/compiler/expr/postfix/Testcase_006_002.noja-test similarity index 70% rename from tests/suite/Testcase_006_002 rename to tests/compiler/expr/postfix/Testcase_006_002.noja-test index 9c414f7..537238e 100644 --- a/tests/suite/Testcase_006_002 +++ b/tests/compiler/expr/postfix/Testcase_006_002.noja-test @@ -1,9 +1,10 @@ -#source +@type [compiler] +@source func(true, false); -#bytecode +@bytecode PUSHFLS; PUSHTRU; diff --git a/tests/suite/Testcase_007_000 b/tests/compiler/expr/postfix/Testcase_007_000.noja-test similarity index 66% rename from tests/suite/Testcase_007_000 rename to tests/compiler/expr/postfix/Testcase_007_000.noja-test index 5288c66..2e08f2d 100644 --- a/tests/suite/Testcase_007_000 +++ b/tests/compiler/expr/postfix/Testcase_007_000.noja-test @@ -1,9 +1,10 @@ -#source +@type [compiler] +@source set[key]; -#bytecode +@bytecode PUSHVAR "set"; PUSHVAR "key"; diff --git a/tests/suite/Testcase_007_001 b/tests/compiler/expr/postfix/Testcase_007_001.noja-test similarity index 84% rename from tests/suite/Testcase_007_001 rename to tests/compiler/expr/postfix/Testcase_007_001.noja-test index ca0e110..b580324 100644 --- a/tests/suite/Testcase_007_001 +++ b/tests/compiler/expr/postfix/Testcase_007_001.noja-test @@ -1,8 +1,9 @@ -#source +@type [compiler] +@source set["dog", "cow", "cat"]; -#bytecode +@bytecode PUSHVAR "set"; diff --git a/tests/suite/Testcase_007_002 b/tests/compiler/expr/postfix/Testcase_007_002.noja-test similarity index 66% rename from tests/suite/Testcase_007_002 rename to tests/compiler/expr/postfix/Testcase_007_002.noja-test index e4c75fe..84b235b 100644 --- a/tests/suite/Testcase_007_002 +++ b/tests/compiler/expr/postfix/Testcase_007_002.noja-test @@ -1,9 +1,10 @@ -#source +@type [compiler] +@source set.key; -#bytecode +@bytecode PUSHVAR "set"; PUSHSTR "key"; diff --git a/tests/suite/Testcase_002_012 b/tests/compiler/expr/prefix/Testcase_002_012.noja-test similarity index 51% rename from tests/suite/Testcase_002_012 rename to tests/compiler/expr/prefix/Testcase_002_012.noja-test index 09369d5..1e5f93b 100644 --- a/tests/suite/Testcase_002_012 +++ b/tests/compiler/expr/prefix/Testcase_002_012.noja-test @@ -1,9 +1,10 @@ -#source +@type [compiler] +@source -1; -#bytecode +@bytecode PUSHINT 1; NEG; diff --git a/tests/suite/Testcase_002_013 b/tests/compiler/expr/prefix/Testcase_002_013.noja-test similarity index 51% rename from tests/suite/Testcase_002_013 rename to tests/compiler/expr/prefix/Testcase_002_013.noja-test index 0cca545..febc6c7 100644 --- a/tests/suite/Testcase_002_013 +++ b/tests/compiler/expr/prefix/Testcase_002_013.noja-test @@ -1,9 +1,10 @@ -#source +@type [compiler] +@source +1; -#bytecode +@bytecode PUSHINT 1; POS; diff --git a/tests/suite/Testcase_002_014 b/tests/compiler/expr/prefix/Testcase_002_014.noja-test similarity index 53% rename from tests/suite/Testcase_002_014 rename to tests/compiler/expr/prefix/Testcase_002_014.noja-test index 11c53b0..c758895 100644 --- a/tests/suite/Testcase_002_014 +++ b/tests/compiler/expr/prefix/Testcase_002_014.noja-test @@ -1,9 +1,10 @@ -#source +@type [compiler] +@source not 1; -#bytecode +@bytecode PUSHINT 1; NOT; diff --git a/tests/compiler/expr/primary/primary_000.noja-test b/tests/compiler/expr/primary/primary_000.noja-test new file mode 100644 index 0000000..7a906fc --- /dev/null +++ b/tests/compiler/expr/primary/primary_000.noja-test @@ -0,0 +1,9 @@ +@type [compiler] + +@source + 1; + +@bytecode + PUSHINT 1; + POP 1; + EXIT; \ No newline at end of file diff --git a/tests/suite/Testcase_001_001 b/tests/compiler/expr/primary/primary_001.noja-test similarity index 54% rename from tests/suite/Testcase_001_001 rename to tests/compiler/expr/primary/primary_001.noja-test index 6b9d80f..3293a9f 100644 --- a/tests/suite/Testcase_001_001 +++ b/tests/compiler/expr/primary/primary_001.noja-test @@ -1,9 +1,10 @@ +@type [compiler] -#source +@source 6.7; -#bytecode +@bytecode PUSHFLT 6.7; POP 1; diff --git a/tests/suite/Testcase_001_002 b/tests/compiler/expr/primary/primary_002.noja-test similarity index 63% rename from tests/suite/Testcase_001_002 rename to tests/compiler/expr/primary/primary_002.noja-test index 17b2edc..238f9d4 100644 --- a/tests/suite/Testcase_001_002 +++ b/tests/compiler/expr/primary/primary_002.noja-test @@ -1,9 +1,10 @@ +@type [compiler] -#source +@source 'Hello, world!'; -#bytecode +@bytecode PUSHSTR "Hello, world!"; POP 1; diff --git a/tests/suite/Testcase_001_003 b/tests/compiler/expr/primary/primary_003.noja-test similarity index 53% rename from tests/suite/Testcase_001_003 rename to tests/compiler/expr/primary/primary_003.noja-test index dbad5cc..08d5f5f 100644 --- a/tests/suite/Testcase_001_003 +++ b/tests/compiler/expr/primary/primary_003.noja-test @@ -1,9 +1,10 @@ -#source +@type [compiler] +@source true; -#bytecode +@bytecode PUSHTRU; POP 1; diff --git a/tests/suite/Testcase_001_004 b/tests/compiler/expr/primary/primary_004.noja-test similarity index 53% rename from tests/suite/Testcase_001_004 rename to tests/compiler/expr/primary/primary_004.noja-test index b338cd8..c4473ae 100644 --- a/tests/suite/Testcase_001_004 +++ b/tests/compiler/expr/primary/primary_004.noja-test @@ -1,9 +1,10 @@ -#source +@type [compiler] +@source false; -#bytecode +@bytecode PUSHFLS; POP 1; diff --git a/tests/suite/Testcase_001_005 b/tests/compiler/expr/primary/primary_005.noja-test similarity index 53% rename from tests/suite/Testcase_001_005 rename to tests/compiler/expr/primary/primary_005.noja-test index 20e71b3..8701077 100644 --- a/tests/suite/Testcase_001_005 +++ b/tests/compiler/expr/primary/primary_005.noja-test @@ -1,9 +1,10 @@ -#source +@type [compiler] +@source none; -#bytecode +@bytecode PUSHNNE; POP 1; diff --git a/tests/suite/Testcase_001_006 b/tests/compiler/expr/primary/primary_006.noja-test similarity index 52% rename from tests/suite/Testcase_001_006 rename to tests/compiler/expr/primary/primary_006.noja-test index 295fd02..0f0e5c9 100644 --- a/tests/suite/Testcase_001_006 +++ b/tests/compiler/expr/primary/primary_006.noja-test @@ -1,9 +1,10 @@ -#source +@type [compiler] +@source ({}); -#bytecode +@bytecode PUSHMAP 0; POP 1; diff --git a/tests/compiler/expr/primary/primary_007.noja-test b/tests/compiler/expr/primary/primary_007.noja-test new file mode 100644 index 0000000..09428f5 --- /dev/null +++ b/tests/compiler/expr/primary/primary_007.noja-test @@ -0,0 +1,14 @@ + +@type [compiler] + +@source + # This comment is because there + # can't be a '[' right before a + # tag. + []; + +@bytecode + + PUSHLST 0; + POP 1; + EXIT; \ No newline at end of file diff --git a/tests/compiler/expr/primary/primary_008.noja-test b/tests/compiler/expr/primary/primary_008.noja-test new file mode 100644 index 0000000..0085103 --- /dev/null +++ b/tests/compiler/expr/primary/primary_008.noja-test @@ -0,0 +1,9 @@ + +@type [compiler] +@source + + {} + +@bytecode + + EXIT; \ No newline at end of file diff --git a/tests/compiler/expr/primary/primary_009.noja-test b/tests/compiler/expr/primary/primary_009.noja-test new file mode 100644 index 0000000..94535bd --- /dev/null +++ b/tests/compiler/expr/primary/primary_009.noja-test @@ -0,0 +1,11 @@ +@type [compiler] + +@source + + 'This \\ is a slash!'; + +@bytecode + + PUSHSTR "This \\ is a slash!"; + POP 1; + EXIT; \ No newline at end of file diff --git a/tests/compiler/expr/primary/primary_010.noja-test b/tests/compiler/expr/primary/primary_010.noja-test new file mode 100644 index 0000000..8c6ef6c --- /dev/null +++ b/tests/compiler/expr/primary/primary_010.noja-test @@ -0,0 +1,11 @@ +@type [compiler] + +@source + + 'This \n is a newline!'; + +@bytecode + + PUSHSTR "This \n is a newline!"; + POP 1; + EXIT; \ No newline at end of file diff --git a/tests/compiler/expr/primary/primary_011.noja-test b/tests/compiler/expr/primary/primary_011.noja-test new file mode 100644 index 0000000..b096d8e --- /dev/null +++ b/tests/compiler/expr/primary/primary_011.noja-test @@ -0,0 +1,11 @@ +@type [compiler] + +@source + + 'This \t is an horizontal tab!'; + +@bytecode + + PUSHSTR "This \t is an horizontal tab!"; + POP 1; + EXIT; \ No newline at end of file diff --git a/tests/compiler/expr/primary/primary_012.noja-test b/tests/compiler/expr/primary/primary_012.noja-test new file mode 100644 index 0000000..a0ab05c --- /dev/null +++ b/tests/compiler/expr/primary/primary_012.noja-test @@ -0,0 +1,11 @@ +@type [compiler] + +@source + + 'This \r is a special character!'; + +@bytecode + + PUSHSTR "This \r is a special character!"; + POP 1; + EXIT; \ No newline at end of file diff --git a/tests/compiler/expr/primary/primary_013.noja-test b/tests/compiler/expr/primary/primary_013.noja-test new file mode 100644 index 0000000..6a6cec2 --- /dev/null +++ b/tests/compiler/expr/primary/primary_013.noja-test @@ -0,0 +1,11 @@ +@type [compiler] + +@source + + 'Look at this \'!'; + +@bytecode + + PUSHSTR "Look at this '!"; + POP 1; + EXIT; \ No newline at end of file diff --git a/tests/compiler/expr/primary/primary_014.noja-test b/tests/compiler/expr/primary/primary_014.noja-test new file mode 100644 index 0000000..0d2122a --- /dev/null +++ b/tests/compiler/expr/primary/primary_014.noja-test @@ -0,0 +1,11 @@ +@type [compiler] + +@source + + "Look at this \"!"; + +@bytecode + + PUSHSTR "Look at this \"!"; + POP 1; + EXIT; \ No newline at end of file diff --git a/tests/suite/Testcase_002_015 b/tests/compiler/expr/relational/Testcase_002_015.noja-test similarity index 60% rename from tests/suite/Testcase_002_015 rename to tests/compiler/expr/relational/Testcase_002_015.noja-test index f2f065b..74a8422 100644 --- a/tests/suite/Testcase_002_015 +++ b/tests/compiler/expr/relational/Testcase_002_015.noja-test @@ -1,9 +1,10 @@ -#source +@type [compiler] +@source 1 == 2; -#bytecode +@bytecode PUSHINT 1; PUSHINT 2; diff --git a/tests/suite/Testcase_002_016 b/tests/compiler/expr/relational/Testcase_002_016.noja-test similarity index 60% rename from tests/suite/Testcase_002_016 rename to tests/compiler/expr/relational/Testcase_002_016.noja-test index 7614b0a..cad6de8 100644 --- a/tests/suite/Testcase_002_016 +++ b/tests/compiler/expr/relational/Testcase_002_016.noja-test @@ -1,9 +1,10 @@ -#source +@type [compiler] +@source 1 != 2; -#bytecode +@bytecode PUSHINT 1; PUSHINT 2; diff --git a/tests/suite/Testcase_002_017 b/tests/compiler/expr/relational/Testcase_002_017.noja-test similarity index 59% rename from tests/suite/Testcase_002_017 rename to tests/compiler/expr/relational/Testcase_002_017.noja-test index 546f488..9525622 100644 --- a/tests/suite/Testcase_002_017 +++ b/tests/compiler/expr/relational/Testcase_002_017.noja-test @@ -1,9 +1,10 @@ -#source +@type [compiler] +@source 1 < 2; -#bytecode +@bytecode PUSHINT 1; PUSHINT 2; diff --git a/tests/suite/Testcase_002_018 b/tests/compiler/expr/relational/Testcase_002_018.noja-test similarity index 59% rename from tests/suite/Testcase_002_018 rename to tests/compiler/expr/relational/Testcase_002_018.noja-test index d7c5df1..cdedeba 100644 --- a/tests/suite/Testcase_002_018 +++ b/tests/compiler/expr/relational/Testcase_002_018.noja-test @@ -1,9 +1,10 @@ -#source +@type [compiler] +@source 1 > 2; -#bytecode +@bytecode PUSHINT 1; PUSHINT 2; diff --git a/tests/suite/Testcase_002_019 b/tests/compiler/expr/relational/Testcase_002_019.noja-test similarity index 60% rename from tests/suite/Testcase_002_019 rename to tests/compiler/expr/relational/Testcase_002_019.noja-test index d9bdb4d..4b2969b 100644 --- a/tests/suite/Testcase_002_019 +++ b/tests/compiler/expr/relational/Testcase_002_019.noja-test @@ -1,9 +1,10 @@ -#source +@type [compiler] +@source 1 <= 2; -#bytecode +@bytecode PUSHINT 1; PUSHINT 2; diff --git a/tests/suite/Testcase_002_020 b/tests/compiler/expr/relational/Testcase_002_020.noja-test similarity index 60% rename from tests/suite/Testcase_002_020 rename to tests/compiler/expr/relational/Testcase_002_020.noja-test index 79b252e..0135431 100644 --- a/tests/suite/Testcase_002_020 +++ b/tests/compiler/expr/relational/Testcase_002_020.noja-test @@ -1,9 +1,10 @@ -#source +@type [compiler] +@source 1 >= 2; -#bytecode +@bytecode PUSHINT 1; PUSHINT 2; diff --git a/tests/suite/Testcase_002_034 b/tests/compiler/expr/relational_and_logical/Testcase_002_034.noja-test similarity index 91% rename from tests/suite/Testcase_002_034 rename to tests/compiler/expr/relational_and_logical/Testcase_002_034.noja-test index 9ebf311..034fd51 100644 --- a/tests/suite/Testcase_002_034 +++ b/tests/compiler/expr/relational_and_logical/Testcase_002_034.noja-test @@ -1,12 +1,13 @@ -#source +@type [compiler] +@source 1 + 2 > 3 + 4; 1 + 2 < 3 + 4; 1 + 2 >= 3 + 4; 1 + 2 <= 3 + 4; -#bytecode +@bytecode PUSHINT 1; PUSHINT 2; diff --git a/tests/suite/Testcase_011_000 b/tests/compiler/func/Testcase_011_000.noja-test similarity index 55% rename from tests/suite/Testcase_011_000 rename to tests/compiler/func/Testcase_011_000.noja-test index 9c63008..c389f30 100644 --- a/tests/suite/Testcase_011_000 +++ b/tests/compiler/func/Testcase_011_000.noja-test @@ -1,11 +1,12 @@ -#source +@type [compiler] +@source fun X() {} -#bytecode +@bytecode - PUSHFUN fun, 0; + PUSHFUN fun, 0, "X"; JUMP end; fun: RETURN 0; diff --git a/tests/suite/Testcase_011_001 b/tests/compiler/func/Testcase_011_001.noja-test similarity index 66% rename from tests/suite/Testcase_011_001 rename to tests/compiler/func/Testcase_011_001.noja-test index 9f04e8d..f4f000c 100644 --- a/tests/suite/Testcase_011_001 +++ b/tests/compiler/func/Testcase_011_001.noja-test @@ -1,11 +1,12 @@ -#source +@type [compiler] +@source fun X() "Hello, world!"; -#bytecode +@bytecode - PUSHFUN fun, 0; + PUSHFUN fun, 0, "X"; JUMP end; fun: PUSHSTR "Hello, world!"; diff --git a/tests/suite/Testcase_011_002 b/tests/compiler/func/Testcase_011_002.noja-test similarity index 74% rename from tests/suite/Testcase_011_002 rename to tests/compiler/func/Testcase_011_002.noja-test index 37658ae..23def24 100644 --- a/tests/suite/Testcase_011_002 +++ b/tests/compiler/func/Testcase_011_002.noja-test @@ -1,14 +1,15 @@ -#source +@type [compiler] +@source fun X() { "Hello, world!"; return false; } -#bytecode +@bytecode - PUSHFUN fun, 0; + PUSHFUN fun, 0, "X"; JUMP end; fun: PUSHSTR "Hello, world!"; diff --git a/tests/suite/Testcase_011_003 b/tests/compiler/func/Testcase_011_003.noja-test similarity index 70% rename from tests/suite/Testcase_011_003 rename to tests/compiler/func/Testcase_011_003.noja-test index 608d508..fe2dc38 100644 --- a/tests/suite/Testcase_011_003 +++ b/tests/compiler/func/Testcase_011_003.noja-test @@ -1,13 +1,14 @@ -#source +@type [compiler] +@source fun nop(a) { return a; } -#bytecode +@bytecode - PUSHFUN fun, 1; + PUSHFUN fun, 1, "nop"; JUMP end; fun: ASS "a"; diff --git a/tests/suite/Testcase_011_004 b/tests/compiler/func/Testcase_011_004.noja-test similarity index 76% rename from tests/suite/Testcase_011_004 rename to tests/compiler/func/Testcase_011_004.noja-test index cc718c3..956ad66 100644 --- a/tests/suite/Testcase_011_004 +++ b/tests/compiler/func/Testcase_011_004.noja-test @@ -1,13 +1,14 @@ -#source +@type [compiler] +@source fun add(a, b) { return a + b; } -#bytecode +@bytecode - PUSHFUN fun, 2; + PUSHFUN fun, 2, "add"; JUMP end; fun: ASS "b"; diff --git a/tests/suite/Testcase_011_005 b/tests/compiler/func/Testcase_011_005.noja-test similarity index 75% rename from tests/suite/Testcase_011_005 rename to tests/compiler/func/Testcase_011_005.noja-test index 6fb92f7..985884a 100644 --- a/tests/suite/Testcase_011_005 +++ b/tests/compiler/func/Testcase_011_005.noja-test @@ -1,13 +1,14 @@ -#source +@type [compiler] +@source fun nop(a: None) { return a; } -#bytecode +@bytecode - PUSHFUN fun, 1; + PUSHFUN fun, 1, "nop"; JUMP end; fun: PUSHVAR "None"; diff --git a/tests/suite/Testcase_011_006 b/tests/compiler/func/Testcase_011_006.noja-test similarity index 79% rename from tests/suite/Testcase_011_006 rename to tests/compiler/func/Testcase_011_006.noja-test index 4d04c93..e2bcc2f 100644 --- a/tests/suite/Testcase_011_006 +++ b/tests/compiler/func/Testcase_011_006.noja-test @@ -1,13 +1,14 @@ -#source +@type [compiler] +@source fun add(a: int, b) { return a + b; } -#bytecode +@bytecode - PUSHFUN fun, 2; + PUSHFUN fun, 2, "add"; JUMP end; fun: ASS "b"; diff --git a/tests/suite/Testcase_011_007 b/tests/compiler/func/Testcase_011_007.noja-test similarity index 79% rename from tests/suite/Testcase_011_007 rename to tests/compiler/func/Testcase_011_007.noja-test index 8d05dba..926fbdd 100644 --- a/tests/suite/Testcase_011_007 +++ b/tests/compiler/func/Testcase_011_007.noja-test @@ -1,13 +1,14 @@ -#source +@type [compiler] +@source fun add(a, b: int) { return a + b; } -#bytecode +@bytecode - PUSHFUN fun, 2; + PUSHFUN fun, 2, "add"; JUMP end; fun: PUSHVAR "int"; diff --git a/tests/suite/Testcase_011_008 b/tests/compiler/func/Testcase_011_008.noja-test similarity index 81% rename from tests/suite/Testcase_011_008 rename to tests/compiler/func/Testcase_011_008.noja-test index 8d36d01..d359f1f 100644 --- a/tests/suite/Testcase_011_008 +++ b/tests/compiler/func/Testcase_011_008.noja-test @@ -1,13 +1,14 @@ -#source +@type [compiler] +@source fun add(a: int, b: int) { return a + b; } -#bytecode +@bytecode - PUSHFUN fun, 2; + PUSHFUN fun, 2, "add"; JUMP end; fun: PUSHVAR "int"; diff --git a/tests/suite/Testcase_011_009 b/tests/compiler/func/Testcase_011_009.noja-test similarity index 84% rename from tests/suite/Testcase_011_009 rename to tests/compiler/func/Testcase_011_009.noja-test index 1494c54..e47a272 100644 --- a/tests/suite/Testcase_011_009 +++ b/tests/compiler/func/Testcase_011_009.noja-test @@ -1,13 +1,14 @@ -#source +@type [compiler] +@source fun add(a: int | float, b: bool | Map) { return a + b; } -#bytecode +@bytecode - PUSHFUN fun, 2; + PUSHFUN fun, 2, "add"; JUMP end; fun: PUSHVAR "bool"; diff --git a/tests/suite/Testcase_012_000 b/tests/compiler/func/Testcase_012_000.noja-test similarity index 80% rename from tests/suite/Testcase_012_000 rename to tests/compiler/func/Testcase_012_000.noja-test index 70c893b..dbf4179 100644 --- a/tests/suite/Testcase_012_000 +++ b/tests/compiler/func/Testcase_012_000.noja-test @@ -1,12 +1,13 @@ -#source +@type [compiler] +@source fun nop(a = 1) {} -#bytecode +@bytecode - PUSHFUN nop, 1; + PUSHFUN nop, 1, "nop"; JUMP nop_end; nop: PUSHTYP; diff --git a/tests/suite/Testcase_012_001 b/tests/compiler/func/Testcase_012_001.noja-test similarity index 78% rename from tests/suite/Testcase_012_001 rename to tests/compiler/func/Testcase_012_001.noja-test index 6751111..fcfaf30 100644 --- a/tests/suite/Testcase_012_001 +++ b/tests/compiler/func/Testcase_012_001.noja-test @@ -1,12 +1,13 @@ -#source +@type [compiler] +@source fun nop(a = 1, b) {} -#bytecode +@bytecode - PUSHFUN nop, 2; + PUSHFUN nop, 2, "nop"; JUMP nop_end; nop: ASS "b"; diff --git a/tests/suite/Testcase_012_002 b/tests/compiler/func/Testcase_012_002.noja-test similarity index 78% rename from tests/suite/Testcase_012_002 rename to tests/compiler/func/Testcase_012_002.noja-test index 98fc52a..e282e64 100644 --- a/tests/suite/Testcase_012_002 +++ b/tests/compiler/func/Testcase_012_002.noja-test @@ -1,12 +1,13 @@ -#source +@type [compiler] +@source fun nop(a, b = true) {} -#bytecode +@bytecode - PUSHFUN nop, 2; + PUSHFUN nop, 2, "nop"; JUMP nop_end; nop: PUSHTYP; diff --git a/tests/suite/Testcase_012_003 b/tests/compiler/func/Testcase_012_003.noja-test similarity index 82% rename from tests/suite/Testcase_012_003 rename to tests/compiler/func/Testcase_012_003.noja-test index 8763941..06e7fdb 100644 --- a/tests/suite/Testcase_012_003 +++ b/tests/compiler/func/Testcase_012_003.noja-test @@ -1,12 +1,13 @@ -#source +@type [compiler] +@source fun nop(a: int = 1) {} -#bytecode +@bytecode - PUSHFUN nop, 1; + PUSHFUN nop, 1, "nop"; JUMP nop_end; nop: PUSHTYP; diff --git a/tests/suite/Testcase_008_000 b/tests/compiler/ifelse/Testcase_008_000.noja-test similarity index 63% rename from tests/suite/Testcase_008_000 rename to tests/compiler/ifelse/Testcase_008_000.noja-test index b9d0cfe..ec88577 100644 --- a/tests/suite/Testcase_008_000 +++ b/tests/compiler/ifelse/Testcase_008_000.noja-test @@ -1,10 +1,11 @@ -#source +@type [compiler] +@source if true: {} -#bytecode +@bytecode PUSHTRU; JUMPIFNOTANDPOP end; diff --git a/tests/suite/Testcase_008_001 b/tests/compiler/ifelse/Testcase_008_001.noja-test similarity index 69% rename from tests/suite/Testcase_008_001 rename to tests/compiler/ifelse/Testcase_008_001.noja-test index e092073..342a587 100644 --- a/tests/suite/Testcase_008_001 +++ b/tests/compiler/ifelse/Testcase_008_001.noja-test @@ -1,10 +1,11 @@ -#source +@type [compiler] +@source if true: none; -#bytecode +@bytecode PUSHTRU; JUMPIFNOTANDPOP end; diff --git a/tests/suite/Testcase_008_002 b/tests/compiler/ifelse/Testcase_008_002.noja-test similarity index 72% rename from tests/suite/Testcase_008_002 rename to tests/compiler/ifelse/Testcase_008_002.noja-test index a68fd35..3de0b69 100644 --- a/tests/suite/Testcase_008_002 +++ b/tests/compiler/ifelse/Testcase_008_002.noja-test @@ -1,12 +1,13 @@ -#source +@type [compiler] +@source if true: {} else {} -#bytecode +@bytecode PUSHTRU; JUMPIFNOTANDPOP end; diff --git a/tests/suite/Testcase_008_003 b/tests/compiler/ifelse/Testcase_008_003.noja-test similarity index 79% rename from tests/suite/Testcase_008_003 rename to tests/compiler/ifelse/Testcase_008_003.noja-test index cc31757..405723c 100644 --- a/tests/suite/Testcase_008_003 +++ b/tests/compiler/ifelse/Testcase_008_003.noja-test @@ -1,12 +1,13 @@ -#source +@type [compiler] +@source if none: true; else false; -#bytecode +@bytecode PUSHNNE; JUMPIFNOTANDPOP else; diff --git a/tests/compiler/other/Testcase_000_000.noja-test b/tests/compiler/other/Testcase_000_000.noja-test new file mode 100644 index 0000000..246dec9 --- /dev/null +++ b/tests/compiler/other/Testcase_000_000.noja-test @@ -0,0 +1,7 @@ +@type [compiler] + +@source + # (Empty source) + +@bytecode + EXIT; \ No newline at end of file diff --git a/tests/suite/Testcase_000_001 b/tests/compiler/other/Testcase_000_001.noja-test similarity index 51% rename from tests/suite/Testcase_000_001 rename to tests/compiler/other/Testcase_000_001.noja-test index 6301d1b..d9dd9d5 100644 --- a/tests/suite/Testcase_000_001 +++ b/tests/compiler/other/Testcase_000_001.noja-test @@ -1,10 +1,9 @@ +@type [compiler] -#source - +@source return none; -#bytecode - +@bytecode PUSHNNE; RETURN 1; EXIT; \ No newline at end of file diff --git a/tests/suite/Testcase_009_000 b/tests/compiler/while/Testcase_009_000.noja-test similarity index 69% rename from tests/suite/Testcase_009_000 rename to tests/compiler/while/Testcase_009_000.noja-test index 8b7944e..d3dc929 100644 --- a/tests/suite/Testcase_009_000 +++ b/tests/compiler/while/Testcase_009_000.noja-test @@ -1,10 +1,11 @@ -#source +@type [compiler] +@source while none: {} -#bytecode +@bytecode begin: PUSHNNE; diff --git a/tests/suite/Testcase_009_001 b/tests/compiler/while/Testcase_009_001.noja-test similarity index 78% rename from tests/suite/Testcase_009_001 rename to tests/compiler/while/Testcase_009_001.noja-test index 967f517..e9f2854 100644 --- a/tests/suite/Testcase_009_001 +++ b/tests/compiler/while/Testcase_009_001.noja-test @@ -1,11 +1,12 @@ -#source +@type [compiler] +@source while none: true; false; -#bytecode +@bytecode begin: PUSHNNE; diff --git a/tests/suite/Testcase_009_002 b/tests/compiler/while/Testcase_009_002.noja-test similarity index 84% rename from tests/suite/Testcase_009_002 rename to tests/compiler/while/Testcase_009_002.noja-test index 32e5603..f6a0ee0 100644 --- a/tests/suite/Testcase_009_002 +++ b/tests/compiler/while/Testcase_009_002.noja-test @@ -1,5 +1,6 @@ -#source +@type [compiler] +@source while none: { true; @@ -7,7 +8,7 @@ } false; -#bytecode +@bytecode begin: PUSHNNE; diff --git a/tests/suite/Testcase_009_003 b/tests/compiler/while/Testcase_009_003.noja-test similarity index 85% rename from tests/suite/Testcase_009_003 rename to tests/compiler/while/Testcase_009_003.noja-test index 8d400b9..a4042a7 100644 --- a/tests/suite/Testcase_009_003 +++ b/tests/compiler/while/Testcase_009_003.noja-test @@ -1,5 +1,6 @@ -#source +@type [compiler] +@source while none: { true; @@ -8,7 +9,7 @@ } false; -#bytecode +@bytecode begin: PUSHNNE; diff --git a/tests/suite/Testcase_009_004 b/tests/compiler/while/Testcase_009_004.noja-test similarity index 77% rename from tests/suite/Testcase_009_004 rename to tests/compiler/while/Testcase_009_004.noja-test index 0556869..147b91c 100644 --- a/tests/suite/Testcase_009_004 +++ b/tests/compiler/while/Testcase_009_004.noja-test @@ -1,11 +1,12 @@ -#source +@type [compiler] +@source while none: break; false; -#bytecode +@bytecode begin: PUSHNNE; diff --git a/tests/runtime/tcase_000.noja-test b/tests/runtime/tcase_000.noja-test new file mode 100644 index 0000000..67ed7e6 --- /dev/null +++ b/tests/runtime/tcase_000.noja-test @@ -0,0 +1,10 @@ +@type [runtime] + +@bytecode + PUSHNNE; + PUSHVAR "print"; + CALL 1, 1; + POP 1; + EXIT; + +@output [none] \ No newline at end of file diff --git a/tests/runtime/tcase_001.noja-test b/tests/runtime/tcase_001.noja-test new file mode 100644 index 0000000..e87e13f --- /dev/null +++ b/tests/runtime/tcase_001.noja-test @@ -0,0 +1,12 @@ +@type [runtime] + +@bytecode + + PUSHTRU; + + PUSHVAR "print"; + CALL 1, 1; + POP 1; + EXIT; + +@output [true] \ No newline at end of file diff --git a/tests/runtime/tcase_002.noja-test b/tests/runtime/tcase_002.noja-test new file mode 100644 index 0000000..57c8906 --- /dev/null +++ b/tests/runtime/tcase_002.noja-test @@ -0,0 +1,12 @@ +@type [runtime] + +@bytecode + + PUSHFLS; + + PUSHVAR "print"; + CALL 1, 1; + POP 1; + EXIT; + +@output [false] \ No newline at end of file diff --git a/tests/runtime/tcase_003.noja-test b/tests/runtime/tcase_003.noja-test new file mode 100644 index 0000000..457c871 --- /dev/null +++ b/tests/runtime/tcase_003.noja-test @@ -0,0 +1,12 @@ +@type [runtime] + +@bytecode + + PUSHINT 7; + + PUSHVAR "print"; + CALL 1, 1; + POP 1; + EXIT; + +@output [7] diff --git a/tests/runtime/tcase_004.noja-test b/tests/runtime/tcase_004.noja-test new file mode 100644 index 0000000..84b2e18 --- /dev/null +++ b/tests/runtime/tcase_004.noja-test @@ -0,0 +1,12 @@ +@type [runtime] + +@bytecode + + PUSHFLT 8.5; + + PUSHVAR "print"; + CALL 1, 1; + POP 1; + EXIT; + +@output [8.50] diff --git a/tests/runtime/tcase_005.noja-test b/tests/runtime/tcase_005.noja-test new file mode 100644 index 0000000..2f8b148 --- /dev/null +++ b/tests/runtime/tcase_005.noja-test @@ -0,0 +1,12 @@ +@type [runtime] + +@bytecode + + PUSHLST 0; + + PUSHVAR "print"; + CALL 1, 1; + POP 1; + EXIT; + +@output {[]} diff --git a/tests/runtime/tcase_006.noja-test b/tests/runtime/tcase_006.noja-test new file mode 100644 index 0000000..8011914 --- /dev/null +++ b/tests/runtime/tcase_006.noja-test @@ -0,0 +1,12 @@ +@type [runtime] + +@bytecode + + PUSHNNETYP; + + PUSHVAR "print"; + CALL 1, 1; + POP 1; + EXIT; + +@output [None] \ No newline at end of file diff --git a/tests/runtime/tcase_007.noja-test b/tests/runtime/tcase_007.noja-test new file mode 100644 index 0000000..9256faa --- /dev/null +++ b/tests/runtime/tcase_007.noja-test @@ -0,0 +1,13 @@ +@type [runtime] + +@bytecode + + PUSHTRU; + PUSHTYP; + + PUSHVAR "print"; + CALL 1, 1; + POP 2; + EXIT; + +@output [bool] \ No newline at end of file diff --git a/tests/runtime/tcase_008.noja-test b/tests/runtime/tcase_008.noja-test new file mode 100644 index 0000000..95aa383 --- /dev/null +++ b/tests/runtime/tcase_008.noja-test @@ -0,0 +1,17 @@ +@type [runtime] + +@bytecode + + PUSHTRU; + JUMPIFNOTANDPOP ye; + PUSHINT 100; + JUMP end; +ye: + PUSHINT 300; +end: + PUSHVAR "print"; + CALL 1, 1; + POP 1; + EXIT; + +@output [100] \ No newline at end of file diff --git a/tests/runtime/tcase_009.noja-test b/tests/runtime/tcase_009.noja-test new file mode 100644 index 0000000..322c9ef --- /dev/null +++ b/tests/runtime/tcase_009.noja-test @@ -0,0 +1,17 @@ +@type [runtime] + +@bytecode + + PUSHFLS; + JUMPIFNOTANDPOP ye; + PUSHINT 100; + JUMP end; +ye: + PUSHINT 300; +end: + PUSHVAR "print"; + CALL 1, 1; + POP 1; + EXIT; + +@output [300] \ No newline at end of file diff --git a/tests/runtime/tcase_010.noja-test b/tests/runtime/tcase_010.noja-test new file mode 100644 index 0000000..5857ea0 --- /dev/null +++ b/tests/runtime/tcase_010.noja-test @@ -0,0 +1,17 @@ +@type [runtime] + +@bytecode + + PUSHTRU; + JUMPIFANDPOP ye; + PUSHINT 100; + JUMP end; +ye: + PUSHINT 300; +end: + PUSHVAR "print"; + CALL 1, 1; + POP 1; + EXIT; + +@output [300] \ No newline at end of file diff --git a/tests/runtime/tcase_011.noja-test b/tests/runtime/tcase_011.noja-test new file mode 100644 index 0000000..fffa255 --- /dev/null +++ b/tests/runtime/tcase_011.noja-test @@ -0,0 +1,17 @@ +@type [runtime] + +@bytecode + + PUSHFLS; + JUMPIFANDPOP ye; + PUSHINT 100; + JUMP end; +ye: + PUSHINT 300; +end: + PUSHVAR "print"; + CALL 1, 1; + POP 1; + EXIT; + +@output [100] \ No newline at end of file diff --git a/tests/runtime/tcase_012.noja-test b/tests/runtime/tcase_012.noja-test new file mode 100644 index 0000000..f57bf09 --- /dev/null +++ b/tests/runtime/tcase_012.noja-test @@ -0,0 +1,13 @@ +@type [runtime] + +@bytecode + + PUSHINT 23; + POS; + + PUSHVAR "print"; + CALL 1, 1; + POP 1; + EXIT; + +@output [23] \ No newline at end of file diff --git a/tests/suite/Testcase_000_000 b/tests/suite/Testcase_000_000 deleted file mode 100644 index e7d6b3f..0000000 --- a/tests/suite/Testcase_000_000 +++ /dev/null @@ -1,7 +0,0 @@ - -#source - - # (Empty source) - -#bytecode - EXIT; \ No newline at end of file diff --git a/tests/suite/Testcase_001_000 b/tests/suite/Testcase_001_000 deleted file mode 100644 index 9ff6226..0000000 --- a/tests/suite/Testcase_001_000 +++ /dev/null @@ -1,10 +0,0 @@ - -#source - - 1; - -#bytecode - - PUSHINT 1; - POP 1; - EXIT; \ No newline at end of file diff --git a/tests/suite/Testcase_001_007 b/tests/suite/Testcase_001_007 deleted file mode 100644 index 4317e6e..0000000 --- a/tests/suite/Testcase_001_007 +++ /dev/null @@ -1,10 +0,0 @@ - -#source - - []; - -#bytecode - - PUSHLST 0; - POP 1; - EXIT; \ No newline at end of file diff --git a/tests/suite/Testcase_001_008 b/tests/suite/Testcase_001_008 deleted file mode 100644 index 753a3b8..0000000 --- a/tests/suite/Testcase_001_008 +++ /dev/null @@ -1,8 +0,0 @@ - -#source - - {} - -#bytecode - - EXIT; \ No newline at end of file diff --git a/tests/suite/Testcase_003_000 b/tests/suite/Testcase_003_000 deleted file mode 100644 index 738c4a9..0000000 --- a/tests/suite/Testcase_003_000 +++ /dev/null @@ -1,13 +0,0 @@ - -#source - - [1]; - -#bytecode - - PUSHLST 1; - PUSHINT 0; - PUSHINT 1; - INSERT; - POP 1; - EXIT; \ No newline at end of file diff --git a/tests/test.noja b/tests/test.noja deleted file mode 100644 index a1aa511..0000000 --- a/tests/test.noja +++ /dev/null @@ -1,129 +0,0 @@ - -# Test the equal operator -{ - assert(1 == 1); - assert(1.0 == 1.0); - assert('--' == '--'); -} - -# Test assignment. -{ - a = 3; - assert(a == 3); -} - -# Test operations on integers. -{ - assert(4 == +4); - assert(0-4 == -4); - assert(1 + 1 == 2); - assert(2 * 3 == 6); - assert(6 / 3 == 2); - assert(4 < 5); - assert(4 > 3); - assert(4 <= 5); - assert(4 <= 4); - assert(4 >= 3); - assert(4 == 4); - assert(4 != 3); -} - -# Test operations on floats. -{ - assert(4.0 == +4.0); - assert(0-4.0 == -4.0); - assert(1.0 + 1.0 == 2.0); - assert(2.0 * 3.0 == 6.0); - assert(6.0 / 3.0 == 2.0); - assert(4.0 < 5.0); - assert(4.0 > 3.0); - assert(4.0 <= 5.0); - assert(4.0 <= 4.0); - assert(4.0 >= 3.0); - assert(4.0 == 4.0); - assert(4.0 != 3.0); -} - -# Test operations on strings. -{ - assert('hey' == 'hey'); - assert('hey' != 'hey2'); -} - -# Test operations on bools. -{ - assert(true); - assert(true == true); - assert(true != false); - assert(false == false); - assert(false != true); - assert(true == not false); - assert(false == not true); - assert((true and true ) == true); - assert((true and false) == false); - assert((false and true ) == false); - assert((false and false) == false); - assert((true or true ) == true); - assert((true or false) == true); - assert((false or true ) == true); - assert((false or false) == false); -} - -# Test short-circuitness of the logical operators -{ - # The assertions shouldn't trigger. - true or assert(false); - false and assert(false); -} - -# Test lists. -{ - [1]; [1.0]; ['x']; [1, 1]; [1.0, 1.0]; ['x', 'x']; -} - -# Test maps. -{ - ({}); - ({ '' : none }); - ({ 1 : none }); - ({ 1.0 : none }); - ({ none : none }); - ({ true : none }); - ({ false: none }); - ({ [] : none }); - ({ {} : none }); - ({ none : '' }); - ({ none : 1 }); - ({ none : 1.0 }); - ({ none : true }); - ({ none : false }); - ({ none : [] }); - ({ none : {} }); -} - -# Test if-else statements. -{ - if true: r = true; else r = false; - assert(r); - - if true: { r = true; } else { r = false; } - assert(r); - - if false: r = false; else r = true; - assert(r); - - if false: { r = false; } else { r = true; } - assert(r); -} - -# Test type variables -{ - assert(type(none) == None); - assert(type(1) == int); - assert(type(10.4) == float); - assert(type("Hello, world!") == String); - assert(type([]) == List); - assert(type({}) == Map); -} - -print('No assertion failed.\n'); \ No newline at end of file