From 4514d94be91a77bd5f422acd535c05931a665090 Mon Sep 17 00:00:00 2001 From: Jacob Date: Sat, 30 Nov 2024 10:24:31 -0500 Subject: [PATCH] Basic addition with integers is now available. --- src/ast.c | 78 +++++++++++++++++++++++++--------------------- src/exec.c | 21 +++++++------ src/grammar.y | 11 ++----- src/include/ast.h | 13 ++++---- src/include/exec.h | 6 ++-- src/lexer.c | 1 + src/main.c | 44 +++++++++++++++++--------- 7 files changed, 95 insertions(+), 79 deletions(-) diff --git a/src/ast.c b/src/ast.c index f03ece0..a0c15d3 100644 --- a/src/ast.c +++ b/src/ast.c @@ -3,46 +3,12 @@ #include "include/ast.h" #include "include/util.h" -#if 0 +extern AST* root; + static char* asttype_names[] = { [AST_TYPE_CALL] = "CALL", [AST_TYPE_NUM] = "NUMBER", }; -#endif - -ASTTypeNum* ast_type_num_init(int val) { - talloc(ASTTypeNum, num); - - num->val = val; - - return num; -} - -void ast_type_num_destroy(ASTTypeNum* num) { - if (!num) - return - - free(num); -} - -ASTTypeCall* ast_type_call_init(char* to, size_t argc, AST** argv) { - talloc(ASTTypeCall, call); - - call->to = to; - call->argc = argc; - call->argv = argv; - - return call; -} - -void ast_type_call_destroy(ASTTypeCall* call) { - if (!call) - return - - free(call->to); - for (size_t i = 0; i < call->argc; i++) free(call->argv[i]); - free(call); -} AST* ast_init(ASTType type, void* data) { AST* ast = malloc(sizeof(AST)); @@ -62,3 +28,43 @@ void ast_destroy(AST* ast) { default: log_dbgf("Unknown ast type %d (max: %d)", ast->type, AST_TYPE_MAX); } } + +void ast_print(AST* ast) { + log_dbgf("Tree type: %s", asttype_names[ast->type]); + fflush(stdout); +} + + +ASTNumData* ast_type_num_init(int val) { + talloc(ASTNumData, num); + + num->val = val; + + return num; +} + +void ast_type_num_destroy(ASTNumData* num) { + if (!num) + return + + free(num); +} + +ASTCallData* ast_type_call_init(char* to, size_t argc, AST** argv) { + talloc(ASTCallData, call); + + call->to = to; + call->argc = argc; + call->argv = argv; + + return call; +} + +void ast_type_call_destroy(ASTCallData* call) { + if (!call) + return + + free(call->to); + for (size_t i = 0; i < call->argc; i++) free(call->argv[i]); + free(call); +} diff --git a/src/exec.c b/src/exec.c index 1d1d21f..37873ad 100644 --- a/src/exec.c +++ b/src/exec.c @@ -5,26 +5,27 @@ #include "include/exec.h" #include "include/util.h" -void exec(AST* ast) { +extern AST* root; + +void exec_expr() { + ast_print(root); log_dbg("Started execution."); - switch (ast->type) { - case AST_TYPE_CALL: exec_call(ast); break; + switch (root->type) { + case AST_TYPE_CALL: exec_call(); break; default: printf("what\n"); } } -void exec_call(AST* ast) { +void exec_call() { log_dbg("Started call execution."); - ASTTypeCall* calldata = (ASTTypeCall*)ast->data; + fflush(stdout); + ASTCallData* calldata = (ASTCallData*)root->data; if (!strcmp(calldata->to, "+") && calldata->argc == 2) { - exec_return(1); - /* - ASTTypeNum* n1 = (ASTTypeNum*)calldata->argv[0]->data; - ASTTypeNum* n2 = (ASTTypeNum*)calldata->argv[1]->data; + ASTNumData* n1 = (ASTNumData*)calldata->argv[0]->data; + ASTNumData* n2 = (ASTNumData*)calldata->argv[1]->data; exec_return(n1->val + n2->val); - */ } } diff --git a/src/grammar.y b/src/grammar.y index d801633..374c278 100644 --- a/src/grammar.y +++ b/src/grammar.y @@ -24,19 +24,14 @@ %token NUM %token CALL %token PLUS +%token NL %type exp %% input: %empty - | line - ; - - -line: - '\n' - | exp '\n' { root = $1; } + | exp { root = $1; } ; exp: @@ -44,7 +39,7 @@ exp: | NUM PLUS NUM { AST* argv[2] = { ast_init(AST_TYPE_NUM, ast_type_num_init($1)), - ast_init(AST_TYPE_NUM, ast_type_num_init($1)) + ast_init(AST_TYPE_NUM, ast_type_num_init($3)) }; $$ = ast_init(AST_TYPE_CALL, ast_type_call_init("+", 2, argv)); }; diff --git a/src/include/ast.h b/src/include/ast.h index f1051c9..27e11b4 100644 --- a/src/include/ast.h +++ b/src/include/ast.h @@ -16,21 +16,22 @@ typedef struct { AST* ast_init(ASTType type, void* data); void ast_destroy(AST* ast); +void ast_print(AST* ast); typedef struct { int val; -} ASTTypeNum; +} ASTNumData; -ASTTypeNum* ast_type_num_init(int val); -void ast_type_num_destroy(ASTTypeNum* num); +ASTNumData* ast_type_num_init(int val); +void ast_type_num_destroy(ASTNumData* num); typedef struct { char* to; // What the call's to. size_t argc; // Argument count. AST** argv; // Argument vector. -} ASTTypeCall; +} ASTCallData; -ASTTypeCall* ast_type_call_init(char* to, size_t argc, AST** argv); -void ast_type_call_destroy(ASTTypeCall* call); +ASTCallData* ast_type_call_init(char* to, size_t argc, AST** argv); +void ast_type_call_destroy(ASTCallData* call); #endif diff --git a/src/include/exec.h b/src/include/exec.h index 5a84546..625abdc 100644 --- a/src/include/exec.h +++ b/src/include/exec.h @@ -1,10 +1,8 @@ #ifndef EXEC_H #define EXEC_H -#include "ast.h" - -void exec(AST* ast); -void exec_call(AST* ast); +void exec_expr(); +void exec_call(); void exec_return(int n); #endif diff --git a/src/lexer.c b/src/lexer.c index f2de0f3..88e8fb6 100644 --- a/src/lexer.c +++ b/src/lexer.c @@ -26,6 +26,7 @@ int yylex() { switch (c) { case '+': return PLUS; + case '\n': return NL; default: return CALL; } diff --git a/src/main.c b/src/main.c index 8f8683f..cc73cdf 100644 --- a/src/main.c +++ b/src/main.c @@ -4,6 +4,7 @@ #include "include/dstr.h" #include "include/lexer.h" #include "include/util.h" +#include "include/exec.h" #include "../build/grammars/grammar.tab.h" @@ -16,28 +17,41 @@ char* inp = NULL; extern int yyparse(); int main(int argc, char** argv) { + while (1) { - Dstr* cline = dstr_init(); // The current line. + Dstr* ln = dstr_init(); + char c; + printf("> "); fflush(stdout); - for (char cch; (cch = getc(stdin)) != '\n';) { - log_dbgf("cchar: %c", cch); - dstr_appendch(cline, cch); - } - dstr_appendch(cline, '\n'); - log_dbgf("cline: %s", cline->buf); + // Accumulate line. + do { + c = getc(stdin); + switch (c) { + case EOF: dstr_destroy(ln); goto lnskip; + case '\n': goto lnend; - if (cline->ln > 0) { - // I hope it's null-terminated. - inp = cline->buf; - if (yyparse() == 0) { - printf("Parsed successfully!\n"); - } else { - printf("Parse error.\n"); + default: dstr_appendch(ln, c); log_dbgf("cchar: %c", c); } + } while (1); + + lnend: + + log_dbgf("cline: %s", ln->buf); + + if (ln->ln > 0) { + // I hope it's null-terminated. + inp = ln->buf; + if (yyparse() == 0) + printf("Parsed successfully!\n"); + else + printf("Parse error.\n"); + + exec_expr(); } - dstr_destroy(cline); + dstr_destroy(ln); } +lnskip:; }