0

I'm following this scheme interpreter tutorial: http://en.wikibooks.org/wiki/Write_Yourself_a_Scheme_in_48_Hours/

but can't seem to figure out how to setup the REPL or Parsec so I can have the functionality to interpret a whole source file. What I'd like to do is to be able to enter something like this from the REPL:

:l ~/myscheme.scm

And the file would be interpreted. Right now, all it does is parse one expression and it ignores the rest. I can see why this is so -- readExpr reads only 1 expression.

Parser excerpt, whole code can be found here: http://en.wikibooks.org/wiki/Write_Yourself_a_Scheme_in_48_Hours/Parsing

 parseExpr :: Parser LispVal
 parseExpr = parseAtom
         <|> parseString
         <|> parseNumber
         <|> parseQuoted
         <|> do char '('
                x <- try parseList <|> parseDottedList
                char ')'
                return x

 readExpr :: String -> String
 readExpr input = case parse parseExpr "lisp" input of
     Left err -> "No match: " ++ show err
     Right _ -> "Found value"

REPL:

import System.IO

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

readPrompt :: String -> IO String
readPrompt prompt = flushStr prompt >> getLine

evalString :: String -> IO String
evalString expr = return $ extractValue $ trapError (liftM show $ readExpr expr >>= eval) 

evalAndPrint :: String -> IO ()
evalAndPrint expr =  evalString expr >>= putStrLn

until_ :: Monad m => (a -> Bool) -> m a -> (a -> m ()) -> m ()
until_ pred prompt action = do 
  result <- prompt
  if pred result 
     then return ()
     else action result >> until_ pred prompt action

runRepl :: IO ()
runRepl = until_ (== "quit") (readPrompt "Lisp>>> ") evalAndPrint

main :: IO ()
main = do args <- getArgs
          case length args of
              0 -> runRepl
              1 -> evalAndPrint $ args !! 0
              otherwise -> putStrLn "Program takes only 0 or 1 argument"

Would appreciate any help!

4

1 回答 1

2

How about parse (many parseExpr) instead of parse parseExpr?

You then will have to amend the interpreter so that it can interpret a list of expressions.

于 2013-03-30T21:07:08.863 回答