0c44e8337a6eb73a2147cdf81ea62612f4044378
[IRC.git] / Robust / src / IR / Flat / BuildFlat.java
1 package IR.Flat;
2 import IR.*;
3 import IR.Tree.*;
4 import java.util.*;
5
6 public class BuildFlat {
7     State state;
8     Hashtable temptovar;
9
10     public BuildFlat(State st) {
11         state=st;
12         temptovar=new Hashtable();
13     }
14
15     public void buildFlat() {
16         Iterator it=state.classset.iterator();
17         while(it.hasNext()) {
18             ClassDescriptor cn=(ClassDescriptor)it.next();
19             flattenClass(cn);
20         }
21     }
22     
23     private void flattenClass(ClassDescriptor cn) {
24         Iterator methodit=cn.getMethods();
25         while(methodit.hasNext()) {
26             MethodDescriptor md=(MethodDescriptor)methodit.next();
27             BlockNode bn=state.getMethodBody(md);
28             FlatNode fn=flattenBlockNode(bn).getBegin();
29             FlatMethod fm=new FlatMethod(md, fn);
30             state.addFlatCode(md,fm);
31         }
32     }
33
34     private NodePair flattenBlockNode(BlockNode bn) {
35         FlatNode begin=null;
36         FlatNode end=null;
37         for(int i=0;i<bn.size();i++) {
38             NodePair np=flattenBlockStatementNode(bn.get(i));
39             FlatNode np_begin=np.getBegin();
40             FlatNode np_end=np.getEnd();
41             if (begin==null) {
42                 begin=np_begin;
43             }
44             if (end==null) {
45                 end=np_end;
46             } else {
47                 end.addNext(np_begin);
48                 end=np_end;
49             }
50         }
51         return new NodePair(begin,end);
52     }
53
54     private NodePair flattenBlockExpressionNode(BlockExpressionNode en) {
55         TempDescriptor tmp=TempDescriptor.tempFactory("neverused");
56         return flattenExpressionNode(en.getExpression(),tmp);
57     }
58
59     private NodePair flattenAssignmentNode(AssignmentNode an,TempDescriptor out_temp) {
60         throw new Error();
61     }
62
63     private NodePair flattenCastNode(CastNode cn,TempDescriptor out_temp) {
64         throw new Error();
65     }
66
67     private NodePair flattenCreateObjectNode(CreateObjectNode con,TempDescriptor out_temp) {
68         throw new Error();
69     }
70
71     private NodePair flattenFieldAccessNode(FieldAccessNode fan,TempDescriptor out_temp) {
72         throw new Error();
73     }
74
75     private NodePair flattenLiteralNode(LiteralNode ln,TempDescriptor out_temp) {
76         throw new Error();
77     }
78
79     private NodePair flattenMethodInvokeNode(MethodInvokeNode min,TempDescriptor out_temp) {
80         throw new Error();
81     }
82
83     private NodePair flattenNameNode(NameNode nn,TempDescriptor out_temp) {
84         throw new Error();
85     }
86
87     private NodePair flattenOpNode(OpNode on,TempDescriptor out_temp) {
88         throw new Error();
89     }
90
91     private NodePair flattenExpressionNode(ExpressionNode en, TempDescriptor out_temp) {
92         switch(en.kind()) {
93         case Kind.AssignmentNode:
94             return flattenAssignmentNode((AssignmentNode)en,out_temp);
95         case Kind.CastNode:
96             return flattenCastNode((CastNode)en,out_temp);
97         case Kind.CreateObjectNode:
98             return flattenCreateObjectNode((CreateObjectNode)en,out_temp);
99         case Kind.FieldAccessNode:
100             return flattenFieldAccessNode((FieldAccessNode)en,out_temp);
101         case Kind.LiteralNode:
102             return flattenLiteralNode((LiteralNode)en,out_temp);
103         case Kind.MethodInvokeNode:
104             return flattenMethodInvokeNode((MethodInvokeNode)en,out_temp);
105         case Kind.NameNode:
106             return flattenNameNode((NameNode)en,out_temp);
107         case Kind.OpNode:
108             return flattenOpNode((OpNode)en,out_temp);
109         }
110         throw new Error();
111     }
112
113     private NodePair flattenDeclarationNode(DeclarationNode dn) {
114         VarDescriptor vd=dn.getVarDescriptor();
115         TempDescriptor td=getTempforVar(vd);
116         return flattenExpressionNode(dn.getExpression(),td);
117     }
118         
119     private TempDescriptor getTempforVar(VarDescriptor vd) {
120         if (temptovar.containsKey(vd))
121             return (TempDescriptor)temptovar.get(vd);
122         else {
123             TempDescriptor td=TempDescriptor.tempFactory(vd.getName());
124             temptovar.put(vd,td);
125             return td;
126         }
127     }
128
129     private NodePair flattenIfStatementNode(IfStatementNode isn) {
130         TempDescriptor cond_temp=TempDescriptor.tempFactory("condition");
131         NodePair cond=flattenExpressionNode(isn.getCondition(),cond_temp);
132         FlatCondBranch fcb=new FlatCondBranch(cond_temp);
133         NodePair true_np=flattenBlockNode(isn.getTrueBlock());
134         NodePair false_np;
135         FlatNop nopend=new FlatNop();
136
137         if (isn.getFalseBlock()!=null)
138             false_np=flattenBlockNode(isn.getFalseBlock());
139         else {
140             FlatNop nop=new FlatNop();
141             false_np=new NodePair(nop,nop);
142         }
143
144         cond.getEnd().addNext(fcb);
145         fcb.addTrueNext(true_np.getBegin());
146         fcb.addFalseNext(false_np.getBegin());
147         true_np.getEnd().addNext(nopend);
148         false_np.getEnd().addNext(nopend);
149         return new NodePair(cond.getBegin(), nopend);
150     }
151             
152     private NodePair flattenLoopNode(LoopNode ln) {
153         if (ln.getType()==LoopNode.FORLOOP) {
154             NodePair initializer=flattenBlockNode(ln.getInitializer());
155             TempDescriptor cond_temp=TempDescriptor.tempFactory("condition");
156             NodePair condition=flattenExpressionNode(ln.getCondition(),cond_temp);
157             NodePair update=flattenBlockNode(ln.getUpdate());
158             NodePair body=flattenBlockNode(ln.getBody());
159             FlatNode begin=initializer.getBegin();
160             FlatCondBranch fcb=new FlatCondBranch(cond_temp);
161             FlatNop nopend=new FlatNop();
162
163             initializer.getEnd().addNext(condition.getBegin());
164             body.getEnd().addNext(update.getBegin());
165             update.getEnd().addNext(condition.getBegin());
166             condition.getEnd().addNext(fcb);
167             fcb.addFalseNext(nopend);
168             fcb.addTrueNext(body.getBegin());
169             return new NodePair(begin,nopend);
170         } else if (ln.getType()==LoopNode.WHILELOOP) {
171             TempDescriptor cond_temp=TempDescriptor.tempFactory("condition");
172             NodePair condition=flattenExpressionNode(ln.getCondition(),cond_temp);
173             NodePair body=flattenBlockNode(ln.getBody());
174             FlatNode begin=condition.getBegin();
175             FlatCondBranch fcb=new FlatCondBranch(cond_temp);
176             FlatNop nopend=new FlatNop();
177
178             body.getEnd().addNext(condition.getBegin());
179             condition.getEnd().addNext(fcb);
180             fcb.addFalseNext(nopend);
181             fcb.addTrueNext(body.getBegin());
182             return new NodePair(begin,nopend);
183         } else if (ln.getType()==LoopNode.DOWHILELOOP) {
184             TempDescriptor cond_temp=TempDescriptor.tempFactory("condition");
185             NodePair condition=flattenExpressionNode(ln.getCondition(),cond_temp);
186             NodePair body=flattenBlockNode(ln.getBody());
187             FlatNode begin=body.getBegin();
188             FlatCondBranch fcb=new FlatCondBranch(cond_temp);
189             FlatNop nopend=new FlatNop();
190
191             body.getEnd().addNext(condition.getBegin());
192             condition.getEnd().addNext(fcb);
193             fcb.addFalseNext(nopend);
194             fcb.addTrueNext(body.getBegin());
195             return new NodePair(begin,nopend);
196         } else throw new Error();
197     }
198             
199     private NodePair flattenReturnNode(ReturnNode rntree) {
200         TempDescriptor retval=TempDescriptor.tempFactory("ret_value");
201         NodePair cond=flattenExpressionNode(rntree.getReturnExpression(),retval);
202         FlatReturnNode rnflat=new FlatReturnNode(retval);
203         cond.getEnd().addNext(rnflat);
204         return new NodePair(cond.getBegin(),rnflat);
205     }
206             
207     private NodePair flattenSubBlockNode(SubBlockNode sbn) {
208         return flattenBlockNode(sbn.getBlockNode());
209     }
210
211     private NodePair flattenBlockStatementNode(BlockStatementNode bsn) {
212         switch(bsn.kind()) {
213         case Kind.BlockExpressionNode:
214             return flattenBlockExpressionNode((BlockExpressionNode)bsn);
215             
216         case Kind.DeclarationNode:
217             return flattenDeclarationNode((DeclarationNode)bsn);
218             
219         case Kind.IfStatementNode:
220             return flattenIfStatementNode((IfStatementNode)bsn);
221             
222         case Kind.LoopNode:
223             return flattenLoopNode((LoopNode)bsn);
224             
225         case Kind.ReturnNode:
226             return flattenReturnNode((IR.Tree.ReturnNode)bsn);
227             
228         case Kind.SubBlockNode:
229             return flattenSubBlockNode((SubBlockNode)bsn);
230             
231         }
232         throw new Error();
233     }
234 }