module System.REPL import System.File ||| A basic read-eval-print loop, maintaining a state ||| @ state the input state ||| @ prompt the prompt to show ||| @ onInput the function to run on reading input, returning a String to ||| output and a new state. Returns Nothing if the repl should exit export replWith : MonadIO io => (state : a) -> (prompt : String) -> (onInput : a -> String -> Maybe (String, a)) -> io () replWith acc prompt fn = do eof <- fEOF stdin if eof then pure () else do putStr prompt fflush stdout x <- getLine case fn acc x of Just (out, acc') => do putStr out replWith acc' prompt fn Nothing => pure () ||| A basic read-eval-print loop ||| @ prompt the prompt to show ||| @ onInput the function to run on reading input, returning a String to ||| output export repl : MonadIO io => (prompt : String) -> (onInput : String -> String) -> io () repl prompt fn = replWith () prompt (\x, s => Just (fn s, ()))