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