Permalink
Browse files

How I could forget about lists?

  • Loading branch information...
dmatveev committed Apr 12, 2012
1 parent 88b820d commit f7db3e7380ba65c26a13b10cf319b5f3a9bd40b4
Showing with 37 additions and 7 deletions.
  1. +31 −6 Eval.hs
  2. +6 −1 Form.hs
View
37 Eval.hs
@@ -13,7 +13,7 @@ eval' :: String -> Either String Form
eval' s = do
tree <- parseTree s
eval tree
-
+
evalSExpr :: Operation -> [Form] -> Either String Form
evalSExpr op args =
@@ -26,6 +26,10 @@ evalSExpr op args =
"=" -> evalBinary evalEqual args
"if" -> evalIf args
+
+ "cons" -> evalBinary evalCons args
+ "car" -> evalUnary evalCar args
+ "cdr" -> evalUnary evalCdr args
evalArith :: (Double -> Double -> Double) -> [Form] -> Either String Form
@@ -39,11 +43,19 @@ evalArith f (arg : args) = do
return $ NumericLiteral $ f left right
+
+evalUnary :: (Form -> Either String Form)
+ -> [Form]
+ -> Either String Form
+evalUnary e (a:[]) = e a
+evalUnary _ _ = wrongNumberOfArgs
+
+
evalBinary :: (Form -> Form -> Either String Form)
-> [Form]
-> Either String Form
-evalBinary e (a:b:_) = e a b
-evalBinary _ _ = wrongNumberOfArgs
+evalBinary e (a:b:[]) = e a b
+evalBinary _ _ = wrongNumberOfArgs
evalDiv :: Form -> Form -> Either String Form
@@ -65,11 +77,24 @@ evalIf (exp : thenForm : elseForm : _ ) = do
e <- eval exp
eval $ if e /= nil then thenForm else elseForm
-evalIf (exp : thenForm : [] ) = do
- evalIf [exp, thenForm, nil]
-
+evalIf (exp : thenForm : [] ) = evalIf [exp, thenForm, nil]
evalIf _ = wrongNumberOfArgs
+evalCons :: Form -> Form -> Either String Form
+evalCons h t = do
+ h' <- eval h
+ t' <- eval t
+ return $ Cons h' t'
+
+
+evalCar :: Form -> Either String Form
+evalCar f = eval f >>= cons >>= \(h, _) -> return h
+
+
+evalCdr :: Form -> Either String Form
+evalCdr f = eval f >>= cons >>= \(_, t) -> return t
+
+
wrongNumberOfArgs :: Either String Form
wrongNumberOfArgs = Left "wrong number of arguments"
View
@@ -11,6 +11,7 @@ data Form = Symbol String
| NumericLiteral Double
| BooleanLiteral Bool
| SExpr Operation [Form]
+ | Cons Form Form
deriving (Eq, Show)
@@ -86,4 +87,8 @@ nil = BooleanLiteral False
numeric :: Form -> Either String Double
numeric (NumericLiteral i) = return i
numeric _ = Left "number expected"
-
+
+
+cons :: Form -> Either String (Form, Form)
+cons (Cons h t) = return $ (h, t)
+cons _ = Left "cons expected"

0 comments on commit f7db3e7

Please sign in to comment.