packages feed

egison-2.3.9: hs-src/Interpreter/egisoni.hs

module Main where
import Language.Egison.Core      -- Egison Interpreter
import Language.Egison.Parser
import Language.Egison.Types     -- Egison data types
import Language.Egison.Variables -- Egison variable operations
import Control.Monad.Error
import System.IO
import System.Environment
import System.Console.Haskeline
import Text.Regex.Posix

main :: IO ()
main = do args <- getArgs
          if null args then do showBanner
                               runRepl
                       else runOne $ args

-- REPL Section
flushStr :: String -> IO ()
flushStr str = putStr str >> hFlush stdout

-- |Execute a single egison file from the command line
runOne :: [String] -> IO ()
runOne args = do
  env <- primitiveBindings
  -- Load standard library
  _ <- loadLibraries env
  result <- runIOThrows $ liftM show $ evalTopExpr env $ Load (args !! 0)
  case result of
    Just errMsg -> putStrLn errMsg
    _  -> do 
      -- Call into (main) if it exists...
      alreadyDefined <- liftIO $ isBound env ("main", [])
      when alreadyDefined (do
        mainResult <- runIOThrows $ liftM show $ evalMain env $ args
        case mainResult of
          Just errMsg -> putStrLn errMsg
          _  -> return ())

-- |Start the REPL (interactive interpreter)
runRepl :: IO ()
runRepl = do
    env <- primitiveBindings
    _ <- loadLibraries env
    runInputT defaultSettings (loop env "> " "")
    where
        loop :: Env -> String -> String -> InputT IO ()
        loop env prompt input0 = do
            minput <- getInputLine prompt
            case minput of
                Nothing -> liftIO showByebyeMessage
                Just "" -> if input0 == ""
                             then loop env "> " ""
                             else loop env "  " (input0 ++ "\n")
                Just input -> do
                  let newInput = input0 ++ input
                  let eTopExpr = readTopExpr newInput
                  case eTopExpr of
                    Left e -> do
                      if show e =~ "unexpected end of input" -- Is this really OK?
                        then loop env "  " $ newInput ++ "\n"
                        else do liftIO $ putStrLn $ show e
                                loop env "> " ""
                    Right _ -> do
                      result <- liftIO (evalString env newInput)
                      if (length result) > 0
                        then do outputStrLn result
                                loop env "> " ""
                        else loop env "> " ""