Skip to content

Commit 704d5f2

Browse files
committed
Complete calculator program
1 parent bc9928a commit 704d5f2

File tree

1 file changed

+42
-39
lines changed

1 file changed

+42
-39
lines changed

13-monadic-parsing/13.09-calculator.hs

Lines changed: 42 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -23,49 +23,47 @@ buttons = standard ++ extra
2323
standard = "qcd=123+456-789*0()/"
2424
extra = "QCD \ESC\BS\DEL\n"
2525

26-
type Pos = (Int, Int)
27-
2826
cls :: IO ()
2927
cls = putStr "\ESC[2J"
3028

31-
writeat :: Pos -> String -> IO ()
29+
writeat :: (Int, Int) -> String -> IO ()
3230
writeat p xs = do
3331
goto p
3432
putStr xs
3533

36-
goto :: Pos -> IO ()
34+
goto :: (Int, Int) -> IO ()
3735
goto (x, y) = putStr ("\ESC[" ++ show y ++ ";" ++ show x ++ "H")
3836

3937
getCh :: IO Char
40-
getCh = do hSetEcho stdin False
41-
x <- getChar
42-
hSetEcho stdin True
43-
return x
38+
getCh = do
39+
hSetEcho stdin False
40+
x <- getChar
41+
hSetEcho stdin True
42+
return x
4443

4544
showbox :: IO ()
46-
showbox = sequence_ [writeat (1, y) b | (y, b) <- zip [1..] box]
45+
showbox = sequence_ [writeat (1,y) b | (y,b) <- zip [1..] box]
4746

4847
display :: [Char] -> IO ()
4948
display xs = do
50-
writeat (3, 2) (replicate 13 ' ')
51-
writeat (3, 2) (reverse (take 13 (reverse xs)))
49+
writeat (3,2) (replicate 13 ' ')
50+
writeat (3,2) (reverse (take 13 (reverse xs)))
5251

5352
calc :: String -> IO ()
5453
calc xs = do
5554
display xs
5655
c <- getCh
5756
if elem c buttons
5857
then process c xs
59-
else do
60-
beep
61-
calc xs
58+
else do beep
59+
calc xs
6260

6361
process :: Char -> String -> IO ()
64-
process c xs
65-
| elem c "qQ\ESC" = quit
66-
| elem c "= \n" = eval xs
67-
| elem c "cC" = clear
68-
| otherwise = press c xs
62+
process c xs | elem c "qQ\ESC" = quit
63+
| elem c "dD\BS\DEL" = delete xs
64+
| elem c "=\n" = eval xs
65+
| elem c "cC" = clear
66+
| otherwise = press c xs
6967

7068
quit :: IO ()
7169
quit = goto (1, 14)
@@ -77,9 +75,8 @@ delete xs = calc (init xs)
7775
eval :: String -> IO ()
7876
eval xs = case parse expr xs of
7977
[(n, [])] -> calc (show n)
80-
_ -> do
81-
beep
82-
calc xs
78+
_ -> do beep
79+
calc xs
8380

8481
beep :: IO ()
8582
beep = putStr "\BEL"
@@ -109,25 +106,31 @@ newtype Parser a = P (String -> [(a, String)])
109106
expr :: Parser Int
110107
expr = do
111108
t <- term
112-
do
113-
symbol "+"
114-
e <- expr
115-
return (t + e) <|> return t
109+
do symbol "+"
110+
e <- expr
111+
return (t + e)
112+
<|> do symbol "-"
113+
e <- expr
114+
return (t - e)
115+
<|> return t
116116

117117
term :: Parser Int
118118
term = do
119119
f <- factor
120-
do
121-
symbol "*"
122-
t <- term
123-
return (f * t) <|> return f
120+
do symbol "*"
121+
t <- term
122+
return (f * t)
123+
<|> do symbol "/"
124+
t <- term
125+
return (f `div` t)
126+
<|> return f
124127

125128
factor :: Parser Int
126-
factor = do
127-
symbol "("
128-
e <- expr
129-
symbol ")"
130-
return e <|> natural
129+
factor = do symbol "("
130+
e <- expr
131+
symbol ")"
132+
return e
133+
<|> nat
131134

132135
parse :: Parser a -> String -> [(a, String)]
133136
parse (P p) inp = p inp
@@ -187,10 +190,10 @@ space = do
187190
return ()
188191

189192
int :: Parser Int
190-
int = do
191-
char '-'
192-
n <- nat
193-
return (-n) <|> nat
193+
int = do char '-'
194+
n <- nat
195+
return (-n)
196+
<|> nat
194197

195198
token :: Parser a -> Parser a
196199
token p = do

0 commit comments

Comments
 (0)