lib: refactor includedirectivep to avoid "re-parsing"
				
					
				
			This commit is contained in:
		
							parent
							
								
									b034fa7ca9
								
							
						
					
					
						commit
						4a9e418b7a
					
				| @ -75,7 +75,7 @@ import Prelude () | |||||||
| import "base-compat-batteries" Prelude.Compat hiding (readFile) | import "base-compat-batteries" Prelude.Compat hiding (readFile) | ||||||
| import qualified Control.Exception as C | import qualified Control.Exception as C | ||||||
| import Control.Monad | import Control.Monad | ||||||
| import Control.Monad.Except (ExceptT(..), runExceptT, throwError) | import Control.Monad.Except (ExceptT(..)) | ||||||
| import Control.Monad.State.Strict | import Control.Monad.State.Strict | ||||||
| import qualified Data.Map.Strict as M | import qualified Data.Map.Strict as M | ||||||
| import Data.Text (Text) | import Data.Text (Text) | ||||||
| @ -190,36 +190,40 @@ includedirectivep :: MonadIO m => ErroringJournalParser m () | |||||||
| includedirectivep = do | includedirectivep = do | ||||||
|   string "include" |   string "include" | ||||||
|   lift (skipSome spacenonewline) |   lift (skipSome spacenonewline) | ||||||
|   filename  <- lift restofline |   filename <- T.unpack <$> takeWhileP Nothing (/= '\n') -- don't consume newline yet | ||||||
|   parentpos <- getPosition | 
 | ||||||
|   parentj   <- get |   -- save parent state | ||||||
|  |   parentParserState <- getParserState | ||||||
|  |   parentj <- get | ||||||
|  | 
 | ||||||
|   let childj = newJournalWithParseStateFrom parentj |   let childj = newJournalWithParseStateFrom parentj | ||||||
|   (ej :: Either String ParsedJournal) <- |   parentpos <- getPosition | ||||||
|     liftIO $ runExceptT $ do | 
 | ||||||
|       let curdir = takeDirectory (sourceName parentpos) |   -- read child input | ||||||
|       filepath <- expandPath curdir filename `orRethrowIOError` (show parentpos ++ " locating " ++ filename) |   let curdir = takeDirectory (sourceName parentpos) | ||||||
|       txt      <- readFilePortably filepath `orRethrowIOError` (show parentpos ++ " reading " ++ filepath) |   filepath <- lift $ expandPath curdir filename `orRethrowIOError` (show parentpos ++ " locating " ++ filename) | ||||||
|       (ej1::Either (ParseError Char CustomErr) ParsedJournal) <- |   childInput <- lift $ readFilePortably filepath `orRethrowIOError` (show parentpos ++ " reading " ++ filepath) | ||||||
|         runParserT | 
 | ||||||
|            (evalStateT |   -- set child state | ||||||
|               (choiceInState |   setInput childInput | ||||||
|                  [journalp |   pushPosition $ initialPos filepath | ||||||
|                  ,timeclockfilep |   put childj | ||||||
|                  ,timedotfilep | 
 | ||||||
|                  -- can't include a csv file yet, that reader is special |   -- parse include file | ||||||
|                  ]) |   let parsers = [ journalp | ||||||
|               childj) |                 , timeclockfilep | ||||||
|            filepath txt |                 , timedotfilep | ||||||
|       either |                 ] -- can't include a csv file yet, that reader is special | ||||||
|         (throwError |   updatedChildj <- journalAddFile (filepath, childInput) <$> | ||||||
|           . ((show parentpos ++ " in included file " ++ show filename ++ ":\n") ++) |                    region (withSource childInput) (choiceInState parsers) | ||||||
|           . parseErrorPretty) | 
 | ||||||
|         (return . journalAddFile (filepath, txt)) |   -- restore parent state, prepending the child's parse info | ||||||
|         ej1 |   setParserState parentParserState | ||||||
|   case ej of |   put $ updatedChildj <> parentj | ||||||
|     Left e       -> throwError e |   -- discard child's parse info, prepend its (reversed) list data, combine other fields | ||||||
|     Right childj -> modify' (\parentj -> childj <> parentj) | 
 | ||||||
|     -- discard child's parse info, prepend its (reversed) list data, combine other fields |   void newline | ||||||
|  | 
 | ||||||
| 
 | 
 | ||||||
| newJournalWithParseStateFrom :: Journal -> Journal | newJournalWithParseStateFrom :: Journal -> Journal | ||||||
| newJournalWithParseStateFrom j = mempty{ | newJournalWithParseStateFrom j = mempty{ | ||||||
| @ -234,11 +238,12 @@ newJournalWithParseStateFrom j = mempty{ | |||||||
| 
 | 
 | ||||||
| -- | Lift an IO action into the exception monad, rethrowing any IO | -- | Lift an IO action into the exception monad, rethrowing any IO | ||||||
| -- error with the given message prepended. | -- error with the given message prepended. | ||||||
| orRethrowIOError :: IO a -> String -> ExceptT String IO a | orRethrowIOError :: MonadIO m => IO a -> String -> TextParser m a | ||||||
| orRethrowIOError io msg = | orRethrowIOError io msg = do | ||||||
|   ExceptT $ |   eResult <- liftIO $ (Right <$> io) `C.catch` \(e::C.IOException) -> pure $ Left $ printf "%s:\n%s" msg (show e) | ||||||
|     (Right <$> io) |   case eResult of | ||||||
|     `C.catch` \(e::C.IOException) -> return $ Left $ printf "%s:\n%s" msg (show e) |     Right res -> pure res | ||||||
|  |     Left errMsg -> fail errMsg | ||||||
| 
 | 
 | ||||||
| accountdirectivep :: JournalParser m () | accountdirectivep :: JournalParser m () | ||||||
| accountdirectivep = do | accountdirectivep = do | ||||||
|  | |||||||
| @ -83,7 +83,7 @@ reader = Reader | |||||||
| parse :: InputOpts -> FilePath -> Text -> ExceptT String IO Journal | parse :: InputOpts -> FilePath -> Text -> ExceptT String IO Journal | ||||||
| parse = parseAndFinaliseJournal timeclockfilep | parse = parseAndFinaliseJournal timeclockfilep | ||||||
| 
 | 
 | ||||||
| timeclockfilep :: ErroringJournalParser IO ParsedJournal | timeclockfilep :: MonadIO m => ErroringJournalParser m ParsedJournal | ||||||
| timeclockfilep = do many timeclockitemp | timeclockfilep = do many timeclockitemp | ||||||
|                     eof |                     eof | ||||||
|                     j@Journal{jparsetimeclockentries=es} <- get |                     j@Journal{jparsetimeclockentries=es} <- get | ||||||
|  | |||||||
		Loading…
	
		Reference in New Issue
	
	Block a user