/exercise3/NSWCAD.lhs

http://sauce-code.googlecode.com/ · Haskell · 94 lines · 72 code · 12 blank · 10 comment · 22 complexity · d2b9d3ea3284ab2d8a487cbb9df64378 MD5 · raw file

  1. \begin{code}
  2. module NSWCAD where
  3. import Data.Maybe
  4. import qualified DeBruijn as S
  5. import qualified IntegerArithmetic as I
  6. import Debug.Trace
  7. data Value = BoolVal Bool | IntVal Integer | Clo S.Term Env
  8. deriving Show
  9. type Env = [Value]
  10. evalInEnv :: Env -> S.Term -> Maybe Value
  11. evalInEnv e t = case t of
  12. -- true,false
  13. S.Tru -> Just (BoolVal True)
  14. S.Fls -> Just (BoolVal False)
  15. -- integer
  16. S.IntConst n -> Just (IntVal n)
  17. -- if
  18. S.If t1 t2 t3 -> case evalInEnv e t1 of
  19. Just (BoolVal True) -> case evalInEnv e t2 of
  20. Just a -> Just a
  21. _ -> error "if-t2"
  22. Just (BoolVal False) -> case evalInEnv e t3 of
  23. Just b -> Just b
  24. _ -> error "if-t3"
  25. _ -> error "if-t1"
  26. -- var
  27. S.Var i -> Just (e !! i)
  28. -- app
  29. S.App t1 t2 -> case evalInEnv e t1 of
  30. Just (Clo (S.Abs tau t') e') -> case evalInEnv e t2 of
  31. Just v' -> case evalInEnv ([v'] ++ e') t' of
  32. Just vv -> Just vv
  33. _ -> error "app-replacement"
  34. _ -> error "app-t2 is not a value"
  35. Just (Clo (S.Fix t') e') -> case evalInEnv e' (S.Fix t') of
  36. Just (Clo (S.Abs tau' tt) ee) -> case evalInEnv e t2 of
  37. Just v'-> case evalInEnv ([v']++ee) tt of
  38. Just vv -> Just vv
  39. _ -> Nothing
  40. _ -> Nothing
  41. _ -> Nothing
  42. _ -> error "app-t1 is not an abstraction"
  43. -- abs
  44. S.Abs tau t1 -> Just (Clo (S.Abs tau t1) e)
  45. -- add, sub,mul,div,nand
  46. S.Bop op t1 t2 -> case evalInEnv e t1 of
  47. Just (IntVal v1) -> case evalInEnv e t2 of
  48. Just (IntVal v2) -> case op of
  49. S.Add -> Just (IntVal (I.intAdd v1 v2))
  50. S.Sub -> Just (IntVal (I.intSub v1 v2))
  51. S.Mul -> Just (IntVal (I.intMul v1 v2))
  52. S.Div -> Just (IntVal (I.intDiv v1 v2))
  53. S.Nand -> Just (IntVal (I.intNand v1 v2))
  54. _ -> error "BOP t2 is not a value"
  55. _ -> error "BOP t1 is not a value"
  56. -- eq,lt
  57. S.Bpr pr t1 t2 -> case evalInEnv e t1 of
  58. Just (IntVal v1) -> case evalInEnv e t2 of
  59. Just (IntVal v2) -> case pr of
  60. S.Eq -> case I.intEq v1 v2 of
  61. True -> Just (BoolVal True)
  62. False -> Just (BoolVal False)
  63. S.Lt -> case I.intLt v1 v2 of
  64. True -> Just (BoolVal True)
  65. False -> Just (BoolVal False)
  66. _ -> error "BRP t2 is not a value"
  67. _ -> error "BRP t1 is not a value"
  68. -- let
  69. S.Let t1 t2 -> case evalInEnv e t1 of
  70. Just a -> case evalInEnv ([a] ++ e) t2 of
  71. Just b -> Just b
  72. _ -> error "let-t2 is not a value"
  73. _ -> error "let t1 is not a value"
  74. -- fix
  75. S.Fix t1 -> case evalInEnv e t1 of
  76. Just (Clo (S.Abs tau t') e') -> case evalInEnv ([Clo (S.Fix (S.Abs tau t')) e'] ++ e') t' of
  77. Just b -> Just b
  78. _ -> error "fix-point error"
  79. _ -> error "fix-t1 is not an abstraction"
  80. eval :: S.Term -> Value
  81. eval t = fromJust (evalInEnv [] t)
  82. \end{code}