2024-09-15 12:39:46 +02:00
|
|
|
module Main (main) where
|
|
|
|
|
2024-09-15 16:47:34 +02:00
|
|
|
import Text.Parsec
|
|
|
|
|
2024-09-16 12:34:30 +02:00
|
|
|
import Lib (exprparser, evaluate, replaceVars, Expr, extractVariableDefinitions)
|
2024-09-15 17:58:53 +02:00
|
|
|
|
|
|
|
import Data.Map (Map)
|
|
|
|
import qualified Data.Map as Map
|
|
|
|
import Data.Ratio
|
2024-09-15 16:47:34 +02:00
|
|
|
|
|
|
|
import System.IO
|
2024-09-15 12:39:46 +02:00
|
|
|
|
2024-09-16 12:34:30 +02:00
|
|
|
initVars :: Map String Rational
|
|
|
|
initVars = Map.fromList [("pi", 245850922 % 78256779), ("e", 271801 % 99990)]
|
|
|
|
|
2024-09-15 12:39:46 +02:00
|
|
|
main :: IO ()
|
2024-09-16 12:34:30 +02:00
|
|
|
main = ioLoop initVars
|
2024-09-15 16:47:34 +02:00
|
|
|
|
2024-09-15 17:58:53 +02:00
|
|
|
precision = 5 :: Int
|
|
|
|
|
|
|
|
showRatio :: Int -> Rational -> String
|
2024-09-16 10:54:43 +02:00
|
|
|
showRatio p r = (if (r < 0) then "-" else "") ++ prepoint_digits ++ (if (length postpoint_digits > 0) then ("." ++ postpoint_digits) else "")
|
2024-09-15 17:58:53 +02:00
|
|
|
where
|
2024-09-15 18:07:45 +02:00
|
|
|
prepoint_digits = init . show . round . abs $ (r * 10)
|
2024-09-16 12:34:30 +02:00
|
|
|
postpoint_digits = reverse . dropWhile (=='0') . reverse .(take p) . (drop (length prepoint_digits)) . show . round . abs $ (r * 10^p)
|
|
|
|
|
|
|
|
useResult :: Map String Rational -> Either ParseError Expr -> String
|
|
|
|
useResult vs (Right expr) = either id ((showRatio precision) . evaluate) $ replaceVars expr vs
|
|
|
|
useResult vs (Left error) = show error
|
|
|
|
|
|
|
|
ioLoop :: Map String Rational -> IO ()
|
|
|
|
ioLoop vs = do done <- isEOF
|
|
|
|
if done
|
|
|
|
then putStrLn "Quit!"
|
|
|
|
else do inp <- getLine
|
|
|
|
let expr = parse exprparser "<stdin>" inp
|
|
|
|
let uvs = either (const vs) (\e -> Map.unionWith (flip const) vs (extractVariableDefinitions e)) expr
|
|
|
|
putStrLn $ useResult uvs expr
|
|
|
|
ioLoop uvs
|
2024-09-15 16:47:34 +02:00
|
|
|
|