Updated exception execution.

Now represents a sort of traceback.
This commit is contained in:
Jacob Signorovitch 2025-03-30 17:05:29 -04:00
parent 5b163b26dd
commit 845a7f87b2
5 changed files with 71 additions and 18 deletions

View File

@ -78,13 +78,25 @@ void ast_num_print(ASTNumData* data, int i) {
INDENT_END;
}
ASTExcData ast_exc_data_init(char* msg) { return (ASTExcData)msg; }
ASTExcData* ast_exc_data_init(char* msg, AST* trace) {
ASTExcData* data = malloc(sizeof(ASTExcData));
data->msg = msg;
data->trace = trace;
return data;
}
void ast_exc_print(ASTExcData data, int i) {
void ast_exc_print(ASTExcData* data, int i) {
INDENT_BEGIN(i);
INDENT_TITLE("ASTExcData", data);
INDENT_FIELD("msg", "\"%s\"", data);
INDENT_FIELD("msg", "\"%s\"", data->msg);
if (data->trace == NULL) {
INDENT_FIELD("trace", "%p", NULL)
} else {
INDENT_FIELD_EXT_NONL_START("trace");
ast_print_i(data->trace, i + 1);
INDENT_FIELD_NONL_END;
}
INDENT_END;
}

View File

@ -6,15 +6,19 @@
#include <stdio.h>
AST* builtin_sum(size_t argc, AST** argv) {
log_dbg("Got here");
ASTNumData total = 0;
for (int i = 0; i < argc; i++) {
AST* arg = exec_exp(argv[i]);
if (arg->type == AST_TYPE_EXC)
return ast_init(
AST_TYPE_EXC,
ast_exc_data_init("`sum` encountered an exception.", arg)
);
if (arg->type != AST_TYPE_NUM)
return ast_init(
AST_TYPE_EXC,
ast_exc_data_init("Sum can't sum some non-num arguments.")
ast_exc_data_init("Sum can't sum some non-num arguments.", NULL)
);
total += *(ASTNumData*)arg->data;
@ -26,19 +30,30 @@ AST* builtin_sum(size_t argc, AST** argv) {
AST* builtin_sub(size_t argc, AST** argv) {
log_dbg("Got here");
AST* first = exec_exp(*argv);
if (first->type == AST_TYPE_EXC)
return ast_init(
AST_TYPE_EXC,
ast_exc_data_init("`sub` encountered an exception.", first)
);
if (first->type != AST_TYPE_NUM)
return ast_init(
AST_TYPE_EXC, ast_exc_data_init("Can't subtract non-num arguments.")
AST_TYPE_EXC,
ast_exc_data_init("Can't subtract non-num arguments.", NULL)
);
ASTNumData total = *(ASTNumData*)first->data;
for (int i = 1; i < argc; i++) {
AST* arg = exec_exp(argv[i]);
if (arg->type == AST_TYPE_EXC)
return ast_init(
AST_TYPE_EXC,
ast_exc_data_init("`sub` encountered an exception.", arg)
);
if (arg->type != AST_TYPE_NUM)
return ast_init(
AST_TYPE_EXC,
ast_exc_data_init("Can't subtract non-num arguments.")
ast_exc_data_init("Can't subtract non-num arguments.", NULL)
);
total -= *(ASTNumData*)arg->data;
@ -50,19 +65,30 @@ AST* builtin_sub(size_t argc, AST** argv) {
AST* builtin_mul(size_t argc, AST** argv) {
log_dbg("Got here");
AST* first = exec_exp(*argv);
if (first->type == AST_TYPE_EXC)
return ast_init(
AST_TYPE_EXC,
ast_exc_data_init("`mul` encountered an expection.", first)
);
if (first->type != AST_TYPE_NUM)
return ast_init(
AST_TYPE_EXC, ast_exc_data_init("Can't multiply non-num arguments.")
AST_TYPE_EXC,
ast_exc_data_init("Can't multiply non-num arguments.", NULL)
);
ASTNumData total = *(ASTNumData*)first->data;
for (int i = 1; i < argc; i++) {
AST* arg = exec_exp(argv[i]);
if (arg->type == AST_TYPE_EXC)
return ast_init(
AST_TYPE_EXC,
ast_exc_data_init("`mul` encountered an execption.", arg)
);
if (arg->type != AST_TYPE_NUM)
return ast_init(
AST_TYPE_EXC,
ast_exc_data_init("Can't multiply non-num arguments.")
ast_exc_data_init("Can't multiply non-num arguments.", NULL)
);
total *= *(ASTNumData*)arg->data;
@ -74,19 +100,30 @@ AST* builtin_mul(size_t argc, AST** argv) {
AST* builtin_div(size_t argc, AST** argv) {
log_dbg("Got here");
AST* first = exec_exp(*argv);
if (first->type == AST_TYPE_EXC)
return ast_init(
AST_TYPE_EXC,
ast_exc_data_init("`div` encountered an exception.", first)
);
if (first->type != AST_TYPE_NUM)
return ast_init(
AST_TYPE_EXC, ast_exc_data_init("Can't divide non-num arguments.")
AST_TYPE_EXC,
ast_exc_data_init("Can't divide non-num arguments.", NULL)
);
ASTNumData total = *(ASTNumData*)first->data;
for (int i = 1; i < argc; i++) {
AST* arg = exec_exp(argv[i]);
if (arg->type == AST_TYPE_EXC)
return ast_init(
AST_TYPE_EXC,
ast_exc_data_init("`div` encountered an exception.", arg)
);
if (arg->type != AST_TYPE_NUM)
return ast_init(
AST_TYPE_EXC,
ast_exc_data_init("Can't divide non-num arguments.")
ast_exc_data_init("Can't divide non-num arguments.", NULL)
);
total /= *(ASTNumData*)arg->data;

View File

@ -69,14 +69,15 @@ AST* exec_call(AST* ast) {
if (fdef == NULL)
return ast_init(
AST_TYPE_EXC, ast_exc_data_init(strdup("No such function found."))
AST_TYPE_EXC, ast_exc_data_init("No such function found.", NULL)
);
switch (fdef->type) {
case AST_TYPE_BIF:
ASTBIFData bifdata = fdef->data;
return bifdata(argc, argv);
default: return ast_init(AST_TYPE_EXC, ast_exc_data_init("Good job!"));
default:
return ast_init(AST_TYPE_EXC, ast_exc_data_init("Good job!", NULL));
}
}
@ -113,7 +114,7 @@ AST* exec_vref(AST* ast) {
msg, sizeof(msg), "Could not find value in scope for `%s`.",
vref->to
);
return ast_init(AST_TYPE_EXC, msg);
return ast_init(AST_TYPE_EXC, ast_exc_data_init(msg, NULL));
}
return exec_exp(found);

View File

@ -51,13 +51,16 @@ void ast_num_data_destroy(ASTNumData* num);
void ast_num_print(ASTNumData*, int i);
// An exception.
typedef char* ASTExcData;
typedef struct ASTEXCDATA {
char* msg; // The exception message.
AST* trace; // The previous exception.
} ASTExcData;
// Create a new `ASTExecData.
ASTExcData ast_exc_data_init(char* msg);
ASTExcData* ast_exc_data_init(char* msg, AST* trace);
// Destroy an `ASTExecData`.
void ast_exc_data_destroy(ASTExcData* exc);
// Print an `ASTExecData`.
void ast_exc_print(ASTExcData, int i);
void ast_exc_print(ASTExcData*, int i);
// A built-in function.
typedef AST* (*ASTBIFData)(size_t argc, AST** argv);

View File

@ -21,7 +21,6 @@ void stack_destroy(Stack* stack) {
}
void stack_push(Stack* stack, void* val) {
log_dbgf("pushed to stack, inc ln to %ld", stack->ln);
if (stack->ln >= STACK_MAX) {
log_dbgf("Ran out of stack (max: %d)", STACK_MAX);
return;
@ -29,6 +28,7 @@ void stack_push(Stack* stack, void* val) {
stack->buf[stack->ln] = val;
stack->ln++;
log_dbgf("pushed to stack, inc ln to %ld", stack->ln);
}
void* stack_pop(Stack* stack) {