aboutsummaryrefslogtreecommitdiff
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
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.
-rw-r--r--pc.y41
-rw-r--r--scope.c3
2 files changed, 27 insertions, 17 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);
}
diff --git a/scope.c b/scope.c
index ef9e4f5..d7d50fc 100644
--- a/scope.c
+++ b/scope.c
@@ -105,9 +105,6 @@ char *name;
int hash;
node *tmp;
- if (root->ret_var && !strcmp(root->ret_var->name, name))
- return root->ret_var;
-
hash = hashpjw(name);
tmp = root->table[hash];
return list_search(tmp, name);