diff options
author | Tucker Evans <tuckerevans24@gmail.com> | 2019-10-02 15:31:12 -0400 |
---|---|---|
committer | Tucker Evans <tuckerevans24@gmail.com> | 2019-10-02 15:35:11 -0400 |
commit | e398b0beb33047b22a73d2d6a4302996dcdda67a (patch) | |
tree | b3344104febc78ad70806fcb11af5870b98fa49d | |
parent | 59f7f4ccb71eb489690ada8821977455ab377699 (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.y | 41 | ||||
-rw-r--r-- | scope.c | 3 |
2 files changed, 27 insertions, 17 deletions
@@ -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); } @@ -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); |