1 {-# LANGUAGE OverloadedStrings #-}
2 module Symantic.Parser.Grammar.Write where
5 import Data.Function (($))
6 import qualified Data.Functor as Pre
7 import Control.Monad (Monad(..))
8 import Data.Maybe (Maybe(..), fromMaybe, catMaybes)
9 import Data.String (IsString(..))
10 import Data.Semigroup (Semigroup(..))
11 import Data.Monoid (Monoid(..))
12 import Symantic.Base.Univariant
13 import Symantic.Parser.Grammar.Combinators
14 import Symantic.Parser.Grammar.Observations
15 import Text.Show (Show(..))
16 import qualified Data.List as List
17 import qualified Control.Monad.Trans.Class as MT
18 import qualified Control.Monad.Trans.Maybe as MT
19 import qualified Control.Monad.Trans.Reader as MT
20 import qualified Data.Text.Lazy as TL
21 import qualified Data.Text.Lazy.Builder as TLB
23 import Symantic.Base.Fixity
26 newtype GramWrite a = GramWrite { unGramWrite :: GramWriteInh -> Maybe TLB.Builder }
28 instance IsString (GramWrite a) where
29 fromString s = GramWrite $ \_inh ->
30 if List.null s then Nothing
31 else Just (fromString s)
33 -- ** Type 'GramWriteInh'
36 { gramWriteInh_indent :: TLB.Builder
37 , gramWriteInh_op :: (Infix, Side)
38 , gramWriteInh_pair :: Pair
41 emptyGramWriteInh :: GramWriteInh
42 emptyGramWriteInh = GramWriteInh
43 { gramWriteInh_indent = "\n"
44 , gramWriteInh_op = (infixN0, SideL)
45 , gramWriteInh_pair = pairParen
48 gramWrite :: GramWrite a -> TL.Text
49 gramWrite (GramWrite r) = TLB.toLazyText $ fromMaybe "" $ r emptyGramWriteInh
52 Semigroup s => IsString s =>
53 GramWriteInh -> Infix -> Maybe s -> Maybe s
54 pairGramWriteInh inh op s =
55 if isPairNeeded (gramWriteInh_op inh) op
56 then Just (fromString o<>" ")<>s<>Just (" "<>fromString c)
58 where (o,c) = gramWriteInh_pair inh
60 instance Sharable GramWrite where
61 def refName x = GramWrite $ \inh ->
62 pairGramWriteInh inh op $
64 <> Just (fromString (show refName))
68 ref refRec refName = GramWrite $ \inh ->
69 pairGramWriteInh inh op $
71 (if refRec then Just "rec " else Nothing) <>
72 Just (fromString (show refName))
75 instance Applicable GramWrite where
76 pure _ = GramWrite $ return Nothing
78 GramWrite x <*> GramWrite y = GramWrite $ \inh ->
80 { gramWriteInh_op = (op, side)
81 , gramWriteInh_pair = pairParen
83 case x (inh' SideL) of
84 Nothing -> y (inh' SideR)
86 case y (inh' SideR) of
89 pairGramWriteInh inh op $
90 Just $ xt <> ", " <> yt
93 instance Alternable GramWrite where
95 try x = GramWrite $ \inh ->
96 pairGramWriteInh inh op $
97 Just "try " <> unGramWrite x inh
100 x <|> y = GramWrite $ \inh ->
101 pairGramWriteInh inh op $
103 { gramWriteInh_op = (op, SideL)
104 , gramWriteInh_pair = pairParen
108 { gramWriteInh_op = (op, SideR)
109 , gramWriteInh_pair = pairParen
111 where op = infixB SideL 3
112 instance Charable GramWrite where
114 instance Selectable GramWrite where
115 branch lr l r = GramWrite $ \inh ->
116 pairGramWriteInh inh op $
118 unGramWrite lr inh <> Just " " <>
119 unGramWrite l inh <> Just " " <>
123 instance Matchable GramWrite where
124 conditional _cs bs a b = GramWrite $ \inh ->
125 pairGramWriteInh inh op $
126 Just "conditional " <>
128 Just (mconcat (List.intersperse ", " $
129 catMaybes $ (Pre.<$> bs) $ \x ->
130 unGramWrite x inh{gramWriteInh_op=(infixN 0, SideL)})) <>
132 unGramWrite a inh <> Just " " <>
136 instance Lookable GramWrite where
137 look x = GramWrite $ \inh ->
138 pairGramWriteInh inh op $
139 Just "look " <> unGramWrite x inh
141 negLook x = GramWrite $ \inh ->
142 pairGramWriteInh inh op $
143 Just "negLook " <> unGramWrite x inh
145 instance Foldable GramWrite where
146 chainPre f x = GramWrite $ \inh ->
147 pairGramWriteInh inh op $
149 unGramWrite f inh <> Just " " <>
152 chainPost f x = GramWrite $ \inh ->
153 pairGramWriteInh inh op $
155 unGramWrite f inh <> Just " " <>