module REPL where import Eval import FileEval import Lexer import Parser import Research import Control.Exception (SomeException, catch) import Control.Monad.IO.Class (liftIO) import Data.Char (isSpace) import Data.List (dropWhile, dropWhileEnd, intercalate) import System.Console.Haskeline import qualified Data.Map as Map repl :: Env -> IO () repl env = runInputT defaultSettings (loop env) where loop :: Env -> InputT IO () loop env = do minput <- getInputLine "tricu < " if | Nothing <- minput -> outputStrLn "Exiting tricu" | Just s <- minput, strip s == "!exit" -> outputStrLn "Exiting tricu" | Just s <- minput, strip s == "" -> do outputStrLn "" loop env | Just s <- minput, strip s == "!import" -> do path <- getInputLine "File path to load < " if | Nothing <- path -> do outputStrLn "No input received; stopping import." loop env | Just p <- path -> do loadedEnv <- liftIO $ evaluateFileWithContext env (strip p) `catch` \e -> errorHandler env e loop $ Map.delete "!result" (Map.union loadedEnv env) | Just s <- minput -> do if | take 2 s == "--" -> loop env | otherwise -> do newEnv <- liftIO $ processInput env s `catch` errorHandler env loop newEnv processInput :: Env -> String -> IO Env processInput env input = do let asts = parseTricu input newEnv = evalTricu env asts if | Just r <- Map.lookup "!result" newEnv -> do putStrLn $ "tricu > " ++ decodeResult r | otherwise -> return () return newEnv errorHandler :: Env -> SomeException -> IO (Env) errorHandler env e = do putStrLn $ "Error: " ++ show e return env strip :: String -> String strip = dropWhileEnd isSpace . dropWhile isSpace