stdata 0.0.3 → 0.0.4
raw patch · 5 files changed
+152/−52 lines, 5 files
Files
- src/Data/SExp/Data.hs +39/−8
- src/Data/SExp/Parse.hs +76/−31
- src/Data/STData/Data.hs +17/−6
- src/Data/STData/Parse.hs +19/−6
- stdata.cabal +1/−1
src/Data/SExp/Data.hs view
@@ -5,6 +5,7 @@ , OpenLink(..) , OpenSExp(..) , SExp(..), SExpLink(..) , DualSExp(..), DualSExpLink(..)+ , sexpSymbolValue, sexpToList, sexpLinkToList, listToSExp, listToSExpLink ) where import Data.Generics@@ -21,25 +22,36 @@ data AntiAtom = -- | Created with QuasiQuotes of form @[sexp| \@:name |]@. Will be converted- -- to expression or pattern of type 'SExp'.+ -- to expression or pattern of type 'SExp'. @name@ will be bound with type+ -- 'SExp'. ValueAntiAtom String -- | Created with QuasiQuotes of form @[sexp| \@atom:name |]@. Will be- -- converted to expression or pattern of type 'Atom'.+ -- converted to expression or pattern of type 'SExp'. @name@ will be bound+ -- with type 'Atom'. | AtomAntiAtom String+ -- | Created with QuasiQuotes of form @[sexp| \@list:name |]@. Will be+ -- converted to expression or pattern of type 'SExp'. @name@ will be bound+ -- with type '[SExp]'.+ | ListAntiAtom String -- | Created with QuasiQuotes of form @[sexp| \@str:name |]@. Will be- -- converted to expression or pattern of type 'Atom'.+ -- converted to expression or pattern of type 'SExp'. @name@ will be bound+ -- with type 'String'. | StringAntiAtom String -- | Created with QuasiQuotes of form @[sexp| \@bool:name |]@. Will be- -- converted to expression or pattern of type 'Atom'.+ -- converted to expression or pattern of type 'SExp'. @name@ will be bound+ -- with type 'Bool'. | BooleanAntiAtom String -- | Created with QuasiQuotes of form @[sexp| \@int:name |]@. Will be- -- converted to expression or pattern of type 'Atom'.+ -- converted to expression or pattern of type 'SExp'. @name@ will be bound+ -- with type 'Integer'. | IntegerAntiAtom String -- | Created with QuasiQuotes of form @[sexp| \@float:name |]@. Will be- -- converted to expression or pattern of type 'Atom'.+ -- converted to expression or pattern of type 'SExp'. @name@ will be bound+ -- with type 'Double'. | FloatingAntiAtom String -- | Created with QuasiQuotes of form @[sexp| \@sym:name |]@. Will be- -- converted to expression or pattern of type 'Atom'.+ -- converted to expression or pattern of type 'SExp'. @name@ will be bound+ -- with type 'String'. | SymbolAntiAtom String deriving (Eq, Ord, Show, Typeable, Data) @@ -71,6 +83,25 @@ data DualSExpLink = PositiveDualSExpLink (OpenLink DualSExp DualSExpLink)- | AntiConsDualSExpLink String+ | AntiConsValueDualSExpLink String+ | AntiConsListDualSExpLink String deriving (Eq, Ord, Show, Typeable, Data) +sexpSymbolValue :: SExp -> Maybe String+sexpSymbolValue (SExp (AtomSExp (SymbolAtom s))) = Just s+sexpSymbolValue _ = Nothing++sexpToList :: SExp -> Maybe [SExp]+sexpToList (SExp (LinkSExp l)) = Just $ sexpLinkToList l+sexpToList _ = Nothing++sexpLinkToList :: SExpLink -> [SExp]+sexpLinkToList (SExpLink NullLink) = []+sexpLinkToList (SExpLink (ConsLink h t)) = h:sexpLinkToList t++listToSExp :: [SExp] -> SExp+listToSExp ss = SExp . LinkSExp $ listToSExpLink ss++listToSExpLink :: [SExp] -> SExpLink+listToSExpLink [] = SExpLink NullLink+listToSExpLink (s:ss) = SExpLink . ConsLink s $ listToSExpLink ss
src/Data/SExp/Parse.hs view
@@ -5,8 +5,8 @@ , stringTokenValueM, booleanTokenValueM, integerTokenValueM, floatingTokenValueM , symbolTokenValueM, lParenTokenValueM, rParenTokenValueM, whitespaceTokenValueM , commentTokenValueM, antiConsTokenValueM, antiValueTokenValueM, antiAtomTokenValueM- , antiStringTokenValueM, antiBooleanTokenValueM, antiIntegerTokenValueM, antiFloatingTokenValueM- , antiSymbolTokenValueM+ , antiListTokenValueM, antiStringTokenValueM, antiBooleanTokenValueM, antiIntegerTokenValueM+ , antiFloatingTokenValueM, antiSymbolTokenValueM , isDiscardSExpToken , sexpTokens , lexSExp@@ -16,6 +16,7 @@ , convertAtomP, convertAntiAtomToValueP , convertOpenLinkP , sexp, sexpl+ , unparseAtom, unparseSExp , lexOne, tokParse, qtokParse ) where @@ -50,6 +51,7 @@ | AntiConsToken | AntiValueToken String | AntiAtomToken String+ | AntiListToken String | AntiStringToken String | AntiBooleanToken String | AntiIntegerToken String@@ -86,6 +88,8 @@ antiValueTokenValueM t = case t of (AntiValueToken n) -> Just n ; _ -> Nothing antiAtomTokenValueM :: SExpToken -> Maybe String antiAtomTokenValueM t = case t of (AntiAtomToken n) -> Just n ; _ -> Nothing+antiListTokenValueM :: SExpToken -> Maybe String+antiListTokenValueM t = case t of (AntiListToken n) -> Just n ; _ -> Nothing antiStringTokenValueM :: SExpToken -> Maybe String antiStringTokenValueM t = case t of (AntiStringToken n) -> Just n ; _ -> Nothing antiBooleanTokenValueM :: SExpToken -> Maybe String@@ -163,6 +167,7 @@ , string "@~" >> return AntiConsToken , string "@:" >> liftM AntiValueToken antiName , string "@atom:" >> liftM AntiAtomToken antiName+ , string "@list:" >> liftM AntiListToken antiName , string "@str:" >> liftM AntiStringToken antiName , string "@bool:" >> liftM AntiBooleanToken antiName , string "@int:" >> liftM AntiIntegerToken antiName@@ -206,6 +211,7 @@ antiConsTok :: SExpParser () ; antiConsTok = sexpTokenParser antiConsTokenValueM antiValueTok :: SExpParser String ; antiValueTok = sexpTokenParser antiValueTokenValueM antiAtomTok :: SExpParser String ; antiAtomTok = sexpTokenParser antiAtomTokenValueM+antiListTok :: SExpParser String ; antiListTok = sexpTokenParser antiListTokenValueM antiStringTok :: SExpParser String ; antiStringTok = sexpTokenParser antiStringTokenValueM antiBooleanTok :: SExpParser String ; antiBooleanTok = sexpTokenParser antiBooleanTokenValueM antiIntegerTok :: SExpParser String ; antiIntegerTok = sexpTokenParser antiIntegerTokenValueM@@ -225,6 +231,7 @@ antiAtomP = msum [ liftM ValueAntiAtom antiValueTok , liftM AtomAntiAtom antiAtomTok+ , liftM ListAntiAtom antiListTok , liftM StringAntiAtom antiStringTok , liftM BooleanAntiAtom antiBooleanTok , liftM IntegerAntiAtom antiIntegerTok@@ -262,8 +269,13 @@ return . PositiveDualSExpLink $ ConsLink s ss , do antiConsTok - anti <- antiValueTok - return $ AntiConsDualSExpLink anti+ msum [ do+ anti <- antiValueTok + return $ AntiConsValueDualSExpLink anti+ , do+ anti <- antiListTok+ return $ AntiConsListDualSExpLink anti+ ] , return $ PositiveDualSExpLink NullLink ] @@ -283,14 +295,15 @@ convertAtomE (FloatingAtom f) = conE 'FloatingAtom `appE` litE (rationalL (toRational f)) convertAtomE (SymbolAtom s) = conE 'SymbolAtom `appE` litE (stringL s) -convertAntiAtomToValueE :: AntiAtom -> (Q Exp -> Q Exp) -> Q Exp-convertAntiAtomToValueE (ValueAntiAtom name) _ = varE $ mkName name-convertAntiAtomToValueE (AtomAntiAtom name) qatom = qatom . varE $ mkName name-convertAntiAtomToValueE (StringAntiAtom name) qatom = qatom $ conE 'StringAtom `appE` varE (mkName name)-convertAntiAtomToValueE (BooleanAntiAtom name) qatom = qatom $ conE 'BooleanAtom `appE` varE (mkName name)-convertAntiAtomToValueE (IntegerAntiAtom name) qatom = qatom $ conE 'IntegerAtom `appE` varE (mkName name)-convertAntiAtomToValueE (FloatingAntiAtom name) qatom = qatom $ conE 'FloatingAtom `appE` varE (mkName name)-convertAntiAtomToValueE (SymbolAntiAtom name) qatom = qatom $ conE 'SymbolAtom `appE` varE (mkName name)+convertAntiAtomToValueE :: AntiAtom -> (Q Exp -> Q Exp) -> (Q Exp -> Q Exp) -> Q Exp+convertAntiAtomToValueE (ValueAntiAtom name) _ _ = varE $ mkName name+convertAntiAtomToValueE (AtomAntiAtom name) qatom _ = qatom . varE $ mkName name+convertAntiAtomToValueE (ListAntiAtom name) _ qlistToValue = qlistToValue . varE $ mkName name+convertAntiAtomToValueE (StringAntiAtom name) qatom _ = qatom $ conE 'StringAtom `appE` varE (mkName name)+convertAntiAtomToValueE (BooleanAntiAtom name) qatom _ = qatom $ conE 'BooleanAtom `appE` varE (mkName name)+convertAntiAtomToValueE (IntegerAntiAtom name) qatom _ = qatom $ conE 'IntegerAtom `appE` varE (mkName name)+convertAntiAtomToValueE (FloatingAntiAtom name) qatom _ = qatom $ conE 'FloatingAtom `appE` varE (mkName name)+convertAntiAtomToValueE (SymbolAntiAtom name) qatom _ = qatom $ conE 'SymbolAtom `appE` varE (mkName name) convertOpenSExpE :: (l -> Q Exp) -> OpenSExp l -> Q Exp convertOpenSExpE _ (AtomSExp a) = conE 'AtomSExp `appE` convertAtomE a@@ -304,13 +317,16 @@ convertDualSExpToSExpE (PositiveDualSExp p) = conE 'SExp `appE` convertOpenSExpE convertDualSExpToSExpLinkE p convertDualSExpToSExpE (AntiAtomDualSExp aa) = - convertAntiAtomToValueE aa $ \ x -> conE 'SExp `appE` (conE 'AtomSExp `appE` x)+ convertAntiAtomToValueE aa (\ x -> conE 'SExp `appE` (conE 'AtomSExp `appE` x))+ (\ x -> varE 'listToSExp `appE` x) convertDualSExpToSExpLinkE :: DualSExpLink -> Q Exp convertDualSExpToSExpLinkE (PositiveDualSExpLink p) = conE 'SExpLink `appE` convertOpenLinkE convertDualSExpToSExpE convertDualSExpToSExpLinkE p-convertDualSExpToSExpLinkE (AntiConsDualSExpLink name) =+convertDualSExpToSExpLinkE (AntiConsValueDualSExpLink name) = conE 'SExpLink `appE` varE (mkName name)+convertDualSExpToSExpLinkE (AntiConsListDualSExpLink name) =+ varE 'listToSExpLink `appE` varE (mkName name) convertAtomP :: Atom -> Q Pat convertAtomP (StringAtom s) = conP 'StringAtom [litP (stringL s)]@@ -320,21 +336,23 @@ convertAtomP (FloatingAtom f) = conP 'FloatingAtom [litP (rationalL (toRational f))] convertAtomP (SymbolAtom s) = conP 'SymbolAtom [litP (stringL s)] -convertAntiAtomToValueP :: AntiAtom -> (Q Pat -> Q Pat) -> Q Pat-convertAntiAtomToValueP (ValueAntiAtom "_") _ = wildP-convertAntiAtomToValueP (ValueAntiAtom name) _ = varP $ mkName name-convertAntiAtomToValueP (AtomAntiAtom "_") qatom = qatom wildP-convertAntiAtomToValueP (AtomAntiAtom name) qatom = qatom . varP $ mkName name-convertAntiAtomToValueP (StringAntiAtom "_") qatom = qatom $ conP 'StringAtom [wildP]-convertAntiAtomToValueP (StringAntiAtom name) qatom = qatom $ conP 'StringAtom [varP $ mkName name]-convertAntiAtomToValueP (BooleanAntiAtom "_") qatom = qatom $ conP 'BooleanAtom [wildP]-convertAntiAtomToValueP (BooleanAntiAtom name) qatom = qatom $ conP 'BooleanAtom [varP $ mkName name]-convertAntiAtomToValueP (IntegerAntiAtom "_") qatom = qatom $ conP 'IntegerAtom [wildP]-convertAntiAtomToValueP (IntegerAntiAtom name) qatom = qatom $ conP 'IntegerAtom [varP $ mkName name]-convertAntiAtomToValueP (FloatingAntiAtom "_") qatom = qatom $ conP 'FloatingAtom [wildP]-convertAntiAtomToValueP (FloatingAntiAtom name) qatom = qatom $ conP 'FloatingAtom [varP $ mkName name]-convertAntiAtomToValueP (SymbolAntiAtom "_") qatom = qatom $ conP 'SymbolAtom [wildP]-convertAntiAtomToValueP (SymbolAntiAtom name) qatom = qatom $ conP 'SymbolAtom [varP $ mkName name]+convertAntiAtomToValueP :: AntiAtom -> (Q Pat -> Q Pat) -> (Q Pat -> Q Pat) -> Q Pat+convertAntiAtomToValueP (ValueAntiAtom "_") _ _ = wildP+convertAntiAtomToValueP (ValueAntiAtom name) _ _ = varP $ mkName name+convertAntiAtomToValueP (AtomAntiAtom "_") qatom _ = qatom wildP+convertAntiAtomToValueP (AtomAntiAtom name) qatom _ = qatom . varP $ mkName name+convertAntiAtomToValueP (ListAntiAtom "_") _ qvalueToList = qvalueToList wildP+convertAntiAtomToValueP (ListAntiAtom name) _ qvalueToList = qvalueToList . varP $ mkName name+convertAntiAtomToValueP (StringAntiAtom "_") qatom _ = qatom $ conP 'StringAtom [wildP]+convertAntiAtomToValueP (StringAntiAtom name) qatom _ = qatom $ conP 'StringAtom [varP $ mkName name]+convertAntiAtomToValueP (BooleanAntiAtom "_") qatom _ = qatom $ conP 'BooleanAtom [wildP]+convertAntiAtomToValueP (BooleanAntiAtom name) qatom _ = qatom $ conP 'BooleanAtom [varP $ mkName name]+convertAntiAtomToValueP (IntegerAntiAtom "_") qatom _ = qatom $ conP 'IntegerAtom [wildP]+convertAntiAtomToValueP (IntegerAntiAtom name) qatom _ = qatom $ conP 'IntegerAtom [varP $ mkName name]+convertAntiAtomToValueP (FloatingAntiAtom "_") qatom _ = qatom $ conP 'FloatingAtom [wildP]+convertAntiAtomToValueP (FloatingAntiAtom name) qatom _ = qatom $ conP 'FloatingAtom [varP $ mkName name]+convertAntiAtomToValueP (SymbolAntiAtom "_") qatom _ = qatom $ conP 'SymbolAtom [wildP]+convertAntiAtomToValueP (SymbolAntiAtom name) qatom _ = qatom $ conP 'SymbolAtom [varP $ mkName name] convertOpenSExpP :: (l -> Q Pat) -> OpenSExp l -> Q Pat convertOpenSExpP _ (AtomSExp a) = conP 'AtomSExp [convertAtomP a]@@ -348,13 +366,16 @@ convertDualSExpToSExpP (PositiveDualSExp p) = conP 'SExp [convertOpenSExpP convertDualSExpToSExpLinkP p] convertDualSExpToSExpP (AntiAtomDualSExp aa) =- convertAntiAtomToValueP aa $ \ x -> conP 'SExp [conP 'AtomSExp [x]]+ convertAntiAtomToValueP aa (\ x -> conP 'SExp [conP 'AtomSExp [x]])+ (\ x -> viewP (varE 'sexpToList) (conP 'Just [x])) convertDualSExpToSExpLinkP :: DualSExpLink -> Q Pat convertDualSExpToSExpLinkP (PositiveDualSExpLink p) = conP 'SExpLink [convertOpenLinkP convertDualSExpToSExpP convertDualSExpToSExpLinkP p]-convertDualSExpToSExpLinkP (AntiConsDualSExpLink name) =+convertDualSExpToSExpLinkP (AntiConsValueDualSExpLink name) = conP 'SExpLink [varP (mkName name)]+convertDualSExpToSExpLinkP (AntiConsListDualSExpLink name) =+ viewP (varE 'sexpLinkToList) (varP (mkName name)) sexp :: QuasiQuoter sexp = QuasiQuoter @@ -371,6 +392,30 @@ , quoteType = undefined , quoteDec = undefined }++-- Unparsing++unparseAtom :: Atom -> String+unparseAtom (StringAtom s) = printf "\"%s\"" (concatMap escape s)+ where+ escape '\n' = "\\n"+ escape '"' = "\\\""+ escape '\\' = "\\\\"+ escape o = [o]+unparseAtom (BooleanAtom True) = "true"+unparseAtom (BooleanAtom False) = "false"+unparseAtom (IntegerAtom i) = show i+unparseAtom (FloatingAtom f) = show f+unparseAtom (SymbolAtom s) = s++unparseSExp :: SExp -> String+unparseSExp (SExp (AtomSExp a)) = unparseAtom a+unparseSExp (SExp (LinkSExp (SExpLink NullLink))) = "()"+unparseSExp (SExp (LinkSExp (SExpLink (ConsLink h t)))) = printf "(%s%s)" (unparseSExp h) (unparseInList t)++unparseInList :: SExpLink -> String+unparseInList (SExpLink NullLink) = ""+unparseInList (SExpLink (ConsLink h t)) = printf " %s%s" (unparseSExp h) (unparseInList t) -- Helpers
src/Data/STData/Data.hs view
@@ -4,11 +4,10 @@ ( OpenSData(..), OpenTData(..) , SData(..), SLink(..), TData(..), TLink(..) , DualSData(..), DualSLink(..), DualTData(..), DualTLink(..)- , sdataToList+ , sdataSymbolValue, sdataToList, slinkToList, listToSData, listToSLink ) where import Data.Generics-import Text.Printf import Data.SExp -- Standard ST-Data@@ -45,7 +44,8 @@ data DualSLink = PositiveDualSLink (OpenLink DualSData DualSLink)- | AntiConsDualSLink String+ | AntiConsValueDualSLink String+ | AntiConsListDualSLink String deriving (Eq, Ord, Show, Typeable, Data) data DualTData = DualTData { unDualTData :: OpenTData DualSLink }@@ -54,10 +54,21 @@ data DualTLink = DualTLink { unDualTLink :: OpenLink DualTData DualTLink } deriving (Eq, Ord, Show, Typeable, Data) -sdataToList :: SData -> [SData]-sdataToList (SData (SLinkSData slink)) = slinkToList slink-sdataToList other = error $ printf "cannot convert sdata to list: %s" (show other)+sdataSymbolValue :: SData -> Maybe String+sdataSymbolValue (SData (AtomSData (SymbolAtom s))) = Just s+sdataSymbolValue _ = Nothing +sdataToList :: SData -> Maybe [SData]+sdataToList (SData (SLinkSData slink)) = Just $ slinkToList slink+sdataToList _ = Nothing+ slinkToList :: SLink -> [SData] slinkToList (SLink NullLink) = [] slinkToList (SLink (ConsLink s ss)) = s : slinkToList ss++listToSData :: [SData] -> SData+listToSData ss = SData . SLinkSData $ listToSLink ss++listToSLink :: [SData] -> SLink+listToSLink [] = SLink NullLink+listToSLink (s:ss) = SLink . ConsLink s $ listToSLink ss
src/Data/STData/Parse.hs view
@@ -183,6 +183,7 @@ antiConsTok :: STDataParser () ; antiConsTok = stDataTokenParser $ sexpSTDataTokenValueM >=> antiConsTokenValueM antiValueTok :: STDataParser String ; antiValueTok = stDataTokenParser $ sexpSTDataTokenValueM >=> antiValueTokenValueM antiAtomTok :: STDataParser String ; antiAtomTok = stDataTokenParser $ sexpSTDataTokenValueM >=> antiAtomTokenValueM+antiListTok :: STDataParser String ; antiListTok = stDataTokenParser $ sexpSTDataTokenValueM >=> antiListTokenValueM antiStringTok :: STDataParser String ; antiStringTok = stDataTokenParser $ sexpSTDataTokenValueM >=> antiStringTokenValueM antiBooleanTok :: STDataParser String ; antiBooleanTok = stDataTokenParser $ sexpSTDataTokenValueM >=> antiBooleanTokenValueM antiIntegerTok :: STDataParser String ; antiIntegerTok = stDataTokenParser $ sexpSTDataTokenValueM >=> antiIntegerTokenValueM@@ -208,6 +209,7 @@ antiAtomP = msum [ liftM ValueAntiAtom antiValueTok , liftM AtomAntiAtom antiAtomTok+ , liftM ListAntiAtom antiListTok , liftM StringAntiAtom antiStringTok , liftM BooleanAntiAtom antiBooleanTok , liftM IntegerAntiAtom antiIntegerTok@@ -262,8 +264,13 @@ return . PositiveDualSLink $ ConsLink s ss , do antiConsTok - anti <- antiValueTok - return $ AntiConsDualSLink anti+ msum [ do+ anti <- antiValueTok + return $ AntiConsValueDualSLink anti+ , do+ anti <- antiListTok+ return $ AntiConsListDualSLink anti+ ] , return $ PositiveDualSLink NullLink ] @@ -309,13 +316,16 @@ convertDualSDataToSDataE (PositiveDualSData p) = conE 'SData `appE` convertOpenSDataE convertDualSDataToSDataLinkE convertDualTDataToTDataLinkE p convertDualSDataToSDataE (AntiAtomDualSData aa) = - convertAntiAtomToValueE aa $ \ x -> conE 'SData `appE` (conE 'AtomSData `appE` x)+ convertAntiAtomToValueE aa (\ x -> conE 'SData `appE` (conE 'AtomSData `appE` x))+ (\ x -> varE 'listToSData `appE` x) convertDualSDataToSDataLinkE :: DualSLink -> Q Exp convertDualSDataToSDataLinkE (PositiveDualSLink p) = conE 'SLink `appE` convertOpenLinkE convertDualSDataToSDataE convertDualSDataToSDataLinkE p-convertDualSDataToSDataLinkE (AntiConsDualSLink name) =+convertDualSDataToSDataLinkE (AntiConsValueDualSLink name) = conE 'SLink `appE` varE (mkName name)+convertDualSDataToSDataLinkE (AntiConsListDualSLink name) =+ varE 'listToSLink `appE` varE (mkName name) convertDualTDataToTDataE :: DualTData -> Q Exp convertDualTDataToTDataE (DualTData p) = @@ -337,13 +347,16 @@ convertDualSDataToSDataP (PositiveDualSData p) = conP 'SData [convertOpenSDataP convertDualSDataToSDataLinkP convertDualTDataToTDataLinkP p] convertDualSDataToSDataP (AntiAtomDualSData aa) = - convertAntiAtomToValueP aa $ \ x -> conP 'SData [conP 'AtomSData [x]]+ convertAntiAtomToValueP aa (\ x -> conP 'SData [conP 'AtomSData [x]])+ (\ x -> viewP (varE 'sdataToList) (conP 'Just [x])) convertDualSDataToSDataLinkP :: DualSLink -> Q Pat convertDualSDataToSDataLinkP (PositiveDualSLink p) = conP 'SLink [convertOpenLinkP convertDualSDataToSDataP convertDualSDataToSDataLinkP p]-convertDualSDataToSDataLinkP (AntiConsDualSLink name) =+convertDualSDataToSDataLinkP (AntiConsValueDualSLink name) = conP 'SLink [varP (mkName name)]+convertDualSDataToSDataLinkP (AntiConsListDualSLink name) =+ viewP (varE 'slinkToList) (varP (mkName name)) convertDualTDataToTDataP :: DualTData -> Q Pat convertDualTDataToTDataP (DualTData p) =
stdata.cabal view
@@ -1,5 +1,5 @@ Name: stdata-Version: 0.0.3+Version: 0.0.4 Synopsis: Structure Data Library Description: Contains datatypes and quasi-quoting functionaly for standard s-expressions and nested structured/unstructured data