aboutsummaryrefslogtreecommitdiff
path: root/pc.y
diff options
context:
space:
mode:
authorTucker Evans <tuckerevans24@gmail.com>2019-10-02 15:31:12 -0400
committerTucker Evans <tuckerevans24@gmail.com>2019-10-02 15:35:11 -0400
commite398b0beb33047b22a73d2d6a4302996dcdda67a (patch)
treeb3344104febc78ad70806fcb11af5870b98fa49d /pc.y
parent59f7f4ccb71eb489690ada8821977455ab377699 (diff)
Fix function recursion
Function were blocked from calling themselves because they could not look outside their scope. Functions are now duplicated to their scope to allow for recursion.
Diffstat (limited to 'pc.y')
-rw-r--r--pc.y41
1 files changed, 27 insertions, 14 deletions
diff --git a/pc.y b/pc.y
index 72ac10b..1ada604 100644
--- a/pc.y
+++ b/pc.y
@@ -203,26 +203,34 @@ sub_prog_head
:FUNC ID arguments ':' standard_type ';'
{
node *tmp;
- int i = 0;
+ int i, j;
+ scope *ss[2];
- check_id(cur_scope->prev, $2);
- tmp = scope_insert(cur_scope->prev, $2);
+ ss[0] = cur_scope->prev;
+ ss[1] = cur_scope;
- i = count_args($3);
+ /*Add function to both current and previous scope*/
+ for (j = 0; j < 2; j++) {
+ i = 0;
+ check_id(ss[j], $2);
+ tmp = scope_insert(ss[j], strdup($2));
- tmp->func_info = malloc(sizeof(struct fi));
- assert(tmp->func_info);
- tmp->func_info->argc = i;
- assert(tmp->func_info->argv = malloc(i * sizeof(int)));
+ i = count_args($3);
+
+ tmp->func_info = malloc(sizeof(struct fi));
+ assert(tmp->func_info);
+ tmp->func_info->argc = i;
+ assert(tmp->func_info->argv = malloc(i * sizeof(int)));
+
+ assert(!set_func_types($3, tmp->func_info->argv, i));
+ tmp->var_type = $5;
+ }
- assert(!set_func_types($3, tmp->func_info->argv, i));
free_tree($3);
- tmp->var_type = $5;
- /* Need to duplicate ID.name so it is not freed with inner
- * scope*/
- cur_scope->ret_var = mknode(strdup($2));
+ /* Fuction name already strdup for function, no need here*/
+ cur_scope->ret_var = mknode($2);
cur_scope->ret_var->var_type = $5;
$$ = $2;
@@ -369,7 +377,12 @@ var
:ID
{
node *tmp;
- tmp = check_exists(cur_scope, $1);
+ /*check for ret_var*/
+ if (cur_scope->ret_var &&
+ !strcmp(cur_scope->ret_var->name, $1))
+ tmp = cur_scope->ret_var;
+ else
+ tmp = check_exists(cur_scope, $1);
$$ = mkid(tmp);
free($1);
}