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 /src/parser.c | |
parent | 45920c8340d2aa5a3c40a3c8aad519fa998bb50b (diff) | |
download | bdl-3821eaa48ca56791cb5c9b85da70dde052d6c7ef.tar.gz bdl-3821eaa48ca56791cb5c9b85da70dde052d6c7ef.zip |
Add support for accessing procedure parameters
Diffstat (limited to 'src/parser.c')
-rw-r--r-- | src/parser.c | 28 |
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 | ||
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); |