aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTucker Evans <tuckerevans24@gmail.com>2019-08-17 11:34:48 -0400
committerTucker Evans <tuckerevans24@gmail.com>2019-08-17 11:34:48 -0400
commit06ebf6a87ca1db975bdbf4f7f3126ea7c26ddde6 (patch)
tree03215f60ea0c776e60f38288470dac10546ad501
parentee6c598892518d956388bb008095de6d4d7fe123 (diff)
Add basic type checking
Squashed commit of WIP-type_check@5dadc4f5667ae69a709dd45c020780f2f424d67e
-rw-r--r--main.c56
-rw-r--r--pc.y3
-rw-r--r--sem_check.c76
-rw-r--r--sem_check.h2
-rw-r--r--tree.c63
-rw-r--r--tree.h2
6 files changed, 198 insertions, 4 deletions
diff --git a/main.c b/main.c
index 6ded432..da597eb 100644
--- a/main.c
+++ b/main.c
@@ -129,15 +129,65 @@ int yyerror(msg)
char* msg;
{
fprintf(stderr, "\nError, line %d: %s\n", line_num, msg);
-#ifdef DEBUG
- fprintf(stderr, "%s\n", yytext);
exit(1);
-#endif
return 0;
}
int main()
{
+#ifdef DEBUG_TYPES
+ printf(
+ "\nPROG\t\t%d\n"
+ "VAR\t\t%d\n"
+ "PROC\t\t%d\n"
+ "FUNC\t\t%d\n"
+ "BEG\t\t%d\n"
+ "END\t\t%d\n"
+ "ID\t\t%d\n"
+ "ADDOP\t\t%d\n"
+ "MULOP\t\t%d\n"
+ "RELOP\t\t%d\n"
+ "ASSIGNOP\t\t%d\n"
+ "ADD\t\t%d\n"
+ "SUB\t\t%d\n"
+ "MUL\t\t%d\n"
+ "DIV\t\t%d\n"
+ "NOT\t\t%d\n"
+ "AND\t\t%d\n"
+ "OR\t\t%d\n"
+ "EQ\t\t%d\n"
+ "NE\t\t%d\n"
+ "LT\t\t%d\n"
+ "LE\t\t%d\n"
+ "GT\t\t%d\n"
+ "GE\t\t%d\n"
+ "INUM\t\t%d\n"
+ "RNUM\t\t%d\n"
+ "INT\t\t%d\n"
+ "REAL\t\t%d\n"
+ "BOOL\t\t%d\n"
+ "ARRAY\t\t%d\n"
+ "OF\t\t%d\n"
+ "DOTS\t\t%d\n"
+ "IF\t\t%d\n"
+ "ELSE\t\t%d\n"
+ "THEN\t\t%d\n"
+ "WHILE\t\t%d\n"
+ "DO\t\t%d\n"
+ "FOR\t\t%d\n"
+ "TO\t\t%d\n"
+ "DT\t\t%d\n"
+ "FCALL\t\t%d\n"
+ "PCALL\t\t%d\n"
+ "ARRAY_ACCESS\t\t%d\n"
+ "LIST\t\t%d\n",
+
+ PROG, VAR, PROC, FUNC, BEG, END, ID, ADDOP, MULOP, RELOP, ASSIGNOP, ADD,
+ SUB, MUL, DIV, NOT, AND, OR, EQ, NE, LT, LE, GT, GE, INUM, RNUM, INT, REAL,
+ BOOL, ARRAY, OF, DOTS, IF, ELSE, THEN, WHILE, DO, FOR, TO, DT, FCALL, PCALL,
+ ARRAY_ACCESS, LIST);
+#endif
+
cur_scope = mkscope();
assert(cur_scope);
diff --git a/pc.y b/pc.y
index 81cb69b..ed4872c 100644
--- a/pc.y
+++ b/pc.y
@@ -1,6 +1,7 @@
%{
#include <stdlib.h>
#include <stddef.h>
+#include <assert.h>
#include "node.h"
#include "scope.h"
@@ -92,6 +93,7 @@ program
compound_statement
'.'
{
+ set_ret_type($9);
print_tree($9);
}
;
@@ -158,6 +160,7 @@ sub_prog_declaration
sub_prog_declarations
compound_statement
{
+ set_ret_type($4);
print_tree($4);
pop_scope(&cur_scope);
}
diff --git a/sem_check.c b/sem_check.c
index 637d044..ae1fa4c 100644
--- a/sem_check.c
+++ b/sem_check.c
@@ -34,3 +34,79 @@ char *n;
return tmp;
}
+
+int check_ret_type(t)
+ptree *t;
+{
+ char buf[100];
+ int type;
+
+ if (!t)
+ printf("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 :
+ case RELOP :
+ if (!(t->r && t->l))
+ yyerror("Missing nodes\n");
+
+ if (t->r->ret_type == t->l->ret_type)
+ return BOOL;
+ else
+ yyerror("Misssing nodes\n");
+ break;
+ case NOT:
+ if (t->ret_type == BOOL)
+ return BOOL;
+ yyerror("NOT needs bool input\n");
+ break;
+ case INUM:
+ printf("INUM: %d", t->attr.ival);
+ return INT;
+ case RNUM:
+ return REAL;
+ case ASSIGNOP:
+ fprintf(stderr, "HERE\n");
+ if (!(t->r && t->l && t->r->attr.nval))
+ yyerror("Incomplete parse tree\n");
+
+ if (t->l->attr.nval->var_type == t->r->ret_type)
+ return 0;
+ 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));
+ yyerror(buf);
+ }
+
+
+ break;
+ case ARRAY_ACCESS:
+ if (!(t->r && t->l && t->l->attr.nval))
+ yyerror("Incorrect Array Access\n");
+
+ type = t->l->attr.nval -> var_type;
+ if (type == ARRAY - INT || type == ARRAY - REAL)
+ return 0;
+ break;
+ default:
+ return -200;
+ snprintf(buf, 101, "Unknown tree node: %d...\n", t->type);
+ yyerror(buf);
+ }
+
+
+ return -1;
+
+}
+
diff --git a/sem_check.h b/sem_check.h
index eef9e96..71ec715 100644
--- a/sem_check.h
+++ b/sem_check.h
@@ -5,4 +5,6 @@ void check_id(scope*, char*);
node* check_exists(scope*, char*);
+int check_ret_type(ptree*);
+
#endif
diff --git a/tree.c b/tree.c
index 71feb5b..7a8c458 100644
--- a/tree.c
+++ b/tree.c
@@ -83,6 +83,67 @@ ptree *list;
}
}
+void set_ret_type(t)
+ptree *t;
+{
+ if (!t){
+ fprintf(stderr, "TEST\n");
+ return;
+ }
+
+ switch (t->type) {
+
+ case ADDOP:
+ fprintf(stderr, "[ADDOP]");
+ break;
+ case MULOP:
+ fprintf(stderr, "[MULOP]");
+ break;
+ case RELOP:
+ fprintf(stderr, "[RELOP]");
+ break;
+ case NOT:
+ fprintf(stderr, "[NOT]");
+ break;
+ case ARRAY_ACCESS:
+ fprintf(stderr, "[ARRAY ACCESS]");
+ break;
+ case LIST:
+ fprintf(stderr, "[LIST]");
+ break;
+ case ID:
+ if (t->r && t->r->attr.nval)
+ fprintf(stderr, "[ID: %s %s]",
+ t->r->attr.nval->name,
+ pretty_type(
+ t->attr.nval->var_type));
+ else
+ fprintf(stderr, "[ID: %s %s]",
+ t->attr.nval->name,
+ pretty_type(
+ t->attr.nval->var_type));
+ break;
+ case INUM:
+ fprintf(stderr, "[INUM: %d]", t->attr.ival);
+ break;
+ case RNUM:
+ fprintf(stderr, "[RNUM: %f]", t->attr.rval);
+ break;
+ case ASSIGNOP:
+ fprintf(stderr, "[ASSIGN]");
+ break;
+ default:
+ fprintf(stderr, "\t%d", t->type);
+ yyerror("Error in tree_print");
+ }
+ fprintf(stderr, "\nWHAT: %d\n", t->type);
+ set_ret_type(t->l);
+ set_ret_type(t->r);
+ t->ret_type = check_ret_type(t);
+
+ return;
+}
+
/*PRINT FUNCS*/
@@ -150,7 +211,7 @@ int spaces;
fprintf(stderr, "\t%d", t->type);
yyerror("Error in tree_print");
}
- fprintf(stderr,"\n");
+ fprintf(stderr," %d\n", t->ret_type);
aux_tree_print(t->l, spaces + 2);
fprintf(stderr,"\n");
aux_tree_print(t->r, spaces + 2);
diff --git a/tree.h b/tree.h
index 0d94f6d..94ccb7d 100644
--- a/tree.h
+++ b/tree.h
@@ -12,6 +12,7 @@ typedef struct parse_tree {
MULOP: MUL DIV
*/
} attr;
+ int ret_type;
struct parse_tree *l, *r;
} ptree;
@@ -25,5 +26,6 @@ ptree* mkrnum(float);
ptree* mkop(int, int, ptree*, ptree*);
void update_type_info(ptree*, int);
+void set_ret_type(ptree*);
#endif