2024-12-20 11:38:09 -06:00
|
|
|
module REPL where
|
|
|
|
|
|
|
|
import Eval
|
2025-01-01 18:05:21 -06:00
|
|
|
import FileEval
|
2024-12-20 11:38:09 -06:00
|
|
|
import Lexer
|
|
|
|
import Parser
|
|
|
|
import Research
|
|
|
|
|
2024-12-29 20:29:41 -06:00
|
|
|
import Control.Exception (SomeException, catch)
|
|
|
|
import Control.Monad.IO.Class (liftIO)
|
2025-01-27 16:46:41 -06:00
|
|
|
import Control.Monad.Catch (handle, MonadCatch)
|
2025-01-02 19:08:14 -06:00
|
|
|
import Data.Char (isSpace)
|
|
|
|
import Data.List (dropWhile, dropWhileEnd, intercalate)
|
2024-12-27 20:46:30 -06:00
|
|
|
import System.Console.Haskeline
|
2024-12-29 20:29:41 -06:00
|
|
|
|
|
|
|
import qualified Data.Map as Map
|
2024-12-20 11:38:09 -06:00
|
|
|
|
2024-12-29 21:49:57 -06:00
|
|
|
repl :: Env -> IO ()
|
2025-01-27 16:46:41 -06:00
|
|
|
repl env = runInputT defaultSettings (withInterrupt (loop env))
|
2024-12-27 20:46:30 -06:00
|
|
|
where
|
2024-12-29 21:49:57 -06:00
|
|
|
loop :: Env -> InputT IO ()
|
2025-01-27 16:46:41 -06:00
|
|
|
loop env = handle (interruptHandler env) $ do
|
2024-12-29 08:29:25 -06:00
|
|
|
minput <- getInputLine "tricu < "
|
2025-01-27 16:46:41 -06:00
|
|
|
case minput of
|
|
|
|
Nothing -> outputStrLn "Exiting tricu"
|
|
|
|
Just s
|
|
|
|
| strip s == "!exit" -> outputStrLn "Exiting tricu"
|
|
|
|
| strip s == "" -> loop env
|
|
|
|
| strip s == "!import" -> do
|
|
|
|
path <- getInputLine "File path to load < "
|
|
|
|
case path of
|
|
|
|
Nothing -> do
|
|
|
|
outputStrLn "No input received; stopping import."
|
|
|
|
loop env
|
|
|
|
Just p -> do
|
|
|
|
loadedEnv <- liftIO $ evaluateFileWithContext env
|
|
|
|
(strip p) `catch` \e -> errorHandler env e
|
|
|
|
loop $ Map.delete "!result" (Map.union loadedEnv env)
|
|
|
|
| take 2 s == "--" -> loop env
|
|
|
|
| otherwise -> do
|
2025-01-19 14:41:25 -06:00
|
|
|
newEnv <- liftIO $ processInput env s `catch` errorHandler env
|
|
|
|
loop newEnv
|
|
|
|
|
2025-01-27 16:46:41 -06:00
|
|
|
interruptHandler :: Env -> Interrupt -> InputT IO ()
|
|
|
|
interruptHandler env _ = do
|
|
|
|
outputStrLn "Interrupted with CTRL+C\n\
|
|
|
|
\You can use the !exit command or CTRL+D to exit"
|
|
|
|
loop env
|
|
|
|
|
2024-12-30 14:19:43 -06:00
|
|
|
processInput :: Env -> String -> IO Env
|
2024-12-29 20:29:41 -06:00
|
|
|
processInput env input = do
|
2025-01-19 14:41:25 -06:00
|
|
|
let asts = parseTricu input
|
2024-12-30 14:19:43 -06:00
|
|
|
newEnv = evalTricu env asts
|
2025-01-19 14:41:25 -06:00
|
|
|
if
|
2025-01-27 16:04:04 -06:00
|
|
|
| Just r <- Map.lookup "!result" newEnv -> do
|
2025-01-02 19:08:14 -06:00
|
|
|
putStrLn $ "tricu > " ++ decodeResult r
|
2025-01-19 14:41:25 -06:00
|
|
|
| otherwise -> return ()
|
2024-12-29 20:29:41 -06:00
|
|
|
return newEnv
|
2024-12-30 14:19:43 -06:00
|
|
|
|
2024-12-29 21:49:57 -06:00
|
|
|
errorHandler :: Env -> SomeException -> IO (Env)
|
2024-12-29 20:29:41 -06:00
|
|
|
errorHandler env e = do
|
|
|
|
putStrLn $ "Error: " ++ show e
|
|
|
|
return env
|
2025-01-02 19:08:14 -06:00
|
|
|
|
|
|
|
strip :: String -> String
|
|
|
|
strip = dropWhileEnd isSpace . dropWhile isSpace
|