hc/app/Main.hs

47 lines
1.8 KiB
Haskell

module Main (main) where
import Text.Parsec
import Lib (exprparser, evaluate, replaceVars, Expr, extractVariableDefinitions, updateVariables)
import Data.Map (Map)
import qualified Data.Map as Map
import Data.Ratio
import System.IO
initVars :: Map String Rational
initVars = Map.fromList [("pi", 245850922 % 78256779), ("e", 271801 % 99990)]
main :: IO ()
main = ioLoop initVars
precision = 5 :: Int
showRatio :: Int -> Rational -> String
showRatio p r = (if (r < 0) then "-" else "") ++ prepoint_digits ++ (if (length postpoint_digits > 0) then ("." ++ postpoint_digits) else "")
where
prepoint_digits = init . show . round . abs $ (r * 10)
postpoint_digits = reverse . dropWhile (=='0') . reverse .(take p) . (drop (length prepoint_digits)) . show . round . abs $ (r * 10^p)
useResult :: Map String Rational -> Expr -> String
useResult vs expr = either id ((showRatio precision) . evaluate) $ replaceVars expr vs
ioLoop :: Map String Rational -> IO ()
ioLoop vs = do done <- isEOF
if done
then putStrLn "Quit!"
else do inp <- getLine
let expr_res = parse exprparser "<stdin>" inp
case expr_res of
Left err -> do
putStrLn . show $ err
ioLoop vs
Right expr -> do
let vardefs = extractVariableDefinitions expr
let uvs_res = updateVariables vardefs vs
case uvs_res of
Left err -> putStrLn err
Right uvs -> putStrLn $ useResult uvs expr
ioLoop (either (const vs) (id) uvs_res)