diff options
author | Tucker Evans <tuckerevans24@gmail.com> | 2019-09-04 13:20:05 -0400 |
---|---|---|
committer | Tucker Evans <tuckerevans24@gmail.com> | 2019-09-04 13:20:05 -0400 |
commit | 30a16a2fdfd527e89a83f49f53cb448aafcb4e9a (patch) | |
tree | 284a664cee7b5e53bdaf1fe560c1a80e950f058c /sem_check.c | |
parent | 7e29eae526f7a5014934b92a239923dd30835afd (diff) | |
parent | 4fced0fc39d3aeacb3c6d434aeeb622468a857cc (diff) |
Merge branch 'type_checking' into func-array_info
Diffstat (limited to 'sem_check.c')
-rw-r--r-- | sem_check.c | 149 |
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; + +} + |