updates
[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.getClassSymbolTable().getDescriptorsIterator();
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 flattenCastNode(CastNode cn,TempDescriptor out_temp) {
60         TempDescriptor tmp=TempDescriptor.tempFactory("tocast");
61         NodePair np=flattenExpressionNode(cn.getExpression(), tmp);
62         FlatCastNode fcn=new FlatCastNode(cn.getType(), tmp, out_temp);
63         np.getEnd().addNext(fcn);
64         return new NodePair(np.getBegin(),fcn);
65     }
66
67     private NodePair flattenLiteralNode(LiteralNode ln,TempDescriptor out_temp) {
68         FlatLiteralNode fln=new FlatLiteralNode(ln.getType(), ln.getValue(), out_temp);
69         return new NodePair(fln,fln);
70     }
71
72     private NodePair flattenCreateObjectNode(CreateObjectNode con,TempDescriptor out_temp) {
73         TypeDescriptor td=con.getType();
74         FlatNew fn=new FlatNew(td, out_temp);
75         TempDescriptor[] temps=new TempDescriptor[con.numArgs()];
76         FlatNode last=fn;
77         //Build arguments
78         for(int i=0;i<con.numArgs();i++) {
79             ExpressionNode en=con.getArg(i);
80             TempDescriptor tmp=TempDescriptor.tempFactory("arg");
81             temps[i]=tmp;
82             NodePair np=flattenExpressionNode(en, tmp);
83             last.addNext(np.getBegin());
84             last=np.getEnd();
85         }
86         MethodDescriptor md=con.getConstructor();
87         //Call to constructor
88         FlatCall fc=new FlatCall(md, null, out_temp, temps);
89         last.addNext(fc);
90         return new NodePair(fn,fc);
91     }
92
93     private NodePair flattenMethodInvokeNode(MethodInvokeNode min,TempDescriptor out_temp) {
94         TempDescriptor[] temps=new TempDescriptor[min.numArgs()];
95         FlatNode first=null;
96         FlatNode last=null;
97         TempDescriptor thisarg=null;
98
99         if (min.getExpression()!=null) {
100             thisarg=TempDescriptor.tempFactory("thisarg");
101             NodePair np=flattenExpressionNode(min.getExpression(),thisarg);
102             first=np.getBegin();
103             last=np.getEnd();
104         }
105         
106         //Build arguments
107         for(int i=0;i<min.numArgs();i++) {
108             ExpressionNode en=min.getArg(i);
109             TempDescriptor td=TempDescriptor.tempFactory("arg");
110             temps[i]=td;
111             NodePair np=flattenExpressionNode(en, td);
112             if (first==null)
113                 first=np.getBegin();
114             else 
115                 last.addNext(np.getBegin());
116             last=np.getEnd();
117         }
118
119         MethodDescriptor md=min.getMethod();
120         
121         //Call to constructor
122         FlatCall fc=new FlatCall(md, out_temp, thisarg, temps);
123         if (first==null) {
124             first=fc;
125         } else
126             last.addNext(fc);
127         return new NodePair(first,fc);
128     }
129
130     private NodePair flattenFieldAccessNode(FieldAccessNode fan,TempDescriptor out_temp) {
131         TempDescriptor tmp=TempDescriptor.tempFactory("temp");
132         NodePair npe=flattenExpressionNode(fan.getExpression(),tmp);
133         FlatFieldNode fn=new FlatFieldNode(fan.getField(),tmp,out_temp);
134         npe.getEnd().addNext(fn);
135         return new NodePair(npe.getBegin(),fn);
136     }
137
138     private NodePair flattenAssignmentNode(AssignmentNode an,TempDescriptor out_temp) {
139         // Two cases:
140         // left side is variable
141         // left side is field
142         
143         Operation base=an.getOperation().getBaseOp();
144         TempDescriptor src_tmp=TempDescriptor.tempFactory("src");
145         NodePair np_src=flattenExpressionNode(an.getSrc(),src_tmp);
146         FlatNode last=np_src.getEnd();
147         if (base!=null) {
148             TempDescriptor src_tmp2=TempDescriptor.tempFactory("tmp");
149             NodePair np_dst_init=flattenExpressionNode(an.getDest(),src_tmp2);
150             last.addNext(np_dst_init.getBegin());
151             TempDescriptor dst_tmp=TempDescriptor.tempFactory("dst_tmp");
152             FlatOpNode fon=new FlatOpNode(dst_tmp, src_tmp,src_tmp2, base);
153             np_dst_init.getEnd().addNext(fon);
154             last=fon;
155             src_tmp=dst_tmp;
156         }
157         
158         if (an.getDest().kind()==Kind.FieldAccessNode) {
159             FieldAccessNode fan=(FieldAccessNode)an.getDest();
160
161
162             // Need to assign field
163         } else if (an.getDest().kind()==Kind.NameNode) {
164             
165         } 
166         throw new Error();
167     }
168
169     private NodePair flattenNameNode(NameNode nn,TempDescriptor out_temp) {
170         throw new Error();
171     }
172
173     private NodePair flattenOpNode(OpNode on,TempDescriptor out_temp) {
174         TempDescriptor temp_left=TempDescriptor.tempFactory("leftop");
175         TempDescriptor temp_right=TempDescriptor.tempFactory("rightop");
176         NodePair left=flattenExpressionNode(on.getLeft(),temp_left);
177         NodePair right;
178         if (on.getRight()!=null)
179             right=flattenExpressionNode(on.getRight(),temp_right);
180         else {
181             FlatNop nop=new FlatNop();
182             right=new NodePair(nop,nop);
183         }
184         Operation op=on.getOp();
185         FlatOpNode fon=new FlatOpNode(out_temp,temp_left,temp_right,op);
186         left.getEnd().addNext(right.getBegin());
187         right.getEnd().addNext(fon);
188         return new NodePair(left.getBegin(),fon);
189     }
190
191     private NodePair flattenExpressionNode(ExpressionNode en, TempDescriptor out_temp) {
192         switch(en.kind()) {
193         case Kind.AssignmentNode:
194             return flattenAssignmentNode((AssignmentNode)en,out_temp);
195         case Kind.CastNode:
196             return flattenCastNode((CastNode)en,out_temp);
197         case Kind.CreateObjectNode:
198             return flattenCreateObjectNode((CreateObjectNode)en,out_temp);
199         case Kind.FieldAccessNode:
200             return flattenFieldAccessNode((FieldAccessNode)en,out_temp);
201         case Kind.LiteralNode:
202             return flattenLiteralNode((LiteralNode)en,out_temp);
203         case Kind.MethodInvokeNode:
204             return flattenMethodInvokeNode((MethodInvokeNode)en,out_temp);
205         case Kind.NameNode:
206             return flattenNameNode((NameNode)en,out_temp);
207         case Kind.OpNode:
208             return flattenOpNode((OpNode)en,out_temp);
209         }
210         throw new Error();
211     }
212
213     private NodePair flattenDeclarationNode(DeclarationNode dn) {
214         VarDescriptor vd=dn.getVarDescriptor();
215         TempDescriptor td=getTempforVar(vd);
216         return flattenExpressionNode(dn.getExpression(),td);
217     }
218         
219     private TempDescriptor getTempforVar(VarDescriptor vd) {
220         if (temptovar.containsKey(vd))
221             return (TempDescriptor)temptovar.get(vd);
222         else {
223             TempDescriptor td=TempDescriptor.tempFactory(vd.getName());
224             temptovar.put(vd,td);
225             return td;
226         }
227     }
228
229     private NodePair flattenIfStatementNode(IfStatementNode isn) {
230         TempDescriptor cond_temp=TempDescriptor.tempFactory("condition");
231         NodePair cond=flattenExpressionNode(isn.getCondition(),cond_temp);
232         FlatCondBranch fcb=new FlatCondBranch(cond_temp);
233         NodePair true_np=flattenBlockNode(isn.getTrueBlock());
234         NodePair false_np;
235         FlatNop nopend=new FlatNop();
236
237         if (isn.getFalseBlock()!=null)
238             false_np=flattenBlockNode(isn.getFalseBlock());
239         else {
240             FlatNop nop=new FlatNop();
241             false_np=new NodePair(nop,nop);
242         }
243
244         cond.getEnd().addNext(fcb);
245         fcb.addTrueNext(true_np.getBegin());
246         fcb.addFalseNext(false_np.getBegin());
247         true_np.getEnd().addNext(nopend);
248         false_np.getEnd().addNext(nopend);
249         return new NodePair(cond.getBegin(), nopend);
250     }
251             
252     private NodePair flattenLoopNode(LoopNode ln) {
253         if (ln.getType()==LoopNode.FORLOOP) {
254             NodePair initializer=flattenBlockNode(ln.getInitializer());
255             TempDescriptor cond_temp=TempDescriptor.tempFactory("condition");
256             NodePair condition=flattenExpressionNode(ln.getCondition(),cond_temp);
257             NodePair update=flattenBlockNode(ln.getUpdate());
258             NodePair body=flattenBlockNode(ln.getBody());
259             FlatNode begin=initializer.getBegin();
260             FlatCondBranch fcb=new FlatCondBranch(cond_temp);
261             FlatNop nopend=new FlatNop();
262
263             initializer.getEnd().addNext(condition.getBegin());
264             body.getEnd().addNext(update.getBegin());
265             update.getEnd().addNext(condition.getBegin());
266             condition.getEnd().addNext(fcb);
267             fcb.addFalseNext(nopend);
268             fcb.addTrueNext(body.getBegin());
269             return new NodePair(begin,nopend);
270         } else if (ln.getType()==LoopNode.WHILELOOP) {
271             TempDescriptor cond_temp=TempDescriptor.tempFactory("condition");
272             NodePair condition=flattenExpressionNode(ln.getCondition(),cond_temp);
273             NodePair body=flattenBlockNode(ln.getBody());
274             FlatNode begin=condition.getBegin();
275             FlatCondBranch fcb=new FlatCondBranch(cond_temp);
276             FlatNop nopend=new FlatNop();
277
278             body.getEnd().addNext(condition.getBegin());
279             condition.getEnd().addNext(fcb);
280             fcb.addFalseNext(nopend);
281             fcb.addTrueNext(body.getBegin());
282             return new NodePair(begin,nopend);
283         } else if (ln.getType()==LoopNode.DOWHILELOOP) {
284             TempDescriptor cond_temp=TempDescriptor.tempFactory("condition");
285             NodePair condition=flattenExpressionNode(ln.getCondition(),cond_temp);
286             NodePair body=flattenBlockNode(ln.getBody());
287             FlatNode begin=body.getBegin();
288             FlatCondBranch fcb=new FlatCondBranch(cond_temp);
289             FlatNop nopend=new FlatNop();
290
291             body.getEnd().addNext(condition.getBegin());
292             condition.getEnd().addNext(fcb);
293             fcb.addFalseNext(nopend);
294             fcb.addTrueNext(body.getBegin());
295             return new NodePair(begin,nopend);
296         } else throw new Error();
297     }
298             
299     private NodePair flattenReturnNode(ReturnNode rntree) {
300         TempDescriptor retval=TempDescriptor.tempFactory("ret_value");
301         NodePair cond=flattenExpressionNode(rntree.getReturnExpression(),retval);
302         FlatReturnNode rnflat=new FlatReturnNode(retval);
303         cond.getEnd().addNext(rnflat);
304         return new NodePair(cond.getBegin(),rnflat);
305     }
306             
307     private NodePair flattenSubBlockNode(SubBlockNode sbn) {
308         return flattenBlockNode(sbn.getBlockNode());
309     }
310
311     private NodePair flattenBlockStatementNode(BlockStatementNode bsn) {
312         switch(bsn.kind()) {
313         case Kind.BlockExpressionNode:
314             return flattenBlockExpressionNode((BlockExpressionNode)bsn);
315             
316         case Kind.DeclarationNode:
317             return flattenDeclarationNode((DeclarationNode)bsn);
318             
319         case Kind.IfStatementNode:
320             return flattenIfStatementNode((IfStatementNode)bsn);
321             
322         case Kind.LoopNode:
323             return flattenLoopNode((LoopNode)bsn);
324             
325         case Kind.ReturnNode:
326             return flattenReturnNode((IR.Tree.ReturnNode)bsn);
327             
328         case Kind.SubBlockNode:
329             return flattenSubBlockNode((SubBlockNode)bsn);
330             
331         }
332         throw new Error();
333     }
334 }