1 {-# LANGUAGE OverloadedStrings #-}
2 module Symantic.Parser.Grammar.Write where
4 import Data.Function (($))
5 import qualified Data.Functor as Pre
6 import Control.Monad (Monad(..))
7 import Data.Maybe (Maybe(..), fromMaybe, catMaybes)
8 import Data.String (IsString(..))
9 import Data.Semigroup (Semigroup(..))
10 import Data.Monoid (Monoid(..))
11 import Text.Show (Show(..))
12 import qualified Data.List as List
13 import qualified Data.Text.Lazy as TL
14 import qualified Data.Text.Lazy.Builder as TLB
16 import Symantic.Base.Fixity
17 import Symantic.Parser.Grammar.Combinators
18 import Symantic.Parser.Grammar.ObserveSharing
20 -- * Type 'WriteGrammar'
21 newtype WriteGrammar a = WriteGrammar { unWriteGrammar :: WriteGrammarInh -> Maybe TLB.Builder }
23 instance IsString (WriteGrammar a) where
24 fromString s = WriteGrammar $ \_inh ->
25 if List.null s then Nothing
26 else Just (fromString s)
28 -- ** Type 'WriteGrammarInh'
31 { writeGrammarInh_indent :: TLB.Builder
32 , writeGrammarInh_op :: (Infix, Side)
33 , writeGrammarInh_pair :: Pair
36 emptyWriteGrammarInh :: WriteGrammarInh
37 emptyWriteGrammarInh = WriteGrammarInh
38 { writeGrammarInh_indent = "\n"
39 , writeGrammarInh_op = (infixN0, SideL)
40 , writeGrammarInh_pair = pairParen
43 writeGrammar :: WriteGrammar a -> TL.Text
44 writeGrammar (WriteGrammar r) = TLB.toLazyText $ fromMaybe "" $ r emptyWriteGrammarInh
46 pairWriteGrammarInh ::
47 Semigroup s => IsString s =>
48 WriteGrammarInh -> Infix -> Maybe s -> Maybe s
49 pairWriteGrammarInh inh op s =
50 if isPairNeeded (writeGrammarInh_op inh) op
51 then Just (fromString o<>" ")<>s<>Just (" "<>fromString c)
53 where (o,c) = writeGrammarInh_pair inh
55 instance Letable WriteGrammar where
56 def name x = WriteGrammar $ \inh ->
57 pairWriteGrammarInh inh op $
59 <> Just (fromString (show name))
60 <> unWriteGrammar x inh
63 ref rec name = WriteGrammar $ \inh ->
64 pairWriteGrammarInh inh op $
66 (if rec then Just "rec " else Nothing) <>
67 Just (fromString (show name))
70 instance Applicable WriteGrammar where
71 pure _ = WriteGrammar $ return Nothing
73 WriteGrammar x <*> WriteGrammar y = WriteGrammar $ \inh ->
75 { writeGrammarInh_op = (op, side)
76 , writeGrammarInh_pair = pairParen
78 case x (inh' SideL) of
79 Nothing -> y (inh' SideR)
81 case y (inh' SideR) of
84 pairWriteGrammarInh inh op $
85 Just $ xt <> ", " <> yt
88 instance Alternable WriteGrammar where
90 try x = WriteGrammar $ \inh ->
91 pairWriteGrammarInh inh op $
92 Just "try " <> unWriteGrammar x inh
95 x <|> y = WriteGrammar $ \inh ->
96 pairWriteGrammarInh inh op $
98 { writeGrammarInh_op = (op, SideL)
99 , writeGrammarInh_pair = pairParen
103 { writeGrammarInh_op = (op, SideR)
104 , writeGrammarInh_pair = pairParen
106 where op = infixB SideL 3
107 instance Charable WriteGrammar where
109 instance Selectable WriteGrammar where
110 branch lr l r = WriteGrammar $ \inh ->
111 pairWriteGrammarInh inh op $
113 unWriteGrammar lr inh <> Just " " <>
114 unWriteGrammar l inh <> Just " " <>
118 instance Matchable WriteGrammar where
119 conditional _cs bs a b = WriteGrammar $ \inh ->
120 pairWriteGrammarInh inh op $
121 Just "conditional " <>
123 Just (mconcat (List.intersperse ", " $
124 catMaybes $ (Pre.<$> bs) $ \x ->
125 unWriteGrammar x inh{writeGrammarInh_op=(infixN 0, SideL)})) <>
127 unWriteGrammar a inh <> Just " " <>
131 instance Lookable WriteGrammar where
132 look x = WriteGrammar $ \inh ->
133 pairWriteGrammarInh inh op $
134 Just "look " <> unWriteGrammar x inh
136 negLook x = WriteGrammar $ \inh ->
137 pairWriteGrammarInh inh op $
138 Just "negLook " <> unWriteGrammar x inh
140 instance Foldable WriteGrammar where
141 chainPre f x = WriteGrammar $ \inh ->
142 pairWriteGrammarInh inh op $
144 unWriteGrammar f inh <> Just " " <>
147 chainPost f x = WriteGrammar $ \inh ->
148 pairWriteGrammarInh inh op $
150 unWriteGrammar f inh <> Just " " <>