aboutsummaryrefslogtreecommitdiff
path: root/sem_check.c
diff options
context:
space:
mode:
authorTucker Evans <tuckerevans24@gmail.com>2019-09-04 13:20:05 -0400
committerTucker Evans <tuckerevans24@gmail.com>2019-09-04 13:20:05 -0400
commit30a16a2fdfd527e89a83f49f53cb448aafcb4e9a (patch)
tree284a664cee7b5e53bdaf1fe560c1a80e950f058c /sem_check.c
parent7e29eae526f7a5014934b92a239923dd30835afd (diff)
parent4fced0fc39d3aeacb3c6d434aeeb622468a857cc (diff)
Merge branch 'type_checking' into func-array_info
Diffstat (limited to 'sem_check.c')
-rw-r--r--sem_check.c149
1 files changed, 145 insertions, 4 deletions
diff --git a/sem_check.c b/sem_check.c
index 637d044..aa83155 100644
--- a/sem_check.c
+++ b/sem_check.c
@@ -1,12 +1,10 @@
+#include "sem_check.h"
+
#include <assert.h>
#include <stdio.h>
-#include "node.h"
-#include "scope.h"
-#include "tree.h"
#include "y.tab.h"
#include "pc.h"
-#include "sem_check.h"
void check_id(s, n)
scope *s;
@@ -34,3 +32,146 @@ char *n;
return tmp;
}
+
+int check_ret_type(t)
+ptree *t;
+{
+ char buf[100];
+ int type;
+
+ if (!t)
+ fprintf(stderr, "TYPE: %d\n", t->type);
+
+ switch (t->type) {
+ case ID:
+ if (!(t->attr.nval))
+ yyerror("Missing ID\n");
+
+ return t->attr.nval->var_type;
+
+ case ADDOP :
+ case MULOP :
+ if (!(t->r && t->l))
+ yyerror("Missing nodes\n");
+
+ if (t->attr.opval == AND || t->attr.opval == OR) {
+ if(t->l->ret_type == BOOL && t->r->ret_type ==BOOL)
+ return BOOL;
+ else {
+ type = t->l->ret_type == BOOL ?
+ t->r->ret_type : t->l->ret_type;
+
+ snprintf(buf, 100, "Mismached types:"
+ "Cannot use boolean "
+ "operator on type %s\n",
+ pretty_type(type));
+ break;
+ }
+ }
+
+ if (t->r->ret_type == t->l->ret_type)
+ return t->r->ret_type;
+ else
+ snprintf(buf, 100, "Mismached types: "
+ "Type %s "
+ "cannot be used with type %s\n",
+ pretty_type(t->r->ret_type),
+ pretty_type(t->l->ret_type));
+
+ break;
+ case RELOP :
+ if (!(t->r && t->l))
+ yyerror("Missing nodes\n");
+ if (t->r->ret_type == t->l->ret_type)
+ return BOOL;
+ else
+ snprintf(buf, 100, "Mismached types: "
+ "Type %s "
+ "cannot be compared to type %s\n",
+ pretty_type(t->r->ret_type),
+ pretty_type(t->l->ret_type));
+ break;
+ case NOT:
+ if (t->l && t->l->ret_type == BOOL)
+ return BOOL;
+ yyerror("NOT needs bool input\n");
+ break;
+ case INUM:
+ return INT;
+ case RNUM:
+ return REAL;
+ case ASSIGNOP:
+ if (!(t->r && t->l))
+ yyerror("Incomplete parse tree\n");
+
+ if (t->l->ret_type == t->r->ret_type)
+ return 1;
+ else
+ snprintf(buf, 100, "Mismached types: "
+ "Cannot assign type %s "
+ "to variable \"%s\" of type %s\n",
+ 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))
+ yyerror("Incorrect Array Access\n");
+
+ if (t->r->ret_type != INT) {
+ snprintf(buf, 100, "Cannot access array"
+ "with type %s\n",
+ pretty_type(t->r->ret_type));
+ break;
+ }
+
+ type = t->l->attr.nval -> var_type;
+ if (type == ARRAY - INT || type == ARRAY - REAL)
+ return ARRAY - type;
+ break;
+ case IF:
+ case WHILE:
+ if (!(t->r && t->l))
+ yyerror("Incomplete parse tree\n");
+
+ if (t->l->ret_type != BOOL)
+ yyerror("If condition must be of type BOOL\n");
+ return 1;
+ case FOR:
+ /*
+ FOR (0)
+ / \
+ TD(0) STATEMENT(0)
+ / \
+ ASSIGNOP(0) INUM(INT)
+ */
+ if (!(t->r && t->l))
+ yyerror("Missing nodes\n");
+ if (t->l->ret_type == 1 && t->r->ret_type == 1)
+ return 1;
+ snprintf(buf, 100, "Incorrect types in for statement...\n");
+ break;
+ case TO:
+ case DT:
+ if (!(t->r && t->l))
+ yyerror("Missing nodes\n");
+
+ if (t->l->ret_type == 1 && t->r->ret_type == INT)
+ return 1;
+ snprintf(buf, 100, "Incorrect types HERE...\n");
+ case SUB:
+ return t->l->ret_type;
+ break;
+ default:
+ return -200;
+ snprintf(buf, 100, "Unknown tree node: %d...\n", t->type);
+ }
+
+ yyerror(buf);
+ return -1;
+
+}
+