Implement basic mima-run functionality
Bugs fixed: - Print correct file name when load/save error occurs - Correctly identify invalid file formats
This commit is contained in:
parent
362025c8df
commit
6b81fd67b4
5 changed files with 52 additions and 16 deletions
|
|
@ -5,6 +5,7 @@ module Mima.Run
|
|||
-- * The 'Run' monad
|
||||
Run
|
||||
, run
|
||||
, runOrExit
|
||||
, throw
|
||||
, catch
|
||||
, handle
|
||||
|
|
@ -18,8 +19,10 @@ module Mima.Run
|
|||
import Control.Monad.IO.Class
|
||||
import Control.Monad.Trans.Except
|
||||
import qualified Data.ByteString.Lazy as BS
|
||||
import Data.Maybe
|
||||
import qualified Data.Text as T
|
||||
import qualified Data.Text.IO as T
|
||||
import System.Exit
|
||||
import System.IO.Error
|
||||
|
||||
newtype Run a = Run (ExceptT T.Text IO a)
|
||||
|
|
@ -28,6 +31,16 @@ newtype Run a = Run (ExceptT T.Text IO a)
|
|||
run :: Run a -> IO (Either T.Text a)
|
||||
run (Run e) = runExceptT e
|
||||
|
||||
runOrExit :: Int -> Run () -> IO ()
|
||||
runOrExit exitCode r = do
|
||||
result <- run r
|
||||
case result of
|
||||
Right () -> pure ()
|
||||
Left e -> do
|
||||
putStrLn "Encountered an exception:"
|
||||
T.putStrLn e
|
||||
exitWith $ ExitFailure exitCode
|
||||
|
||||
throw :: T.Text -> Run a
|
||||
throw = Run . throwE
|
||||
|
||||
|
|
@ -43,8 +56,10 @@ isRelevantError e = isAlreadyInUseError e || isDoesNotExistError e || isPermissi
|
|||
formatRelevantError :: IOError -> Maybe T.Text
|
||||
formatRelevantError e
|
||||
| isRelevantError e = Just $ T.pack $
|
||||
"Can't open file " <> ioeGetLocation e <> ": " <> ioeGetErrorString e
|
||||
"Can't open file " <> fileName <> ": " <> ioeGetErrorString e
|
||||
| otherwise = Nothing
|
||||
where
|
||||
fileName = fromMaybe "<unknown>" $ ioeGetFileName e
|
||||
|
||||
protect :: IO a -> Run a
|
||||
protect m = do
|
||||
|
|
|
|||
|
|
@ -6,8 +6,8 @@ module Mima.Vm.State
|
|||
, basicState
|
||||
, AbortReason(..)
|
||||
, step
|
||||
, run
|
||||
, runN
|
||||
, execute
|
||||
, executeN
|
||||
) where
|
||||
|
||||
import Control.Applicative
|
||||
|
|
@ -157,16 +157,16 @@ step ms = do
|
|||
(SmallInstruction so lv) -> doSmallOpcode so lv ms'
|
||||
(LargeInstruction lo sv) -> doLargeOpcode lo sv ms'
|
||||
|
||||
run :: MimaState -> (MimaState, AbortReason, Integer)
|
||||
run = helper 0
|
||||
execute :: MimaState -> (MimaState, AbortReason, Integer)
|
||||
execute = helper 0
|
||||
where
|
||||
helper completed s =
|
||||
case step s of
|
||||
Left e -> (s, e, completed)
|
||||
Right s' -> helper (completed + 1) s'
|
||||
|
||||
runN :: Integer -> MimaState -> (MimaState, Maybe AbortReason, Integer)
|
||||
runN n = helper 0
|
||||
executeN :: Integer -> MimaState -> (MimaState, Maybe AbortReason, Integer)
|
||||
executeN n = helper 0
|
||||
where
|
||||
helper completed s =
|
||||
if completed >= n
|
||||
|
|
|
|||
|
|
@ -32,7 +32,7 @@ loadMimaState :: FilePath -> Run MimaState
|
|||
loadMimaState path = do
|
||||
bs <- readFileBS path
|
||||
case B.decodeOrFail bs of
|
||||
Right ("", 0, a) -> pure a
|
||||
Right ("", _, a) -> pure a
|
||||
Right _ -> throw "invalid file format"
|
||||
Left (_, _, e) -> throw $ T.pack e
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue