-
Notifications
You must be signed in to change notification settings - Fork 0
/
TypeTransformer.java
119 lines (110 loc) · 4.41 KB
/
TypeTransformer.java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
import java.util.*;
public class TypeTransformer {
public static Program T (Program p, TypeMap tm) {
Block body = (Block)T(p.body, tm);
return new Program(p.decpart, body);
}
public static Expression T (Expression e, TypeMap tm) {
if (e instanceof Value)
return e;
if (e instanceof Variable)
return e;
if (e instanceof Binary) {
Binary b = (Binary)e;
Type typ1 = StaticTypeCheck.typeOf(b.term1, tm);
Type typ2 = StaticTypeCheck.typeOf(b.term2, tm);
Expression t1 = T (b.term1, tm);
Expression t2 = T (b.term2, tm);
if (typ1 == Type.INT)
return new Binary(b.op.intMap(b.op.val), t1,t2);
else if (typ1 == Type.FLOAT)
return new Binary(b.op.floatMap(b.op.val), t1,t2);
else if (typ1 == Type.CHAR)
return new Binary(b.op.charMap(b.op.val), t1,t2);
else if (typ1 == Type.BOOL)
return new Binary(b.op.boolMap(b.op.val), t1,t2);
throw new IllegalArgumentException("should never reach here");
}
if (e instanceof Unary) {
Unary u = (Unary)e;
Type termType = StaticTypeCheck.typeOf(u.term, tm);
Expression t = T(u.term, tm);
if(termType == Type.INT && u.op.NegateOp()) {
Operator o = new Operator("INTU-");
return new Unary(o, t);
} else if(termType == Type.INT) {
return new Unary(u.op.intMap(u.op.val), t);
} else if(termType == Type.FLOAT && u.op.NegateOp()) {
Operator o = new Operator("FLOATU-");
return new Unary(o, t);
} else if(termType == Type.CHAR) {
return new Unary(u.op.charMap(u.op.val), t);
} else if(termType == Type.FLOAT) {
return new Unary(u.op.floatMap(u.op.val), t);
} else if(termType == Type.BOOL) {
return new Unary(u.op.boolMap(u.op.val), t);
}
throw new IllegalArgumentException("should never reach here");
}
throw new IllegalArgumentException("should never reach here");
}
public static Statement T (Statement s, TypeMap tm) {
if (s instanceof Skip) return s;
if (s instanceof Assignment) {
Assignment a = (Assignment)s;
Variable target = a.target;
Expression src = T (a.source, tm);
Type ttype = (Type)tm.members.get(a.target);
Type srctype = StaticTypeCheck.typeOf(a.source, tm);
if (ttype == Type.FLOAT) {
if (srctype == Type.INT) {
src = new Unary(new Operator(Operator.I2F), src);
srctype = Type.FLOAT;
}
}
else if (ttype == Type.INT) {
if (srctype == Type.CHAR) {
src = new Unary(new Operator(Operator.C2I), src);
srctype = Type.INT;
}
}
StaticTypeCheck.check( ttype == srctype,
"bug in assignment to " + target);
return new Assignment(target, src);
}
if (s instanceof Conditional) {
Conditional c = (Conditional)s;
Expression test = T (c.test, tm);
Statement tbr = T (c.thenbranch, tm);
Statement ebr = T (c.elsebranch, tm);
return new Conditional(test, tbr, ebr);
}
if (s instanceof Loop) {
Loop l = (Loop)s;
Expression test = T (l.test, tm);
Statement body = T (l.body, tm);
return new Loop(test, body);
}
if (s instanceof Block) {
Block b = (Block)s;
Block out = new Block();
for (Statement stmt : b.members)
out.members.add(T(stmt, tm));
return out;
}
throw new IllegalArgumentException("should never reach here");
}
public static void main(String args[]) {
Parser parser = new Parser(new Lexer(args[0]));
Program prog = parser.program();
prog.display();
System.out.println("\nBegin type checking...");
System.out.println("Type map:");
TypeMap map = StaticTypeCheck.typing(prog.decpart);
map.display();
StaticTypeCheck.V(prog);
Program out = T(prog, map);
System.out.println("Output AST");
out.display();
} //main
} // class TypeTransformer