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 state.addFlatCode(md,fm);
34 private NodePair flattenBlockNode(BlockNode bn) {
37 for(int i=0;i<bn.size();i++) {
38 NodePair np=flattenBlockStatementNode(bn.get(i));
39 FlatNode np_begin=np.getBegin();
40 FlatNode np_end=np.getEnd();
47 end.addNext(np_begin);
51 return new NodePair(begin,end);
54 private NodePair flattenBlockExpressionNode(BlockExpressionNode en) {
55 TempDescriptor tmp=TempDescriptor.tempFactory("neverused");
56 return flattenExpressionNode(en.getExpression(),tmp);
59 private NodePair flattenCastNode(CastNode cn,TempDescriptor out_temp) {
60 TempDescriptor tmp=TempDescriptor.tempFactory("tocast");
61 NodePair np=flattenExpressionNode(cn.getExpression(), tmp);
62 FlatCastNode fcn=new FlatCastNode(cn.getType(), tmp, out_temp);
63 np.getEnd().addNext(fcn);
64 return new NodePair(np.getBegin(),fcn);
67 private NodePair flattenLiteralNode(LiteralNode ln,TempDescriptor out_temp) {
68 FlatLiteralNode fln=new FlatLiteralNode(ln.getType(), ln.getValue(), out_temp);
69 return new NodePair(fln,fln);
72 private NodePair flattenCreateObjectNode(CreateObjectNode con,TempDescriptor out_temp) {
73 TypeDescriptor td=con.getType();
74 FlatNew fn=new FlatNew(td, out_temp);
75 TempDescriptor[] temps=new TempDescriptor[con.numArgs()];
78 for(int i=0;i<con.numArgs();i++) {
79 ExpressionNode en=con.getArg(i);
80 TempDescriptor tmp=TempDescriptor.tempFactory("arg");
82 NodePair np=flattenExpressionNode(en, tmp);
83 last.addNext(np.getBegin());
86 MethodDescriptor md=con.getConstructor();
88 FlatCall fc=new FlatCall(md, null, out_temp, temps);
90 return new NodePair(fn,fc);
93 private NodePair flattenMethodInvokeNode(MethodInvokeNode min,TempDescriptor out_temp) {
94 TempDescriptor[] temps=new TempDescriptor[min.numArgs()];
97 TempDescriptor thisarg=null;
99 if (min.getExpression()!=null) {
100 thisarg=TempDescriptor.tempFactory("thisarg");
101 NodePair np=flattenExpressionNode(min.getExpression(),thisarg);
107 for(int i=0;i<min.numArgs();i++) {
108 ExpressionNode en=min.getArg(i);
109 TempDescriptor td=TempDescriptor.tempFactory("arg");
111 NodePair np=flattenExpressionNode(en, td);
115 last.addNext(np.getBegin());
119 MethodDescriptor md=min.getMethod();
121 //Call to constructor
122 FlatCall fc=new FlatCall(md, out_temp, thisarg, temps);
127 return new NodePair(first,fc);
130 private NodePair flattenFieldAccessNode(FieldAccessNode fan,TempDescriptor out_temp) {
131 TempDescriptor tmp=TempDescriptor.tempFactory("temp");
132 NodePair npe=flattenExpressionNode(fan.getExpression(),tmp);
133 FlatFieldNode fn=new FlatFieldNode(fan.getField(),tmp,out_temp);
134 npe.getEnd().addNext(fn);
135 return new NodePair(npe.getBegin(),fn);
138 private NodePair flattenAssignmentNode(AssignmentNode an,TempDescriptor out_temp) {
140 // left side is variable
141 // left side is field
143 Operation base=an.getOperation().getBaseOp();
144 TempDescriptor src_tmp=TempDescriptor.tempFactory("src");
145 NodePair np_src=flattenExpressionNode(an.getSrc(),src_tmp);
146 FlatNode last=np_src.getEnd();
148 TempDescriptor src_tmp2=TempDescriptor.tempFactory("tmp");
149 NodePair np_dst_init=flattenExpressionNode(an.getDest(),src_tmp2);
150 last.addNext(np_dst_init.getBegin());
151 TempDescriptor dst_tmp=TempDescriptor.tempFactory("dst_tmp");
152 FlatOpNode fon=new FlatOpNode(dst_tmp, src_tmp,src_tmp2, base);
153 np_dst_init.getEnd().addNext(fon);
158 if (an.getDest().kind()==Kind.FieldAccessNode) {
159 FieldAccessNode fan=(FieldAccessNode)an.getDest();
162 // Need to assign field
163 } else if (an.getDest().kind()==Kind.NameNode) {
169 private NodePair flattenNameNode(NameNode nn,TempDescriptor out_temp) {
173 private NodePair flattenOpNode(OpNode on,TempDescriptor out_temp) {
174 TempDescriptor temp_left=TempDescriptor.tempFactory("leftop");
175 TempDescriptor temp_right=TempDescriptor.tempFactory("rightop");
176 NodePair left=flattenExpressionNode(on.getLeft(),temp_left);
178 if (on.getRight()!=null)
179 right=flattenExpressionNode(on.getRight(),temp_right);
181 FlatNop nop=new FlatNop();
182 right=new NodePair(nop,nop);
184 Operation op=on.getOp();
185 FlatOpNode fon=new FlatOpNode(out_temp,temp_left,temp_right,op);
186 left.getEnd().addNext(right.getBegin());
187 right.getEnd().addNext(fon);
188 return new NodePair(left.getBegin(),fon);
191 private NodePair flattenExpressionNode(ExpressionNode en, TempDescriptor out_temp) {
193 case Kind.AssignmentNode:
194 return flattenAssignmentNode((AssignmentNode)en,out_temp);
196 return flattenCastNode((CastNode)en,out_temp);
197 case Kind.CreateObjectNode:
198 return flattenCreateObjectNode((CreateObjectNode)en,out_temp);
199 case Kind.FieldAccessNode:
200 return flattenFieldAccessNode((FieldAccessNode)en,out_temp);
201 case Kind.LiteralNode:
202 return flattenLiteralNode((LiteralNode)en,out_temp);
203 case Kind.MethodInvokeNode:
204 return flattenMethodInvokeNode((MethodInvokeNode)en,out_temp);
206 return flattenNameNode((NameNode)en,out_temp);
208 return flattenOpNode((OpNode)en,out_temp);
213 private NodePair flattenDeclarationNode(DeclarationNode dn) {
214 VarDescriptor vd=dn.getVarDescriptor();
215 TempDescriptor td=getTempforVar(vd);
216 return flattenExpressionNode(dn.getExpression(),td);
219 private TempDescriptor getTempforVar(VarDescriptor vd) {
220 if (temptovar.containsKey(vd))
221 return (TempDescriptor)temptovar.get(vd);
223 TempDescriptor td=TempDescriptor.tempFactory(vd.getName());
224 temptovar.put(vd,td);
229 private NodePair flattenIfStatementNode(IfStatementNode isn) {
230 TempDescriptor cond_temp=TempDescriptor.tempFactory("condition");
231 NodePair cond=flattenExpressionNode(isn.getCondition(),cond_temp);
232 FlatCondBranch fcb=new FlatCondBranch(cond_temp);
233 NodePair true_np=flattenBlockNode(isn.getTrueBlock());
235 FlatNop nopend=new FlatNop();
237 if (isn.getFalseBlock()!=null)
238 false_np=flattenBlockNode(isn.getFalseBlock());
240 FlatNop nop=new FlatNop();
241 false_np=new NodePair(nop,nop);
244 cond.getEnd().addNext(fcb);
245 fcb.addTrueNext(true_np.getBegin());
246 fcb.addFalseNext(false_np.getBegin());
247 true_np.getEnd().addNext(nopend);
248 false_np.getEnd().addNext(nopend);
249 return new NodePair(cond.getBegin(), nopend);
252 private NodePair flattenLoopNode(LoopNode ln) {
253 if (ln.getType()==LoopNode.FORLOOP) {
254 NodePair initializer=flattenBlockNode(ln.getInitializer());
255 TempDescriptor cond_temp=TempDescriptor.tempFactory("condition");
256 NodePair condition=flattenExpressionNode(ln.getCondition(),cond_temp);
257 NodePair update=flattenBlockNode(ln.getUpdate());
258 NodePair body=flattenBlockNode(ln.getBody());
259 FlatNode begin=initializer.getBegin();
260 FlatCondBranch fcb=new FlatCondBranch(cond_temp);
261 FlatNop nopend=new FlatNop();
263 initializer.getEnd().addNext(condition.getBegin());
264 body.getEnd().addNext(update.getBegin());
265 update.getEnd().addNext(condition.getBegin());
266 condition.getEnd().addNext(fcb);
267 fcb.addFalseNext(nopend);
268 fcb.addTrueNext(body.getBegin());
269 return new NodePair(begin,nopend);
270 } else if (ln.getType()==LoopNode.WHILELOOP) {
271 TempDescriptor cond_temp=TempDescriptor.tempFactory("condition");
272 NodePair condition=flattenExpressionNode(ln.getCondition(),cond_temp);
273 NodePair body=flattenBlockNode(ln.getBody());
274 FlatNode begin=condition.getBegin();
275 FlatCondBranch fcb=new FlatCondBranch(cond_temp);
276 FlatNop nopend=new FlatNop();
278 body.getEnd().addNext(condition.getBegin());
279 condition.getEnd().addNext(fcb);
280 fcb.addFalseNext(nopend);
281 fcb.addTrueNext(body.getBegin());
282 return new NodePair(begin,nopend);
283 } else if (ln.getType()==LoopNode.DOWHILELOOP) {
284 TempDescriptor cond_temp=TempDescriptor.tempFactory("condition");
285 NodePair condition=flattenExpressionNode(ln.getCondition(),cond_temp);
286 NodePair body=flattenBlockNode(ln.getBody());
287 FlatNode begin=body.getBegin();
288 FlatCondBranch fcb=new FlatCondBranch(cond_temp);
289 FlatNop nopend=new FlatNop();
291 body.getEnd().addNext(condition.getBegin());
292 condition.getEnd().addNext(fcb);
293 fcb.addFalseNext(nopend);
294 fcb.addTrueNext(body.getBegin());
295 return new NodePair(begin,nopend);
296 } else throw new Error();
299 private NodePair flattenReturnNode(ReturnNode rntree) {
300 TempDescriptor retval=TempDescriptor.tempFactory("ret_value");
301 NodePair cond=flattenExpressionNode(rntree.getReturnExpression(),retval);
302 FlatReturnNode rnflat=new FlatReturnNode(retval);
303 cond.getEnd().addNext(rnflat);
304 return new NodePair(cond.getBegin(),rnflat);
307 private NodePair flattenSubBlockNode(SubBlockNode sbn) {
308 return flattenBlockNode(sbn.getBlockNode());
311 private NodePair flattenBlockStatementNode(BlockStatementNode bsn) {
313 case Kind.BlockExpressionNode:
314 return flattenBlockExpressionNode((BlockExpressionNode)bsn);
316 case Kind.DeclarationNode:
317 return flattenDeclarationNode((DeclarationNode)bsn);
319 case Kind.IfStatementNode:
320 return flattenIfStatementNode((IfStatementNode)bsn);
323 return flattenLoopNode((LoopNode)bsn);
325 case Kind.ReturnNode:
326 return flattenReturnNode((IR.Tree.ReturnNode)bsn);
328 case Kind.SubBlockNode:
329 return flattenSubBlockNode((SubBlockNode)bsn);