package EDU.gac.max.MC97.S97.c3; import java.util.Hashtable; import java.util.Enumeration; import EDU.gac.max.MC97.S97.compiler_support.Register; abstract class Proc{ public abstract String gen(); } class MainProc extends Proc{ Stmt body; MainProc(Stmt theBody){ body = theBody; } public String gen(){ Hashtable regsToSave = new Hashtable(); String bodyCode = body.gen(regsToSave); return prolog(regsToSave) + bodyCode + epilog(regsToSave); } // The two calls below to the Hashtable's keys method need to return // enumerations that follow the same order, or registers will get restored // into one another. This seems like a reasonable property to assume, but // the official 1.0.2 API documentation for Hashtable doesn't say anything // about it, so I'm on thin ice -- cross your fingers. private String prolog(Hashtable regsToSave){ StringBuffer theProlog = new StringBuffer("main:\n"); if(regsToSave.size() > 0) theProlog.append("\tsubu $sp, $sp, " + (4 * regsToSave.size()) + "\n"); Enumeration e = regsToSave.keys(); for(int offset = 0; e.hasMoreElements(); offset += 4){ theProlog.append("\tsw " + (Register) (e.nextElement()) + ", " + offset + "($sp)\n"); } return theProlog.toString(); } private String epilog(Hashtable regsToSave){ StringBuffer theEpilog = new StringBuffer("\tli $v0, 0\n"); Enumeration e = regsToSave.keys(); int offset; for(offset = 0; e.hasMoreElements(); offset += 4){ theEpilog.append("\tlw " + (Register) (e.nextElement()) + ", " + offset + "($sp)\n"); } if(offset > 0) theEpilog.append("\taddu $sp, $sp, " + offset + "\n"); theEpilog.append("\tj $ra\n"); return theEpilog.toString(); } }