1
1
mirror of https://github.com/kanaka/mal.git synced 2024-10-26 14:22:25 +03:00
mal/impls/haskell/step1_read_print.hs
Nicolas Boulenguez c9c504ac20 haskell: make grammar readable as reference, misc
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.
2021-07-11 17:38:14 -06:00

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