Browse Source

Added IsList instance for s-cargot lists

Getty Ritter 9 years ago
parent
commit
d51c85a085
3 changed files with 39 additions and 36 deletions
  1. 17 0
      Data/SCargot/Common.hs
  2. 22 1
      Data/SCargot/Repr.hs
  3. 0 35
      Data/SCargot/Tutorial.hs

+ 17 - 0
Data/SCargot/Common.hs

@@ -16,6 +16,12 @@ import           Text.Parsec
 import           Text.Parsec.Char (satisfy)
 import           Text.Parsec.Text (Parser)
 
+-- | Parse an identifier according to the R5RS Scheme standard. This
+--   will not normalize case, even though the R5RS standard specifies
+--   that all identifiers be normalized to lower case first.
+--
+--   An R5RS identifier is, broadly speaking, alphabetic or numeric
+--   and may include various symbols, but no escapes.
 parseR5RSIdent :: Parser Text
 parseR5RSIdent =
   T.pack <$> ((:) <$> initial <*> many subsequent <|> peculiar)
@@ -26,6 +32,11 @@ parseR5RSIdent =
 hasCategory :: Char -> [GeneralCategory] -> Bool
 hasCategory c cs = generalCategory c `elem` cs
 
+-- | Parse an identifier according to the R6RS Scheme standard. An
+--   R6RS identifier may include inline hexadecimal escape sequences
+--   so that, for example, 'foo' is equivalent to 'f\x6f;o', and is
+--   more liberal than R5RS as to which Unicode characters it may
+--   accept.
 parseR6RSIdent :: Parser Text
 parseR6RSIdent =
   T.pack <$> ((:) <$> initial <*> many subsequent <|> peculiar)
@@ -54,6 +65,12 @@ parseR6RSIdent =
         uniClass :: (Char -> Bool) -> Parser Char
         uniClass sp = satisfy (\ c -> c > '\x7f' && sp c)
 
+-- | Parse an identifier according to the R7RS Scheme standard. An
+--   R7RS identifier, in addition to a typical identifier format,
+--   can also be a chunk of text surrounded by vertical bars that
+--   can contain spaces and other characters. Unlike R6RS, it does
+--   not allow escapes to be included in identifiers that are not
+--   surrounded by vertical bars.
 parseR7RSIdent :: Parser Text
 parseR7RSIdent =  T.pack <$>
           (  (:) <$> initial <*> many subsequent

+ 22 - 1
Data/SCargot/Repr.hs

@@ -1,4 +1,5 @@
 {-# LANGUAGE DeriveFunctor #-}
+{-# LANGUAGE TypeFamilies #-}
 
 module Data.SCargot.Repr
        ( -- * Elementary SExpr representation
@@ -13,7 +14,8 @@ module Data.SCargot.Repr
        , fromWellFormed
        ) where
 
-import Data.String (IsString(..))
+--import Data.String (IsString(..))
+import GHC.Exts (IsList(..), IsString(..))
 
 -- | All S-Expressions can be understood as a sequence
 --   of @cons@ cells (represented here by 'SCons'), the
@@ -28,7 +30,12 @@ data SExpr atom
 instance IsString atom => IsString (SExpr atom) where
   fromString = SAtom . fromString
 
+instance IsList (SExpr atom) where
+  type Item (SExpr atom) = SExpr atom
+  fromList = foldr SCons SNil
+  toList   = undefined
+
+-- | sometimes, the cons-based interface is too low
 --   level, and we'd rather have the lists themselves
 --   exposed. In this case, we have 'RSList' to
 --   represent a well-formed cons list, and 'RSDotted'
@@ -48,6 +55,13 @@ data RichSExpr atom
 instance IsString atom => IsString (RichSExpr atom) where
   fromString = RSAtom . fromString
 
+instance IsList (RichSExpr atom) where
+  type Item (RichSExpr atom) = RichSExpr atom
+  fromList = RSList
+  toList (RSList xs)   = xs
+  toList (RSDotted {}) = error "Unable to turn dotted list into haskell list"
+  toList (RSAtom {})   = error "Unable to turn atom into Haskell list"
+
 -- |  It should always be true that
 --
 --   > fromRich (toRich x) == x
@@ -78,6 +92,12 @@ data WellFormedSExpr atom
   | WFSAtom atom
     deriving (Eq, Show, Read, Functor)
 
+instance IsList (WellFormedSExpr atom) where
+  type Item (WellFormedSExpr atom) = WellFormedSExpr atom
+  fromList = WFSList
+  toList (WFSList xs) = xs
+  toList (WFSAtom {}) = error "Unable to turn atom into Haskell list"
+
 instance IsString atom => IsString (WellFormedSExpr atom) where
   fromString = WFSAtom . fromString
 

+ 0 - 35
Data/SCargot/Tutorial.hs

@@ -1,35 +0,0 @@
-{-| The "s-cargot" library attempts to be as general as possible, and
-    to support a wide range of use-cases for s-expressions. It is built
-    around a core of primitives which are then exposed in various
-    ways, and can be easily and flexibly extended. This tutorial
-    describes particular use-cases, and then shows how to adapt this
-    library to that use-case.
--}
-
-module Data.SCargot.Tutorial
-  ( -- * Basic Usage and Organization
-    -- $usage
-    -- * Building a Custom Config Format
-    -- $config
-    -- * Analyzing Scheme code
-    -- $scheme
-    -- * Building a Custom Lisp
-    -- $lisp
-  ) where
-
-{- $usage
-When people talk about s-expressions, they're really talking about
-a _family_ of formats that have in common a rough structure and
-the fact that -}
-
-{- $config
-
--}
-
-{- $scheme
-
--}
-
-{- $lisp
-
--}