{-# LANGUAGE FlexibleContexts, FlexibleInstances, MultiParamTypeClasses, RecordWildCards,
TypeFamilies, TemplateHaskell #-}
module Conditionals where
import Control.Applicative
import Data.Monoid ((<>))
import qualified Rank2.TH
import Text.Grampa
import Text.Grampa.ContextFree.LeftRecursive (Parser)
class ConditionalDomain c e where
ifThenElse :: c -> e -> e -> e
instance ConditionalDomain Bool e where
ifThenElse True t _ = t
ifThenElse False _ f = f
instance ConditionalDomain [Char] [Char] where
ifThenElse cond t f = "if " <> cond <> " then " <> t <> " else " <> f
data Conditionals t e f = Conditionals{expr :: f e,
test :: f t,
term :: f e}
instance (Show (f t), Show (f e)) => Show (Conditionals t e f) where
showsPrec prec a rest = "Conditionals{expr=" ++ showsPrec prec (expr a)
(", test= " ++ showsPrec prec (test a)
(", term= " ++ showsPrec prec (term a) ("}" ++ rest)))
instance TokenParsing (Parser (Conditionals t e) String)
instance LexicalParsing (Parser (Conditionals t e) String)
$(Rank2.TH.deriveAll ''Conditionals)
conditionals :: (ConditionalDomain t e, LexicalParsing (Parser g String))
=> GrammarBuilder (Conditionals t e) g Parser String
conditionals Conditionals{..} =
Conditionals{expr= ifThenElse <$> (keyword "if" *> test) <*> (keyword "then" *> term) <*> (keyword "else" *> term),
test= empty,
term= empty}