From d5a07fae56392b5b3237cade56a0a37bc77b0440 Mon Sep 17 00:00:00 2001 From: Jacob Signorovitch Date: Tue, 4 Feb 2025 11:30:45 -0500 Subject: [PATCH] Started adding scope. Doesn't really do anything yet as blocks aren't fully implemented. --- src/exec.c | 69 ++++++++++++++++++++++++++++++++++----------- src/grammar.y | 6 ++-- src/include/exec.h | 12 +++++--- src/include/stack.h | 9 +++--- src/main.c | 4 +-- 5 files changed, 70 insertions(+), 30 deletions(-) diff --git a/src/exec.c b/src/exec.c index f4f5b97..8d87d08 100644 --- a/src/exec.c +++ b/src/exec.c @@ -4,64 +4,88 @@ #include "include/ast.h" #include "include/exec.h" +#include "include/stack.h" #include "include/util.h" +#include "include/htab.h" extern AST* root; -ASTNumData exec_exp(AST* ast) { +ASTNumData exec_start(AST* ast) { + // The `Stack` of `HTab` that makes up the scope of any given `AST`. + Stack* scope = stack_init(); + + // Global scope. Just dummy values for testing. + HTab* global = htab_init(); + + // n = 42.02 + char* name = malloc(2); // TODO: Write a macro for this pattern. + strcpy(name, "n"); + AST* n = ast_init(AST_TYPE_VDEF, ast_vdef_data_init(name, + ast_init(AST_TYPE_NUM, ast_num_data_init(42.02)) + )); + + htab_ins(global, ((ASTVDefData*)n->data)->name, ((ASTVDefData*)n->data)->val); + + // Push global namespace to `scope`. + stack_push(scope, global); + + return exec_exp(ast, scope); +} + +ASTNumData exec_exp(AST* ast, Stack* scope) { log_dbg("Started execution."); switch (ast->type) { - case AST_TYPE_CALL: return exec_call(ast); + case AST_TYPE_CALL: return exec_call(ast, scope); case AST_TYPE_NUM: return *(ASTNumData*)ast->data; - case AST_TYPE_VREF: return exec_vref(ast); - case AST_TYPE_VDEF: return exec_vdef(ast); + case AST_TYPE_VREF: return exec_vref(ast, scope); + case AST_TYPE_VDEF: return exec_vdef(ast, scope); default: printf("what\n"); exit(1); } } -ASTNumData exec_call(AST* ast) { +ASTNumData exec_call(AST* ast, Stack* scope) { log_dbg("Started call execution."); fflush(stdout); ASTCallData* calldata = (ASTCallData*)ast->data; if (calldata->argc >= 1) { if (!strcmp(calldata->to, "sum")) { - double total = exec_exp(calldata->argv[0]); + double total = exec_exp(calldata->argv[0], scope); for ( size_t i = 1; i < calldata->argc; - total += exec_exp(calldata->argv[i++]) + total += exec_exp(calldata->argv[i++], scope) ); return total; } else if (!strcmp(calldata->to, "sub")) { - double total = exec_exp(calldata->argv[0]); + double total = exec_exp(calldata->argv[0], scope); for ( size_t i = 1; i < calldata->argc; - total -= exec_exp(calldata->argv[i++]) + total -= exec_exp(calldata->argv[i++], scope) ); return total; } else if (!strcmp(calldata->to, "mul")) { - double total = exec_exp(calldata->argv[0]); + double total = exec_exp(calldata->argv[0], scope); for ( size_t i = 1; i < calldata->argc; - total *= exec_exp(calldata->argv[i++]) + total *= exec_exp(calldata->argv[i++], scope) ); return total; } else if (!strcmp(calldata->to, "div")) { - double total = exec_exp(calldata->argv[0]); + double total = exec_exp(calldata->argv[0], scope); for ( size_t i = 1; i < calldata->argc; - total /= exec_exp(calldata->argv[i++]) + total /= exec_exp(calldata->argv[i++], scope) ); return total; @@ -69,14 +93,25 @@ ASTNumData exec_call(AST* ast) { return -1000; } -ASTNumData exec_vdef(AST* ast) { +ASTNumData exec_vdef(AST* ast, Stack* scope) { ASTVDefData* data = (ASTVDefData*) ast->data; AST* val = data->val; - return exec_exp(val); + char* key = data->name; + htab_ins(scope->val[0], key, val); + return exec_exp(val, scope); } -ASTNumData exec_vref(AST* ast) { - return *ast_num_data_init(42.42); +ASTNumData exec_vref(AST* ast, Stack* scope) { + log_dbg("attempting to reference var"); + ASTVrefData* vref = (ASTVrefData*) ast->data; + + char* key = vref->to; + AST* val; + + val = htab_get(scope->val[0], key); + if (val != NULL) return exec_exp(val, scope); else log_dbg("didn't find def"); + + return *ast_num_data_init(101.0); } void exec_print(double n) { printf("= %lf\n", n); } diff --git a/src/grammar.y b/src/grammar.y index 839a707..d98eb38 100644 --- a/src/grammar.y +++ b/src/grammar.y @@ -124,9 +124,9 @@ exp: } // Variable reference. - //| WORD { - // $$ = ast_init(AST_TYPE_VREF, ast_vref_data_init($1)); - //} + | WORD { + $$ = ast_init(AST_TYPE_VREF, ast_vref_data_init($1)); + } | WORD GROUPS arg GROUPE { size_t argc = $3->ln; diff --git a/src/include/exec.h b/src/include/exec.h index 4caaeca..657e07e 100644 --- a/src/include/exec.h +++ b/src/include/exec.h @@ -2,11 +2,15 @@ #define EXEC_H #include "ast.h" +#include "stack.h" -ASTNumData exec_exp(AST* ast); -ASTNumData exec_call(AST* ast); -ASTNumData exec_vref(AST* ast); -ASTNumData exec_vdef(AST* ast); + +// Start executing at the root of the AST. Initialize the `scope`. +ASTNumData exec_start(AST* ast); +ASTNumData exec_exp(AST* ast, Stack* scope); +ASTNumData exec_call(AST* ast, Stack* scope); +ASTNumData exec_vref(AST* ast, Stack* scope); +ASTNumData exec_vdef(AST* ast, Stack* scope); void exec_print(double n); #endif diff --git a/src/include/stack.h b/src/include/stack.h index 4962368..5a68611 100644 --- a/src/include/stack.h +++ b/src/include/stack.h @@ -10,14 +10,15 @@ typedef struct { void* val[STACK_MAX]; // The stack itself. } Stack; +// Create a `Stack`. Stack* stack_init(); -// Destroy a stack. -// Note that `stack->i` must be `0`. +// Destroy a `Stack`. +// Note that `->i` must be `0`, i.e. the `Stack` must be empty. void stack_destroy(Stack* stack); -// Push a value to the stack. +// Push a value to the `Stack`. void stack_push(Stack* stack, void* val); -// Pop a value from the stack. +// Pop a value from the `Stack`. void* stack_pop(Stack* stack); #endif diff --git a/src/main.c b/src/main.c index 527aa60..89618ed 100644 --- a/src/main.c +++ b/src/main.c @@ -19,7 +19,7 @@ int main(int argc, char** argv) { if (argc - 1 && strlen(argv[1]) > 0 && (inp = argv[1]) && !yyparse()) { log_dbg("Parsed successfully!\n"); - exec_print(exec_exp(root)); + exec_print(exec_start(root)); ast_destroy(root); exit(0); } @@ -51,7 +51,7 @@ int main(int argc, char** argv) { log_dbg("Parsed successfully!\n"); } else printf("Parse error.\n"); - exec_print(exec_exp(root)); + exec_print(exec_start(root)); #ifdef DBG ast_print(root); #endif