From 3821eaa48ca56791cb5c9b85da70dde052d6c7ef Mon Sep 17 00:00:00 2001 From: Bad Diode Date: Wed, 10 Nov 2021 18:16:34 +0100 Subject: Add support for accessing procedure parameters --- src/compiler.h | 17 ++++++++++++++--- src/parser.c | 28 +++++++++++++++++++++++----- src/parser.h | 1 + 3 files changed, 38 insertions(+), 8 deletions(-) diff --git a/src/compiler.h b/src/compiler.h index 14c6954..2a44220 100644 --- a/src/compiler.h +++ b/src/compiler.h @@ -515,7 +515,7 @@ void compile_def(Object *obj) { context_printf(" ;; --> compile_def\n"); compile_object(obj->var_expr); - ssize_t idx = find_local_index(current_env->locals, obj->var_name); + ssize_t idx = find_var_index(current_env->locals, obj->var_name); context_printf(" pop rax\n"); context_printf(" mov [rbp + %ld], rax\n", 8 * idx); compile_nil(); @@ -525,8 +525,19 @@ compile_def(Object *obj) { void compile_symbol(Object *obj) { context_printf(" ;; --> compile_symbol\n"); - ssize_t idx = find_local_index(current_env->locals, obj); - context_printf(" mov rax, [rbp + %ld]\n", 8 * idx); + ssize_t idx = find_var_index(current_env->locals, obj); + if (idx != -1) { + context_printf(" mov rax, [rbp + %ld]\n", 8 * idx); + context_printf(" push rax\n"); + context_printf(" ;; <-- compile_symbol\n"); + return; + } + idx = find_var_index(current_env->params, obj); + assert(idx != -1 && "unexpected index"); + size_t n_locals = array_size(current_env->locals); + size_t n_params = array_size(current_env->params); + size_t offset = 8 * (n_locals + n_params - idx + 1); + context_printf(" mov rax, [rbp + %ld]\n", offset); context_printf(" push rax\n"); context_printf(" ;; <-- compile_symbol\n"); } diff --git a/src/parser.c b/src/parser.c index 2bf95d4..5bb7393 100644 --- a/src/parser.c +++ b/src/parser.c @@ -429,9 +429,9 @@ parse_tree(Parser *parser, Errors *errors) { } ssize_t -find_local_index(Object **locals, Object *symbol) { - for (size_t i = 0; i < array_size(locals); i++) { - if (object_equal(locals[i], symbol)) { +find_var_index(Object **vars, Object *symbol) { + for (size_t i = 0; i < array_size(vars); i++) { + if (object_equal(vars[i], symbol)) { return i; } } @@ -441,10 +441,14 @@ find_local_index(Object **locals, Object *symbol) { Object * symbol_in_env(Environment *env, Object *symbol) { while (env != NULL) { - ssize_t idx = find_local_index(env->locals, symbol); + ssize_t idx = find_var_index(env->locals, symbol); if (idx != -1) { return env->locals[idx]; } + idx = find_var_index(env->params, symbol); + if (idx != -1) { + return env->params[idx]; + } env = env->parent; } return NULL; @@ -452,12 +456,20 @@ symbol_in_env(Environment *env, Object *symbol) { void insert_local(Environment *env, Object *symbol) { - if (find_local_index(env->locals, symbol) != -1) { + if (find_var_index(env->locals, symbol) != -1) { return; } array_push(env->locals, symbol); } +void +insert_params(Environment *env, Object *symbol) { + if (find_var_index(env->params, symbol) != -1) { + return; + } + array_push(env->params, symbol); +} + void semantic_analysis(Environment *env, Object *obj, Errors *errors) { if (obj == NULL || obj->visited) { @@ -523,6 +535,9 @@ semantic_analysis(Environment *env, Object *obj, Errors *errors) { // Initialize scope for this lambda. Environment *new_env = env_alloc(env); obj->env = new_env; + for (size_t i = 0; i < array_size(obj->params); i++) { + insert_params(obj->env, obj->params[i]); + } // Used for removing unnecessary statements. Object **new_body = NULL; array_init(new_body, 0); @@ -622,7 +637,9 @@ Environment * env_alloc(Environment *parent) { Environment *env = malloc(sizeof(Environment)); env->locals = NULL; + env->params = NULL; array_init(env->locals, 0); + array_init(env->params, 0); env->parent = parent; array_push(environments, env); return env; @@ -663,6 +680,7 @@ free_objects(void) { for (size_t i = 0; i < array_size(environments); i++) { Environment *env = environments[i]; array_free(env->locals); + array_free(env->params); free(env); } array_free(environments); diff --git a/src/parser.h b/src/parser.h index c117c61..2c5cb61 100644 --- a/src/parser.h +++ b/src/parser.h @@ -5,6 +5,7 @@ typedef struct Environment { struct Object **locals; + struct Object **params; struct Environment *parent; } Environment; -- cgit v1.2.1