gdritter repos s-cargot / 14c258a
Modified cabal file + module contents to be 7.{8,10} compatible Getty Ritter 9 years ago
10 changed file(s) with 122 addition(s) and 95 deletion(s). Collapse all Expand all
2626 , simpleBlockComment
2727 ) where
2828
29 import Control.Monad (void)
30 import Data.Text (Text)
3129 import Text.Parsec ( (<|>)
3230 , anyChar
3331 , manyTill
1919 , signedHexNumber
2020 ) where
2121
22 #if !MIN_VERSION_base(4,8,0)
23 import Control.Applicative hiding ((<|>), many)
24 #endif
2225 import Data.Char
2326 import Data.Text (Text)
2427 import qualified Data.Text as T
2528 import Text.Parsec
26 import Text.Parsec.Char (satisfy)
2729 import Text.Parsec.Text (Parser)
2830
2931 -- | Parse an identifier according to the R5RS Scheme standard. This
184186 signedDecNumber :: Parser Integer
185187 signedDecNumber = ($) <$> sign <*> decNumber
186188
189 dozDigit :: Parser Char
187190 dozDigit = digit <|> oneOf "AaBb\x218a\x218b"
188191
189192 -- | A parser for non-signed duodecimal (dozenal) numbers. This understands both
1818 , mkParser
1919 , flatPrint
2020 )
21 import Data.SCargot.Comments (withLispComments)
2221
2322 isAtomChar :: Char -> Bool
2423 isAtomChar c = isAlphaNum c
77 , haskLikePrinter
88 ) where
99
10 import Control.Applicative ((<$>), (<*>), (<$))
10 #if !MIN_VERSION_base(4,8,0)
11 import Control.Applicative ((<$>), (<$))
12 #endif
1113 import Data.Maybe (catMaybes)
1214 import Data.String (IsString(..))
1315 import Data.Text (Text, pack)
5254 pString :: Parser Text
5355 pString = pack . catMaybes <$> between (char '"') (char '"') (many (val <|> esc))
5456 where val = Just <$> satisfy (\ c -> c /= '"' && c /= '\\' && c > '\026')
55 esc = do char '\\'
57 esc = do _ <- char '\\'
5658 Nothing <$ (gap <|> char '&') <|>
5759 Just <$> code
5860 gap = many1 space >> char '\\'
8486 n <- decNumber
8587 withDot n <|> noDot n
8688 where withDot n = do
87 char '.'
89 _ <- char '.'
8890 m <- decNumber
89 e <- option 1.0 exponent
91 e <- option 1.0 expn
9092 return ((fromIntegral n + asDec m 0) * e)
9193 noDot n = do
92 e <- exponent
94 e <- expn
9395 return (fromIntegral n * e)
94 exponent = do
95 oneOf "eE"
96 expn = do
97 _ <- oneOf "eE"
9698 s <- power
9799 x <- decNumber
98100 return (10 ** s (fromIntegral x))
1919 , withQuote
2020 ) where
2121
22 import Control.Applicative ((<*), (*>), (<*>), (<$>), pure)
22 #if !MIN_VERSION_base(4,8,0)
23 import Control.Applicative ((<$>), (<*), pure)
24 #endif
2325 import Control.Monad ((>=>))
24 import Data.Char (isAlpha, isDigit, isAlphaNum)
2526 import Data.Map.Strict (Map)
2627 import qualified Data.Map.Strict as M
27 import Data.Maybe (fromJust)
28 import Data.Monoid ((<>))
28 import Data.Text (Text)
2929 import Data.String (IsString)
30 import Data.Text (Text, pack, unpack)
31 import qualified Data.Text as T
3230 import Text.Parsec ( (<|>)
3331 , (<?>)
3432 , char
4442 import Data.SCargot.Repr ( SExpr(..)
4543 , RichSExpr
4644 , WellFormedSExpr
47 , fromRich
4845 , toRich
49 , fromWellFormed
5046 , toWellFormed
5147 )
5248
197193 c <- peekChar
198194 case c of
199195 Just '.' -> do
200 char '.'
196 _ <- char '.'
201197 cdr <- sExpr
202198 skip
203 char ')'
199 _ <- char ')'
204200 skip
205201 return (SCons car cdr)
206202 Just ')' -> do
207 char ')'
203 _ <- char ')'
208204 skip
209205 return (SCons car SNil)
210206 _ -> do
11 {-# LANGUAGE PatternSynonyms #-}
2 {-# LANGUAGE ScopedTypeVariables #-}
23 {-# LANGUAGE ViewPatterns #-}
34
45 module Data.SCargot.Repr.Basic
2728 , asAssoc
2829 ) where
2930
30 import Control.Applicative ((<$>), (<*>), pure)
31 #if !MIN_VERSION_base(4,8,0)
32 import Control.Applicative (Applicative, (<$>), (<*>), pure)
33 #endif
3134 import Data.SCargot.Repr as R
3235
3336 -- | A traversal with access to the first element of a pair.
3841 -- >>> set _car (A "two" ::: A "three" ::: Nil) (A "one" ::: A "elephant")
3942 -- (A "two" ::: A "three" ::: Nil) ::: A "elephant"
4043 _car :: Applicative f => (SExpr a -> f (SExpr a)) -> SExpr a -> f (SExpr a)
41 _car f (x ::: xs) = (:::) <$> f x <*> pure xs
42 _car _ (A a) = pure (A a)
43 _car _ Nil = pure Nil
44 _car f (SCons x xs) = (:::) <$> f x <*> pure xs
45 _car _ (SAtom a) = pure (A a)
46 _car _ SNil = pure SNil
4447
4548 -- | A traversal with access to the second element of a pair.
4649 --
5053 -- >>> set _cdr (A "two" ::: A "three" ::: Nil) (A "one" ::: A "elephant")
5154 -- A "one" ::: A "two" ::: A "three" ::: Nil
5255 _cdr :: Applicative f => (SExpr a -> f (SExpr a)) -> SExpr a -> f (SExpr a)
53 _cdr f (x ::: xs) = (:::) <$> pure x <*> f xs
54 _cdr _ (A a) = pure (A a)
55 _cdr _ Nil = pure Nil
56 _cdr f (SCons x xs) = (:::) <$> pure x <*> f xs
57 _cdr _ (SAtom a) = pure (A a)
58 _cdr _ SNil = pure Nil
5659
5760 -- | Produce the head and tail of the s-expression (if possible).
5861 --
112115 -- >>> L [A "pachy", A "derm"]
113116 -- SCons (SAtom "pachy") (SCons (SAtom "derm") SNil)
114117 pattern L xs <- (gatherList -> Right xs)
118 #if MIN_VERSION_base(4,8,0)
115119 where L xs = mkList xs
120 #endif
121
116122
117123 -- | An alias for matching a dotted list.
118124 --
119125 -- >>> DL [A "pachy"] A "derm"
120126 -- SCons (SAtom "pachy") (SAtom "derm")
121127 pattern DL xs x <- (gatherDList -> Just (xs, x))
128 #if MIN_VERSION_base(4,8,0)
122129 where DL xs x = mkDList xs x
130 #endif
123131
124132 getShape :: SExpr a -> String
125133 getShape Nil = "empty list"
126 getShape sx = go 0 sx
127 where go n Nil = "list of length " ++ show n
128 go n A {} = "dotted list of length " ++ show n
129 go n (_:::xs) = go (n+1) xs
134 getShape sx = go (0 :: Int) sx
135 where go n SNil = "list of length " ++ show n
136 go n SAtom {} = "dotted list of length " ++ show n
137 go n (SCons _ xs) = go (n+1) xs
130138
131139 -- | Utility function for parsing a pair of things.
132140 --
143151 -- | Utility function for parsing a list of things.
144152 fromList :: (SExpr t -> Either String a) -> SExpr t -> Either String [a]
145153 fromList p (s ::: ss) = (:) <$> p s <*> fromList p ss
146 fromList p Nil = pure []
154 fromList _ Nil = pure []
147155 fromList _ sx = Left ("fromList: expected list; found " ++ getShape sx)
148156
149157 -- | Utility function for parsing a single atom
2828 , isNil
2929 , asAtom
3030 , asAssoc
31 , car
32 , cdr
3133 ) where
3234
33 import Control.Applicative ((<$>), (<*>), pure)
35 #if !MIN_VERSION_base(4,8,0)
36 import Control.Applicative (Applicative, (<$>), (<*>), pure)
37 #endif
3438 import Data.SCargot.Repr as R
3539
3640 -- | A traversal with access to the first element of a pair.
4145 -- >>> set _car (L [A "two", A "three"]) (DL [A "one"] "elephant")
4246 -- DL [L[A "two",A "three"]] "elephant"
4347 _car :: Applicative f => (RichSExpr a -> f (RichSExpr a)) -> RichSExpr a -> f (RichSExpr a)
44 _car f (L (x:xs)) = (\ x -> L (x:xs)) `fmap` f x
45 _car f (DL (x:xs) a) = (\ x -> DL (x:xs) a) `fmap` f x
46 _car _ (A a) = pure (A a)
47 _car _ Nil = pure Nil
48 _car f (RSList (x:xs)) = (\ y -> L (y:xs)) `fmap` f x
49 _car f (RSDotted (x:xs) a) = (\ y -> DL (y:xs) a) `fmap` f x
50 _car _ (RSAtom a) = pure (A a)
51 _car _ (RSList []) = pure Nil
52 _car _ (RSDotted [] a) = pure (A a)
4853
4954 -- | A traversal with access to the second element of a pair. Using
5055 -- this to modify an s-expression may result in changing the
5762 -- >>> set _cdr (L [A "two", A "three"]) (DL [A "one"] "elephant")
5863 -- L [A "one",A "two",A "three"]
5964 _cdr :: Applicative f => (RichSExpr a -> f (RichSExpr a)) -> RichSExpr a -> f (RichSExpr a)
60 _cdr f (L (x:xs)) =
61 let go Nil = L [x]
62 go (A a) = DL [x] a
63 go (L xs') = L (x:xs')
65 _cdr f (RSList (x:xs)) =
66 let go (RSList []) = L [x]
67 go (RSAtom a) = DL [x] a
68 go (RSList xs') = L (x:xs')
69 go (RSDotted ys a') = DL (x:ys) a'
6470 in go `fmap` f (L xs)
65 _cdr f (DL [x] a) =
66 let go Nil = L [x]
67 go (A a') = DL [x] a'
68 go (L xs) = L (x:xs)
71 _cdr f (RSDotted [x] a) =
72 let go (RSList []) = L [x]
73 go (RSAtom a') = DL [x] a'
74 go (RSList xs) = L (x:xs)
75 go (RSDotted ys a') = DL (x:ys) a'
6976 in go `fmap` f (A a)
70 _cdr f (DL (x:xs) a) =
71 let go Nil = L [x]
72 go (A a') = DL [x] a'
73 go (L xs) = L (x:xs)
77 _cdr f (RSDotted (x:xs) a) =
78 let go (RSList []) = L [x]
79 go (RSAtom a') = DL [x] a'
80 go (RSList ys) = L (x:ys)
81 go (RSDotted ys a') = DL (x:ys) a'
7482 in go `fmap` f (DL xs a)
75 _cdr _ (A a) = pure (A a)
76 _cdr _ Nil = pure Nil
83 _cdr _ (RSAtom a) = pure (A a)
84 _cdr _ (RSList []) = pure Nil
85 _cdr _ (RSDotted [] a) = pure (A a)
7786
7887 -- | Produce the head and tail of the s-expression (if possible).
7988 --
8089 -- >>> uncons (L [A "el", A "eph", A "ant"])
8190 -- Just (A "el",L [A "eph",A "ant"])
8291 uncons :: RichSExpr a -> Maybe (RichSExpr a, RichSExpr a)
83 uncons R.RSAtom {} = Nothing
8492 uncons (R.RSList (x:xs)) = Just (x, R.RSList xs)
8593 uncons (R.RSDotted (x:xs) a) = Just (x, R.RSDotted xs a)
94 uncons _ = Nothing
8695
8796 -- | Combine the two s-expressions into a new one.
8897 --
99108 -- >>> A "one" ::: L [A "two", A "three"]
100109 -- RSList [RSAtom "one",RSAtom "two",RSAtom "three"]
101110 pattern x ::: xs <- (uncons -> Just (x, xs))
111 #if MIN_VERSION_base(4,8,0)
102112 where x ::: xs = cons x xs
113 #endif
103114
104115 -- | A shorter alias for `RSAtom`
105116 --
153164 -- >>> fromAtom (L [A "elephant"])
154165 -- Left "fromAtom: expected atom; found list"
155166 fromAtom :: RichSExpr t -> Either String t
156 fromAtom (L _) = Left "fromAtom: expected atom; found list"
157 fromAtom (DL _ _) = Left "fromAtom: expected atom; found dotted list"
158 fromAtom (A a) = return a
167 fromAtom (RSList _) = Left "fromAtom: expected atom; found list"
168 fromAtom (RSDotted _ _) = Left "fromAtom: expected atom; found dotted list"
169 fromAtom (RSAtom a) = return a
159170
160171 -- | Parses a two-element list using the provided function.
161172 --
166177 -- Left "asPair: expected two-element list; found list of length 1"
167178 asPair :: ((RichSExpr t, RichSExpr t) -> Either String a)
168179 -> RichSExpr t -> Either String a
169 asPair f (L [l, r]) = f (l, r)
170 asPair _ (L ls) = Left ("asPair: expected two-element list; found list of lenght " ++ show (length ls))
171 asPair _ DL {} = Left ("asPair: expected two-element list; found dotted list")
172 asPair _ A {} = Left ("asPair: expected two-element list; found atom")
180 asPair f (RSList [l, r]) = f (l, r)
181 asPair _ (RSList ls) = Left ("asPair: expected two-element list; found list of lenght " ++ show (length ls))
182 asPair _ RSDotted {} = Left ("asPair: expected two-element list; found dotted list")
183 asPair _ RSAtom {} = Left ("asPair: expected two-element list; found atom")
173184
174185 -- | Parse an arbitrary-length list using the provided function.
175186 --
180191 -- Left "asList: expected list; found dotted list"
181192 asList :: ([RichSExpr t] -> Either String a)
182193 -> RichSExpr t -> Either String a
183 asList f (L ls) = f ls
184 asList _ DL {} = Left ("asList: expected list; found dotted list")
185 asList _ A { } = Left ("asList: expected list; found dotted list")
194 asList f (RSList ls) = f ls
195 asList _ RSDotted {} = Left ("asList: expected list; found dotted list")
196 asList _ RSAtom { } = Left ("asList: expected list; found dotted list")
186197
187198 -- | Match a given literal atom, failing otherwise.
188199 --
191202 -- >>> isAtom "elephant" (L [A "elephant"])
192203 -- Left "isAtom: expected atom; found list"
193204 isAtom :: Eq t => t -> RichSExpr t -> Either String ()
194 isAtom s (A s')
205 isAtom s (RSAtom s')
195206 | s == s' = return ()
196207 | otherwise = Left "isAtom: failed to match atom"
197 isAtom _ L {} = Left "isAtom: expected atom; found list"
198 isAtom _ DL {} = Left "isAtom: expected atom; found dotted list"
208 isAtom _ RSList {} = Left "isAtom: expected atom; found list"
209 isAtom _ RSDotted {} = Left "isAtom: expected atom; found dotted list"
199210
200211 -- | Match an empty list, failing otherwise.
201212 --
204215 -- >>> isNil (A "elephant")
205216 -- Left "isNil: expected nil; found atom"
206217 isNil :: RichSExpr t -> Either String ()
207 isNil Nil = return ()
208 isNil L {} = Left "isNil: expected nil; found non-nil list"
209 isNil DL {} = Left "isNil: expected nil; found dotted list"
210 isNil A {} = Left "isNil: expected nil; found atom"
218 isNil (RSList []) = return ()
219 isNil RSList {} = Left "isNil: expected nil; found non-nil list"
220 isNil RSDotted {} = Left "isNil: expected nil; found dotted list"
221 isNil RSAtom {} = Left "isNil: expected nil; found atom"
211222
212223 -- | Parse an atom using the provided function.
213224 --
217228 -- >>> asAtom (return . map toUpper) (L [])
218229 -- Left "asAtom: expected atom; found list"
219230 asAtom :: (t -> Either String a) -> RichSExpr t -> Either String a
220 asAtom f (A s) = f s
221 asAtom _ L {} = Left ("asAtom: expected atom; found list")
222 asAtom _ DL {} = Left ("asAtom: expected atom; found dotted list")
231 asAtom f (RSAtom s) = f s
232 asAtom _ RSList {} = Left ("asAtom: expected atom; found list")
233 asAtom _ RSDotted {} = Left ("asAtom: expected atom; found dotted list")
223234
224235 -- | Parse an assoc-list using the provided function.
225236 --
231242 -- Left "asAssoc: expected pair; found list of length 1"
232243 asAssoc :: ([(RichSExpr t, RichSExpr t)] -> Either String a)
233244 -> RichSExpr t -> Either String a
234 asAssoc f (L ss) = gatherPairs ss >>= f
235 where gatherPairs (L [a, b] : ss) = (:) <$> pure (a, b) <*> gatherPairs ss
245 asAssoc f (RSList ss) = gatherPairs ss >>= f
246 where gatherPairs (RSList [a, b] : ts) = (:) <$> pure (a, b) <*> gatherPairs ts
236247 gatherPairs [] = pure []
237 gatherPairs (A {} : _) = Left ("asAssoc: expected pair; found atom")
238 gatherPairs (DL {} : _) = Left ("asAssoc: expected pair; found dotted list")
239 gatherPairs (L ls : _) = Left ("asAssoc: expected pair; found list of length " ++ show (length ls))
240 asAssoc f DL {} = Left "asAssoc: expected assoc list; found dotted list"
241 asAssoc f A {} = Left "asAssoc: expected assoc list; found atom"
248 gatherPairs (RSAtom {} : _) = Left ("asAssoc: expected pair; found atom")
249 gatherPairs (RSDotted {} : _) = Left ("asAssoc: expected pair; found dotted list")
250 gatherPairs (RSList ls : _) = Left ("asAssoc: expected pair; found list of length " ++ show (length ls))
251 asAssoc _ RSDotted {} = Left "asAssoc: expected assoc list; found dotted list"
252 asAssoc _ RSAtom {} = Left "asAssoc: expected assoc list; found atom"
242253
243254 car :: (RichSExpr t -> Either String t') -> [RichSExpr t] -> Either String t'
244255 car f (x:_) = f x
2121 , asPair
2222 , asList
2323 , isAtom
24 , isNil
2425 , asAtom
2526 , asAssoc
2627 , car
2728 , cdr
2829 ) where
2930
31 #if !MIN_VERSION_base(4,8,0)
3032 import Control.Applicative ((<$>), (<*>), pure)
33 #endif
3134 import Data.SCargot.Repr as R
3235
3336 -- | Produce the head and tail of the s-expression (if possible).
3639 -- Just (WFSAtom "el",WFSList [WFSAtom "eph",WFSAtom "ant"])
3740 uncons :: WellFormedSExpr a -> Maybe (WellFormedSExpr a, WellFormedSExpr a)
3841 uncons R.WFSAtom {} = Nothing
42 uncons (R.WFSList []) = Nothing
3943 uncons (R.WFSList (x:xs)) = Just (x, R.WFSList xs)
4044
4145 -- | Combine the two-expressions into a new one. This will return
7680 pattern Nil = R.WFSList []
7781
7882 getShape :: WellFormedSExpr a -> String
79 getShape A {} = "atom"
80 getShape Nil = "empty list"
81 getShape (L sx) = "list of length " ++ show (length sx)
83 getShape WFSAtom {} = "atom"
84 getShape (WFSList []) = "empty list"
85 getShape (WFSList sx) = "list of length " ++ show (length sx)
8286
8387 -- | Utility function for parsing a pair of things.
8488 --
181185 asAssoc :: ([(WellFormedSExpr t, WellFormedSExpr t)] -> Either String a)
182186 -> WellFormedSExpr t -> Either String a
183187 asAssoc f (L ss) = gatherPairs ss >>= f
184 where gatherPairs (L [a, b] : ss) = (:) <$> pure (a, b) <*> gatherPairs ss
188 where gatherPairs (L [a, b] : ts) = (:) <$> pure (a, b) <*> gatherPairs ts
185189 gatherPairs [] = pure []
186190 gatherPairs (sx:_) = Left ("asAssoc: expected pair; found " ++ getShape sx)
187191 asAssoc _ sx = Left ("asAssoc: expected list; found " ++ getShape sx)
2020
2121 import Data.Data (Data)
2222 import Data.Foldable (Foldable(..))
23 import Data.Monoid (Monoid(..), (<>))
2423 import Data.Traversable (Traversable(..))
2524 import Data.Typeable (Typeable)
2625 import GHC.Exts (IsList(..), IsString(..))
26
27 #if !MIN_VERSION_base(4,8,0)
28 import Prelude hiding (foldr)
29 #endif
2730
2831 -- | All S-Expressions can be understood as a sequence
2932 -- of @cons@ cells (represented here by 'SCons'), the
8588 toRich (SCons x xs) = go xs (toRich x:)
8689 where go (SAtom a) rs = RSDotted (rs []) a
8790 go SNil rs = RSList (rs [])
88 go (SCons x xs) rs = go xs (rs . (toRich x:))
91 go (SCons y ys) rs = go ys (rs . (toRich y:))
92 toRich SNil = RSList []
8993
9094 -- | This follows the same laws as 'toRich'.
9195 fromRich :: RichSExpr atom -> SExpr atom
128132 toWellFormed (SCons x xs) = do
129133 x' <- toWellFormed x
130134 go xs (x':)
131 where go (SAtom a) rs = Left "Found atom in cdr position"
135 where go (SAtom _) _ = Left "Found atom in cdr position"
132136 go SNil rs = return (WFSList (rs []))
133 go (SCons x xs) rs = do
134 x' <- toWellFormed x
135 go xs (rs . (x':))
137 go (SCons y ys) rs = do
138 y' <- toWellFormed y
139 go ys (rs . (y':))
136140
137141 -- | Convert a WellFormedSExpr back into a SExpr.
138142 fromWellFormed :: WellFormedSExpr atom -> SExpr atom
3535 Data.SCargot.Common,
3636 Data.SCargot.Language.Basic,
3737 Data.SCargot.Language.HaskLike
38 build-depends: base >=4.7 && <5,
39 parsec,
40 text,
41 containers
38 build-depends: base >=4.7 && <5,
39 parsec >=3.1 && <4,
40 text >=1.2 && <2,
41 containers >=0.5 && <1
4242 default-language: Haskell2010
43 default-extensions: CPP
44 ghc-options: -Wall