changed error reporting function interface

This commit is contained in:
Francesco Cozzuto
2023-01-20 01:22:20 +01:00
parent 9cc7121cd9
commit 0980cc193d
29 changed files with 391 additions and 437 deletions
+1 -5
View File
@@ -1,9 +1,5 @@
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};
+16 -15
View File
@@ -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;
}
+10 -11
View File
@@ -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;
}
+4 -4
View File
@@ -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;
}
+5 -5
View File
@@ -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;
}
+5 -5
View File
@@ -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;
}
}
+10 -10
View File
@@ -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;
}
+13 -13
View File
@@ -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,7 +53,7 @@ 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;
}
}
@@ -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;
}
}
+10 -10
View File
@@ -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,7 +532,7 @@ _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;
@@ -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;
+6 -6
View File
@@ -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;
}
+5 -5
View File
@@ -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);
@@ -79,7 +79,7 @@ CodegenContext *CodegenContext_New(Error *error, BPAlloc *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;
}
+1 -1
View File
@@ -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);
+2 -11
View File
@@ -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;
}
+1 -6
View File
@@ -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 */
+93 -91
View File
@@ -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;
}
+151 -189
View File
@@ -8,181 +8,17 @@
#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);
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");
}
#include <signal.h>
Runtime *runt = NULL;
static void signalHandler(int signo)
{
(void) signo;
if (runt != NULL)
Runtime_Interrupt(runt);
}
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)
{
Error error;
Error_Init(&error);
Error_Report(&error, 1, "Couldn't initialize runtime");
print_error(NULL, &error);
Error_Free(&error);
return 0;
}
signal(SIGINT, signalHandler);
signal(SIGTERM, signalHandler);
// We use a [RuntimeError] instead of a simple [Error]
// because the [RuntimeError] makes a snapshot of the
// runtime state when an error is reported. Other than
// this fact they are interchangable. Any function that
// 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.
{
Object *native_bins = Object_NewStaticMap(bins_basic, bins_basic_init, runt, (Error*) &error);
if(native_bins == NULL)
{
assert(error.base.occurred == 1);
print_error(NULL, (Error*) &error);
RuntimeError_Free(&error);
Runtime_Free(runt);
return 0;
}
// Just to execute the prelude
Runtime_SetBuiltins(runt, native_bins);
extern char start_noja[];
Source *prelude = Source_FromString("<prelude>", start_noja, -1, (Error*) &error);
if (prelude == NULL) {
assert(error.base.occurred == 1);
print_error(NULL, (Error*) &error);
RuntimeError_Free(&error);
Runtime_Free(runt);
return 0;
}
CompilationErrorType errtyp;
Executable *prelude_exe = compile(prelude, (Error*) &error, &errtyp);
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);
RuntimeError_Free(&error);
Runtime_Free(runt);
Source_Free(prelude);
return 0;
}
Object *rets[8];
int retc = run(runt, (Error*) &error, prelude_exe, 0, NULL, NULL, 0, rets);
if(retc < 0) {
print_error("Runtime", (Error*) &error);
RuntimeError_Free(&error);
Runtime_Free(runt);
Source_Free(prelude);
Executable_Free(prelude_exe);
return 0;
}
Object *noja_bins = rets[0];
// 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);
if(native_bins == NULL)
{
assert(error.base.occurred == 1);
print_error(NULL, (Error*) &error);
RuntimeError_Free(&error);
Runtime_Free(runt);
Source_Free(prelude);
Executable_Free(prelude_exe);
return 0;
}
Object *all_bins = Object_NewClosure(native_bins, noja_bins, Runtime_GetHeap(runt), (Error*) &error);
if (all_bins == NULL) {
print_error(NULL, (Error*) &error);
RuntimeError_Free(&error);
Runtime_Free(runt);
Source_Free(prelude);
Executable_Free(prelude_exe);
return 0;
}
Runtime_SetBuiltins(runt, all_bins);
Source_Free(prelude);
Executable_Free(prelude_exe);
}
Object *rets[8];
int retc = run(runt, (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);
if(error.snapshot == NULL)
fprintf(stderr, "No snapshot available.\n");
else
Snapshot_Print(error.snapshot, stderr);
RuntimeError_Free(&error);
}
TimingTable *table = Runtime_GetTimingTable(runt);
if (table != NULL) {
const char *file = "profiling-results.txt";
TimingTable *table = Runtime_GetTimingTable(runtime);
if (table == NULL)
return;
FILE *stream = fopen(file, "wb");
if (stream == NULL) {
fprintf(stderr, "Failed to serialize profiling results\n");
} else {
return;
}
const FunctionExecutionSummary *summary;
size_t count;
@@ -202,10 +38,144 @@ static _Bool interpret(Executable *exe, bool time, size_t heap)
fclose(stream);
fprintf(stderr, "Wrote profiling result to %s\n", file);
}
#include <signal.h>
Runtime *runtime = NULL;
static void signalHandler(int signo)
{
(void) signo;
if (runtime != NULL)
Runtime_Interrupt(runtime);
}
static _Bool interpret(Executable *exe, bool time, size_t heap)
{
RuntimeConfig config = Runtime_GetDefaultConfigs();
config.time = time;
runtime = Runtime_New(heap, config);
if(runtime == NULL)
{
Error error;
Error_Init(&error);
Error_Report(&error, ErrorType_INTERNAL, "Couldn't initialize runtime");
Error_Print(&error, ErrorType_UNSPECIFIED);
Error_Free(&error);
return 0;
}
signal(SIGINT, signalHandler);
signal(SIGTERM, signalHandler);
// We use a [RuntimeError] instead of a simple [Error]
// because the [RuntimeError] makes a snapshot of the
// runtime state when an error is reported. Other than
// this fact they are interchangable. Any function that
// expects a pointer to [Error] can receive a [RuntimeError]
// upcasted to [Error].
RuntimeError error;
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, runtime, (Error*) &error);
if(native_bins == NULL)
{
assert(error.base.occurred == 1);
Error_Print((Error*) &error, ErrorType_RUNTIME);
RuntimeError_Free(&error);
Runtime_Free(runtime);
return 0;
}
Runtime_Free(runt);
// Just to execute the prelude
Runtime_SetBuiltins(runtime, native_bins);
extern char start_noja[];
Source *prelude = Source_FromString("<prelude>", start_noja, -1, (Error*) &error);
if (prelude == NULL) {
assert(error.base.occurred == 1);
Error_Print((Error*) &error, ErrorType_RUNTIME);
RuntimeError_Free(&error);
Runtime_Free(runtime);
return 0;
}
Executable *prelude_exe = compile(prelude, (Error*) &error);
if(prelude_exe == NULL) {
Error_Print((Error*) &error, ErrorType_RUNTIME);
RuntimeError_Free(&error);
Runtime_Free(runtime);
Source_Free(prelude);
return 0;
}
Object *rets[8];
int retc = run(runtime, (Error*) &error, prelude_exe, 0, NULL, NULL, 0, rets);
if(retc < 0) {
Error_Print((Error*) &error, ErrorType_RUNTIME);
RuntimeError_Free(&error);
Runtime_Free(runtime);
Source_Free(prelude);
Executable_Free(prelude_exe);
return 0;
}
Object *noja_bins = rets[0];
// Need to remake the native built-ins because
// running the script invalidated the previous
// pointer.
native_bins = Object_NewStaticMap(bins_basic, bins_basic_init, runtime, (Error*) &error);
if(native_bins == NULL)
{
assert(error.base.occurred == 1);
Error_Print((Error*) &error, ErrorType_RUNTIME);
RuntimeError_Free(&error);
Runtime_Free(runtime);
Source_Free(prelude);
Executable_Free(prelude_exe);
return 0;
}
Object *all_bins = Object_NewClosure(native_bins, noja_bins, Runtime_GetHeap(runtime), (Error*) &error);
if (all_bins == NULL) {
Error_Print((Error*) &error, ErrorType_RUNTIME);
RuntimeError_Free(&error);
Runtime_Free(runtime);
Source_Free(prelude);
Executable_Free(prelude_exe);
return 0;
}
Runtime_SetBuiltins(runtime, all_bins);
Source_Free(prelude);
Executable_Free(prelude_exe);
}
Object *rets[8];
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)
{
Error_Print((Error*) &error, ErrorType_RUNTIME);
if(error.snapshot == NULL)
fprintf(stderr, "No snapshot available.\n");
else
Snapshot_Print(error.snapshot, stderr);
RuntimeError_Free(&error);
}
serializeProfilingResults(runtime, "profiling-results.txt");
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;
}
+4 -4
View File
@@ -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;
}
@@ -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;
}
+10 -10
View File
@@ -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;
}
+1 -1
View File
@@ -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;
}
+1 -1
View File
@@ -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;
}
+4 -4
View File
@@ -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;
}
+3 -3
View File
@@ -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;
}
+6 -6
View File
@@ -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;
}
+2 -2
View File
@@ -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;
}
+38 -38
View File
@@ -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;
}
@@ -587,7 +587,7 @@ static _Bool step(Runtime *runtime, Error *error)
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;
}
+36 -4
View File
@@ -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;
@@ -136,3 +136,35 @@ void Error_Panic_(const char *file, int 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");
}
+13 -3
View File
@@ -32,8 +32,17 @@
#define ERROR_H
#include <stdarg.h>
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
+10 -10
View File
@@ -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;
}
+6 -40
View File
@@ -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("<input>", 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("<output>", 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);