plzwrk-0.0.0.4: src/Web/Framework/Plzwrk/TH/QuoteHSX.hs
module Web.Framework.Plzwrk.TH.QuoteHSX
( hsx
, hsx'
, hmFromList
)
where
import Data.List.Split
import qualified Data.Hashable as H
import qualified Language.Haskell.TH as TH
import Language.Haskell.Meta.Parse ( parseExp )
import Language.Haskell.TH.Quote
import Language.Haskell.TH.Syntax
import Web.Framework.Plzwrk.TH.HSX
import Web.Framework.Plzwrk.Base
import qualified Data.HashMap.Strict as HM
import qualified Data.Set as S
hsx :: QuasiQuoter
hsx = QuasiQuoter { quoteExp = quoteExprExp True
, quotePat = undefined
, quoteDec = undefined
, quoteType = undefined
}
hsx' :: QuasiQuoter
hsx' = QuasiQuoter { quoteExp = quoteExprExp False
, quotePat = undefined
, quoteDec = undefined
, quoteType = undefined
}
haskize y = either
(\s -> TH.appE
(TH.varE (TH.mkName "error"))
(TH.litE (TH.StringL $ "Could not parse: " <> y <> " due to error " <> s))
)
returnQ
(parseExp y)
hmFromList :: (Eq k, H.Hashable k) => [(k, v)] -> HM.HashMap k v
hmFromList = HM.fromList
hsxAttributeToExpQ :: (String, HSXAttribute) -> TH.Q TH.Exp
hsxAttributeToExpQ (k, HSXStringAttribute v) = TH.tupE
[ TH.litE (TH.StringL k)
, TH.lamE
[TH.varP (TH.mkName "_")]
(TH.appE (TH.conE (TH.mkName "PwTextAttribute")) (TH.litE (TH.StringL v)))
]
hsxAttributeToExpQ (k, HSXHaskellCodeAttribute v) = TH.tupE
[ TH.litE (TH.StringL k)
, TH.lamE [TH.varP (TH.mkName "_")]
(TH.appE (TH.conE (TH.mkName "PwFunctionAttribute")) (haskize v))
]
hsxAttributeToExpQ (k, HSXHaskellTxtAttribute v) = TH.tupE
[ TH.litE (TH.StringL k)
, TH.lamE [TH.varP (TH.mkName "_")]
(TH.appE (TH.conE (TH.mkName "PwTextAttribute")) (haskize v))
]
wrapInLambda :: Bool -> TH.Q TH.Exp -> TH.Q TH.Exp
wrapInLambda True e = TH.lamE [TH.varP (TH.mkName "_")] e
wrapInLambda False e = e
hsxToExpQ :: Bool -> HSX -> TH.Q TH.Exp
hsxToExpQ lam (HSXHaskellCode y ) = haskize y
hsxToExpQ lam (HSXHaskellText y ) = wrapInLambda True $ TH.appE (TH.conE (TH.mkName "PwTextNode")) (haskize y)
hsxToExpQ lam (HSXElement tag attrs elts) = wrapInLambda lam $ foldl
TH.appE
(TH.conE (TH.mkName "PwElement"))
[ TH.litE (TH.StringL tag)
, TH.listE (fmap hsxAttributeToExpQ attrs)
, TH.listE (fmap (\x -> hsxToExpQ True x) elts)
]
hsxToExpQ lam (HSXSelfClosingTag tag attrs) = wrapInLambda lam $ foldl
TH.appE
(TH.conE (TH.mkName "PwElement"))
[ (TH.litE (TH.StringL tag))
, TH.listE (fmap hsxAttributeToExpQ attrs)
, (TH.conE (TH.mkName "[]"))
]
hsxToExpQ lam (HSXBody b) = wrapInLambda lam
$ TH.appE (TH.conE (TH.mkName "PwTextNode")) (TH.litE (TH.StringL b))
quoteExprExp b s = do
pos <- getPosition
result <- parseHSX pos s
hsxToExpQ b result
getPosition = fmap transPos TH.location where
transPos loc =
(TH.loc_filename loc, fst (TH.loc_start loc), snd (TH.loc_start loc))