mirror of
https://github.com/zoriya/HAL.git
synced 2026-05-30 20:51:00 +00:00
Handling quotes (without the read syntax)
This commit is contained in:
@@ -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
@@ -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
@@ -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 (== ')')
|
||||
|
||||
Reference in New Issue
Block a user