From 0980cc193d1a44d32c4e9f6f75a3d38252303470 Mon Sep 17 00:00:00 2001 From: Francesco Cozzuto Date: Fri, 20 Jan 2023 01:22:20 +0100 Subject: [PATCH] changed error reporting function interface --- examples/importer.noja | 8 +- src/lib/assembler/assemble.c | 31 +++--- src/lib/builtins/basic.c | 21 ++-- src/lib/builtins/buffer.c | 8 +- src/lib/builtins/files.c | 10 +- src/lib/builtins/math.c | 10 +- src/lib/builtins/string.c | 20 ++-- src/lib/builtins/utils.c | 28 +++--- src/lib/common/executable.c | 22 ++-- src/lib/compiler/codegen.c | 12 +-- src/lib/compiler/codegenctx.c | 12 +-- src/lib/compiler/codegenctx.h | 2 +- src/lib/compiler/compile.c | 13 +-- src/lib/compiler/compile.h | 7 +- src/lib/compiler/parse.c | 184 +++++++++++++++++----------------- src/lib/noja.c | 176 +++++++++++++------------------- src/lib/objects/heap.c | 10 +- src/lib/objects/o_buffer.c | 20 ++-- src/lib/objects/o_dir.c | 2 +- src/lib/objects/o_file.c | 2 +- src/lib/objects/o_list.c | 8 +- src/lib/objects/o_string.c | 6 +- src/lib/objects/objects.c | 12 +-- src/lib/runtime/o_func.c | 4 +- src/lib/runtime/runtime.c | 78 +++++++------- src/lib/utils/error.c | 40 +++++++- src/lib/utils/error.h | 16 ++- src/lib/utils/source.c | 20 ++-- src/test/main.c | 46 ++------- 29 files changed, 391 insertions(+), 437 deletions(-) diff --git a/examples/importer.noja b/examples/importer.noja index 9637174..dd5b8fa 100644 --- a/examples/importer.noja +++ b/examples/importer.noja @@ -1,10 +1,6 @@ -vars, err = import("imported.noja"); -if vars == none: { - print("Import failed!! (", err, ")\n"); - return none; -} +vars = import("imported.noja"); me = {name: vars.myName, age: vars.myAge}; -print(me, "\n"); \ No newline at end of file +print(me, "\n"); diff --git a/src/lib/assembler/assemble.c b/src/lib/assembler/assemble.c index e1b9f2f..95c7c8c 100644 --- a/src/lib/assembler/assemble.c +++ b/src/lib/assembler/assemble.c @@ -56,7 +56,8 @@ static bool parseLabelAndOpcode(Context *ctx, bool *no_label, char c = ctx->str[ctx->cur]; if(!isalpha(c) && c != '_') { // ERROR: Missing opcode - Error_Report(error, 0, "Missing opcode"); + Error_Report(error, ErrorType_SYNTAX, "Missing opcode"); + #warning "should there be a return here?" } label_or_opcode.offset = ctx->cur; @@ -77,7 +78,7 @@ static bool parseLabelAndOpcode(Context *ctx, bool *no_label, skipSpaces(ctx); if(ctx->cur == ctx->len || (!isalpha(ctx->str[ctx->cur]) && ctx->str[ctx->cur] != '_')) { - Error_Report(error, 0, "Missing opcode after label"); + Error_Report(error, ErrorType_SYNTAX, "Missing opcode after label"); return false; } @@ -111,7 +112,7 @@ static bool parseStringOperand(Context *ctx, Error *error, BPAlloc *alloc, Opera ctx->cur += 1; if(ctx->cur == ctx->len) { - Error_Report(error, 0, "End of source inside a string literal"); + Error_Report(error, ErrorType_SYNTAX, "End of source inside a string literal"); return false; } @@ -123,7 +124,7 @@ static bool parseStringOperand(Context *ctx, Error *error, BPAlloc *alloc, Opera char *copy = BPAlloc_Malloc(alloc, literal_length+1); if(copy == NULL) { - Error_Report(error, 1, "No memory"); + Error_Report(error, ErrorType_INTERNAL, "No memory"); return false; } @@ -151,7 +152,7 @@ static bool parseIntegerOperand(Context *ctx, Error *error, Operand *op) // Will this overflow? if(buffer > (LLONG_MAX - d) / 10) { - Error_Report(error, 0, "Integer literal is too big to be represented in %d bits", 8*sizeof(buffer)); + Error_Report(error, ErrorType_SEMANTIC, "Integer literal is too big to be represented in %d bits", 8*sizeof(buffer)); return false; } @@ -254,7 +255,7 @@ static bool parseOperands(Context *ctx, BPAlloc *alloc, Error *error, Promise *promise = LabelList_GetLabel(list, ctx->str + offset, length); if(promise == NULL) { - Error_Report(error, 1, "No memory"); + Error_Report(error, ErrorType_INTERNAL, "No memory"); return false; } @@ -263,12 +264,12 @@ static bool parseOperands(Context *ctx, BPAlloc *alloc, Error *error, } else { // ERROR: Unexpected character - Error_Report(error, 0, "Unexpected character '%c'", c); + Error_Report(error, ErrorType_SYNTAX, "Unexpected character '%c'", c); return false; } if(*opc == opc_max) { - Error_Report(error, 0, "Too many operands"); + Error_Report(error, ErrorType_SEMANTIC, "Too many operands"); return false; } opv[*opc] = op; @@ -281,7 +282,7 @@ static bool parseOperands(Context *ctx, BPAlloc *alloc, Error *error, c = ctx->str[ctx->cur]; if(c != ',') { - Error_Report(error, 0, "Unexpected character '%c' (',' or ';' were expected)", c); + Error_Report(error, ErrorType_SYNTAX, "Unexpected character '%c' (',' or ';' were expected)", c); return false; } @@ -301,20 +302,20 @@ Executable *assemble(Source *src, Error *error) BPAlloc *alloc = BPAlloc_Init(-1); if(alloc == NULL) { - Error_Report(error, 1, "No memory"); + Error_Report(error, ErrorType_INTERNAL, "No memory"); return NULL; } LabelList *list = LabelList_New(alloc); if(list == NULL) { - Error_Report(error, 1, "No memory"); + Error_Report(error, ErrorType_INTERNAL, "No memory"); BPAlloc_Free(alloc); return NULL; } ExeBuilder *builder = ExeBuilder_New(alloc); if(builder == NULL) { - Error_Report(error, 1, "No memory"); + Error_Report(error, ErrorType_INTERNAL, "No memory"); LabelList_Free(list); BPAlloc_Free(alloc); return NULL; @@ -342,7 +343,7 @@ Executable *assemble(Source *src, Error *error) if(no_label == false) { long long int value = ExeBuilder_InstrCount(builder); if(!LabelList_SetLabel(list, ctx.str + label.offset, label.length, value)) { - Error_Report(error, 1, "Out of memory"); + Error_Report(error, ErrorType_INTERNAL, "Out of memory"); goto done; } } @@ -352,7 +353,7 @@ Executable *assemble(Source *src, Error *error) Opcode opcode; const char *name = ctx.str + opcode_name.offset; if(!Executable_GetOpcodeBinaryFromName(name, opcode_name.length, &opcode)) { - Error_Report(error, 0, "Opcode %.*s doesn't exist", (int) opcode_name.length, name); + Error_Report(error, ErrorType_SEMANTIC, "Opcode %.*s doesn't exist", (int) opcode_name.length, name); goto done; } @@ -377,7 +378,7 @@ Executable *assemble(Source *src, Error *error) size_t unresolved_count = LabelList_GetUnresolvedCount(list); if(unresolved_count > 0) { - Error_Report(error, 0, "%d unresolved labels", unresolved_count); + Error_Report(error, ErrorType_SEMANTIC, "%d unresolved labels", unresolved_count); goto done; } diff --git a/src/lib/builtins/basic.c b/src/lib/builtins/basic.c index ed76e6d..10ee89d 100644 --- a/src/lib/builtins/basic.c +++ b/src/lib/builtins/basic.c @@ -54,7 +54,7 @@ static int bin_getCurrentWorkingDirectory(Runtime *runtime, Object **argv, unsig char path[1024]; if(getcwd(path, sizeof(path)) == NULL) { - Error_Report(error, 1, "Couldn't get current working directory because a buffer is too small"); + Error_Report(error, ErrorType_INTERNAL, "Couldn't get current working directory because a buffer is too small"); return -1; } @@ -139,19 +139,19 @@ static int bin_import(Runtime *runtime, if(path[0] == '/') { if(path_len >= sizeof(full_path)) { - Error_Report(error, 1, "Internal buffer is too small"); + Error_Report(error, ErrorType_INTERNAL, "Internal buffer is too small"); return -1; } strcpy(full_path, path); } else { size_t written = Runtime_GetCurrentScriptFolder(runtime, full_path, sizeof(full_path)); if(written == 0) { - Error_Report(error, 1, "Internal buffer is too small"); + Error_Report(error, ErrorType_INTERNAL, "Internal buffer is too small"); return -1; } if(written + path_len >= sizeof(full_path)) { - Error_Report(error, 1, "Internal buffer is too small"); + Error_Report(error, ErrorType_INTERNAL, "Internal buffer is too small"); return -1; } @@ -163,8 +163,7 @@ static int bin_import(Runtime *runtime, if(src == NULL) return -1; - CompilationErrorType errtyp; - Executable *exe = compile(src, error, &errtyp); + Executable *exe = compile(src, error); if(exe == NULL) { Source_Free(src); return -1; @@ -241,7 +240,7 @@ static int bin_input(Runtime *runtime, Object **argv, unsigned int argc, Object if(tmp == NULL) { if(str != maybe) free(str); - Error_Report(error, 1, "No memory"); + Error_Report(error, ErrorType_INTERNAL, "No memory"); return -1; } @@ -275,13 +274,13 @@ static int bin_assert(Runtime *runtime, Object **argv, unsigned int argc, Object { if(!Object_IsBool(argv[i])) { - Error_Report(error, 0, "Argument %d isn't a boolean", i); + Error_Report(error, ErrorType_RUNTIME, "Argument %d isn't a boolean", i); return -1; } if(!Object_GetBool(argv[i])) { - Error_Report(error, 0, "Assertion failed"); + Error_Report(error, ErrorType_RUNTIME, "Assertion failed"); return -1; } } @@ -298,7 +297,7 @@ static int bin_error(Runtime *runtime, Object **argv, unsigned int argc, Object if(!Object_IsString(argv[0])) { - Error_Report(error, 0, "Argument is not a string"); + Error_Report(error, ErrorType_RUNTIME, "Argument is not a string"); return -1; } @@ -308,7 +307,7 @@ static int bin_error(Runtime *runtime, Object **argv, unsigned int argc, Object string = Object_GetString(argv[0], &length); ASSERT(string != NULL); - Error_Report(error, 0, "%s", string); + Error_Report(error, ErrorType_RUNTIME, "%s", string); return -1; } diff --git a/src/lib/builtins/buffer.c b/src/lib/builtins/buffer.c index c10c671..3de0063 100644 --- a/src/lib/builtins/buffer.c +++ b/src/lib/builtins/buffer.c @@ -11,7 +11,7 @@ static int bin_new(Runtime *runtime, Object **argv, unsigned int argc, Object *r if(!Object_IsInt(argv[0])) { - Error_Report(error, 0, "Argument is not an int"); + Error_Report(error, ErrorType_RUNTIME, "Argument is not an int"); return -1; } @@ -33,13 +33,13 @@ static int bin_sliceUp(Runtime *runtime, Object **argv, unsigned int argc, Objec if(!Object_IsInt(argv[1])) { - Error_Report(error, 0, "Argument 1 is not an int"); + Error_Report(error, ErrorType_RUNTIME, "Argument 1 is not an int"); return -1; } if(!Object_IsInt(argv[2])) { - Error_Report(error, 0, "Argument 2 is not an int"); + Error_Report(error, ErrorType_RUNTIME, "Argument 2 is not an int"); return -1; } @@ -78,7 +78,7 @@ static int bin_toString(Runtime *runtime, Object **argv, unsigned int argc, Obje if(!Object_IsBuffer(argv[0])) { - Error_Report(error, 0, "Argument is not a buffer"); + Error_Report(error, ErrorType_RUNTIME, "Argument is not a buffer"); return -1; } diff --git a/src/lib/builtins/files.c b/src/lib/builtins/files.c index 56053ab..ff18b96 100644 --- a/src/lib/builtins/files.c +++ b/src/lib/builtins/files.c @@ -124,7 +124,7 @@ static int bin_read(Runtime *runtime, Object **argv, unsigned int argc, Object * if (pargs[2].defined) { int n = pargs[2].as_int; if (n < 0) { - Error_Report(error, 0, "Argument count must be a non-negative integer"); + Error_Report(error, ErrorType_RUNTIME, "Argument count must be a non-negative integer"); return -1; } count = MIN((size_t) n, dstlen); @@ -160,7 +160,7 @@ static int bin_write(Runtime *runtime, Object **argv, unsigned int argc, Object if (pargs[2].defined) { int n = pargs[2].as_int; if (n < 0) { - Error_Report(error, 0, "Argument count must be a non-negative integer"); + Error_Report(error, ErrorType_RUNTIME, "Argument count must be a non-negative integer"); return -1; } count = MIN((size_t) n, srclen); @@ -181,7 +181,7 @@ static int bin_openDir(Runtime *runtime, Object **argv, unsigned int argc, Objec if(!Object_IsString(argv[0])) { - Error_Report(error, 0, "Expected first argument to be a string, but it's a %s", Object_GetName(argv[0])); + Error_Report(error, ErrorType_RUNTIME, "Expected first argument to be a string, but it's a %s", Object_GetName(argv[0])); return -1; } @@ -216,7 +216,7 @@ static int bin_nextDirItem(Runtime *runtime, Object **argv, unsigned int argc, O if(!Object_IsDir(argv[0])) { - Error_Report(error, 0, "Expected first argument to be a directory, but it's a %s", Object_GetName(argv[0])); + Error_Report(error, ErrorType_RUNTIME, "Expected first argument to be a directory, but it's a %s", Object_GetName(argv[0])); return -1; } @@ -233,7 +233,7 @@ static int bin_nextDirItem(Runtime *runtime, Object **argv, unsigned int argc, O return 0; // Nothing left to read. // An error occurred. - Error_Report(error, 1, "Failed to read directory item"); + Error_Report(error, ErrorType_INTERNAL, "Failed to read directory item"); return -1; } diff --git a/src/lib/builtins/math.c b/src/lib/builtins/math.c index 5510349..6385e97 100644 --- a/src/lib/builtins/math.c +++ b/src/lib/builtins/math.c @@ -49,7 +49,7 @@ } \ else \ { \ - Error_Report(error, 0, "Expected first argument to be a float, but it's a %s", Object_GetName(argv[0])); \ + Error_Report(error, ErrorType_RUNTIME, "Expected first argument to be a float, but it's a %s", Object_GetName(argv[0])); \ return -1; \ } \ } @@ -62,13 +62,13 @@ \ if(!Object_IsFloat(argv[0])) \ { \ - Error_Report(error, 0, "Expected first argument to be a float, but it's a %s", Object_GetName(argv[0])); \ + Error_Report(error, ErrorType_RUNTIME, "Expected first argument to be a float, but it's a %s", Object_GetName(argv[0])); \ return -1; \ } \ \ if(!Object_IsFloat(argv[1])) \ { \ - Error_Report(error, 0, "Expected second argument to be a float, but it's a %s", Object_GetName(argv[1])); \ + Error_Report(error, ErrorType_RUNTIME, "Expected second argument to be a float, but it's a %s", Object_GetName(argv[1])); \ return -1; \ } \ \ @@ -110,7 +110,7 @@ static int bin_ceil(Runtime *runtime, Object **argv, unsigned int argc, Object * } else { - Error_Report(error, 0, "Expected first argument to be a float, but it's a %s", Object_GetName(argv[0])); + Error_Report(error, ErrorType_RUNTIME, "Expected first argument to be a float, but it's a %s", Object_GetName(argv[0])); return -1; } } @@ -131,7 +131,7 @@ static int bin_floor(Runtime *runtime, Object **argv, unsigned int argc, Object } else { - Error_Report(error, 0, "Expected first argument to be a float, but it's a %s", Object_GetName(argv[0])); + Error_Report(error, ErrorType_RUNTIME, "Expected first argument to be a float, but it's a %s", Object_GetName(argv[0])); return -1; } } diff --git a/src/lib/builtins/string.c b/src/lib/builtins/string.c index 1d1079d..508079a 100644 --- a/src/lib/builtins/string.c +++ b/src/lib/builtins/string.c @@ -19,7 +19,7 @@ static int bin_ord(Runtime *runtime, Object **argv, unsigned int argc, Object *r if(!Object_IsString(argv[0])) { - Error_Report(error, 0, "Argument #%d is not a string", 1); + Error_Report(error, ErrorType_RUNTIME, "Argument #%d is not a string", 1); return -1; } @@ -30,7 +30,7 @@ static int bin_ord(Runtime *runtime, Object **argv, unsigned int argc, Object *r if(length == 0) { - Error_Report(error, 0, "Argument #%d is an empty string", 1); + Error_Report(error, ErrorType_RUNTIME, "Argument #%d is an empty string", 1); return -1; } @@ -55,7 +55,7 @@ static int bin_chr(Runtime *runtime, Object **argv, unsigned int argc, Object *r if(!Object_IsInt(argv[0])) { - Error_Report(error, 0, "Argument #%d is not an integer", 1); + Error_Report(error, ErrorType_RUNTIME, "Argument #%d is not an integer", 1); return -1; } @@ -67,7 +67,7 @@ static int bin_chr(Runtime *runtime, Object **argv, unsigned int argc, Object *r if(k<0) { - Error_Report(error, 0, "Argument #%d is not valid utf-32", 1); + Error_Report(error, ErrorType_RUNTIME, "Argument #%d is not valid utf-32", 1); return -1; } @@ -88,7 +88,7 @@ static int bin_cat(Runtime *runtime, Object **argv, unsigned int argc, Object *r { if(!Object_IsString(argv[i])) { - Error_Report(error, 0, "Argument #%d is not a string", i+1); + Error_Report(error, ErrorType_RUNTIME, "Argument #%d is not a string", i+1); return -1; } @@ -110,7 +110,7 @@ static int bin_cat(Runtime *runtime, Object **argv, unsigned int argc, Object *r if(buffer == NULL) { - Error_Report(error, 1, "No memory"); + Error_Report(error, ErrorType_INTERNAL, "No memory"); return -1; } } @@ -157,7 +157,7 @@ static int bin_slice(Runtime *runtime, Object **argv, unsigned int argc, Object if (pargs[1].defined) { int64_t n = pargs[1].as_int; if (n < 0) { - Error_Report(error, 0, "starting offset of string slice must be non-negative"); + Error_Report(error, ErrorType_RUNTIME, "starting offset of string slice must be non-negative"); return -1; } offset = (size_t) n; @@ -167,7 +167,7 @@ static int bin_slice(Runtime *runtime, Object **argv, unsigned int argc, Object if (pargs[2].defined) { int64_t n = pargs[2].as_int; if (n < 0) { - Error_Report(error, 0, "length of string slice must be non-negative"); + Error_Report(error, ErrorType_RUNTIME, "length of string slice must be non-negative"); return -1; } length = (size_t) n; @@ -175,11 +175,11 @@ static int bin_slice(Runtime *runtime, Object **argv, unsigned int argc, Object length = srclen - offset; if (offset > srclen) { - Error_Report(error, 0, "string slice offset is out of bounds"); + Error_Report(error, ErrorType_RUNTIME, "string slice offset is out of bounds"); return -1; } if (offset + length > srclen) { - Error_Report(error, 0, "string slice length is out of bounds"); + Error_Report(error, ErrorType_RUNTIME, "string slice length is out of bounds"); return -1; } diff --git a/src/lib/builtins/utils.c b/src/lib/builtins/utils.c index e4b868a..5fb3b2c 100644 --- a/src/lib/builtins/utils.c +++ b/src/lib/builtins/utils.c @@ -6,7 +6,7 @@ int returnValuesVA(Error *error, Heap *heap, Object *rets[static MAX_RETS], cons while (fmt[i] != '\0') { if (retc == MAX_RETS) { - Error_Report(error, 1, "Return value limit reached"); + Error_Report(error, ErrorType_INTERNAL, "Return value limit reached"); return -1; } @@ -19,7 +19,7 @@ int returnValuesVA(Error *error, Heap *heap, Object *rets[static MAX_RETS], cons case 's': ret = Object_FromString(va_arg(va, char*), -1, heap, error); break; case 'F': ret = Object_FromStream(va_arg(va, FILE*), heap, error); break; default: - Error_Report(error, 1, "Invalid format specifier '%c'", fmt[i]); + Error_Report(error, ErrorType_INTERNAL, "Invalid format specifier '%c'", fmt[i]); return -1; } @@ -43,7 +43,7 @@ bool parseArgs(Error *error, while (fmt[i] != '\0') { if (current_arg == argc) { - Error_Report(error, 0, "Missing arguments"); + Error_Report(error, ErrorType_RUNTIME, "Missing arguments"); return false; } Object *arg = argv[current_arg]; @@ -53,11 +53,11 @@ bool parseArgs(Error *error, may_be_none = true; i++; if (fmt[i] == '\0') { - Error_Report(error, 1, "Format terminated unexpectedly"); + Error_Report(error, ErrorType_INTERNAL, "Format terminated unexpectedly"); return false; } } - + if (may_be_none && Object_IsNone(arg)) { pargs[current_arg].defined = false; } else { @@ -69,7 +69,7 @@ bool parseArgs(Error *error, case 'b': /* Boolean */ if (!Object_IsBool(arg)) { - Error_Report(error, 0, "Argument %d was expected to be bool, but a %s was provided", current_arg+1, arg->type->name); + Error_Report(error, ErrorType_RUNTIME, "Argument %d was expected to be bool, but a %s was provided", current_arg+1, arg->type->name); return false; } pargs[current_arg].defined = true; @@ -79,7 +79,7 @@ bool parseArgs(Error *error, case 'B': /* Buffer */ { if (!Object_IsBuffer(arg)) { - Error_Report(error, 0, "Argument %d was expected to be a buffer, but a %s was provided", current_arg+1, arg->type->name); + Error_Report(error, ErrorType_RUNTIME, "Argument %d was expected to be a buffer, but a %s was provided", current_arg+1, arg->type->name); return false; } void *data; @@ -93,7 +93,7 @@ bool parseArgs(Error *error, case 'i': /* Integer */ if (!Object_IsInt(arg)) { - Error_Report(error, 0, "Argument %d was expected to be an int, but a %s was provided", current_arg+1, arg->type->name); + Error_Report(error, ErrorType_RUNTIME, "Argument %d was expected to be an int, but a %s was provided", current_arg+1, arg->type->name); return false; } pargs[current_arg].defined = true; @@ -102,7 +102,7 @@ bool parseArgs(Error *error, case 'f': /* Float */ if (!Object_IsFloat(arg)) { - Error_Report(error, 0, "Argument %d was expected to be a float, but a %s was provided", current_arg+1, arg->type->name); + Error_Report(error, ErrorType_RUNTIME, "Argument %d was expected to be a float, but a %s was provided", current_arg+1, arg->type->name); return false; } pargs[current_arg].defined = true; @@ -111,7 +111,7 @@ bool parseArgs(Error *error, case 'l': /* List */ if (!Object_IsList(arg)) { - Error_Report(error, 0, "Argument %d was expected to be a list, but a %s was provided", current_arg+1, arg->type->name); + Error_Report(error, ErrorType_RUNTIME, "Argument %d was expected to be a list, but a %s was provided", current_arg+1, arg->type->name); return false; } pargs[current_arg].defined = true; @@ -119,7 +119,7 @@ bool parseArgs(Error *error, case 'm': /* Map */ if (!Object_IsMap(arg)) { - Error_Report(error, 0, "Argument %d was expected to be a map, but a %s was provided", current_arg+1, arg->type->name); + Error_Report(error, ErrorType_RUNTIME, "Argument %d was expected to be a map, but a %s was provided", current_arg+1, arg->type->name); return false; } break; @@ -127,7 +127,7 @@ bool parseArgs(Error *error, case 's': /* String */ { if (!Object_IsString(arg)) { - Error_Report(error, 0, "Argument %d was expected to be a string, but a %s was provided", current_arg+1, arg->type->name); + Error_Report(error, ErrorType_RUNTIME, "Argument %d was expected to be a string, but a %s was provided", current_arg+1, arg->type->name); return false; } const void *data; @@ -141,7 +141,7 @@ bool parseArgs(Error *error, case 'F': /* File */ if (!Object_IsFile(arg)) { - Error_Report(error, 0, "Argument %d was expected to be a file, but a %s was provided", current_arg+1, arg->type->name); + Error_Report(error, ErrorType_RUNTIME, "Argument %d was expected to be a file, but a %s was provided", current_arg+1, arg->type->name); return false; } pargs[current_arg].defined = true; @@ -149,7 +149,7 @@ bool parseArgs(Error *error, break; default: - Error_Report(error, 1, "Invalid argument parser format specifier '%c'", fmt[i]); + Error_Report(error, ErrorType_INTERNAL, "Invalid argument parser format specifier '%c'", fmt[i]); return false; } } diff --git a/src/lib/common/executable.c b/src/lib/common/executable.c index 1884ab5..5e76fa1 100644 --- a/src/lib/common/executable.c +++ b/src/lib/common/executable.c @@ -450,7 +450,7 @@ Executable *ExeBuilder_Finalize(ExeBuilder *exeb, Error *error) if(exeb->promc > 0) { - Error_Report(error, 1, "There are still %d unfulfilled promises", exeb->promc); + Error_Report(error, ErrorType_INTERNAL, "There are still %d unfulfilled promises", exeb->promc); return 0; } @@ -465,7 +465,7 @@ Executable *ExeBuilder_Finalize(ExeBuilder *exeb, Error *error) if(temp == NULL) { - Error_Report(error, 1, "No memory"); + Error_Report(error, ErrorType_INTERNAL, "No memory"); return NULL; } @@ -524,7 +524,7 @@ _Bool ExeBuilder_Append(ExeBuilder *exeb, Error *error, Opcode opcode, Operand * #ifndef NDEBUG if (info == NULL) { - Error_Report(error, 1, "Missing instruction table entry for opcode %d", opcode); + Error_Report(error, ErrorType_INTERNAL, "Missing instruction table entry for opcode %d", opcode); return 0; } #endif @@ -532,12 +532,12 @@ _Bool ExeBuilder_Append(ExeBuilder *exeb, Error *error, Opcode opcode, Operand * if(opc != info->opcount) { // ERROR: Too many operands were provided. - Error_Report(error, 1, + Error_Report(error, ErrorType_INTERNAL, "Instruction %s expects %d operands, but %d were provided", info->name, info->opcount, opc); return 0; } - + ASSERT(opc <= MAX_OPS); { @@ -545,7 +545,7 @@ _Bool ExeBuilder_Append(ExeBuilder *exeb, Error *error, Opcode opcode, Operand * if(instr == NULL) { - Error_Report(error, 1, "No memory"); + Error_Report(error, ErrorType_INTERNAL, "No memory"); return 0; } @@ -570,13 +570,13 @@ _Bool ExeBuilder_Append(ExeBuilder *exeb, Error *error, Opcode opcode, Operand * if(expected_type == OPTP_STRING) { - Error_Report(error, 1, "Promise values can't be provided as string operands"); + Error_Report(error, ErrorType_INTERNAL, "Promise values can't be provided as string operands"); return 0; } if(Promise_Size(opv[i].as_promise) != operand_type_sizes[expected_type]) { - Error_Report(error, 1, + Error_Report(error, ErrorType_INTERNAL, "Provided promise has a value size of %d, " "but since %s %s was expected, the promise " "size must be %d", @@ -590,7 +590,7 @@ _Bool ExeBuilder_Append(ExeBuilder *exeb, Error *error, Opcode opcode, Operand * else if(expected_type != provided_type) { // ERROR: Wrong operand type provided. - Error_Report(error, 1, + Error_Report(error, ErrorType_INTERNAL, "Instruction %s expects %s %s as operand %d, but %s %s was provided instead", info->name, operand_type_arts[expected_type], @@ -612,7 +612,7 @@ _Bool ExeBuilder_Append(ExeBuilder *exeb, Error *error, Opcode opcode, Operand * if(!BucketList_Append(exeb->data, opv[i].as_string, strlen(opv[i].as_string)+1)) { - Error_Report(error, 1, "No memory"); + Error_Report(error, ErrorType_INTERNAL, "No memory"); return 0; } break; @@ -628,7 +628,7 @@ _Bool ExeBuilder_Append(ExeBuilder *exeb, Error *error, Opcode opcode, Operand * if(!Promise_Subscribe2(opv[i].as_promise, &instr->operands[i], exeb, promise_callback)) { - Error_Report(error, 1, "No memory"); + Error_Report(error, ErrorType_INTERNAL, "No memory"); return 0; } break; diff --git a/src/lib/compiler/codegen.c b/src/lib/compiler/codegen.c index 2271418..7c02beb 100644 --- a/src/lib/compiler/codegen.c +++ b/src/lib/compiler/codegen.c @@ -320,7 +320,7 @@ static void flattenTupleTree(CodegenContext *ctx, ExprNode *root, ExprNode *tupl if(max == *count) { - CodegenContext_ReportErrorAndJump(ctx, 0, "Static buffer is too small"); + CodegenContext_ReportErrorAndJump(ctx, ErrorType_INTERNAL, "Static buffer is too small"); UNREACHABLE; } @@ -348,7 +348,7 @@ static void emitInstrForAssignmentNode(CodegenContext *ctx, OperExprNode *asgn, if(((ExprNode*) rop)->kind == EXPR_CALL) emitInstrForFuncCallNode(ctx, (CallExprNode*) rop, label_break, count); else { - CodegenContext_ReportErrorAndJump(ctx, 0, "Assigning to %d variables only 1 value", count); + CodegenContext_ReportErrorAndJump(ctx, ErrorType_SEMANTIC, "Assigning to %d variables only 1 value", count); UNREACHABLE; } } @@ -376,7 +376,7 @@ static void emitInstrForAssignmentNode(CodegenContext *ctx, OperExprNode *asgn, } default: - CodegenContext_ReportErrorAndJump(ctx, 0, "Assigning to something that it can't be assigned to"); + CodegenContext_ReportErrorAndJump(ctx, ErrorType_SEMANTIC, "Assigning to something that it can't be assigned to"); UNREACHABLE; } @@ -415,7 +415,7 @@ static void emitInstrForExprNode(CodegenContext *ctx, ExprNode *expr, } case EXPR_ARW: - CodegenContext_ReportErrorAndJump(ctx, 0, "Operator -> out of a function call"); + CodegenContext_ReportErrorAndJump(ctx, ErrorType_SEMANTIC, "Operator -> out of a function call"); UNREACHABLE; return; @@ -683,7 +683,7 @@ static void emitInstrForNode(CodegenContext *ctx, Node *node, Label *label_break case NODE_BREAK: if(label_break == NULL) - CodegenContext_ReportErrorAndJump(ctx, 0, "Break not inside a loop"); + CodegenContext_ReportErrorAndJump(ctx, ErrorType_SEMANTIC, "Break not inside a loop"); emitInstr_JUMP(ctx, label_break, node->offset, node->length); return; @@ -770,7 +770,7 @@ Executable *codegen(AST *ast, BPAlloc *alloc, Error *error) CodegenContext *ctx = CodegenContext_New(error, alloc); if(ctx == NULL) { - Error_Report(error, 1, "No memory"); + Error_Report(error, ErrorType_INTERNAL, "No memory"); return NULL; } diff --git a/src/lib/compiler/codegenctx.c b/src/lib/compiler/codegenctx.c index 7be4527..409768a 100644 --- a/src/lib/compiler/codegenctx.c +++ b/src/lib/compiler/codegenctx.c @@ -17,7 +17,7 @@ Label *Label_New(CodegenContext *ctx) if(promise != NULL) return (Label*) promise; - CodegenContext_ReportErrorAndJump(ctx, 1, "No memory"); + CodegenContext_ReportErrorAndJump(ctx, ErrorType_INTERNAL, "No memory"); UNREACHABLE; return NULL; // For the compiler warning. } @@ -54,12 +54,12 @@ static void okNowJump(CodegenContext *ctx) } void CodegenContext_ReportErrorAndJump_(CodegenContext *ctx, const char *file, - const char *func, int line, bool internal, + const char *func, int line, ErrorType type, const char *format, ...) { va_list args; va_start(args, format); - _Error_Report2(ctx->error, internal, file, func, line, format, args); + _Error_Report2(ctx->error, type, file, func, line, format, args); va_end(args); okNowJump(ctx); @@ -74,12 +74,12 @@ void CodegenContext_SetJumpDest(CodegenContext *ctx, jmp_buf *env) } CodegenContext *CodegenContext_New(Error *error, BPAlloc *alloc) -{ +{ bool own_alloc; if(alloc == NULL) { alloc = BPAlloc_Init(-1); if(alloc == NULL) { - Error_Report(error, 1, "No memory"); + Error_Report(error, ErrorType_INTERNAL, "No memory"); return false; } own_alloc = true; @@ -91,7 +91,7 @@ CodegenContext *CodegenContext_New(Error *error, BPAlloc *alloc) if(ctx == NULL) { if(own_alloc) BPAlloc_Free(alloc); - Error_Report(error, 1, "No memory"); + Error_Report(error, ErrorType_INTERNAL, "No memory"); return NULL; } diff --git a/src/lib/compiler/codegenctx.h b/src/lib/compiler/codegenctx.h index d12b1d4..3656de7 100644 --- a/src/lib/compiler/codegenctx.h +++ b/src/lib/compiler/codegenctx.h @@ -9,7 +9,7 @@ void CodegenContext_EmitInstr(CodegenContext *ctx, Opcode opcode, Ope void CodegenContext_SetJumpDest(CodegenContext *ctx, jmp_buf *env); void CodegenContext_Free(CodegenContext *ctx); Executable *CodegenContext_MakeExecutableAndFree(CodegenContext *ctx, Source *src); -void CodegenContext_ReportErrorAndJump_(CodegenContext *ctx, const char *file, const char *func, int line, bool internal, const char *format, ...); +void CodegenContext_ReportErrorAndJump_(CodegenContext *ctx, const char *file, const char *func, int line, ErrorType type, const char *format, ...); #define CodegenContext_ReportErrorAndJump(ctx, int, fmt, ...) CodegenContext_ReportErrorAndJump_(ctx, __FILE__, __func__, __LINE__, int, fmt, ## __VA_ARGS__) int CodegenContext_InstrCount(CodegenContext *ctx); diff --git a/src/lib/compiler/compile.c b/src/lib/compiler/compile.c index ec8d316..c30913f 100644 --- a/src/lib/compiler/compile.c +++ b/src/lib/compiler/compile.c @@ -5,15 +5,14 @@ #include "codegen.h" #include "compile.h" -Executable *compile(Source *src, Error *error, CompilationErrorType *errtyp) +Executable *compile(Source *src, Error *error) { // Create a bump-pointer allocator to hold the AST. BPAlloc *alloc = BPAlloc_Init(-1); if(alloc == NULL) { - *errtyp = CompilationErrorType_INTERNAL; - Error_Report(error, 1, "No memory"); + Error_Report(error, ErrorType_INTERNAL, "No memory"); return NULL; } @@ -24,10 +23,6 @@ Executable *compile(Source *src, Error *error, CompilationErrorType *errtyp) if(ast == NULL) { assert(error->occurred); - if(error->internal) - *errtyp = CompilationErrorType_INTERNAL; - else - *errtyp = CompilationErrorType_SYNTAX; BPAlloc_Free(alloc); return NULL; } @@ -41,10 +36,6 @@ Executable *compile(Source *src, Error *error, CompilationErrorType *errtyp) if(exe == NULL) { assert(error->occurred); - if(error->internal) - *errtyp = CompilationErrorType_INTERNAL; - else - *errtyp = CompilationErrorType_SEMANTIC; return NULL; } diff --git a/src/lib/compiler/compile.h b/src/lib/compiler/compile.h index 3855023..d62fef9 100644 --- a/src/lib/compiler/compile.h +++ b/src/lib/compiler/compile.h @@ -3,10 +3,5 @@ #include "../utils/error.h" #include "../utils/source.h" #include "../common/executable.h" -typedef enum { - CompilationErrorType_SYNTAX, - CompilationErrorType_SEMANTIC, - CompilationErrorType_INTERNAL, -} CompilationErrorType; -Executable *compile(Source *src, Error *error, CompilationErrorType *errtyp); +Executable *compile(Source *src, Error *error); #endif /* COMPILE_H */ \ No newline at end of file diff --git a/src/lib/compiler/parse.c b/src/lib/compiler/parse.c index cd24a75..dbb33ee 100644 --- a/src/lib/compiler/parse.c +++ b/src/lib/compiler/parse.c @@ -209,7 +209,7 @@ static Token *tokenize(Source *src, BPAlloc *alloc, Error *error) if(tok == NULL) { // Error: No memory. - Error_Report(error, 1, "No memory"); + Error_Report(error, ErrorType_INTERNAL, "No memory"); return NULL; } @@ -377,7 +377,7 @@ static Token *tokenize(Source *src, BPAlloc *alloc, Error *error) if(tok == NULL) { // Error: No memory. - Error_Report(error, 1, "No memory"); + Error_Report(error, ErrorType_INTERNAL, "No memory"); return NULL; } @@ -599,7 +599,7 @@ static Node *parse_statement(Context *ctx) if(current(ctx) != ';') { - Error_Report(ctx->error, 0, "Got token \"%.*s\" where \";\" was expected", ctx->token->length, ctx->src + ctx->token->offset); + Error_Report(ctx->error, ErrorType_SYNTAX, "Got token \"%.*s\" where \";\" was expected", ctx->token->length, ctx->src + ctx->token->offset); return NULL; } @@ -609,7 +609,7 @@ static Node *parse_statement(Context *ctx) if(node == NULL) { - Error_Report(ctx->error, 1, "No memory"); + Error_Report(ctx->error, ErrorType_INTERNAL, "No memory"); return NULL; } @@ -633,7 +633,9 @@ static Node *parse_statement(Context *ctx) if(current(ctx) != ';') { - Error_Report(ctx->error, 0, "Got token \"%.*s\" where \";\" was expected", ctx->token->length, ctx->src + ctx->token->offset); + Error_Report(ctx->error, ErrorType_SYNTAX, + "Got token \"%.*s\" where \";\" was expected", + ctx->token->length, ctx->src + ctx->token->offset); return NULL; } @@ -643,7 +645,7 @@ static Node *parse_statement(Context *ctx) if(node == NULL) { - Error_Report(ctx->error, 1, "No memory"); + Error_Report(ctx->error, ErrorType_INTERNAL, "No memory"); return NULL; } @@ -665,7 +667,7 @@ static Node *parse_statement(Context *ctx) return parse_dowhile_statement(ctx); } - Error_Report(ctx->error, 0, "Got token \"%.*s\" where the start of a statement was expected", + Error_Report(ctx->error, ErrorType_SYNTAX, "Got token \"%.*s\" where the start of a statement was expected", ctx->token->length, ctx->src + ctx->token->offset); return NULL; } @@ -681,7 +683,7 @@ static Node *parse_expression_statement(Context *ctx) if(done(ctx)) { - Error_Report(ctx->error, 0, "Source ended right after an expression, where a ';' was expected"); + Error_Report(ctx->error, ErrorType_SYNTAX, "Source ended right after an expression, where a ';' was expected"); return NULL; } @@ -690,7 +692,7 @@ static Node *parse_expression_statement(Context *ctx) // ERROR: Got something other than a semicolon at the end // of statement. - Error_Report(ctx->error, 0, "Got token \"%.*s\" where \";\" was expected", ctx->token->length, ctx->src + ctx->token->offset); + Error_Report(ctx->error, ErrorType_SYNTAX, "Got token \"%.*s\" where \";\" was expected", ctx->token->length, ctx->src + ctx->token->offset); return NULL; } @@ -713,7 +715,7 @@ static Node *makeStringExprNode(Context *ctx, const char *str, int len) if(copy == NULL) { - Error_Report(ctx->error, 1, "No memory"); + Error_Report(ctx->error, ErrorType_INTERNAL, "No memory"); return NULL; } @@ -728,7 +730,7 @@ static Node *makeStringExprNode(Context *ctx, const char *str, int len) if(node == NULL) { - Error_Report(ctx->error, 1, "No memory"); + Error_Report(ctx->error, ErrorType_INTERNAL, "No memory"); return NULL; } @@ -750,13 +752,13 @@ static Node *parse_string_primary_expression(Context *ctx) if(done(ctx)) { - Error_Report(ctx->error, 0, "Source ended where a string literal was expected"); + Error_Report(ctx->error, ErrorType_SYNTAX, "Source ended where a string literal was expected"); return NULL; } if(current(ctx) != TSTRING) { - Error_Report(ctx->error, 0, "Got token \"%.*s\" where a string literal was expected", ctx->token->length, ctx->src + ctx->token->offset); + Error_Report(ctx->error, ErrorType_SYNTAX, "Got token \"%.*s\" where a string literal was expected", ctx->token->length, ctx->src + ctx->token->offset); return NULL; } @@ -782,7 +784,7 @@ static Node *parse_string_primary_expression(Context *ctx) if(temp_used + segm_len >= (int) sizeof(temp)) { - Error_Report(ctx->error, 1, "String is too big to be rendered inside the fixed size buffer"); + Error_Report(ctx->error, ErrorType_INTERNAL, "String is too big to be rendered inside the fixed size buffer"); return NULL; } @@ -795,7 +797,7 @@ static Node *parse_string_primary_expression(Context *ctx) if(temp_used + 1 >= (int) sizeof(temp)) { - Error_Report(ctx->error, 1, "String is too big to be rendered inside the fixed size buffer"); + Error_Report(ctx->error, ErrorType_INTERNAL, "String is too big to be rendered inside the fixed size buffer"); return NULL; } @@ -816,7 +818,7 @@ static Node *parse_string_primary_expression(Context *ctx) case '\'': temp[temp_used++] = '\''; break; default: - Error_Report(ctx->error, 0, "Invalid escape sequence \\%c", src[i]); + Error_Report(ctx->error, ErrorType_SYNTAX, "Invalid escape sequence \\%c", src[i]); return NULL; } @@ -841,13 +843,13 @@ static Node *parse_list_primary_expression(Context *ctx) if(done(ctx)) { - Error_Report(ctx->error, 0, "Source ended where a list literal was expected"); + Error_Report(ctx->error, ErrorType_SYNTAX, "Source ended where a list literal was expected"); return NULL; } if(current(ctx) != '[') { - Error_Report(ctx->error, 0, "Got token \"%.*s\" where a list literal was expected", ctx->token->length, ctx->src + ctx->token->offset); + Error_Report(ctx->error, ErrorType_SYNTAX, "Got token \"%.*s\" where a list literal was expected", ctx->token->length, ctx->src + ctx->token->offset); return NULL; } @@ -886,9 +888,9 @@ static Node *parse_list_primary_expression(Context *ctx) if(current(ctx) != ',') { if(current(ctx) == TDONE) - Error_Report(ctx->error, 0, "Source ended inside a list literal"); + Error_Report(ctx->error, ErrorType_SYNTAX, "Source ended inside a list literal"); else - Error_Report(ctx->error, 0, "Got unexpected token \"%.*s\" inside list literal, where ',' or ']' were expected", ctx->token->length, ctx->src + ctx->token->offset); + Error_Report(ctx->error, ErrorType_SYNTAX, "Got unexpected token \"%.*s\" inside list literal, where ',' or ']' were expected", ctx->token->length, ctx->src + ctx->token->offset); return NULL; } @@ -908,7 +910,7 @@ static Node *parse_list_primary_expression(Context *ctx) if(list == NULL) { - Error_Report(ctx->error, 1, "No memory"); + Error_Report(ctx->error, ErrorType_INTERNAL, "No memory"); return NULL; } @@ -931,14 +933,14 @@ static Node *parse_map_primary_expression(Context *ctx) if(done(ctx)) { - Error_Report(ctx->error, 0, + Error_Report(ctx->error, ErrorType_SYNTAX, "Source ended where a map literal was expected"); return NULL; } if(current(ctx) != '{') { - Error_Report(ctx->error, 0, + Error_Report(ctx->error, ErrorType_SYNTAX, "Got token \"%.*s\" where a map literal was expected", ctx->token->length, ctx->src + ctx->token->offset); return NULL; @@ -954,7 +956,7 @@ static Node *parse_map_primary_expression(Context *ctx) if(done(ctx)) { - Error_Report(ctx->error, 0, "Source ended where a map child item's key was expected"); + Error_Report(ctx->error, ErrorType_SYNTAX, "Source ended where a map child item's key was expected"); return NULL; } @@ -1005,7 +1007,7 @@ static Node *parse_map_primary_expression(Context *ctx) if(done(ctx)) { - Error_Report(ctx->error, 0, + Error_Report(ctx->error, ErrorType_SYNTAX, "Source ended where a map key-value " "separator ':' was expected"); return NULL; @@ -1013,7 +1015,7 @@ static Node *parse_map_primary_expression(Context *ctx) if(current(ctx) != ':') { - Error_Report(ctx->error, 0, + Error_Report(ctx->error, ErrorType_SYNTAX, "Got token \"%.*s\" where a map key-value " "separator ':' was expected", ctx->token->length, @@ -1053,9 +1055,9 @@ static Node *parse_map_primary_expression(Context *ctx) if(current(ctx) != ',') { if(current(ctx) == TDONE) - Error_Report(ctx->error, 0, "Source ended inside a map literal"); + Error_Report(ctx->error, ErrorType_SYNTAX, "Source ended inside a map literal"); else - Error_Report(ctx->error, 0, + Error_Report(ctx->error, ErrorType_SYNTAX, "Got unexpected token \"%.*s\" inside " "map literal, where ',' or '}' were expected", ctx->token->length, ctx->src + ctx->token->offset); @@ -1078,7 +1080,7 @@ static Node *parse_map_primary_expression(Context *ctx) if(map == NULL) { - Error_Report(ctx->error, 1, "No memory"); + Error_Report(ctx->error, ErrorType_INTERNAL, "No memory"); return NULL; } @@ -1117,7 +1119,7 @@ static Node *makeIdentExprNode(Context *ctx) if(copy == NULL) { - Error_Report(ctx->error, 1, "No memory"); + Error_Report(ctx->error, ErrorType_INTERNAL, "No memory"); return NULL; } @@ -1127,7 +1129,7 @@ static Node *makeIdentExprNode(Context *ctx) if(node == NULL) { - Error_Report(ctx->error, 1, "No memory"); + Error_Report(ctx->error, ErrorType_INTERNAL, "No memory"); return NULL; } @@ -1149,7 +1151,7 @@ static Node *parse_primary_expresion(Context *ctx) if(done(ctx)) { - Error_Report(ctx->error, 0, "Source ended where a primary expression was expected"); + Error_Report(ctx->error, ErrorType_SYNTAX, "Source ended where a primary expression was expected"); return NULL; } @@ -1173,13 +1175,13 @@ static Node *parse_primary_expresion(Context *ctx) if(done(ctx)) { - Error_Report(ctx->error, 0, "Source ended before \")\", after sub-expression"); + Error_Report(ctx->error, ErrorType_SYNTAX, "Source ended before \")\", after sub-expression"); return NULL; } if(current(ctx) != ')') { - Error_Report(ctx->error, 0, "Missing \")\", after sub-expression"); + Error_Report(ctx->error, ErrorType_SYNTAX, "Missing \")\", after sub-expression"); return NULL; } next(ctx); // Consume the ')'. @@ -1192,7 +1194,7 @@ static Node *parse_primary_expresion(Context *ctx) if(ctx->token->length >= (int) sizeof(buffer)) { - Error_Report(ctx->error, 1, "Integer is too big"); + Error_Report(ctx->error, ErrorType_INTERNAL, "Integer is too big"); return NULL; } @@ -1205,7 +1207,7 @@ static Node *parse_primary_expresion(Context *ctx) if(errno == ERANGE) { - Error_Report(ctx->error, 1, "Integer is too big"); + Error_Report(ctx->error, ErrorType_INTERNAL, "Integer is too big"); return NULL; } else assert(errno == 0); @@ -1216,7 +1218,7 @@ static Node *parse_primary_expresion(Context *ctx) if(node == NULL) { - Error_Report(ctx->error, 1, "No memory"); + Error_Report(ctx->error, ErrorType_INTERNAL, "No memory"); return NULL; } @@ -1239,7 +1241,7 @@ static Node *parse_primary_expresion(Context *ctx) if(ctx->token->length >= (int) sizeof(buffer)) { - Error_Report(ctx->error, 1, "Floating is too big"); + Error_Report(ctx->error, ErrorType_INTERNAL, "Floating is too big"); return NULL; } @@ -1252,7 +1254,7 @@ static Node *parse_primary_expresion(Context *ctx) if(errno == ERANGE) { - Error_Report(ctx->error, 1, "Floating is too big"); + Error_Report(ctx->error, ErrorType_INTERNAL, "Floating is too big"); return NULL; } else assert(errno == 0); @@ -1263,7 +1265,7 @@ static Node *parse_primary_expresion(Context *ctx) if(node == NULL) { - Error_Report(ctx->error, 1, "No memory"); + Error_Report(ctx->error, ErrorType_INTERNAL, "No memory"); return NULL; } @@ -1293,7 +1295,7 @@ static Node *parse_primary_expresion(Context *ctx) if(node == NULL) { - Error_Report(ctx->error, 1, "No memory"); + Error_Report(ctx->error, ErrorType_INTERNAL, "No memory"); return NULL; } @@ -1317,7 +1319,7 @@ static Node *parse_primary_expresion(Context *ctx) if(node == NULL) { - Error_Report(ctx->error, 1, "No memory"); + Error_Report(ctx->error, ErrorType_INTERNAL, "No memory"); return NULL; } @@ -1341,7 +1343,7 @@ static Node *parse_primary_expresion(Context *ctx) if(node == NULL) { - Error_Report(ctx->error, 1, "No memory"); + Error_Report(ctx->error, ErrorType_INTERNAL, "No memory"); return NULL; } @@ -1367,11 +1369,11 @@ static Node *parse_primary_expresion(Context *ctx) } case TDONE: - Error_Report(ctx->error, 1, "Unexpected end of source where a primary expression was expected"); + Error_Report(ctx->error, ErrorType_INTERNAL, "Unexpected end of source where a primary expression was expected"); return NULL; default: - Error_Report(ctx->error, 1, "Unexpected token \"%.*s\" where a primary expression was expected", ctx->token->length, ctx->src + ctx->token->offset); + Error_Report(ctx->error, ErrorType_INTERNAL, "Unexpected token \"%.*s\" where a primary expression was expected", ctx->token->length, ctx->src + ctx->token->offset); return NULL; } @@ -1385,7 +1387,7 @@ static Node *makeIndexOrArrowSelectionExprNode(Context *ctx, bool arrow, Node *s if(sel == NULL) { - Error_Report(ctx->error, 1, "No memory"); + Error_Report(ctx->error, ErrorType_INTERNAL, "No memory"); return NULL; } @@ -1423,13 +1425,13 @@ static Node *parse_postfix_expression(Context *ctx) if(done(ctx)) { - Error_Report(ctx->error, 0, "Source ended after dot or arrow"); + Error_Report(ctx->error, ErrorType_SYNTAX, "Source ended after dot or arrow"); return NULL; } if(current(ctx) != TIDENT) { - Error_Report(ctx->error, 0, "Got unexpected token \"%.*s\" after dot or arrow, where an identifier was expected", ctx->token->length, ctx->src + ctx->token->offset); + Error_Report(ctx->error, ErrorType_SYNTAX, "Got unexpected token \"%.*s\" after dot or arrow, where an identifier was expected", ctx->token->length, ctx->src + ctx->token->offset); return NULL; } @@ -1460,7 +1462,7 @@ static Node *parse_postfix_expression(Context *ctx) if(ls->itemc == 0) { - Error_Report(ctx->error, 0, "Missing index in index selection expression"); + Error_Report(ctx->error, ErrorType_SYNTAX, "Missing index in index selection expression"); return NULL; } @@ -1506,9 +1508,9 @@ static Node *parse_postfix_expression(Context *ctx) if(current(ctx) != ',') { if(current(ctx) == TDONE) - Error_Report(ctx->error, 0, "Source ended inside a function argument list"); + Error_Report(ctx->error, ErrorType_SYNTAX, "Source ended inside a function argument list"); else - Error_Report(ctx->error, 0, "Got unexpected token \"%.*s\" where ',' or ')' were expected", ctx->token->length, ctx->src + ctx->token->offset); + Error_Report(ctx->error, ErrorType_SYNTAX, "Got unexpected token \"%.*s\" where ',' or ')' were expected", ctx->token->length, ctx->src + ctx->token->offset); return NULL; } @@ -1527,7 +1529,7 @@ static Node *parse_postfix_expression(Context *ctx) if(call == NULL) { - Error_Report(ctx->error, 1, "No memory"); + Error_Report(ctx->error, ErrorType_INTERNAL, "No memory"); return NULL; } @@ -1557,14 +1559,14 @@ static Node *parse_prefix_expression(Context *ctx) { if(done(ctx)) { - Error_Report(ctx->error, 0, "Source ended where a prefix expression was expected"); + Error_Report(ctx->error, ErrorType_SYNTAX, "Source ended where a prefix expression was expected"); return NULL; } switch(current(ctx)) { case TDONE: - Error_Report(ctx->error, 1, "Unexpected end of source where a prefix expression was expected"); + Error_Report(ctx->error, ErrorType_INTERNAL, "Unexpected end of source where a prefix expression was expected"); return NULL; case '+': @@ -1714,7 +1716,7 @@ static Node *parse_expression_2(Context *ctx, Node *left_expr, int min_prec, _Bo if(temp == NULL) { - Error_Report(ctx->error, 1, "No memory"); + Error_Report(ctx->error, ErrorType_INTERNAL, "No memory"); return NULL; } @@ -1777,13 +1779,13 @@ static Node *parse_ifelse_statement(Context *ctx) if(done(ctx)) { - Error_Report(ctx->error, 0, "Source ended where an if-else statement was expected"); + Error_Report(ctx->error, ErrorType_SYNTAX, "Source ended where an if-else statement was expected"); return NULL; } if(current(ctx) != TKWIF) { - Error_Report(ctx->error, 0, "Got unexpected token \"%.*s\" where an if-else statement was expected", ctx->token->length, ctx->src + ctx->token->offset); + Error_Report(ctx->error, ErrorType_SYNTAX, "Got unexpected token \"%.*s\" where an if-else statement was expected", ctx->token->length, ctx->src + ctx->token->offset); return NULL; } @@ -1799,13 +1801,13 @@ static Node *parse_ifelse_statement(Context *ctx) if(done(ctx)) { - Error_Report(ctx->error, 0, "Source ended right after an if-else condition, where a ':' was expected"); + Error_Report(ctx->error, ErrorType_SYNTAX, "Source ended right after an if-else condition, where a ':' was expected"); return NULL; } if(current(ctx) != ':') { - Error_Report(ctx->error, 0, "Got unexpected token \"%.*s\" after an if-else condition, where a ':' was expected", ctx->token->length, ctx->src + ctx->token->offset); + Error_Report(ctx->error, ErrorType_SYNTAX, "Got unexpected token \"%.*s\" after an if-else condition, where a ':' was expected", ctx->token->length, ctx->src + ctx->token->offset); return NULL; } @@ -1835,7 +1837,7 @@ static Node *parse_ifelse_statement(Context *ctx) if(ifelse == NULL) { // ERROR: No memory. - Error_Report(ctx->error, 1, "No memory"); + Error_Report(ctx->error, ErrorType_INTERNAL, "No memory"); return NULL; } @@ -1874,7 +1876,7 @@ static Node *parse_compound_statement(Context *ctx, TokenKind end) if(current(ctx) != end) { - Error_Report(ctx->error, 0, "Source ended inside compound statement"); + Error_Report(ctx->error, ErrorType_SYNTAX, "Source ended inside compound statement"); return NULL; } @@ -1885,7 +1887,7 @@ static Node *parse_compound_statement(Context *ctx, TokenKind end) if(node == NULL) { // ERROR: No memory. - Error_Report(ctx->error, 1, "No memory"); + Error_Report(ctx->error, ErrorType_INTERNAL, "No memory"); return NULL; } @@ -1906,9 +1908,9 @@ static _Bool parse_function_arguments(Context *ctx, int *argc_, Node **argv_) if(next(ctx) != '(') { if(done(ctx)) - Error_Report(ctx->error, 0, "Source ended where a function argument list was expected"); + Error_Report(ctx->error, ErrorType_SYNTAX, "Source ended where a function argument list was expected"); else - Error_Report(ctx->error, 0, "Got unexpected token \"%.*s\" where a function argument list was expected", ctx->token->length, ctx->src + ctx->token->offset); + Error_Report(ctx->error, ErrorType_SYNTAX, "Got unexpected token \"%.*s\" where a function argument list was expected", ctx->token->length, ctx->src + ctx->token->offset); return 0; } @@ -1923,13 +1925,13 @@ static _Bool parse_function_arguments(Context *ctx, int *argc_, Node **argv_) { if(done(ctx)) { - Error_Report(ctx->error, 0, "Source ended inside a function argument list"); + Error_Report(ctx->error, ErrorType_SYNTAX, "Source ended inside a function argument list"); return 0; } if(current(ctx) != TIDENT) { - Error_Report(ctx->error, 0, "Got unexpected token \"%.*s\" where a function argument name was expected", ctx->token->length, ctx->src + ctx->token->offset); + Error_Report(ctx->error, ErrorType_SYNTAX, "Got unexpected token \"%.*s\" where a function argument name was expected", ctx->token->length, ctx->src + ctx->token->offset); return 0; } @@ -1937,7 +1939,7 @@ static _Bool parse_function_arguments(Context *ctx, int *argc_, Node **argv_) if(arg_name == NULL) { - Error_Report(ctx->error, 1, "No memory"); + Error_Report(ctx->error, ErrorType_INTERNAL, "No memory"); return 0; } @@ -1966,7 +1968,7 @@ static _Bool parse_function_arguments(Context *ctx, int *argc_, Node **argv_) if(arg == NULL) { - Error_Report(ctx->error, 1, "No memory"); + Error_Report(ctx->error, ErrorType_INTERNAL, "No memory"); return 0; } @@ -1988,7 +1990,7 @@ static _Bool parse_function_arguments(Context *ctx, int *argc_, Node **argv_) if(done(ctx)) { - Error_Report(ctx->error, 0, "Source ended inside a function argument list"); + Error_Report(ctx->error, ErrorType_SYNTAX, "Source ended inside a function argument list"); return 0; } @@ -1997,7 +1999,7 @@ static _Bool parse_function_arguments(Context *ctx, int *argc_, Node **argv_) if(current(ctx) != ',') { - Error_Report(ctx->error, 0, "Got unexpected token \"%.*s\" inside function argument list, where either ',' or ')' were expected", ctx->token->length, ctx->src + ctx->token->offset); + Error_Report(ctx->error, ErrorType_SYNTAX, "Got unexpected token \"%.*s\" inside function argument list, where either ',' or ')' were expected", ctx->token->length, ctx->src + ctx->token->offset); return 0; } @@ -2019,13 +2021,13 @@ static FuncDeclNode *parse_function_definition(Context *ctx) if(done(ctx)) { - Error_Report(ctx->error, 0, "Source ended where a function definition was expected"); + Error_Report(ctx->error, ErrorType_SYNTAX, "Source ended where a function definition was expected"); return NULL; } if(current(ctx) != TKWFUN) { - Error_Report(ctx->error, 0, "Got unexpected token \"%.*s\" where a function definition was expected", ctx->token->length, ctx->src + ctx->token->offset); + Error_Report(ctx->error, ErrorType_SYNTAX, "Got unexpected token \"%.*s\" where a function definition was expected", ctx->token->length, ctx->src + ctx->token->offset); return NULL; } @@ -2034,16 +2036,16 @@ static FuncDeclNode *parse_function_definition(Context *ctx) if(next(ctx) != TIDENT) { if(done(ctx)) - Error_Report(ctx->error, 0, "Source ended where an identifier was expected as function name"); + Error_Report(ctx->error, ErrorType_SYNTAX, "Source ended where an identifier was expected as function name"); else - Error_Report(ctx->error, 0, "Got unexpected token \"%.*s\" where an identifier was expected as function name", ctx->token->length, ctx->src + ctx->token->offset); + Error_Report(ctx->error, ErrorType_SYNTAX, "Got unexpected token \"%.*s\" where an identifier was expected as function name", ctx->token->length, ctx->src + ctx->token->offset); return NULL; } char *name_val = copy_token_text(ctx); if(name_val == NULL) { - Error_Report(ctx->error, 1, "No memory"); + Error_Report(ctx->error, ErrorType_INTERNAL, "No memory"); return NULL; } int name_len = strlen(name_val); @@ -2057,7 +2059,7 @@ static FuncDeclNode *parse_function_definition(Context *ctx) if(done(ctx)) { - Error_Report(ctx->error, 0, "Source ended before function body"); + Error_Report(ctx->error, ErrorType_SYNTAX, "Source ended before function body"); return NULL; } @@ -2075,7 +2077,7 @@ static FuncDeclNode *parse_function_definition(Context *ctx) FuncExprNode *expr = BPAlloc_Malloc(ctx->alloc, sizeof(FuncExprNode)); if (expr == NULL) { - Error_Report(ctx->error, 1, "No memory"); + Error_Report(ctx->error, ErrorType_INTERNAL, "No memory"); return NULL; } expr->base.base.kind = NODE_EXPR; @@ -2090,7 +2092,7 @@ static FuncDeclNode *parse_function_definition(Context *ctx) StringExprNode *name = BPAlloc_Malloc(ctx->alloc, sizeof(StringExprNode)); if (name == NULL) { - Error_Report(ctx->error, 1, "No memory"); + Error_Report(ctx->error, ErrorType_INTERNAL, "No memory"); return NULL; } name->base.base.kind = NODE_EXPR; @@ -2104,7 +2106,7 @@ static FuncDeclNode *parse_function_definition(Context *ctx) func = BPAlloc_Malloc(ctx->alloc, sizeof(FuncDeclNode)); if(func == NULL) { - Error_Report(ctx->error, 1, "No memory"); + Error_Report(ctx->error, ErrorType_INTERNAL, "No memory"); return NULL; } func->base.kind = NODE_FUNC; @@ -2124,13 +2126,13 @@ static Node *parse_while_statement(Context *ctx) if(done(ctx)) { - Error_Report(ctx->error, 0, "Source ended where a while statement was expected"); + Error_Report(ctx->error, ErrorType_SYNTAX, "Source ended where a while statement was expected"); return NULL; } if(current(ctx) != TKWWHILE) { - Error_Report(ctx->error, 0, "Got unexpected token \"%.*s\" where a while statement was expected", ctx->token->length, ctx->src + ctx->token->offset); + Error_Report(ctx->error, ErrorType_SYNTAX, "Got unexpected token \"%.*s\" where a while statement was expected", ctx->token->length, ctx->src + ctx->token->offset); return NULL; } @@ -2146,13 +2148,13 @@ static Node *parse_while_statement(Context *ctx) if(done(ctx)) { - Error_Report(ctx->error, 0, "Source ended right after a while loop condition, where a ':' was expected"); + Error_Report(ctx->error, ErrorType_SYNTAX, "Source ended right after a while loop condition, where a ':' was expected"); return NULL; } if(current(ctx) != ':') { - Error_Report(ctx->error, 0, "Got unexpected token \"%.*s\" after a while loop condition, where a ':' was expected", ctx->token->length, ctx->src + ctx->token->offset); + Error_Report(ctx->error, ErrorType_SYNTAX, "Got unexpected token \"%.*s\" after a while loop condition, where a ':' was expected", ctx->token->length, ctx->src + ctx->token->offset); return NULL; } @@ -2170,7 +2172,7 @@ static Node *parse_while_statement(Context *ctx) if(whl == NULL) { // ERROR: No memory. - Error_Report(ctx->error, 1, "No memory"); + Error_Report(ctx->error, ErrorType_INTERNAL, "No memory"); return NULL; } @@ -2191,13 +2193,13 @@ static Node *parse_dowhile_statement(Context *ctx) if(done(ctx)) { - Error_Report(ctx->error, 0, "Source ended where a do-while statement was expected"); + Error_Report(ctx->error, ErrorType_SYNTAX, "Source ended where a do-while statement was expected"); return NULL; } if(current(ctx) != TKWDO) { - Error_Report(ctx->error, 0, "Got unexpected token \"%.*s\" where a do-while statement was expected", ctx->token->length, ctx->src + ctx->token->offset); + Error_Report(ctx->error, ErrorType_SYNTAX, "Got unexpected token \"%.*s\" where a do-while statement was expected", ctx->token->length, ctx->src + ctx->token->offset); return NULL; } @@ -2213,13 +2215,13 @@ static Node *parse_dowhile_statement(Context *ctx) if(done(ctx)) { - Error_Report(ctx->error, 0, "Source ended right after a do-while body, where the \"while\" keyword was expected"); + Error_Report(ctx->error, ErrorType_SYNTAX, "Source ended right after a do-while body, where the \"while\" keyword was expected"); return NULL; } if(current(ctx) != TKWWHILE) { - Error_Report(ctx->error, 0, "Got unexpected token \"%.*s\" after a do-while body, where the \"while\" keyword was expected", ctx->token->length, ctx->src + ctx->token->offset); + Error_Report(ctx->error, ErrorType_SYNTAX, "Got unexpected token \"%.*s\" after a do-while body, where the \"while\" keyword was expected", ctx->token->length, ctx->src + ctx->token->offset); return NULL; } @@ -2232,13 +2234,13 @@ static Node *parse_dowhile_statement(Context *ctx) if(done(ctx)) { - Error_Report(ctx->error, 0, "Source ended right after a do-while condition, where a ';' was expected"); + Error_Report(ctx->error, ErrorType_SYNTAX, "Source ended right after a do-while condition, where a ';' was expected"); return NULL; } if(current(ctx) != ';') { - Error_Report(ctx->error, 0, "Got unexpected token \"%.*s\" after a do-while conditnion, where a ';' was expected", ctx->token->length, ctx->src + ctx->token->offset); + Error_Report(ctx->error, ErrorType_SYNTAX, "Got unexpected token \"%.*s\" after a do-while conditnion, where a ';' was expected", ctx->token->length, ctx->src + ctx->token->offset); return NULL; } @@ -2251,7 +2253,7 @@ static Node *parse_dowhile_statement(Context *ctx) if(dowhl == NULL) { // ERROR: No memory. - Error_Report(ctx->error, 1, "No memory"); + Error_Report(ctx->error, ErrorType_INTERNAL, "No memory"); return NULL; } diff --git a/src/lib/noja.c b/src/lib/noja.c index 489ee0b..f598b14 100644 --- a/src/lib/noja.c +++ b/src/lib/noja.c @@ -8,41 +8,48 @@ #include "runtime/timing.h" #include "noja.h" -static void print_error(const char *type, Error *error) +static void serializeProfilingResults(Runtime *runtime, const char *file) { - if(type == NULL) - fprintf(stderr, "Error"); - else if(error->internal) - fprintf(stderr, "Internal Error"); - else - fprintf(stderr, "%s Error", type); + TimingTable *table = Runtime_GetTimingTable(runtime); + if (table == NULL) + return; - fprintf(stderr, ": %s.", error->message); - -#ifdef DEBUG - if(error->file != NULL) - { - if(error->line > 0 && error->func != NULL) - fprintf(stderr, " (Reported in %s:%d in %s)", error->file, error->line, error->func); - else if(error->line > 0 && error->func == NULL) - fprintf(stderr, " (Reported in %s:%d)", error->file, error->line); - else if(error->line < 1 && error->func != NULL) - fprintf(stderr, " (Reported in %s in %s)", error->file, error->func); + FILE *stream = fopen(file, "wb"); + if (stream == NULL) { + fprintf(stderr, "Failed to serialize profiling results\n"); + return; } -#endif - - fprintf(stderr, "\n"); + + const FunctionExecutionSummary *summary; + size_t count; + + summary = TimingTable_getSummary(table, &count); + assert(summary != NULL); + + for (size_t i = 0; i < count; i++) { + if (summary[i].calls > 0) { + fprintf(stream, "%20s - %s - %ld calls - %.2lfus\n", + summary[i].name, + Source_GetName(summary[i].src), + summary[i].calls, + summary[i].time * 1000000); + } + } + + fclose(stream); + fprintf(stderr, "Wrote profiling result to %s\n", file); } + #include -Runtime *runt = NULL; +Runtime *runtime = NULL; static void signalHandler(int signo) { (void) signo; - if (runt != NULL) - Runtime_Interrupt(runt); + if (runtime != NULL) + Runtime_Interrupt(runtime); } static _Bool interpret(Executable *exe, bool time, size_t heap) @@ -50,13 +57,13 @@ static _Bool interpret(Executable *exe, bool time, size_t heap) RuntimeConfig config = Runtime_GetDefaultConfigs(); config.time = time; - runt = Runtime_New(heap, config); - if(runt == NULL) + runtime = Runtime_New(heap, config); + if(runtime == NULL) { Error error; Error_Init(&error); - Error_Report(&error, 1, "Couldn't initialize runtime"); - print_error(NULL, &error); + Error_Report(&error, ErrorType_INTERNAL, "Couldn't initialize runtime"); + Error_Print(&error, ErrorType_UNSPECIFIED); Error_Free(&error); return 0; } @@ -70,55 +77,47 @@ static _Bool interpret(Executable *exe, bool time, size_t heap) // expects a pointer to [Error] can receive a [RuntimeError] // upcasted to [Error]. RuntimeError error; - RuntimeError_Init(&error, runt); // Here we specify the runtime to snapshot in case of failure. + RuntimeError_Init(&error, runtime); // Here we specify the runtime to snapshot in case of failure. { - Object *native_bins = Object_NewStaticMap(bins_basic, bins_basic_init, runt, (Error*) &error); + Object *native_bins = Object_NewStaticMap(bins_basic, bins_basic_init, runtime, (Error*) &error); if(native_bins == NULL) { assert(error.base.occurred == 1); - print_error(NULL, (Error*) &error); + Error_Print((Error*) &error, ErrorType_RUNTIME); RuntimeError_Free(&error); - Runtime_Free(runt); + Runtime_Free(runtime); return 0; } // Just to execute the prelude - Runtime_SetBuiltins(runt, native_bins); + Runtime_SetBuiltins(runtime, native_bins); extern char start_noja[]; Source *prelude = Source_FromString("", start_noja, -1, (Error*) &error); if (prelude == NULL) { assert(error.base.occurred == 1); - print_error(NULL, (Error*) &error); + Error_Print((Error*) &error, ErrorType_RUNTIME); RuntimeError_Free(&error); - Runtime_Free(runt); + Runtime_Free(runtime); return 0; } - CompilationErrorType errtyp; - Executable *prelude_exe = compile(prelude, (Error*) &error, &errtyp); + Executable *prelude_exe = compile(prelude, (Error*) &error); if(prelude_exe == NULL) { - const char *errname; - switch(errtyp) { - default: - case CompilationErrorType_INTERNAL: errname = NULL; break; - case CompilationErrorType_SYNTAX: errname = "Syntax"; break; - case CompilationErrorType_SEMANTIC: errname = "Semantic"; break; - } - print_error(errname, (Error*) &error); + Error_Print((Error*) &error, ErrorType_RUNTIME); RuntimeError_Free(&error); - Runtime_Free(runt); + Runtime_Free(runtime); Source_Free(prelude); return 0; } Object *rets[8]; - int retc = run(runt, (Error*) &error, prelude_exe, 0, NULL, NULL, 0, rets); + int retc = run(runtime, (Error*) &error, prelude_exe, 0, NULL, NULL, 0, rets); if(retc < 0) { - print_error("Runtime", (Error*) &error); + Error_Print((Error*) &error, ErrorType_RUNTIME); RuntimeError_Free(&error); - Runtime_Free(runt); + Runtime_Free(runtime); Source_Free(prelude); Executable_Free(prelude_exe); return 0; @@ -128,43 +127,43 @@ static _Bool interpret(Executable *exe, bool time, size_t heap) // Need to remake the native built-ins because // running the script invalidated the previous // pointer. - native_bins = Object_NewStaticMap(bins_basic, bins_basic_init, runt, (Error*) &error); + native_bins = Object_NewStaticMap(bins_basic, bins_basic_init, runtime, (Error*) &error); if(native_bins == NULL) { assert(error.base.occurred == 1); - print_error(NULL, (Error*) &error); + Error_Print((Error*) &error, ErrorType_RUNTIME); RuntimeError_Free(&error); - Runtime_Free(runt); + Runtime_Free(runtime); Source_Free(prelude); Executable_Free(prelude_exe); return 0; } - Object *all_bins = Object_NewClosure(native_bins, noja_bins, Runtime_GetHeap(runt), (Error*) &error); + Object *all_bins = Object_NewClosure(native_bins, noja_bins, Runtime_GetHeap(runtime), (Error*) &error); if (all_bins == NULL) { - print_error(NULL, (Error*) &error); + Error_Print((Error*) &error, ErrorType_RUNTIME); RuntimeError_Free(&error); - Runtime_Free(runt); + Runtime_Free(runtime); Source_Free(prelude); Executable_Free(prelude_exe); return 0; } - Runtime_SetBuiltins(runt, all_bins); + Runtime_SetBuiltins(runtime, all_bins); Source_Free(prelude); Executable_Free(prelude_exe); } Object *rets[8]; - int retc = run(runt, (Error*) &error, exe, 0, NULL, NULL, 0, rets); + int retc = run(runtime, (Error*) &error, exe, 0, NULL, NULL, 0, rets); // NOTE: The pointer to the builtins object is invalidated // now because it may be moved by the garbage collector. if(retc < 0) { - print_error("Runtime", (Error*) &error); + Error_Print((Error*) &error, ErrorType_RUNTIME); if(error.snapshot == NULL) fprintf(stderr, "No snapshot available.\n"); @@ -174,38 +173,9 @@ static _Bool interpret(Executable *exe, bool time, size_t heap) RuntimeError_Free(&error); } - TimingTable *table = Runtime_GetTimingTable(runt); - if (table != NULL) { + serializeProfilingResults(runtime, "profiling-results.txt"); - const char *file = "profiling-results.txt"; - - FILE *stream = fopen(file, "wb"); - if (stream == NULL) { - fprintf(stderr, "Failed to serialize profiling results\n"); - } else { - - const FunctionExecutionSummary *summary; - size_t count; - - summary = TimingTable_getSummary(table, &count); - assert(summary != NULL); - - for (size_t i = 0; i < count; i++) { - if (summary[i].calls > 0) { - fprintf(stream, "%20s - %s - %ld calls - %.2lfus\n", - summary[i].name, - Source_GetName(summary[i].src), - summary[i].calls, - summary[i].time * 1000000); - } - } - - fclose(stream); - fprintf(stderr, "Wrote profiling result to %s\n", file); - } - } - - Runtime_Free(runt); + Runtime_Free(runtime); return retc > -1; } @@ -213,17 +183,9 @@ static Executable *compile_source_and_print_error_on_failure(Source *src) { Error error; Error_Init(&error); - CompilationErrorType errtyp; - Executable *exe = compile(src, &error, &errtyp); + Executable *exe = compile(src, &error); if(exe == NULL) { - const char *errname; - switch(errtyp) { - default: - case CompilationErrorType_INTERNAL: errname = NULL; break; - case CompilationErrorType_SYNTAX: errname = "Syntax"; break; - case CompilationErrorType_SEMANTIC: errname = "Semantic"; break; - } - print_error(errname, &error); + Error_Print(&error, ErrorType_UNSPECIFIED); Error_Free(&error); return NULL; } @@ -249,7 +211,7 @@ static _Bool interpret_file(const char *file, bool time, size_t heap) if(src == NULL) { assert(error.occurred == 1); - print_error(NULL, &error); + Error_Print(&error, ErrorType_UNSPECIFIED); Error_Free(&error); return 0; } @@ -277,7 +239,7 @@ static _Bool interpret_code(const char *code, bool time, size_t heap) if(src == NULL) { assert(error.occurred); - print_error(NULL, &error); + Error_Print(&error, ErrorType_UNSPECIFIED); Error_Free(&error); return 0; } @@ -305,14 +267,14 @@ static _Bool interpret_asm_file(const char *file, bool time, size_t heap) if(src == NULL) { assert(error.occurred == 1); - print_error(NULL, &error); + Error_Print(&error, ErrorType_UNSPECIFIED); Error_Free(&error); return 0; } Executable *exe = assemble(src, &error); if(exe == NULL) { - print_error("Assemblation", &error); + Error_Print(&error, ErrorType_UNSPECIFIED); Source_Free(src); Error_Free(&error); return 0; @@ -336,14 +298,14 @@ static _Bool interpret_asm_code(const char *code, bool time, size_t heap) if(src == NULL) { assert(error.occurred); - print_error(NULL, &error); + Error_Print(&error, ErrorType_UNSPECIFIED); Error_Free(&error); return 0; } Executable *exe = assemble(src, &error); if(exe == NULL) { - print_error("Assemblation", &error); + Error_Print(&error, ErrorType_UNSPECIFIED); Source_Free(src); Error_Free(&error); return 0; @@ -367,7 +329,7 @@ static _Bool disassemble_file(const char *file) if(src == NULL) { assert(error.occurred == 1); - print_error(NULL, &error); + Error_Print(&error, ErrorType_UNSPECIFIED); Error_Free(&error); return 0; } @@ -388,7 +350,7 @@ static _Bool disassemble_code(const char *code) if(src == NULL) { assert(error.occurred); - print_error(NULL, &error); + Error_Print(&error, ErrorType_UNSPECIFIED); Error_Free(&error); return 0; } diff --git a/src/lib/objects/heap.c b/src/lib/objects/heap.c index 4e68fc0..77c3659 100644 --- a/src/lib/objects/heap.c +++ b/src/lib/objects/heap.c @@ -222,7 +222,7 @@ void *Heap_Malloc(Heap *heap, TypeObject *type, Error *err) if(heap->pend == NULL) { - Error_Report(err, 1, "No memory"); + Error_Report(err, ErrorType_INTERNAL, "No memory"); return NULL; } @@ -237,7 +237,7 @@ void *Heap_Malloc(Heap *heap, TypeObject *type, Error *err) if(new_pend == NULL) { - Error_Report(err, 1, "No memory"); + Error_Report(err, ErrorType_INTERNAL, "No memory"); return NULL; } @@ -273,7 +273,7 @@ void *Heap_Malloc(Heap *heap, TypeObject *type, Error *err) heap->pend[heap->pend_used++] = (PendingDestruct) { .object = obj, .destructor = obj->type->free }; heap->objcount += 1; - + return (Object*) addr; } @@ -296,7 +296,7 @@ void *Heap_RawMalloc(Heap *heap, int size, Error *err) { if(heap->collecting) { - Error_Report(err, 1, "Out of heap"); + Error_Report(err, ErrorType_INTERNAL, "Out of heap"); return NULL; } @@ -336,7 +336,7 @@ _Bool Heap_StartCollection(Heap *heap, Error *error) if(new_body == NULL) { - Error_Report(error, 1, "No memory"); + Error_Report(error, ErrorType_INTERNAL, "No memory"); return 0; } diff --git a/src/lib/objects/o_buffer.c b/src/lib/objects/o_buffer.c index 3e35870..b4f450d 100644 --- a/src/lib/objects/o_buffer.c +++ b/src/lib/objects/o_buffer.c @@ -96,7 +96,7 @@ Object *Object_NewBuffer(size_t size, Heap *heap, Error *error) Payload *payload = malloc(sizeof(Payload) + size); if(payload == NULL) { - Error_Report(error, 1, "No memory"); + Error_Report(error, ErrorType_INTERNAL, "No memory"); return NULL; } payload->refs = 1; @@ -134,19 +134,19 @@ Object *Object_SliceBuffer(Object *obj, size_t offset, size_t length, Heap *heap { if(!Object_IsBuffer(obj)) { - Error_Report(error, 0, "Not a " TYPENAME_BUFFER); + Error_Report(error, ErrorType_RUNTIME, "Not a " TYPENAME_BUFFER); return NULL; } Payload *payload = ((BufferObject*) obj)->payload; if(offset >= payload->size) { - Error_Report(error, 0, "Offset out of range"); + Error_Report(error, ErrorType_RUNTIME, "Offset out of range"); return NULL; } if(offset + length > payload->size) { - Error_Report(error, 0, "Length out of range"); + Error_Report(error, ErrorType_RUNTIME, "Length out of range"); return NULL; } @@ -187,7 +187,7 @@ static Object *buffer_select(Object *self, Object *key, Heap *heap, Error *error if(!Object_IsInt(key)) { - Error_Report(error, 0, "Non integer key"); + Error_Report(error, ErrorType_RUNTIME, "Non integer key"); return NULL; } @@ -197,7 +197,7 @@ static Object *buffer_select(Object *self, Object *key, Heap *heap, Error *error if(idx < 0 || (size_t) idx >= buffer->length) { - Error_Report(error, 0, "Index out of range"); + Error_Report(error, ErrorType_RUNTIME, "Index out of range"); return NULL; } @@ -222,24 +222,24 @@ static _Bool buffer_insert(Object *self, Object *key, Object *val, Heap *heap, E if(!Object_IsInt(key)) { - Error_Report(error, 0, "Non integer key"); + Error_Report(error, ErrorType_RUNTIME, "Non integer key"); return NULL; } if(!Object_IsInt(val)) { - Error_Report(error, 0, "Non integer value"); + Error_Report(error, ErrorType_RUNTIME, "Non integer value"); return NULL; } int idx = Object_GetInt(key); long long int qword = Object_GetInt(val); if(idx < 0 || (size_t) idx >= buffer->length) { - Error_Report(error, 0, "Out of range index"); + Error_Report(error, ErrorType_RUNTIME, "Out of range index"); return NULL; } if(qword > 255 || qword < 0) { - Error_Report(error, 0, "Not in range [0, 255]"); + Error_Report(error, ErrorType_RUNTIME, "Not in range [0, 255]"); return NULL; } diff --git a/src/lib/objects/o_dir.c b/src/lib/objects/o_dir.c index 506e792..bb53547 100644 --- a/src/lib/objects/o_dir.c +++ b/src/lib/objects/o_dir.c @@ -86,6 +86,6 @@ static _Bool dir_free(Object *obj, Error *error) if(closedir(dob->dir) == 0) return 1; - Error_Report(error, 0, "Failed to close directory"); + Error_Report(error, ErrorType_RUNTIME, "Failed to close directory"); return 0; } \ No newline at end of file diff --git a/src/lib/objects/o_file.c b/src/lib/objects/o_file.c index c1b2ed6..7c62e98 100644 --- a/src/lib/objects/o_file.c +++ b/src/lib/objects/o_file.c @@ -85,6 +85,6 @@ static _Bool file_free(Object *self, Error *error) if(fclose(fob->fp) == 0) return 1; - Error_Report(error, 0, "Failed to close stream"); + Error_Report(error, ErrorType_RUNTIME, "Failed to close stream"); return 0; } \ No newline at end of file diff --git a/src/lib/objects/o_list.c b/src/lib/objects/o_list.c index 1ea3c32..e8f2a0a 100644 --- a/src/lib/objects/o_list.c +++ b/src/lib/objects/o_list.c @@ -212,7 +212,7 @@ static Object *select_(Object *self, Object *key, Heap *heap, Error *error) if(!Object_IsInt(key)) { - Error_Report(error, 0, "Non integer key"); + Error_Report(error, ErrorType_RUNTIME, "Non integer key"); return NULL; } @@ -222,7 +222,7 @@ static Object *select_(Object *self, Object *key, Heap *heap, Error *error) if(idx < 0 || idx >= list->count) { - Error_Report(error, 0, "Out of range index"); + Error_Report(error, ErrorType_RUNTIME, "Out of range index"); return NULL; } @@ -266,7 +266,7 @@ static _Bool insert(Object *self, Object *key, Object *val, Heap *heap, Error *e if(!Object_IsInt(key)) { - Error_Report(error, 0, "Non integer key"); + Error_Report(error, ErrorType_RUNTIME, "Non integer key"); return NULL; } @@ -274,7 +274,7 @@ static _Bool insert(Object *self, Object *key, Object *val, Heap *heap, Error *e if(idx < 0 || idx > list->count) { - Error_Report(error, 0, "Out of range index"); + Error_Report(error, ErrorType_RUNTIME, "Out of range index"); return NULL; } diff --git a/src/lib/objects/o_string.c b/src/lib/objects/o_string.c index d861a2d..d70cde8 100644 --- a/src/lib/objects/o_string.c +++ b/src/lib/objects/o_string.c @@ -96,7 +96,7 @@ static Object *select_(Object *self, Object *key, Heap *heap, Error *error) if(!Object_IsInt(key)) { - Error_Report(error, 0, "Non integer key"); + Error_Report(error, ErrorType_RUNTIME, "Non integer key"); return NULL; } int idx = Object_GetInt(key); @@ -105,7 +105,7 @@ static Object *select_(Object *self, Object *key, Heap *heap, Error *error) if(idx < 0 || idx >= str->count) { - Error_Report(error, 0, "Out of range index"); + Error_Report(error, ErrorType_RUNTIME, "Out of range index"); return NULL; } @@ -147,7 +147,7 @@ Object *Object_FromString(const char *str, int len, Heap *heap, Error *error) if(count < 0) { - Error_Report(error, 0, "Invalid UTF-8 sequence"); + Error_Report(error, ErrorType_RUNTIME, "Invalid UTF-8 sequence"); return NULL; } diff --git a/src/lib/objects/objects.c b/src/lib/objects/objects.c index 2eb49ef..0343e9e 100644 --- a/src/lib/objects/objects.c +++ b/src/lib/objects/objects.c @@ -123,7 +123,7 @@ Object *Object_Copy(Object *obj, Heap *heap, Error *err) if(type->copy == NULL) { - Error_Report(err, 0, "Object %s doesn't implement %s", Object_GetName(obj), __func__); + Error_Report(err, ErrorType_RUNTIME, "Object %s doesn't implement %s", Object_GetName(obj), __func__); return NULL; } @@ -139,7 +139,7 @@ int Object_Call(Object *obj, Object **argv, unsigned int argc, Object *rets[stat if(type->call == NULL) { - Error_Report(err, 0, "Object of type %s isn't callable", Object_GetName(obj), __func__); + Error_Report(err, ErrorType_RUNTIME, "Object of type %s isn't callable", Object_GetName(obj), __func__); return -1; } @@ -179,7 +179,7 @@ Object *Object_Select(Object *coll, Object *key, Heap *heap, Error *err) if(type->select == NULL) { - Error_Report(err, 0, "Object %s doesn't implement %s", Object_GetName(coll), __func__); + Error_Report(err, ErrorType_RUNTIME, "Object %s doesn't implement %s", Object_GetName(coll), __func__); return NULL; } @@ -197,7 +197,7 @@ Object *Object_Delete(Object *coll, Object *key, Heap *heap, Error *err) if(type->delete == NULL) { - Error_Report(err, 0, "Object %s doesn't implement %s", Object_GetName(coll), __func__); + Error_Report(err, ErrorType_RUNTIME, "Object %s doesn't implement %s", Object_GetName(coll), __func__); return NULL; } @@ -215,7 +215,7 @@ _Bool Object_Insert(Object *coll, Object *key, Object *val, Heap *heap, Error *e if(type->insert == NULL) { - Error_Report(err, 0, "Object %s doesn't implement %s", Object_GetName(coll), __func__); + Error_Report(err, ErrorType_RUNTIME, "Object %s doesn't implement %s", Object_GetName(coll), __func__); return 0; } @@ -232,7 +232,7 @@ int Object_Count(Object *coll, Error *err) if(type->count == NULL) { - Error_Report(err, 0, "Object %s doesn't implement %s", Object_GetName(coll), __func__); + Error_Report(err, ErrorType_RUNTIME, "Object %s doesn't implement %s", Object_GetName(coll), __func__); return -1; } diff --git a/src/lib/runtime/o_func.c b/src/lib/runtime/o_func.c index 6b3cd18..6b60062 100644 --- a/src/lib/runtime/o_func.c +++ b/src/lib/runtime/o_func.c @@ -91,7 +91,7 @@ static int call(Object *self, Object **argv, unsigned int argc, Object *rets[sta if(argv2 == NULL) { - Error_Report(error, 1, "No memory"); + Error_Report(error, ErrorType_INTERNAL, "No memory"); return -1; } @@ -197,7 +197,7 @@ Object *Object_FromNojaFunction(Runtime *runtime, const char *name, Executable * if(exe_copy == NULL) { - Error_Report(error, 1, "Failed to copy executable"); + Error_Report(error, ErrorType_INTERNAL, "Failed to copy executable"); return NULL; } diff --git a/src/lib/runtime/runtime.c b/src/lib/runtime/runtime.c index cd9bdaa..e2eced7 100644 --- a/src/lib/runtime/runtime.c +++ b/src/lib/runtime/runtime.c @@ -250,7 +250,7 @@ _Bool Runtime_Push(Runtime *runtime, Error *error, Object *obj) if(runtime->depth == 0) { - Error_Report(error, 0, "There are no frames on the stack"); + Error_Report(error, ErrorType_RUNTIME, "There are no frames on the stack"); return 0; } @@ -258,13 +258,13 @@ _Bool Runtime_Push(Runtime *runtime, Error *error, Object *obj) if(runtime->frame->used == MAX_FRAME_STACK) { - Error_Report(error, 0, "Frame stack limit of %d reached", MAX_FRAME_STACK); + Error_Report(error, ErrorType_RUNTIME, "Frame stack limit of %d reached", MAX_FRAME_STACK); return 0; } if(!Stack_Push(runtime->stack, obj)) { - Error_Report(error, 0, "Out of stack"); + Error_Report(error, ErrorType_RUNTIME, "Out of stack"); return 0; } @@ -279,7 +279,7 @@ _Bool Runtime_Pop(Runtime *runtime, Error *error, unsigned int n) if(runtime->depth == 0) { - Error_Report(error, 0, "There are no frames on the stack"); + Error_Report(error, ErrorType_RUNTIME, "There are no frames on the stack"); return 0; } @@ -287,7 +287,7 @@ _Bool Runtime_Pop(Runtime *runtime, Error *error, unsigned int n) if((unsigned int) runtime->frame->used < n) { - Error_Report(error, 0, "Frame has not enough values on the stack"); + Error_Report(error, ErrorType_RUNTIME, "Frame has not enough values on the stack"); return 0; } @@ -434,7 +434,7 @@ static Object *do_math_op(Object *lop, Object *rop, Opcode opcode, Heap *heap, E case OPCODE_DIV: \ if((y) == 0) \ { \ - Error_Report(error, 0, "Division by zero"); \ + Error_Report(error, ErrorType_RUNTIME, "Division by zero"); \ return NULL; \ } \ (z) = (x) / (y); \ @@ -466,7 +466,7 @@ static Object *do_math_op(Object *lop, Object *rop, Opcode opcode, Heap *heap, E } else { - Error_Report(error, 0, "Arithmetic operation on a non-numeric object"); + Error_Report(error, ErrorType_RUNTIME, "Arithmetic operation on a non-numeric object"); return NULL; } } @@ -492,13 +492,13 @@ static Object *do_math_op(Object *lop, Object *rop, Opcode opcode, Heap *heap, E } else { - Error_Report(error, 0, "Arithmetic operation on a non-numeric object"); + Error_Report(error, ErrorType_RUNTIME, "Arithmetic operation on a non-numeric object"); return NULL; } } else { - Error_Report(error, 0, "Arithmetic operation on a non-numeric object"); + Error_Report(error, ErrorType_RUNTIME, "Arithmetic operation on a non-numeric object"); return NULL; } @@ -541,7 +541,7 @@ static Object *do_relational_op(Object *lop, Object *rop, Opcode opcode, Heap *h } else { - Error_Report(error, 0, "Relational operation on a non-numeric object"); + Error_Report(error, ErrorType_RUNTIME, "Relational operation on a non-numeric object"); return NULL; } } @@ -562,13 +562,13 @@ static Object *do_relational_op(Object *lop, Object *rop, Opcode opcode, Heap *h } else { - Error_Report(error, 0, "Relational operation on a non-numeric object"); + Error_Report(error, ErrorType_RUNTIME, "Relational operation on a non-numeric object"); return NULL; } } else { - Error_Report(error, 0, "Relational operation on a non-numeric object"); + Error_Report(error, ErrorType_RUNTIME, "Relational operation on a non-numeric object"); return NULL; } @@ -584,10 +584,10 @@ static _Bool step(Runtime *runtime, Error *error) Opcode opcode; Operand ops[3]; int opc = sizeof(ops) / sizeof(ops[0]); - + if(!Executable_Fetch(runtime->frame->exe, runtime->frame->index, &opcode, ops, &opc)) { - Error_Report(error, 1, "Invalid instruction index"); + Error_Report(error, ErrorType_INTERNAL, "Invalid instruction index"); return 0; } @@ -605,7 +605,7 @@ static _Bool step(Runtime *runtime, Error *error) if(runtime->frame->used == 0) { - Error_Report(error, 1, "Frame doesn't have enough items on the stack to execute POS"); + Error_Report(error, ErrorType_INTERNAL, "Frame doesn't have enough items on the stack to execute POS"); return 0; } @@ -619,7 +619,7 @@ static _Bool step(Runtime *runtime, Error *error) if(runtime->frame->used == 0) { - Error_Report(error, 1, "Frame doesn't have enough items on the stack to execute NEG"); + Error_Report(error, ErrorType_INTERNAL, "Frame doesn't have enough items on the stack to execute NEG"); return 0; } @@ -644,7 +644,7 @@ static _Bool step(Runtime *runtime, Error *error) } else { - Error_Report(error, 0, "Negation operand on a non-numeric object"); + Error_Report(error, ErrorType_RUNTIME, "Negation operand on a non-numeric object"); return 0; } @@ -662,7 +662,7 @@ static _Bool step(Runtime *runtime, Error *error) if(runtime->frame->used == 0) { - Error_Report(error, 1, "Frame doesn't have enough items on the stack to execute NOT"); + Error_Report(error, ErrorType_INTERNAL, "Frame doesn't have enough items on the stack to execute NOT"); return 0; } @@ -675,7 +675,7 @@ static _Bool step(Runtime *runtime, Error *error) if(!Object_IsBool(top)) { - Error_Report(error, 0, "NOT operand isn't a boolean"); + Error_Report(error, ErrorType_RUNTIME, "NOT operand isn't a boolean"); return 0; } @@ -696,7 +696,7 @@ static _Bool step(Runtime *runtime, Error *error) if(runtime->frame->used == 0) { - Error_Report(error, 1, "Frame doesn't have enough items on the stack to execute NLB"); + Error_Report(error, ErrorType_INTERNAL, "Frame doesn't have enough items on the stack to execute NLB"); return 0; } @@ -784,7 +784,7 @@ static _Bool step(Runtime *runtime, Error *error) ASSERT(lop != NULL); if (!Object_IsInt(rop) || !Object_IsInt(lop)) { - Error_Report(error, 0, "Arithmetic operation on a non-numeric object"); + Error_Report(error, ErrorType_RUNTIME, "Arithmetic operation on a non-numeric object"); return 0; } @@ -872,7 +872,7 @@ static _Bool step(Runtime *runtime, Error *error) if(runtime->frame->used == 0) { - Error_Report(error, 0, "Frame has not enough values on the stack"); + Error_Report(error, ErrorType_RUNTIME, "Frame has not enough values on the stack"); return 0; } @@ -913,7 +913,7 @@ static _Bool step(Runtime *runtime, Error *error) if(runtime->frame->used < 2) { - Error_Report(error, 1, "Frame doesn't own enough objects to execute CHECKTYPE"); + Error_Report(error, ErrorType_INTERNAL, "Frame doesn't own enough objects to execute CHECKTYPE"); return 0; } @@ -936,7 +936,7 @@ static _Bool step(Runtime *runtime, Error *error) Object_Print(arg, provided_fp); fclose(allowed_fp); fclose(provided_fp); - Error_Report(error, 0, "Argument %d \"%s\" has an unallowed type. Was expected something with type %s but was provided %s", + Error_Report(error, ErrorType_RUNTIME, "Argument %d \"%s\" has an unallowed type. Was expected something with type %s but was provided %s", arg_index+1, arg_name, allowed, provided); return 0; } @@ -955,7 +955,7 @@ static _Bool step(Runtime *runtime, Error *error) if(runtime->frame->used < argc + 1) { - Error_Report(error, 1, "Frame doesn't own enough objects to execute call"); + Error_Report(error, ErrorType_INTERNAL, "Frame doesn't own enough objects to execute call"); return 0; } @@ -967,7 +967,7 @@ static _Bool step(Runtime *runtime, Error *error) int max_argc = sizeof(argv) / sizeof(argv[0]); if(argc > max_argc) { - Error_Report(error, 1, "Static buffer only allows function calls with up to %d arguments", max_argc); + Error_Report(error, ErrorType_INTERNAL, "Static buffer only allows function calls with up to %d arguments", max_argc); return 0; } @@ -1020,7 +1020,7 @@ static _Bool step(Runtime *runtime, Error *error) const char *name = "SELECT"; if (opcode == OPCODE_SELECT2) name = "SELECT2"; - Error_Report(error, 1, "Frame has not enough values on the stack to run %s instruction", name); + Error_Report(error, ErrorType_INTERNAL, "Frame has not enough values on the stack to run %s instruction", name); return 0; } @@ -1063,7 +1063,7 @@ static _Bool step(Runtime *runtime, Error *error) if(runtime->frame->used < 3) { - Error_Report(error, 1, "Frame has not enough values on the stack to run INSERT instruction"); + Error_Report(error, ErrorType_INTERNAL, "Frame has not enough values on the stack to run INSERT instruction"); return 0; } @@ -1087,7 +1087,7 @@ static _Bool step(Runtime *runtime, Error *error) if(runtime->frame->used < 3) { - Error_Report(error, 1, "Frame has not enough values on the stack to run INSERT2 instruction"); + Error_Report(error, ErrorType_INTERNAL, "Frame has not enough values on the stack to run INSERT2 instruction"); return 0; } @@ -1180,7 +1180,7 @@ static _Bool step(Runtime *runtime, Error *error) { if(error->occurred == 0) // There's no such variable. - Error_Report(error, 0, "Reference to undefined variable \"%s\"", ops[0].as_string); + Error_Report(error, ErrorType_RUNTIME, "Reference to undefined variable \"%s\"", ops[0].as_string); return 0; } @@ -1302,7 +1302,7 @@ static _Bool step(Runtime *runtime, Error *error) if(runtime->frame->used < 1) { - Error_Report(error, 1, "Frame has not enough values on the stack to run PUSHTYP instruction"); + Error_Report(error, ErrorType_INTERNAL, "Frame has not enough values on the stack to run PUSHTYP instruction"); return 0; } @@ -1356,7 +1356,7 @@ static _Bool step(Runtime *runtime, Error *error) if(runtime->frame->used == 0) { - Error_Report(error, 1, "Frame doesn't have enough items on the stack to execute JUMPIFNOTANDPOP"); + Error_Report(error, ErrorType_INTERNAL, "Frame doesn't have enough items on the stack to execute JUMPIFNOTANDPOP"); return 0; } @@ -1369,7 +1369,7 @@ static _Bool step(Runtime *runtime, Error *error) if(!Object_IsBool(top)) { - Error_Report(error, 0, "Not a boolean"); + Error_Report(error, ErrorType_RUNTIME, "Not a boolean"); return 0; } @@ -1388,7 +1388,7 @@ static _Bool step(Runtime *runtime, Error *error) if(runtime->frame->used == 0) { - Error_Report(error, 1, "Frame doesn't have enough items on the stack to execute JUMPIFNOTANDPOP"); + Error_Report(error, ErrorType_INTERNAL, "Frame doesn't have enough items on the stack to execute JUMPIFNOTANDPOP"); return 0; } @@ -1401,7 +1401,7 @@ static _Bool step(Runtime *runtime, Error *error) if(!Object_IsBool(top)) { - Error_Report(error, 0, "Not a boolean"); + Error_Report(error, ErrorType_RUNTIME, "Not a boolean"); return 0; } @@ -1460,7 +1460,7 @@ int run(Runtime *runtime, Error *error, if(runtime->depth == MAX_FRAMES) { - Error_Report(error, 1, "Maximum nested call limit of %d was reached", MAX_FRAMES); + Error_Report(error, ErrorType_INTERNAL, "Maximum nested call limit of %d was reached", MAX_FRAMES); return -1; } @@ -1481,7 +1481,7 @@ int run(Runtime *runtime, Error *error, if(frame.exe == NULL) { - Error_Report(error, 1, "Failed to copy executable"); + Error_Report(error, ErrorType_INTERNAL, "Failed to copy executable"); return -1; } @@ -1503,13 +1503,13 @@ int run(Runtime *runtime, Error *error, if(runtime->interrupt || (runtime->callback.func != NULL && !runtime->callback.func(runtime, runtime->callback.data))) - Error_Report(error, 0, "Forced abortion"); + Error_Report(error, ErrorType_RUNTIME, "Forced abortion"); else while(step(runtime, error)) { if(runtime->interrupt || (runtime->callback.func != NULL && !runtime->callback.func(runtime, runtime->callback.data))) { - Error_Report(error, 0, "Forced abortion"); + Error_Report(error, ErrorType_RUNTIME, "Forced abortion"); break; } diff --git a/src/lib/utils/error.c b/src/lib/utils/error.c index 9f4c580..439f003 100644 --- a/src/lib/utils/error.c +++ b/src/lib/utils/error.c @@ -52,17 +52,17 @@ void Error_Free(Error *err) memset(err, 0, sizeof (Error)); } -void _Error_Report(Error *err, _Bool internal, +void _Error_Report(Error *err, ErrorType type, const char *file, const char *func, int line, const char *fmt, ...) { va_list va; va_start(va, fmt); - _Error_Report2(err, internal, file, func, line, fmt, va); + _Error_Report2(err, type, file, func, line, fmt, va); va_end(va); } -void _Error_Report2(Error *err, _Bool internal, +void _Error_Report2(Error *err, ErrorType type, const char *file, const char *func, int line, const char *fmt, va_list va) { @@ -80,7 +80,7 @@ void _Error_Report2(Error *err, _Bool internal, ASSERT(err->occurred == 0); err->occurred = 1; - err->internal = internal; + err->type = type; err->file = file; err->func = func; err->line = line; @@ -135,4 +135,36 @@ void Error_Panic_(const char *file, int line, fprintf(fp, " (reported in %s:%d)", file, line); va_end(args); abort(); +} + +void Error_Print(Error *error, ErrorType type_if_unspecified) +{ + ErrorType type = error->type; + if (type == ErrorType_UNSPECIFIED) + type = type_if_unspecified; + + const char *name; + switch (error->type) { + case ErrorType_INTERNAL: name = "Internal Error"; break; + case ErrorType_SYNTAX: name = "Syntax Error"; break; + case ErrorType_SEMANTIC: name = "Semantic Error"; break; + case ErrorType_RUNTIME: name = "Runtime Error"; break; + default: name = "Error"; break; + } + + fprintf(stderr, "%s: %s.", name, error->message); + +#ifdef DEBUG + if(error->file != NULL) + { + if(error->line > 0 && error->func != NULL) + fprintf(stderr, " (Reported in %s:%d in %s)", error->file, error->line, error->func); + else if(error->line > 0 && error->func == NULL) + fprintf(stderr, " (Reported in %s:%d)", error->file, error->line); + else if(error->line < 1 && error->func != NULL) + fprintf(stderr, " (Reported in %s in %s)", error->file, error->func); + } +#endif + + fprintf(stderr, "\n"); } \ No newline at end of file diff --git a/src/lib/utils/error.h b/src/lib/utils/error.h index e86981c..b8cdf61 100644 --- a/src/lib/utils/error.h +++ b/src/lib/utils/error.h @@ -32,8 +32,17 @@ #define ERROR_H #include +typedef enum { + ErrorType_SYNTAX, + ErrorType_SEMANTIC, + ErrorType_RUNTIME, + ErrorType_INTERNAL, + ErrorType_UNSPECIFIED = 0, +} ErrorType; + typedef struct Error Error; struct Error { + ErrorType type; void (*on_report)(Error *err); _Bool occurred, internal, @@ -49,9 +58,10 @@ struct Error { void Error_Init(Error *err); void Error_Init2(Error *err, void (*on_report)(Error *err)); void Error_Free(Error *err); -#define Error_Report(err, internal, fmt, ...) _Error_Report(err, internal, __FILE__, __func__, __LINE__, fmt, ## __VA_ARGS__) -void _Error_Report (Error *err, _Bool internal, const char *file, const char *func, int line, const char *fmt, ...); -void _Error_Report2(Error *err, _Bool internal, const char *file, const char *func, int line, const char *fmt, va_list va); +#define Error_Report(err, typ, fmt, ...) _Error_Report(err, typ, __FILE__, __func__, __LINE__, fmt, ## __VA_ARGS__) +void _Error_Report (Error *err, ErrorType typ, const char *file, const char *func, int line, const char *fmt, ...); +void _Error_Report2(Error *err, ErrorType typ, const char *file, const char *func, int line, const char *fmt, va_list va); void Error_Panic_(const char *file, int line, const char *fmt, ...); #define Error_Panic(fmt, ...) Error_Panic_(__FILE__, __LINE__, fmt, ## __VA_ARGS__) +void Error_Print(Error *error, ErrorType type_if_unspecified); #endif \ No newline at end of file diff --git a/src/lib/utils/source.c b/src/lib/utils/source.c index c357ad5..c4f3de1 100644 --- a/src/lib/utils/source.c +++ b/src/lib/utils/source.c @@ -88,14 +88,14 @@ Source *Source_FromFile(const char *file, Error *error) assert(file != NULL); if(file[0] == '\0') { - Error_Report(error, 0, "Empty file name"); + Error_Report(error, ErrorType_UNSPECIFIED, "Empty file name"); return NULL; } char maybe[1024]; const char *abs_path = Path_MakeAbsolute(file, maybe, sizeof(maybe)); if(abs_path == NULL) { - Error_Report(error, 0, "Internal buffer is too small"); + Error_Report(error, ErrorType_UNSPECIFIED, "Internal buffer is too small"); return NULL; } @@ -111,15 +111,15 @@ Source *Source_FromFile(const char *file, Error *error) if(fp == NULL) { if(errno == ENOENT) - Error_Report(error, 0, "File \"%s\" doesn't exist", file); + Error_Report(error, ErrorType_UNSPECIFIED, "File \"%s\" doesn't exist", file); else - Error_Report(error, 1, "Call to fopen failed (%s, errno = %d)", strerror(errno), errno); + Error_Report(error, ErrorType_INTERNAL, "Call to fopen failed (%s, errno = %d)", strerror(errno), errno); return NULL; } if(fseek(fp, 0, SEEK_END)) { - Error_Report(error, 1, "Call to fseek failed (%s, errno = %d)", strerror(errno), errno); + Error_Report(error, ErrorType_INTERNAL, "Call to fseek failed (%s, errno = %d)", strerror(errno), errno); fclose(fp); return NULL; } @@ -128,14 +128,14 @@ Source *Source_FromFile(const char *file, Error *error) if(size < 0) { - Error_Report(error, 1, "Call to ftell failed (%s, errno = %d)", strerror(errno), errno); + Error_Report(error, ErrorType_INTERNAL, "Call to ftell failed (%s, errno = %d)", strerror(errno), errno); fclose(fp); return NULL; } if(fseek(fp, 0, SEEK_SET)) { - Error_Report(error, 1, "Call to fseek failed (%s, errno = %d)", strerror(errno), errno); + Error_Report(error, ErrorType_INTERNAL, "Call to fseek failed (%s, errno = %d)", strerror(errno), errno); fclose(fp); return NULL; } @@ -150,7 +150,7 @@ Source *Source_FromFile(const char *file, Error *error) if(s == NULL) { - Error_Report(error, 1, "No memory"); + Error_Report(error, ErrorType_INTERNAL, "No memory"); fclose(fp); return NULL; } @@ -171,7 +171,7 @@ Source *Source_FromFile(const char *file, Error *error) if(p != size) { - Error_Report(error, 1, "Call to fread failed, %d bytes out of %d were read (%s, errno = %d)", p, size, strerror(errno), errno); + Error_Report(error, ErrorType_INTERNAL, "Call to fread failed, %d bytes out of %d were read (%s, errno = %d)", p, size, strerror(errno), errno); fclose(fp); free(s); return NULL; @@ -197,7 +197,7 @@ Source *Source_FromString(const char *name, const char *body, int size, Error *e if(memory == NULL) { - Error_Report(error, 1, "No memory"); + Error_Report(error, ErrorType_INTERNAL, "No memory"); return NULL; } diff --git a/src/test/main.c b/src/test/main.c index 3d20c05..f1231e6 100644 --- a/src/test/main.c +++ b/src/test/main.c @@ -86,32 +86,6 @@ // NOTE: From https://gist.github.com/RabaDabaDoba/145049536f815903c79944599c6f952a -static void print_error(const char *type, Error *error) -{ - if(type == NULL) - fprintf(stderr, RED "Error" CRESET); - else if(error->internal) - fprintf(stderr, RED "Internal Error" CRESET); - else - fprintf(stderr, RED "%s Error" CRESET, type); - - fprintf(stderr, " :: %s.", error->message); - -#ifdef DEBUG - if(error->file != NULL) - { - if(error->line > 0 && error->func != NULL) - fprintf(stderr, " (Reported in %s:%d in %s)", error->file, error->line, error->func); - else if(error->line > 0 && error->func == NULL) - fprintf(stderr, " (Reported in %s:%d)", error->file, error->line); - else if(error->line < 1 && error->func != NULL) - fprintf(stderr, " (Reported in %s in %s)", error->file, error->func); - } -#endif - - fprintf(stderr, "\n"); -} - typedef enum { TokenType_END, TokenType_TEXT, @@ -310,14 +284,14 @@ static bool parseTestCaseSource(Source *source, TestCase *testcase) testcase->source = Source_FromString("", str + source_offset, source_length, &error); if(testcase->source == NULL) { - print_error(NULL, &error); + Error_Print(&error, ErrorType_UNSPECIFIED); Error_Free(&error); return false; } testcase->bytecode = Source_FromString("", str + bytecode_offset, bytecode_length, &error); if(testcase->bytecode == NULL) { - print_error(NULL, &error); + Error_Print(&error, ErrorType_UNSPECIFIED); Source_Free(testcase->source); Error_Free(&error); return false; @@ -331,17 +305,9 @@ static Executable *compile_source_and_print_error_on_failure(Source *src) { Error error; Error_Init(&error); - CompilationErrorType errtyp; - Executable *exe = compile(src, &error, &errtyp); + Executable *exe = compile(src, &error); if(exe == NULL) { - const char *errname; - switch(errtyp) { - default: - case CompilationErrorType_INTERNAL: errname = NULL; break; - case CompilationErrorType_SYNTAX: errname = "Syntax"; break; - case CompilationErrorType_SEMANTIC: errname = "Semantic"; break; - } - print_error(errname, &error); + Error_Print(&error, ErrorType_UNSPECIFIED); Error_Free(&error); return NULL; } @@ -364,7 +330,7 @@ static TestResult runTest(const char *file) source = Source_FromFile(file, &error); if(source == NULL) { - print_error(NULL, &error); + Error_Print(&error, ErrorType_UNSPECIFIED); Error_Free(&error); return TestResult_ABORT; } @@ -395,7 +361,7 @@ static TestResult runTest(const char *file) exe2 = assemble(testcase.bytecode, &error); if(exe2 == NULL) { - print_error("Assemblation", &error); + Error_Print(&error, ErrorType_UNSPECIFIED); Error_Free(&error); Executable_Free(exe1); Source_Free(testcase.source);