content: {-# LANGUAGE TemplateHaskell #-}
  {-# LANGUAGE QuasiQuotes #-}
  {- Printf.hs -}
  module TH.Printf where
  
  -- Skeletal printf from the paper.
  -- It needs to be in a separate module to the one where
  -- you intend to use it.
  
  -- Import some Template Haskell syntax
  -- import Language.Haskell.THSyntax
  import Language.Haskell.TH
  import Language.Haskell.TH.Quote
  import qualified Language.Haskell.TH as TH
  
  -- Describe a format string
  data Format = D | S | L String
  
  -- Parse a format string.  This is left largely to you
  -- as we are here interested in building our first ever
  -- Template Haskell program and not in building printf.
  parse :: String -> [Format]
  parse s   = [ L s ]
  
  -- Generate Haskell source code from a parsed representation
  -- of the format string.  This code will be spliced into
  -- the module which calls "pr", at compile time.
  gen :: [Format] -> ExpQ
  gen [D]   = [| \n -> show n |]
  gen [S]   = [| \s -> s |]
  gen [L s] = stringE s
  
  -- Here we generate the Haskell code for the splice
  -- from an input format string.
  pr :: String -> ExpQ
  pr s      = gen (parse s)
  
  -- str :: QuasiQuoter
  -- str = QuasiQuoter { quoteExp = stringE }
  
  silly :: QuasiQuoter
  silly = QuasiQuoter { quoteExp = \_ -> [| "yeah!!!" |] }
  
  silly2 :: QuasiQuoter
  silly2 = QuasiQuoter { quoteExp = \_ -> stringE "yeah!!!"
                       , quotePat = undefined
                       , quoteType = undefined
                       , quoteDec = undefined
                       }
  
  