From bc5797c31a154efe3d2ca857ae8ace710001e5c0 Mon Sep 17 00:00:00 2001
From: Mikhail Vorozhtsov <mikhail.vorozhtsov@gmail.com>
Date: Sun, 15 Jul 2012 00:56:17 +0700
Subject: [PATCH] Added multi-way if-expressions support.
---
Language/Haskell/TH.hs | 2 +-
Language/Haskell/TH/Lib.hs | 3 +++
Language/Haskell/TH/Ppr.hs | 24 ++++++++++++++++++------
Language/Haskell/TH/PprLib.hs | 4 +++-
Language/Haskell/TH/Syntax.hs | 1 +
5 files changed, 26 insertions(+), 8 deletions(-)
diff --git a/Language/Haskell/TH.hs b/Language/Haskell/TH.hs
index fc4722f..8e36af7 100644
|
a
|
b
|
|
| 56 | 56 | -- *** Expressions |
| 57 | 57 | dyn, global, varE, conE, litE, appE, uInfixE, parensE, |
| 58 | 58 | infixE, infixApp, sectionL, sectionR, |
| 59 | | lamE, lam1E, lamCaseE, tupE, condE, letE, caseE, appsE, |
| | 59 | lamE, lam1E, lamCaseE, tupE, condE, multiIfE, letE, caseE, appsE, |
| 60 | 60 | listE, sigE, recConE, recUpdE, stringE, fieldExp, |
| 61 | 61 | -- **** Ranges |
| 62 | 62 | fromE, fromThenE, fromToE, fromThenToE, |
diff --git a/Language/Haskell/TH/Lib.hs b/Language/Haskell/TH/Lib.hs
index 1edeb0b..52865ad 100644
|
a
|
b
|
|
| 254 | 254 | condE :: ExpQ -> ExpQ -> ExpQ -> ExpQ |
| 255 | 255 | condE x y z = do { a <- x; b <- y; c <- z; return (CondE a b c)} |
| 256 | 256 | |
| | 257 | multiIfE :: [Q (Guard, Exp)] -> ExpQ |
| | 258 | multiIfE alts = sequence alts >>= return . MultiIfE |
| | 259 | |
| 257 | 260 | letE :: [DecQ] -> ExpQ -> ExpQ |
| 258 | 261 | letE ds e = do { ds2 <- sequence ds; e2 <- e; return (LetE ds2 e2) } |
| 259 | 262 | |
diff --git a/Language/Haskell/TH/Ppr.hs b/Language/Haskell/TH/Ppr.hs
index a53fffe..a1d08e2 100644
|
a
|
b
|
|
| 115 | 115 | = parensIf (i > noPrec) $ sep [text "if" <+> ppr guard, |
| 116 | 116 | nest 1 $ text "then" <+> ppr true, |
| 117 | 117 | nest 1 $ text "else" <+> ppr false] |
| | 118 | pprExp i (MultiIfE alts) |
| | 119 | = parensIf (i > noPrec) $ vcat $ |
| | 120 | case alts of |
| | 121 | [] -> [text "if {}"] |
| | 122 | (alt : alts') -> text "if" <+> pprGuarded arrow alt |
| | 123 | : map (nest 3 . pprGuarded arrow) alts' |
| 118 | 124 | pprExp i (LetE ds e) = parensIf (i > noPrec) $ text "let" <+> ppr ds |
| 119 | 125 | $$ text " in" <+> ppr e |
| 120 | 126 | pprExp i (CaseE e ms) |
| … |
… |
|
| 156 | 162 | $$ where_clause ds |
| 157 | 163 | |
| 158 | 164 | ------------------------------ |
| | 165 | pprGuarded :: Doc -> (Guard, Exp) -> Doc |
| | 166 | pprGuarded eqDoc (guard, expr) = case guard of |
| | 167 | NormalG guardExpr -> char '|' <+> ppr guardExpr <+> eqDoc <+> ppr expr |
| | 168 | PatG stmts -> char '|' <+> vcat (punctuate comma $ map ppr stmts) $$ |
| | 169 | nest nestDepth (eqDoc <+> ppr expr) |
| | 170 | |
| | 171 | ------------------------------ |
| 159 | 172 | pprBody :: Bool -> Body -> Doc |
| 160 | | pprBody eq (GuardedB xs) = nest nestDepth $ vcat $ map do_guard xs |
| 161 | | where eqd = if eq then text "=" else text "->" |
| 162 | | do_guard (NormalG g, e) = text "|" <+> ppr g <+> eqd <+> ppr e |
| 163 | | do_guard (PatG ss, e) = text "|" <+> vcat (map ppr ss) |
| 164 | | $$ nest nestDepth (eqd <+> ppr e) |
| 165 | | pprBody eq (NormalB e) = (if eq then text "=" else text "->") <+> ppr e |
| | 173 | pprBody eq body = case body of |
| | 174 | GuardedB xs -> nest nestDepth $ vcat $ map (pprGuarded eqDoc) xs |
| | 175 | NormalB e -> eqDoc <+> ppr e |
| | 176 | where eqDoc | eq = equals |
| | 177 | | otherwise = arrow |
| 166 | 178 | |
| 167 | 179 | ------------------------------ |
| 168 | 180 | pprLit :: Precedence -> Lit -> Doc |
diff --git a/Language/Haskell/TH/PprLib.hs b/Language/Haskell/TH/PprLib.hs
index e42c986..42856bb 100644
|
a
|
b
|
|
| 10 | 10 | |
| 11 | 11 | -- * Primitive Documents |
| 12 | 12 | empty, |
| 13 | | semi, comma, colon, space, equals, |
| | 13 | semi, comma, colon, space, equals, arrow, |
| 14 | 14 | lparen, rparen, lbrack, rbrack, lbrace, rbrace, |
| 15 | 15 | |
| 16 | 16 | -- * Converting values into documents |
| … |
… |
|
| 63 | 63 | colon :: Doc; -- ^ A ':' character |
| 64 | 64 | space :: Doc; -- ^ A space character |
| 65 | 65 | equals :: Doc; -- ^ A '=' character |
| | 66 | arrow :: Doc; -- ^ A "->" string |
| 66 | 67 | lparen :: Doc; -- ^ A '(' character |
| 67 | 68 | rparen :: Doc; -- ^ A ')' character |
| 68 | 69 | lbrack :: Doc; -- ^ A '[' character |
| … |
… |
|
| 163 | 164 | colon = return HPJ.colon |
| 164 | 165 | space = return HPJ.space |
| 165 | 166 | equals = return HPJ.equals |
| | 167 | arrow = return $ HPJ.text "->" |
| 166 | 168 | lparen = return HPJ.lparen |
| 167 | 169 | rparen = return HPJ.rparen |
| 168 | 170 | lbrack = return HPJ.lbrack |
diff --git a/Language/Haskell/TH/Syntax.hs b/Language/Haskell/TH/Syntax.hs
index 65aff77..d9c1dcc 100644
|
a
|
b
|
|
| 866 | 866 | | TupE [Exp] -- ^ @{ (e1,e2) } @ |
| 867 | 867 | | UnboxedTupE [Exp] -- ^ @{ (# e1,e2 #) } @ |
| 868 | 868 | | CondE Exp Exp Exp -- ^ @{ if e1 then e2 else e3 }@ |
| | 869 | | MultiIfE [(Guard, Exp)] -- ^ @{ if | g1 -> e1 | g2 -> e2 }@ |
| 869 | 870 | | LetE [Dec] Exp -- ^ @{ let x=e1; y=e2 in e3 }@ |
| 870 | 871 | | CaseE Exp [Match] -- ^ @{ case e of m1; m2 }@ |
| 871 | 872 | | DoE [Stmt] -- ^ @{ do { p <- e1; e2 } }@ |