@@ -0,0 +1,59 @@
1+{-# LANGUAGE FlexibleInstances #-}
2+{-# LANGUAGE UndecidableInstances #-}
3+{-# LANGUAGE MultiParamTypeClasses #-}
4+module Data.Syntax.Indent where
6+import Control.Lens.SemiIso
7+import Data.Char (isSpace)
8+import Data.SemiIsoFunctor
9+import Data.Sequences (fromList)
11+import Data.Syntax.Char
12+import Data.Syntax.Combinator
13+import Prelude hiding (takeWhile, take)
15+newtype Indent m a = Indent { unIndent :: Int -> m a }
17+instance SemiIsoFunctor m => SemiIsoFunctor (Indent m) where
18+ simap f (Indent g) = Indent $ \i -> simap f (g i)
20+instance SemiIsoApply m => SemiIsoApply (Indent m) where
21+ sipure ai = Indent $ \_ -> sipure ai
22+ Indent f /*/ Indent g = Indent $ \i -> f i /*/ g i
24+instance SemiIsoAlternative m => SemiIsoAlternative (Indent m) where
25+ siempty = Indent $ \_ -> siempty
26+ Indent f /|/ Indent g = Indent $ \i -> f i /|/ g i
28+instance SemiIsoMonad m => SemiIsoMonad (Indent m) where
29+ (Indent m) //= f = Indent $ \i -> m i //= (\x -> unIndent (f x) i)
31+instance SemiIsoFix m => SemiIsoFix (Indent m) where
32+ sifix f = Indent $ \i -> sifix $ \y -> unIndent (f y) i
34+instance Syntax syn seq => Syntax (Indent syn) seq where
35+ anyChar = Indent $ const anyChar
36+ char = Indent . const . char
37+ notChar = Indent . const . notChar
38+ satisfy = Indent . const . satisfy
39+ satisfyWith ai = Indent . const . satisfyWith ai
40+ string = Indent . const . string
41+ take = Indent . const . take
42+ takeWhile = Indent . const . takeWhile
43+ takeWhile1 = Indent . const . takeWhile1
44+ takeTill = Indent . const . takeTill
45+ takeTill1 = Indent . const . takeTill1
47+instance SyntaxChar syn seq => SyntaxChar (Indent syn) seq where
48+ decimal = Indent $ const decimal
49+ scientific = Indent $ const scientific
51+breakLine :: SyntaxChar syn seq => Indent syn ()
52+breakLine = Indent $ \i -> opt (char '\n') /*
53+ (constant (fromList $ replicate (4*i) ' ') /$/ takeWhile isSpace)
55+indented :: Indent m a -> Indent m a
56+indented (Indent f) = Indent $ \i -> f (i + 1)
58+runIndent :: Indent m a -> m a
59+runIndent = ($ 0) . unIndent