From eb3fbca030f78deb8eedcd017246f73a778ce308 Mon Sep 17 00:00:00 2001 From: Jacob Date: Sat, 15 Feb 2025 11:03:51 -0500 Subject: [PATCH] Some things are broken. EVERYTHING IS BROKEN AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA. --- TODO.md | 3 +++ config.mk | 2 +- src/ast.c | 17 +++++++++--- src/builtin.c | 23 +++++++++++++++++ src/exec.c | 60 ++++++++++++++----------------------------- src/include/ast.h | 10 ++++++++ src/include/builtin.h | 12 +++++++++ 7 files changed, 82 insertions(+), 45 deletions(-) create mode 100644 src/builtin.c create mode 100644 src/include/builtin.h diff --git a/TODO.md b/TODO.md index 466ff09..7cfea1f 100644 --- a/TODO.md +++ b/TODO.md @@ -1,2 +1,5 @@ +FIX EXCEPTION PRINTING (probably broken because of string literals being dereferenced) + + 1. Change editor to GNU Readline. 2. Make variables persist through lines in the editor. diff --git a/config.mk b/config.mk index 04c7510..4e083ce 100644 --- a/config.mk +++ b/config.mk @@ -11,7 +11,7 @@ TEST_DIR = test TEST_BUILD_DIR = $(BUILD_DIR)/test TEST_OBJ_DIR = $(TEST_BUILD_DIR)/obj -CC = clang +CC = clang -std=c2x LINK = clang CFLAGS = -Wall -DDBG -ggdb -fsanitize=leak LDFLAGS = -lm diff --git a/src/ast.c b/src/ast.c index 361371f..5df11be 100644 --- a/src/ast.c +++ b/src/ast.c @@ -9,7 +9,7 @@ extern AST* root; static char* asttype_names[] = { [AST_TYPE_CALL] = "FUNC CALL", [AST_TYPE_NUM] = "NUMBER", [AST_TYPE_VREF] = "VAR REFERENCE", [AST_TYPE_VDEF] = "VAR DEFINITION", - [AST_TYPE_BLOCK] = "BLOCK", + [AST_TYPE_BLOCK] = "BLOCK", [AST_TYPE_EXC] = "EXCEPTION" }; AST* ast_init(ASTType type, void* data) { @@ -50,6 +50,7 @@ void ast_print_i(AST* ast, int i) { printf("%s %lf\n", INDENT_spacing->buf, *(ASTNumData*)ast->data); break; case AST_TYPE_CALL: ast_call_print(ast->data, i + 2); break; + case AST_TYPE_EXC: ast_exc_print(ast->data, i + 2); break; case AST_TYPE_VREF: ast_vref_print(ast->data, i + 2); break; case AST_TYPE_VDEF: ast_vdef_print(ast->data, i + 2); break; case AST_TYPE_BLOCK: ast_block_print(ast->data, i + 2); break; @@ -77,8 +78,18 @@ 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) { return (ASTExcData*)msg; } + +void ast_exc_print(ASTExcData* data, int i) { + INDENT_BEGIN(i); + + INDENT_TITLE("ASTExcData", data); + INDENT_FIELD("msg", "\"%s\"", *data); + INDENT_END; +} + +ASTBIFData* ast_bif_data_init(AST* fn(size_t, AST**)) { + return (ASTBIFData*)fn; } ASTCallData* ast_call_data_init(char* to, size_t argc, AST** argv) { diff --git a/src/builtin.c b/src/builtin.c new file mode 100644 index 0000000..e7d7dbe --- /dev/null +++ b/src/builtin.c @@ -0,0 +1,23 @@ +#include "include/builtin.h" +#include "include/ast.h" +#include "include/util.h" +#include +#include + +AST* builtin_sum(size_t argc, AST** argv) { + log_dbg("Got here"); + ASTNumData total = 0; + + for (int i = 0; i < argc; i++) { + AST* arg = argv[i]; + if (arg->type != AST_TYPE_NUM) + return ast_init( + AST_TYPE_EXC, + ast_exc_data_init("Sum can't sum some non-num arguments.") + ); + + total += *(ASTNumData*)arg->data; + } + + return ast_init(AST_TYPE_NUM, ast_num_data_init(total)); +} diff --git a/src/exec.c b/src/exec.c index 4809ad3..c044f1c 100644 --- a/src/exec.c +++ b/src/exec.c @@ -3,6 +3,7 @@ #include #include "include/ast.h" +#include "include/builtin.h" #include "include/exec.h" #include "include/htab.h" #include "include/stack.h" @@ -10,11 +11,17 @@ extern AST* root; +AST* exec_find(char* name); + AST* exec_start(AST* ast) { scope = stack_init(); HTab* global = htab_init(); + htab_ins( + global, "sum", ast_init(AST_TYPE_BIF, ast_bif_data_init(builtin_sum)) + ); + // Push global namespace to `scope`. stack_push(scope, global); @@ -51,48 +58,20 @@ AST* exec_block(AST* ast) { AST* exec_call(AST* ast) { log_dbg("Started call execution."); - fflush(stdout); - ASTCallData* calldata = (ASTCallData*)ast->data; - if (calldata->argc >= 1) { - if (!strcmp(calldata->to, "sum")) { - AST* total = ast_init(AST_TYPE_NUM, ast_num_data_init(0)); + ASTCallData* data = (ASTCallData*)ast->data; + size_t argc = data->argc; + AST** argv = data->argv; + char* fname = data->to; - for (size_t i = 0; i < calldata->argc; i++) { - AST* arg = exec_exp(calldata->argv[i]); + AST* fdef = exec_find(fname); - if (arg->type != AST_TYPE_NUM) { - return ast_init( - AST_TYPE_EXC, ast_exc_data_init("Wrong type, fool.") - ); - } - - *((ASTNumData*) total->data) += *((ASTNumData*)arg->data); - } - - return total; - } /*else if (!strcmp(calldata->to, "sub")) { - double total = exec_exp(calldata->argv[0]); - - for (size_t i = 1; i < calldata->argc; - total -= exec_exp(calldata->argv[i++])); - - return total; - } else if (!strcmp(calldata->to, "mul")) { - double total = exec_exp(calldata->argv[0]); - - for (size_t i = 1; i < calldata->argc; - total *= exec_exp(calldata->argv[i++])); - - return total; - } else if (!strcmp(calldata->to, "div")) { - double total = exec_exp(calldata->argv[0]); - - for (size_t i = 1; i < calldata->argc; - total /= exec_exp(calldata->argv[i++])); - - return total; - }*/ + 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")); } + return ast_init(AST_TYPE_EXC, ast_exc_data_init("No such function found.")); } @@ -105,8 +84,7 @@ AST* exec_find(char* name) { if (val != NULL) return val; } - log_dbgf("Could not find var %s", name); - exit(1); + return ast_init(AST_TYPE_EXC, ast_exc_data_init("Couln't find term.")); } AST* exec_vdef(AST* ast) { diff --git a/src/include/ast.h b/src/include/ast.h index 41f932e..a26b6a8 100644 --- a/src/include/ast.h +++ b/src/include/ast.h @@ -16,6 +16,7 @@ typedef enum { AST_TYPE_LIST, // A list (variable size, variable type). // Misc. types. + AST_TYPE_BIF, // Built-in function. AST_TYPE_CALL, // A function call. AST_TYPE_VDEF, // A variable definition. AST_TYPE_VREF, // A variable reference. @@ -43,6 +44,15 @@ void ast_num_print(ASTNumData*, int i); typedef char* ASTExcData; ASTExcData* ast_exc_data_init(char* msg); void ast_exc_data_destroy(ASTExcData* exc); +void ast_exc_print(ASTExcData*, int i); + +// A built-in function. +typedef AST* (*ASTBIFData)(size_t argc, AST** argv); + +// Create a built-in function. +ASTBIFData* ast_bif_data_init(AST* fn(size_t, AST**)); + +// There is no `ASTBIFData` destroy function, as function pointers are immortal. typedef struct { char* to; // What the call's to. diff --git a/src/include/builtin.h b/src/include/builtin.h new file mode 100644 index 0000000..00d204b --- /dev/null +++ b/src/include/builtin.h @@ -0,0 +1,12 @@ +#ifndef BUILTIN_H +#define BUILTIN_H + +#include "ast.h" + +// Sum some nums. +AST* builtin_sum(size_t argc, AST** argv); + +// The list of built-in functions. +static AST* (*builtin_fns[])(size_t argc, AST** argv) = {builtin_sum}; + +#endif