Handling quotes (without the read syntax)

This commit is contained in:
Zoe Roux
2021-11-04 17:04:40 +01:00
parent 67359c3e8f
commit a46e29261a
3 changed files with 37 additions and 8 deletions
+7
View File
@@ -56,6 +56,13 @@ pCharIf predicate = Parser subParse
pUntil :: (Char -> Bool) -> Parser String
pUntil predicate = some $ pCharIf (not . predicate)
pString :: String -> Parser String
pString (x:xs) = do
c <- pCharIf (== x)
str <- pString xs
return (c:str)
pString [] = pure ""
pToken :: Parser String
pToken = pUntil $ \x -> isSpace x || x == ')' || x == '('
+5 -2
View File
@@ -6,7 +6,8 @@ data Atom =
AString String |
AFloat Float |
ACons Atom Atom |
ANil
ANil |
AQuote Atom
newtype SExpr = SExpr [Statement]
@@ -15,7 +16,9 @@ instance Show Atom where
show (ASymbol symb) = symb
show (AString str) = "\"" ++ str ++ "\""
show (AFloat float) = show float
show ANil = "nil"
show (AQuote atom) = show atom
show ANil = "()"
show (ACons (ASymbol "quote") (ACons fi ANil)) = "'" ++ show fi
show (ACons fi se) = "(" ++ showCon fi se ++ ")"
where
showCon :: Atom -> Atom -> String
+25 -6
View File
@@ -1,16 +1,35 @@
module LispParser where
import BasicParser
( Parser, pCharIf, pUntil, pInt, pFloat, tokenify, pToken )
( Parser, pCharIf, pUntil, pInt, pFloat, tokenify, pToken, pString )
import Expressions ( SExpr(..), Atom(..), Statement(..) )
import Control.Applicative ( Alternative(some, (<|>)) )
_pAtom :: Parser Atom
_pAtom = AInt <$> pInt
<|> AFloat <$> pFloat
<|> pCharIf (== '"') *> (AString <$> pUntil (== '"')) <* pCharIf (== '"')
<|> ANil <$ pString "nil"
<|> ASymbol <$> pToken
pAtom :: Parser Atom
pAtom =
AInt <$> pInt <|>
AFloat <$> pFloat <|>
pCharIf (== '"') *> (AString <$> pUntil (== '"')) <* pCharIf (== '"') <|>
ASymbol <$> pToken
pAtom = (pCharIf (== '\'') *> pQuotedAtom)
<|> _pAtom
-- handle read syntax for:
-- - (1 2 3)
-- - (1 . 2)
-- - (1 2 3 . 4)
-- - (1 2 '3 . 4)
-- - '3
-- - '()
-- WARNING, doing (cons 'quote (cons 3 nil)) create a Cons (Quote (Symbol 'quote'), 3, nil)
-- so the result is printed as (quote 3) and not '3. Chez-Scheme print this as '3
-- 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)
<|> AQuote <$> _pAtom
pSExpr :: Parser SExpr
pSExpr = pCharIf (== '(') *> (SExpr <$> some (tokenify pStatement)) <* pCharIf (== ')')