-
Notifications
You must be signed in to change notification settings - Fork 1
Expand file tree
/
Copy pathRun.hs
More file actions
109 lines (93 loc) · 3.6 KB
/
Run.hs
File metadata and controls
109 lines (93 loc) · 3.6 KB
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
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
import System.Environment
import System.Exit
import System.IO
import System.Console.GetOpt
import Data.Number.CReal
import Data.Char
import Control.Monad
import Parquail
import TranslateQuail
import Printquail
import Types
import ErrM
data Options = Options
{ optVerbose , optPrecision :: Int
, optHelp, optVersion :: Bool
}
defaultOptions :: Options
defaultOptions = Options
{ optVerbose = 2
, optPrecision = 10
, optHelp = False
, optVersion = False
}
type OptTran = Endo Options
options :: [OptDescr OptTran]
options =
[ Option ['h'] ["help"] (NoArg help) "Print this help."
, Option ['v'] ["verbose"] (ReqArg verbose "VALUE") "Verbose mode between 0 (minimum) and 4 (maximum). Default value if not specified is 2."
, Option ['p'] ["precision"] (ReqArg precision "VALUE") "Define computation precision as a number of digits. Default value if not specified is 10."
, Option [] ["version"] (NoArg version) "show version number"
]
{-
options :: [OptDescr Flag]
options =
[ Option ['h'] ["help"] (NoArg Help) "Print this help."
, Option ['v'] ["verbose"] (ReqArg verbose "VALUE") "Verbose mode between 0 (minimum) and 4 (maximum). Default value if not specified is 2."
, Option ['p'] ["precision"] (ReqArg precision "VALUE") "Define computation precision as a number of digits. Default value if not specified is 10."
, Option [] ["version"] (NoArg Version) "show version number"
]
-}
help :: OptTran
help opt = opt { optHelp = True}
version :: OptTran
version opt = opt { optVersion = True}
verbose :: String -> OptTran
verbose s opt | all isDigit s = opt { optVerbose = read s }
| otherwise = error $ "unexpected verbose argument: " ++ show s
precision :: String -> OptTran
precision s opt | all isDigit s = opt { optPrecision = read s }
| otherwise = error $ "unexpected precision argument: " ++ show s
printVersion :: IO ()
printVersion = putStrLn "hasQuail 2.35"
approxCReal :: Int -> CReal -> CReal
approxCReal pr = read . showCReal pr
-- Here one can statically pick the precision for integers
type IntPrec = Int
-- type IntPrec = Int64
-- type IntPrec = Integer
getOptions :: IO (Options , [String])
getOptions = do
args <- getArgs
case getOpt Permute options args of
(o , fp , []) -> return (foldl (flip id) defaultOptions o , fp)
(_,_, errs) -> ioError (userError (concat errs ++ usage))
usage :: String
usage = usageInfo header options
where header = "Usage: Run [OPTION...] file..."
main :: IO ()
main = do
(opt , fps) <- getOptions
let v = optVerbose opt
let pr = optPrecision opt
case () of
_ | optHelp opt -> putStrLn usage
| optVersion opt -> printVersion
| [fp] <- fps -> do
s <- readFile fp
case pProgr $ myLexer s of
Bad err -> hPutStrLn stderr err >> exitWith (ExitFailure 1)
Ok t -> do
when (v > 0) $ putStrLn $ printTree t
let st = transProgr $ t
let (leak , totSecret) = expected st
let totSec = logBase 2 (fromIntegral (totSecret :: IntPrec))
let leak' = approxCReal pr leak
-- putStrLn . showProbTree . runProgram $ st
-- putStrLn $ "bits leaked: " ++ show (expected st :: Double)
putStrLn $ "bits leaked: " ++ showCReal pr leak'
putStrLn $ "total size of secret: " ++ showCReal pr totSec
++ " ("
++ showCReal pr (100 * leak' / totSec)
++ "%)"
| otherwise -> hPutStrLn stderr ("Can't understand input: " ++ unwords fps) >> exitWith (ExitFailure 1)