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