simple rpn calculator

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
import System
import System.IO
import Control.Monad

prompt :: String
prompt = "> "

opsTable :: [(String, Int -> Int -> Int)]
opsTable = [ ("+", (+))
           , ("-", (-))
           , ("*", (*))
           , ("/", div)
           ]

mainLoop :: [Int] -> IO ()
mainLoop []     = mainLoop [0,0]
mainLoop (a:[]) = mainLoop [a,0]
mainLoop all@(a:b:rest) = do
    -- Display the current stack before the prompt
    let promptString = (show $ reverse all) ++ prompt
    putStr promptString
    hFlush stdout
    -- And get the user's input
    input <- getLine

    when (input == "exit") $ do
        fail "User initiated exit"
        return ()

    case input `lookup` opsTable of
         Nothing -> mainLoop $ read input : all
         Just op -> mainLoop $ op b a : rest

main = mainLoop []