Skip to content

Instantly share code, notes, and snippets.

@MiyamonY
Created March 25, 2015 11:39
Show Gist options
  • Save MiyamonY/494de2c6c8eeda0a35c6 to your computer and use it in GitHub Desktop.
Save MiyamonY/494de2c6c8eeda0a35c6 to your computer and use it in GitHub Desktop.
import System.IO
import Text.Parsec
import Text.Parsec.String
type Pos = (Int, Int)
goto :: Pos -> IO ()
goto (x, y) = putStr $ "\ESC[" ++ show y ++ ";" ++ show x ++ "H"
beep :: IO ()
beep = putStr "\BEL"
cls :: IO ()
cls = putStr "\ESC[2J]"
writeat :: Pos -> String -> IO ()
writeat p xs = do
goto p
putStr xs
seqn :: [IO a] -> IO ()
seqn [] = return ()
seqn (a:as) = do a
seqn as
box :: [String]
box = ["+---------------+",
"| |",
"+---+---+---+---+",
"| q | c | d | = |",
"+---+---+---+---+",
"| 1 | 2 | 3 | + |",
"+---+---+---+---+",
"| 4 | 5 | 6 | - |",
"+---+---+---+---+",
"| 7 | 8 | 9 | * |",
"+---+---+---+---+",
"| 0 | ( | ) | / |",
"+---+---+---+---+"]
buttons :: [Char]
buttons = standard ++ extra
where standard = "qcd=123+456-789*0()/"
extra = "QCD \ESC\BS\DEL\n"
showbox :: IO ()
showbox = seqn [writeat (1, y) xs | (y, xs) <- zip [1..13] box]
display :: String -> IO ()
display xs = do writeat (3, 2) " |"
writeat (3, 2) (reverse . take 13 . reverse $ xs)
calc :: String -> IO ()
calc xs = do display xs
c <- getChar
if c `elem` buttons
then process c xs
else do
beep
calc xs
process :: Char -> String -> IO ()
process c xs
| c `elem` "qQ\ESC" = quit
| c `elem` "dD\BS\DEL" = delete xs
| c `elem` "=\n" = eval xs
| c `elem` "cC" = clear
| otherwise = press c xs
quit :: IO ()
quit = goto (1, 14)
delete :: String -> IO ()
delete "" = calc ""
delete xs = calc (init xs)
eval :: String -> IO ()
eval xs = calc xs
clear :: IO ()
clear = calc ""
press :: Char -> String -> IO ()
press c xs = calc (xs ++ [c])
run :: IO ()
run = do cls
showbox
clear
main :: IO()
main = do
hSetBuffering stdout NoBuffering
run
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment