|
@@ -1,26 +1,22 @@
|
|
|
{-# LANGUAGE ViewPatterns #-}
|
|
|
{-# LANGUAGE OverloadedStrings #-}
|
|
|
|
|
|
-module Data.SCargot.General
|
|
|
- (
|
|
|
- SExprSpec
|
|
|
- , mkSpec
|
|
|
- , convertSpec
|
|
|
+module Data.SCargot.Parse
|
|
|
+ (
|
|
|
+ decode
|
|
|
+ , decodeOne
|
|
|
+
|
|
|
+ , SExprParser
|
|
|
+ , Reader
|
|
|
+ , Comment
|
|
|
+ , mkParser
|
|
|
+ , setCarrier
|
|
|
, addReader
|
|
|
, setComment
|
|
|
-
|
|
|
+
|
|
|
, asRich
|
|
|
, asWellFormed
|
|
|
, withQuote
|
|
|
-
|
|
|
- , decode
|
|
|
- , decodeOne
|
|
|
- , encode
|
|
|
- , encodeOne
|
|
|
-
|
|
|
- , Reader
|
|
|
- , Comment
|
|
|
- , Serializer
|
|
|
) where
|
|
|
|
|
|
import Control.Applicative ((<*), (*>), (<*>), (<$>), pure)
|
|
@@ -63,87 +59,69 @@ type Reader atom = (Parser (SExpr atom) -> Parser (SExpr atom))
|
|
|
|
|
|
|
|
|
|
|
|
+
|
|
|
+
|
|
|
type Comment = Parser ()
|
|
|
|
|
|
-type Serializer atom = atom -> Text
|
|
|
-
|
|
|
-data SExprSpec atom carrier = SExprSpec
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+data SExprParser atom carrier = SExprParser
|
|
|
{ sesPAtom :: Parser atom
|
|
|
- , sesSAtom :: Serializer atom
|
|
|
, readerMap :: ReaderMacroMap atom
|
|
|
, comment :: Maybe Comment
|
|
|
, postparse :: SExpr atom -> Either String carrier
|
|
|
- , preserial :: carrier -> SExpr atom
|
|
|
}
|
|
|
|
|
|
+
|
|
|
+
|
|
|
|
|
|
-mkSpec :: Parser atom -> Serializer atom -> SExprSpec atom (SExpr atom)
|
|
|
-mkSpec p s = SExprSpec
|
|
|
- { sesPAtom = p <?> "atom"
|
|
|
- , sesSAtom = s
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+mkParser :: Parser atom -> SExprParser atom (SExpr atom)
|
|
|
+mkParser parser = SExprParser
|
|
|
+ { sesPAtom = parser
|
|
|
, readerMap = M.empty
|
|
|
, comment = Nothing
|
|
|
, postparse = return
|
|
|
- , preserial = id
|
|
|
}
|
|
|
|
|
|
+
|
|
|
|
|
|
|
|
|
|
|
|
+
|
|
|
|
|
|
-convertSpec :: (b -> Either String c) -> (c -> b)
|
|
|
- -> SExprSpec a b -> SExprSpec a c
|
|
|
-convertSpec f g spec = spec
|
|
|
- { postparse = postparse spec >=> f
|
|
|
- , preserial = preserial spec . g
|
|
|
- }
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+setCarrier :: (b -> Either String c) -> SExprParser a b -> SExprParser a c
|
|
|
+setCarrier f spec = spec { postparse = postparse spec >=> f }
|
|
|
|
|
|
|
|
|
|
|
|
-asRich :: SExprSpec a (SExpr b) -> SExprSpec a (RichSExpr b)
|
|
|
-asRich = convertSpec (return . toRich) fromRich
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+asRich :: SExprParser a (SExpr b) -> SExprParser a (RichSExpr b)
|
|
|
+asRich = setCarrier (return . toRich)
|
|
|
|
|
|
|
|
|
|
|
|
-asWellFormed :: SExprSpec a (SExpr b) -> SExprSpec a (WellFormedSExpr b)
|
|
|
-asWellFormed = convertSpec toWellFormed fromWellFormed
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+asWellFormed :: SExprParser a (SExpr b) -> SExprParser a (WellFormedSExpr b)
|
|
|
+asWellFormed = setCarrier toWellFormed
|
|
|
|
|
|
|
|
|
|
|
@@ -152,16 +130,13 @@ asWellFormed = convertSpec toWellFormed fromWellFormed
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
-addReader :: Char -> Reader a -> SExprSpec a c -> SExprSpec a c
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+addReader :: Char -> Reader a -> SExprParser a c -> SExprParser a c
|
|
|
addReader c reader spec = spec
|
|
|
{ readerMap = M.insert c reader (readerMap spec) }
|
|
|
|
|
@@ -171,23 +146,25 @@ addReader c reader spec = spec
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
|
|
|
-setComment :: Comment -> SExprSpec a c -> SExprSpec a c
|
|
|
+setComment :: Comment -> SExprParser a c -> SExprParser a c
|
|
|
setComment c spec = spec { comment = Just (c <?> "comment") }
|
|
|
|
|
|
-withQuote :: IsString t => SExprSpec t (SExpr t) -> SExprSpec t (SExpr t)
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+withQuote :: IsString t => SExprParser t (SExpr t) -> SExprParser t (SExpr t)
|
|
|
withQuote = addReader '\'' (fmap go)
|
|
|
where go s = SCons "quote" (SCons s SNil)
|
|
|
|
|
@@ -250,17 +227,17 @@ doParse p t = case runParser p () "" t of
|
|
|
|
|
|
|
|
|
|
|
|
-decodeOne :: SExprSpec atom carrier -> Text -> Either String carrier
|
|
|
+decodeOne :: SExprParser atom carrier -> Text -> Either String carrier
|
|
|
decodeOne spec = doParse (parser <* eof) >=> (postparse spec)
|
|
|
where parser = parseGenericSExpr
|
|
|
(sesPAtom spec)
|
|
|
(readerMap spec)
|
|
|
(buildSkip (comment spec))
|
|
|
|
|
|
+
|
|
|
|
|
|
|
|
|
-decode :: SExprSpec atom carrier -> Text -> Either String [carrier]
|
|
|
+decode :: SExprParser atom carrier -> Text -> Either String [carrier]
|
|
|
decode spec =
|
|
|
doParse (many1 parser <* eof) >=> mapM (postparse spec)
|
|
|
where parser = parseGenericSExpr
|
|
@@ -268,6 +245,7 @@ decode spec =
|
|
|
(readerMap spec)
|
|
|
(buildSkip (comment spec))
|
|
|
|
|
|
+
|
|
|
|
|
|
encodeSExpr :: SExpr atom -> (atom -> Text) -> Text
|
|
|
encodeSExpr SNil _ = "()"
|
|
@@ -279,8 +257,9 @@ encodeSExpr (SCons x xs) t = go xs (encodeSExpr x t)
|
|
|
|
|
|
|
|
|
|
|
|
-encodeOne :: SExprSpec atom carrier -> carrier -> Text
|
|
|
+encodeOne :: SExprParser atom carrier -> carrier -> Text
|
|
|
encodeOne spec c = encodeSExpr (preserial spec c) (sesSAtom spec)
|
|
|
|
|
|
-encode :: SExprSpec atom carrier -> [carrier] -> Text
|
|
|
+encode :: SExprParser atom carrier -> [carrier] -> Text
|
|
|
encode spec cs = T.concat (map (encodeOne spec) cs)
|
|
|
+-}
|