ginger-0.2.6.0: src/Text/Ginger/Optimizer.hs
-- | A syntax tree optimizer
module Text.Ginger.Optimizer
( Optimizable (..) )
where
import Text.Ginger.AST
import Data.Monoid
class Optimizable a where
optimize :: a -> a
instance Optimizable Template where
optimize = optimizeTemplate
instance Optimizable Statement where
optimize = optimizeStatement
instance Optimizable Block where
optimize = optimizeBlock
instance Optimizable Macro where
optimize = optimizeMacro
optimizeTemplate t =
t { templateBody = optimize $ templateBody t
, templateBlocks = fmap optimize $ templateBlocks t
, templateParent = fmap optimize $ templateParent t
}
{-
= MultiS [Statement] -- ^ A sequence of multiple statements
| ScopedS Statement -- ^ Run wrapped statement in a local scope
| LiteralS Html -- ^ Literal output (anything outside of any tag)
| InterpolationS Expression -- ^ {{ expression }}
| IfS Expression Statement Statement -- ^ {% if expression %}statement{% else %}statement{% endif %}
| ForS (Maybe VarName) VarName Expression Statement -- ^ {% for index, varname in expression %}statement{% endfor %}
| SetVarS VarName Expression -- ^ {% set varname = expr %}
| DefMacroS VarName Macro -- ^ {% macro varname %}statements{% endmacro %}
| BlockRefS VarName
| PreprocessedIncludeS Template -- ^ {% include "template" %}
| NullS -- ^ The do-nothing statement (NOP)
-}
optimizeStatement (MultiS items) =
case optimizeStatementList items of
[] -> NullS
[x] -> x
xs -> MultiS xs
optimizeStatement s = s
optimizeBlock (Block b) = Block $ optimize b
optimizeMacro (Macro args body) = Macro args (optimize body)
optimizeStatementList =
mergeLiterals .
cullNulls .
fmap optimize
cullNulls :: [Statement] -> [Statement]
cullNulls = filter (not . isNullS)
where
isNullS NullS = True
isNullS _ = False
mergeLiterals :: [Statement] -> [Statement]
mergeLiterals [] = []
mergeLiterals [x] = [x]
mergeLiterals (x@(LiteralS a):y@(LiteralS b):xs) = mergeLiterals $ (LiteralS $ a <> b):xs
mergeLiterals (x:xs) = x:mergeLiterals xs