我正在关注此计划解释器教程:http://en.wikibooks.org/wiki/Write_Yourself_a_Scheme_in_48_Hours/
但似乎无法弄清楚如何设置REPL或Parsec所以我可以具有解释整个源文件的功能。我想做的是能够从REPL中输入这样的内容:
:l ~/myscheme.scm
该文件将被解释。现在,它所做的就是解析一个表达式而忽略其余的表达式。我可以看出为什么会这样 - readExpr只读取1个表达式。
Parser摘录,整个代码可以在这里找到: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"
非常感谢任何帮助!
答案 0 :(得分:2)
parse (many parseExpr)
而不是parse parseExpr
呢?
然后,您必须修改解释器,以便它可以解释表达式列表。