aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorBad Diode <bd@badd10de.dev>2021-11-10 18:16:34 +0100
committerBad Diode <bd@badd10de.dev>2021-11-10 18:16:34 +0100
commit3821eaa48ca56791cb5c9b85da70dde052d6c7ef (patch)
tree29ffb560968006159f4a533a76f1d62811af8fdf
parent45920c8340d2aa5a3c40a3c8aad519fa998bb50b (diff)
downloadbdl-3821eaa48ca56791cb5c9b85da70dde052d6c7ef.tar.gz
bdl-3821eaa48ca56791cb5c9b85da70dde052d6c7ef.zip
Add support for accessing procedure parameters
-rw-r--r--src/compiler.h17
-rw-r--r--src/parser.c28
-rw-r--r--src/parser.h1
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
515compile_def(Object *obj) { 515compile_def(Object *obj) {
516 context_printf(" ;; --> compile_def\n"); 516 context_printf(" ;; --> compile_def\n");
517 compile_object(obj->var_expr); 517 compile_object(obj->var_expr);
518 ssize_t idx = find_local_index(current_env->locals, obj->var_name); 518 ssize_t idx = find_var_index(current_env->locals, obj->var_name);
519 context_printf(" pop rax\n"); 519 context_printf(" pop rax\n");
520 context_printf(" mov [rbp + %ld], rax\n", 8 * idx); 520 context_printf(" mov [rbp + %ld], rax\n", 8 * idx);
521 compile_nil(); 521 compile_nil();
@@ -525,8 +525,19 @@ compile_def(Object *obj) {
525void 525void
526compile_symbol(Object *obj) { 526compile_symbol(Object *obj) {
527 context_printf(" ;; --> compile_symbol\n"); 527 context_printf(" ;; --> compile_symbol\n");
528 ssize_t idx = find_local_index(current_env->locals, obj); 528 ssize_t idx = find_var_index(current_env->locals, obj);
529 context_printf(" mov rax, [rbp + %ld]\n", 8 * idx); 529 if (idx != -1) {
530 context_printf(" mov rax, [rbp + %ld]\n", 8 * idx);
531 context_printf(" push rax\n");
532 context_printf(" ;; <-- compile_symbol\n");
533 return;
534 }
535 idx = find_var_index(current_env->params, obj);
536 assert(idx != -1 && "unexpected index");
537 size_t n_locals = array_size(current_env->locals);
538 size_t n_params = array_size(current_env->params);
539 size_t offset = 8 * (n_locals + n_params - idx + 1);
540 context_printf(" mov rax, [rbp + %ld]\n", offset);
530 context_printf(" push rax\n"); 541 context_printf(" push rax\n");
531 context_printf(" ;; <-- compile_symbol\n"); 542 context_printf(" ;; <-- compile_symbol\n");
532} 543}
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) {
429} 429}
430 430
431ssize_t 431ssize_t
432find_local_index(Object **locals, Object *symbol) { 432find_var_index(Object **vars, Object *symbol) {
433 for (size_t i = 0; i < array_size(locals); i++) { 433 for (size_t i = 0; i < array_size(vars); i++) {
434 if (object_equal(locals[i], symbol)) { 434 if (object_equal(vars[i], symbol)) {
435 return i; 435 return i;
436 } 436 }
437 } 437 }
@@ -441,10 +441,14 @@ find_local_index(Object **locals, Object *symbol) {
441Object * 441Object *
442symbol_in_env(Environment *env, Object *symbol) { 442symbol_in_env(Environment *env, Object *symbol) {
443 while (env != NULL) { 443 while (env != NULL) {
444 ssize_t idx = find_local_index(env->locals, symbol); 444 ssize_t idx = find_var_index(env->locals, symbol);
445 if (idx != -1) { 445 if (idx != -1) {
446 return env->locals[idx]; 446 return env->locals[idx];
447 } 447 }
448 idx = find_var_index(env->params, symbol);
449 if (idx != -1) {
450 return env->params[idx];
451 }
448 env = env->parent; 452 env = env->parent;
449 } 453 }
450 return NULL; 454 return NULL;
@@ -452,13 +456,21 @@ symbol_in_env(Environment *env, Object *symbol) {
452 456
453void 457void
454insert_local(Environment *env, Object *symbol) { 458insert_local(Environment *env, Object *symbol) {
455 if (find_local_index(env->locals, symbol) != -1) { 459 if (find_var_index(env->locals, symbol) != -1) {
456 return; 460 return;
457 } 461 }
458 array_push(env->locals, symbol); 462 array_push(env->locals, symbol);
459} 463}
460 464
461void 465void
466insert_params(Environment *env, Object *symbol) {
467 if (find_var_index(env->params, symbol) != -1) {
468 return;
469 }
470 array_push(env->params, symbol);
471}
472
473void
462semantic_analysis(Environment *env, Object *obj, Errors *errors) { 474semantic_analysis(Environment *env, Object *obj, Errors *errors) {
463 if (obj == NULL || obj->visited) { 475 if (obj == NULL || obj->visited) {
464 return; 476 return;
@@ -523,6 +535,9 @@ semantic_analysis(Environment *env, Object *obj, Errors *errors) {
523 // Initialize scope for this lambda. 535 // Initialize scope for this lambda.
524 Environment *new_env = env_alloc(env); 536 Environment *new_env = env_alloc(env);
525 obj->env = new_env; 537 obj->env = new_env;
538 for (size_t i = 0; i < array_size(obj->params); i++) {
539 insert_params(obj->env, obj->params[i]);
540 }
526 // Used for removing unnecessary statements. 541 // Used for removing unnecessary statements.
527 Object **new_body = NULL; 542 Object **new_body = NULL;
528 array_init(new_body, 0); 543 array_init(new_body, 0);
@@ -622,7 +637,9 @@ Environment *
622env_alloc(Environment *parent) { 637env_alloc(Environment *parent) {
623 Environment *env = malloc(sizeof(Environment)); 638 Environment *env = malloc(sizeof(Environment));
624 env->locals = NULL; 639 env->locals = NULL;
640 env->params = NULL;
625 array_init(env->locals, 0); 641 array_init(env->locals, 0);
642 array_init(env->params, 0);
626 env->parent = parent; 643 env->parent = parent;
627 array_push(environments, env); 644 array_push(environments, env);
628 return env; 645 return env;
@@ -663,6 +680,7 @@ free_objects(void) {
663 for (size_t i = 0; i < array_size(environments); i++) { 680 for (size_t i = 0; i < array_size(environments); i++) {
664 Environment *env = environments[i]; 681 Environment *env = environments[i];
665 array_free(env->locals); 682 array_free(env->locals);
683 array_free(env->params);
666 free(env); 684 free(env);
667 } 685 }
668 array_free(environments); 686 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 @@
5 5
6typedef struct Environment { 6typedef struct Environment {
7 struct Object **locals; 7 struct Object **locals;
8 struct Object **params;
8 struct Environment *parent; 9 struct Environment *parent;
9} Environment; 10} Environment;
10 11