aboutsummaryrefslogtreecommitdiffstats
path: root/src/parser.c
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 /src/parser.c
parent45920c8340d2aa5a3c40a3c8aad519fa998bb50b (diff)
downloadbdl-3821eaa48ca56791cb5c9b85da70dde052d6c7ef.tar.gz
bdl-3821eaa48ca56791cb5c9b85da70dde052d6c7ef.zip
Add support for accessing procedure parameters
Diffstat (limited to 'src/parser.c')
-rw-r--r--src/parser.c28
1 files changed, 23 insertions, 5 deletions
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);