/src/Main.hs

http://github.com/vito/hummus · Haskell · 81 lines · 62 code · 17 blank · 2 comment · 10 complexity · ba7e117a595c894ecc90a4079a80121a MD5 · raw file

  1. {-# LANGUAGE OverloadedStrings, RankNTypes #-}
  2. module Main where
  3. import Control.Monad.Trans
  4. import Data.Attoparsec
  5. import Prelude hiding (catch)
  6. import System.Console.Haskeline
  7. import System.Environment (getArgs, getEnv)
  8. import System.FilePath ((</>))
  9. import qualified Data.ByteString as BS
  10. import Hummus.Types
  11. import Hummus.Parser
  12. import Hummus.Runtime
  13. import qualified Hummus.Prelude as Prelude
  14. main :: IO ()
  15. main = do
  16. as <- getArgs
  17. runVM $ do
  18. Prelude.fromGround $ \e -> do
  19. case as of
  20. [] -> do
  21. home <- liftIO (getEnv "HOME")
  22. runInputT
  23. (defaultSettings { historyFile = Just (home </> ".hummus_history") })
  24. (repl "" e)
  25. [f] -> do
  26. s <- liftIO (BS.readFile f)
  27. case parseOnly sexps s of
  28. Right ss -> mapM_ (evaluate e) ss
  29. Left m -> error m
  30. _ -> error "unknown argument form"
  31. return Inert
  32. return ()
  33. -- TODO: super hacky
  34. instance MonadException (VM ans) where
  35. catch x _ = x -- TODO
  36. block x = x -- TODO
  37. unblock x = x -- TODO
  38. repl :: String -> Value ans -> InputT (VM ans) ()
  39. repl p e = do
  40. mi <- getInputLine (if null p then "Hummus> " else "....... ")
  41. case mi of
  42. Just i ->
  43. case parse sexps (BS.pack . map (toEnum . fromEnum) $ p ++ i) of
  44. Done _ ss -> finish ss
  45. Fail rest context message -> do
  46. outputStrLn "Parse error!"
  47. outputStrLn ("at: " ++ show rest)
  48. if not (null context)
  49. then outputStrLn "Context:"
  50. else return ()
  51. mapM_ (outputStrLn . (" " ++)) context
  52. outputStrLn message
  53. repl "" e
  54. Partial f ->
  55. case f "" of
  56. Done _ ss -> finish ss
  57. _ -> repl (p ++ i ++ "\n") e
  58. Nothing -> return ()
  59. where
  60. finish ss = do
  61. v <- lift (evaluateSequence e ss)
  62. String s <- lift (evaluate e (Pair (Symbol "send") (Pair v (Pair (Symbol "->string") Null))))
  63. outputStrLn s
  64. repl "" e