changed error reporting function interface
This commit is contained in:
@@ -1,10 +1,6 @@
|
|||||||
|
|
||||||
vars, err = import("imported.noja");
|
vars = import("imported.noja");
|
||||||
if vars == none: {
|
|
||||||
print("Import failed!! (", err, ")\n");
|
|
||||||
return none;
|
|
||||||
}
|
|
||||||
|
|
||||||
me = {name: vars.myName, age: vars.myAge};
|
me = {name: vars.myName, age: vars.myAge};
|
||||||
|
|
||||||
print(me, "\n");
|
print(me, "\n");
|
||||||
|
|||||||
@@ -56,7 +56,8 @@ static bool parseLabelAndOpcode(Context *ctx, bool *no_label,
|
|||||||
char c = ctx->str[ctx->cur];
|
char c = ctx->str[ctx->cur];
|
||||||
if(!isalpha(c) && c != '_') {
|
if(!isalpha(c) && c != '_') {
|
||||||
// ERROR: Missing opcode
|
// 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;
|
label_or_opcode.offset = ctx->cur;
|
||||||
@@ -77,7 +78,7 @@ static bool parseLabelAndOpcode(Context *ctx, bool *no_label,
|
|||||||
skipSpaces(ctx);
|
skipSpaces(ctx);
|
||||||
|
|
||||||
if(ctx->cur == ctx->len || (!isalpha(ctx->str[ctx->cur]) && ctx->str[ctx->cur] != '_')) {
|
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;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -111,7 +112,7 @@ static bool parseStringOperand(Context *ctx, Error *error, BPAlloc *alloc, Opera
|
|||||||
ctx->cur += 1;
|
ctx->cur += 1;
|
||||||
|
|
||||||
if(ctx->cur == ctx->len) {
|
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;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -123,7 +124,7 @@ static bool parseStringOperand(Context *ctx, Error *error, BPAlloc *alloc, Opera
|
|||||||
|
|
||||||
char *copy = BPAlloc_Malloc(alloc, literal_length+1);
|
char *copy = BPAlloc_Malloc(alloc, literal_length+1);
|
||||||
if(copy == NULL) {
|
if(copy == NULL) {
|
||||||
Error_Report(error, 1, "No memory");
|
Error_Report(error, ErrorType_INTERNAL, "No memory");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -151,7 +152,7 @@ static bool parseIntegerOperand(Context *ctx, Error *error, Operand *op)
|
|||||||
|
|
||||||
// Will this overflow?
|
// Will this overflow?
|
||||||
if(buffer > (LLONG_MAX - d) / 10) {
|
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;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -254,7 +255,7 @@ static bool parseOperands(Context *ctx, BPAlloc *alloc, Error *error,
|
|||||||
|
|
||||||
Promise *promise = LabelList_GetLabel(list, ctx->str + offset, length);
|
Promise *promise = LabelList_GetLabel(list, ctx->str + offset, length);
|
||||||
if(promise == NULL) {
|
if(promise == NULL) {
|
||||||
Error_Report(error, 1, "No memory");
|
Error_Report(error, ErrorType_INTERNAL, "No memory");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -263,12 +264,12 @@ static bool parseOperands(Context *ctx, BPAlloc *alloc, Error *error,
|
|||||||
|
|
||||||
} else {
|
} else {
|
||||||
// ERROR: Unexpected character
|
// ERROR: Unexpected character
|
||||||
Error_Report(error, 0, "Unexpected character '%c'", c);
|
Error_Report(error, ErrorType_SYNTAX, "Unexpected character '%c'", c);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(*opc == opc_max) {
|
if(*opc == opc_max) {
|
||||||
Error_Report(error, 0, "Too many operands");
|
Error_Report(error, ErrorType_SEMANTIC, "Too many operands");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
opv[*opc] = op;
|
opv[*opc] = op;
|
||||||
@@ -281,7 +282,7 @@ static bool parseOperands(Context *ctx, BPAlloc *alloc, Error *error,
|
|||||||
|
|
||||||
c = ctx->str[ctx->cur];
|
c = ctx->str[ctx->cur];
|
||||||
if(c != ',') {
|
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;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -301,20 +302,20 @@ Executable *assemble(Source *src, Error *error)
|
|||||||
|
|
||||||
BPAlloc *alloc = BPAlloc_Init(-1);
|
BPAlloc *alloc = BPAlloc_Init(-1);
|
||||||
if(alloc == NULL) {
|
if(alloc == NULL) {
|
||||||
Error_Report(error, 1, "No memory");
|
Error_Report(error, ErrorType_INTERNAL, "No memory");
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
LabelList *list = LabelList_New(alloc);
|
LabelList *list = LabelList_New(alloc);
|
||||||
if(list == NULL) {
|
if(list == NULL) {
|
||||||
Error_Report(error, 1, "No memory");
|
Error_Report(error, ErrorType_INTERNAL, "No memory");
|
||||||
BPAlloc_Free(alloc);
|
BPAlloc_Free(alloc);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
ExeBuilder *builder = ExeBuilder_New(alloc);
|
ExeBuilder *builder = ExeBuilder_New(alloc);
|
||||||
if(builder == NULL) {
|
if(builder == NULL) {
|
||||||
Error_Report(error, 1, "No memory");
|
Error_Report(error, ErrorType_INTERNAL, "No memory");
|
||||||
LabelList_Free(list);
|
LabelList_Free(list);
|
||||||
BPAlloc_Free(alloc);
|
BPAlloc_Free(alloc);
|
||||||
return NULL;
|
return NULL;
|
||||||
@@ -342,7 +343,7 @@ Executable *assemble(Source *src, Error *error)
|
|||||||
if(no_label == false) {
|
if(no_label == false) {
|
||||||
long long int value = ExeBuilder_InstrCount(builder);
|
long long int value = ExeBuilder_InstrCount(builder);
|
||||||
if(!LabelList_SetLabel(list, ctx.str + label.offset, label.length, value)) {
|
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;
|
goto done;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -352,7 +353,7 @@ Executable *assemble(Source *src, Error *error)
|
|||||||
Opcode opcode;
|
Opcode opcode;
|
||||||
const char *name = ctx.str + opcode_name.offset;
|
const char *name = ctx.str + opcode_name.offset;
|
||||||
if(!Executable_GetOpcodeBinaryFromName(name, opcode_name.length, &opcode)) {
|
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;
|
goto done;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -377,7 +378,7 @@ Executable *assemble(Source *src, Error *error)
|
|||||||
|
|
||||||
size_t unresolved_count = LabelList_GetUnresolvedCount(list);
|
size_t unresolved_count = LabelList_GetUnresolvedCount(list);
|
||||||
if(unresolved_count > 0) {
|
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;
|
goto done;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+10
-11
@@ -54,7 +54,7 @@ static int bin_getCurrentWorkingDirectory(Runtime *runtime, Object **argv, unsig
|
|||||||
|
|
||||||
char path[1024];
|
char path[1024];
|
||||||
if(getcwd(path, sizeof(path)) == NULL) {
|
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;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -139,19 +139,19 @@ static int bin_import(Runtime *runtime,
|
|||||||
|
|
||||||
if(path[0] == '/') {
|
if(path[0] == '/') {
|
||||||
if(path_len >= sizeof(full_path)) {
|
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;
|
return -1;
|
||||||
}
|
}
|
||||||
strcpy(full_path, path);
|
strcpy(full_path, path);
|
||||||
} else {
|
} else {
|
||||||
size_t written = Runtime_GetCurrentScriptFolder(runtime, full_path, sizeof(full_path));
|
size_t written = Runtime_GetCurrentScriptFolder(runtime, full_path, sizeof(full_path));
|
||||||
if(written == 0) {
|
if(written == 0) {
|
||||||
Error_Report(error, 1, "Internal buffer is too small");
|
Error_Report(error, ErrorType_INTERNAL, "Internal buffer is too small");
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(written + path_len >= sizeof(full_path)) {
|
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;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -163,8 +163,7 @@ static int bin_import(Runtime *runtime,
|
|||||||
if(src == NULL)
|
if(src == NULL)
|
||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
CompilationErrorType errtyp;
|
Executable *exe = compile(src, error);
|
||||||
Executable *exe = compile(src, error, &errtyp);
|
|
||||||
if(exe == NULL) {
|
if(exe == NULL) {
|
||||||
Source_Free(src);
|
Source_Free(src);
|
||||||
return -1;
|
return -1;
|
||||||
@@ -241,7 +240,7 @@ static int bin_input(Runtime *runtime, Object **argv, unsigned int argc, Object
|
|||||||
if(tmp == NULL)
|
if(tmp == NULL)
|
||||||
{
|
{
|
||||||
if(str != maybe) free(str);
|
if(str != maybe) free(str);
|
||||||
Error_Report(error, 1, "No memory");
|
Error_Report(error, ErrorType_INTERNAL, "No memory");
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -275,13 +274,13 @@ static int bin_assert(Runtime *runtime, Object **argv, unsigned int argc, Object
|
|||||||
{
|
{
|
||||||
if(!Object_IsBool(argv[i]))
|
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;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(!Object_GetBool(argv[i]))
|
if(!Object_GetBool(argv[i]))
|
||||||
{
|
{
|
||||||
Error_Report(error, 0, "Assertion failed");
|
Error_Report(error, ErrorType_RUNTIME, "Assertion failed");
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -298,7 +297,7 @@ static int bin_error(Runtime *runtime, Object **argv, unsigned int argc, Object
|
|||||||
|
|
||||||
if(!Object_IsString(argv[0]))
|
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;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -308,7 +307,7 @@ static int bin_error(Runtime *runtime, Object **argv, unsigned int argc, Object
|
|||||||
string = Object_GetString(argv[0], &length);
|
string = Object_GetString(argv[0], &length);
|
||||||
ASSERT(string != NULL);
|
ASSERT(string != NULL);
|
||||||
|
|
||||||
Error_Report(error, 0, "%s", string);
|
Error_Report(error, ErrorType_RUNTIME, "%s", string);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -11,7 +11,7 @@ static int bin_new(Runtime *runtime, Object **argv, unsigned int argc, Object *r
|
|||||||
|
|
||||||
if(!Object_IsInt(argv[0]))
|
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;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -33,13 +33,13 @@ static int bin_sliceUp(Runtime *runtime, Object **argv, unsigned int argc, Objec
|
|||||||
|
|
||||||
if(!Object_IsInt(argv[1]))
|
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;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(!Object_IsInt(argv[2]))
|
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;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -78,7 +78,7 @@ static int bin_toString(Runtime *runtime, Object **argv, unsigned int argc, Obje
|
|||||||
|
|
||||||
if(!Object_IsBuffer(argv[0]))
|
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;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -124,7 +124,7 @@ static int bin_read(Runtime *runtime, Object **argv, unsigned int argc, Object *
|
|||||||
if (pargs[2].defined) {
|
if (pargs[2].defined) {
|
||||||
int n = pargs[2].as_int;
|
int n = pargs[2].as_int;
|
||||||
if (n < 0) {
|
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;
|
return -1;
|
||||||
}
|
}
|
||||||
count = MIN((size_t) n, dstlen);
|
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) {
|
if (pargs[2].defined) {
|
||||||
int n = pargs[2].as_int;
|
int n = pargs[2].as_int;
|
||||||
if (n < 0) {
|
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;
|
return -1;
|
||||||
}
|
}
|
||||||
count = MIN((size_t) n, srclen);
|
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]))
|
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;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -216,7 +216,7 @@ static int bin_nextDirItem(Runtime *runtime, Object **argv, unsigned int argc, O
|
|||||||
|
|
||||||
if(!Object_IsDir(argv[0]))
|
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;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -233,7 +233,7 @@ static int bin_nextDirItem(Runtime *runtime, Object **argv, unsigned int argc, O
|
|||||||
return 0; // Nothing left to read.
|
return 0; // Nothing left to read.
|
||||||
|
|
||||||
// An error occurred.
|
// An error occurred.
|
||||||
Error_Report(error, 1, "Failed to read directory item");
|
Error_Report(error, ErrorType_INTERNAL, "Failed to read directory item");
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -49,7 +49,7 @@
|
|||||||
} \
|
} \
|
||||||
else \
|
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; \
|
return -1; \
|
||||||
} \
|
} \
|
||||||
}
|
}
|
||||||
@@ -62,13 +62,13 @@
|
|||||||
\
|
\
|
||||||
if(!Object_IsFloat(argv[0])) \
|
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; \
|
return -1; \
|
||||||
} \
|
} \
|
||||||
\
|
\
|
||||||
if(!Object_IsFloat(argv[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; \
|
return -1; \
|
||||||
} \
|
} \
|
||||||
\
|
\
|
||||||
@@ -110,7 +110,7 @@ static int bin_ceil(Runtime *runtime, Object **argv, unsigned int argc, Object *
|
|||||||
}
|
}
|
||||||
else
|
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;
|
return -1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -131,7 +131,7 @@ static int bin_floor(Runtime *runtime, Object **argv, unsigned int argc, Object
|
|||||||
}
|
}
|
||||||
else
|
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;
|
return -1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+10
-10
@@ -19,7 +19,7 @@ static int bin_ord(Runtime *runtime, Object **argv, unsigned int argc, Object *r
|
|||||||
|
|
||||||
if(!Object_IsString(argv[0]))
|
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;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -30,7 +30,7 @@ static int bin_ord(Runtime *runtime, Object **argv, unsigned int argc, Object *r
|
|||||||
|
|
||||||
if(length == 0)
|
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;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -55,7 +55,7 @@ static int bin_chr(Runtime *runtime, Object **argv, unsigned int argc, Object *r
|
|||||||
|
|
||||||
if(!Object_IsInt(argv[0]))
|
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;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -67,7 +67,7 @@ static int bin_chr(Runtime *runtime, Object **argv, unsigned int argc, Object *r
|
|||||||
|
|
||||||
if(k<0)
|
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;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -88,7 +88,7 @@ static int bin_cat(Runtime *runtime, Object **argv, unsigned int argc, Object *r
|
|||||||
{
|
{
|
||||||
if(!Object_IsString(argv[i]))
|
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;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -110,7 +110,7 @@ static int bin_cat(Runtime *runtime, Object **argv, unsigned int argc, Object *r
|
|||||||
|
|
||||||
if(buffer == NULL)
|
if(buffer == NULL)
|
||||||
{
|
{
|
||||||
Error_Report(error, 1, "No memory");
|
Error_Report(error, ErrorType_INTERNAL, "No memory");
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -157,7 +157,7 @@ static int bin_slice(Runtime *runtime, Object **argv, unsigned int argc, Object
|
|||||||
if (pargs[1].defined) {
|
if (pargs[1].defined) {
|
||||||
int64_t n = pargs[1].as_int;
|
int64_t n = pargs[1].as_int;
|
||||||
if (n < 0) {
|
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;
|
return -1;
|
||||||
}
|
}
|
||||||
offset = (size_t) n;
|
offset = (size_t) n;
|
||||||
@@ -167,7 +167,7 @@ static int bin_slice(Runtime *runtime, Object **argv, unsigned int argc, Object
|
|||||||
if (pargs[2].defined) {
|
if (pargs[2].defined) {
|
||||||
int64_t n = pargs[2].as_int;
|
int64_t n = pargs[2].as_int;
|
||||||
if (n < 0) {
|
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;
|
return -1;
|
||||||
}
|
}
|
||||||
length = (size_t) n;
|
length = (size_t) n;
|
||||||
@@ -175,11 +175,11 @@ static int bin_slice(Runtime *runtime, Object **argv, unsigned int argc, Object
|
|||||||
length = srclen - offset;
|
length = srclen - offset;
|
||||||
|
|
||||||
if (offset > srclen) {
|
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;
|
return -1;
|
||||||
}
|
}
|
||||||
if (offset + length > srclen) {
|
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;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+14
-14
@@ -6,7 +6,7 @@ int returnValuesVA(Error *error, Heap *heap, Object *rets[static MAX_RETS], cons
|
|||||||
while (fmt[i] != '\0') {
|
while (fmt[i] != '\0') {
|
||||||
|
|
||||||
if (retc == MAX_RETS) {
|
if (retc == MAX_RETS) {
|
||||||
Error_Report(error, 1, "Return value limit reached");
|
Error_Report(error, ErrorType_INTERNAL, "Return value limit reached");
|
||||||
return -1;
|
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 's': ret = Object_FromString(va_arg(va, char*), -1, heap, error); break;
|
||||||
case 'F': ret = Object_FromStream(va_arg(va, FILE*), heap, error); break;
|
case 'F': ret = Object_FromStream(va_arg(va, FILE*), heap, error); break;
|
||||||
default:
|
default:
|
||||||
Error_Report(error, 1, "Invalid format specifier '%c'", fmt[i]);
|
Error_Report(error, ErrorType_INTERNAL, "Invalid format specifier '%c'", fmt[i]);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -43,7 +43,7 @@ bool parseArgs(Error *error,
|
|||||||
while (fmt[i] != '\0') {
|
while (fmt[i] != '\0') {
|
||||||
|
|
||||||
if (current_arg == argc) {
|
if (current_arg == argc) {
|
||||||
Error_Report(error, 0, "Missing arguments");
|
Error_Report(error, ErrorType_RUNTIME, "Missing arguments");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
Object *arg = argv[current_arg];
|
Object *arg = argv[current_arg];
|
||||||
@@ -53,11 +53,11 @@ bool parseArgs(Error *error,
|
|||||||
may_be_none = true;
|
may_be_none = true;
|
||||||
i++;
|
i++;
|
||||||
if (fmt[i] == '\0') {
|
if (fmt[i] == '\0') {
|
||||||
Error_Report(error, 1, "Format terminated unexpectedly");
|
Error_Report(error, ErrorType_INTERNAL, "Format terminated unexpectedly");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (may_be_none && Object_IsNone(arg)) {
|
if (may_be_none && Object_IsNone(arg)) {
|
||||||
pargs[current_arg].defined = false;
|
pargs[current_arg].defined = false;
|
||||||
} else {
|
} else {
|
||||||
@@ -69,7 +69,7 @@ bool parseArgs(Error *error,
|
|||||||
|
|
||||||
case 'b': /* Boolean */
|
case 'b': /* Boolean */
|
||||||
if (!Object_IsBool(arg)) {
|
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;
|
return false;
|
||||||
}
|
}
|
||||||
pargs[current_arg].defined = true;
|
pargs[current_arg].defined = true;
|
||||||
@@ -79,7 +79,7 @@ bool parseArgs(Error *error,
|
|||||||
case 'B': /* Buffer */
|
case 'B': /* Buffer */
|
||||||
{
|
{
|
||||||
if (!Object_IsBuffer(arg)) {
|
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;
|
return false;
|
||||||
}
|
}
|
||||||
void *data;
|
void *data;
|
||||||
@@ -93,7 +93,7 @@ bool parseArgs(Error *error,
|
|||||||
|
|
||||||
case 'i': /* Integer */
|
case 'i': /* Integer */
|
||||||
if (!Object_IsInt(arg)) {
|
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;
|
return false;
|
||||||
}
|
}
|
||||||
pargs[current_arg].defined = true;
|
pargs[current_arg].defined = true;
|
||||||
@@ -102,7 +102,7 @@ bool parseArgs(Error *error,
|
|||||||
|
|
||||||
case 'f': /* Float */
|
case 'f': /* Float */
|
||||||
if (!Object_IsFloat(arg)) {
|
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;
|
return false;
|
||||||
}
|
}
|
||||||
pargs[current_arg].defined = true;
|
pargs[current_arg].defined = true;
|
||||||
@@ -111,7 +111,7 @@ bool parseArgs(Error *error,
|
|||||||
|
|
||||||
case 'l': /* List */
|
case 'l': /* List */
|
||||||
if (!Object_IsList(arg)) {
|
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;
|
return false;
|
||||||
}
|
}
|
||||||
pargs[current_arg].defined = true;
|
pargs[current_arg].defined = true;
|
||||||
@@ -119,7 +119,7 @@ bool parseArgs(Error *error,
|
|||||||
|
|
||||||
case 'm': /* Map */
|
case 'm': /* Map */
|
||||||
if (!Object_IsMap(arg)) {
|
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;
|
return false;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
@@ -127,7 +127,7 @@ bool parseArgs(Error *error,
|
|||||||
case 's': /* String */
|
case 's': /* String */
|
||||||
{
|
{
|
||||||
if (!Object_IsString(arg)) {
|
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;
|
return false;
|
||||||
}
|
}
|
||||||
const void *data;
|
const void *data;
|
||||||
@@ -141,7 +141,7 @@ bool parseArgs(Error *error,
|
|||||||
|
|
||||||
case 'F': /* File */
|
case 'F': /* File */
|
||||||
if (!Object_IsFile(arg)) {
|
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;
|
return false;
|
||||||
}
|
}
|
||||||
pargs[current_arg].defined = true;
|
pargs[current_arg].defined = true;
|
||||||
@@ -149,7 +149,7 @@ bool parseArgs(Error *error,
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
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;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+11
-11
@@ -450,7 +450,7 @@ Executable *ExeBuilder_Finalize(ExeBuilder *exeb, Error *error)
|
|||||||
|
|
||||||
if(exeb->promc > 0)
|
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;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -465,7 +465,7 @@ Executable *ExeBuilder_Finalize(ExeBuilder *exeb, Error *error)
|
|||||||
|
|
||||||
if(temp == NULL)
|
if(temp == NULL)
|
||||||
{
|
{
|
||||||
Error_Report(error, 1, "No memory");
|
Error_Report(error, ErrorType_INTERNAL, "No memory");
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -524,7 +524,7 @@ _Bool ExeBuilder_Append(ExeBuilder *exeb, Error *error, Opcode opcode, Operand *
|
|||||||
|
|
||||||
#ifndef NDEBUG
|
#ifndef NDEBUG
|
||||||
if (info == NULL) {
|
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;
|
return 0;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
@@ -532,12 +532,12 @@ _Bool ExeBuilder_Append(ExeBuilder *exeb, Error *error, Opcode opcode, Operand *
|
|||||||
if(opc != info->opcount)
|
if(opc != info->opcount)
|
||||||
{
|
{
|
||||||
// ERROR: Too many operands were provided.
|
// ERROR: Too many operands were provided.
|
||||||
Error_Report(error, 1,
|
Error_Report(error, ErrorType_INTERNAL,
|
||||||
"Instruction %s expects %d operands, but %d were provided",
|
"Instruction %s expects %d operands, but %d were provided",
|
||||||
info->name, info->opcount, opc);
|
info->name, info->opcount, opc);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
ASSERT(opc <= MAX_OPS);
|
ASSERT(opc <= MAX_OPS);
|
||||||
|
|
||||||
{
|
{
|
||||||
@@ -545,7 +545,7 @@ _Bool ExeBuilder_Append(ExeBuilder *exeb, Error *error, Opcode opcode, Operand *
|
|||||||
|
|
||||||
if(instr == NULL)
|
if(instr == NULL)
|
||||||
{
|
{
|
||||||
Error_Report(error, 1, "No memory");
|
Error_Report(error, ErrorType_INTERNAL, "No memory");
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -570,13 +570,13 @@ _Bool ExeBuilder_Append(ExeBuilder *exeb, Error *error, Opcode opcode, Operand *
|
|||||||
|
|
||||||
if(expected_type == OPTP_STRING)
|
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;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(Promise_Size(opv[i].as_promise) != operand_type_sizes[expected_type])
|
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, "
|
"Provided promise has a value size of %d, "
|
||||||
"but since %s %s was expected, the promise "
|
"but since %s %s was expected, the promise "
|
||||||
"size must be %d",
|
"size must be %d",
|
||||||
@@ -590,7 +590,7 @@ _Bool ExeBuilder_Append(ExeBuilder *exeb, Error *error, Opcode opcode, Operand *
|
|||||||
else if(expected_type != provided_type)
|
else if(expected_type != provided_type)
|
||||||
{
|
{
|
||||||
// ERROR: Wrong operand type provided.
|
// 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",
|
"Instruction %s expects %s %s as operand %d, but %s %s was provided instead",
|
||||||
info->name,
|
info->name,
|
||||||
operand_type_arts[expected_type],
|
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))
|
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;
|
return 0;
|
||||||
}
|
}
|
||||||
break;
|
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))
|
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;
|
return 0;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|||||||
@@ -320,7 +320,7 @@ static void flattenTupleTree(CodegenContext *ctx, ExprNode *root, ExprNode *tupl
|
|||||||
|
|
||||||
if(max == *count)
|
if(max == *count)
|
||||||
{
|
{
|
||||||
CodegenContext_ReportErrorAndJump(ctx, 0, "Static buffer is too small");
|
CodegenContext_ReportErrorAndJump(ctx, ErrorType_INTERNAL, "Static buffer is too small");
|
||||||
UNREACHABLE;
|
UNREACHABLE;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -348,7 +348,7 @@ static void emitInstrForAssignmentNode(CodegenContext *ctx, OperExprNode *asgn,
|
|||||||
if(((ExprNode*) rop)->kind == EXPR_CALL)
|
if(((ExprNode*) rop)->kind == EXPR_CALL)
|
||||||
emitInstrForFuncCallNode(ctx, (CallExprNode*) rop, label_break, count);
|
emitInstrForFuncCallNode(ctx, (CallExprNode*) rop, label_break, count);
|
||||||
else {
|
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;
|
UNREACHABLE;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -376,7 +376,7 @@ static void emitInstrForAssignmentNode(CodegenContext *ctx, OperExprNode *asgn,
|
|||||||
}
|
}
|
||||||
|
|
||||||
default:
|
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;
|
UNREACHABLE;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -415,7 +415,7 @@ static void emitInstrForExprNode(CodegenContext *ctx, ExprNode *expr,
|
|||||||
}
|
}
|
||||||
|
|
||||||
case EXPR_ARW:
|
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;
|
UNREACHABLE;
|
||||||
return;
|
return;
|
||||||
|
|
||||||
@@ -683,7 +683,7 @@ static void emitInstrForNode(CodegenContext *ctx, Node *node, Label *label_break
|
|||||||
|
|
||||||
case NODE_BREAK:
|
case NODE_BREAK:
|
||||||
if(label_break == NULL)
|
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);
|
emitInstr_JUMP(ctx, label_break, node->offset, node->length);
|
||||||
return;
|
return;
|
||||||
|
|
||||||
@@ -770,7 +770,7 @@ Executable *codegen(AST *ast, BPAlloc *alloc, Error *error)
|
|||||||
|
|
||||||
CodegenContext *ctx = CodegenContext_New(error, alloc);
|
CodegenContext *ctx = CodegenContext_New(error, alloc);
|
||||||
if(ctx == NULL) {
|
if(ctx == NULL) {
|
||||||
Error_Report(error, 1, "No memory");
|
Error_Report(error, ErrorType_INTERNAL, "No memory");
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -17,7 +17,7 @@ Label *Label_New(CodegenContext *ctx)
|
|||||||
if(promise != NULL)
|
if(promise != NULL)
|
||||||
return (Label*) promise;
|
return (Label*) promise;
|
||||||
|
|
||||||
CodegenContext_ReportErrorAndJump(ctx, 1, "No memory");
|
CodegenContext_ReportErrorAndJump(ctx, ErrorType_INTERNAL, "No memory");
|
||||||
UNREACHABLE;
|
UNREACHABLE;
|
||||||
return NULL; // For the compiler warning.
|
return NULL; // For the compiler warning.
|
||||||
}
|
}
|
||||||
@@ -54,12 +54,12 @@ static void okNowJump(CodegenContext *ctx)
|
|||||||
}
|
}
|
||||||
|
|
||||||
void CodegenContext_ReportErrorAndJump_(CodegenContext *ctx, const char *file,
|
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, ...)
|
const char *format, ...)
|
||||||
{
|
{
|
||||||
va_list args;
|
va_list args;
|
||||||
va_start(args, format);
|
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);
|
va_end(args);
|
||||||
|
|
||||||
okNowJump(ctx);
|
okNowJump(ctx);
|
||||||
@@ -74,12 +74,12 @@ void CodegenContext_SetJumpDest(CodegenContext *ctx, jmp_buf *env)
|
|||||||
}
|
}
|
||||||
|
|
||||||
CodegenContext *CodegenContext_New(Error *error, BPAlloc *alloc)
|
CodegenContext *CodegenContext_New(Error *error, BPAlloc *alloc)
|
||||||
{
|
{
|
||||||
bool own_alloc;
|
bool own_alloc;
|
||||||
if(alloc == NULL) {
|
if(alloc == NULL) {
|
||||||
alloc = BPAlloc_Init(-1);
|
alloc = BPAlloc_Init(-1);
|
||||||
if(alloc == NULL) {
|
if(alloc == NULL) {
|
||||||
Error_Report(error, 1, "No memory");
|
Error_Report(error, ErrorType_INTERNAL, "No memory");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
own_alloc = true;
|
own_alloc = true;
|
||||||
@@ -91,7 +91,7 @@ CodegenContext *CodegenContext_New(Error *error, BPAlloc *alloc)
|
|||||||
if(ctx == NULL) {
|
if(ctx == NULL) {
|
||||||
if(own_alloc)
|
if(own_alloc)
|
||||||
BPAlloc_Free(alloc);
|
BPAlloc_Free(alloc);
|
||||||
Error_Report(error, 1, "No memory");
|
Error_Report(error, ErrorType_INTERNAL, "No memory");
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -9,7 +9,7 @@ void CodegenContext_EmitInstr(CodegenContext *ctx, Opcode opcode, Ope
|
|||||||
void CodegenContext_SetJumpDest(CodegenContext *ctx, jmp_buf *env);
|
void CodegenContext_SetJumpDest(CodegenContext *ctx, jmp_buf *env);
|
||||||
void CodegenContext_Free(CodegenContext *ctx);
|
void CodegenContext_Free(CodegenContext *ctx);
|
||||||
Executable *CodegenContext_MakeExecutableAndFree(CodegenContext *ctx, Source *src);
|
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__)
|
#define CodegenContext_ReportErrorAndJump(ctx, int, fmt, ...) CodegenContext_ReportErrorAndJump_(ctx, __FILE__, __func__, __LINE__, int, fmt, ## __VA_ARGS__)
|
||||||
int CodegenContext_InstrCount(CodegenContext *ctx);
|
int CodegenContext_InstrCount(CodegenContext *ctx);
|
||||||
|
|
||||||
|
|||||||
@@ -5,15 +5,14 @@
|
|||||||
#include "codegen.h"
|
#include "codegen.h"
|
||||||
#include "compile.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.
|
// Create a bump-pointer allocator to hold the AST.
|
||||||
BPAlloc *alloc = BPAlloc_Init(-1);
|
BPAlloc *alloc = BPAlloc_Init(-1);
|
||||||
|
|
||||||
if(alloc == NULL)
|
if(alloc == NULL)
|
||||||
{
|
{
|
||||||
*errtyp = CompilationErrorType_INTERNAL;
|
Error_Report(error, ErrorType_INTERNAL, "No memory");
|
||||||
Error_Report(error, 1, "No memory");
|
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -24,10 +23,6 @@ Executable *compile(Source *src, Error *error, CompilationErrorType *errtyp)
|
|||||||
if(ast == NULL)
|
if(ast == NULL)
|
||||||
{
|
{
|
||||||
assert(error->occurred);
|
assert(error->occurred);
|
||||||
if(error->internal)
|
|
||||||
*errtyp = CompilationErrorType_INTERNAL;
|
|
||||||
else
|
|
||||||
*errtyp = CompilationErrorType_SYNTAX;
|
|
||||||
BPAlloc_Free(alloc);
|
BPAlloc_Free(alloc);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
@@ -41,10 +36,6 @@ Executable *compile(Source *src, Error *error, CompilationErrorType *errtyp)
|
|||||||
if(exe == NULL)
|
if(exe == NULL)
|
||||||
{
|
{
|
||||||
assert(error->occurred);
|
assert(error->occurred);
|
||||||
if(error->internal)
|
|
||||||
*errtyp = CompilationErrorType_INTERNAL;
|
|
||||||
else
|
|
||||||
*errtyp = CompilationErrorType_SEMANTIC;
|
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -3,10 +3,5 @@
|
|||||||
#include "../utils/error.h"
|
#include "../utils/error.h"
|
||||||
#include "../utils/source.h"
|
#include "../utils/source.h"
|
||||||
#include "../common/executable.h"
|
#include "../common/executable.h"
|
||||||
typedef enum {
|
Executable *compile(Source *src, Error *error);
|
||||||
CompilationErrorType_SYNTAX,
|
|
||||||
CompilationErrorType_SEMANTIC,
|
|
||||||
CompilationErrorType_INTERNAL,
|
|
||||||
} CompilationErrorType;
|
|
||||||
Executable *compile(Source *src, Error *error, CompilationErrorType *errtyp);
|
|
||||||
#endif /* COMPILE_H */
|
#endif /* COMPILE_H */
|
||||||
+93
-91
@@ -209,7 +209,7 @@ static Token *tokenize(Source *src, BPAlloc *alloc, Error *error)
|
|||||||
if(tok == NULL)
|
if(tok == NULL)
|
||||||
{
|
{
|
||||||
// Error: No memory.
|
// Error: No memory.
|
||||||
Error_Report(error, 1, "No memory");
|
Error_Report(error, ErrorType_INTERNAL, "No memory");
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -377,7 +377,7 @@ static Token *tokenize(Source *src, BPAlloc *alloc, Error *error)
|
|||||||
if(tok == NULL)
|
if(tok == NULL)
|
||||||
{
|
{
|
||||||
// Error: No memory.
|
// Error: No memory.
|
||||||
Error_Report(error, 1, "No memory");
|
Error_Report(error, ErrorType_INTERNAL, "No memory");
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -599,7 +599,7 @@ static Node *parse_statement(Context *ctx)
|
|||||||
|
|
||||||
if(current(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;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -609,7 +609,7 @@ static Node *parse_statement(Context *ctx)
|
|||||||
|
|
||||||
if(node == NULL)
|
if(node == NULL)
|
||||||
{
|
{
|
||||||
Error_Report(ctx->error, 1, "No memory");
|
Error_Report(ctx->error, ErrorType_INTERNAL, "No memory");
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -633,7 +633,9 @@ static Node *parse_statement(Context *ctx)
|
|||||||
|
|
||||||
if(current(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;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -643,7 +645,7 @@ static Node *parse_statement(Context *ctx)
|
|||||||
|
|
||||||
if(node == NULL)
|
if(node == NULL)
|
||||||
{
|
{
|
||||||
Error_Report(ctx->error, 1, "No memory");
|
Error_Report(ctx->error, ErrorType_INTERNAL, "No memory");
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -665,7 +667,7 @@ static Node *parse_statement(Context *ctx)
|
|||||||
return parse_dowhile_statement(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);
|
ctx->token->length, ctx->src + ctx->token->offset);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
@@ -681,7 +683,7 @@ static Node *parse_expression_statement(Context *ctx)
|
|||||||
|
|
||||||
if(done(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;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -690,7 +692,7 @@ static Node *parse_expression_statement(Context *ctx)
|
|||||||
// ERROR: Got something other than a semicolon at the end
|
// ERROR: Got something other than a semicolon at the end
|
||||||
// of statement.
|
// 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;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -713,7 +715,7 @@ static Node *makeStringExprNode(Context *ctx, const char *str, int len)
|
|||||||
|
|
||||||
if(copy == NULL)
|
if(copy == NULL)
|
||||||
{
|
{
|
||||||
Error_Report(ctx->error, 1, "No memory");
|
Error_Report(ctx->error, ErrorType_INTERNAL, "No memory");
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -728,7 +730,7 @@ static Node *makeStringExprNode(Context *ctx, const char *str, int len)
|
|||||||
|
|
||||||
if(node == NULL)
|
if(node == NULL)
|
||||||
{
|
{
|
||||||
Error_Report(ctx->error, 1, "No memory");
|
Error_Report(ctx->error, ErrorType_INTERNAL, "No memory");
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -750,13 +752,13 @@ static Node *parse_string_primary_expression(Context *ctx)
|
|||||||
|
|
||||||
if(done(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;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(current(ctx) != TSTRING)
|
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;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -782,7 +784,7 @@ static Node *parse_string_primary_expression(Context *ctx)
|
|||||||
|
|
||||||
if(temp_used + segm_len >= (int) sizeof(temp))
|
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;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -795,7 +797,7 @@ static Node *parse_string_primary_expression(Context *ctx)
|
|||||||
|
|
||||||
if(temp_used + 1 >= (int) sizeof(temp))
|
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;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -816,7 +818,7 @@ static Node *parse_string_primary_expression(Context *ctx)
|
|||||||
case '\'': temp[temp_used++] = '\''; break;
|
case '\'': temp[temp_used++] = '\''; break;
|
||||||
|
|
||||||
default:
|
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;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -841,13 +843,13 @@ static Node *parse_list_primary_expression(Context *ctx)
|
|||||||
|
|
||||||
if(done(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;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(current(ctx) != '[')
|
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;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -886,9 +888,9 @@ static Node *parse_list_primary_expression(Context *ctx)
|
|||||||
if(current(ctx) != ',')
|
if(current(ctx) != ',')
|
||||||
{
|
{
|
||||||
if(current(ctx) == TDONE)
|
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
|
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;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -908,7 +910,7 @@ static Node *parse_list_primary_expression(Context *ctx)
|
|||||||
|
|
||||||
if(list == NULL)
|
if(list == NULL)
|
||||||
{
|
{
|
||||||
Error_Report(ctx->error, 1, "No memory");
|
Error_Report(ctx->error, ErrorType_INTERNAL, "No memory");
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -931,14 +933,14 @@ static Node *parse_map_primary_expression(Context *ctx)
|
|||||||
|
|
||||||
if(done(ctx))
|
if(done(ctx))
|
||||||
{
|
{
|
||||||
Error_Report(ctx->error, 0,
|
Error_Report(ctx->error, ErrorType_SYNTAX,
|
||||||
"Source ended where a map literal was expected");
|
"Source ended where a map literal was expected");
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(current(ctx) != '{')
|
if(current(ctx) != '{')
|
||||||
{
|
{
|
||||||
Error_Report(ctx->error, 0,
|
Error_Report(ctx->error, ErrorType_SYNTAX,
|
||||||
"Got token \"%.*s\" where a map literal was expected",
|
"Got token \"%.*s\" where a map literal was expected",
|
||||||
ctx->token->length, ctx->src + ctx->token->offset);
|
ctx->token->length, ctx->src + ctx->token->offset);
|
||||||
return NULL;
|
return NULL;
|
||||||
@@ -954,7 +956,7 @@ static Node *parse_map_primary_expression(Context *ctx)
|
|||||||
|
|
||||||
if(done(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;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1005,7 +1007,7 @@ static Node *parse_map_primary_expression(Context *ctx)
|
|||||||
|
|
||||||
if(done(ctx))
|
if(done(ctx))
|
||||||
{
|
{
|
||||||
Error_Report(ctx->error, 0,
|
Error_Report(ctx->error, ErrorType_SYNTAX,
|
||||||
"Source ended where a map key-value "
|
"Source ended where a map key-value "
|
||||||
"separator ':' was expected");
|
"separator ':' was expected");
|
||||||
return NULL;
|
return NULL;
|
||||||
@@ -1013,7 +1015,7 @@ static Node *parse_map_primary_expression(Context *ctx)
|
|||||||
|
|
||||||
if(current(ctx) != ':')
|
if(current(ctx) != ':')
|
||||||
{
|
{
|
||||||
Error_Report(ctx->error, 0,
|
Error_Report(ctx->error, ErrorType_SYNTAX,
|
||||||
"Got token \"%.*s\" where a map key-value "
|
"Got token \"%.*s\" where a map key-value "
|
||||||
"separator ':' was expected",
|
"separator ':' was expected",
|
||||||
ctx->token->length,
|
ctx->token->length,
|
||||||
@@ -1053,9 +1055,9 @@ static Node *parse_map_primary_expression(Context *ctx)
|
|||||||
if(current(ctx) != ',')
|
if(current(ctx) != ',')
|
||||||
{
|
{
|
||||||
if(current(ctx) == TDONE)
|
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
|
else
|
||||||
Error_Report(ctx->error, 0,
|
Error_Report(ctx->error, ErrorType_SYNTAX,
|
||||||
"Got unexpected token \"%.*s\" inside "
|
"Got unexpected token \"%.*s\" inside "
|
||||||
"map literal, where ',' or '}' were expected",
|
"map literal, where ',' or '}' were expected",
|
||||||
ctx->token->length, ctx->src + ctx->token->offset);
|
ctx->token->length, ctx->src + ctx->token->offset);
|
||||||
@@ -1078,7 +1080,7 @@ static Node *parse_map_primary_expression(Context *ctx)
|
|||||||
|
|
||||||
if(map == NULL)
|
if(map == NULL)
|
||||||
{
|
{
|
||||||
Error_Report(ctx->error, 1, "No memory");
|
Error_Report(ctx->error, ErrorType_INTERNAL, "No memory");
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1117,7 +1119,7 @@ static Node *makeIdentExprNode(Context *ctx)
|
|||||||
|
|
||||||
if(copy == NULL)
|
if(copy == NULL)
|
||||||
{
|
{
|
||||||
Error_Report(ctx->error, 1, "No memory");
|
Error_Report(ctx->error, ErrorType_INTERNAL, "No memory");
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1127,7 +1129,7 @@ static Node *makeIdentExprNode(Context *ctx)
|
|||||||
|
|
||||||
if(node == NULL)
|
if(node == NULL)
|
||||||
{
|
{
|
||||||
Error_Report(ctx->error, 1, "No memory");
|
Error_Report(ctx->error, ErrorType_INTERNAL, "No memory");
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1149,7 +1151,7 @@ static Node *parse_primary_expresion(Context *ctx)
|
|||||||
|
|
||||||
if(done(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;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1173,13 +1175,13 @@ static Node *parse_primary_expresion(Context *ctx)
|
|||||||
|
|
||||||
if(done(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;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(current(ctx) != ')')
|
if(current(ctx) != ')')
|
||||||
{
|
{
|
||||||
Error_Report(ctx->error, 0, "Missing \")\", after sub-expression");
|
Error_Report(ctx->error, ErrorType_SYNTAX, "Missing \")\", after sub-expression");
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
next(ctx); // Consume the ')'.
|
next(ctx); // Consume the ')'.
|
||||||
@@ -1192,7 +1194,7 @@ static Node *parse_primary_expresion(Context *ctx)
|
|||||||
|
|
||||||
if(ctx->token->length >= (int) sizeof(buffer))
|
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;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1205,7 +1207,7 @@ static Node *parse_primary_expresion(Context *ctx)
|
|||||||
|
|
||||||
if(errno == ERANGE)
|
if(errno == ERANGE)
|
||||||
{
|
{
|
||||||
Error_Report(ctx->error, 1, "Integer is too big");
|
Error_Report(ctx->error, ErrorType_INTERNAL, "Integer is too big");
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
else assert(errno == 0);
|
else assert(errno == 0);
|
||||||
@@ -1216,7 +1218,7 @@ static Node *parse_primary_expresion(Context *ctx)
|
|||||||
|
|
||||||
if(node == NULL)
|
if(node == NULL)
|
||||||
{
|
{
|
||||||
Error_Report(ctx->error, 1, "No memory");
|
Error_Report(ctx->error, ErrorType_INTERNAL, "No memory");
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1239,7 +1241,7 @@ static Node *parse_primary_expresion(Context *ctx)
|
|||||||
|
|
||||||
if(ctx->token->length >= (int) sizeof(buffer))
|
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;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1252,7 +1254,7 @@ static Node *parse_primary_expresion(Context *ctx)
|
|||||||
|
|
||||||
if(errno == ERANGE)
|
if(errno == ERANGE)
|
||||||
{
|
{
|
||||||
Error_Report(ctx->error, 1, "Floating is too big");
|
Error_Report(ctx->error, ErrorType_INTERNAL, "Floating is too big");
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
else assert(errno == 0);
|
else assert(errno == 0);
|
||||||
@@ -1263,7 +1265,7 @@ static Node *parse_primary_expresion(Context *ctx)
|
|||||||
|
|
||||||
if(node == NULL)
|
if(node == NULL)
|
||||||
{
|
{
|
||||||
Error_Report(ctx->error, 1, "No memory");
|
Error_Report(ctx->error, ErrorType_INTERNAL, "No memory");
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1293,7 +1295,7 @@ static Node *parse_primary_expresion(Context *ctx)
|
|||||||
|
|
||||||
if(node == NULL)
|
if(node == NULL)
|
||||||
{
|
{
|
||||||
Error_Report(ctx->error, 1, "No memory");
|
Error_Report(ctx->error, ErrorType_INTERNAL, "No memory");
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1317,7 +1319,7 @@ static Node *parse_primary_expresion(Context *ctx)
|
|||||||
|
|
||||||
if(node == NULL)
|
if(node == NULL)
|
||||||
{
|
{
|
||||||
Error_Report(ctx->error, 1, "No memory");
|
Error_Report(ctx->error, ErrorType_INTERNAL, "No memory");
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1341,7 +1343,7 @@ static Node *parse_primary_expresion(Context *ctx)
|
|||||||
|
|
||||||
if(node == NULL)
|
if(node == NULL)
|
||||||
{
|
{
|
||||||
Error_Report(ctx->error, 1, "No memory");
|
Error_Report(ctx->error, ErrorType_INTERNAL, "No memory");
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1367,11 +1369,11 @@ static Node *parse_primary_expresion(Context *ctx)
|
|||||||
}
|
}
|
||||||
|
|
||||||
case TDONE:
|
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;
|
return NULL;
|
||||||
|
|
||||||
default:
|
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;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1385,7 +1387,7 @@ static Node *makeIndexOrArrowSelectionExprNode(Context *ctx, bool arrow, Node *s
|
|||||||
|
|
||||||
if(sel == NULL)
|
if(sel == NULL)
|
||||||
{
|
{
|
||||||
Error_Report(ctx->error, 1, "No memory");
|
Error_Report(ctx->error, ErrorType_INTERNAL, "No memory");
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1423,13 +1425,13 @@ static Node *parse_postfix_expression(Context *ctx)
|
|||||||
|
|
||||||
if(done(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;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(current(ctx) != TIDENT)
|
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;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1460,7 +1462,7 @@ static Node *parse_postfix_expression(Context *ctx)
|
|||||||
|
|
||||||
if(ls->itemc == 0)
|
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;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1506,9 +1508,9 @@ static Node *parse_postfix_expression(Context *ctx)
|
|||||||
if(current(ctx) != ',')
|
if(current(ctx) != ',')
|
||||||
{
|
{
|
||||||
if(current(ctx) == TDONE)
|
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
|
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;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1527,7 +1529,7 @@ static Node *parse_postfix_expression(Context *ctx)
|
|||||||
|
|
||||||
if(call == NULL)
|
if(call == NULL)
|
||||||
{
|
{
|
||||||
Error_Report(ctx->error, 1, "No memory");
|
Error_Report(ctx->error, ErrorType_INTERNAL, "No memory");
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1557,14 +1559,14 @@ static Node *parse_prefix_expression(Context *ctx)
|
|||||||
{
|
{
|
||||||
if(done(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;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
switch(current(ctx))
|
switch(current(ctx))
|
||||||
{
|
{
|
||||||
case TDONE:
|
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;
|
return NULL;
|
||||||
|
|
||||||
case '+':
|
case '+':
|
||||||
@@ -1714,7 +1716,7 @@ static Node *parse_expression_2(Context *ctx, Node *left_expr, int min_prec, _Bo
|
|||||||
|
|
||||||
if(temp == NULL)
|
if(temp == NULL)
|
||||||
{
|
{
|
||||||
Error_Report(ctx->error, 1, "No memory");
|
Error_Report(ctx->error, ErrorType_INTERNAL, "No memory");
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1777,13 +1779,13 @@ static Node *parse_ifelse_statement(Context *ctx)
|
|||||||
|
|
||||||
if(done(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;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(current(ctx) != TKWIF)
|
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;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1799,13 +1801,13 @@ static Node *parse_ifelse_statement(Context *ctx)
|
|||||||
|
|
||||||
if(done(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;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(current(ctx) != ':')
|
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;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1835,7 +1837,7 @@ static Node *parse_ifelse_statement(Context *ctx)
|
|||||||
if(ifelse == NULL)
|
if(ifelse == NULL)
|
||||||
{
|
{
|
||||||
// ERROR: No memory.
|
// ERROR: No memory.
|
||||||
Error_Report(ctx->error, 1, "No memory");
|
Error_Report(ctx->error, ErrorType_INTERNAL, "No memory");
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1874,7 +1876,7 @@ static Node *parse_compound_statement(Context *ctx, TokenKind end)
|
|||||||
|
|
||||||
if(current(ctx) != 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;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1885,7 +1887,7 @@ static Node *parse_compound_statement(Context *ctx, TokenKind end)
|
|||||||
if(node == NULL)
|
if(node == NULL)
|
||||||
{
|
{
|
||||||
// ERROR: No memory.
|
// ERROR: No memory.
|
||||||
Error_Report(ctx->error, 1, "No memory");
|
Error_Report(ctx->error, ErrorType_INTERNAL, "No memory");
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1906,9 +1908,9 @@ static _Bool parse_function_arguments(Context *ctx, int *argc_, Node **argv_)
|
|||||||
if(next(ctx) != '(')
|
if(next(ctx) != '(')
|
||||||
{
|
{
|
||||||
if(done(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
|
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;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1923,13 +1925,13 @@ static _Bool parse_function_arguments(Context *ctx, int *argc_, Node **argv_)
|
|||||||
{
|
{
|
||||||
if(done(ctx))
|
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;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(current(ctx) != TIDENT)
|
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;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1937,7 +1939,7 @@ static _Bool parse_function_arguments(Context *ctx, int *argc_, Node **argv_)
|
|||||||
|
|
||||||
if(arg_name == NULL)
|
if(arg_name == NULL)
|
||||||
{
|
{
|
||||||
Error_Report(ctx->error, 1, "No memory");
|
Error_Report(ctx->error, ErrorType_INTERNAL, "No memory");
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1966,7 +1968,7 @@ static _Bool parse_function_arguments(Context *ctx, int *argc_, Node **argv_)
|
|||||||
|
|
||||||
if(arg == NULL)
|
if(arg == NULL)
|
||||||
{
|
{
|
||||||
Error_Report(ctx->error, 1, "No memory");
|
Error_Report(ctx->error, ErrorType_INTERNAL, "No memory");
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1988,7 +1990,7 @@ static _Bool parse_function_arguments(Context *ctx, int *argc_, Node **argv_)
|
|||||||
|
|
||||||
if(done(ctx))
|
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;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1997,7 +1999,7 @@ static _Bool parse_function_arguments(Context *ctx, int *argc_, Node **argv_)
|
|||||||
|
|
||||||
if(current(ctx) != ',')
|
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;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -2019,13 +2021,13 @@ static FuncDeclNode *parse_function_definition(Context *ctx)
|
|||||||
|
|
||||||
if(done(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;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(current(ctx) != TKWFUN)
|
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;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -2034,16 +2036,16 @@ static FuncDeclNode *parse_function_definition(Context *ctx)
|
|||||||
if(next(ctx) != TIDENT)
|
if(next(ctx) != TIDENT)
|
||||||
{
|
{
|
||||||
if(done(ctx))
|
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
|
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;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
char *name_val = copy_token_text(ctx);
|
char *name_val = copy_token_text(ctx);
|
||||||
if(name_val == NULL)
|
if(name_val == NULL)
|
||||||
{
|
{
|
||||||
Error_Report(ctx->error, 1, "No memory");
|
Error_Report(ctx->error, ErrorType_INTERNAL, "No memory");
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
int name_len = strlen(name_val);
|
int name_len = strlen(name_val);
|
||||||
@@ -2057,7 +2059,7 @@ static FuncDeclNode *parse_function_definition(Context *ctx)
|
|||||||
|
|
||||||
if(done(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;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -2075,7 +2077,7 @@ static FuncDeclNode *parse_function_definition(Context *ctx)
|
|||||||
FuncExprNode *expr = BPAlloc_Malloc(ctx->alloc, sizeof(FuncExprNode));
|
FuncExprNode *expr = BPAlloc_Malloc(ctx->alloc, sizeof(FuncExprNode));
|
||||||
if (expr == NULL)
|
if (expr == NULL)
|
||||||
{
|
{
|
||||||
Error_Report(ctx->error, 1, "No memory");
|
Error_Report(ctx->error, ErrorType_INTERNAL, "No memory");
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
expr->base.base.kind = NODE_EXPR;
|
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));
|
StringExprNode *name = BPAlloc_Malloc(ctx->alloc, sizeof(StringExprNode));
|
||||||
if (name == NULL)
|
if (name == NULL)
|
||||||
{
|
{
|
||||||
Error_Report(ctx->error, 1, "No memory");
|
Error_Report(ctx->error, ErrorType_INTERNAL, "No memory");
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
name->base.base.kind = NODE_EXPR;
|
name->base.base.kind = NODE_EXPR;
|
||||||
@@ -2104,7 +2106,7 @@ static FuncDeclNode *parse_function_definition(Context *ctx)
|
|||||||
func = BPAlloc_Malloc(ctx->alloc, sizeof(FuncDeclNode));
|
func = BPAlloc_Malloc(ctx->alloc, sizeof(FuncDeclNode));
|
||||||
if(func == NULL)
|
if(func == NULL)
|
||||||
{
|
{
|
||||||
Error_Report(ctx->error, 1, "No memory");
|
Error_Report(ctx->error, ErrorType_INTERNAL, "No memory");
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
func->base.kind = NODE_FUNC;
|
func->base.kind = NODE_FUNC;
|
||||||
@@ -2124,13 +2126,13 @@ static Node *parse_while_statement(Context *ctx)
|
|||||||
|
|
||||||
if(done(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;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(current(ctx) != TKWWHILE)
|
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;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -2146,13 +2148,13 @@ static Node *parse_while_statement(Context *ctx)
|
|||||||
|
|
||||||
if(done(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;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(current(ctx) != ':')
|
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;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -2170,7 +2172,7 @@ static Node *parse_while_statement(Context *ctx)
|
|||||||
if(whl == NULL)
|
if(whl == NULL)
|
||||||
{
|
{
|
||||||
// ERROR: No memory.
|
// ERROR: No memory.
|
||||||
Error_Report(ctx->error, 1, "No memory");
|
Error_Report(ctx->error, ErrorType_INTERNAL, "No memory");
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -2191,13 +2193,13 @@ static Node *parse_dowhile_statement(Context *ctx)
|
|||||||
|
|
||||||
if(done(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;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(current(ctx) != TKWDO)
|
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;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -2213,13 +2215,13 @@ static Node *parse_dowhile_statement(Context *ctx)
|
|||||||
|
|
||||||
if(done(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;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(current(ctx) != TKWWHILE)
|
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;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -2232,13 +2234,13 @@ static Node *parse_dowhile_statement(Context *ctx)
|
|||||||
|
|
||||||
if(done(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;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(current(ctx) != ';')
|
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;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -2251,7 +2253,7 @@ static Node *parse_dowhile_statement(Context *ctx)
|
|||||||
if(dowhl == NULL)
|
if(dowhl == NULL)
|
||||||
{
|
{
|
||||||
// ERROR: No memory.
|
// ERROR: No memory.
|
||||||
Error_Report(ctx->error, 1, "No memory");
|
Error_Report(ctx->error, ErrorType_INTERNAL, "No memory");
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+69
-107
@@ -8,41 +8,48 @@
|
|||||||
#include "runtime/timing.h"
|
#include "runtime/timing.h"
|
||||||
#include "noja.h"
|
#include "noja.h"
|
||||||
|
|
||||||
static void print_error(const char *type, Error *error)
|
static void serializeProfilingResults(Runtime *runtime, const char *file)
|
||||||
{
|
{
|
||||||
if(type == NULL)
|
TimingTable *table = Runtime_GetTimingTable(runtime);
|
||||||
fprintf(stderr, "Error");
|
if (table == NULL)
|
||||||
else if(error->internal)
|
return;
|
||||||
fprintf(stderr, "Internal Error");
|
|
||||||
else
|
|
||||||
fprintf(stderr, "%s Error", type);
|
|
||||||
|
|
||||||
fprintf(stderr, ": %s.", error->message);
|
FILE *stream = fopen(file, "wb");
|
||||||
|
if (stream == NULL) {
|
||||||
#ifdef DEBUG
|
fprintf(stderr, "Failed to serialize profiling results\n");
|
||||||
if(error->file != NULL)
|
return;
|
||||||
{
|
|
||||||
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
|
|
||||||
|
const FunctionExecutionSummary *summary;
|
||||||
fprintf(stderr, "\n");
|
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 <signal.h>
|
#include <signal.h>
|
||||||
|
|
||||||
Runtime *runt = NULL;
|
Runtime *runtime = NULL;
|
||||||
|
|
||||||
static void signalHandler(int signo)
|
static void signalHandler(int signo)
|
||||||
{
|
{
|
||||||
(void) signo;
|
(void) signo;
|
||||||
if (runt != NULL)
|
if (runtime != NULL)
|
||||||
Runtime_Interrupt(runt);
|
Runtime_Interrupt(runtime);
|
||||||
}
|
}
|
||||||
|
|
||||||
static _Bool interpret(Executable *exe, bool time, size_t heap)
|
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();
|
RuntimeConfig config = Runtime_GetDefaultConfigs();
|
||||||
config.time = time;
|
config.time = time;
|
||||||
|
|
||||||
runt = Runtime_New(heap, config);
|
runtime = Runtime_New(heap, config);
|
||||||
if(runt == NULL)
|
if(runtime == NULL)
|
||||||
{
|
{
|
||||||
Error error;
|
Error error;
|
||||||
Error_Init(&error);
|
Error_Init(&error);
|
||||||
Error_Report(&error, 1, "Couldn't initialize runtime");
|
Error_Report(&error, ErrorType_INTERNAL, "Couldn't initialize runtime");
|
||||||
print_error(NULL, &error);
|
Error_Print(&error, ErrorType_UNSPECIFIED);
|
||||||
Error_Free(&error);
|
Error_Free(&error);
|
||||||
return 0;
|
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]
|
// expects a pointer to [Error] can receive a [RuntimeError]
|
||||||
// upcasted to [Error].
|
// upcasted to [Error].
|
||||||
RuntimeError 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)
|
if(native_bins == NULL)
|
||||||
{
|
{
|
||||||
assert(error.base.occurred == 1);
|
assert(error.base.occurred == 1);
|
||||||
print_error(NULL, (Error*) &error);
|
Error_Print((Error*) &error, ErrorType_RUNTIME);
|
||||||
RuntimeError_Free(&error);
|
RuntimeError_Free(&error);
|
||||||
Runtime_Free(runt);
|
Runtime_Free(runtime);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Just to execute the prelude
|
// Just to execute the prelude
|
||||||
Runtime_SetBuiltins(runt, native_bins);
|
Runtime_SetBuiltins(runtime, native_bins);
|
||||||
|
|
||||||
extern char start_noja[];
|
extern char start_noja[];
|
||||||
Source *prelude = Source_FromString("<prelude>", start_noja, -1, (Error*) &error);
|
Source *prelude = Source_FromString("<prelude>", start_noja, -1, (Error*) &error);
|
||||||
if (prelude == NULL) {
|
if (prelude == NULL) {
|
||||||
assert(error.base.occurred == 1);
|
assert(error.base.occurred == 1);
|
||||||
print_error(NULL, (Error*) &error);
|
Error_Print((Error*) &error, ErrorType_RUNTIME);
|
||||||
RuntimeError_Free(&error);
|
RuntimeError_Free(&error);
|
||||||
Runtime_Free(runt);
|
Runtime_Free(runtime);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
CompilationErrorType errtyp;
|
Executable *prelude_exe = compile(prelude, (Error*) &error);
|
||||||
Executable *prelude_exe = compile(prelude, (Error*) &error, &errtyp);
|
|
||||||
if(prelude_exe == NULL) {
|
if(prelude_exe == NULL) {
|
||||||
const char *errname;
|
Error_Print((Error*) &error, ErrorType_RUNTIME);
|
||||||
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);
|
RuntimeError_Free(&error);
|
||||||
Runtime_Free(runt);
|
Runtime_Free(runtime);
|
||||||
Source_Free(prelude);
|
Source_Free(prelude);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
Object *rets[8];
|
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) {
|
if(retc < 0) {
|
||||||
print_error("Runtime", (Error*) &error);
|
Error_Print((Error*) &error, ErrorType_RUNTIME);
|
||||||
RuntimeError_Free(&error);
|
RuntimeError_Free(&error);
|
||||||
Runtime_Free(runt);
|
Runtime_Free(runtime);
|
||||||
Source_Free(prelude);
|
Source_Free(prelude);
|
||||||
Executable_Free(prelude_exe);
|
Executable_Free(prelude_exe);
|
||||||
return 0;
|
return 0;
|
||||||
@@ -128,43 +127,43 @@ static _Bool interpret(Executable *exe, bool time, size_t heap)
|
|||||||
// Need to remake the native built-ins because
|
// Need to remake the native built-ins because
|
||||||
// running the script invalidated the previous
|
// running the script invalidated the previous
|
||||||
// pointer.
|
// 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)
|
if(native_bins == NULL)
|
||||||
{
|
{
|
||||||
assert(error.base.occurred == 1);
|
assert(error.base.occurred == 1);
|
||||||
print_error(NULL, (Error*) &error);
|
Error_Print((Error*) &error, ErrorType_RUNTIME);
|
||||||
RuntimeError_Free(&error);
|
RuntimeError_Free(&error);
|
||||||
Runtime_Free(runt);
|
Runtime_Free(runtime);
|
||||||
Source_Free(prelude);
|
Source_Free(prelude);
|
||||||
Executable_Free(prelude_exe);
|
Executable_Free(prelude_exe);
|
||||||
return 0;
|
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) {
|
if (all_bins == NULL) {
|
||||||
print_error(NULL, (Error*) &error);
|
Error_Print((Error*) &error, ErrorType_RUNTIME);
|
||||||
RuntimeError_Free(&error);
|
RuntimeError_Free(&error);
|
||||||
Runtime_Free(runt);
|
Runtime_Free(runtime);
|
||||||
Source_Free(prelude);
|
Source_Free(prelude);
|
||||||
Executable_Free(prelude_exe);
|
Executable_Free(prelude_exe);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
Runtime_SetBuiltins(runt, all_bins);
|
Runtime_SetBuiltins(runtime, all_bins);
|
||||||
|
|
||||||
Source_Free(prelude);
|
Source_Free(prelude);
|
||||||
Executable_Free(prelude_exe);
|
Executable_Free(prelude_exe);
|
||||||
}
|
}
|
||||||
|
|
||||||
Object *rets[8];
|
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
|
// NOTE: The pointer to the builtins object is invalidated
|
||||||
// now because it may be moved by the garbage collector.
|
// now because it may be moved by the garbage collector.
|
||||||
|
|
||||||
if(retc < 0)
|
if(retc < 0)
|
||||||
{
|
{
|
||||||
print_error("Runtime", (Error*) &error);
|
Error_Print((Error*) &error, ErrorType_RUNTIME);
|
||||||
|
|
||||||
if(error.snapshot == NULL)
|
if(error.snapshot == NULL)
|
||||||
fprintf(stderr, "No snapshot available.\n");
|
fprintf(stderr, "No snapshot available.\n");
|
||||||
@@ -174,38 +173,9 @@ static _Bool interpret(Executable *exe, bool time, size_t heap)
|
|||||||
RuntimeError_Free(&error);
|
RuntimeError_Free(&error);
|
||||||
}
|
}
|
||||||
|
|
||||||
TimingTable *table = Runtime_GetTimingTable(runt);
|
serializeProfilingResults(runtime, "profiling-results.txt");
|
||||||
if (table != NULL) {
|
|
||||||
|
|
||||||
const char *file = "profiling-results.txt";
|
Runtime_Free(runtime);
|
||||||
|
|
||||||
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);
|
|
||||||
return retc > -1;
|
return retc > -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -213,17 +183,9 @@ static Executable *compile_source_and_print_error_on_failure(Source *src)
|
|||||||
{
|
{
|
||||||
Error error;
|
Error error;
|
||||||
Error_Init(&error);
|
Error_Init(&error);
|
||||||
CompilationErrorType errtyp;
|
Executable *exe = compile(src, &error);
|
||||||
Executable *exe = compile(src, &error, &errtyp);
|
|
||||||
if(exe == NULL) {
|
if(exe == NULL) {
|
||||||
const char *errname;
|
Error_Print(&error, ErrorType_UNSPECIFIED);
|
||||||
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_Free(&error);
|
Error_Free(&error);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
@@ -249,7 +211,7 @@ static _Bool interpret_file(const char *file, bool time, size_t heap)
|
|||||||
if(src == NULL)
|
if(src == NULL)
|
||||||
{
|
{
|
||||||
assert(error.occurred == 1);
|
assert(error.occurred == 1);
|
||||||
print_error(NULL, &error);
|
Error_Print(&error, ErrorType_UNSPECIFIED);
|
||||||
Error_Free(&error);
|
Error_Free(&error);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@@ -277,7 +239,7 @@ static _Bool interpret_code(const char *code, bool time, size_t heap)
|
|||||||
if(src == NULL)
|
if(src == NULL)
|
||||||
{
|
{
|
||||||
assert(error.occurred);
|
assert(error.occurred);
|
||||||
print_error(NULL, &error);
|
Error_Print(&error, ErrorType_UNSPECIFIED);
|
||||||
Error_Free(&error);
|
Error_Free(&error);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@@ -305,14 +267,14 @@ static _Bool interpret_asm_file(const char *file, bool time, size_t heap)
|
|||||||
if(src == NULL)
|
if(src == NULL)
|
||||||
{
|
{
|
||||||
assert(error.occurred == 1);
|
assert(error.occurred == 1);
|
||||||
print_error(NULL, &error);
|
Error_Print(&error, ErrorType_UNSPECIFIED);
|
||||||
Error_Free(&error);
|
Error_Free(&error);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
Executable *exe = assemble(src, &error);
|
Executable *exe = assemble(src, &error);
|
||||||
if(exe == NULL) {
|
if(exe == NULL) {
|
||||||
print_error("Assemblation", &error);
|
Error_Print(&error, ErrorType_UNSPECIFIED);
|
||||||
Source_Free(src);
|
Source_Free(src);
|
||||||
Error_Free(&error);
|
Error_Free(&error);
|
||||||
return 0;
|
return 0;
|
||||||
@@ -336,14 +298,14 @@ static _Bool interpret_asm_code(const char *code, bool time, size_t heap)
|
|||||||
if(src == NULL)
|
if(src == NULL)
|
||||||
{
|
{
|
||||||
assert(error.occurred);
|
assert(error.occurred);
|
||||||
print_error(NULL, &error);
|
Error_Print(&error, ErrorType_UNSPECIFIED);
|
||||||
Error_Free(&error);
|
Error_Free(&error);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
Executable *exe = assemble(src, &error);
|
Executable *exe = assemble(src, &error);
|
||||||
if(exe == NULL) {
|
if(exe == NULL) {
|
||||||
print_error("Assemblation", &error);
|
Error_Print(&error, ErrorType_UNSPECIFIED);
|
||||||
Source_Free(src);
|
Source_Free(src);
|
||||||
Error_Free(&error);
|
Error_Free(&error);
|
||||||
return 0;
|
return 0;
|
||||||
@@ -367,7 +329,7 @@ static _Bool disassemble_file(const char *file)
|
|||||||
if(src == NULL)
|
if(src == NULL)
|
||||||
{
|
{
|
||||||
assert(error.occurred == 1);
|
assert(error.occurred == 1);
|
||||||
print_error(NULL, &error);
|
Error_Print(&error, ErrorType_UNSPECIFIED);
|
||||||
Error_Free(&error);
|
Error_Free(&error);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@@ -388,7 +350,7 @@ static _Bool disassemble_code(const char *code)
|
|||||||
if(src == NULL)
|
if(src == NULL)
|
||||||
{
|
{
|
||||||
assert(error.occurred);
|
assert(error.occurred);
|
||||||
print_error(NULL, &error);
|
Error_Print(&error, ErrorType_UNSPECIFIED);
|
||||||
Error_Free(&error);
|
Error_Free(&error);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -222,7 +222,7 @@ void *Heap_Malloc(Heap *heap, TypeObject *type, Error *err)
|
|||||||
|
|
||||||
if(heap->pend == NULL)
|
if(heap->pend == NULL)
|
||||||
{
|
{
|
||||||
Error_Report(err, 1, "No memory");
|
Error_Report(err, ErrorType_INTERNAL, "No memory");
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -237,7 +237,7 @@ void *Heap_Malloc(Heap *heap, TypeObject *type, Error *err)
|
|||||||
|
|
||||||
if(new_pend == NULL)
|
if(new_pend == NULL)
|
||||||
{
|
{
|
||||||
Error_Report(err, 1, "No memory");
|
Error_Report(err, ErrorType_INTERNAL, "No memory");
|
||||||
return NULL;
|
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->pend[heap->pend_used++] = (PendingDestruct) { .object = obj, .destructor = obj->type->free };
|
||||||
|
|
||||||
heap->objcount += 1;
|
heap->objcount += 1;
|
||||||
|
|
||||||
return (Object*) addr;
|
return (Object*) addr;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -296,7 +296,7 @@ void *Heap_RawMalloc(Heap *heap, int size, Error *err)
|
|||||||
{
|
{
|
||||||
if(heap->collecting)
|
if(heap->collecting)
|
||||||
{
|
{
|
||||||
Error_Report(err, 1, "Out of heap");
|
Error_Report(err, ErrorType_INTERNAL, "Out of heap");
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -336,7 +336,7 @@ _Bool Heap_StartCollection(Heap *heap, Error *error)
|
|||||||
|
|
||||||
if(new_body == NULL)
|
if(new_body == NULL)
|
||||||
{
|
{
|
||||||
Error_Report(error, 1, "No memory");
|
Error_Report(error, ErrorType_INTERNAL, "No memory");
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+10
-10
@@ -96,7 +96,7 @@ Object *Object_NewBuffer(size_t size, Heap *heap, Error *error)
|
|||||||
Payload *payload = malloc(sizeof(Payload) + size);
|
Payload *payload = malloc(sizeof(Payload) + size);
|
||||||
if(payload == NULL)
|
if(payload == NULL)
|
||||||
{
|
{
|
||||||
Error_Report(error, 1, "No memory");
|
Error_Report(error, ErrorType_INTERNAL, "No memory");
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
payload->refs = 1;
|
payload->refs = 1;
|
||||||
@@ -134,19 +134,19 @@ Object *Object_SliceBuffer(Object *obj, size_t offset, size_t length, Heap *heap
|
|||||||
{
|
{
|
||||||
if(!Object_IsBuffer(obj))
|
if(!Object_IsBuffer(obj))
|
||||||
{
|
{
|
||||||
Error_Report(error, 0, "Not a " TYPENAME_BUFFER);
|
Error_Report(error, ErrorType_RUNTIME, "Not a " TYPENAME_BUFFER);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
Payload *payload = ((BufferObject*) obj)->payload;
|
Payload *payload = ((BufferObject*) obj)->payload;
|
||||||
|
|
||||||
if(offset >= payload->size) {
|
if(offset >= payload->size) {
|
||||||
Error_Report(error, 0, "Offset out of range");
|
Error_Report(error, ErrorType_RUNTIME, "Offset out of range");
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(offset + length > payload->size) {
|
if(offset + length > payload->size) {
|
||||||
Error_Report(error, 0, "Length out of range");
|
Error_Report(error, ErrorType_RUNTIME, "Length out of range");
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -187,7 +187,7 @@ static Object *buffer_select(Object *self, Object *key, Heap *heap, Error *error
|
|||||||
|
|
||||||
if(!Object_IsInt(key))
|
if(!Object_IsInt(key))
|
||||||
{
|
{
|
||||||
Error_Report(error, 0, "Non integer key");
|
Error_Report(error, ErrorType_RUNTIME, "Non integer key");
|
||||||
return NULL;
|
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)
|
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;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -222,24 +222,24 @@ static _Bool buffer_insert(Object *self, Object *key, Object *val, Heap *heap, E
|
|||||||
|
|
||||||
if(!Object_IsInt(key))
|
if(!Object_IsInt(key))
|
||||||
{
|
{
|
||||||
Error_Report(error, 0, "Non integer key");
|
Error_Report(error, ErrorType_RUNTIME, "Non integer key");
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
if(!Object_IsInt(val))
|
if(!Object_IsInt(val))
|
||||||
{
|
{
|
||||||
Error_Report(error, 0, "Non integer value");
|
Error_Report(error, ErrorType_RUNTIME, "Non integer value");
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
int idx = Object_GetInt(key);
|
int idx = Object_GetInt(key);
|
||||||
long long int qword = Object_GetInt(val);
|
long long int qword = Object_GetInt(val);
|
||||||
if(idx < 0 || (size_t) idx >= buffer->length)
|
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;
|
return NULL;
|
||||||
}
|
}
|
||||||
if(qword > 255 || qword < 0)
|
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;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -86,6 +86,6 @@ static _Bool dir_free(Object *obj, Error *error)
|
|||||||
if(closedir(dob->dir) == 0)
|
if(closedir(dob->dir) == 0)
|
||||||
return 1;
|
return 1;
|
||||||
|
|
||||||
Error_Report(error, 0, "Failed to close directory");
|
Error_Report(error, ErrorType_RUNTIME, "Failed to close directory");
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@@ -85,6 +85,6 @@ static _Bool file_free(Object *self, Error *error)
|
|||||||
if(fclose(fob->fp) == 0)
|
if(fclose(fob->fp) == 0)
|
||||||
return 1;
|
return 1;
|
||||||
|
|
||||||
Error_Report(error, 0, "Failed to close stream");
|
Error_Report(error, ErrorType_RUNTIME, "Failed to close stream");
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@@ -212,7 +212,7 @@ static Object *select_(Object *self, Object *key, Heap *heap, Error *error)
|
|||||||
|
|
||||||
if(!Object_IsInt(key))
|
if(!Object_IsInt(key))
|
||||||
{
|
{
|
||||||
Error_Report(error, 0, "Non integer key");
|
Error_Report(error, ErrorType_RUNTIME, "Non integer key");
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -222,7 +222,7 @@ static Object *select_(Object *self, Object *key, Heap *heap, Error *error)
|
|||||||
|
|
||||||
if(idx < 0 || idx >= list->count)
|
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;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -266,7 +266,7 @@ static _Bool insert(Object *self, Object *key, Object *val, Heap *heap, Error *e
|
|||||||
|
|
||||||
if(!Object_IsInt(key))
|
if(!Object_IsInt(key))
|
||||||
{
|
{
|
||||||
Error_Report(error, 0, "Non integer key");
|
Error_Report(error, ErrorType_RUNTIME, "Non integer key");
|
||||||
return NULL;
|
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)
|
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;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -96,7 +96,7 @@ static Object *select_(Object *self, Object *key, Heap *heap, Error *error)
|
|||||||
|
|
||||||
if(!Object_IsInt(key))
|
if(!Object_IsInt(key))
|
||||||
{
|
{
|
||||||
Error_Report(error, 0, "Non integer key");
|
Error_Report(error, ErrorType_RUNTIME, "Non integer key");
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
int idx = Object_GetInt(key);
|
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)
|
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;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -147,7 +147,7 @@ Object *Object_FromString(const char *str, int len, Heap *heap, Error *error)
|
|||||||
|
|
||||||
if(count < 0)
|
if(count < 0)
|
||||||
{
|
{
|
||||||
Error_Report(error, 0, "Invalid UTF-8 sequence");
|
Error_Report(error, ErrorType_RUNTIME, "Invalid UTF-8 sequence");
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -123,7 +123,7 @@ Object *Object_Copy(Object *obj, Heap *heap, Error *err)
|
|||||||
|
|
||||||
if(type->copy == NULL)
|
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;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -139,7 +139,7 @@ int Object_Call(Object *obj, Object **argv, unsigned int argc, Object *rets[stat
|
|||||||
|
|
||||||
if(type->call == NULL)
|
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;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -179,7 +179,7 @@ Object *Object_Select(Object *coll, Object *key, Heap *heap, Error *err)
|
|||||||
|
|
||||||
if(type->select == NULL)
|
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;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -197,7 +197,7 @@ Object *Object_Delete(Object *coll, Object *key, Heap *heap, Error *err)
|
|||||||
|
|
||||||
if(type->delete == NULL)
|
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;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -215,7 +215,7 @@ _Bool Object_Insert(Object *coll, Object *key, Object *val, Heap *heap, Error *e
|
|||||||
|
|
||||||
if(type->insert == NULL)
|
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;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -232,7 +232,7 @@ int Object_Count(Object *coll, Error *err)
|
|||||||
|
|
||||||
if(type->count == NULL)
|
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;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -91,7 +91,7 @@ static int call(Object *self, Object **argv, unsigned int argc, Object *rets[sta
|
|||||||
|
|
||||||
if(argv2 == NULL)
|
if(argv2 == NULL)
|
||||||
{
|
{
|
||||||
Error_Report(error, 1, "No memory");
|
Error_Report(error, ErrorType_INTERNAL, "No memory");
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -197,7 +197,7 @@ Object *Object_FromNojaFunction(Runtime *runtime, const char *name, Executable *
|
|||||||
|
|
||||||
if(exe_copy == NULL)
|
if(exe_copy == NULL)
|
||||||
{
|
{
|
||||||
Error_Report(error, 1, "Failed to copy executable");
|
Error_Report(error, ErrorType_INTERNAL, "Failed to copy executable");
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+39
-39
@@ -250,7 +250,7 @@ _Bool Runtime_Push(Runtime *runtime, Error *error, Object *obj)
|
|||||||
|
|
||||||
if(runtime->depth == 0)
|
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;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -258,13 +258,13 @@ _Bool Runtime_Push(Runtime *runtime, Error *error, Object *obj)
|
|||||||
|
|
||||||
if(runtime->frame->used == MAX_FRAME_STACK)
|
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;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(!Stack_Push(runtime->stack, obj))
|
if(!Stack_Push(runtime->stack, obj))
|
||||||
{
|
{
|
||||||
Error_Report(error, 0, "Out of stack");
|
Error_Report(error, ErrorType_RUNTIME, "Out of stack");
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -279,7 +279,7 @@ _Bool Runtime_Pop(Runtime *runtime, Error *error, unsigned int n)
|
|||||||
|
|
||||||
if(runtime->depth == 0)
|
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;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -287,7 +287,7 @@ _Bool Runtime_Pop(Runtime *runtime, Error *error, unsigned int n)
|
|||||||
|
|
||||||
if((unsigned int) runtime->frame->used < 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;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -434,7 +434,7 @@ static Object *do_math_op(Object *lop, Object *rop, Opcode opcode, Heap *heap, E
|
|||||||
case OPCODE_DIV: \
|
case OPCODE_DIV: \
|
||||||
if((y) == 0) \
|
if((y) == 0) \
|
||||||
{ \
|
{ \
|
||||||
Error_Report(error, 0, "Division by zero"); \
|
Error_Report(error, ErrorType_RUNTIME, "Division by zero"); \
|
||||||
return NULL; \
|
return NULL; \
|
||||||
} \
|
} \
|
||||||
(z) = (x) / (y); \
|
(z) = (x) / (y); \
|
||||||
@@ -466,7 +466,7 @@ static Object *do_math_op(Object *lop, Object *rop, Opcode opcode, Heap *heap, E
|
|||||||
}
|
}
|
||||||
else
|
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;
|
return NULL;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -492,13 +492,13 @@ static Object *do_math_op(Object *lop, Object *rop, Opcode opcode, Heap *heap, E
|
|||||||
}
|
}
|
||||||
else
|
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;
|
return NULL;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
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;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -541,7 +541,7 @@ static Object *do_relational_op(Object *lop, Object *rop, Opcode opcode, Heap *h
|
|||||||
}
|
}
|
||||||
else
|
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;
|
return NULL;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -562,13 +562,13 @@ static Object *do_relational_op(Object *lop, Object *rop, Opcode opcode, Heap *h
|
|||||||
}
|
}
|
||||||
else
|
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;
|
return NULL;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
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;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -584,10 +584,10 @@ static _Bool step(Runtime *runtime, Error *error)
|
|||||||
Opcode opcode;
|
Opcode opcode;
|
||||||
Operand ops[3];
|
Operand ops[3];
|
||||||
int opc = sizeof(ops) / sizeof(ops[0]);
|
int opc = sizeof(ops) / sizeof(ops[0]);
|
||||||
|
|
||||||
if(!Executable_Fetch(runtime->frame->exe, runtime->frame->index, &opcode, ops, &opc))
|
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;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -605,7 +605,7 @@ static _Bool step(Runtime *runtime, Error *error)
|
|||||||
|
|
||||||
if(runtime->frame->used == 0)
|
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;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -619,7 +619,7 @@ static _Bool step(Runtime *runtime, Error *error)
|
|||||||
|
|
||||||
if(runtime->frame->used == 0)
|
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;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -644,7 +644,7 @@ static _Bool step(Runtime *runtime, Error *error)
|
|||||||
}
|
}
|
||||||
else
|
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;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -662,7 +662,7 @@ static _Bool step(Runtime *runtime, Error *error)
|
|||||||
|
|
||||||
if(runtime->frame->used == 0)
|
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;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -675,7 +675,7 @@ static _Bool step(Runtime *runtime, Error *error)
|
|||||||
|
|
||||||
if(!Object_IsBool(top))
|
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;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -696,7 +696,7 @@ static _Bool step(Runtime *runtime, Error *error)
|
|||||||
|
|
||||||
if(runtime->frame->used == 0)
|
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;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -784,7 +784,7 @@ static _Bool step(Runtime *runtime, Error *error)
|
|||||||
ASSERT(lop != NULL);
|
ASSERT(lop != NULL);
|
||||||
|
|
||||||
if (!Object_IsInt(rop) || !Object_IsInt(lop)) {
|
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;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -872,7 +872,7 @@ static _Bool step(Runtime *runtime, Error *error)
|
|||||||
|
|
||||||
if(runtime->frame->used == 0)
|
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;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -913,7 +913,7 @@ static _Bool step(Runtime *runtime, Error *error)
|
|||||||
|
|
||||||
if(runtime->frame->used < 2)
|
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;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -936,7 +936,7 @@ static _Bool step(Runtime *runtime, Error *error)
|
|||||||
Object_Print(arg, provided_fp);
|
Object_Print(arg, provided_fp);
|
||||||
fclose(allowed_fp);
|
fclose(allowed_fp);
|
||||||
fclose(provided_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);
|
arg_index+1, arg_name, allowed, provided);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@@ -955,7 +955,7 @@ static _Bool step(Runtime *runtime, Error *error)
|
|||||||
|
|
||||||
if(runtime->frame->used < argc + 1)
|
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;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -967,7 +967,7 @@ static _Bool step(Runtime *runtime, Error *error)
|
|||||||
int max_argc = sizeof(argv) / sizeof(argv[0]);
|
int max_argc = sizeof(argv) / sizeof(argv[0]);
|
||||||
if(argc > max_argc)
|
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;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1020,7 +1020,7 @@ static _Bool step(Runtime *runtime, Error *error)
|
|||||||
const char *name = "SELECT";
|
const char *name = "SELECT";
|
||||||
if (opcode == OPCODE_SELECT2)
|
if (opcode == OPCODE_SELECT2)
|
||||||
name = "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;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1063,7 +1063,7 @@ static _Bool step(Runtime *runtime, Error *error)
|
|||||||
|
|
||||||
if(runtime->frame->used < 3)
|
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;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1087,7 +1087,7 @@ static _Bool step(Runtime *runtime, Error *error)
|
|||||||
|
|
||||||
if(runtime->frame->used < 3)
|
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;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1180,7 +1180,7 @@ static _Bool step(Runtime *runtime, Error *error)
|
|||||||
{
|
{
|
||||||
if(error->occurred == 0)
|
if(error->occurred == 0)
|
||||||
// There's no such variable.
|
// 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;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1302,7 +1302,7 @@ static _Bool step(Runtime *runtime, Error *error)
|
|||||||
|
|
||||||
if(runtime->frame->used < 1)
|
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;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1356,7 +1356,7 @@ static _Bool step(Runtime *runtime, Error *error)
|
|||||||
|
|
||||||
if(runtime->frame->used == 0)
|
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;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1369,7 +1369,7 @@ static _Bool step(Runtime *runtime, Error *error)
|
|||||||
|
|
||||||
if(!Object_IsBool(top))
|
if(!Object_IsBool(top))
|
||||||
{
|
{
|
||||||
Error_Report(error, 0, "Not a boolean");
|
Error_Report(error, ErrorType_RUNTIME, "Not a boolean");
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1388,7 +1388,7 @@ static _Bool step(Runtime *runtime, Error *error)
|
|||||||
|
|
||||||
if(runtime->frame->used == 0)
|
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;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1401,7 +1401,7 @@ static _Bool step(Runtime *runtime, Error *error)
|
|||||||
|
|
||||||
if(!Object_IsBool(top))
|
if(!Object_IsBool(top))
|
||||||
{
|
{
|
||||||
Error_Report(error, 0, "Not a boolean");
|
Error_Report(error, ErrorType_RUNTIME, "Not a boolean");
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1460,7 +1460,7 @@ int run(Runtime *runtime, Error *error,
|
|||||||
|
|
||||||
if(runtime->depth == MAX_FRAMES)
|
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;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1481,7 +1481,7 @@ int run(Runtime *runtime, Error *error,
|
|||||||
|
|
||||||
if(frame.exe == NULL)
|
if(frame.exe == NULL)
|
||||||
{
|
{
|
||||||
Error_Report(error, 1, "Failed to copy executable");
|
Error_Report(error, ErrorType_INTERNAL, "Failed to copy executable");
|
||||||
return -1;
|
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)))
|
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
|
else
|
||||||
while(step(runtime, error))
|
while(step(runtime, error))
|
||||||
{
|
{
|
||||||
if(runtime->interrupt || (runtime->callback.func != NULL && !runtime->callback.func(runtime, runtime->callback.data)))
|
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;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+36
-4
@@ -52,17 +52,17 @@ void Error_Free(Error *err)
|
|||||||
memset(err, 0, sizeof (Error));
|
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 *file, const char *func, int line,
|
||||||
const char *fmt, ...)
|
const char *fmt, ...)
|
||||||
{
|
{
|
||||||
va_list va;
|
va_list va;
|
||||||
va_start(va, fmt);
|
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);
|
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 *file, const char *func, int line,
|
||||||
const char *fmt, va_list va)
|
const char *fmt, va_list va)
|
||||||
{
|
{
|
||||||
@@ -80,7 +80,7 @@ void _Error_Report2(Error *err, _Bool internal,
|
|||||||
ASSERT(err->occurred == 0);
|
ASSERT(err->occurred == 0);
|
||||||
|
|
||||||
err->occurred = 1;
|
err->occurred = 1;
|
||||||
err->internal = internal;
|
err->type = type;
|
||||||
err->file = file;
|
err->file = file;
|
||||||
err->func = func;
|
err->func = func;
|
||||||
err->line = line;
|
err->line = line;
|
||||||
@@ -135,4 +135,36 @@ void Error_Panic_(const char *file, int line,
|
|||||||
fprintf(fp, " (reported in %s:%d)", file, line);
|
fprintf(fp, " (reported in %s:%d)", file, line);
|
||||||
va_end(args);
|
va_end(args);
|
||||||
abort();
|
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
@@ -32,8 +32,17 @@
|
|||||||
#define ERROR_H
|
#define ERROR_H
|
||||||
#include <stdarg.h>
|
#include <stdarg.h>
|
||||||
|
|
||||||
|
typedef enum {
|
||||||
|
ErrorType_SYNTAX,
|
||||||
|
ErrorType_SEMANTIC,
|
||||||
|
ErrorType_RUNTIME,
|
||||||
|
ErrorType_INTERNAL,
|
||||||
|
ErrorType_UNSPECIFIED = 0,
|
||||||
|
} ErrorType;
|
||||||
|
|
||||||
typedef struct Error Error;
|
typedef struct Error Error;
|
||||||
struct Error {
|
struct Error {
|
||||||
|
ErrorType type;
|
||||||
void (*on_report)(Error *err);
|
void (*on_report)(Error *err);
|
||||||
_Bool occurred,
|
_Bool occurred,
|
||||||
internal,
|
internal,
|
||||||
@@ -49,9 +58,10 @@ struct Error {
|
|||||||
void Error_Init(Error *err);
|
void Error_Init(Error *err);
|
||||||
void Error_Init2(Error *err, void (*on_report)(Error *err));
|
void Error_Init2(Error *err, void (*on_report)(Error *err));
|
||||||
void Error_Free(Error *err);
|
void Error_Free(Error *err);
|
||||||
#define Error_Report(err, internal, fmt, ...) _Error_Report(err, internal, __FILE__, __func__, __LINE__, fmt, ## __VA_ARGS__)
|
#define Error_Report(err, typ, fmt, ...) _Error_Report(err, typ, __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_Report (Error *err, ErrorType typ, 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);
|
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, ...);
|
void Error_Panic_(const char *file, int line, const char *fmt, ...);
|
||||||
#define Error_Panic(fmt, ...) Error_Panic_(__FILE__, __LINE__, fmt, ## __VA_ARGS__)
|
#define Error_Panic(fmt, ...) Error_Panic_(__FILE__, __LINE__, fmt, ## __VA_ARGS__)
|
||||||
|
void Error_Print(Error *error, ErrorType type_if_unspecified);
|
||||||
#endif
|
#endif
|
||||||
+10
-10
@@ -88,14 +88,14 @@ Source *Source_FromFile(const char *file, Error *error)
|
|||||||
assert(file != NULL);
|
assert(file != NULL);
|
||||||
|
|
||||||
if(file[0] == '\0') {
|
if(file[0] == '\0') {
|
||||||
Error_Report(error, 0, "Empty file name");
|
Error_Report(error, ErrorType_UNSPECIFIED, "Empty file name");
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
char maybe[1024];
|
char maybe[1024];
|
||||||
const char *abs_path = Path_MakeAbsolute(file, maybe, sizeof(maybe));
|
const char *abs_path = Path_MakeAbsolute(file, maybe, sizeof(maybe));
|
||||||
if(abs_path == NULL) {
|
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;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -111,15 +111,15 @@ Source *Source_FromFile(const char *file, Error *error)
|
|||||||
if(fp == NULL)
|
if(fp == NULL)
|
||||||
{
|
{
|
||||||
if(errno == ENOENT)
|
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
|
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;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(fseek(fp, 0, SEEK_END))
|
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);
|
fclose(fp);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
@@ -128,14 +128,14 @@ Source *Source_FromFile(const char *file, Error *error)
|
|||||||
|
|
||||||
if(size < 0)
|
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);
|
fclose(fp);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(fseek(fp, 0, SEEK_SET))
|
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);
|
fclose(fp);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
@@ -150,7 +150,7 @@ Source *Source_FromFile(const char *file, Error *error)
|
|||||||
|
|
||||||
if(s == NULL)
|
if(s == NULL)
|
||||||
{
|
{
|
||||||
Error_Report(error, 1, "No memory");
|
Error_Report(error, ErrorType_INTERNAL, "No memory");
|
||||||
fclose(fp);
|
fclose(fp);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
@@ -171,7 +171,7 @@ Source *Source_FromFile(const char *file, Error *error)
|
|||||||
|
|
||||||
if(p != size)
|
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);
|
fclose(fp);
|
||||||
free(s);
|
free(s);
|
||||||
return NULL;
|
return NULL;
|
||||||
@@ -197,7 +197,7 @@ Source *Source_FromString(const char *name, const char *body, int size, Error *e
|
|||||||
|
|
||||||
if(memory == NULL)
|
if(memory == NULL)
|
||||||
{
|
{
|
||||||
Error_Report(error, 1, "No memory");
|
Error_Report(error, ErrorType_INTERNAL, "No memory");
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+6
-40
@@ -86,32 +86,6 @@
|
|||||||
|
|
||||||
// NOTE: From https://gist.github.com/RabaDabaDoba/145049536f815903c79944599c6f952a
|
// 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 {
|
typedef enum {
|
||||||
TokenType_END,
|
TokenType_END,
|
||||||
TokenType_TEXT,
|
TokenType_TEXT,
|
||||||
@@ -310,14 +284,14 @@ static bool parseTestCaseSource(Source *source, TestCase *testcase)
|
|||||||
|
|
||||||
testcase->source = Source_FromString("<input>", str + source_offset, source_length, &error);
|
testcase->source = Source_FromString("<input>", str + source_offset, source_length, &error);
|
||||||
if(testcase->source == NULL) {
|
if(testcase->source == NULL) {
|
||||||
print_error(NULL, &error);
|
Error_Print(&error, ErrorType_UNSPECIFIED);
|
||||||
Error_Free(&error);
|
Error_Free(&error);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
testcase->bytecode = Source_FromString("<output>", str + bytecode_offset, bytecode_length, &error);
|
testcase->bytecode = Source_FromString("<output>", str + bytecode_offset, bytecode_length, &error);
|
||||||
if(testcase->bytecode == NULL) {
|
if(testcase->bytecode == NULL) {
|
||||||
print_error(NULL, &error);
|
Error_Print(&error, ErrorType_UNSPECIFIED);
|
||||||
Source_Free(testcase->source);
|
Source_Free(testcase->source);
|
||||||
Error_Free(&error);
|
Error_Free(&error);
|
||||||
return false;
|
return false;
|
||||||
@@ -331,17 +305,9 @@ static Executable *compile_source_and_print_error_on_failure(Source *src)
|
|||||||
{
|
{
|
||||||
Error error;
|
Error error;
|
||||||
Error_Init(&error);
|
Error_Init(&error);
|
||||||
CompilationErrorType errtyp;
|
Executable *exe = compile(src, &error);
|
||||||
Executable *exe = compile(src, &error, &errtyp);
|
|
||||||
if(exe == NULL) {
|
if(exe == NULL) {
|
||||||
const char *errname;
|
Error_Print(&error, ErrorType_UNSPECIFIED);
|
||||||
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_Free(&error);
|
Error_Free(&error);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
@@ -364,7 +330,7 @@ static TestResult runTest(const char *file)
|
|||||||
|
|
||||||
source = Source_FromFile(file, &error);
|
source = Source_FromFile(file, &error);
|
||||||
if(source == NULL) {
|
if(source == NULL) {
|
||||||
print_error(NULL, &error);
|
Error_Print(&error, ErrorType_UNSPECIFIED);
|
||||||
Error_Free(&error);
|
Error_Free(&error);
|
||||||
return TestResult_ABORT;
|
return TestResult_ABORT;
|
||||||
}
|
}
|
||||||
@@ -395,7 +361,7 @@ static TestResult runTest(const char *file)
|
|||||||
|
|
||||||
exe2 = assemble(testcase.bytecode, &error);
|
exe2 = assemble(testcase.bytecode, &error);
|
||||||
if(exe2 == NULL) {
|
if(exe2 == NULL) {
|
||||||
print_error("Assemblation", &error);
|
Error_Print(&error, ErrorType_UNSPECIFIED);
|
||||||
Error_Free(&error);
|
Error_Free(&error);
|
||||||
Executable_Free(exe1);
|
Executable_Free(exe1);
|
||||||
Source_Free(testcase.source);
|
Source_Free(testcase.source);
|
||||||
|
|||||||
Reference in New Issue
Block a user