signature FRAME = sig type access type frame datatype frag = PROC of {body: Tree.stm, frame: frame} | STRING of Temp.label * string val FP: Temp.temp val RV: Temp.temp val newFrame: {name: Temp.label, formals: bool list} -> frame val name: frame -> Temp.label val formals: frame -> access Array.array val allocLocal: frame -> bool -> access val frameOffset: access -> int val accessToExp: access -> Tree.exp -> Tree.exp val initFragList: unit -> unit val addFrag: frag -> unit val getFragList: unit -> frag list end structure Frame :> FRAME = struct structure A = Array structure T = Tree structure TE = Temp datatype access = InFrame of int | InReg of TE.temp datatype frame = FRAME of {(* frame name *) name: TE.label, (* args: from arguments to accesses *) args: access A.array, (* argsTotal: total number of arguments *) argsTotal: int, (* argsInFrame: number of arguments allocated in frame *) argsInFrame: int, (* localCount: number of local variables *) localCount: int ref} val FP = TE.newTemp () val RV = TE.newTemp () fun newFrame {name= lab, formals= bs}: frame = let val n = List.length bs val args = A.array (n, InFrame 0) fun aux ([], i, j) = j | aux (b :: bs, i, j) = case b of true => (* escapes *) (A.update (args, i, InFrame j); aux (bs, i+1, j+1)) | false => (* does not escape *) (A.update (args, i, InReg (TE.newTemp ())); aux (bs, i+1, j)) val argsInFrame = aux (bs, 0, 0) in FRAME {name= lab, args= args, argsTotal= n, argsInFrame= argsInFrame, localCount = ref (argsInFrame + 1)} end fun name (FRAME f: frame): TE.label = #name (f) fun formals (FRAME f: frame): access A.array = #args (f) fun allocLocal (F: frame) (escape: bool): access = let val FRAME f = F in if escape then let val r = #localCount (f) val i = !r val _ = (r := i + 1) in InFrame i end else InReg (TE.newTemp ()) end fun frameOffset (InFrame i) = i | frameOffset (InReg _) = Error.err "offset: a register" fun accessToExp (InFrame i) = (fn fp => T.MEM (T.BINOP (T.PLUS, fp, T.CONST (~(i+1))))) | accessToExp (InReg r) = (fn fp => T.TEMP r) datatype frag = PROC of {body: Tree.stm, frame: frame} | STRING of Temp.label * string val fragList: (frag list) ref = ref [] fun addFrag (frag: frag) = (fragList := frag :: !fragList) fun initFragList () = (fragList := []) fun getFragList (): frag list = !fragList end