daily pastebin goal
6%
SHARE
TWEET

Untitled

a guest Apr 16th, 2018 48 Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. module Main where
  2. import Text.ParserCombinators.Parsec
  3. import System.Environment
  4. import System.IO
  5. import Control.Monad
  6.  
  7. -- Lisp Value Data Type
  8. data LispVal = Atom String
  9.  
  10. instance Show LispVal where show = showVal
  11.  
  12. showVal :: LispVal -> String
  13. showVal (Atom name) = name
  14.  
  15. -- Parsers
  16. readExpr :: String -> LispVal
  17. readExpr input = case (parse parseExpr "lisp" input) of
  18.   Left err  -> Atom $ "No match: " ++ show err
  19.   Right val -> val
  20.  
  21. parseExpr :: Parser LispVal
  22. parseExpr = parseAtom
  23.  
  24. symbol :: Parser Char
  25. symbol = oneOf "!#$%&|*+-/:<=>?@^_~"
  26.  
  27. parseAtom :: Parser LispVal
  28. parseAtom = do {
  29.     first <- (letter <|> symbol);
  30.     rest <- many (letter <|> digit <|> symbol);
  31.     return $ Atom (first:rest);
  32. }
  33.  
  34.  
  35. -- Evaluator
  36. eval :: LispVal -> LispVal
  37. eval lispVal = lispVal
  38.  
  39.  
  40. -- Repl
  41. readPrompt :: String -> IO String
  42. readPrompt prompt = putStr prompt >> hFlush stdout >> getLine
  43.  
  44. readEvalPrint :: String -> IO()
  45. readEvalPrint = putStrLn . show . eval . readExpr
  46.  
  47. loopUntil :: (a -> Bool) -> IO a -> (a -> IO ()) -> IO ()
  48. loopUntil pred prompt action = do {
  49.     x <- prompt;
  50.     if pred x
  51.       then return ()
  52.       else (action x >> loopUntil pred prompt action)
  53. }
  54.  
  55. -- main
  56. main :: IO ()
  57. main = loopUntil (== "quit") (readPrompt ">> ") readEvalPrint
RAW Paste Data
Top