> module Evaluator where > import ParseLib hiding (nat) Comm ::= Var := Expr | Expr Expr ::= Num | Var | App App ::= Ô(Õ Expr Op Expr Ô)Õ Num ::= [-] Digit { Digit } Op ::= + | - | * | / Var ::= a | b | É | z Digit ::= 0 | 1 | ... | 9 > type Mem = [(String,Int)] > store :: Mem -> String -> Int -> Mem > store m v i = (v,i) : m > fetch :: Mem -> String -> Int > fetch [] var = 0 > fetch ((v,i):vis) var > | var == v = i > | otherwise = fetch vis var > calc :: IO () > calc = do putStr "Expression evaluator" > run [] > run :: Mem -> IO () > run mem = do putStr "\n? " > s <- getLine > if s == quitSignal > then do { putStr "...bye"; return () } > else > case papply comm s of > [((v,m),"")] -> do putStr (" = "++ show v) > run m > _ -> do putStr " *** error" > run mem > where > comm :: Parser (Int,Mem) > comm = do v <- name > char ':' > char '=' > e <- expr > return (e, store mem v e) > +++ > do e <- expr > return (e,mem) > expr :: Parser Int > expr = num +++ var +++ app > var :: Parser Int > var = do n <- name > return (fetch mem n) > app :: Parser Int > app = do char '(' > e1 <- expr > op <- char '+' +++ > char '-' +++ > char '*' +++ > char '/' > e2 <- expr > char ')' > case op of > '+' -> return (e1 + e2) > '-' -> return (e1 - e2) > '*' -> return (e1 * e2) > '/' -> if e2 /= 0 > then return (e1 `div` e2) > else mzero > nat :: Parser Int > nat = do d <- digit > s <- many digit > return (read (d:s)) > num = do char '-' > n <- nat > return (-n) > +++ nat > name :: Parser String > name = do c <- lower > cs <- many lower > return (c:cs) > quitSignal = "#"