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) {
174 FlatNop nop=new FlatNop();
175 return new NodePair(nop,nop);
176 } else throw new Error();
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);
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);
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);
196 if (on.getRight()!=null)
197 right=flattenExpressionNode(on.getRight(),temp_right);
199 FlatNop nop=new FlatNop();
200 right=new NodePair(nop,nop);
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);
209 private NodePair flattenExpressionNode(ExpressionNode en, TempDescriptor out_temp) {
211 case Kind.AssignmentNode:
212 return flattenAssignmentNode((AssignmentNode)en,out_temp);
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);
224 return flattenNameNode((NameNode)en,out_temp);
226 return flattenOpNode((OpNode)en,out_temp);
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);
237 FlatNop fn=new FlatNop();
238 return new NodePair(fn,fn);
242 private TempDescriptor getTempforVar(VarDescriptor vd) {
243 if (temptovar.containsKey(vd))
244 return (TempDescriptor)temptovar.get(vd);
246 TempDescriptor td=TempDescriptor.tempFactory(vd.getName());
247 temptovar.put(vd,td);
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());
258 FlatNop nopend=new FlatNop();
260 if (isn.getFalseBlock()!=null)
261 false_np=flattenBlockNode(isn.getFalseBlock());
263 FlatNop nop=new FlatNop();
264 false_np=new NodePair(nop,nop);
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);
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();
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();
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();
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();
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);
330 private NodePair flattenSubBlockNode(SubBlockNode sbn) {
331 return flattenBlockNode(sbn.getBlockNode());
334 private NodePair flattenBlockStatementNode(BlockStatementNode bsn) {
336 case Kind.BlockExpressionNode:
337 return flattenBlockExpressionNode((BlockExpressionNode)bsn);
339 case Kind.DeclarationNode:
340 return flattenDeclarationNode((DeclarationNode)bsn);
342 case Kind.IfStatementNode:
343 return flattenIfStatementNode((IfStatementNode)bsn);
346 return flattenLoopNode((LoopNode)bsn);
348 case Kind.ReturnNode:
349 return flattenReturnNode((IR.Tree.ReturnNode)bsn);
351 case Kind.SubBlockNode:
352 return flattenSubBlockNode((SubBlockNode)bsn);