aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--check/for.p7
-rw-r--r--check/type/addop/fail-int.p4
-rw-r--r--check/type/addop/fail-real.p5
-rw-r--r--check/type/addop/pass-int.p4
-rw-r--r--check/type/addop/pass-real.p5
-rw-r--r--check/type/arrray/fail-access.p5
-rw-r--r--check/type/arrray/fail-int.p5
-rw-r--r--check/type/arrray/fail-real.p5
-rw-r--r--check/type/arrray/pass-access.p5
-rw-r--r--check/type/arrray/pass-int.p5
-rw-r--r--check/type/arrray/pass-real.p5
-rw-r--r--check/type/assign/fail-int.p5
-rw-r--r--check/type/assign/fail-real.p5
-rw-r--r--check/type/assign/pass-int.p5
-rw-r--r--check/type/assign/pass-real.p5
-rw-r--r--check/type/bool/.pass-bool.c.swpbin0 -> 12288 bytes
-rw-r--r--check/type/bool/fail-and.p7
-rw-r--r--check/type/bool/fail-bool.p5
-rw-r--r--check/type/bool/fail-if.p9
-rw-r--r--check/type/bool/fail-int.p5
-rw-r--r--check/type/bool/fail-or.p6
-rw-r--r--check/type/bool/fail-real.p4
-rw-r--r--check/type/bool/fail-while.p7
-rw-r--r--check/type/bool/pass-bool.p7
-rw-r--r--check/type/bool/pass-if.p9
-rw-r--r--check/type/bool/pass-int.p10
-rw-r--r--check/type/bool/pass-real.p10
-rw-r--r--check/type/bool/pass-while.p7
-rw-r--r--check/type/fail-if.p9
-rw-r--r--check/type/mulop/fail-int.p6
-rw-r--r--check/type/mulop/fail-real.p5
-rw-r--r--check/type/mulop/pass-int.p5
-rw-r--r--check/type/mulop/pass-real.p5
-rw-r--r--check/type/pass-if.p9
-rw-r--r--main.c59
-rw-r--r--node.c4
-rw-r--r--pc.h3
-rw-r--r--pc.l12
-rw-r--r--pc.y42
-rw-r--r--scope.c6
-rw-r--r--scope.h4
-rw-r--r--sem_check.c149
-rw-r--r--sem_check.h5
-rw-r--r--tree.c131
-rw-r--r--tree.h4
45 files changed, 545 insertions, 74 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/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
--- /dev/null
+++ b/check/type/bool/.pass-bool.c.swp
Binary files 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.
diff --git a/main.c b/main.c
index 6ded432..34acd52 100644
--- a/main.c
+++ b/main.c
@@ -1,3 +1,5 @@
+#include "pc.h"
+
#include <stdio.h>
#include <stdlib.h>
#include <assert.h>
@@ -5,7 +7,6 @@
#include "node.h"
#include "scope.h"
#include "y.tab.h"
-#include "pc.h"
extern char *yytext;
extern int line_num;
@@ -129,15 +130,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/node.c b/node.c
index 40ed47c..eaf4190 100644
--- a/node.c
+++ b/node.c
@@ -1,10 +1,10 @@
+#include "node.h"
+
#include <stdio.h>
#include <stdlib.h>
#include <assert.h>
#include <string.h>
-#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/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;
}
diff --git a/pc.y b/pc.y
index cd993ec..1bb4a4f 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"
@@ -83,6 +84,8 @@ extern scope *cur_scope;
%type <ival> type
%type <ival> standard_type
+%type <ival> TD
+
%%
program
@@ -92,6 +95,7 @@ program
compound_statement
'.'
{
+ set_ret_type($9);
print_tree($9);
}
;
@@ -158,6 +162,7 @@ sub_prog_declaration
sub_prog_declarations
compound_statement
{
+ set_ret_type($4);
print_tree($4);
pop_scope(&cur_scope);
}
@@ -262,12 +267,36 @@ 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
+ {
+ $$ = $1;
}
;
-TD: TO | DT;
+TD
+ :TO
+ {
+ $$ = TO;
+ }
+ |DT
+ {
+ $$ = DT;
+ }
+;
var
:ID
@@ -280,6 +309,7 @@ var
tmp = scope_safe_search(cur_scope, $1);
$$ = mktree(ARRAY_ACCESS, mkid(tmp), $3);
+ $$->attr.nval = $$->l->attr.nval;
}
;
@@ -382,5 +412,11 @@ factor
{
$$ = mktree(NOT, $2, NULL);
}
+ |ADDOP factor{
+ if ($1 != SUB)
+ yyerror("SUB NOT CORRECT\n");
+ else
+ $$ = mktree(SUB, $2, NULL);
+ }
;
diff --git a/scope.c b/scope.c
index eca78cd..00e2417 100644
--- a/scope.c
+++ b/scope.c
@@ -1,10 +1,12 @@
+#include "scope.h"
+
#include <stdio.h>
#include <stdlib.h>
#include <assert.h>
#include <string.h>
-#include "node.h"
-#include "scope.h"
+#include "pc.h"
+
scope* mkscope()
{
diff --git a/scope.h b/scope.h
index 0a07a26..8a809fb 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 {
@@ -20,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*);
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;
+
+}
+
diff --git a/sem_check.h b/sem_check.h
index eef9e96..ce7d7fb 100644
--- a/sem_check.h
+++ b/sem_check.h
@@ -1,8 +1,13 @@
#ifndef SEMCHECK_H
#define SEMCHECK_H
+#include "scope.h"
+#include "tree.h"
+
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..2afdfa6 100644
--- a/tree.c
+++ b/tree.c
@@ -1,12 +1,14 @@
+#include "tree.h"
+
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <assert.h>
-#include "node.h"
-#include "tree.h"
#include "y.tab.h"
+#include "scope.h"
#include "pc.h"
+#include "sem_check.h"
/* parse tree funcs */
ptree* mktree(type, l, r)
@@ -19,6 +21,7 @@ ptree *l, *r;
t->type = type;
t->l = l;
t->r = r;
+ t->ret_type = 0;
return t;
}
@@ -83,6 +86,22 @@ ptree *list;
}
}
+void set_ret_type(t)
+ptree *t;
+{
+ if (!t)
+ return;
+
+ 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;
+}
+
/*PRINT FUNCS*/
@@ -106,51 +125,71 @@ int spaces;
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;
- default:
- fprintf(stderr, "\t%d", t->type);
- yyerror("Error in tree_print");
+ 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;
+ case WHILE:
+ fprintf(stderr, "[WHILE]");
+ break;
+ case FOR:
+ fprintf(stderr, "[FOR]");
+ break;
+ case TO:
+ fprintf(stderr, "[TO]");
+ break;
+ 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");
}
- 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..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 {
@@ -12,6 +14,7 @@ typedef struct parse_tree {
MULOP: MUL DIV
*/
} attr;
+ int ret_type;
struct parse_tree *l, *r;
} ptree;
@@ -25,5 +28,6 @@ ptree* mkrnum(float);
ptree* mkop(int, int, ptree*, ptree*);
void update_type_info(ptree*, int);
+void set_ret_type(ptree*);
#endif