1 module Language.Symantic.RNC.Write.Fixity where
4 import Data.Eq (Eq(..))
5 import Data.Function ((.))
7 import Data.Maybe (Maybe(..))
8 import Data.Ord (Ord(..))
10 import Data.String (String, IsString(..))
11 import Text.Show (Show(..))
21 = Prefix { unifix_precedence :: Precedence }
22 | Postfix { unifix_precedence :: Precedence }
28 { infix_associativity :: Maybe Associativity
29 , infix_precedence :: Precedence
32 infixL :: Precedence -> Infix
33 infixL = Infix (Just AssocL)
35 infixR :: Precedence -> Infix
36 infixR = Infix (Just AssocR)
38 infixB :: Side -> Precedence -> Infix
39 infixB = Infix . Just . AssocB
41 infixN :: Precedence -> Infix
42 infixN = Infix Nothing
50 -- | Given 'Precedence' and 'Associativity' of its parent operator,
51 -- and the operand 'Side' it is in,
52 -- return whether an 'Infix' operator
53 -- needs to be enclosed by a 'Pair'.
54 isPairNeeded :: (Infix, Side) -> Infix -> Bool
55 isPairNeeded (po, lr) op =
56 infix_precedence op < infix_precedence po
57 || infix_precedence op == infix_precedence po
61 case (lr, infix_associativity po) of
62 (_, Just AssocB{}) -> True
63 (SideL, Just AssocL) -> True
64 (SideR, Just AssocR) -> True
67 -- | If 'isPairNeeded' is 'True',
68 -- enclose the given 'IsString' by given 'Pair',
69 -- otherwise returns the same 'IsString'.
71 Semigroup s => IsString s =>
72 Pair -> (Infix, Side) -> Infix ->
74 pairIfNeeded (o,c) po op s =
76 then fromString o <> s <> fromString c
79 -- * Type 'Precedence'
82 -- ** Class 'PrecedenceOf'
83 class PrecedenceOf a where
84 precedence :: a -> Precedence
85 instance PrecedenceOf Fixity where
86 precedence (Fixity1 uni) = precedence uni
87 precedence (Fixity2 inf) = precedence inf
88 instance PrecedenceOf Unifix where
89 precedence = unifix_precedence
90 instance PrecedenceOf Infix where
91 precedence = infix_precedence
93 -- * Type 'Associativity'
95 = AssocL -- ^ Associate to the left: @a ¹ b ² c == (a ¹ b) ² c@
96 | AssocR -- ^ Associate to the right: @a ¹ b ² c == a ¹ (b ² c)@
97 | AssocB Side -- ^ Associate to both sides, but to 'Side' when reading.
107 type Pair = (String, String)
108 pairParen, pairBrace :: Pair
109 pairParen = ("(",")")
110 pairBrace = ("{","}")