mirror of
https://github.com/GaloisInc/cryptol.git
synced 2024-12-16 20:03:27 +03:00
d76f21f89e
Since they don’t run in the normal REPL environment, they need to know about where to find the Prelude and CryptolTC.z3 more directly.
161 lines
5.8 KiB
Haskell
161 lines
5.8 KiB
Haskell
-- |
|
|
-- Module : $Header$
|
|
-- Copyright : (c) 2015-2016 Galois, Inc.
|
|
-- License : BSD3
|
|
-- Maintainer : cryptol@galois.com
|
|
-- Stability : provisional
|
|
-- Portability : portable
|
|
|
|
{-# LANGUAGE OverloadedStrings #-}
|
|
{-# LANGUAGE ScopedTypeVariables #-}
|
|
module Main where
|
|
|
|
import qualified Data.Text.Lazy as T
|
|
import qualified Data.Text.Lazy.IO as T
|
|
import System.FilePath ((</>))
|
|
import qualified System.Directory as Dir
|
|
|
|
import qualified Cryptol.Eval as E
|
|
import qualified Cryptol.Eval.Monad as E
|
|
import qualified Cryptol.Eval.Value as E
|
|
|
|
import qualified Cryptol.ModuleSystem.Base as M
|
|
import qualified Cryptol.ModuleSystem.Env as M
|
|
import qualified Cryptol.ModuleSystem.Monad as M
|
|
import qualified Cryptol.ModuleSystem.NamingEnv as M
|
|
|
|
import qualified Cryptol.Parser as P
|
|
import qualified Cryptol.Parser.AST as P
|
|
import qualified Cryptol.Parser.NoInclude as P
|
|
|
|
import qualified Cryptol.Symbolic as S
|
|
import qualified Cryptol.Symbolic.Value as S
|
|
|
|
import qualified Cryptol.TypeCheck as T
|
|
import qualified Cryptol.TypeCheck.AST as T
|
|
|
|
import qualified Cryptol.Utils.Ident as I
|
|
|
|
import qualified Data.SBV.Dynamic as SBV
|
|
|
|
import Criterion.Main
|
|
|
|
main :: IO ()
|
|
main = do
|
|
cd <- Dir.getCurrentDirectory
|
|
defaultMain [
|
|
bgroup "parser" [
|
|
parser "Prelude" "lib/Cryptol.cry"
|
|
, parser "Extras" "lib/Cryptol/Extras.cry"
|
|
, parser "PreludeWithExtras" "bench/data/PreludeWithExtras.cry"
|
|
, parser "BigSequence" "bench/data/BigSequence.cry"
|
|
, parser "BigSequenceHex" "bench/data/BigSequenceHex.cry"
|
|
, parser "AES" "bench/data/AES.cry"
|
|
, parser "SHA512" "bench/data/SHA512.cry"
|
|
]
|
|
, bgroup "typechecker" [
|
|
tc cd "Prelude" "lib/Cryptol.cry"
|
|
, tc cd "Extras" "lib/Cryptol/Extras.cry"
|
|
, tc cd "PreludeWithExtras" "bench/data/PreludeWithExtras.cry"
|
|
, tc cd "BigSequence" "bench/data/BigSequence.cry"
|
|
, tc cd "BigSequenceHex" "bench/data/BigSequenceHex.cry"
|
|
, tc cd "AES" "bench/data/AES.cry"
|
|
, tc cd "SHA512" "bench/data/SHA512.cry"
|
|
]
|
|
, bgroup "conc_eval" [
|
|
ceval cd "AES" "bench/data/AES.cry" "bench_correct"
|
|
, ceval cd "ZUC" "bench/data/ZUC.cry" "ZUC_TestVectors"
|
|
, ceval cd "SHA512" "bench/data/SHA512.cry" "testVector1 ()"
|
|
]
|
|
, bgroup "sym_eval" [
|
|
seval cd "AES" "bench/data/AES.cry" "bench_correct"
|
|
, seval cd "ZUC" "bench/data/ZUC.cry" "ZUC_TestVectors"
|
|
, seval cd "SHA512" "bench/data/SHA512.cry" "testVector1 ()"
|
|
]
|
|
]
|
|
|
|
-- | Make a benchmark for parsing a Cryptol module
|
|
parser :: String -> FilePath -> Benchmark
|
|
parser name path =
|
|
env (T.readFile path) $ \(~bytes) ->
|
|
bench name $ nfIO $ do
|
|
let cfg = P.defaultConfig
|
|
{ P.cfgSource = path
|
|
, P.cfgPreProc = P.guessPreProc path
|
|
}
|
|
case P.parseModule cfg bytes of
|
|
Right pm -> return pm
|
|
Left err -> error (show err)
|
|
|
|
-- | Make a benchmark for typechecking a Cryptol module. Does parsing
|
|
-- in the setup phase in order to isolate typechecking
|
|
tc :: String -> String -> FilePath -> Benchmark
|
|
tc cd name path =
|
|
let withLib = M.withPrependedSearchPath [cd </> "lib"] in
|
|
let setup = do
|
|
bytes <- T.readFile path
|
|
let cfg = P.defaultConfig
|
|
{ P.cfgSource = path
|
|
, P.cfgPreProc = P.guessPreProc path
|
|
}
|
|
Right pm = P.parseModule cfg bytes
|
|
menv <- M.initialModuleEnv
|
|
(Right ((prims, scm, tcEnv), menv'), _) <- M.runModuleM menv $ withLib $ do
|
|
-- code from `loadModule` and `checkModule` in
|
|
-- `Cryptol.ModuleSystem.Base`
|
|
let pm' = M.addPrelude pm
|
|
M.loadDeps pm'
|
|
Right nim <- M.io (P.removeIncludesModule path pm')
|
|
npm <- M.noPat nim
|
|
(tcEnv,declsEnv,scm) <- M.renameModule npm
|
|
prims <- if P.thing (P.mName pm) == I.preludeName
|
|
then return (M.toPrimMap declsEnv)
|
|
else M.getPrimMap
|
|
return (prims, scm, tcEnv)
|
|
return (prims, scm, tcEnv, menv')
|
|
in env setup $ \ ~(prims, scm, tcEnv, menv) ->
|
|
bench name $ nfIO $ M.runModuleM menv $ withLib $ do
|
|
let act = M.TCAction { M.tcAction = T.tcModule
|
|
, M.tcLinter = M.moduleLinter (P.thing (P.mName scm))
|
|
, M.tcPrims = prims
|
|
}
|
|
M.typecheck act scm tcEnv
|
|
|
|
ceval :: String -> String -> FilePath -> T.Text -> Benchmark
|
|
ceval cd name path expr =
|
|
let withLib = M.withPrependedSearchPath [cd </> "lib"] in
|
|
let setup = do
|
|
menv <- M.initialModuleEnv
|
|
(Right (texpr, menv'), _) <- M.runModuleM menv $ withLib $ do
|
|
m <- M.loadModuleByPath path
|
|
M.setFocusedModule (T.mName m)
|
|
let Right pexpr = P.parseExpr expr
|
|
(_, texpr, _) <- M.checkExpr pexpr
|
|
return texpr
|
|
return (texpr, menv')
|
|
in env setup $ \ ~(texpr, menv) ->
|
|
bench name $ nfIO $ E.runEval $ do
|
|
env' <- E.evalDecls (S.allDeclGroups menv) mempty
|
|
(e :: E.Value) <- E.evalExpr env' texpr
|
|
E.forceValue e
|
|
|
|
|
|
seval :: String -> String -> FilePath -> T.Text -> Benchmark
|
|
seval cd name path expr =
|
|
let withLib = M.withPrependedSearchPath [cd </> "lib"] in
|
|
let setup = do
|
|
menv <- M.initialModuleEnv
|
|
(Right (texpr, menv'), _) <- M.runModuleM menv $ withLib $ do
|
|
m <- M.loadModuleByPath path
|
|
M.setFocusedModule (T.mName m)
|
|
let Right pexpr = P.parseExpr expr
|
|
(_, texpr, _) <- M.checkExpr pexpr
|
|
return texpr
|
|
return (texpr, menv')
|
|
in env setup $ \ ~(texpr, menv) ->
|
|
bench name $ nfIO $ E.runEval $ do
|
|
env' <- E.evalDecls (S.allDeclGroups menv) mempty
|
|
(e :: S.Value) <- E.evalExpr env' texpr
|
|
E.io $ SBV.compileToSMTLib SBV.SMTLib2 False $
|
|
return (S.fromVBit e)
|