diff options
author | Bad Diode <bd@badd10de.dev> | 2021-11-10 18:16:34 +0100 |
---|---|---|
committer | Bad Diode <bd@badd10de.dev> | 2021-11-10 18:16:34 +0100 |
commit | 3821eaa48ca56791cb5c9b85da70dde052d6c7ef (patch) | |
tree | 29ffb560968006159f4a533a76f1d62811af8fdf | |
parent | 45920c8340d2aa5a3c40a3c8aad519fa998bb50b (diff) | |
download | bdl-3821eaa48ca56791cb5c9b85da70dde052d6c7ef.tar.gz bdl-3821eaa48ca56791cb5c9b85da70dde052d6c7ef.zip |
Add support for accessing procedure parameters
-rw-r--r-- | src/compiler.h | 17 | ||||
-rw-r--r-- | src/parser.c | 28 | ||||
-rw-r--r-- | 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 | |||
515 | compile_def(Object *obj) { | 515 | compile_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) { | |||
525 | void | 525 | void |
526 | compile_symbol(Object *obj) { | 526 | compile_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 | ||
431 | ssize_t | 431 | ssize_t |
432 | find_local_index(Object **locals, Object *symbol) { | 432 | find_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) { | |||
441 | Object * | 441 | Object * |
442 | symbol_in_env(Environment *env, Object *symbol) { | 442 | symbol_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 | ||
453 | void | 457 | void |
454 | insert_local(Environment *env, Object *symbol) { | 458 | insert_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 | ||
461 | void | 465 | void |
466 | insert_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 | |||
473 | void | ||
462 | semantic_analysis(Environment *env, Object *obj, Errors *errors) { | 474 | semantic_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 * | |||
622 | env_alloc(Environment *parent) { | 637 | env_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 | ||
6 | typedef struct Environment { | 6 | typedef 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 | ||