6 public class BuildFlat {
10 public BuildFlat(State st) {
12 temptovar=new Hashtable();
15 public void buildFlat() {
16 Iterator it=state.getClassSymbolTable().getDescriptorsIterator();
18 ClassDescriptor cn=(ClassDescriptor)it.next();
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);
35 private NodePair flattenBlockNode(BlockNode bn) {
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();
48 end.addNext(np_begin);
53 end=begin=new FlatNop();
55 return new NodePair(begin,end);
58 private NodePair flattenBlockExpressionNode(BlockExpressionNode en) {
59 TempDescriptor tmp=TempDescriptor.tempFactory("neverused");
60 return flattenExpressionNode(en.getExpression(),tmp);
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);
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);
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()];
82 for(int i=0;i<con.numArgs();i++) {
83 ExpressionNode en=con.getArg(i);
84 TempDescriptor tmp=TempDescriptor.tempFactory("arg");
86 NodePair np=flattenExpressionNode(en, tmp);
87 last.addNext(np.getBegin());
90 MethodDescriptor md=con.getConstructor();
92 FlatCall fc=new FlatCall(md, null, out_temp, temps);
94 return new NodePair(fn,fc);
97 private NodePair flattenMethodInvokeNode(MethodInvokeNode min,TempDescriptor out_temp) {
98 TempDescriptor[] temps=new TempDescriptor[min.numArgs()];
101 TempDescriptor thisarg=null;
103 if (min.getExpression()!=null) {
104 thisarg=TempDescriptor.tempFactory("thisarg");
105 NodePair np=flattenExpressionNode(min.getExpression(),thisarg);
111 for(int i=0;i<min.numArgs();i++) {
112 ExpressionNode en=min.getArg(i);
113 TempDescriptor td=TempDescriptor.tempFactory("arg");
115 NodePair np=flattenExpressionNode(en, td);
119 last.addNext(np.getBegin());
123 MethodDescriptor md=min.getMethod();
125 //Call to constructor
126 FlatCall fc=new FlatCall(md, out_temp, thisarg, temps);
131 return new NodePair(first,fc);
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);
142 private NodePair flattenAssignmentNode(AssignmentNode an,TempDescriptor out_temp) {
144 // left side is variable
145 // left side is field
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();
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);
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 NameNode nn=(NameNode)an.getDest();
173 if (nn.getExpression()!=null) {
174 FieldAccessNode fan=(FieldAccessNode)nn.getExpression();
175 ExpressionNode en=fan.getExpression();
176 TempDescriptor dst_tmp=TempDescriptor.tempFactory("dst");
177 NodePair np_baseexp=flattenExpressionNode(en, dst_tmp);
178 last.addNext(np_baseexp.getBegin());
179 FlatSetFieldNode fsfn=new FlatSetFieldNode(dst_tmp, fan.getField(), src_tmp);
180 np_baseexp.getEnd().addNext(fsfn);
181 return new NodePair(np_src.getBegin(), fsfn);
183 if (nn.getField()!=null) {
184 FlatSetFieldNode fsfn=new FlatSetFieldNode(getTempforVar(nn.getVar()), nn.getField(), src_tmp);
186 return new NodePair(np_src.getBegin(), fsfn);
188 FlatOpNode fon=new FlatOpNode(getTempforVar(nn.getVar()), src_tmp, null, new Operation(Operation.ASSIGN));
190 return new NodePair(np_src.getBegin(),fon);
197 private NodePair flattenNameNode(NameNode nn,TempDescriptor out_temp) {
198 if (nn.getExpression()!=null) {
199 /* Hack - use subtree instead */
200 return flattenExpressionNode(nn.getExpression(),out_temp);
201 } else if (nn.getField()!=null) {
202 TempDescriptor tmp=getTempforVar(nn.getVar());
203 FlatFieldNode ffn=new FlatFieldNode(nn.getField(), tmp, out_temp);
204 return new NodePair(ffn,ffn);
206 TempDescriptor tmp=getTempforVar(nn.getVar());
207 FlatOpNode fon=new FlatOpNode(out_temp, tmp, null, new Operation(Operation.ASSIGN));
208 return new NodePair(fon,fon);
212 private NodePair flattenOpNode(OpNode on,TempDescriptor out_temp) {
213 TempDescriptor temp_left=TempDescriptor.tempFactory("leftop");
214 TempDescriptor temp_right=TempDescriptor.tempFactory("rightop");
215 NodePair left=flattenExpressionNode(on.getLeft(),temp_left);
217 if (on.getRight()!=null)
218 right=flattenExpressionNode(on.getRight(),temp_right);
220 FlatNop nop=new FlatNop();
221 right=new NodePair(nop,nop);
223 Operation op=on.getOp();
224 FlatOpNode fon=new FlatOpNode(out_temp,temp_left,temp_right,op);
225 left.getEnd().addNext(right.getBegin());
226 right.getEnd().addNext(fon);
227 return new NodePair(left.getBegin(),fon);
230 private NodePair flattenExpressionNode(ExpressionNode en, TempDescriptor out_temp) {
232 case Kind.AssignmentNode:
233 return flattenAssignmentNode((AssignmentNode)en,out_temp);
235 return flattenCastNode((CastNode)en,out_temp);
236 case Kind.CreateObjectNode:
237 return flattenCreateObjectNode((CreateObjectNode)en,out_temp);
238 case Kind.FieldAccessNode:
239 return flattenFieldAccessNode((FieldAccessNode)en,out_temp);
240 case Kind.LiteralNode:
241 return flattenLiteralNode((LiteralNode)en,out_temp);
242 case Kind.MethodInvokeNode:
243 return flattenMethodInvokeNode((MethodInvokeNode)en,out_temp);
245 return flattenNameNode((NameNode)en,out_temp);
247 return flattenOpNode((OpNode)en,out_temp);
252 private NodePair flattenDeclarationNode(DeclarationNode dn) {
253 VarDescriptor vd=dn.getVarDescriptor();
254 TempDescriptor td=getTempforVar(vd);
255 if (dn.getExpression()!=null)
256 return flattenExpressionNode(dn.getExpression(),td);
258 FlatNop fn=new FlatNop();
259 return new NodePair(fn,fn);
263 private TempDescriptor getTempforVar(VarDescriptor vd) {
264 if (temptovar.containsKey(vd))
265 return (TempDescriptor)temptovar.get(vd);
267 TempDescriptor td=TempDescriptor.tempFactory(vd.getName());
268 temptovar.put(vd,td);
273 private NodePair flattenIfStatementNode(IfStatementNode isn) {
274 TempDescriptor cond_temp=TempDescriptor.tempFactory("condition");
275 NodePair cond=flattenExpressionNode(isn.getCondition(),cond_temp);
276 FlatCondBranch fcb=new FlatCondBranch(cond_temp);
277 NodePair true_np=flattenBlockNode(isn.getTrueBlock());
279 FlatNop nopend=new FlatNop();
281 if (isn.getFalseBlock()!=null)
282 false_np=flattenBlockNode(isn.getFalseBlock());
284 FlatNop nop=new FlatNop();
285 false_np=new NodePair(nop,nop);
288 cond.getEnd().addNext(fcb);
289 fcb.addTrueNext(true_np.getBegin());
290 fcb.addFalseNext(false_np.getBegin());
291 true_np.getEnd().addNext(nopend);
292 false_np.getEnd().addNext(nopend);
293 return new NodePair(cond.getBegin(), nopend);
296 private NodePair flattenLoopNode(LoopNode ln) {
297 if (ln.getType()==LoopNode.FORLOOP) {
298 NodePair initializer=flattenBlockNode(ln.getInitializer());
299 TempDescriptor cond_temp=TempDescriptor.tempFactory("condition");
300 NodePair condition=flattenExpressionNode(ln.getCondition(),cond_temp);
301 NodePair update=flattenBlockNode(ln.getUpdate());
302 NodePair body=flattenBlockNode(ln.getBody());
303 FlatNode begin=initializer.getBegin();
304 FlatCondBranch fcb=new FlatCondBranch(cond_temp);
305 FlatNop nopend=new FlatNop();
307 initializer.getEnd().addNext(condition.getBegin());
308 body.getEnd().addNext(update.getBegin());
309 update.getEnd().addNext(condition.getBegin());
310 condition.getEnd().addNext(fcb);
311 fcb.addFalseNext(nopend);
312 fcb.addTrueNext(body.getBegin());
313 return new NodePair(begin,nopend);
314 } else if (ln.getType()==LoopNode.WHILELOOP) {
315 TempDescriptor cond_temp=TempDescriptor.tempFactory("condition");
316 NodePair condition=flattenExpressionNode(ln.getCondition(),cond_temp);
317 NodePair body=flattenBlockNode(ln.getBody());
318 FlatNode begin=condition.getBegin();
319 FlatCondBranch fcb=new FlatCondBranch(cond_temp);
320 FlatNop nopend=new FlatNop();
322 body.getEnd().addNext(condition.getBegin());
323 condition.getEnd().addNext(fcb);
324 fcb.addFalseNext(nopend);
325 fcb.addTrueNext(body.getBegin());
326 return new NodePair(begin,nopend);
327 } else if (ln.getType()==LoopNode.DOWHILELOOP) {
328 TempDescriptor cond_temp=TempDescriptor.tempFactory("condition");
329 NodePair condition=flattenExpressionNode(ln.getCondition(),cond_temp);
330 NodePair body=flattenBlockNode(ln.getBody());
331 FlatNode begin=body.getBegin();
332 FlatCondBranch fcb=new FlatCondBranch(cond_temp);
333 FlatNop nopend=new FlatNop();
335 body.getEnd().addNext(condition.getBegin());
336 condition.getEnd().addNext(fcb);
337 fcb.addFalseNext(nopend);
338 fcb.addTrueNext(body.getBegin());
339 return new NodePair(begin,nopend);
340 } else throw new Error();
343 private NodePair flattenReturnNode(ReturnNode rntree) {
344 TempDescriptor retval=TempDescriptor.tempFactory("ret_value");
345 NodePair cond=flattenExpressionNode(rntree.getReturnExpression(),retval);
346 FlatReturnNode rnflat=new FlatReturnNode(retval);
347 cond.getEnd().addNext(rnflat);
348 return new NodePair(cond.getBegin(),rnflat);
351 private NodePair flattenSubBlockNode(SubBlockNode sbn) {
352 return flattenBlockNode(sbn.getBlockNode());
355 private NodePair flattenBlockStatementNode(BlockStatementNode bsn) {
357 case Kind.BlockExpressionNode:
358 return flattenBlockExpressionNode((BlockExpressionNode)bsn);
360 case Kind.DeclarationNode:
361 return flattenDeclarationNode((DeclarationNode)bsn);
363 case Kind.IfStatementNode:
364 return flattenIfStatementNode((IfStatementNode)bsn);
367 return flattenLoopNode((LoopNode)bsn);
369 case Kind.ReturnNode:
370 return flattenReturnNode((IR.Tree.ReturnNode)bsn);
372 case Kind.SubBlockNode:
373 return flattenSubBlockNode((SubBlockNode)bsn);