From 09406d74711fd241a16f4e0d4cc76bfa11e42a60 Mon Sep 17 00:00:00 2001 From: Bad Diode Date: Wed, 10 Nov 2021 17:13:56 +0100 Subject: Add initial local definition/access --- src/compiler.h | 39 +++++++++++++++++++++++++++++++++++---- src/main.c | 2 +- src/parser.c | 5 +++-- 3 files changed, 39 insertions(+), 7 deletions(-) diff --git a/src/compiler.h b/src/compiler.h index fe36ecf..023a039 100644 --- a/src/compiler.h +++ b/src/compiler.h @@ -23,6 +23,7 @@ do { \ array_insert(current_context, buf, n_chars); \ } while(false); +static Environment *current_env = NULL; // TODO: Separate c/h files // TODO: Create a "driver.c" file with the (display) function for external @@ -51,7 +52,7 @@ do { \ void compile_object(Object *obj); void compile_fixnum(Object *obj); void compile_proc_call(Object *obj); -void compile(Root *roots); +void compile(Program program); char * generate_label(char *prefix) { @@ -505,6 +506,25 @@ compile_lambda(Object *obj) { context_printf(" ;; <-- compile_lambda\n"); } +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); + context_printf(" pop rax\n"); + context_printf(" mov [rbp + %ld], rax\n", 8 * (idx + 1)); + context_printf(" ;; <-- compile_def\n"); +} + +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 + 1)); + context_printf(" push rax\n"); + context_printf(" ;; <-- compile_symbol\n"); +} + void compile_object(Object *obj) { switch (obj->type) { @@ -516,6 +536,8 @@ compile_object(Object *obj) { case OBJ_TYPE_STRING: { compile_string(obj); } break; case OBJ_TYPE_IF: { compile_if(obj); } break; case OBJ_TYPE_LAMBDA: { compile_lambda(obj); } break; + case OBJ_TYPE_DEF: { compile_def(obj); } break; + case OBJ_TYPE_SYMBOL: { compile_symbol(obj); } break; default: break; } } @@ -555,16 +577,17 @@ emit_data_section(void) { } void -compile(Root *roots) { +compile(Program program) { // Prepare compilation variables. array_init(constants, 0); array_init(labels, 0); array_init(procedures, 0); array_init(current_context, 0); + current_env = program.env; // Compile program. - for (size_t i = 0; i < array_size(roots); i++) { - Object *root = roots[i]; + for (size_t i = 0; i < array_size(program.roots); i++) { + Object *root = program.roots[i]; compile_object(root); } @@ -604,7 +627,15 @@ compile(Root *roots) { printf("alignb 8\n"); printf("global _start\n"); printf("_start:\n"); + + // Initialize heap pointer. printf(" mov r15, bdl_heap\n"); + + // Initialize main locals. + printf(" sub rsp, %zu\n", 8 * array_size(program.env->locals)); + printf(" mov rbp, rsp\n"); + + // Keep the bottom stack value set as NIL_VAL for a default return value. printf(" push NIL_VAL\n"); for (size_t i = 0; i < array_size(current_context); i++) { putchar(current_context[i]); diff --git a/src/main.c b/src/main.c index 8962519..d006d2d 100644 --- a/src/main.c +++ b/src/main.c @@ -45,7 +45,7 @@ process_source(const StringView *source, const char *file_name) { // TODO: Optimization. // Compilation. - compile(program.roots); + compile(program); // Free resources. free_objects(); diff --git a/src/parser.c b/src/parser.c index 100916b..2bf95d4 100644 --- a/src/parser.c +++ b/src/parser.c @@ -569,6 +569,7 @@ parse(Token *tokens, Errors *errors) { // Prepare global environment of builtin functions. Environment *global_env = env_alloc(NULL); + Environment *env = env_alloc(global_env); size_t n_builtins = sizeof(builtins) / sizeof(char*); for (size_t i = 0; i < n_builtins; i++) { // Prepare builtin symbol. @@ -600,7 +601,7 @@ parse(Token *tokens, Errors *errors) { } } array_push(final_roots, root); - semantic_analysis(global_env, root, errors); + semantic_analysis(env, root, errors); if (errors->n != 0) { array_free(final_roots); return (Program){0}; @@ -614,7 +615,7 @@ parse(Token *tokens, Errors *errors) { // TODO: Type check basic expressions (e.g. arithmetic/numeric comparisons). // We can't be sure when we have functions unless the return type is known. - return (Program){roots, global_env}; + return (Program){roots, env}; } Environment * -- cgit v1.2.1