@@ -1,17 +1,31 @@
1{-# LANGUAGE FlexibleInstances #-}
1{-# LANGUAGE FlexibleInstances #-}
2{-# LANGUAGE UndecidableInstances #-}
2{-# LANGUAGE UndecidableInstances #-}
3{-# LANGUAGE MultiParamTypeClasses #-}
3{-# LANGUAGE MultiParamTypeClasses #-}
5+Module : Data.Syntax.Indent
6+Description : Indentation.
7+Copyright : (c) Paweł Nowak
10+Maintainer : Paweł Nowak <pawel834@gmail.com>
11+Stability : experimental
13+Provides a very simple indentation as a \"monad\" transformer.
4−module Data.Syntax.Indent where
15+module Data.Syntax.Indent (
6−import Control.Lens.SemiIso
7−import Data.Char (isSpace)
8import Data.SemiIsoFunctor
22import Data.SemiIsoFunctor
9−import Data.Sequences (fromList)
10import Data.Syntax
23import Data.Syntax
11import Data.Syntax.Char
24import Data.Syntax.Char
12import Data.Syntax.Combinator
25import Data.Syntax.Combinator
13import Prelude hiding (takeWhile, take)
26import Prelude hiding (takeWhile, take)
28+-- | Adds indentation to a syntax description.
15newtype Indent m a = Indent { unIndent :: (Int, m ()) -> m a }
29newtype Indent m a = Indent { unIndent :: (Int, m ()) -> m a }
17instance SemiIsoFunctor m => SemiIsoFunctor (Indent m) where
31instance SemiIsoFunctor m => SemiIsoFunctor (Indent m) where
@@ -48,11 +62,16 @@ instance SyntaxChar syn seq => SyntaxChar (Indent syn) seq where
48 decimal = Indent $ const decimal
62 decimal = Indent $ const decimal
49 scientific = Indent $ const scientific
63 scientific = Indent $ const scientific
65+-- | @runIndent m tab@ runs the 'Indent' transformer using @tab@ once for each
66+-- level of indentation.
67+runIndent :: Indent m a -> m () -> m a
68+runIndent = ($ 0) . curry . unIndent
70+-- | Inserts a new line and correct indentation, but does not
71+-- require any formatting when parsing (it just skips all white space).
51breakLine :: SyntaxChar syn seq => Indent syn ()
72breakLine :: SyntaxChar syn seq => Indent syn ()
52breakLine = Indent $ \(i, tab) -> opt (char '\n') /* opt (sireplicate_ i tab) /* spaces_
73breakLine = Indent $ \(i, tab) -> opt (char '\n') /* opt (sireplicate_ i tab) /* spaces_
75+-- | Increases the indentation level of its argument by one.
54indented :: Indent m a -> Indent m a
76indented :: Indent m a -> Indent m a
55indented (Indent f) = Indent $ \(i, tab) -> f (i + 1, tab)
77indented (Indent f) = Indent $ \(i, tab) -> f (i + 1, tab)
57−runIndent :: Indent m a -> m () -> m a
58−runIndent = ($ 0) . curry . unIndent