{-# LANGUAGE CPP #-}
module Curry.CondCompile.Type
( Program, Stmt (..), Else (..), Elif (..), Cond (..), Op (..)
) where
#if __GLASGOW_HASKELL__ >= 804
import Prelude hiding ((<>))
#endif
import Curry.Base.Pretty
type Program = [Stmt]
data Stmt = If Cond [Stmt] [Elif] Else
| IfDef String [Stmt] [Elif] Else
| IfNDef String [Stmt] [Elif] Else
| Define String Int
| Undef String
| Line String
deriving Int -> Stmt -> ShowS
[Stmt] -> ShowS
Stmt -> String
(Int -> Stmt -> ShowS)
-> (Stmt -> String) -> ([Stmt] -> ShowS) -> Show Stmt
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [Stmt] -> ShowS
$cshowList :: [Stmt] -> ShowS
show :: Stmt -> String
$cshow :: Stmt -> String
showsPrec :: Int -> Stmt -> ShowS
$cshowsPrec :: Int -> Stmt -> ShowS
Show
newtype Else = Else (Maybe [Stmt])
deriving Int -> Else -> ShowS
[Else] -> ShowS
Else -> String
(Int -> Else -> ShowS)
-> (Else -> String) -> ([Else] -> ShowS) -> Show Else
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [Else] -> ShowS
$cshowList :: [Else] -> ShowS
show :: Else -> String
$cshow :: Else -> String
showsPrec :: Int -> Else -> ShowS
$cshowsPrec :: Int -> Else -> ShowS
Show
newtype Elif = Elif (Cond, [Stmt])
deriving Int -> Elif -> ShowS
[Elif] -> ShowS
Elif -> String
(Int -> Elif -> ShowS)
-> (Elif -> String) -> ([Elif] -> ShowS) -> Show Elif
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [Elif] -> ShowS
$cshowList :: [Elif] -> ShowS
show :: Elif -> String
$cshow :: Elif -> String
showsPrec :: Int -> Elif -> ShowS
$cshowsPrec :: Int -> Elif -> ShowS
Show
data Cond = Comp String Op Int
| Defined String
| NDefined String
deriving Int -> Cond -> ShowS
[Cond] -> ShowS
Cond -> String
(Int -> Cond -> ShowS)
-> (Cond -> String) -> ([Cond] -> ShowS) -> Show Cond
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [Cond] -> ShowS
$cshowList :: [Cond] -> ShowS
show :: Cond -> String
$cshow :: Cond -> String
showsPrec :: Int -> Cond -> ShowS
$cshowsPrec :: Int -> Cond -> ShowS
Show
data Op = Eq
| Neq
| Lt
| Leq
| Gt
| Geq
deriving Int -> Op -> ShowS
[Op] -> ShowS
Op -> String
(Int -> Op -> ShowS)
-> (Op -> String) -> ([Op] -> ShowS) -> Show Op
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [Op] -> ShowS
$cshowList :: [Op] -> ShowS
show :: Op -> String
$cshow :: Op -> String
showsPrec :: Int -> Op -> ShowS
$cshowsPrec :: Int -> Op -> ShowS
Show
instance Pretty Stmt where
pPrint :: Stmt -> Doc
pPrint (If c :: Cond
c stmts :: [Stmt]
stmts is :: [Elif]
is e :: Else
e) = String -> Doc -> [Stmt] -> [Elif] -> Else -> Doc
prettyIf "#if" (Cond -> Doc
forall a. Pretty a => a -> Doc
pPrint Cond
c) [Stmt]
stmts [Elif]
is Else
e
pPrint (IfDef v :: String
v stmts :: [Stmt]
stmts is :: [Elif]
is e :: Else
e) = String -> Doc -> [Stmt] -> [Elif] -> Else -> Doc
prettyIf "#ifdef" (String -> Doc
text String
v) [Stmt]
stmts [Elif]
is Else
e
pPrint (IfNDef v :: String
v stmts :: [Stmt]
stmts is :: [Elif]
is e :: Else
e) = String -> Doc -> [Stmt] -> [Elif] -> Else -> Doc
prettyIf "#ifndef" (String -> Doc
text String
v) [Stmt]
stmts [Elif]
is Else
e
pPrint (Define v :: String
v i :: Int
i ) = String -> Doc
text "#define" Doc -> Doc -> Doc
<+> String -> Doc
text String
v Doc -> Doc -> Doc
<+> Int -> Doc
int Int
i
pPrint (Undef v :: String
v ) = String -> Doc
text "#undef" Doc -> Doc -> Doc
<+> String -> Doc
text String
v
pPrint (Line s :: String
s ) = String -> Doc
text String
s
pPrintList :: [Stmt] -> Doc
pPrintList = (Stmt -> Doc -> Doc) -> Doc -> [Stmt] -> Doc
forall (t :: * -> *) a b.
Foldable t =>
(a -> b -> b) -> b -> t a -> b
foldr (Doc -> Doc -> Doc
($+$) (Doc -> Doc -> Doc) -> (Stmt -> Doc) -> Stmt -> Doc -> Doc
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Stmt -> Doc
forall a. Pretty a => a -> Doc
pPrint) Doc
empty
instance Pretty Elif where
pPrint :: Elif -> Doc
pPrint (Elif (c :: Cond
c, stmts :: [Stmt]
stmts)) = String -> Doc
text "#elif" Doc -> Doc -> Doc
<+> Cond -> Doc
forall a. Pretty a => a -> Doc
pPrint Cond
c Doc -> Doc -> Doc
$+$ [Stmt] -> Doc
forall a. Pretty a => a -> Doc
pPrint [Stmt]
stmts
pPrintList :: [Elif] -> Doc
pPrintList = (Elif -> Doc -> Doc) -> Doc -> [Elif] -> Doc
forall (t :: * -> *) a b.
Foldable t =>
(a -> b -> b) -> b -> t a -> b
foldr (Doc -> Doc -> Doc
($+$) (Doc -> Doc -> Doc) -> (Elif -> Doc) -> Elif -> Doc -> Doc
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Elif -> Doc
forall a. Pretty a => a -> Doc
pPrint) Doc
empty
instance Pretty Else where
pPrint :: Else -> Doc
pPrint (Else (Just stmts :: [Stmt]
stmts)) = String -> Doc
text "#else" Doc -> Doc -> Doc
$+$ [Stmt] -> Doc
forall a. Pretty a => a -> Doc
pPrint [Stmt]
stmts
pPrint (Else Nothing) = Doc
empty
prettyIf :: String -> Doc -> [Stmt] -> [Elif] -> Else -> Doc
prettyIf :: String -> Doc -> [Stmt] -> [Elif] -> Else -> Doc
prettyIf k :: String
k doc :: Doc
doc stmts :: [Stmt]
stmts is :: [Elif]
is e :: Else
e = (Doc -> Doc -> Doc) -> Doc -> [Doc] -> Doc
forall (t :: * -> *) a b.
Foldable t =>
(a -> b -> b) -> b -> t a -> b
foldr Doc -> Doc -> Doc
($+$) Doc
empty
[String -> Doc
text String
k Doc -> Doc -> Doc
<+> Doc
doc, [Stmt] -> Doc
forall a. Pretty a => a -> Doc
pPrint [Stmt]
stmts, [Elif] -> Doc
forall a. Pretty a => a -> Doc
pPrint [Elif]
is, Else -> Doc
forall a. Pretty a => a -> Doc
pPrint Else
e, String -> Doc
text "#endif"]
instance Pretty Cond where
pPrint :: Cond -> Doc
pPrint (Comp v :: String
v op :: Op
op i :: Int
i) = String -> Doc
text String
v Doc -> Doc -> Doc
<+> Op -> Doc
forall a. Pretty a => a -> Doc
pPrint Op
op Doc -> Doc -> Doc
<+> Int -> Doc
int Int
i
pPrint (Defined v :: String
v ) = String -> Doc
text "defined(" Doc -> Doc -> Doc
<> String -> Doc
text String
v Doc -> Doc -> Doc
<> Char -> Doc
char ')'
pPrint (NDefined v :: String
v ) = String -> Doc
text "!defined(" Doc -> Doc -> Doc
<> String -> Doc
text String
v Doc -> Doc -> Doc
<> Char -> Doc
char ')'
instance Pretty Op where
pPrint :: Op -> Doc
pPrint Eq = String -> Doc
text "=="
pPrint Neq = String -> Doc
text "/="
pPrint Lt = String -> Doc
text "<"
pPrint Leq = String -> Doc
text "<="
pPrint Gt = String -> Doc
text ">"
pPrint Geq = String -> Doc
text ">="