aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--main.c26
-rw-r--r--pc.h1
-rw-r--r--pc.y5
-rw-r--r--sem_check.c32
-rw-r--r--tree.c11
5 files changed, 69 insertions, 6 deletions
diff --git a/main.c b/main.c
index 394e3bc..43eef9e 100644
--- a/main.c
+++ b/main.c
@@ -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
diff --git a/pc.h b/pc.h
index 653b720..79174f4 100644
--- a/pc.h
+++ b/pc.h
@@ -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
diff --git a/pc.y b/pc.y
index f97db8d..8d142a2 100644
--- a/pc.y
+++ b/pc.y
@@ -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");
+
+}
diff --git a/tree.c b/tree.c
index d1d0e76..a1a3f0f 100644
--- a/tree.c
+++ b/tree.c
@@ -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);