From 7e29eae526f7a5014934b92a239923dd30835afd Mon Sep 17 00:00:00 2001 From: Tucker Evans Date: Mon, 5 Aug 2019 21:31:48 -0400 Subject: WIP Add function and array info to node struct --- node.c | 3 +++ node.h | 13 +++++++++++++ pc.y | 12 +++++++++++- 3 files changed, 27 insertions(+), 1 deletion(-) diff --git a/node.c b/node.c index 0e87370..40ed47c 100644 --- a/node.c +++ b/node.c @@ -17,6 +17,9 @@ char *str; p->var_type = -1; + p->func_info = NULL; + p->array_info = NULL; + return p; } diff --git a/node.h b/node.h index 90e3936..e59cb86 100644 --- a/node.h +++ b/node.h @@ -1,5 +1,15 @@ #ifndef NODE_H #define NODE_H +/*function/array info structs*/ +struct fi { + int argc; + int *argv; +}; + +struct ai { + int size; + int start_idx; +}; /* Linked list */ @@ -7,6 +17,9 @@ typedef struct node_s { char *name; struct node_s *next; int var_type; + + struct fi* func_info; + struct ai* array_info; } node; /*constructor*/ diff --git a/pc.y b/pc.y index 81cb69b..cd993ec 100644 --- a/pc.y +++ b/pc.y @@ -167,8 +167,18 @@ sub_prog_declaration sub_prog_head :FUNC ID arguments ':' standard_type ';' { + node *tmp; + int i = -1; + check_id(cur_scope->prev, $2); - scope_insert(cur_scope->prev, $2); + tmp = scope_insert(cur_scope->prev, $2); + + assert(tmp->func_info = malloc(sizeof struct fi)); + /*TODO add count of parameters*/ + tmp->func_info->argc = i; + assert(tmp->func_info->argv = malloc(i * sizeof int)); + + tmp->var_type = $5 cur_scope->ret_var = scope_insert(cur_scope, $2); cur_scope->ret_var->var_type = $5; -- cgit v1.1 From ec98dd863237aa4a1853e0efb589f2da597c5640 Mon Sep 17 00:00:00 2001 From: Tucker Evans Date: Thu, 29 Aug 2019 09:46:20 -0400 Subject: Add more test files --- check/type/addop/fail-int.p | 4 ++++ check/type/addop/fail-real.p | 5 +++++ check/type/addop/pass-int.p | 4 ++++ check/type/addop/pass-real.p | 5 +++++ check/type/arrray/fail-access.p | 5 +++++ check/type/arrray/fail-int.p | 5 +++++ check/type/arrray/fail-real.p | 5 +++++ check/type/arrray/pass-access.p | 5 +++++ check/type/arrray/pass-int.p | 5 +++++ check/type/arrray/pass-real.p | 5 +++++ check/type/assign/fail-int.p | 5 +++++ check/type/assign/fail-real.p | 5 +++++ check/type/assign/pass-int.p | 5 +++++ check/type/assign/pass-real.p | 5 +++++ check/type/bool/.pass-bool.c.swp | Bin 0 -> 12288 bytes check/type/bool/fail-and.p | 7 +++++++ check/type/bool/fail-bool.p | 5 +++++ check/type/bool/fail-if.p | 9 +++++++++ check/type/bool/fail-int.p | 5 +++++ check/type/bool/fail-or.p | 6 ++++++ check/type/bool/fail-real.p | 4 ++++ check/type/bool/fail-while.p | 7 +++++++ check/type/bool/pass-bool.p | 7 +++++++ check/type/bool/pass-if.p | 9 +++++++++ check/type/bool/pass-int.p | 10 ++++++++++ check/type/bool/pass-real.p | 10 ++++++++++ check/type/bool/pass-while.p | 7 +++++++ check/type/fail-if.p | 9 +++++++++ check/type/mulop/fail-int.p | 6 ++++++ check/type/mulop/fail-real.p | 5 +++++ check/type/mulop/pass-int.p | 5 +++++ check/type/mulop/pass-real.p | 5 +++++ check/type/pass-if.p | 9 +++++++++ 33 files changed, 193 insertions(+) create mode 100644 check/type/addop/fail-int.p create mode 100644 check/type/addop/fail-real.p create mode 100644 check/type/addop/pass-int.p create mode 100644 check/type/addop/pass-real.p create mode 100644 check/type/arrray/fail-access.p create mode 100644 check/type/arrray/fail-int.p create mode 100644 check/type/arrray/fail-real.p create mode 100644 check/type/arrray/pass-access.p create mode 100644 check/type/arrray/pass-int.p create mode 100644 check/type/arrray/pass-real.p create mode 100644 check/type/assign/fail-int.p create mode 100644 check/type/assign/fail-real.p create mode 100644 check/type/assign/pass-int.p create mode 100644 check/type/assign/pass-real.p create mode 100644 check/type/bool/.pass-bool.c.swp create mode 100644 check/type/bool/fail-and.p create mode 100644 check/type/bool/fail-bool.p create mode 100644 check/type/bool/fail-if.p create mode 100644 check/type/bool/fail-int.p create mode 100644 check/type/bool/fail-or.p create mode 100644 check/type/bool/fail-real.p create mode 100644 check/type/bool/fail-while.p create mode 100644 check/type/bool/pass-bool.p create mode 100644 check/type/bool/pass-if.p create mode 100644 check/type/bool/pass-int.p create mode 100644 check/type/bool/pass-real.p create mode 100644 check/type/bool/pass-while.p create mode 100644 check/type/fail-if.p create mode 100644 check/type/mulop/fail-int.p create mode 100644 check/type/mulop/fail-real.p create mode 100644 check/type/mulop/pass-int.p create mode 100644 check/type/mulop/pass-real.p create mode 100644 check/type/pass-if.p diff --git a/check/type/addop/fail-int.p b/check/type/addop/fail-int.p new file mode 100644 index 0000000..0d75b0d --- /dev/null +++ b/check/type/addop/fail-int.p @@ -0,0 +1,4 @@ +program main ( input, output ); +begin + 1 + 1.1 +end. diff --git a/check/type/addop/fail-real.p b/check/type/addop/fail-real.p new file mode 100644 index 0000000..865f0fc --- /dev/null +++ b/check/type/addop/fail-real.p @@ -0,0 +1,5 @@ +program main ( input, output ); + var a: integer; +begin + a := 1.1 + 1 +end. diff --git a/check/type/addop/pass-int.p b/check/type/addop/pass-int.p new file mode 100644 index 0000000..8a65883 --- /dev/null +++ b/check/type/addop/pass-int.p @@ -0,0 +1,4 @@ +program main ( input, output ); +begin + 1 + 1 +end. diff --git a/check/type/addop/pass-real.p b/check/type/addop/pass-real.p new file mode 100644 index 0000000..7cf1450 --- /dev/null +++ b/check/type/addop/pass-real.p @@ -0,0 +1,5 @@ +program main ( input, output ); + var a: real; +begin + a := 3.1 + 0.04 +end. diff --git a/check/type/arrray/fail-access.p b/check/type/arrray/fail-access.p new file mode 100644 index 0000000..c77aee3 --- /dev/null +++ b/check/type/arrray/fail-access.p @@ -0,0 +1,5 @@ +program main ( input, output ); + var a: array [1..10] of integer; +begin + a[3.2] := 1 +end. diff --git a/check/type/arrray/fail-int.p b/check/type/arrray/fail-int.p new file mode 100644 index 0000000..672f798 --- /dev/null +++ b/check/type/arrray/fail-int.p @@ -0,0 +1,5 @@ +program main ( input, output ); + var a: array [1..10] of integer; +begin + a[3] := 1.1 +end. diff --git a/check/type/arrray/fail-real.p b/check/type/arrray/fail-real.p new file mode 100644 index 0000000..993dbf9 --- /dev/null +++ b/check/type/arrray/fail-real.p @@ -0,0 +1,5 @@ +program main ( input, output ); + var a: array [1..10] of real; +begin + a[3] := 1 +end. diff --git a/check/type/arrray/pass-access.p b/check/type/arrray/pass-access.p new file mode 100644 index 0000000..a6af0ec --- /dev/null +++ b/check/type/arrray/pass-access.p @@ -0,0 +1,5 @@ +program main ( input, output ); + var a: array [1..10] of integer; +begin + a[3] := 1 +end. diff --git a/check/type/arrray/pass-int.p b/check/type/arrray/pass-int.p new file mode 100644 index 0000000..a6af0ec --- /dev/null +++ b/check/type/arrray/pass-int.p @@ -0,0 +1,5 @@ +program main ( input, output ); + var a: array [1..10] of integer; +begin + a[3] := 1 +end. diff --git a/check/type/arrray/pass-real.p b/check/type/arrray/pass-real.p new file mode 100644 index 0000000..582bbdb --- /dev/null +++ b/check/type/arrray/pass-real.p @@ -0,0 +1,5 @@ +program main ( input, output ); + var a: array [1..10] of real; +begin + a[3] := 1.1 +end. diff --git a/check/type/assign/fail-int.p b/check/type/assign/fail-int.p new file mode 100644 index 0000000..d17bc1c --- /dev/null +++ b/check/type/assign/fail-int.p @@ -0,0 +1,5 @@ +program main ( input, output ); + var a: integer; +begin + a := 1.1 +end. diff --git a/check/type/assign/fail-real.p b/check/type/assign/fail-real.p new file mode 100644 index 0000000..47fde34 --- /dev/null +++ b/check/type/assign/fail-real.p @@ -0,0 +1,5 @@ +program main ( input, output ); + var a: real; +begin + a := 1 +end. diff --git a/check/type/assign/pass-int.p b/check/type/assign/pass-int.p new file mode 100644 index 0000000..5f150c8 --- /dev/null +++ b/check/type/assign/pass-int.p @@ -0,0 +1,5 @@ +program main ( input, output ); + var a: integer; +begin + a := 1 +end. diff --git a/check/type/assign/pass-real.p b/check/type/assign/pass-real.p new file mode 100644 index 0000000..13db838 --- /dev/null +++ b/check/type/assign/pass-real.p @@ -0,0 +1,5 @@ +program main ( input, output ); + var a: real; +begin + a := 1.1 +end. diff --git a/check/type/bool/.pass-bool.c.swp b/check/type/bool/.pass-bool.c.swp new file mode 100644 index 0000000..e18746d Binary files /dev/null and b/check/type/bool/.pass-bool.c.swp differ diff --git a/check/type/bool/fail-and.p b/check/type/bool/fail-and.p new file mode 100644 index 0000000..124de1f --- /dev/null +++ b/check/type/bool/fail-and.p @@ -0,0 +1,7 @@ + +program main ( input, output ); + var a: integer; +begin + a := 1; + (a = 1) and 1 +end. diff --git a/check/type/bool/fail-bool.p b/check/type/bool/fail-bool.p new file mode 100644 index 0000000..4cf0b6e --- /dev/null +++ b/check/type/bool/fail-bool.p @@ -0,0 +1,5 @@ +program main ( input, output ); + var a: integer; +begin + not 1.1 +end. diff --git a/check/type/bool/fail-if.p b/check/type/bool/fail-if.p new file mode 100644 index 0000000..17126d6 --- /dev/null +++ b/check/type/bool/fail-if.p @@ -0,0 +1,9 @@ +program main ( input, output ); + var a: integer; +begin + if (1) + then + a:= 1 + else + a:= 0 +end. diff --git a/check/type/bool/fail-int.p b/check/type/bool/fail-int.p new file mode 100644 index 0000000..3eb4866 --- /dev/null +++ b/check/type/bool/fail-int.p @@ -0,0 +1,5 @@ +program main ( input, output ); + var a: integer; +begin + 1 <> 1.1 +end. diff --git a/check/type/bool/fail-or.p b/check/type/bool/fail-or.p new file mode 100644 index 0000000..a48cdf3 --- /dev/null +++ b/check/type/bool/fail-or.p @@ -0,0 +1,6 @@ +program main ( input, output ); + var a: integer; +begin + a := 1; + (a = 1) or 1.1 +end. diff --git a/check/type/bool/fail-real.p b/check/type/bool/fail-real.p new file mode 100644 index 0000000..7c7d00d --- /dev/null +++ b/check/type/bool/fail-real.p @@ -0,0 +1,4 @@ +program main ( input, output ); +begin + 1.1 <> 1 +end. diff --git a/check/type/bool/fail-while.p b/check/type/bool/fail-while.p new file mode 100644 index 0000000..b02048d --- /dev/null +++ b/check/type/bool/fail-while.p @@ -0,0 +1,7 @@ +program main ( input, output ); + var a: integer; +begin + while (1) + do + a:= 0 +end. diff --git a/check/type/bool/pass-bool.p b/check/type/bool/pass-bool.p new file mode 100644 index 0000000..3701bcb --- /dev/null +++ b/check/type/bool/pass-bool.p @@ -0,0 +1,7 @@ +program main ( input, output ); + var a: integer; +begin + not (1.1 = 1.1); + (1.1 = 1.1) or (1 = 2); + (1.1 = 1.1) and (1 = 2) +end. diff --git a/check/type/bool/pass-if.p b/check/type/bool/pass-if.p new file mode 100644 index 0000000..30e5abf --- /dev/null +++ b/check/type/bool/pass-if.p @@ -0,0 +1,9 @@ +program main ( input, output ); + var a: integer; +begin + if ((1 = 1) ) + then + a:= 1 + else + a:= 0 +end. diff --git a/check/type/bool/pass-int.p b/check/type/bool/pass-int.p new file mode 100644 index 0000000..da2bc97 --- /dev/null +++ b/check/type/bool/pass-int.p @@ -0,0 +1,10 @@ +program main ( input, output ); + var a: integer; +begin + 1 = 1; + 1 <= 1; + 1 >= 1; + 1 < 1; + 1 > 1; + 1 <> 1 +end. diff --git a/check/type/bool/pass-real.p b/check/type/bool/pass-real.p new file mode 100644 index 0000000..67e8b99 --- /dev/null +++ b/check/type/bool/pass-real.p @@ -0,0 +1,10 @@ +program main ( input, output ); + var a: integer; +begin + 1.1 = 1.1; + 1.1 <= 1.1; + 1.1 >= 1.1; + 1.1 < 1.1; + 1.1 > 1.1; + 1.1 <> 1.1 +end. diff --git a/check/type/bool/pass-while.p b/check/type/bool/pass-while.p new file mode 100644 index 0000000..160c187 --- /dev/null +++ b/check/type/bool/pass-while.p @@ -0,0 +1,7 @@ +program main ( input, output ); + var a: integer; +begin + while ((1 = 1) ) + do + a:= 1 +end. diff --git a/check/type/fail-if.p b/check/type/fail-if.p new file mode 100644 index 0000000..17126d6 --- /dev/null +++ b/check/type/fail-if.p @@ -0,0 +1,9 @@ +program main ( input, output ); + var a: integer; +begin + if (1) + then + a:= 1 + else + a:= 0 +end. diff --git a/check/type/mulop/fail-int.p b/check/type/mulop/fail-int.p new file mode 100644 index 0000000..fdd83e3 --- /dev/null +++ b/check/type/mulop/fail-int.p @@ -0,0 +1,6 @@ +program main ( input, output ); + var a: integer; +begin + a := 1 * 1.1; + a := 1.1 +end. diff --git a/check/type/mulop/fail-real.p b/check/type/mulop/fail-real.p new file mode 100644 index 0000000..8975458 --- /dev/null +++ b/check/type/mulop/fail-real.p @@ -0,0 +1,5 @@ +program main ( input, output ); + var a: integer; +begin + a := 1.1 * 1 +end. diff --git a/check/type/mulop/pass-int.p b/check/type/mulop/pass-int.p new file mode 100644 index 0000000..5f1f327 --- /dev/null +++ b/check/type/mulop/pass-int.p @@ -0,0 +1,5 @@ +program main ( input, output ); + var a: integer; +begin + a := 1 * 1 +end. diff --git a/check/type/mulop/pass-real.p b/check/type/mulop/pass-real.p new file mode 100644 index 0000000..d03ee76 --- /dev/null +++ b/check/type/mulop/pass-real.p @@ -0,0 +1,5 @@ +program main ( input, output ); + var a: real; +begin + a := 3.1 * 0.04 +end. diff --git a/check/type/pass-if.p b/check/type/pass-if.p new file mode 100644 index 0000000..30e5abf --- /dev/null +++ b/check/type/pass-if.p @@ -0,0 +1,9 @@ +program main ( input, output ); + var a: integer; +begin + if ((1 = 1) ) + then + a:= 1 + else + a:= 0 +end. -- cgit v1.1 From 227b13eccaecc05d76ca8dceb922a9d280ead0c4 Mon Sep 17 00:00:00 2001 From: Tucker Evans Date: Thu, 29 Aug 2019 11:53:06 -0400 Subject: Fix return value for correctly typed statements Change okay return value to 1 so 0 can be used to denote an unset return type --- sem_check.c | 6 +++--- tree.c | 9 ++++++--- 2 files changed, 9 insertions(+), 6 deletions(-) diff --git a/sem_check.c b/sem_check.c index 3d42996..c5e9fb6 100644 --- a/sem_check.c +++ b/sem_check.c @@ -107,7 +107,7 @@ ptree *t; yyerror("Incomplete parse tree\n"); if (t->l->ret_type == t->r->ret_type) - return 0; + return 1; else { snprintf(buf, 100, "Mismached types: " "Cannot assign type %s " @@ -142,13 +142,13 @@ ptree *t; if (t->l->ret_type != BOOL) yyerror("If condition must be of type BOOL\n"); - return 0; + return 1; 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); + snprintf(buf, 100, "Unknown tree node: %d...\n", t->type); yyerror(buf); } diff --git a/tree.c b/tree.c index fd40781..bb025f5 100644 --- a/tree.c +++ b/tree.c @@ -21,6 +21,7 @@ ptree *l, *r; t->type = type; t->l = l; t->r = r; + t->ret_type = 0; return t; } @@ -90,10 +91,12 @@ ptree *t; { if (!t) return; - - set_ret_type(t->l); - set_ret_type(t->r); + if (! (t->l && t->l->ret_type == 1)) + set_ret_type(t->l); + if (! (t->r && t->r->ret_type == 1)) + set_ret_type(t->r); + t->ret_type = check_ret_type(t); return; -- cgit v1.1 From 6f3310ddead0a00c6b8c1d2085fd0e83a1ada827 Mon Sep 17 00:00:00 2001 From: Tucker Evans Date: Thu, 29 Aug 2019 11:54:46 -0400 Subject: Fix consolidate yyerror calls to after switch Any failed type checking now sets buf string to error message and breaks out of switch case and will then call yyerror with buf string. --- sem_check.c | 17 +++++++---------- 1 file changed, 7 insertions(+), 10 deletions(-) diff --git a/sem_check.c b/sem_check.c index c5e9fb6..88f41ad 100644 --- a/sem_check.c +++ b/sem_check.c @@ -65,20 +65,19 @@ ptree *t; "Cannot use boolean " "operator on type %s\n", pretty_type(type)); - yyerror(buf); + break; } } if (t->r->ret_type == t->l->ret_type) return t->r->ret_type; - else { + 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)) @@ -91,7 +90,6 @@ ptree *t; "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->l && t->l->ret_type == BOOL) @@ -108,15 +106,14 @@ ptree *t; if (t->l->ret_type == t->r->ret_type) return 1; - else { + 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; @@ -128,7 +125,7 @@ ptree *t; snprintf(buf, 100, "Cannot access array" "with type %s\n", pretty_type(t->r->ret_type)); - yyerror(buf); + break; } type = t->l->attr.nval -> var_type; @@ -149,9 +146,9 @@ ptree *t; default: return -200; snprintf(buf, 100, "Unknown tree node: %d...\n", t->type); - yyerror(buf); } + yyerror(buf); return -1; } -- cgit v1.1 From 389c2765afebb0b6112493e53117405488a4f3f1 Mon Sep 17 00:00:00 2001 From: Tucker Evans Date: Thu, 29 Aug 2019 11:57:55 -0400 Subject: Add for loop type checking --- sem_check.c | 22 +++++++++++++++++++++- 1 file changed, 21 insertions(+), 1 deletion(-) diff --git a/sem_check.c b/sem_check.c index 88f41ad..773c70a 100644 --- a/sem_check.c +++ b/sem_check.c @@ -141,7 +141,27 @@ ptree *t; yyerror("If condition must be of type BOOL\n"); return 1; case FOR: - /*TODO add for type checking after parsing is correct*/ + /* + 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"); break; default: return -200; -- cgit v1.1 From 4fced0fc39d3aeacb3c6d434aeeb622468a857cc Mon Sep 17 00:00:00 2001 From: Tucker Evans Date: Mon, 2 Sep 2019 13:34:06 -0400 Subject: Add unary minus to parsing --- pc.y | 6 ++++++ sem_check.c | 4 +++- tree.c | 3 +++ 3 files changed, 12 insertions(+), 1 deletion(-) diff --git a/pc.y b/pc.y index d679c18..ca94f5d 100644 --- a/pc.y +++ b/pc.y @@ -402,5 +402,11 @@ factor { $$ = mktree(NOT, $2, NULL); } + |ADDOP factor{ + if ($1 != SUB) + yyerror("SUB NOT CORRECT\n"); + else + $$ = mktree(SUB, $2, NULL); + } ; diff --git a/sem_check.c b/sem_check.c index 773c70a..aa83155 100644 --- a/sem_check.c +++ b/sem_check.c @@ -54,7 +54,7 @@ ptree *t; if (!(t->r && t->l)) yyerror("Missing nodes\n"); - if (t->attr.opval == ADD || t->attr.opval == OR) { + if (t->attr.opval == AND || t->attr.opval == OR) { if(t->l->ret_type == BOOL && t->r->ret_type ==BOOL) return BOOL; else { @@ -162,6 +162,8 @@ ptree *t; 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; diff --git a/tree.c b/tree.c index bb025f5..2afdfa6 100644 --- a/tree.c +++ b/tree.c @@ -182,6 +182,9 @@ int spaces; case DT: fprintf(stderr, "[DOWN-TO]"); break; + case SUB: + fprintf(stderr, "[SUB]"); + break; default: fprintf(stderr, "\t%d", t->type); yyerror("Error in tree_print"); -- cgit v1.1 From d8a7a9b0ed653ec8061896efc0c8e11b5df6b166 Mon Sep 17 00:00:00 2001 From: Tucker Evans Date: Thu, 5 Sep 2019 10:50:02 -0400 Subject: Add counting of function arguments --- main.c | 28 ++++++++++++++++++++++++++++ pc.h | 3 +++ pc.y | 15 ++++++++++----- 3 files changed, 41 insertions(+), 5 deletions(-) diff --git a/main.c b/main.c index 34acd52..d6cffdd 100644 --- a/main.c +++ b/main.c @@ -134,6 +134,34 @@ char* msg; return 0; } +int count_args(t) +ptree *t; +{ + int r, l; + + if (t->r && t->r->type == LIST) + r = count_args(t->r); + else if (t->r && t->r->type == ID) + r = 1; + else { + char buf[100]; + snprintf(buf, 100, "COUNT ARGS1: %d\n",(t->r)); + yyerror(buf); + } + + if (t->l && t->l->type == LIST) + l = count_args(t->l); + else if (t->l && t->l->type == ID) + l = 1; + else{ + char buf[100]; + snprintf(buf, 100, "COUNT ARGS2: %d\n", (t->l)); + yyerror(buf); + } + + return l + r; +} + int main() { #ifdef DEBUG_TYPES diff --git a/pc.h b/pc.h index e13c481..ea49612 100644 --- a/pc.h +++ b/pc.h @@ -2,6 +2,7 @@ #define PC_H #include "y.tab.h" +#include "tree.h" char* pretty_type(int); @@ -10,4 +11,6 @@ void debug_print(int, union YYSTYPE*); int yyerror(char*); #endif +int count_args(ptree*); + #define DEBUG diff --git a/pc.y b/pc.y index 1bb4a4f..3f3f7ad 100644 --- a/pc.y +++ b/pc.y @@ -173,17 +173,22 @@ sub_prog_head :FUNC ID arguments ':' standard_type ';' { node *tmp; - int i = -1; + int i = 0; check_id(cur_scope->prev, $2); tmp = scope_insert(cur_scope->prev, $2); - assert(tmp->func_info = malloc(sizeof struct fi)); - /*TODO add count of parameters*/ + if ($3->type == ID) + i = 1; + else + i = count_args($3); + + tmp->func_info = malloc(sizeof(struct fi)); + assert(tmp->func_info); tmp->func_info->argc = i; - assert(tmp->func_info->argv = malloc(i * sizeof int)); + assert(tmp->func_info->argv = malloc(i * sizeof(int))); - tmp->var_type = $5 + tmp->var_type = $5; cur_scope->ret_var = scope_insert(cur_scope, $2); cur_scope->ret_var->var_type = $5; -- cgit v1.1 From c6d13abfc122c15ecc182b1fc5645628e8eb4d18 Mon Sep 17 00:00:00 2001 From: Tucker Evans Date: Thu, 5 Sep 2019 17:59:44 -0400 Subject: Add function argument types --- main.c | 23 +++++++++++++++++++++++ pc.h | 3 ++- pc.y | 3 +++ scope.c | 7 ++++++- 4 files changed, 34 insertions(+), 2 deletions(-) diff --git a/main.c b/main.c index d6cffdd..6c601ff 100644 --- a/main.c +++ b/main.c @@ -162,6 +162,29 @@ ptree *t; return l + r; } +int set_func_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 (t->type == ID){ + if (--size == -1) + yyerror("VARIABLE COUNT CHANGED!!!\n"); + + *nxt = t->attr.nval->var_type; + return size; + } + return size; +} + int main() { #ifdef DEBUG_TYPES diff --git a/pc.h b/pc.h index ea49612..653b720 100644 --- a/pc.h +++ b/pc.h @@ -9,8 +9,9 @@ char* pretty_type(int); void debug_print(int, union YYSTYPE*); int yyerror(char*); -#endif int count_args(ptree*); +int set_func_types(ptree*, int*, int); +#endif #define DEBUG diff --git a/pc.y b/pc.y index 3f3f7ad..8991403 100644 --- a/pc.y +++ b/pc.y @@ -188,6 +188,9 @@ sub_prog_head tmp->func_info->argc = i; assert(tmp->func_info->argv = malloc(i * sizeof(int))); + print_tree($3); + assert(!set_func_types($3, tmp->func_info->argv, i)); + tmp->var_type = $5; cur_scope->ret_var = scope_insert(cur_scope, $2); diff --git a/scope.c b/scope.c index 00e2417..9d9da5e 100644 --- a/scope.c +++ b/scope.c @@ -146,8 +146,13 @@ scope *s; for (i = 0; i < HASH_SIZE; i++) { for( tmp=s->table[i]; tmp; tmp = tmp->next) { - fprintf(stderr, "\t%s:%s\n", tmp->name, + fprintf(stderr, "\t%s:%s\t", tmp->name, pretty_type(tmp->var_type)); + if (tmp->func_info && tmp->func_info->argv) { + for (int i = 0; i < tmp->func_info->argc; i++) + fprintf(stderr, " %s ", pretty_type(tmp->func_info->argv[i])); + } + fprintf(stderr, "\n"); } } } -- cgit v1.1 From 1300aa3672d7ae27963465fa6d8d2a6ebe8a71d2 Mon Sep 17 00:00:00 2001 From: Tucker Evans Date: Thu, 5 Sep 2019 18:09:37 -0400 Subject: Fix count_args to handle single variable parameters --- main.c | 26 +++++++++----------------- pc.y | 5 +---- 2 files changed, 10 insertions(+), 21 deletions(-) diff --git a/main.c b/main.c index 6c601ff..394e3bc 100644 --- a/main.c +++ b/main.c @@ -139,27 +139,19 @@ ptree *t; { int r, l; - if (t->r && t->r->type == LIST) - r = count_args(t->r); - else if (t->r && t->r->type == ID) - r = 1; - else { - char buf[100]; - snprintf(buf, 100, "COUNT ARGS1: %d\n",(t->r)); - yyerror(buf); - } + if (!t) + return 0; - if (t->l && t->l->type == LIST) + if (t->type == LIST){ + r = count_args(t->r); l = count_args(t->l); - else if (t->l && t->l->type == ID) - l = 1; - else{ - char buf[100]; - snprintf(buf, 100, "COUNT ARGS2: %d\n", (t->l)); - yyerror(buf); + } else if (t->type == ID) { + return 1; + } else { + yyerror("NOT A PARAMETER LIST\n"); } - return l + r; + return r + l; } int set_func_types(t, nxt, size) diff --git a/pc.y b/pc.y index 8991403..dc7b704 100644 --- a/pc.y +++ b/pc.y @@ -178,10 +178,7 @@ sub_prog_head check_id(cur_scope->prev, $2); tmp = scope_insert(cur_scope->prev, $2); - if ($3->type == ID) - i = 1; - else - i = count_args($3); + i = count_args($3); tmp->func_info = malloc(sizeof(struct fi)); assert(tmp->func_info); -- cgit v1.1 From 3a9747434de494fa189cf02ac31f6a4cff7fc761 Mon Sep 17 00:00:00 2001 From: Tucker Evans Date: Thu, 5 Sep 2019 18:15:32 -0400 Subject: Add procedure argument types --- pc.y | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) diff --git a/pc.y b/pc.y index dc7b704..72e9b6a 100644 --- a/pc.y +++ b/pc.y @@ -195,8 +195,20 @@ sub_prog_head } |PROC ID arguments ';' { + node *tmp; + int i = 0; + check_id(cur_scope->prev, $2); - scope_insert(cur_scope->prev, $2); + tmp = scope_insert(cur_scope->prev, $2); + + i = count_args($3); + + tmp->func_info = malloc(sizeof(struct fi)); + assert(tmp->func_info); + tmp->func_info->argc = i; + assert(tmp->func_info->argv = malloc(i * sizeof(int))); + + assert(!set_func_types($3, tmp->func_info->argv, i)); } ; -- cgit v1.1 From b26e6d2c8ff71beac5da975de1b6ac450bfe282b Mon Sep 17 00:00:00 2001 From: Tucker Evans Date: Thu, 5 Sep 2019 18:16:11 -0400 Subject: Fix debug prints - Removes tree_print from function parsing - ID can't have ID as child, removes check in tree_print --- pc.y | 1 - tree.c | 14 ++++---------- 2 files changed, 4 insertions(+), 11 deletions(-) diff --git a/pc.y b/pc.y index 72e9b6a..f97db8d 100644 --- a/pc.y +++ b/pc.y @@ -185,7 +185,6 @@ sub_prog_head tmp->func_info->argc = i; assert(tmp->func_info->argv = malloc(i * sizeof(int))); - print_tree($3); assert(!set_func_types($3, tmp->func_info->argv, i)); tmp->var_type = $5; diff --git a/tree.c b/tree.c index 2afdfa6..d1d0e76 100644 --- a/tree.c +++ b/tree.c @@ -144,16 +144,10 @@ int spaces; 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)); + 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 ecfd5f25bfa7b5ce00b8feb83eb1deeb7009e7f7 Mon Sep 17 00:00:00 2001 From: Tucker Evans Date: Thu, 5 Sep 2019 21:05:10 -0400 Subject: Add new type check files for func/proc arguments --- check/args-proc.p | 45 +++++++++++++++++++++++++++++++++++++++++++++ check/args.p | 45 +++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 90 insertions(+) create mode 100644 check/args-proc.p create mode 100644 check/args.p diff --git a/check/args-proc.p b/check/args-proc.p new file mode 100644 index 0000000..d49f932 --- /dev/null +++ b/check/args-proc.p @@ -0,0 +1,45 @@ +program main ( input, output ); + + var a, b: integer; + var x,y,z: real; + var ai :array [1..10] of integer; + + procedure bar (a, b: integer); + var test:integer; + begin + test := 2; + a := 2 + end; + procedure bar1 (a, b: real); + var test:integer; + begin + test := 2; + a := 2.0 + end; + procedure bar2 (a: real); + var test:integer; + begin + test := 2; + a := 2.0 + end; + procedure bar3 (a, b, c, d, e, f, g: integer); + var test:integer; + begin + test := 2; + a := 2 + end; + procedure bar4 (a, b, c, d: real; e, f, g: integer); + var test:integer; + begin + test := 2; + a := 2.0; + e := 2 + end; +begin +{ TEST } + + a := 1; + x := 3.14; + b := a + 35 + (* test *) +end. diff --git a/check/args.p b/check/args.p new file mode 100644 index 0000000..358dc7c --- /dev/null +++ b/check/args.p @@ -0,0 +1,45 @@ +program main ( input, output ); + + var a, b: integer; + var x,y,z: real; + var ai :array [1..10] of integer; + + function bar (a, b: integer) : real; + var test:integer; + begin + test := 2; + a := 2 + end; + function bar1 (a, b: real) : real; + var test:integer; + begin + test := 2; + a := 2.0 + end; + function bar2 (a: real) : real; + var test:integer; + begin + test := 2; + a := 2.0 + end; + function bar3 (a, b, c, d, e, f, g: integer) : real; + var test:integer; + begin + test := 2; + a := 2 + end; + function bar4 (a, b, c, d: real; e, f, g: integer) : real; + var test:integer; + begin + test := 2; + a := 2.0; + e := 2 + end; +begin +{ TEST } + + a := 1; + x := 3.14; + b := a + 35 + (* test *) +end. -- cgit v1.1 From 948b0460c9d079e5eff4e6247d35aa946956e4a5 Mon Sep 17 00:00:00 2001 From: Tucker Evans Date: Sun, 8 Sep 2019 21:18:44 -0400 Subject: Add checking types on function call --- main.c | 26 +++++++++++++++++++++++++- pc.h | 1 + pc.y | 5 ++++- sem_check.c | 32 +++++++++++++++++++++++++++++--- tree.c | 11 ++++++++++- 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 #include +#include +#include #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); -- cgit v1.1 From 6130381c23c2ca4e050e83b7a20e3ba56d0fc283 Mon Sep 17 00:00:00 2001 From: Tucker Evans Date: Sun, 8 Sep 2019 22:00:47 -0400 Subject: Adds type checking procedure arguments --- pc.y | 2 ++ sem_check.c | 6 ++++-- sem_check.h | 2 ++ tree.c | 1 + 4 files changed, 9 insertions(+), 2 deletions(-) diff --git a/pc.y b/pc.y index 8d142a2..c144043 100644 --- a/pc.y +++ b/pc.y @@ -270,6 +270,7 @@ statement |proc_statement { $$ = $1; + check_call($$); } |compound_statement { @@ -346,6 +347,7 @@ proc_statement tmp = check_exists(cur_scope, $1); $$ = mktree(PCALL, mkid(tmp), $3); } + /*calls checked with proc_statement*/ ; expr_list diff --git a/sem_check.c b/sem_check.c index f6e412a..af97507 100644 --- a/sem_check.c +++ b/sem_check.c @@ -183,10 +183,12 @@ ptree *t; { int argc, *argv; - print_tree(t); - if (!(t && t->attr.nval && t->attr.nval->func_info)) + if (!(t && (t->type == FCALL || t->type == PCALL))) yyerror("Tree is not a function call\n"); + if (!(t->l && t->l->attr.nval && t->l->attr.nval->func_info)) + yyerror("Incorrect Call Tree\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*/ diff --git a/sem_check.h b/sem_check.h index ce7d7fb..0da2cc9 100644 --- a/sem_check.h +++ b/sem_check.h @@ -10,4 +10,6 @@ node* check_exists(scope*, char*); int check_ret_type(ptree*); +void check_call(ptree*); + #endif diff --git a/tree.c b/tree.c index a1a3f0f..b30fa35 100644 --- a/tree.c +++ b/tree.c @@ -22,6 +22,7 @@ ptree *l, *r; t->l = l; t->r = r; t->ret_type = 0; + t->attr.nval = 0; return t; } -- cgit v1.1 From 11b46650941f54bf7b95648de04c897656b9867b Mon Sep 17 00:00:00 2001 From: Tucker Evans Date: Thu, 12 Sep 2019 19:50:14 -0400 Subject: Fix setting type for multiple declared arrays --- pc.y | 6 +++--- scope.c | 7 +++++++ tree.c | 40 ++++++++++++++++++++++++++++++++++------ tree.h | 2 +- 4 files changed, 45 insertions(+), 10 deletions(-) diff --git a/pc.y b/pc.y index c144043..26d766f 100644 --- a/pc.y +++ b/pc.y @@ -81,7 +81,7 @@ extern scope *cur_scope; %type proc_statement %type var -%type type +%type type %type standard_type %type TD @@ -131,11 +131,11 @@ var_declarations type :standard_type { - $$ = $1; + $$ = mktree($1, NULL, NULL); } |ARRAY '[' INUM DOTS INUM ']' OF standard_type { - $$ = ARRAY - $8; + $$ = mktree(ARRAY - $8, mkinum($3), mkinum($5)); } ; diff --git a/scope.c b/scope.c index 9d9da5e..0355014 100644 --- a/scope.c +++ b/scope.c @@ -146,8 +146,15 @@ scope *s; for (i = 0; i < HASH_SIZE; i++) { for( tmp=s->table[i]; tmp; tmp = tmp->next) { + if(!tmp->array_info) fprintf(stderr, "\t%s:%s\t", tmp->name, pretty_type(tmp->var_type)); + else + fprintf(stderr, "\t%s:%s [%d:%d]\t", tmp->name, + pretty_type(tmp->var_type), + tmp->array_info->start_idx, + tmp->array_info->start_idx + + tmp->array_info->size); if (tmp->func_info && tmp->func_info->argv) { for (int i = 0; i < tmp->func_info->argc; i++) fprintf(stderr, " %s ", pretty_type(tmp->func_info->argv[i])); diff --git a/tree.c b/tree.c index b30fa35..35fe071 100644 --- a/tree.c +++ b/tree.c @@ -60,31 +60,51 @@ ptree *l, *r; return p; } -void update_type_info(list, type) -int type; -ptree *list; +void update_type_info(list, t) +ptree *list, *t; { - assert(list); + int type; + struct ai *info = NULL; + assert(list && t); + + type = t->type; + if (type != INT && type != REAL){ + assert(info = malloc(sizeof(struct ai))); + info->size = t->r->attr.ival - t->l->attr.ival; + info->start_idx = t->l->attr.ival; + } + if (list->type == ID) { list->attr.nval->var_type = type; + if (info) + list->attr.nval->array_info = info; return; } while (list->r && list->r->type == ID) { /*Set type of right child through list*/ list->r->attr.nval->var_type = type; + if (info) + list->r->attr.nval->array_info = info; if (list->l) { if (list->l->type == LIST) { list = list->l; continue; /*Continue down list*/ - } else if (list->l->type == ID) + } else if (list->l->type == ID) { /*Set type of first declared ID (only left node in LIST)*/ list->l->attr.nval->var_type = type; + if (info){ + list->l->attr.nval->array_info = info; + } + } } - return; /*At _end_ of list (did not continue)*/ + break; /*At _end_ of list (did not continue)*/ } + + /*TODO free t. and list?*/ + return; } void set_ret_type(t) @@ -189,6 +209,14 @@ int spaces; case FCALL: fprintf(stderr, "[CALL]"); break; + case INT: + case REAL: + fprintf(stderr, "[STD TYPE]"); + break; + case ARRAY - INT: + case ARRAY - REAL: + fprintf(stderr, "[ARRAY]"); + break; default: fprintf(stderr, "[?: %d]", t->type); yyerror("Error in tree_print"); diff --git a/tree.h b/tree.h index 23edf8f..0c0cd74 100644 --- a/tree.h +++ b/tree.h @@ -27,7 +27,7 @@ ptree* mkinum(int); ptree* mkrnum(float); ptree* mkop(int, int, ptree*, ptree*); -void update_type_info(ptree*, int); +void update_type_info(ptree*, ptree*); void set_ret_type(ptree*); #endif -- cgit v1.1 From d8f19b2f532d0a0d7131c1141ca481fa2d08b946 Mon Sep 17 00:00:00 2001 From: Tucker Evans Date: Thu, 12 Sep 2019 19:56:21 -0400 Subject: Add some debug print methods to pc.y --- pc.y | 7 +++++++ scope.h | 2 ++ 2 files changed, 9 insertions(+) diff --git a/pc.y b/pc.y index 26d766f..790610b 100644 --- a/pc.y +++ b/pc.y @@ -97,6 +97,10 @@ program { set_ret_type($9); print_tree($9); +#ifdef DEBUG + print_scope(cur_scope); +#endif + pop_scope(&cur_scope); } ; @@ -164,6 +168,9 @@ sub_prog_declaration { set_ret_type($4); print_tree($4); +#ifdef DEBUG + print_scope(cur_scope); +#endif pop_scope(&cur_scope); } ; diff --git a/scope.h b/scope.h index 8a809fb..4fbe9ca 100644 --- a/scope.h +++ b/scope.h @@ -24,6 +24,8 @@ node* scope_search_all(scope*, char*); node* scope_search(scope*, char*); node* scope_safe_search(scope*, char*); +void print_scope(scope *); + /*hash function*/ int hashpjw(char*); #endif -- cgit v1.1