diff options
author | Tucker Evans <tuckerevans24@gmail.com> | 2019-09-08 21:18:44 -0400 |
---|---|---|
committer | Tucker Evans <tuckerevans24@gmail.com> | 2019-09-08 21:59:41 -0400 |
commit | 948b0460c9d079e5eff4e6247d35aa946956e4a5 (patch) | |
tree | bc3bef845747f28474327779e891a1a2fa07a7e6 | |
parent | ecfd5f25bfa7b5ce00b8feb83eb1deeb7009e7f7 (diff) |
Add checking types on function call
-rw-r--r-- | main.c | 26 | ||||
-rw-r--r-- | pc.h | 1 | ||||
-rw-r--r-- | pc.y | 5 | ||||
-rw-r--r-- | sem_check.c | 32 | ||||
-rw-r--r-- | tree.c | 11 |
5 files changed, 69 insertions, 6 deletions
@@ -145,9 +145,10 @@ ptree *t; if (t->type == LIST){ r = count_args(t->r); l = count_args(t->l); - } else if (t->type == ID) { + } else if (t->type != LIST) { return 1; } else { + fprintf(stderr, "PTR: %x\n", t); yyerror("NOT A PARAMETER LIST\n"); } @@ -177,6 +178,29 @@ int size, *nxt; return size; } +int get_call_types(t, nxt, size) +ptree *t; +int size, *nxt; +{ + int tmp; + + if (!t) + return size; + + if (t->type == LIST){ + tmp = set_func_types(t->l, nxt, size); + for (;size > tmp; --size) ++nxt; + size = set_func_types(t->r, nxt, size); + } else { + if (--size == -1) + yyerror("VARIABLE COUNT CHANGED!!!\n"); + set_ret_type(t); + *nxt = t->ret_type; + return size; + } + return size; +} + int main() { #ifdef DEBUG_TYPES @@ -12,6 +12,7 @@ int yyerror(char*); int count_args(ptree*); int set_func_types(ptree*, int*, int); +int get_call_types(ptree*, int*, int); #endif #define DEBUG @@ -216,7 +216,9 @@ arguments { $$ = $2; } - |/*empty*/ + |/*empty*/{ + $$ = NULL; + } ; param_list @@ -411,6 +413,7 @@ factor tmp = check_exists(cur_scope, $1); $$ = mktree(FCALL, mkid(tmp), $3); + check_call($$); } |INUM { diff --git a/sem_check.c b/sem_check.c index aa83155..f6e412a 100644 --- a/sem_check.c +++ b/sem_check.c @@ -2,6 +2,8 @@ #include <assert.h> #include <stdio.h> +#include <stdlib.h> +#include <string.h> #include "y.tab.h" #include "pc.h" @@ -113,9 +115,6 @@ ptree *t; pretty_type(t->r->ret_type), t->l->attr.nval->name, pretty_type(t->l->attr.nval->var_type)); - - - break; case ARRAY_ACCESS: if (!(t->r && t->l && t->l->attr.nval)) @@ -165,6 +164,10 @@ ptree *t; case SUB: return t->l->ret_type; break; + case PCALL: + case FCALL: + if (t->l && t->l->attr.nval) + return t->l->attr.nval->var_type; default: return -200; snprintf(buf, 100, "Unknown tree node: %d...\n", t->type); @@ -175,3 +178,26 @@ ptree *t; } +void check_call(t) +ptree *t; +{ + int argc, *argv; + + print_tree(t); + if (!(t && t->attr.nval && t->attr.nval->func_info)) + yyerror("Tree is not a function call\n"); + + argc = t->l->attr.nval->func_info->argc; + if (t->l->attr.nval->func_info->argc != count_args(t->r)) + /*TODO add info about expected argument count*/ + yyerror("Incorrect argument count"); + + assert(argv = malloc(sizeof(int) * argc)); + + get_call_types(t->r, argv, argc); + + if (memcmp(argv, t->l->attr.nval->func_info->argv, argc * sizeof(int))) + /*TODO add info on which argument causes error*/ + yyerror("Incorrect types in fuction arguments"); + +} @@ -148,6 +148,10 @@ int spaces; t->attr.nval->name, pretty_type( t->attr.nval->var_type)); + if (t->attr.nval->func_info) + fprintf(stderr, "\t %d", + t->attr.nval->func_info->argc); + fprintf(stderr, "]"); break; case INUM: fprintf(stderr, "[INUM: %d]", t->attr.ival); @@ -179,8 +183,13 @@ int spaces; case SUB: fprintf(stderr, "[SUB]"); break; + case PCALL: + fprintf(stderr,"[P]"); + case FCALL: + fprintf(stderr, "[CALL]"); + break; default: - fprintf(stderr, "\t%d", t->type); + fprintf(stderr, "[?: %d]", t->type); yyerror("Error in tree_print"); } fprintf(stderr," %d\n", t->ret_type); |