0

私はこのスキーム インタープリター チュートリアルに従っています: http://en.wikibooks.org/wiki/Write_Yourself_a_Scheme_in_48_Hours/

しかし、ソースファイル全体を解釈する機能を持つことができるように、REPL または Parsec をセットアップする方法を理解できないようです。私がやりたいのは、REPL から次のようなものを入力できるようにすることです。

:l ~/myscheme.scm

そして、ファイルは解釈されます。現時点では、1 つの式を解析するだけで、残りは無視されます。なぜそうなのかはわかります -- readExpr は 1 つの式だけを読み取ります。

パーサーの抜粋、コード全体はこちらにあります: 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"

交換:

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"

助けていただければ幸いです!

4

1 に答える 1

2

parse (many parseExpr)の代わりにいかがparse parseExprですか?

次に、式のリストを解釈できるようにインタープリターを修正する必要があります。

于 2013-03-30T21:07:08.863 に答える