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:
Joscha 2020-03-27 22:07:24 +00:00
parent 362025c8df
commit 6b81fd67b4
5 changed files with 52 additions and 16 deletions

View file

@ -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

View file

@ -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

View file

@ -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