aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--pc.y9
-rw-r--r--sem_check.c27
-rw-r--r--sem_check.h1
3 files changed, 37 insertions, 0 deletions
diff --git a/pc.y b/pc.y
index da58fb5..32be027 100644
--- a/pc.y
+++ b/pc.y
@@ -92,6 +92,8 @@ extern scope *cur_scope;
%type <ival> TD
+%type <sval> sub_prog_head
+
%%
program
@@ -181,6 +183,9 @@ sub_prog_declaration
sub_prog_declarations
compound_statement
{
+ if ($1)
+ check_func_return($4, $1);
+
set_ret_type($4);
#ifdef DEBUG
print_tree($4);
@@ -219,6 +224,8 @@ sub_prog_head
* scope*/
cur_scope->ret_var = scope_insert(cur_scope, strdup($2));
cur_scope->ret_var->var_type = $5;
+
+ $$ = $2;
}
|PROC ID arguments ';'
{
@@ -237,6 +244,8 @@ sub_prog_head
assert(!set_func_types($3, tmp->func_info->argv, i));
free_tree($3);
+
+ $$ = NULL;
}
;
diff --git a/sem_check.c b/sem_check.c
index fd85c98..e30d8c5 100644
--- a/sem_check.c
+++ b/sem_check.c
@@ -206,3 +206,30 @@ ptree *t;
yyerror("Incorrect types in fuction arguments");
}
+
+int func_ret(t, name)
+ptree *t;
+char *name;
+{
+ if (!t)
+ return 0;
+
+ if (t->type == ASSIGNOP && t->l)
+ if (t->l->type == ID && !strcmp(t->l->attr.nval->name, name))
+ return 1;
+
+ return func_ret(t->l, name) || func_ret(t->r, name);
+}
+
+void check_func_return(t,name)
+ptree *t;
+char *name;
+{
+ char buf[100];
+
+ if (!func_ret(t,name)) {
+ snprintf(buf, 100, "Function %s does not return a value\n",
+ name);
+ yyerror(buf);
+ }
+}
diff --git a/sem_check.h b/sem_check.h
index 0da2cc9..8f5394a 100644
--- a/sem_check.h
+++ b/sem_check.h
@@ -12,4 +12,5 @@ int check_ret_type(ptree*);
void check_call(ptree*);
+void check_func_return(ptree*, char*);
#endif