8000 useless commit · compiler-experts/miniJava@6e83d4d · GitHub
[go: up one dir, main page]

Skip to content

Commit 6e83d4d

Browse files
committed
useless commit
1 parent 0904e5c commit 6e83d4d

File tree

5 files changed

+260
-36
lines changed

5 files changed

+260
-36
lines changed

README.md

Lines changed: 53 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -127,14 +127,64 @@ If you are a team member of the project, please follow the [Working Standard](./
127127
- [x] non-static Methods
128128
---
129129

130-
### Second part: The typer and the execution support
130+
### Second part: The Type-checking and the Execution
131131

132132
*Deadline 25/02/2018*
133133

134-
#### Type
134+
#### Type-checking
135135

136-
- [] The construction of the class definition environment. This environment contains the type of methods for each class. This phase ignores the attributes (which are not visible outside the class) and the method bodies.
136+
- [x] The construction of the class definition environment. This environment contains the type of methods for each class. This phase ignores the attributes (which are not visible outside the class) and the method bodies.
137+
- [x] create a class definition environment type called `class_env`, it contains 4 fields as follows
138+
- methods: a `Hashtbl` that maps from methode name to methode return type and argument type
139+
- constructors: a `Hashtbl` that maps from constructor name to class reference type and argument type
140+
- attributes: a `Hashtbl` that maps from attribute name to attribute type (declared type)
141+
- parent: a class reference type that refers to its class
142+
- [x] create a `Hashtbl` that maps from class
137143
- [] The second phase is concerned with verifying that the inside of classes is correct (mainly the body of methods). She will also make sure of the correction of the higher level expression.
144+
- [x] create 3 verification methode that verifies the following aspects of the program
145+
- [x] `verify_methods` that checks the type of methods
146+
- [x] create a local definition environment type called `current_env` it contains 3 fields as follows
147+
- returntype: the declared return type of the methode
148+
- variables: a `Hashtbl` that maps from local variable name to local variable declared type
149+
- this_class: the id of the class
150+
- env_type: a string that identifies the type of the local definition environment, it could be `constructor`, `methode` or `attribute`, in this case, the `env_type` is `methode`
151+
- [x] write a verification methode (`verify_declared_args`) that checks the declared type of variables in the methode arguments
152+
- [x] check if there exists Duplicate Local Variable
153+
- [] write a verification methode (`verify_statement`) that checks the body of the methode
154+
- [x] check declared variables
155+
- [x] check block of statement
156+
- [x] check expression
157+
- [x] check return statement when it's none, ex: `return;`
158+
- [] check return statement when it's not none, ex: `return x;`
159+
- [] check throw statement
160+
- [] check while statement
161+
- [] check if statement when it doesn't have `else`
162+
- [] check if statement when it has `else`
163+
- [] check for statement
164+
- [] check try statement
165+
- [x] `verify_constructors` that checks the type of constructors
166+
- [x] `verify_attributes` that checks the type of attributes
167+
168+
##### Errors that can be found during Type-checking
169+
170+
- ArgumentAlreadyExists
171+
- AttributeAlreadyExists
172+
- ClassAlreadyExists
173+
- ConstructorAlreadyExists
174+
- DuplicateLocalVariable
175+
- IncompatibleTypes
176+
- when constructor try to return a variable -> IncompatibleTypes("unexpected return value")
177+
- when methode return does not contain variable -> IncompatibleTypes("missing return value")
178+
- when methode return type does not corresponds with the declared one -> IncompatibleTypes("missing return value")
179+
- MethodAlreadyExists
180+
- UnknowVariable
181+
- WrongTypesAssignOperation
182+
- WrongTypesOperation
183+
184+
##### Errors that can not yet be found during Type-checking
185+
186+
- errors related to overloading
187+
- errors related to overriding
138188

139189
#### Execution
140190

phase2/Typing/TypeError.ml

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,4 +9,11 @@ exception MethodAlreadyExists of string
99
exception ConstructorAlreadyExists of string
1010
exception WrongTypesAssignOperation of Type.t option * Type.t option
1111
exception WrongTypesOperation of Type.t option * Type.t option
12-
exception UnknowVariable of string
12+
exception UnknownVariable of string
13+
exception UnknownClass of string
14+
exception WrongInvokedArgumentsLength of string
15+
exception ArgumentTypeNotExiste
16+
exception InvalidMethodDeclaration of string
17+
exception ArgumentTypeNotMatch of string
18+
exception UnknownMethod of string
19+
exception UnknowActualType of string

phase2/Typing/Typing.ml

Lines changed: 136 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,8 @@ type func_info = {
1010
type curr_env = {
1111
returntype : Type.t;
1212
variables: (string, Type.t) Hashtbl.t;
13-
this_class: string
13+
this_class: string;
14+
env_type: string
1415
}
1516

1617
(* class definition environment *)
@@ -37,7 +38,26 @@ let print_class_envs class_envs =
3738
Hashtbl.iter (fun k v -> print_string("class " ^ k ^ "\n"); print_class_env v ) class_envs;
3839
print_endline ("")
3940

40-
let verify_argument current_env arguments =
41+
42+
(* compare two arguments'type in two lists*)
43+
let compare_args a1 a2 =
44+
match a1.etype with
45+
| None -> raise(ArgumentTypeNotExiste)
46+
| Some t -> if(t <> a2.ptype) then raise(ArgumentTypeNotMatch("arguments type not match"))
47+
48+
(* check if the input arguments' type is coherent *)
49+
let verify_invoke_args args const_info func_name =
50+
(* chek if the length of arguments match the arguments which are defined in a constructor *)
51+
if(List.length args <> List.length const_info) then
52+
raise(WrongInvokedArgumentsLength("actual and formal argument lists differ in length"))
53+
else
54+
begin
55+
(* Use List.iter2 to compare to list*)
56+
List.iter2 compare_args args const_info
57+
end
58+
59+
(* verify declared types of variables in constructor arguments or methodes arguments *)
60+
let verify_declared_args current_env arguments =
4161
if (Hashtbl.mem current_env.variables arguments.pident) <> true
4262
then (
4363
(* print_arguments " " arguments; *)
@@ -61,7 +81,7 @@ let verify_name s env current_env =
6181
begin
6282
(* second find in global env *)
6383
if (Hashtbl.mem (Hashtbl.find env current_env.this_class).attributes s) <> true
64-
then raise(UnknowVariable(s))
84+
then raise(UnknownVariable(s))
6585
else Some(Hashtbl.find (Hashtbl.find env current_env.this_class).attributes s)
6686
end
6787
else Some(Hashtbl.find current_env.variables s)
@@ -70,16 +90,16 @@ let verify_name s env current_env =
7090
let verify_assignop_type t1 t2 =
7191
if t1 <> t2 then
7292
begin
73-
raise(TypeError.WrongTypesAssignOperation(t1, t2));
93+
raise(WrongTypesAssignOperation(t1, t2));
7494
match t1 with
7595
| Some t ->
7696
print_string "\n************************\n";
77-
print_string ((Type.stringOf t));
97+
print_string ((stringOf t));
7898
print_string "\n************************\n";
7999
match t2 with
80100
| Some t ->
81101
print_string "\n++++++++++++++++++++++\n";
82-
print_string ((Type.stringOf t));
102+
print_string ((stringOf t));
83103
print_string "\n++++++++++++++++++++++\n";
84104
| None -> ()
85105
| None -> ()
@@ -89,16 +109,69 @@ let verify_assignop_type t1 t2 =
89109
let verify_operation_type t1 op t2 =
90110
if t1 <> t2 then
91111
begin
92-
raise(TypeError.WrongTypesOperation(t1, t2));
112+
raise(WrongTypesOperation(t1, t2));
113+
end
114+
115+
(* check the type of call expression when it existe the method name, the arguments and global env *)
116+
let verify_call_expr meth_name args env class_name =
117+
let meths_table = (Hashtbl.find env class_name).methods in
118+
(* first check if method defines in class *)
119+
if(Hashtbl.mem meths_table meth_name) <> true then
120+
raise(UnknownMethod(meth_name))
121+
else
122+
begin
123+
let meth_info = Hashtbl.find meths_table meth_name in
124+
try
125+
verify_invoke_args args meth_info.fargs class_name;
126+
Some(meth_info.ftype);
127+
with
128+
| ArgumentTypeNotExiste -> raise(ArgumentTypeNotExiste)
129+
| ArgumentTypeNotMatch s-> raise(ArgumentTypeNotMatch("Arguments\' type in "^meth_name^" not match"))
130+
| WrongInvokedArgumentsLength s -> raise(WrongInvokedArgumentsLength(s))
93131
end
94132

95133
(* check the type of the expressions *)
96134
let rec verify_expression env current_env e =
97-
print_string(string_of_expression_desc(e.edesc));
135+
(* print_string(string_of_expression_desc(e.edesc)); *)
98136
match e.edesc with
99-
| New (None,n,al) -> () (*TODO*)
137+
| New (None,n,al) ->
138+
List.iter (verify_expression env current_env) al;
139+
let (lastClass, mylist) = ListII.extract_last n in
140+
(* first find in global env class*)
141+
if(Hashtbl.mem env lastClass) <> true then
142+
raise(UnknownClass(lastClass))
143+
else
144+
begin
145+
(* then check if constructor has already declared or not *)
146+
let consts_table = (Hashtbl.find env lastClass).constructors in
147+
(* when there is no constructor in global env and the arguments are null,
148+
then set the expression type is the type of constructor *)
149+
if(Hashtbl.length consts_table = 0 && List.length al = 0) then
150+
e.etype <- Some(Ref({ tpath = []; tid = lastClass }))
151+
else
152+
begin
153+
(* check the type of arguments in the constructor *)
154+
let consts_info = Hashtbl.find consts_table lastClass in
155+
try
156+
verify_invoke_args al consts_info.fargs lastClass;
157+
e.etype <- Some(consts_info.ftype)
158+
with
159+
| ArgumentTypeNotExiste -> raise(ArgumentTypeNotExiste)
160+
| ArgumentTypeNotMatch s -> raise(ArgumentTypeNotMatch("Arguments\' type in "< F438 /span>^lastClass^" not match"))
161+
| WrongInvokedArgumentsLength s -> raise(WrongInvokedArgumentsLength(s))
162+
end
163+
end
100164
(* | NewArray (Some n1,n2,al) -> () (*TODO*) *)
101-
| Call (r,m,al) -> () (*TODO*)
165+
| Call (r,m,al) ->
166+
(match r with
167+
| None -> (* when method is called without declaring class name*)
168+
List.iter (verify_expression env current_env) al;
169+
e.etype <- verify_call_expr m al env current_env.this_class
170+
| Some c ->
171+
List.iter (verify_expression env current_env) al;
172+
let class_name = string_of_expression(c) in
173+
e.etype <- verify_call_expr m al env class_name
174+
)
102175
| Attr (r,a) -> () (*TODO*)
103176
| If (e1, e2, e3) -> () (*TODO*)
104177
| Val v ->
@@ -143,9 +216,9 @@ let rec verify_statement current_env envs statement =
143216
match e.etype with
144217
| None -> print_string ("["^s^"]"); (*TODO*)
145218
(* check int i = 2, int j = i *)
146-
| Some real_t -> (
147-
if real_t <> t
148-
then raise(IncompatibleTypes((Type.stringOf real_t)^" cannnot be converted to "^(Type.stringOf t)^" for "^id))
219+
| Some actual_t -> (
220+
if actual_t <> t (*actual type not equals to declared type*)
221+
then raise(IncompatibleTypes((Type.stringOf actual_t)^" cannnot be converted to "^(Type.stringOf t)^" for "^id))
149222
else add_local_variable current_env id t
150223
)
151224
)
@@ -154,16 +227,41 @@ let rec verify_statement current_env envs statement =
154227
| Block b ->
155228
let block_env = { returntype = current_env.returntype;
156229
variables = Hashtbl.copy current_env.variables;
157-
this_class = current_env.this_class } in
230+
this_class = current_env.this_class;
231+
env_type = current_env.env_type} in
158232
List.iter (verify_statement block_env envs) b
159-
| Nop -> () (*TODO*)
160-
| Expr e -> () (*TODO*)
161-
| Return None -> () (*TODO*)
162-
| Return Some(e) -> () (*TODO*)
233+
| Nop -> ()
234+
| Expr e -> verify_expression envs current_env e
235+
(* check when the return clause is none, ex: return;*)
236+
| Return None -> (
237+
match current_env.returntype with
238+
| Ref(ref)-> if current_env.env_type <> "constructor" then raise(IncompatibleTypes("missing return value"))
239+
| Void -> ()
240+
| _ -> raise(IncompatibleTypes("This methode must return a result of type "^(Type.stringOf current_env.returntype)))
241+
)
242+
(* check when the return clause is not none, ex: return x;*)
243+
| Return Some(e) -> (verify_expression envs current_env e;
244+
if current_env.env_type <> "methode" then raise(IncompatibleTypes("unexpected return value"));
245+
match current_env.returntype, e.etype with
246+
| declared_t, Some(actual_t) -> if declared_t <> actual_t
247+
then raise(IncompatibleTypes((stringOf actual_t)^" cannot be converted to "^(stringOf declared_t)))
248+
| _, None -> raise(InvalidMethodDeclaration("return type required"))
249+
)
163250
| Throw e -> () (*TODO*)
164251
| While(e,s) -> () (*TODO*)
165-
| If(e,s,None) -> () (*TODO*)
166-
| If(e,s1,Some s2) -> () (*TODO*)
252+
| If(e,s,None) -> (verify_expression envs current_env e;
253+
verify_statement current_env envs s;
254+
match e.etype with
255+
| None -> raise(UnknowActualType("unknow type in if condition"))
256+
| Some actual_t -> if actual_t <> Primitive(Boolean)
257+
then raise(IncompatibleTypes((stringOf actual_t)^" cannot be converted to boolean")))
258+
| If(e,s1,Some s2) -> (verify_expression envs current_env e;
259+
verify_statement current_env envs s1;
260+
verify_statement current_env envs s2;
261+
match e.etype with
262+
| None -> raise(UnknowActualType("unknow type in if else condition"))
263+
| Some actual_t -> if actual_t <> Primitive(Boolean)
264+
then raise(IncompatibleTypes((stringOf actual_t)^" cannot be converted to boolean")))
167265
| For(fil,eo,el,s) -> () (*TODO*)
168266
| Try(body,catch,finally) -> () (*TODO*)
169267

@@ -173,20 +271,32 @@ let verify_constructors envs current_class consts =
173271
(* print_endline ("=====verify_constructors======");
174272
print_class_env(Hashtbl.find envs current_class);
175273
print_endline ("=====verify_constructors======"); *)
176-
let current_env = {returntype = Type.Ref({ tpath = []; tid = consts.cname }); variables = Hashtbl.create 17; this_class = current_class} in
177-
List.iter (verify_argument current_env) consts.cargstype;
178-
List.iter (verify_statement current_env envs) consts.cbody
274+
let current_env = {
275+
returntype = Type.Ref({ tpath = []; tid = consts.cname });
276+
variables = Hashtbl.create 17;
277+
this_class = current_class;
278+
env_type = "constructor"} in
279+
List.iter (verify_declared_args current_env) consts.cargstype;
280+
List.iter (verify_statement current_env envs) consts.cbody (*TODO: I am constructor*)
179281

180282
let verify_methods envs current_class meths =
181-
let current_env = {returntype = meths.mreturntype; variables = Hashtbl.create 17; this_class = current_class} in
182-
List.iter (verify_argument current_env) meths.margstype;
283+
let current_env = {
284+
returntype = meths.mreturntype;
285+
variables = Hashtbl.create 17;
286+
this_class = current_class;
287+
env_type = "methode"} in
288+
List.iter (verify_declared_args current_env) meths.margstype;
183289
List.iter (verify_statement current_env envs) meths.mbody
184290

185291
(* check the type of the attibutes *)
186292
let verify_attributes envs current_class attrs =
187293
match attrs.adefault with
188294
| Some e ->
189-
let current_env = {returntype = Type.Void; variables = Hashtbl.create 17; this_class = current_class} in
295+
let current_env = {
296+
returntype = Type.Void;
297+
variables = Hashtbl.create 17;
298+
this_class = current_class;
299+
env_type = "attribute"} in
190300
verify_expression envs current_env e;
191301
(* Verify the assignment operation's type is coherent *)
192302
let mytype = Some(attrs.atype) in
Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
1+
class I {
2+
boolean a = (56 == 5);
3+
float b = 8.5f;
4+
boolean a2 = false;
5+
String c = "yes";
6+
int i = 5;
7+
int j = i;
8+
// Return None for constructor -> ok
9+
public I(boolean a, float b) {
10+
this.a = a;
11+
this.b = b;
12+
return;
13+
}
14+
// Return something for constructor -> not ok
15+
// public I(boolean a, float b) {
16+
// this.a = a;
17+
// this.b = b;
18+
// return i;
19+
// }
20+
// Return ref_type for methode -> ok
21+
private I func1 (int a, int b) {
22+
// int b = 1; // test Duplicate Local Variable -> not ok
23+
// { // Test Block in verify_statement
24+
// int n = 5;
25+
// String m = b;
26+
// }
27+
I ret = new I(false, 5.5f);
28+
i++; // test Expr in in verify_statement
29+
return ret;
30+
}
31+
// Return None for methode -> not ok
32+
// private I func2 (int a, int b) {
33+
// return;
34+
// }
35+
private void testIf(int i){
36+
int j = 0;
37+
// test if
38+
if (i == 1) {
39+
int x =0;
40+
j = 5;
41+
}
42+
// test if else
43+
if (i == 1) {
44+
int x = 0;
45+
j = 4;
46+
} else {
47+
int x = 1;
48+
j = 5;
49+
}
50+
// if conditon must be boolean
51+
// if (i) {
52+
// j = 4;
53+
// }
54+
}
55+
}

0 commit comments

Comments
 (0)
0