rendered paste body> module Ex3FunctionsCodeGenerator where
> import Ex3FunctionsTypes
> import List
-----------------------------------------------------------
Solution for Compilers exercise 3
Paul Kelly Imperial College London 2006
-----------------------------------------------------------
Fill in the gaps...
Part (1): translate function declaration
ls
> transFunction :: Function -> [Instr]
> transFunction (Defun fname paramname body)
> = [Define fname] ++ transExp body allRegs ++ restoreRegs everyReg ++ [Ret]
> everyReg = [D0,D1, D2, D3, D4, D5, D6, D7]
> allRegs = [D1, D2, D3, D4, D5, D6, D7]
Part (2): saving registers
> saveRegs :: [Register] -> [Instr]
> saveRegs regs = map pusher (everyReg \\ regs)
Part (3): translate expression (ie function body, perhaps including
function calls)
> transExp :: Exp -> [Register] -> [Instr]
> transExp (Const x) (dst:rest) = [Mov (ImmNum x)(Reg (dst))]
> transExp (Var varNam) (dst:rest) = [Mov (Reg D0) (Reg (dst))]
> transExp (Minus (exp) (exp1)) (src:rest) | (weight (exp1) > weight (exp)) = transExp(exp1) (src:rest) ++ transExp(exp) (rest) ++ [Sub (Reg (head rest)) (Reg (src))]
> | otherwise = transExp(exp) (src:rest) ++ transExp(exp1) (rest) ++ [Sub (Reg (src)) (Reg (head rest))]
> transExp (Apply (fname) (exp)) (reg:regs) = saveRegs (reg:regs) ++ transExp exp (reg:regs) ++ [Jsr fname] ++ [Mov (Reg D1) (Reg (head regs))] ++ restoreRegs (reg:regs)
> weight :: Exp -> Int
> weight (Const x) = 1
> weight (Var varName) = 1
> weight (Minus exp exp1) |(weight(exp1)< weight(exp)) = 1 + weight (exp1)
> | otherwise = 1 + weight (exp)
> weight (Apply fname exp) = 1 + weight(exp)
> restoreRegs :: [Register] -> [Instr]
> restoreRegs regs = map popper (everyReg \\ regs)
> pusher reg = Mov (Reg reg) Push
> popper reg = Mov Pop (Reg reg)