diff --git a/app/Main.hs b/app/Main.hs index f7bc506..1815576 100644 --- a/app/Main.hs +++ b/app/Main.hs @@ -13,7 +13,7 @@ main = runInputT defaultSettings (loop $ []) where loop :: LispEnv -> InputT IO () loop env = do - minput <- getInputLine " > " + minput <- getInputLine "> " case minput of Nothing -> return () Just "exit" -> return () diff --git a/src/BasicParser.hs b/src/BasicParser.hs index 45ce591..0ced647 100644 --- a/src/BasicParser.hs +++ b/src/BasicParser.hs @@ -1,7 +1,7 @@ module BasicParser where import Control.Applicative ( Alternative(..) ) -import Data.Char ( isDigit, isNumber, isSpace ) +import Data.Char ( isDigit, isNumber, isSpace, isAlphaNum ) import Text.Read ( readMaybe ) data Parser a = Parser { @@ -64,7 +64,7 @@ pString (x:xs) = do pString [] = pure "" pToken :: Parser String -pToken = pUntil $ \x -> isSpace x || x == ')' || x == '(' +pToken = pUntil (not . isAlphaNum) pDigit :: Parser Char pDigit = pCharIf isDigit diff --git a/src/LispParser.hs b/src/LispParser.hs index b6a2378..27aa5ea 100644 --- a/src/LispParser.hs +++ b/src/LispParser.hs @@ -4,6 +4,7 @@ import BasicParser ( Parser, pCharIf, pUntil, pInt, pFloat, tokenify, pToken, pString ) import Expressions ( SExpr(..), Atom(..), Statement(..) ) import Control.Applicative ( Alternative(some, (<|>)) ) +import Debug.Trace _pAtom :: Parser Atom _pAtom = AInt <$> pInt @@ -28,9 +29,26 @@ pAtom = (pCharIf (== '\'') *> pQuotedAtom) -- but I believe that this is not really a feature. pQuotedAtom :: Parser Atom pQuotedAtom = ANil <$ pString "()" - <|> pCharIf (== '\'') *> ((\x -> ACons (ASymbol "quote") (ACons x ANil)) <$> pQuotedAtom) + <|> pCharIf (== '\'') *> + ((\x -> ACons (ASymbol "quote") (ACons x ANil)) <$> pQuotedAtom) + <|> pCharIf (== '(') *> pConsReadExpr <*pCharIf (== ')') <|> AQuote <$> _pAtom +pConsReadExpr :: Parser Atom +pConsReadExpr = + do + fs <- tokenify pQuotedAtom + se <- tokenify pConsReadExpr + return $ ACons fs se + <|> do + fs <- tokenify pQuotedAtom + tokenify $ pCharIf (== '.') + se <- tokenify pQuotedAtom + return $ ACons fs se + <|> do + fs <- tokenify pQuotedAtom + return $ ACons fs ANil + pSExpr :: Parser SExpr pSExpr = pCharIf (== '(') *> (SExpr <$> some (tokenify pStatement)) <* pCharIf (== ')')