/exercise3/CESMachine.lhs

http://sauce-code.googlecode.com/ · Haskell · 112 lines · 104 code · 8 blank · 0 comment · 22 complexity · efff94ec767675f62f8583d2717e6a7f MD5 · raw file

  1. \begin{code}
  2. module CESMachine where
  3. import Debug.Trace
  4. import qualified IntegerArithmetic as I
  5. import qualified DeBruijn as DB
  6. data Inst = Int Integer
  7. | Bool Bool
  8. | Bop BOP
  9. | Bpr BPR
  10. | Access Int
  11. | Close Code
  12. | Let
  13. | EndLet
  14. | Apply
  15. | Return
  16. | If
  17. | Fix
  18. deriving Show
  19. data BOP = Add | Sub | Mul | Div | Nand
  20. instance Show BOP where
  21. show Add = "+"
  22. show Sub = "-"
  23. show Mul = "*"
  24. show Div = "/"
  25. show Nand = "^"
  26. data BPR = Eq | Lt
  27. instance Show BPR where
  28. show Eq = "="
  29. show Lt = "<"
  30. type Code = [ Inst ]
  31. data Value = BoolVal Bool | IntVal Integer | Clo Code Env
  32. deriving Show
  33. type Env = [Value]
  34. data Slot = Value Value | Code Code | Env Env
  35. deriving Show
  36. type Stack = [Slot]
  37. type State = (Code, Env, Stack)
  38. compile :: DB.Term -> Code
  39. compile t = case t of
  40. DB.Var n -> [Access n]
  41. DB.IntConst n -> [Int n]
  42. DB.Abs tp t0 -> case compile t0 of t1 -> [Close (t1 ++ [Return])]
  43. DB.App t1 t2 -> case compile t1 of
  44. t1' -> case compile t2 of
  45. t2' -> t1' ++ t2' ++ [Apply]
  46. DB.If t0 t1 t2 -> case compile t0 of
  47. t0' -> case compile t1 of
  48. t1' -> case compile t2 of
  49. t2' -> t0' ++ t1' ++ t2' ++ [If]
  50. DB.Tru -> [Bool True]
  51. DB.Fls -> [Bool False]
  52. DB.Fix t0 -> case compile t0 of t0' -> t0' ++ [Fix]
  53. DB.Let t1 t2 -> case compile t1 of
  54. t1' -> case compile t2 of
  55. t2' -> t1' ++ [Let] ++ t2' ++ [EndLet]
  56. DB.Bop bop t1 t2 -> case compile t1 of
  57. t1' -> case compile t2 of
  58. t2' -> case bop of
  59. DB.Add -> t1' ++ t2' ++ [Bop Add]
  60. DB.Sub -> t1' ++ t2' ++ [Bop Sub]
  61. DB.Mul -> t1' ++ t2' ++ [Bop Mul]
  62. DB.Div -> t1' ++ t2' ++ [Bop Div]
  63. DB.Nand -> t1' ++ t2' ++ [Bop Nand]
  64. DB.Bpr bpr t1 t2 -> case compile t1 of
  65. t1' -> case compile t2 of
  66. t2' -> case bpr of
  67. DB.Eq -> t1' ++ t2' ++ [Bpr Eq]
  68. DB.Lt -> t1' ++ t2' ++ [Bpr Lt]
  69. step :: State -> Maybe State
  70. step state = case state of
  71. (Access i : c, e, s) -> Just (c, e,Value (e !! i) : s)
  72. (If:c, e, s2:s1:(Value (BoolVal v0)):s) -> case v0 of
  73. True -> Just(c, e, s1:s)
  74. False -> Just(c, e, s2:s)
  75. (Close code':code, env, s) -> Just(code, env, Env [Clo code' env]:s)
  76. (Apply:code, env, (Value v):(Env [Clo code' env']):s) -> Just(code', v:env', (Code code):(Env env):s)
  77. (Apply:code, env, (Value v):(Value (Clo code' env')):s) -> Just(code', v:env', (Code code):(Env env):s)
  78. (Return:c, e, s':(Code c'):(Env e'):s) -> Just(c', e', s':s)
  79. (Int n:c, e, s) -> Just(c, e, (Value (IntVal n)):s)
  80. (Bool b:c, e, s) -> Just(c, e, (Value (BoolVal b)):s)
  81. ((Bop bop):c, e, (Value (IntVal v2)):(Value (IntVal v1)):s) -> case bop of
  82. Add -> Just (c, e, (Value (IntVal (I.intAdd v1 v2))):s)
  83. Sub -> Just (c, e, (Value (IntVal (I.intSub v1 v2))):s)
  84. Mul -> Just (c, e, (Value (IntVal (I.intMul v1 v2))):s)
  85. Div -> Just (c, e, (Value (IntVal (I.intDiv v1 v2))):s)
  86. Nand-> Just (c, e, (Value (IntVal (I.intNand v1 v2))):s)
  87. ((Bpr bpr):c, e, (Value (IntVal v2)):(Value (IntVal v1)):s) -> case bpr of
  88. Eq -> Just (c, e, (Value (BoolVal (I.intEq v1 v2))):s)
  89. Lt -> Just (c, e, (Value (BoolVal (I.intLt v1 v2))):s)
  90. (Let:code, env, (Value v):s) -> Just(code, v:env, s)
  91. (Let:code, env, (Env env'):s) -> Just(code, env'++env, s)
  92. (EndLet:code, v:env, s) -> Just(code, env, s)
  93. (Fix:code, env, (Env [Clo code' env']):s) -> Just(code', (Clo [Close code', Fix] []):env, (Code code):(Env env):s)
  94. _ -> Nothing
  95. loop :: State -> State
  96. loop state =
  97. case step state of
  98. Just state'-> loop state'
  99. Nothing -> state
  100. eval :: DB.Term -> Value
  101. eval t = case loop (compile t, [], []) of
  102. (_,_,Value v:_) -> v
  103. _ -> error "not a value"
  104. \end{code}