-- Next, match Haddock comments if no -haddock flag
-"-- " $docsym .* / { ifExtension (not . haddockEnabled) } ;
+"-- " [$docsym \#] .* / { ifExtension (not . haddockEnabled) } ;
-- Now, when we've matched comments that begin with 2 dashes and continue
-- with a different character, we need to match comments that begin with three
"|]" / { ifExtension thEnabled } { token ITcloseQuote }
\$ @varid / { ifExtension thEnabled } { skip_one_varid ITidEscape }
"$(" / { ifExtension thEnabled } { token ITparenEscape }
+
+ "[$" @varid "|" / { ifExtension qqEnabled }
+ { lex_quasiquote_tok }
}
<0> {
| ITparenEscape -- $(
| ITvarQuote -- '
| ITtyQuote -- ''
+ | ITquasiQuote (FastString,FastString,SrcSpan) -- [:...|...|]
-- Arrow notation extension
| ITproc
qual_size = orig_buf `byteDiff` dot_buf
varid span buf len =
+ fs `seq`
case lookupUFM reservedWordsFM fs of
Just (keyword,0) -> do
maybe_layout keyword
Just (c,i) -> do setInput i; return c
-- -----------------------------------------------------------------------------
+-- QuasiQuote
+
+lex_quasiquote_tok :: Action
+lex_quasiquote_tok span buf len = do
+ let quoter = reverse $ takeWhile (/= '$')
+ $ reverse $ lexemeToString buf (len - 1)
+ quoteStart <- getSrcLoc
+ quote <- lex_quasiquote ""
+ end <- getSrcLoc
+ return (L (mkSrcSpan (srcSpanStart span) end)
+ (ITquasiQuote (mkFastString quoter,
+ mkFastString (reverse quote),
+ mkSrcSpan quoteStart end)))
+
+lex_quasiquote :: String -> P String
+lex_quasiquote s = do
+ i <- getInput
+ case alexGetChar' i of
+ Nothing -> lit_error
+
+ Just ('\\',i)
+ | Just ('|',i) <- next -> do
+ setInput i; lex_quasiquote ('|' : s)
+ | Just (']',i) <- next -> do
+ setInput i; lex_quasiquote (']' : s)
+ where next = alexGetChar' i
+
+ Just ('|',i)
+ | Just (']',i) <- next -> do
+ setInput i; return s
+ where next = alexGetChar' i
+
+ Just (c, i) -> do
+ setInput i; lex_quasiquote (c : s)
+
+-- -----------------------------------------------------------------------------
-- Warnings
warn :: DynFlag -> SDoc -> Action
fail = failP
returnP :: a -> P a
-returnP a = P $ \s -> POk s a
+returnP a = a `seq` (P $ \s -> POk s a)
thenP :: P a -> (a -> P b) -> P b
(P m) `thenP` k = P $ \ s ->
unboxedTuplesBit = 15 -- (# and #)
standaloneDerivingBit = 16 -- standalone instance deriving declarations
transformComprehensionsBit = 17
+qqBit = 18 -- enable quasiquoting
genericsEnabled, ffiEnabled, parrEnabled :: Int -> Bool
always _ = True
unboxedTuplesEnabled flags = testBit flags unboxedTuplesBit
standaloneDerivingEnabled flags = testBit flags standaloneDerivingBit
transformComprehensionsEnabled flags = testBit flags transformComprehensionsBit
+qqEnabled flags = testBit flags qqBit
-- PState for parsing options pragmas
--
.|. parrBit `setBitIf` dopt Opt_PArr flags
.|. arrowsBit `setBitIf` dopt Opt_Arrows flags
.|. thBit `setBitIf` dopt Opt_TemplateHaskell flags
+ .|. qqBit `setBitIf` dopt Opt_QuasiQuotes flags
.|. ipBit `setBitIf` dopt Opt_ImplicitParams flags
.|. explicitForallBit `setBitIf` dopt Opt_ScopedTypeVariables flags
.|. explicitForallBit `setBitIf` dopt Opt_PolymorphicComponents flags
sc <- getLexState
exts <- getExts
case alexScanUser exts inp sc of
- AlexEOF -> do let span = mkSrcSpan loc1 loc1
- setLastToken span 0 0
- return (L span ITeof)
- AlexError (AI loc2 _ buf) -> do
- reportLexError loc1 loc2 buf "lexical error"
+ AlexEOF -> do
+ let span = mkSrcSpan loc1 loc1
+ setLastToken span 0 0
+ return (L span ITeof)
+ AlexError (AI loc2 _ buf) ->
+ reportLexError loc1 loc2 buf "lexical error"
AlexSkip inp2 _ -> do
- setInput inp2
- lexToken
+ setInput inp2
+ lexToken
AlexToken inp2@(AI end _ buf2) len t -> do
- setInput inp2
- let span = mkSrcSpan loc1 end
- let bytes = byteDiff buf buf2
- span `seq` setLastToken span bytes bytes
- t span buf bytes
+ setInput inp2
+ let span = mkSrcSpan loc1 end
+ let bytes = byteDiff buf buf2
+ span `seq` setLastToken span bytes bytes
+ t span buf bytes
reportLexError loc1 loc2 buf str
| atEnd buf = failLocMsgP loc1 loc2 (str ++ " at end of input")