be64f97a34e62fc28afb2e04a923950f0a0c7834
[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 Hashtable getMap() {
16         return temptovar;
17     }
18
19     public void buildFlat() {
20         Iterator it=state.getClassSymbolTable().getDescriptorsIterator();
21         while(it.hasNext()) {
22             ClassDescriptor cn=(ClassDescriptor)it.next();
23             flattenClass(cn);
24         }
25         
26         Iterator task_it=state.getTaskSymbolTable().getDescriptorsIterator();
27         while(task_it.hasNext()) {
28             TaskDescriptor td=(TaskDescriptor)task_it.next();
29             flattenTask(td);
30         }
31     }
32     
33     private void flattenTask(TaskDescriptor td) {
34         BlockNode bn=state.getMethodBody(td);
35         FlatNode fn=flattenBlockNode(bn).getBegin();
36         FlatFlagActionNode ffan=new FlatFlagActionNode(false);
37         ffan.addNext(fn);
38         FlatMethod fm=new FlatMethod(td, ffan);
39
40         for(int i=0;i<td.numParameters();i++) {
41             fm.addParameterTemp(getTempforVar(td.getParameter(i)));
42         }
43
44         /* Flatten Vector of Flag Effects */
45         Vector flags=td.getFlagEffects();
46         updateFlagActionNode(ffan,flags);
47
48         state.addFlatCode(td,fm);
49     }
50
51
52     /* This method transforms a vector of FlagEffects into the FlatFlagActionNode */
53     private void updateFlagActionNode(FlatFlagActionNode ffan, Vector flags) {
54         for(int i=0;i<flags.size();i++) {
55             FlagEffects fes=(FlagEffects)flags.get(i);
56             TempDescriptor flagtemp=getTempforVar(fes.getVar());
57             for(int j=0;j<fes.numEffects();j++) {
58                 FlagEffect fe=fes.getEffect(j);
59                 ffan.addFlagAction(flagtemp, fe.getFlag(), fe.getStatus());
60             }
61         }
62     }
63
64     private void flattenClass(ClassDescriptor cn) {
65         Iterator methodit=cn.getMethods();
66         while(methodit.hasNext()) {
67             MethodDescriptor md=(MethodDescriptor)methodit.next();
68             BlockNode bn=state.getMethodBody(md);
69             FlatNode fn=flattenBlockNode(bn).getBegin();
70             FlatMethod fm=new FlatMethod(md, fn);
71             if (!md.isStatic())
72                 fm.addParameterTemp(getTempforVar(md.getThis()));
73             for(int i=0;i<md.numParameters();i++) {
74                 fm.addParameterTemp(getTempforVar(md.getParameter(i)));
75             }
76             System.out.println(fm.printMethod());
77             state.addFlatCode(md,fm);
78         }
79     }
80
81     private NodePair flattenBlockNode(BlockNode bn) {
82         FlatNode begin=null;
83         FlatNode end=null;
84         for(int i=0;i<bn.size();i++) {
85             NodePair np=flattenBlockStatementNode(bn.get(i));
86             FlatNode np_begin=np.getBegin();
87             FlatNode np_end=np.getEnd();
88             if (begin==null) {
89                 begin=np_begin;
90             }
91             if (end==null) {
92                 end=np_end;
93             } else {
94                 end.addNext(np_begin);
95                 end=np_end;
96             }
97         }
98         if (begin==null) {
99             end=begin=new FlatNop();
100         }
101         return new NodePair(begin,end);
102     }
103
104     private NodePair flattenBlockExpressionNode(BlockExpressionNode en) {
105         TempDescriptor tmp=TempDescriptor.tempFactory("neverused",en.getExpression().getType());
106         return flattenExpressionNode(en.getExpression(),tmp);
107     }
108
109     private NodePair flattenCastNode(CastNode cn,TempDescriptor out_temp) {
110         TempDescriptor tmp=TempDescriptor.tempFactory("tocast",cn.getExpression().getType());
111         NodePair np=flattenExpressionNode(cn.getExpression(), tmp);
112         FlatCastNode fcn=new FlatCastNode(cn.getType(), tmp, out_temp);
113         np.getEnd().addNext(fcn);
114         return new NodePair(np.getBegin(),fcn);
115     }
116
117     private NodePair flattenLiteralNode(LiteralNode ln,TempDescriptor out_temp) {
118         FlatLiteralNode fln=new FlatLiteralNode(ln.getType(), ln.getValue(), out_temp);
119         return new NodePair(fln,fln);
120     }
121
122     private NodePair flattenCreateObjectNode(CreateObjectNode con,TempDescriptor out_temp) {
123         TypeDescriptor td=con.getType();
124         if (!td.isArray()) {
125             FlatNew fn=new FlatNew(td, out_temp);
126             TempDescriptor[] temps=new TempDescriptor[con.numArgs()];
127             FlatNode last=fn;
128
129             if (con.getFlagEffects()!=null) {
130                 FlatFlagActionNode ffan=new FlatFlagActionNode(false);
131                 FlagEffects fes=con.getFlagEffects();
132                 TempDescriptor flagtemp=out_temp;
133                 for(int j=0;j<fes.numEffects();j++) {
134                     FlagEffect fe=fes.getEffect(j);
135                     ffan.addFlagAction(flagtemp, fe.getFlag(), fe.getStatus());
136                 }
137                 last.addNext(ffan);
138                 last=ffan;
139             }
140             //Build arguments
141             for(int i=0;i<con.numArgs();i++) {
142                 ExpressionNode en=con.getArg(i);
143                 TempDescriptor tmp=TempDescriptor.tempFactory("arg",en.getType());
144                 temps[i]=tmp;
145                 NodePair np=flattenExpressionNode(en, tmp);
146                 last.addNext(np.getBegin());
147                 last=np.getEnd();
148             }
149             MethodDescriptor md=con.getConstructor();
150             //Call to constructor
151             FlatCall fc=new FlatCall(md, null, out_temp, temps);
152             last.addNext(fc);
153             last=fc;
154             return new NodePair(fn,last); 
155         } else {
156             FlatNode first=null;
157             FlatNode last=null;
158             TempDescriptor[] temps=new TempDescriptor[con.numArgs()];
159             for (int i=0;i<con.numArgs();i++) {
160                 ExpressionNode en=con.getArg(i);
161                 TempDescriptor tmp=TempDescriptor.tempFactory("arg",en.getType());
162                 temps[i]=tmp;           
163                 NodePair np=flattenExpressionNode(en, tmp);
164                 if (first==null)
165                     first=np.getBegin();
166                 else
167                     last.addNext(np.getBegin());
168                 last=np.getEnd();
169                 
170                 TempDescriptor tmp2=(i==0)?
171                     out_temp:
172                 TempDescriptor.tempFactory("arg",en.getType());
173             }
174             FlatNew fn=new FlatNew(td, out_temp, temps[0]);
175             last.addNext(fn);
176             if (temps.length>1) {
177                 NodePair np=generateNewArrayLoop(temps, td.dereference(), out_temp, 0);
178                 fn.addNext(np.getBegin());
179                 return new NodePair(first,np.getEnd()); 
180             } else
181                 return new NodePair(first, fn);
182         }
183     }
184
185     private NodePair generateNewArrayLoop(TempDescriptor[] temparray, TypeDescriptor td, TempDescriptor tmp, int i) {
186         TempDescriptor index=TempDescriptor.tempFactory("index",new TypeDescriptor(TypeDescriptor.INT));
187         TempDescriptor tmpone=TempDescriptor.tempFactory("index",new TypeDescriptor(TypeDescriptor.INT));
188         FlatNop fnop=new FlatNop();//last node
189
190         //index=0
191         FlatLiteralNode fln=new FlatLiteralNode(index.getType(),new Integer(0),index);
192         //tmpone=1
193         FlatLiteralNode fln2=new FlatLiteralNode(tmpone.getType(),new Integer(1),tmpone);
194
195         TempDescriptor tmpbool=TempDescriptor.tempFactory("comp",new TypeDescriptor(TypeDescriptor.BOOLEAN));
196
197         FlatOpNode fcomp=new FlatOpNode(tmpbool,index,temparray[i],new Operation(Operation.LT));
198         FlatCondBranch fcb=new FlatCondBranch(tmpbool);
199         //is index<temp[i]
200         TempDescriptor new_tmp=TempDescriptor.tempFactory("tmp",td);
201         FlatNew fn=new FlatNew(td, new_tmp, temparray[i+1]);
202         FlatSetElementNode fsen=new FlatSetElementNode(tmp,index,new_tmp);
203         // index=index+1
204         FlatOpNode fon=new FlatOpNode(index,index,tmpone,new Operation(Operation.ADD));
205         //jump out
206         fln.addNext(fln2);
207         fln2.addNext(fcomp);
208         fcomp.addNext(fcb);
209         fcb.addTrueNext(fn);
210         fcb.addFalseNext(fnop);
211         fn.addNext(fsen);
212         //Recursive call here
213         if ((i+2)<temparray.length) {
214             NodePair np2=generateNewArrayLoop(temparray, td.dereference(), new_tmp, i+1);
215             fsen.addNext(np2.getBegin());
216             np2.getEnd().addNext(fon);
217         } else {
218             fsen.addNext(fon);
219         }
220         fon.addNext(fcomp);
221         return new NodePair(fln, fnop);
222     }
223
224     private NodePair flattenMethodInvokeNode(MethodInvokeNode min,TempDescriptor out_temp) {
225         TempDescriptor[] temps=new TempDescriptor[min.numArgs()];
226         FlatNode first=null;
227         FlatNode last=null;
228         TempDescriptor thisarg=null;
229
230         if (min.getExpression()!=null) {
231             thisarg=TempDescriptor.tempFactory("thisarg",min.getExpression().getType());
232             NodePair np=flattenExpressionNode(min.getExpression(),thisarg);
233             first=np.getBegin();
234             last=np.getEnd();
235         }
236         
237         //Build arguments
238         for(int i=0;i<min.numArgs();i++) {
239             ExpressionNode en=min.getArg(i);
240             TempDescriptor td=TempDescriptor.tempFactory("arg",en.getType());
241             temps[i]=td;
242             NodePair np=flattenExpressionNode(en, td);
243             if (first==null)
244                 first=np.getBegin();
245             else 
246                 last.addNext(np.getBegin());
247             last=np.getEnd();
248         }
249
250         MethodDescriptor md=min.getMethod();
251         
252         //Call to constructor
253         
254         FlatCall fc;
255         if(md.getReturnType()==null||md.getReturnType().isVoid())
256             fc=new FlatCall(md, null, thisarg, temps);
257         else 
258             fc=new FlatCall(md, out_temp, thisarg, temps);
259         if (first==null) {
260             first=fc;
261         } else
262             last.addNext(fc);
263         return new NodePair(first,fc);
264     }
265
266     private NodePair flattenFieldAccessNode(FieldAccessNode fan,TempDescriptor out_temp) {
267         TempDescriptor tmp=TempDescriptor.tempFactory("temp",fan.getExpression().getType());
268         NodePair npe=flattenExpressionNode(fan.getExpression(),tmp);
269         FlatFieldNode fn=new FlatFieldNode(fan.getField(),tmp,out_temp);
270         npe.getEnd().addNext(fn);
271         return new NodePair(npe.getBegin(),fn);
272     }
273
274     private NodePair flattenArrayAccessNode(ArrayAccessNode aan,TempDescriptor out_temp) {
275         TempDescriptor tmp=TempDescriptor.tempFactory("temp",aan.getExpression().getType());
276         TempDescriptor tmpindex=TempDescriptor.tempFactory("temp",aan.getIndex().getType());
277         NodePair npe=flattenExpressionNode(aan.getExpression(),tmp);
278         NodePair npi=flattenExpressionNode(aan.getIndex(),tmpindex);
279         FlatElementNode fn=new FlatElementNode(tmp,tmpindex,out_temp);
280         npe.getEnd().addNext(npi.getBegin());
281         npi.getEnd().addNext(fn);
282         return new NodePair(npe.getBegin(),fn);
283     }
284
285     private NodePair flattenAssignmentNode(AssignmentNode an,TempDescriptor out_temp) {
286         // Two cases:
287         // left side is variable
288         // left side is field
289         
290         Operation base=an.getOperation().getBaseOp();
291         TempDescriptor src_tmp=TempDescriptor.tempFactory("src",an.getSrc().getType());
292         NodePair np_src=flattenExpressionNode(an.getSrc(),src_tmp);
293         FlatNode last=np_src.getEnd();
294         if (base!=null) {
295             TempDescriptor src_tmp2=TempDescriptor.tempFactory("tmp", an.getDest().getType());
296             NodePair np_dst_init=flattenExpressionNode(an.getDest(),src_tmp2);
297             last.addNext(np_dst_init.getBegin());
298             TempDescriptor dst_tmp=TempDescriptor.tempFactory("dst_tmp",an.getDest().getType());
299             FlatOpNode fon=new FlatOpNode(dst_tmp, src_tmp,src_tmp2, base);
300             np_dst_init.getEnd().addNext(fon);
301             last=fon;
302             src_tmp=dst_tmp;
303         }
304         
305         if (an.getDest().kind()==Kind.FieldAccessNode) {
306             FieldAccessNode fan=(FieldAccessNode)an.getDest();
307             ExpressionNode en=fan.getExpression();
308             TempDescriptor dst_tmp=TempDescriptor.tempFactory("dst",en.getType());
309             NodePair np_baseexp=flattenExpressionNode(en, dst_tmp);
310             last.addNext(np_baseexp.getBegin());
311             FlatSetFieldNode fsfn=new FlatSetFieldNode(dst_tmp, fan.getField(), src_tmp);
312             np_baseexp.getEnd().addNext(fsfn);
313             return new NodePair(np_src.getBegin(), fsfn);
314         } else if (an.getDest().kind()==Kind.ArrayAccessNode) {
315             ArrayAccessNode aan=(ArrayAccessNode)an.getDest();
316             ExpressionNode en=aan.getExpression();
317             ExpressionNode enindex=aan.getIndex();
318             TempDescriptor dst_tmp=TempDescriptor.tempFactory("dst",en.getType());
319             TempDescriptor index_tmp=TempDescriptor.tempFactory("index",enindex.getType());
320             NodePair np_baseexp=flattenExpressionNode(en, dst_tmp);
321             NodePair np_indexexp=flattenExpressionNode(enindex, index_tmp);
322             last.addNext(np_baseexp.getBegin());
323             np_baseexp.getEnd().addNext(np_indexexp.getBegin());
324             FlatSetElementNode fsen=new FlatSetElementNode(dst_tmp, index_tmp, src_tmp);
325             np_indexexp.getEnd().addNext(fsen);
326             return new NodePair(np_src.getBegin(), fsen);
327         } else if (an.getDest().kind()==Kind.NameNode) {
328             NameNode nn=(NameNode)an.getDest();
329             if (nn.getExpression()!=null) {
330                 FieldAccessNode fan=(FieldAccessNode)nn.getExpression();
331                 ExpressionNode en=fan.getExpression();
332                 TempDescriptor dst_tmp=TempDescriptor.tempFactory("dst",en.getType());
333                 NodePair np_baseexp=flattenExpressionNode(en, dst_tmp);
334                 last.addNext(np_baseexp.getBegin());
335                 FlatSetFieldNode fsfn=new FlatSetFieldNode(dst_tmp, fan.getField(), src_tmp);
336                 np_baseexp.getEnd().addNext(fsfn);
337                 return new NodePair(np_src.getBegin(), fsfn);
338             } else {
339                 if (nn.getField()!=null) {
340                     FlatSetFieldNode fsfn=new FlatSetFieldNode(getTempforVar(nn.getVar()), nn.getField(), src_tmp);
341                     last.addNext(fsfn);
342                     return new NodePair(np_src.getBegin(), fsfn);
343                 } else {
344                     FlatOpNode fon=new FlatOpNode(getTempforVar(nn.getVar()), src_tmp, null, new Operation(Operation.ASSIGN));
345                     last.addNext(fon);
346                     return new NodePair(np_src.getBegin(),fon);
347                 }
348             }
349         } 
350         throw new Error();
351     }
352
353     private NodePair flattenNameNode(NameNode nn,TempDescriptor out_temp) {
354         if (nn.getExpression()!=null) {
355             /* Hack - use subtree instead */
356             return flattenExpressionNode(nn.getExpression(),out_temp);
357         } else if (nn.getField()!=null) {
358             TempDescriptor tmp=getTempforVar(nn.getVar());
359             FlatFieldNode ffn=new FlatFieldNode(nn.getField(), tmp, out_temp); 
360             return new NodePair(ffn,ffn);
361         } else {
362             TempDescriptor tmp=getTempforVar(nn.getVar());
363             FlatOpNode fon=new FlatOpNode(out_temp, tmp, null, new Operation(Operation.ASSIGN));
364             return new NodePair(fon,fon);
365         }
366     }
367
368     private NodePair flattenOpNode(OpNode on,TempDescriptor out_temp) {
369         TempDescriptor temp_left=TempDescriptor.tempFactory("leftop",on.getLeft().getType());
370         TempDescriptor temp_right=null;
371
372         Operation op=on.getOp();
373         if (op.getOp()==Operation.POSTINC||
374             op.getOp()==Operation.POSTDEC||
375             op.getOp()==Operation.PREINC||
376             op.getOp()==Operation.PREDEC) {
377             LiteralNode ln=new LiteralNode("int",new Integer(1));
378             ln.setType(new TypeDescriptor(TypeDescriptor.INT));
379             AssignmentNode an=new AssignmentNode(on.getLeft(),ln,
380                                new AssignOperation((op.getOp()==Operation.POSTINC||op.getOp()==Operation.PREINC)?AssignOperation.PLUSEQ:AssignOperation.MINUSEQ));
381             if (op.getOp()==Operation.POSTINC||
382                 op.getOp()==Operation.POSTDEC) {
383                 NodePair left=flattenExpressionNode(on.getLeft(),out_temp);
384                 NodePair assign=flattenAssignmentNode(an,temp_left);
385                 left.getEnd().addNext(assign.getBegin());
386                 return new NodePair(left.getBegin(),assign.getEnd());
387             } else {
388                 NodePair assign=flattenAssignmentNode(an,out_temp);
389                 return assign;
390             }
391         } 
392         
393         NodePair left=flattenExpressionNode(on.getLeft(),temp_left);
394         NodePair right;
395         if (on.getRight()!=null) {
396             temp_right=TempDescriptor.tempFactory("rightop",on.getRight().getType());
397             right=flattenExpressionNode(on.getRight(),temp_right);
398         } else {
399             FlatNop nop=new FlatNop();
400             right=new NodePair(nop,nop);
401         }
402
403         if (op.getOp()==Operation.LOGIC_OR) {
404             /* Need to do shortcircuiting */
405             FlatCondBranch fcb=new FlatCondBranch(temp_left);
406             FlatOpNode fon1=new FlatOpNode(out_temp,temp_left,null,new Operation(Operation.ASSIGN));
407             FlatOpNode fon2=new FlatOpNode(out_temp,temp_right,null,new Operation(Operation.ASSIGN));
408             FlatNop fnop=new FlatNop();
409             left.getEnd().addNext(fcb);
410             fcb.addFalseNext(right.getBegin());
411             right.getEnd().addNext(fon2);
412             fon2.addNext(fnop);
413             fcb.addTrueNext(fon1);
414             fon1.addNext(fnop);
415             return new NodePair(left.getBegin(), fnop);
416         } else if (op.getOp()==Operation.LOGIC_AND) {
417             /* Need to do shortcircuiting */
418             FlatCondBranch fcb=new FlatCondBranch(temp_left);
419             FlatOpNode fon1=new FlatOpNode(out_temp,temp_left,null,new Operation(Operation.ASSIGN));
420             FlatOpNode fon2=new FlatOpNode(out_temp,temp_right,null,new Operation(Operation.ASSIGN));
421             FlatNop fnop=new FlatNop();
422             left.getEnd().addNext(fcb);
423             fcb.addTrueNext(right.getBegin());
424             right.getEnd().addNext(fon2);
425             fon2.addNext(fnop);
426             fcb.addFalseNext(fon1);
427             fon1.addNext(fnop);
428             return new NodePair(left.getBegin(), fnop);
429         }
430
431         FlatOpNode fon=new FlatOpNode(out_temp,temp_left,temp_right,op);
432         left.getEnd().addNext(right.getBegin());
433         right.getEnd().addNext(fon);
434         return new NodePair(left.getBegin(),fon);
435     }
436
437     private NodePair flattenExpressionNode(ExpressionNode en, TempDescriptor out_temp) {
438         switch(en.kind()) {
439         case Kind.AssignmentNode:
440             return flattenAssignmentNode((AssignmentNode)en,out_temp);
441         case Kind.CastNode:
442             return flattenCastNode((CastNode)en,out_temp);
443         case Kind.CreateObjectNode:
444             return flattenCreateObjectNode((CreateObjectNode)en,out_temp);
445         case Kind.FieldAccessNode:
446             return flattenFieldAccessNode((FieldAccessNode)en,out_temp);
447         case Kind.ArrayAccessNode:
448             return flattenArrayAccessNode((ArrayAccessNode)en,out_temp);
449         case Kind.LiteralNode:
450             return flattenLiteralNode((LiteralNode)en,out_temp);
451         case Kind.MethodInvokeNode:
452             return flattenMethodInvokeNode((MethodInvokeNode)en,out_temp);
453         case Kind.NameNode:
454             return flattenNameNode((NameNode)en,out_temp);
455         case Kind.OpNode:
456             return flattenOpNode((OpNode)en,out_temp);
457         }
458         throw new Error();
459     }
460
461     private NodePair flattenDeclarationNode(DeclarationNode dn) {
462         VarDescriptor vd=dn.getVarDescriptor();
463         TempDescriptor td=getTempforVar(vd);
464         if (dn.getExpression()!=null)
465             return flattenExpressionNode(dn.getExpression(),td);
466         else {
467             FlatNop fn=new FlatNop();
468             return new NodePair(fn,fn);
469         }
470     }
471         
472     private TempDescriptor getTempforVar(VarDescriptor vd) {
473         if (temptovar.containsKey(vd))
474             return (TempDescriptor)temptovar.get(vd);
475         else {
476             TempDescriptor td=TempDescriptor.tempFactory(vd.getName(),vd.getType());
477             temptovar.put(vd,td);
478             return td;
479         }
480     }
481
482     private NodePair flattenIfStatementNode(IfStatementNode isn) {
483         TempDescriptor cond_temp=TempDescriptor.tempFactory("condition",new TypeDescriptor(TypeDescriptor.BOOLEAN));
484         NodePair cond=flattenExpressionNode(isn.getCondition(),cond_temp);
485         FlatCondBranch fcb=new FlatCondBranch(cond_temp);
486         NodePair true_np=flattenBlockNode(isn.getTrueBlock());
487         NodePair false_np;
488         FlatNop nopend=new FlatNop();
489
490         if (isn.getFalseBlock()!=null)
491             false_np=flattenBlockNode(isn.getFalseBlock());
492         else {
493             FlatNop nop=new FlatNop();
494             false_np=new NodePair(nop,nop);
495         }
496
497         cond.getEnd().addNext(fcb);
498         fcb.addTrueNext(true_np.getBegin());
499         fcb.addFalseNext(false_np.getBegin());
500         true_np.getEnd().addNext(nopend);
501         false_np.getEnd().addNext(nopend);
502         return new NodePair(cond.getBegin(), nopend);
503     }
504             
505     private NodePair flattenLoopNode(LoopNode ln) {
506         if (ln.getType()==LoopNode.FORLOOP) {
507             NodePair initializer=flattenBlockNode(ln.getInitializer());
508             TempDescriptor cond_temp=TempDescriptor.tempFactory("condition", new TypeDescriptor(TypeDescriptor.BOOLEAN));
509             NodePair condition=flattenExpressionNode(ln.getCondition(),cond_temp);
510             NodePair update=flattenBlockNode(ln.getUpdate());
511             NodePair body=flattenBlockNode(ln.getBody());
512             FlatNode begin=initializer.getBegin();
513             FlatCondBranch fcb=new FlatCondBranch(cond_temp);
514             FlatNop nopend=new FlatNop();
515
516             initializer.getEnd().addNext(condition.getBegin());
517             body.getEnd().addNext(update.getBegin());
518             update.getEnd().addNext(condition.getBegin());
519             condition.getEnd().addNext(fcb);
520             fcb.addFalseNext(nopend);
521             fcb.addTrueNext(body.getBegin());
522             return new NodePair(begin,nopend);
523         } else if (ln.getType()==LoopNode.WHILELOOP) {
524             TempDescriptor cond_temp=TempDescriptor.tempFactory("condition", new TypeDescriptor(TypeDescriptor.BOOLEAN));
525             NodePair condition=flattenExpressionNode(ln.getCondition(),cond_temp);
526             NodePair body=flattenBlockNode(ln.getBody());
527             FlatNode begin=condition.getBegin();
528             FlatCondBranch fcb=new FlatCondBranch(cond_temp);
529             FlatNop nopend=new FlatNop();
530
531             body.getEnd().addNext(condition.getBegin());
532             condition.getEnd().addNext(fcb);
533             fcb.addFalseNext(nopend);
534             fcb.addTrueNext(body.getBegin());
535             return new NodePair(begin,nopend);
536         } else if (ln.getType()==LoopNode.DOWHILELOOP) {
537             TempDescriptor cond_temp=TempDescriptor.tempFactory("condition", new TypeDescriptor(TypeDescriptor.BOOLEAN));
538             NodePair condition=flattenExpressionNode(ln.getCondition(),cond_temp);
539             NodePair body=flattenBlockNode(ln.getBody());
540             FlatNode begin=body.getBegin();
541             FlatCondBranch fcb=new FlatCondBranch(cond_temp);
542             FlatNop nopend=new FlatNop();
543
544             body.getEnd().addNext(condition.getBegin());
545             condition.getEnd().addNext(fcb);
546             fcb.addFalseNext(nopend);
547             fcb.addTrueNext(body.getBegin());
548             return new NodePair(begin,nopend);
549         } else throw new Error();
550     }
551             
552     private NodePair flattenReturnNode(ReturnNode rntree) {
553         TempDescriptor retval=null;
554         NodePair cond=null;
555         if (rntree.getReturnExpression()!=null) {
556             retval=TempDescriptor.tempFactory("ret_value", rntree.getReturnExpression().getType());
557             cond=flattenExpressionNode(rntree.getReturnExpression(),retval);
558         }
559
560         FlatReturnNode rnflat=new FlatReturnNode(retval);
561
562         if (cond!=null) {
563             cond.getEnd().addNext(rnflat);
564             return new NodePair(cond.getBegin(),rnflat);
565         } else
566             return new NodePair(rnflat,rnflat);
567     }
568
569     private NodePair flattenTaskExitNode(TaskExitNode ten) {
570         FlatFlagActionNode ffan=new FlatFlagActionNode(true);
571         updateFlagActionNode(ffan, ten.getFlagEffects());
572         return new NodePair(ffan, ffan);
573     }
574
575     private NodePair flattenSubBlockNode(SubBlockNode sbn) {
576         return flattenBlockNode(sbn.getBlockNode());
577     }
578
579     private NodePair flattenBlockStatementNode(BlockStatementNode bsn) {
580         switch(bsn.kind()) {
581         case Kind.BlockExpressionNode:
582             return flattenBlockExpressionNode((BlockExpressionNode)bsn);
583             
584         case Kind.DeclarationNode:
585             return flattenDeclarationNode((DeclarationNode)bsn);
586             
587         case Kind.IfStatementNode:
588             return flattenIfStatementNode((IfStatementNode)bsn);
589             
590         case Kind.LoopNode:
591             return flattenLoopNode((LoopNode)bsn);
592             
593         case Kind.ReturnNode:
594             return flattenReturnNode((IR.Tree.ReturnNode)bsn);
595
596         case Kind.TaskExitNode:
597             return flattenTaskExitNode((IR.Tree.TaskExitNode)bsn);
598             
599         case Kind.SubBlockNode:
600             return flattenSubBlockNode((SubBlockNode)bsn);
601             
602         }
603         throw new Error();
604     }
605 }