Write out the typechecker prelude when necessary

Bundle the typechecker prelude (CryptolTC.z3) with the executable, so
that it's able to write it out and re-use it when necessary.

Fixes #404
This commit is contained in:
Trevor Elliott 2017-03-28 16:29:21 -07:00
parent f89c23b594
commit 7fc50a9cbb
3 changed files with 28 additions and 12 deletions

View File

@ -215,7 +215,7 @@ findModule n = do
handleNotFound = handleNotFound =
case n of case n of
m | m == preludeName -> writePreludeContents m | m == preludeName -> io writePreludeContents
_ -> moduleNotFound n =<< getSearchPath _ -> moduleNotFound n =<< getSearchPath
-- generate all possible search paths -- generate all possible search paths

View File

@ -8,13 +8,16 @@
-- --
-- Compile the prelude into the executable as a last resort -- Compile the prelude into the executable as a last resort
{-# LANGUAGE Trustworthy #-}
{-# LANGUAGE CPP #-} {-# LANGUAGE CPP #-}
{-# LANGUAGE QuasiQuotes #-} {-# LANGUAGE QuasiQuotes #-}
{-# LANGUAGE OverloadedStrings #-} {-# LANGUAGE OverloadedStrings #-}
module Cryptol.Prelude (writePreludeContents) where module Cryptol.Prelude (
writePreludeContents,
writeTcPreludeContents,
) where
import Cryptol.ModuleSystem.Monad
import System.Directory (getTemporaryDirectory) import System.Directory (getTemporaryDirectory)
import System.IO (hClose, hPutStr, openTempFile) import System.IO (hClose, hPutStr, openTempFile)
@ -25,10 +28,24 @@ preludeContents = [there|lib/Cryptol.cry|]
-- | Write the contents of the Prelude to a temporary file so that -- | Write the contents of the Prelude to a temporary file so that
-- Cryptol can load the module. -- Cryptol can load the module.
writePreludeContents :: ModuleM FilePath writePreludeContents :: IO FilePath
writePreludeContents = io $ do writePreludeContents = do
tmpdir <- getTemporaryDirectory tmpdir <- getTemporaryDirectory
(path, h) <- openTempFile tmpdir "Cryptol.cry" (path, h) <- openTempFile tmpdir "Cryptol.cry"
hPutStr h preludeContents hPutStr h preludeContents
hClose h hClose h
return path return path
cryptolTcContents :: String
cryptolTcContents = [there|lib/CryptolTC.z3|]
-- | Write the contents of the Prelude to a temporary file so that
-- Cryptol can load the module.
writeTcPreludeContents :: IO FilePath
writeTcPreludeContents = do
tmpdir <- getTemporaryDirectory
(path, h) <- openTempFile tmpdir "CryptolTC.z3"
hPutStr h cryptolTcContents
hClose h
return path

View File

@ -19,6 +19,7 @@ module Cryptol.TypeCheck.Monad
import Cryptol.ModuleSystem.Name (FreshM(..),Supply) import Cryptol.ModuleSystem.Name (FreshM(..),Supply)
import Cryptol.Parser.Position import Cryptol.Parser.Position
import qualified Cryptol.Parser.AST as P import qualified Cryptol.Parser.AST as P
import Cryptol.Prelude (writeTcPreludeContents)
import Cryptol.TypeCheck.AST import Cryptol.TypeCheck.AST
import Cryptol.TypeCheck.Subst import Cryptol.TypeCheck.Subst
import Cryptol.TypeCheck.Unify(mgu, Result(..), UnificationError(..)) import Cryptol.TypeCheck.Unify(mgu, Result(..), UnificationError(..))
@ -34,8 +35,7 @@ import qualified Data.Map as Map
import qualified Data.Set as Set import qualified Data.Set as Set
import Data.Map (Map) import Data.Map (Map)
import Data.Set (Set) import Data.Set (Set)
import Data.List(find, minimumBy, groupBy, sortBy, foldl', import Data.List(find, minimumBy, groupBy, sortBy, foldl')
intercalate)
import Data.Maybe(mapMaybe) import Data.Maybe(mapMaybe)
import Data.Function(on) import Data.Function(on)
import MonadLib hiding (mapM) import MonadLib hiding (mapM)
@ -168,11 +168,10 @@ runInferM info (IM m) = CrySAT.withSolver (inpSolverConfig info) $ \solver ->
-- The actual order does not matter -- The actual order does not matter
cmpRange (Range x y z) (Range a b c) = compare (x,y,z) (a,b,c) cmpRange (Range x y z) (Range a b c) = compare (x,y,z) (a,b,c)
loadCryTCPrel _ [] = loadCryTCPrel s [] =
panic "runInferM" [ "Failed to find file: CryptolTC.z3" do file <- writeTcPreludeContents
, "Searched paths: " ++ CrySAT.loadFile s file
intercalate ":" (inpSearchPath info)
]
loadCryTCPrel s (p : ps) = loadCryTCPrel s (p : ps) =
do let file = p </> "CryptolTC.z3" do let file = p </> "CryptolTC.z3"
yes <- doesFileExist file yes <- doesFileExist file