template-hsml-0.1.0.0: src/Template/HSML/Internal/Parser.hs
{-# LANGUAGE RecordWildCards #-}
module Template.HSML.Internal.Parser
( hsmlParser
, shsmlParser
, hsmlTemplate
, shsmlTemplate
) where
------------------------------------------------------------------------------
import qualified Language.Haskell.Exts.Parser as HE
-- import qualified Language.Haskell.Exts.Extension as HE
-- import qualified Language.Haskell.Exts.Syntax as HE
------------------------------------------------------------------------------
import Control.Applicative
------------------------------------------------------------------------------
import Data.Monoid ((<>))
------------------------------------------------------------------------------
import qualified Text.Parsec.String as P
import qualified Text.Parsec.Prim as P
------------------------------------------------------------------------------
import qualified Template.HSML.Internal.Types as I
import qualified Template.HSML.Internal.Parser.Raw as I
------------------------------------------------------------------------------
hsmlTemplate :: String -> Either String I.Template
hsmlTemplate str =
case P.parse hsmlParser ".HSML" str of
Right tpl -> Right tpl
Left err -> Left $ show err
hsmlParser :: P.Parser I.Template
hsmlParser = I.hsmlParser >>= transform
shsmlTemplate :: String -> Either String I.Template
shsmlTemplate str =
case P.parse shsmlParser ".HSML" str of
Right tpl -> Right tpl
Left err -> Left $ show err
shsmlParser :: P.Parser I.Template
shsmlParser = I.shsmlParser >>= transform
------------------------------------------------------------------------------
transform :: I.RTemplate -> P.Parser I.Template
transform I.Template{..} = do
args <- mapM transformArg templateArgs
decs <- mapM transformDec templateDecs
sections <- mapM transformSection templateSections
return I.Template
{ I.templateArgs = args
, I.templateDecs = decs
, I.templateSections = sections
}
transformArg :: I.RArg -> P.Parser I.Arg
transformArg (I.RArg name mtype) =
case mtype of
Just stype ->
case HE.parseType stype of
HE.ParseOk t -> return . I.Arg name $ Just t
HE.ParseFailed _ r -> fail $ "Could not parse type \"" <> stype <> "\", reason: " <> r
Nothing -> return $ I.Arg name Nothing
transformDec :: I.RDec -> P.Parser I.Dec
transformDec (I.RDec sdec) =
case HE.parseDecl sdec of
HE.ParseOk d -> return $ I.Dec d
HE.ParseFailed _ r -> fail $ "Could not parse declaration \"" <> sdec <> "\", reason: " <> r
transformExp :: I.RExp -> P.Parser I.Exp
transformExp (I.RExp sexp) =
case HE.parseExp sexp of
HE.ParseOk e -> return $ I.Exp e
HE.ParseFailed _ r -> fail $ "Could not parse expression \"" <> sexp <> "\", reason: " <> r
transformSection :: I.RSection -> P.Parser I.Section
transformSection (I.ElementNode name rattributes rsections) = do
attributes <- mapM transformAttribute rattributes
sections <- mapM transformSection rsections
return $ I.ElementNode name attributes sections
transformSection (I.ElementLeaf name rattributes) = do
attributes <- mapM transformAttribute rattributes
return $ I.ElementLeaf name attributes
transformSection (I.Text text) = return $ I.Text text
transformSection (I.TextRaw text) = return $ I.TextRaw text
transformSection (I.Expression rexp) = I.Expression <$> transformExp rexp
transformAttribute :: I.RAttribute -> P.Parser I.Attribute
transformAttribute (I.Attribute rname rvalue) =
I.Attribute <$> transformName rname <*> transformValue rvalue
where
transformName (I.AttributeNameExp rexp) = I.AttributeNameExp <$> transformExp rexp
transformName (I.AttributeNameText text) = return $ I.AttributeNameText text
transformValue (I.AttributeValueExp rexp) = I.AttributeValueExp <$> transformExp rexp
transformValue (I.AttributeValueText text) = return $ I.AttributeValueText text