aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--check/args-proc.p45
-rw-r--r--check/args.p45
-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.c67
-rw-r--r--node.c3
-rw-r--r--node.h13
-rw-r--r--pc.h5
-rw-r--r--pc.y56
-rw-r--r--scope.c14
-rw-r--r--scope.h2
-rw-r--r--sem_check.c81
-rw-r--r--sem_check.h2
-rw-r--r--tree.c78
-rw-r--r--tree.h2
46 files changed, 561 insertions, 45 deletions
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.
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 15135bb..246bfb0 100644
--- a/main.c
+++ b/main.c
@@ -134,6 +134,73 @@ char* msg;
return 0;
}
+int count_args(t)
+ptree *t;
+{
+ int r, l;
+
+ if (!t)
+ return 0;
+
+ if (t->type == LIST){
+ r = count_args(t->r);
+ l = count_args(t->l);
+ } else if (t->type != LIST) {
+ return 1;
+ } else {
+ fprintf(stderr, "PTR: %x\n", t);
+ yyerror("NOT A PARAMETER LIST\n");
+ }
+
+ return r + l;
+}
+
+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 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/node.c b/node.c
index d8d5276..eaf4190 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.h b/pc.h
index e13c481..79174f4 100644
--- a/pc.h
+++ b/pc.h
@@ -2,12 +2,17 @@
#define PC_H
#include "y.tab.h"
+#include "tree.h"
char* pretty_type(int);
void debug_print(int, union YYSTYPE*);
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 426cf71..4a2d664 100644
--- a/pc.y
+++ b/pc.y
@@ -81,7 +81,7 @@ extern scope *cur_scope;
%type <tval> proc_statement
%type <tval> var
-%type <ival> type
+%type <tval> type
%type <ival> standard_type
%type <ival> TD
@@ -98,6 +98,10 @@ program
set_ret_type($9);
print_tree($9);
free_tree($4);
+#ifdef DEBUG
+ print_scope(cur_scope);
+#endif
+ pop_scope(&cur_scope);
}
;
@@ -132,11 +136,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));
}
;
@@ -166,6 +170,9 @@ sub_prog_declaration
set_ret_type($4);
print_tree($4);
free_tree($4);
+#ifdef DEBUG
+ print_scope(cur_scope);
+#endif
pop_scope(&cur_scope);
}
;
@@ -174,16 +181,42 @@ sub_prog_declaration
sub_prog_head
:FUNC ID arguments ':' standard_type ';'
{
+ 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));
+
+ tmp->var_type = $5;
cur_scope->ret_var = scope_insert(cur_scope, $2);
cur_scope->ret_var->var_type = $5;
}
|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));
}
;
@@ -192,7 +225,9 @@ arguments
{
$$ = $2;
}
- |/*empty*/
+ |/*empty*/{
+ $$ = NULL;
+ }
;
param_list
@@ -244,6 +279,7 @@ statement
|proc_statement
{
$$ = $1;
+ check_call($$);
}
|compound_statement
{
@@ -320,6 +356,7 @@ proc_statement
tmp = check_exists(cur_scope, $1);
$$ = mktree(PCALL, mkid(tmp), $3);
}
+ /*calls checked with proc_statement*/
;
expr_list
@@ -387,6 +424,7 @@ factor
tmp = check_exists(cur_scope, $1);
$$ = mktree(FCALL, mkid(tmp), $3);
+ check_call($$);
}
|INUM
{
@@ -404,5 +442,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 00e2417..0355014 100644
--- a/scope.c
+++ b/scope.c
@@ -146,8 +146,20 @@ 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,
+ 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]));
+ }
+ fprintf(stderr, "\n");
}
}
}
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
diff --git a/sem_check.c b/sem_check.c
index 3d42996..af97507 100644
--- a/sem_check.c
+++ b/sem_check.c
@@ -2,6 +2,8 @@
#include <assert.h>
#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
#include "y.tab.h"
#include "pc.h"
@@ -54,7 +56,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 {
@@ -65,20 +67,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 +92,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)
@@ -107,18 +107,14 @@ ptree *t;
yyerror("Incomplete parse tree\n");
if (t->l->ret_type == t->r->ret_type)
- return 0;
- else {
+ 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));
- yyerror(buf);
- }
-
-
break;
case ARRAY_ACCESS:
if (!(t->r && t->l && t->l->attr.nval))
@@ -128,7 +124,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;
@@ -142,17 +138,68 @@ 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*/
+ /*
+ 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;
+ case PCALL:
+ case FCALL:
+ if (t->l && t->l->attr.nval)
+ return t->l->attr.nval->var_type;
default:
return -200;
- snprintf(buf, 101, "Unknown tree node: %d...\n", t->type);
- yyerror(buf);
+ snprintf(buf, 100, "Unknown tree node: %d...\n", t->type);
}
+ yyerror(buf);
return -1;
}
+void check_call(t)
+ptree *t;
+{
+ int argc, *argv;
+
+ 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*/
+ 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/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 bc4a770..9b32f15 100644
--- a/tree.c
+++ b/tree.c
@@ -21,6 +21,8 @@ ptree *l, *r;
t->type = type;
t->l = l;
t->r = r;
+ t->ret_type = 0;
+ t->attr.nval = 0;
return t;
}
@@ -58,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)
@@ -90,10 +112,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;
@@ -141,16 +165,14 @@ 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));
+ 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 +201,24 @@ int spaces;
case DT:
fprintf(stderr, "[DOWN-TO]");
break;
+ case SUB:
+ fprintf(stderr, "[SUB]");
+ break;
+ case PCALL:
+ fprintf(stderr,"[P]");
+ 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, "\t%d", t->type);
+ fprintf(stderr, "[?: %d]", t->type);
yyerror("Error in tree_print");
}
fprintf(stderr," %d\n", t->ret_type);
diff --git a/tree.h b/tree.h
index ed7c1ef..b0a1085 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*);
void free_tree(ptree*);