Guest User

Untitled

a guest
Apr 16th, 2018
73
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 1.48 KB | None | 0 0
  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. | List [LispVal]
  10.  
  11. instance Show LispVal where show = showVal
  12.  
  13. showVal :: LispVal -> String
  14. showVal (Atom name) = name
  15. showVal (List contents) = "(" ++ (unwords $ map show contents) ++ ")"
  16.  
  17. -- Parsers
  18. readExpr :: String -> LispVal
  19. readExpr input = case (parse parseExpr "lisp" input) of
  20. Left err -> Atom $ "No match: " ++ show err
  21. Right val -> val
  22.  
  23. parseExpr :: Parser LispVal
  24. parseExpr = parseAtom
  25. <|> parseList
  26.  
  27. symbol :: Parser Char
  28. symbol = oneOf "!#$%&|*+-/:<=>?@^_~"
  29.  
  30. parseAtom :: Parser LispVal
  31. parseAtom = do {
  32. first <- (letter <|> symbol);
  33. rest <- many (letter <|> digit <|> symbol);
  34. return $ Atom (first:rest);
  35. }
  36.  
  37. parseList :: Parser LispVal
  38. parseList = do {
  39. char '(';
  40. xs <- sepBy parseExpr (skipMany1 space);
  41. char ')';
  42. return $ List xs;
  43. }
  44.  
  45. -- Evaluator
  46. eval :: LispVal -> LispVal
  47. eval lispVal = lispVal
  48.  
  49. -- Repl
  50. readPrompt :: String -> IO String
  51. readPrompt prompt = putStr prompt >> hFlush stdout >> getLine
  52.  
  53. readEvalPrint :: String -> IO()
  54. readEvalPrint = putStrLn . show . eval . readExpr
  55.  
  56. loopUntil :: (a -> Bool) -> IO a -> (a -> IO ()) -> IO ()
  57. loopUntil pred prompt action = do {
  58. x <- prompt;
  59. if pred x
  60. then return ()
  61. else (action x >> loopUntil pred prompt action)
  62. }
  63.  
  64. -- main
  65. main :: IO ()
  66. main = loopUntil (== "quit") (readPrompt ">> ") readEvalPrint
Add Comment
Please, Sign In to add comment