X-Git-Url: http://git.megacz.com/?a=blobdiff_plain;f=docs%2Fusers_guide%2Fglasgow_exts.xml;h=c9e6183d0491d952d530058b2bb187132811985c;hb=1fe5459fe14758dbbc6106f616446f43e21a0511;hp=9b4dc588d32847818b81b96e0e1efdde82c4c572;hpb=493fd9dfc6a7a60a7f5fdc126e2c4b731fbb4c3c;p=ghc-hetmet.git
diff --git a/docs/users_guide/glasgow_exts.xml b/docs/users_guide/glasgow_exts.xml
index 9b4dc58..c9e6183 100644
--- a/docs/users_guide/glasgow_exts.xml
+++ b/docs/users_guide/glasgow_exts.xml
@@ -290,6 +290,17 @@ documentation describes all the libraries that come with GHC.
+
+
+
+ Enables quasiquotation (see ).
+
+ Syntax stolen:
+ [:varid|.
+
+
+
@@ -4985,6 +4996,15 @@ Wiki page.
+ A quasi-quotation can appear in either a pattern context or an
+ expression context and is also written in Oxford brackets:
+
+ [:varid| ... |],
+ where the "..." is an arbitrary string; a full description of the
+ quasi-quotation facility is given in .
+
+
+
A name can be quoted with either one or two prefix single quotes:
'f has type Name, and names the function f.
@@ -5158,6 +5178,124 @@ The basic idea is to compile the program twice:
+ Template Haskell Quasi-quotation
+Quasi-quotation allows patterns and expressions to be written using
+programmer-defined concrete syntax; the motivation behind the extension and
+several examples are documented in
+"Why It's
+Nice to be Quoted: Quasiquoting for Haskell" (Proc Haskell Workshop
+2007). The example below shows how to write a quasiquoter for a simple
+expression language.
+
+
+In the example, the quasiquoter expr is bound to a value of
+type Language.Haskell.TH.Quote.QuasiQuoter which contains two
+functions for quoting expressions and patterns, respectively. The first argument
+to each quoter is the (arbitrary) string enclosed in the Oxford brackets. The
+context of the quasi-quotation statement determines which of the two parsers is
+called: if the quasi-quotation occurs in an expression context, the expression
+parser is called, and if it occurs in a pattern context, the pattern parser is
+called.
+
+
+Note that in the example we make use of an antiquoted
+variable n, indicated by the syntax 'int:n
+(this syntax for anti-quotation was defined by the parser's
+author, not by GHC). This binds n to the
+integer value argument of the constructor IntExpr when
+pattern matching. Please see the referenced paper for further details regarding
+anti-quotation as well as the description of a technique that uses SYB to
+leverage a single parser of type String -> a to generate both
+an expression parser that returns a value of type Q Exp and a
+pattern parser that returns a value of type Q Pat.
+
+
+In general, a quasi-quote has the form
+[$quoter| string |].
+The quoter must be the name of an imported quoter; it
+cannot be an arbitrary expression. The quoted string
+can be arbitrary, and may contain newlines.
+
+
+Quasiquoters must obey the same stage restrictions as Template Haskell, e.g., in
+the example, expr cannot be defined
+in Main.hs where it is used, but must be imported.
+
+
+
+
+{- Main.hs -}
+module Main where
+
+import Expr
+
+main :: IO ()
+main = do { print $ eval [$expr|1 + 2|]
+ ; case IntExpr 1 of
+ { [$expr|'int:n|] -> print n
+ ; _ -> return ()
+ }
+ }
+
+
+{- Expr.hs -}
+module Expr where
+
+import qualified Language.Haskell.TH as TH
+import Language.Haskell.TH.Quasi
+
+data Expr = IntExpr Integer
+ | AntiIntExpr String
+ | BinopExpr BinOp Expr Expr
+ | AntiExpr String
+ deriving(Show, Typeable, Data)
+
+data BinOp = AddOp
+ | SubOp
+ | MulOp
+ | DivOp
+ deriving(Show, Typeable, Data)
+
+eval :: Expr -> Integer
+eval (IntExpr n) = n
+eval (BinopExpr op x y) = (opToFun op) (eval x) (eval y)
+ where
+ opToFun AddOp = (+)
+ opToFun SubOp = (-)
+ opToFun MulOp = (*)
+ opToFun DivOp = div
+
+expr = QuasiQuoter parseExprExp parseExprPat
+
+-- Parse an Expr, returning its representation as
+-- either a Q Exp or a Q Pat. See the referenced paper
+-- for how to use SYB to do this by writing a single
+-- parser of type String -> Expr instead of two
+-- separate parsers.
+
+parseExprExp :: String -> Q Exp
+parseExprExp ...
+
+parseExprPat :: String -> Q Pat
+parseExprPat ...
+
+
+Now run the compiler:
+
+
+$ ghc --make -XQuasiQuotes Main.hs -o main
+
+
+Run "main" and here is your output:
+
+
+$ ./main
+3
+1
+
+
+
+
@@ -6171,7 +6309,7 @@ exactly what you asked for, no more and no less.
there was no pragma).
- "INLINE[~k] f" means: be willing to inline
+ "NOINLINE[~k] f" means: be willing to inline
f
until phase k, but from phase
k onwards do not inline it.