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 Letable GramWrite where
61 let_ letRec letName = GramWrite $ \inh ->
62 pairGramWriteInh inh op $
64 (if letRec then Just "rec " else Nothing) <>
65 Just (fromString (show letName))
68 instance Applicable GramWrite where
69 pure _ = GramWrite $ return Nothing
71 GramWrite x <*> GramWrite y = GramWrite $ \inh ->
73 { gramWriteInh_op = (op, side)
74 , gramWriteInh_pair = pairParen
76 case x (inh' SideL) of
77 Nothing -> y (inh' SideR)
79 case y (inh' SideR) of
82 pairGramWriteInh inh op $
83 Just $ xt <> ", " <> yt
86 instance Alternable GramWrite where
88 try x = GramWrite $ \inh ->
89 pairGramWriteInh inh op $
90 Just "try " <> unGramWrite x inh
93 x <|> y = GramWrite $ \inh ->
94 pairGramWriteInh inh op $
96 { gramWriteInh_op = (op, SideL)
97 , gramWriteInh_pair = pairParen
101 { gramWriteInh_op = (op, SideR)
102 , gramWriteInh_pair = pairParen
104 where op = infixB SideL 3
105 instance Charable GramWrite where
107 instance Selectable GramWrite where
108 branch lr l r = GramWrite $ \inh ->
109 pairGramWriteInh inh op $
111 unGramWrite lr inh <> Just " " <>
112 unGramWrite l inh <> Just " " <>
116 instance Matchable GramWrite where
117 conditional _cs bs a b = GramWrite $ \inh ->
118 pairGramWriteInh inh op $
119 Just "conditional " <>
121 Just (mconcat (List.intersperse ", " $
122 catMaybes $ (Pre.<$> bs) $ \x ->
123 unGramWrite x inh{gramWriteInh_op=(infixN 0, SideL)})) <>
125 unGramWrite a inh <> Just " " <>
129 instance Lookable GramWrite where
130 look x = GramWrite $ \inh ->
131 pairGramWriteInh inh op $
132 Just "look " <> unGramWrite x inh
134 negLook x = GramWrite $ \inh ->
135 pairGramWriteInh inh op $
136 Just "negLook " <> unGramWrite x inh
138 instance Foldable GramWrite where
139 chainPre f x = GramWrite $ \inh ->
140 pairGramWriteInh inh op $
142 unGramWrite f inh <> Just " " <>
145 chainPost f x = GramWrite $ \inh ->
146 pairGramWriteInh inh op $
148 unGramWrite f inh <> Just " " <>