From 081f3735abf4add6dbbd6ba4ca56da10bd54139e Mon Sep 17 00:00:00 2001 From: Tucker Evans Date: Sun, 4 Aug 2019 11:51:56 -0400 Subject: Fix adding variable to scope during assignment --- pc.y | 4 ++-- scope.c | 7 ++++++- 2 files changed, 8 insertions(+), 3 deletions(-) diff --git a/pc.y b/pc.y index d63d8fc..54e4ede 100644 --- a/pc.y +++ b/pc.y @@ -260,12 +260,12 @@ TD: TO | DT; var :ID { - $$ = mkid(scope_insert(cur_scope,$1)); + $$ = mkid(scope_safe_search_all(cur_scope,$1)); } |ID '[' expr ']' { node* tmp; - tmp = scope_insert(cur_scope, $1); + tmp = scope_safe_search_all(cur_scope, $1); $$ = mktree(ARRAY_ACCESS, mkid(tmp), $3); } diff --git a/scope.c b/scope.c index 6706765..eca78cd 100644 --- a/scope.c +++ b/scope.c @@ -138,9 +138,14 @@ scope *s; { int i; node * tmp; + + fprintf(stderr, "\n\nSCOPE\n" + "==========================================================\n"); + for (i = 0; i < HASH_SIZE; i++) { for( tmp=s->table[i]; tmp; tmp = tmp->next) { - fprintf(stderr, "\t%s\n", tmp->name); + fprintf(stderr, "\t%s:%s\n", tmp->name, + pretty_type(tmp->var_type)); } } } -- cgit v1.1 From 89fca11404f818b1ece0abb03b42acbcb1f3a280 Mon Sep 17 00:00:00 2001 From: Tucker Evans Date: Sun, 4 Aug 2019 11:52:30 -0400 Subject: Fix tree print with variable types --- tree.c | 16 +++++++++++++--- 1 file changed, 13 insertions(+), 3 deletions(-) diff --git a/tree.c b/tree.c index 8a2c3bf..e0216fd 100644 --- a/tree.c +++ b/tree.c @@ -27,7 +27,7 @@ ptree* mkid(n) node *n; { ptree *p = mktree(ID, NULL, NULL); - p->attr.nval = n; /* memory leak? double strdup*/ + p->attr.nval = n; return p; } @@ -70,7 +70,8 @@ ptree *list; list = list->l; continue; /*Continue down list*/ } else if (list->l->type == ID) - /*Set type of first declared ID (only left node in LIST)*/ + /*Set type of first declared ID + (only left node in LIST)*/ list->l->attr.nval->var_type = type; } return; /*At _end_ of list (did not continue)*/ @@ -120,7 +121,16 @@ int spaces; fprintf(stderr, "[LIST]"); break; case ID: - fprintf(stderr, "[ID: %s %d]", t->attr.nval->name, t->attr.nval->var_type); + 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); -- cgit v1.1 From 0408f0c8d8d095267b322859e208f209edd47311 Mon Sep 17 00:00:00 2001 From: Tucker Evans Date: Sun, 4 Aug 2019 20:59:15 -0400 Subject: Fix safe search function call --- pc.y | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/pc.y b/pc.y index 54e4ede..92a1f0c 100644 --- a/pc.y +++ b/pc.y @@ -260,12 +260,12 @@ TD: TO | DT; var :ID { - $$ = mkid(scope_safe_search_all(cur_scope,$1)); + $$ = mkid(scope_safe_search(cur_scope,$1)); } |ID '[' expr ']' { node* tmp; - tmp = scope_safe_search_all(cur_scope, $1); + tmp = scope_safe_search(cur_scope, $1); $$ = mktree(ARRAY_ACCESS, mkid(tmp), $3); } -- cgit v1.1 From 0caa6768c7055c3e3fb2f2ebeda2c35152ea011b Mon Sep 17 00:00:00 2001 From: Tucker Evans Date: Sun, 4 Aug 2019 21:23:38 -0400 Subject: Update checks --- check/array.p | 32 ++++++++++++++++++++++++++++++++ check/for.p | 16 ++++++++++++++++ check/main.p | 5 +---- 3 files changed, 49 insertions(+), 4 deletions(-) create mode 100644 check/array.p create mode 100644 check/for.p diff --git a/check/array.p b/check/array.p new file mode 100644 index 0000000..e378655 --- /dev/null +++ b/check/array.p @@ -0,0 +1,32 @@ +program main ( input, output ); + + var a, b: integer; + var x,y,z: real; + var ai :array [1..10] of integer; + procedure boo (n: integer); + var a,c: integer; + begin + a := n + end; + function bar (a: integer) : real; + var test:integer; + begin + test := 2; + a := 2 + end; + procedure foo; + begin + a := 33333; + x := 1e10; + z := 1e-10; + y := 2.5543e-2 + end; +begin +{ TEST } + + a := 1; + x := 3.14; + b := a + 35; + ai[2] := a + (* test *) +end. diff --git a/check/for.p b/check/for.p new file mode 100644 index 0000000..694f9a5 --- /dev/null +++ b/check/for.p @@ -0,0 +1,16 @@ +program main ( input, output ); + + var a, b: integer; + var x,y,z: real; + var ai :array [1..10] of integer; +begin +{ TEST } + + a := 1; + x := 3.14; + b := a + 35; + (* test *) + for c := 0 to 10 do begin + for a:= 10 downto 0 do b := a - c + end +end. diff --git a/check/main.p b/check/main.p index f05808b..613f8dc 100644 --- a/check/main.p +++ b/check/main.p @@ -26,9 +26,6 @@ begin a := 1; x := 3.14; - b := a + 35; + b := a + 35 (* test *) - for c := 0 to 10 do begin - for a:= 10 downto 0 do b := a - c - end end. -- cgit v1.1 From a359edde7c8806687c4f0307dbfc6f77077ba063 Mon Sep 17 00:00:00 2001 From: Tucker Evans Date: Sun, 4 Aug 2019 21:52:30 -0400 Subject: Fix updating type on single variable declarations --- main.c | 6 +++--- node.c | 2 ++ pc.y | 2 ++ tree.c | 7 ++++++- 4 files changed, 13 insertions(+), 4 deletions(-) diff --git a/main.c b/main.c index dba3b7f..6ded432 100644 --- a/main.c +++ b/main.c @@ -17,10 +17,10 @@ int t; { if (t == ARRAY) { return "ARRAY"; - } else if (t == INT - ARRAY) { - return "ARRAY of INT"; - } else if (t == INT - ARRAY) { + } else if (t == ARRAY - INT) { return "ARRAY of INT"; + } else if (t == ARRAY - REAL) { + return "ARRAY of REAL"; } else if (t == INT) { return "INT"; } else if (t == REAL) { diff --git a/node.c b/node.c index 586ed52..0e87370 100644 --- a/node.c +++ b/node.c @@ -15,6 +15,8 @@ char *str; p->name = strdup(str); p->next = NULL; + p->var_type = -1; + return p; } diff --git a/pc.y b/pc.y index 92a1f0c..81cb69b 100644 --- a/pc.y +++ b/pc.y @@ -192,10 +192,12 @@ param_list :id_list ':' type { $$ = $1; + update_type_info($1, $3); } |param_list ';' id_list ':' type { $$ = mktree(LIST, $1, $3); + update_type_info($3, $5); } ; diff --git a/tree.c b/tree.c index e0216fd..71feb5b 100644 --- a/tree.c +++ b/tree.c @@ -61,10 +61,15 @@ int type; ptree *list; { assert(list); + if (list->type == ID) { + list->attr.nval->var_type = type; + return; + } + while (list->r && list->r->type == ID) { /*Set type of right child through list*/ list->r->attr.nval->var_type = type; - + if (list->l) { if (list->l->type == LIST) { list = list->l; -- cgit v1.1 From ee6c598892518d956388bb008095de6d4d7fe123 Mon Sep 17 00:00:00 2001 From: Tucker Evans Date: Mon, 5 Aug 2019 20:59:25 -0400 Subject: Add gitignore and checklists --- .gitignore | 6 ++++++ CHECKLIST.txt | 55 +++++++++++++++++++++++++++++++++++++++++++++++++++ SemanticCheckList.txt | 37 ++++++++++++++++++++++++++++++++++ 3 files changed, 98 insertions(+) create mode 100644 .gitignore create mode 100644 CHECKLIST.txt create mode 100644 SemanticCheckList.txt diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..21840e8 --- /dev/null +++ b/.gitignore @@ -0,0 +1,6 @@ +*~ +*.bak +*.o +y.* +mypc +lex.yy.c diff --git a/CHECKLIST.txt b/CHECKLIST.txt new file mode 100644 index 0000000..ce22f78 --- /dev/null +++ b/CHECKLIST.txt @@ -0,0 +1,55 @@ +Project: DRAGON +=============== + +- Arrange an online demo of your compiler during Finals week (15min). + +- Send a self-contained compressed tar source of your compiler by + email. Your compiler must run on the ITL machines. + +- Submit a hardcopy of your compiler documentation: design document, + user manual, testing report, status report (limitations, caveats, or + bugs), and a "dragon" haiku. Indicate clearly in your report an + extra feature that is unique to your compiler. + +CHECK LIST +---------- +[X] (1.0) Lexical Analysis +[X] a. Line numbering +[X] b. Two styles of comments +[X] c. (optional) Scientific notation + +[ ] (1.5) Syntax Analysis: grammar adjustments +[X] a. Unlimited nesting of subprograms +[ ] b. Array access on both sides of assignment +[X] c. Allow for statements. + d. (optional) Another loop construct + e. (optional) Multidimensional arrays +[ ] f. (optional) Records and pointers +[ ] +[ ] (2.0) Symbol Table +[ ] a. Memory-leak handler + b. (optional) Statistical analysis of hashpjw +[ ] +[ ] (2.5) Syntax Tree (Intermediate Code Generation) +[ ] a. Visual print +[ ] b. Memory-leak handler + +[ ] (3.0) Semantic Analysis & Type Checking +[ ] a. Check list +[ ] b. Error reporting +[ ] c. (optional) Error recovery + +[ ] (4.0) Code Generation +[ ] a. Input/Output statements +[ ] b. Simple expressions (arithmetic and relational): gencode +[ ] c. Statements (assignment, conditional, loop) +[ ] d. Nonlocal names: base frame pointer (static scope parent) +[ ] e. Recursive routines (example: GCD program) +[ ] f. Complex expressions (register spilling) +[ ] g. (optional) Arrays (L-value, R-value, parameters, nonlocal) +[ ] h. (optional) Floating-point support + +[ ] Extra Trails (under construction) +[ ] - Lambda or Objects. +[ ] - Code generator for IA64 or SPARC (RISC architecture). +[ ] - Code optimization. diff --git a/SemanticCheckList.txt b/SemanticCheckList.txt new file mode 100644 index 0000000..9bd2c2c --- /dev/null +++ b/SemanticCheckList.txt @@ -0,0 +1,37 @@ +DRAGON Semantic Checklist +========================= + +[ ] 1. Semantic rules for Scoping +[ ] 1.1. Local objects cannot be declared more than once +[ ] 1.2. Local objects hide non-local objects with the same name +[ ] 1.3. Non-local objects should be visible from inner scopes (unless a local object of the same name exists) +[ ] 1.4. Function and procedure names exist in the scope they are defined (and not in their own scopes) +[ ] 1.5. Local objects cease to exist once their scopes cease to exist + +[ ] 2. Semantic rules for Expressions +[ ] 2.1. Expressions return typed-values +[ ] 2.2. Objects must be declared before they used in expressions +[ ] 2.3. Objects of different types cannot appear in the same expression (no type promotions) + +[ ] 3. Semantic rules for Statements +[ ] 3.1. Statements do not return values +[ ] 3.2. The test expression for IF-THEN, IF-THEN-ELSE, WHILE-DO must be Boolean-valued; +[ ] note that the Boolean type must be implicitly defined +[ ] 3.3. The ELSE clause always binds to the closest IF (resolution of the dangling ELSE problem) +[ ] 3.4. The variable type in FOR-DO must match the types of lower bound and upper bound expressions + +[ ] 4. Semantic rules for Arrays +[ ] 4.1. Non-integer valued expressions cannot be used for indexing arrays + +[ ] 5. Semantic rules for Functions +[ ] 5.1. Function calls return values of type Integer or Real +[ ] 5.2. Function must contain a "return" statement within its own body; +[ ] this is of the form: := +[ ] 5.3. Functions must accept exactly the same number of arguments as is +[ ] declared in its header, with the correct sequence of types +[X] 5.4. Functions are not allowed to update the value of nonlocal objects (via assignment statements) + +[ ] 6. Semantic rules for Procedures +[ ] 6.1. Procedure calls do not return values +[ ] 6.2. Procedures must accept exactly the same number of arguments as is +[ ] declared in its header, with the correct sequence of types -- cgit v1.1 From 06ebf6a87ca1db975bdbf4f7f3126ea7c26ddde6 Mon Sep 17 00:00:00 2001 From: Tucker Evans Date: Sat, 17 Aug 2019 11:34:48 -0400 Subject: Add basic type checking Squashed commit of WIP-type_check@5dadc4f5667ae69a709dd45c020780f2f424d67e --- main.c | 56 ++++++++++++++++++++++++++++++++++++++++++--- pc.y | 3 +++ sem_check.c | 76 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ sem_check.h | 2 ++ tree.c | 63 +++++++++++++++++++++++++++++++++++++++++++++++++- tree.h | 2 ++ 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 #include +#include #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 -- cgit v1.1 From 190274a66622d65cd30726a8daf3edb02dfe009e Mon Sep 17 00:00:00 2001 From: Tucker Evans Date: Fri, 16 Aug 2019 22:06:54 -0400 Subject: Fix MULOP/ADDOP return BOOL in check_ret_type Removes some debug printing --- sem_check.c | 8 ++++++++ tree.c | 1 - 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/sem_check.c b/sem_check.c index ae1fa4c..2e9b5ba 100644 --- a/sem_check.c +++ b/sem_check.c @@ -53,6 +53,14 @@ ptree *t; case ADDOP : case MULOP : + if (!(t->r && t->l)) + yyerror("Missing nodes\n"); + + if (t->r->ret_type == t->l->ret_type) + return t->r->ret_type; + else + yyerror("Misssing nodes\n"); + break; case RELOP : if (!(t->r && t->l)) yyerror("Missing nodes\n"); diff --git a/tree.c b/tree.c index 7a8c458..eead0e5 100644 --- a/tree.c +++ b/tree.c @@ -136,7 +136,6 @@ ptree *t; 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); -- cgit v1.1 From bddc723d0eb67b32bf50e2eabe4999dc96e741f3 Mon Sep 17 00:00:00 2001 From: Tucker Evans Date: Sat, 17 Aug 2019 12:09:23 -0400 Subject: Fix debug_print calls in tokenizer Was printing RELOP for ADDOP&MULOPs --- pc.l | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/pc.l b/pc.l index 509b6cf..ec5b947 100644 --- a/pc.l +++ b/pc.l @@ -174,37 +174,37 @@ id [A-Za-z][A-Za-z0-9_]* "+" { yylval.opval = ADD; - debug_print(RELOP, &yylval); + debug_print(ADDOP, &yylval); return ADDOP; } "-" { yylval.opval = SUB; - debug_print(RELOP, &yylval); + debug_print(ADDOP, &yylval); return ADDOP; } "or" { yylval.opval = OR; - debug_print(RELOP, &yylval); + debug_print(ADDOP, &yylval); return ADDOP; } "*" { yylval.opval = MUL; - debug_print(RELOP, &yylval); + debug_print(MULOP, &yylval); return MULOP; } "/" { yylval.opval = DIV; - debug_print(RELOP, &yylval); + debug_print(MULOP, &yylval); return MULOP; } "and" { yylval.opval = AND; - debug_print(RELOP, &yylval); + debug_print(MULOP, &yylval); return MULOP; } -- cgit v1.1 From 7449656c35052b29c65f0b7b53895b22b958a259 Mon Sep 17 00:00:00 2001 From: Tucker Evans Date: Sat, 17 Aug 2019 12:16:17 -0400 Subject: Fix error message for ADDOP/MULOP Removes some debugging prints --- sem_check.c | 11 ++++++++--- tree.c | 1 - 2 files changed, 8 insertions(+), 4 deletions(-) diff --git a/sem_check.c b/sem_check.c index 2e9b5ba..da54a21 100644 --- a/sem_check.c +++ b/sem_check.c @@ -58,8 +58,14 @@ ptree *t; if (t->r->ret_type == t->l->ret_type) return t->r->ret_type; - else - yyerror("Misssing nodes\n"); + 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)); + yyerror(buf); + } break; case RELOP : if (!(t->r && t->l)) @@ -81,7 +87,6 @@ ptree *t; case RNUM: return REAL; case ASSIGNOP: - fprintf(stderr, "HERE\n"); if (!(t->r && t->l && t->r->attr.nval)) yyerror("Incomplete parse tree\n"); diff --git a/tree.c b/tree.c index eead0e5..11c08d4 100644 --- a/tree.c +++ b/tree.c @@ -87,7 +87,6 @@ void set_ret_type(t) ptree *t; { if (!t){ - fprintf(stderr, "TEST\n"); return; } -- cgit v1.1 From 7a1850b859041a990ab93416f7b3d76a5d946191 Mon Sep 17 00:00:00 2001 From: Tucker Evans Date: Sat, 17 Aug 2019 13:02:49 -0400 Subject: Add allows expressions as statements --- pc.y | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/pc.y b/pc.y index ed4872c..97bf33e 100644 --- a/pc.y +++ b/pc.y @@ -258,6 +258,10 @@ statement /*TODO design tree structure for FOR loops*/ $$ = NULL; } + | expr + { + $$ = $1; + } ; TD: TO | DT; -- cgit v1.1 From 47016c39ed801aecfa900f30a49d94ae247b1156 Mon Sep 17 00:00:00 2001 From: Tucker Evans Date: Sat, 17 Aug 2019 13:04:08 -0400 Subject: Fix error messages for RELOP type checking Removes debug prints --- sem_check.c | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/sem_check.c b/sem_check.c index da54a21..44eb82f 100644 --- a/sem_check.c +++ b/sem_check.c @@ -74,7 +74,12 @@ ptree *t; if (t->r->ret_type == t->l->ret_type) return BOOL; else - yyerror("Misssing nodes\n"); + 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)); + yyerror(buf); break; case NOT: if (t->ret_type == BOOL) @@ -82,7 +87,6 @@ ptree *t; yyerror("NOT needs bool input\n"); break; case INUM: - printf("INUM: %d", t->attr.ival); return INT; case RNUM: return REAL; -- cgit v1.1 From 950a05bb51c231a690aff725068703946231a6a7 Mon Sep 17 00:00:00 2001 From: Tucker Evans Date: Sat, 17 Aug 2019 14:06:09 -0400 Subject: Add array type checking --- pc.y | 1 + sem_check.c | 15 +++++++++++---- 2 files changed, 12 insertions(+), 4 deletions(-) diff --git a/pc.y b/pc.y index 97bf33e..264218c 100644 --- a/pc.y +++ b/pc.y @@ -277,6 +277,7 @@ var tmp = scope_safe_search(cur_scope, $1); $$ = mktree(ARRAY_ACCESS, mkid(tmp), $3); + $$->attr.nval = $$->l->attr.nval; } ; diff --git a/sem_check.c b/sem_check.c index 44eb82f..a3d08b8 100644 --- a/sem_check.c +++ b/sem_check.c @@ -42,7 +42,7 @@ ptree *t; int type; if (!t) - printf("TYPE: %d\n", t->type); + fprintf(stderr, "TYPE: %d\n", t->type); switch (t->type) { case ID: @@ -91,10 +91,10 @@ ptree *t; case RNUM: return REAL; case ASSIGNOP: - if (!(t->r && t->l && t->r->attr.nval)) + if (!(t->r && t->l)) yyerror("Incomplete parse tree\n"); - if (t->l->attr.nval->var_type == t->r->ret_type) + if (t->l->ret_type == t->r->ret_type) return 0; else { snprintf(buf, 100, "Mismached types: " @@ -112,9 +112,16 @@ ptree *t; 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)); + yyerror(buf); + } + type = t->l->attr.nval -> var_type; if (type == ARRAY - INT || type == ARRAY - REAL) - return 0; + return ARRAY - type; break; default: return -200; -- cgit v1.1 From 1ff4c71e7a5140cd045a9483a76d667bd6837744 Mon Sep 17 00:00:00 2001 From: Tucker Evans Date: Sat, 17 Aug 2019 14:15:21 -0400 Subject: Fix not type checking --- sem_check.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sem_check.c b/sem_check.c index a3d08b8..d174bf8 100644 --- a/sem_check.c +++ b/sem_check.c @@ -82,7 +82,7 @@ ptree *t; yyerror(buf); break; case NOT: - if (t->ret_type == BOOL) + if (t->l && t->l->ret_type == BOOL) return BOOL; yyerror("NOT needs bool input\n"); break; -- cgit v1.1 From 9508f73e75aa588e9639530c72e8f5ed2c02067c Mon Sep 17 00:00:00 2001 From: Tucker Evans Date: Sat, 17 Aug 2019 15:46:16 -0400 Subject: Add if statements to tree print Removes printing tree during return type setting --- tree.c | 116 +++++++++++++++++++++-------------------------------------------- 1 file changed, 38 insertions(+), 78 deletions(-) diff --git a/tree.c b/tree.c index 11c08d4..ee4bb8e 100644 --- a/tree.c +++ b/tree.c @@ -86,12 +86,40 @@ ptree *list; void set_ret_type(t) ptree *t; { - if (!t){ + if (!t) return; - } - - switch (t->type) { + + set_ret_type(t->l); + set_ret_type(t->r); + t->ret_type = check_ret_type(t); + + return; +} + + +/*PRINT FUNCS*/ + +void print_tree(t) +ptree *t; +{ + fprintf(stderr, "\n\nTREE\n" + "==========================================================\n"); + aux_tree_print(t, 0); + fprintf(stderr, + "**********************************************************\n"); + return; +} + +void aux_tree_print(t, spaces) +ptree* t; +int spaces; +{ + int i; + if ( t ) { + for (i = 0; i < spaces; i++) + fprintf(stderr," "); + switch (t->type) { case ADDOP: fprintf(stderr, "[ADDOP]"); break; @@ -131,80 +159,12 @@ ptree *t; case ASSIGNOP: fprintf(stderr, "[ASSIGN]"); break; - default: - fprintf(stderr, "\t%d", t->type); - yyerror("Error in tree_print"); - } - set_ret_type(t->l); - set_ret_type(t->r); - t->ret_type = check_ret_type(t); - - return; -} - - -/*PRINT FUNCS*/ - -void print_tree(t) -ptree *t; -{ - fprintf(stderr, "\n\nTREE\n" - "==========================================================\n"); - aux_tree_print(t, 0); - fprintf(stderr, - "**********************************************************\n"); - return; -} - -void aux_tree_print(t, spaces) -ptree* t; -int spaces; -{ - int i; - if ( t ) { - for (i = 0; i < spaces; i++) - fprintf(stderr," "); - 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; + case IF: + fprintf(stderr, "[IF]"); + break; + case THEN: + fprintf(stderr, "[THEN]"); + break; default: fprintf(stderr, "\t%d", t->type); yyerror("Error in tree_print"); -- cgit v1.1 From e1d044ff79638cf781816e8723fa78f1e9a7b34e Mon Sep 17 00:00:00 2001 From: Tucker Evans Date: Sat, 17 Aug 2019 15:47:08 -0400 Subject: Add Type checking if statement condition --- scope.c | 1 + sem_check.c | 9 ++++++++- tree.c | 2 ++ 3 files changed, 11 insertions(+), 1 deletion(-) diff --git a/scope.c b/scope.c index eca78cd..f093b82 100644 --- a/scope.c +++ b/scope.c @@ -5,6 +5,7 @@ #include "node.h" #include "scope.h" +#include "pc.h" scope* mkscope() { diff --git a/sem_check.c b/sem_check.c index d174bf8..7e6e338 100644 --- a/sem_check.c +++ b/sem_check.c @@ -123,13 +123,20 @@ ptree *t; if (type == ARRAY - INT || type == ARRAY - REAL) return ARRAY - type; break; + case IF: + 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 0; + default: return -200; snprintf(buf, 101, "Unknown tree node: %d...\n", t->type); yyerror(buf); } - return -1; } diff --git a/tree.c b/tree.c index ee4bb8e..de9a0f5 100644 --- a/tree.c +++ b/tree.c @@ -5,6 +5,8 @@ #include "node.h" #include "tree.h" +#include "scope.h" +#include "sem_check.h" #include "y.tab.h" #include "pc.h" -- cgit v1.1 From ee21031fb16f5ed89dd1dbaf73bc2a1201f955b1 Mon Sep 17 00:00:00 2001 From: Tucker Evans Date: Sat, 17 Aug 2019 16:30:28 -0400 Subject: Fix deal with and/or ops correctly in type checking --- sem_check.c | 16 +++++++++++++++- 1 file changed, 15 insertions(+), 1 deletion(-) diff --git a/sem_check.c b/sem_check.c index 7e6e338..d18fb59 100644 --- a/sem_check.c +++ b/sem_check.c @@ -56,6 +56,21 @@ ptree *t; if (!(t->r && t->l)) yyerror("Missing nodes\n"); + if (t->attr.opval == ADD || 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)); + yyerror(buf); + } + } + if (t->r->ret_type == t->l->ret_type) return t->r->ret_type; else { @@ -70,7 +85,6 @@ ptree *t; case RELOP : if (!(t->r && t->l)) yyerror("Missing nodes\n"); - if (t->r->ret_type == t->l->ret_type) return BOOL; else -- cgit v1.1 From fe712311578b014a9e074f25856520732a1b3da8 Mon Sep 17 00:00:00 2001 From: Tucker Evans Date: Sun, 18 Aug 2019 18:14:11 -0400 Subject: Add while (and holding place for for) type checking --- sem_check.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/sem_check.c b/sem_check.c index d18fb59..c6f4c4e 100644 --- a/sem_check.c +++ b/sem_check.c @@ -138,13 +138,16 @@ ptree *t; 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 0; - + case FOR: + /*TODO add for type checking after parsing is correct*/ + break; default: return -200; snprintf(buf, 101, "Unknown tree node: %d...\n", t->type); -- cgit v1.1 From b4d095d8616c8a5f2d85f8dc91b8429b0a7108a3 Mon Sep 17 00:00:00 2001 From: Tucker Evans Date: Sun, 18 Aug 2019 18:31:19 -0400 Subject: Add WHILE to tree_print --- tree.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/tree.c b/tree.c index de9a0f5..daad71f 100644 --- a/tree.c +++ b/tree.c @@ -164,6 +164,9 @@ int spaces; case IF: fprintf(stderr, "[IF]"); break; + case WHILE: + fprintf(stderr, "[WHILE]"); + break; case THEN: fprintf(stderr, "[THEN]"); break; -- cgit v1.1 From 3f1cee416602070225b81deb8c2222a5324f8204 Mon Sep 17 00:00:00 2001 From: Tucker Evans Date: Sun, 18 Aug 2019 18:31:36 -0400 Subject: Fix clean up header includes --- main.c | 3 ++- node.c | 4 ++-- pc.h | 3 +++ scope.c | 5 +++-- scope.h | 2 ++ sem_check.c | 6 ++---- sem_check.h | 3 +++ tree.c | 8 ++++---- tree.h | 2 ++ 9 files changed, 23 insertions(+), 13 deletions(-) diff --git a/main.c b/main.c index da597eb..34acd52 100644 --- a/main.c +++ b/main.c @@ -1,3 +1,5 @@ +#include "pc.h" + #include #include #include @@ -5,7 +7,6 @@ #include "node.h" #include "scope.h" #include "y.tab.h" -#include "pc.h" extern char *yytext; extern int line_num; diff --git a/node.c b/node.c index 0e87370..d8d5276 100644 --- a/node.c +++ b/node.c @@ -1,10 +1,10 @@ +#include "node.h" + #include #include #include #include -#include "node.h" - /*constructor*/ node* mknode(str) char *str; diff --git a/pc.h b/pc.h index 7a8be68..e13c481 100644 --- a/pc.h +++ b/pc.h @@ -1,5 +1,8 @@ #ifndef PC_H #define PC_H + +#include "y.tab.h" + char* pretty_type(int); void debug_print(int, union YYSTYPE*); diff --git a/scope.c b/scope.c index f093b82..00e2417 100644 --- a/scope.c +++ b/scope.c @@ -1,12 +1,13 @@ +#include "scope.h" + #include #include #include #include -#include "node.h" -#include "scope.h" #include "pc.h" + scope* mkscope() { int i; diff --git a/scope.h b/scope.h index 0a07a26..f233d78 100644 --- a/scope.h +++ b/scope.h @@ -1,6 +1,8 @@ #ifndef SCOPE_H #define SCOPE_H +#include "node.h" + #define HASH_SIZE 211 typedef struct hash { diff --git a/sem_check.c b/sem_check.c index c6f4c4e..3d42996 100644 --- a/sem_check.c +++ b/sem_check.c @@ -1,12 +1,10 @@ +#include "sem_check.h" + #include #include -#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; diff --git a/sem_check.h b/sem_check.h index 71ec715..ce7d7fb 100644 --- a/sem_check.h +++ b/sem_check.h @@ -1,6 +1,9 @@ #ifndef SEMCHECK_H #define SEMCHECK_H +#include "scope.h" +#include "tree.h" + void check_id(scope*, char*); node* check_exists(scope*, char*); diff --git a/tree.c b/tree.c index daad71f..1874712 100644 --- a/tree.c +++ b/tree.c @@ -1,14 +1,14 @@ +#include "tree.h" + #include #include #include #include -#include "node.h" -#include "tree.h" -#include "scope.h" -#include "sem_check.h" #include "y.tab.h" +#include "scope.h" #include "pc.h" +#include "sem_check.h" /* parse tree funcs */ ptree* mktree(type, l, r) diff --git a/tree.h b/tree.h index 94ccb7d..23edf8f 100644 --- a/tree.h +++ b/tree.h @@ -1,6 +1,8 @@ #ifndef TREE_H #define TREE_H +#include "node.h" + typedef struct parse_tree { int type; union { -- cgit v1.1 From f9ff4c818cee8c8b83e9a3d5161d4de2b8443146 Mon Sep 17 00:00:00 2001 From: Tucker Evans Date: Sun, 18 Aug 2019 22:22:19 -0400 Subject: Fix scope header to match funcs in scope.c --- scope.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/scope.h b/scope.h index f233d78..8a809fb 100644 --- a/scope.h +++ b/scope.h @@ -22,7 +22,7 @@ void push_scope(scope**); node* scope_insert(scope*, char*); node* scope_search_all(scope*, char*); node* scope_search(scope*, char*); -node* scope_safe_search_all(scope*, char*); +node* scope_safe_search(scope*, char*); /*hash function*/ int hashpjw(char*); -- cgit v1.1 From dd07055aca1c45d147d773350e0c21930822a74f Mon Sep 17 00:00:00 2001 From: Tucker Evans Date: Sun, 18 Aug 2019 22:27:52 -0400 Subject: Add for loop parsing Also fixes tree printing --- check/for.p | 7 +------ pc.y | 28 +++++++++++++++++++++++++--- tree.c | 19 ++++++++++++++----- 3 files changed, 40 insertions(+), 14 deletions(-) diff --git a/check/for.p b/check/for.p index 694f9a5..5391c8c 100644 --- a/check/for.p +++ b/check/for.p @@ -1,14 +1,9 @@ program main ( input, output ); - var a, b: integer; - var x,y,z: real; - var ai :array [1..10] of integer; + var a, b,c: integer; begin -{ TEST } a := 1; - x := 3.14; - b := a + 35; (* test *) for c := 0 to 10 do begin for a:= 10 downto 0 do b := a - c diff --git a/pc.y b/pc.y index 264218c..d679c18 100644 --- a/pc.y +++ b/pc.y @@ -84,6 +84,8 @@ extern scope *cur_scope; %type type %type standard_type +%type TD + %% program @@ -255,8 +257,19 @@ statement } |FOR var ASSIGNOP expr TD expr DO statement { - /*TODO design tree structure for FOR loops*/ - $$ = NULL; + /* + FOR + / \ + TD STATEMENT + / \ + ASSIGNOP INUM + */ + ptree *tmp; + + tmp = mktree(ASSIGNOP, $2, $4); + tmp = mktree($5, tmp, $6); //$5 is TD + + $$ = mktree(FOR, tmp, $8); } | expr { @@ -264,7 +277,16 @@ statement } ; -TD: TO | DT; +TD + :TO + { + $$ = TO; + } + |DT + { + $$ = DT; + } +; var :ID diff --git a/tree.c b/tree.c index 1874712..fd40781 100644 --- a/tree.c +++ b/tree.c @@ -164,15 +164,24 @@ int spaces; case IF: fprintf(stderr, "[IF]"); break; + case THEN: + fprintf(stderr, "[THEN]"); + break; case WHILE: fprintf(stderr, "[WHILE]"); break; - case THEN: - fprintf(stderr, "[THEN]"); + case FOR: + fprintf(stderr, "[FOR]"); + break; + case TO: + fprintf(stderr, "[TO]"); + break; + case DT: + fprintf(stderr, "[DOWN-TO]"); break; - default: - fprintf(stderr, "\t%d", t->type); - yyerror("Error in tree_print"); + default: + fprintf(stderr, "\t%d", t->type); + yyerror("Error in tree_print"); } fprintf(stderr," %d\n", t->ret_type); aux_tree_print(t->l, spaces + 2); -- cgit v1.1