module Text.Parsec.Indent (
IndentParserT,
withBlock, withLineFold,
withBlock', withLineFold',
block, lineFold,
manyLine, manyIndent,
foldLine, foldLine3, foldLine4,
foldLine5, (<+/>), (<-/>), runIndent
) where
import Text.Parsec
import Text.Parsec.Pos
import Control.Monad.State
import Control.Concatenative
type IndentParserT s u m a = ParsecT s u (StateT SourcePos m) a
withLineFold :: (Stream s (StateT SourcePos m) Char, Monad m) => (a -> [b] -> c) ->
IndentParserT s u m a -> IndentParserT s u m b -> IndentParserT s u m c
withLineFold f a p = withPos $ do
r1 <- a
r2 <- many (sameOrIndented >> p)
return (f r1 r2)
withLineFold' :: (Stream s (StateT SourcePos m) Char, Monad m) =>
IndentParserT s u m a -> IndentParserT s u m b -> IndentParserT s u m [b]
withLineFold' = withLineFold (flip const)
withBlock' :: (Stream s (StateT SourcePos m) Char, Monad m) =>
IndentParserT s u m a -> IndentParserT s u m b -> IndentParserT s u m [b]
withBlock' = withBlock (flip const)
lineFold :: (Stream s (StateT SourcePos m) Char, Monad m) => IndentParserT s u m a -> IndentParserT s u m [a]
lineFold = withLineFold' (return ())
withBlock :: (Stream s (StateT SourcePos m) Char, Monad m) => (a -> [b] -> c) ->
IndentParserT s u m a -> IndentParserT s u m b -> IndentParserT s u m c
withBlock f a p = withPos $ do
r1 <- a
r2 <- option [] (indented >> block p)
return (f r1 r2)
indented :: (Stream s (StateT SourcePos m) Char, Monad m) => IndentParserT s u m ()
indented = do
pos <- getPosition
s <- get
if biAp sourceColumn (<) pos s then mzero else do
put $ setSourceLine s (sourceLine pos)
return ()
sameOrIndented :: (Stream s (StateT SourcePos m) Char, Monad m) => IndentParserT s u m ()
sameOrIndented = same <|> indented
same :: (Stream s (StateT SourcePos m) Char, Monad m) => IndentParserT s u m ()
same = do
pos <- getPosition
s <- get
if biAp sourceLine (==) pos s then return () else mzero
block :: (Stream s (StateT SourcePos m) Char, Monad m) => IndentParserT s u m a -> IndentParserT s u m [a]
block p = withPos $ do
r <- many1 (checkIndent >> p)
return r
withPos :: (Stream s (StateT SourcePos m) Char, Monad m) => IndentParserT s u m a -> IndentParserT s u m a
withPos x = do
a <- get
p <- getPosition
r <- put p >> x
put a >> return r
checkIndent :: (Stream s (StateT SourcePos m) Char, Monad m) => IndentParserT s u m ()
checkIndent = do
s <- get
p <- getPosition
if biAp sourceColumn (==) p s then return () else mzero
runIndent :: Monad m => SourceName -> StateT SourcePos m a -> m a
runIndent s = flip evalStateT (initialPos s)
manyLine :: (Stream s (StateT SourcePos m) Char, Monad m) => IndentParserT s u m a -> IndentParserT s u m [a]
manyLine p = withPos (many (same >> p))
manyIndent :: (Stream s (StateT SourcePos m) Char, Monad m) => IndentParserT s u m a -> IndentParserT s u m [a]
manyIndent p = withPos (many (sameOrIndented >> p))
foldLine :: (Stream s (StateT SourcePos m) Char, Monad m) =>
(a -> b -> c) -> IndentParserT s u m a -> IndentParserT s u m b -> IndentParserT s u m c
foldLine f a b = withPos $ do
r1 <- a
r2 <- sameOrIndented >> b
return $ f r1 r2
foldLine3 :: (Stream s (StateT SourcePos m) Char, Monad m) =>
(a -> b -> c -> d) -> IndentParserT s u m a -> IndentParserT s u m b
-> IndentParserT s u m c -> IndentParserT s u m d
foldLine3 f a b c = withPos $ do
r1 <- a
r2 <- sameOrIndented >> b
r3 <- sameOrIndented >> c
return $ f r1 r2 r3
foldLine4 :: (Stream s (StateT SourcePos m) Char, Monad m) =>
(a -> b -> c -> d -> e) -> IndentParserT s u m a -> IndentParserT s u m b
-> IndentParserT s u m c -> IndentParserT s u m d -> IndentParserT s u m e
foldLine4 f a b c d = withPos $ do
r1 <- a
r2 <- sameOrIndented >> b
r3 <- sameOrIndented >> c
r4 <- sameOrIndented >> d
return $ f r1 r2 r3 r4
foldLine5 :: (Stream s (StateT SourcePos m) Char, Monad m) =>
(a -> b -> c -> d -> e -> f) -> IndentParserT s u m a -> IndentParserT s u m b
-> IndentParserT s u m c -> IndentParserT s u m d -> IndentParserT s u m e
-> IndentParserT s u m f
foldLine5 f a b c d e = withPos $ do
r1 <- a
r2 <- sameOrIndented >> b
r3 <- sameOrIndented >> c
r4 <- sameOrIndented >> d
r5 <- sameOrIndented >> e
return $ f r1 r2 r3 r4 r5
(<+/>) :: (Stream s (StateT SourcePos m) Char, Monad m) =>
IndentParserT s u m (a -> b) -> IndentParserT s u m a -> IndentParserT s u m b
(<+/>) = foldLine id
(<-/>) :: (Stream s (StateT SourcePos m) Char, Monad m) =>
IndentParserT s u m a -> IndentParserT s u m b -> IndentParserT s u m a
(<-/>) = foldLine const