mirror of
https://github.com/kanaka/mal.git
synced 2024-10-26 14:22:25 +03:00
c9c504ac20
Split user functions and macros, merge user functions and core functions. Add a flag triggering debugging info in EVAL. Reserve mutable environments for REPL and let*. Move env type declaration from Types to Env. Check let* arguments only once. Share more code between map constructions and key type checks. Stop copying metadata when evaluating collections. The strict variant of Data.Map.Strict is recommended for general use. simplify printer.
50 lines
1008 B
Haskell
50 lines
1008 B
Haskell
import System.IO (hFlush, stdout)
|
|
import Control.Monad.Except (liftIO, runExceptT)
|
|
|
|
import Readline (addHistory, readline, load_history)
|
|
import Types
|
|
import Reader (read_str)
|
|
import Printer (_pr_str)
|
|
|
|
-- read
|
|
|
|
mal_read :: String -> IOThrows MalVal
|
|
mal_read = read_str
|
|
|
|
-- eval
|
|
|
|
eval :: MalVal -> MalVal
|
|
eval = id
|
|
|
|
-- print
|
|
|
|
mal_print :: MalVal -> IOThrows String
|
|
mal_print = liftIO . Printer._pr_str True
|
|
|
|
-- repl
|
|
|
|
rep :: String -> IOThrows String
|
|
rep line = mal_print =<< (eval <$> mal_read line)
|
|
|
|
repl_loop :: IO ()
|
|
repl_loop = do
|
|
line <- readline "user> "
|
|
case line of
|
|
Nothing -> return ()
|
|
Just "" -> repl_loop
|
|
Just str -> do
|
|
addHistory str
|
|
res <- runExceptT $ rep str
|
|
out <- case res of
|
|
Left mv -> (++) "Error: " <$> liftIO (Printer._pr_str True mv)
|
|
Right val -> return val
|
|
putStrLn out
|
|
hFlush stdout
|
|
repl_loop
|
|
|
|
main :: IO ()
|
|
main = do
|
|
load_history
|
|
|
|
repl_loop
|