module Zinza.Parser (parseTemplate) where
import Control.Applicative (many, optional, some, (<|>))
import Control.Monad (void)
import Data.Char (isAlphaNum, isLower)
import Data.List (foldl')
import Text.Parsec
(anyChar, eof, getPosition, lookAhead, notFollowedBy, parse, satisfy,
try)
import Text.Parsec.Char (char, space, spaces, string)
import Text.Parsec.Pos (SourcePos, sourceColumn, sourceLine)
import Text.Parsec.String (Parser)
import Zinza.Errors
import Zinza.Expr
import Zinza.Node
import Zinza.Pos
import Zinza.Var
parseTemplate
:: FilePath
-> String
-> Either ParseError (Nodes Var)
parseTemplate :: String -> String -> Either ParseError (Nodes String)
parseTemplate String
input String
contents
= (ParseError -> Either ParseError (Nodes String))
-> (Nodes String -> Either ParseError (Nodes String))
-> Either ParseError (Nodes String)
-> Either ParseError (Nodes String)
forall a c b. (a -> c) -> (b -> c) -> Either a b -> c
either (ParseError -> Either ParseError (Nodes String)
forall a b. a -> Either a b
Left (ParseError -> Either ParseError (Nodes String))
-> (ParseError -> ParseError)
-> ParseError
-> Either ParseError (Nodes String)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. String -> ParseError
ParseError (String -> ParseError)
-> (ParseError -> String) -> ParseError -> ParseError
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ParseError -> String
forall a. Show a => a -> String
show) Nodes String -> Either ParseError (Nodes String)
forall a b. b -> Either a b
Right
(Either ParseError (Nodes String)
-> Either ParseError (Nodes String))
-> Either ParseError (Nodes String)
-> Either ParseError (Nodes String)
forall a b. (a -> b) -> a -> b
$ Parsec String () (Nodes String)
-> String -> String -> Either ParseError (Nodes String)
forall s t a.
Stream s Identity t =>
Parsec s () a -> String -> s -> Either ParseError a
parse (Parsec String () (Nodes String)
nodesP Parsec String () (Nodes String)
-> ParsecT String () Identity () -> Parsec String () (Nodes String)
forall a b.
ParsecT String () Identity a
-> ParsecT String () Identity b -> ParsecT String () Identity a
forall (f :: * -> *) a b. Applicative f => f a -> f b -> f a
<* ParsecT String () Identity ()
forall s (m :: * -> *) t u.
(Stream s m t, Show t) =>
ParsecT s u m ()
eof) String
input String
contents
toLoc :: SourcePos -> Loc
toLoc :: SourcePos -> Loc
toLoc SourcePos
p = Column -> Column -> Loc
Loc (SourcePos -> Column
sourceLine SourcePos
p) (SourcePos -> Column
sourceColumn SourcePos
p)
varP :: Parser Var
varP :: Parser String
varP = (:) (Char -> String -> String)
-> ParsecT String () Identity Char
-> ParsecT String () Identity (String -> String)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> (Char -> Bool) -> ParsecT String () Identity Char
forall s (m :: * -> *) u.
Stream s m Char =>
(Char -> Bool) -> ParsecT s u m Char
satisfy Char -> Bool
isLower ParsecT String () Identity (String -> String)
-> Parser String -> Parser String
forall a b.
ParsecT String () Identity (a -> b)
-> ParsecT String () Identity a -> ParsecT String () Identity b
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> ParsecT String () Identity Char -> Parser String
forall a.
ParsecT String () Identity a -> ParsecT String () Identity [a]
forall (f :: * -> *) a. Alternative f => f a -> f [a]
many ((Char -> Bool) -> ParsecT String () Identity Char
forall s (m :: * -> *) u.
Stream s m Char =>
(Char -> Bool) -> ParsecT s u m Char
satisfy Char -> Bool
isVarChar)
locP :: Parser Loc
locP :: Parser Loc
locP = SourcePos -> Loc
toLoc (SourcePos -> Loc)
-> ParsecT String () Identity SourcePos -> Parser Loc
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> ParsecT String () Identity SourcePos
forall (m :: * -> *) s u. Monad m => ParsecT s u m SourcePos
getPosition
located :: Parser a -> Parser (Located a)
located :: forall a. Parser a -> Parser (Located a)
located Parser a
p = do
Loc
l <- Parser Loc
locP
Loc -> a -> Located a
forall a. Loc -> a -> Located a
L Loc
l (a -> Located a) -> Parser a -> Parser (Located a)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Parser a
p
locVarP :: Parser (Located Var)
locVarP :: Parser (Located String)
locVarP = Parser String -> Parser (Located String)
forall a. Parser a -> Parser (Located a)
located Parser String
varP
isVarChar :: Char -> Bool
isVarChar :: Char -> Bool
isVarChar Char
c = Char -> Bool
isAlphaNum Char
c Bool -> Bool -> Bool
|| Char
c Char -> Char -> Bool
forall a. Eq a => a -> a -> Bool
== Char
'_'
nodeP :: Parser (Node Var)
nodeP :: Parser (Node String)
nodeP = Parser (Node String)
forall var. Parser (Node var)
commentP Parser (Node String)
-> Parser (Node String) -> Parser (Node String)
forall a.
ParsecT String () Identity a
-> ParsecT String () Identity a -> ParsecT String () Identity a
forall (f :: * -> *) a. Alternative f => f a -> f a -> f a
<|> Parser (Node String)
directiveP Parser (Node String)
-> Parser (Node String) -> Parser (Node String)
forall a.
ParsecT String () Identity a
-> ParsecT String () Identity a -> ParsecT String () Identity a
forall (f :: * -> *) a. Alternative f => f a -> f a -> f a
<|> Parser (Node String)
exprNodeP Parser (Node String)
-> Parser (Node String) -> Parser (Node String)
forall a.
ParsecT String () Identity a
-> ParsecT String () Identity a -> ParsecT String () Identity a
forall (f :: * -> *) a. Alternative f => f a -> f a -> f a
<|> Parser (Node String)
newlineN Parser (Node String)
-> Parser (Node String) -> Parser (Node String)
forall a.
ParsecT String () Identity a
-> ParsecT String () Identity a -> ParsecT String () Identity a
forall (f :: * -> *) a. Alternative f => f a -> f a -> f a
<|> Parser (Node String)
rawP
nodesP :: Parser (Nodes Var)
nodesP :: Parsec String () (Nodes String)
nodesP = Parser (Node String) -> Parsec String () (Nodes String)
forall a.
ParsecT String () Identity a -> ParsecT String () Identity [a]
forall (f :: * -> *) a. Alternative f => f a -> f [a]
many Parser (Node String)
nodeP
newlineN :: Parser (Node Var)
newlineN :: Parser (Node String)
newlineN = String -> Node String
forall a. String -> Node a
NRaw (String -> Node String) -> (Char -> String) -> Char -> Node String
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Char -> String
forall a. a -> [a]
forall (f :: * -> *) a. Applicative f => a -> f a
pure (Char -> Node String)
-> ParsecT String () Identity Char -> Parser (Node String)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Char -> ParsecT String () Identity Char
forall s (m :: * -> *) u.
Stream s m Char =>
Char -> ParsecT s u m Char
char Char
'\n'
rawP :: Parser (Node Var)
rawP :: Parser (Node String)
rawP = String -> Maybe Char -> Node String
forall {a}. String -> Maybe Char -> Node a
mk (String -> Maybe Char -> Node String)
-> Parser String
-> ParsecT String () Identity (Maybe Char -> Node String)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> ParsecT String () Identity Char -> Parser String
forall a.
ParsecT String () Identity a -> ParsecT String () Identity [a]
forall (f :: * -> *) a. Alternative f => f a -> f [a]
some ParsecT String () Identity Char
forall {u}. ParsecT String u Identity Char
rawCharP ParsecT String () Identity (Maybe Char -> Node String)
-> ParsecT String () Identity (Maybe Char) -> Parser (Node String)
forall a b.
ParsecT String () Identity (a -> b)
-> ParsecT String () Identity a -> ParsecT String () Identity b
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> ParsecT String () Identity Char
-> ParsecT String () Identity (Maybe Char)
forall (f :: * -> *) a. Alternative f => f a -> f (Maybe a)
optional (Char -> ParsecT String () Identity Char
forall s (m :: * -> *) u.
Stream s m Char =>
Char -> ParsecT s u m Char
char Char
'\n') where
rawCharP :: ParsecT String u Identity Char
rawCharP = ParsecT String u Identity Char
forall {u}. ParsecT String u Identity Char
notBrace ParsecT String u Identity Char
-> ParsecT String u Identity Char -> ParsecT String u Identity Char
forall a.
ParsecT String u Identity a
-> ParsecT String u Identity a -> ParsecT String u Identity a
forall (f :: * -> *) a. Alternative f => f a -> f a -> f a
<|> ParsecT String u Identity Char -> ParsecT String u Identity Char
forall s u (m :: * -> *) a. ParsecT s u m a -> ParsecT s u m a
try (Char -> ParsecT String u Identity Char
forall s (m :: * -> *) u.
Stream s m Char =>
Char -> ParsecT s u m Char
char Char
'{' ParsecT String u Identity Char
-> ParsecT String u Identity Char -> ParsecT String u Identity Char
forall a b.
ParsecT String u Identity a
-> ParsecT String u Identity b -> ParsecT String u Identity a
forall (f :: * -> *) a b. Applicative f => f a -> f b -> f a
<* ParsecT String u Identity Char -> ParsecT String u Identity Char
forall s (m :: * -> *) t u a.
Stream s m t =>
ParsecT s u m a -> ParsecT s u m a
lookAhead ParsecT String u Identity Char
forall {u}. ParsecT String u Identity Char
notSpecial)
notBrace :: ParsecT String u Identity Char
notBrace = (Char -> Bool) -> ParsecT String u Identity Char
forall s (m :: * -> *) u.
Stream s m Char =>
(Char -> Bool) -> ParsecT s u m Char
satisfy ((Char -> Bool) -> ParsecT String u Identity Char)
-> (Char -> Bool) -> ParsecT String u Identity Char
forall a b. (a -> b) -> a -> b
$ \Char
c -> Char
c Char -> Char -> Bool
forall a. Eq a => a -> a -> Bool
/= Char
'{' Bool -> Bool -> Bool
&& Char
c Char -> Char -> Bool
forall a. Eq a => a -> a -> Bool
/= Char
'\n'
notSpecial :: ParsecT String u Identity Char
notSpecial = (Char -> Bool) -> ParsecT String u Identity Char
forall s (m :: * -> *) u.
Stream s m Char =>
(Char -> Bool) -> ParsecT s u m Char
satisfy ((Char -> Bool) -> ParsecT String u Identity Char)
-> (Char -> Bool) -> ParsecT String u Identity Char
forall a b. (a -> b) -> a -> b
$ \Char
c -> Char
c Char -> Char -> Bool
forall a. Eq a => a -> a -> Bool
/= Char
'{' Bool -> Bool -> Bool
&& Char
c Char -> Char -> Bool
forall a. Eq a => a -> a -> Bool
/= Char
'%' Bool -> Bool -> Bool
&& Char
c Char -> Char -> Bool
forall a. Eq a => a -> a -> Bool
/= Char
'#'
mk :: String -> Maybe Char -> Node a
mk String
s Maybe Char
Nothing = String -> Node a
forall a. String -> Node a
NRaw String
s
mk String
s (Just Char
c) = String -> Node a
forall a. String -> Node a
NRaw (String
s String -> String -> String
forall a. [a] -> [a] -> [a]
++ [Char
c])
exprNodeP :: Parser (Node Var)
exprNodeP :: Parser (Node String)
exprNodeP = do
String
_ <- Parser String -> Parser String
forall s u (m :: * -> *) a. ParsecT s u m a -> ParsecT s u m a
try (String -> Parser String
forall s (m :: * -> *) u.
Stream s m Char =>
String -> ParsecT s u m String
string String
"{{")
ParsecT String () Identity ()
forall s (m :: * -> *) u. Stream s m Char => ParsecT s u m ()
spaces
LExpr String
expr <- Parser (LExpr String)
exprP
ParsecT String () Identity ()
forall s (m :: * -> *) u. Stream s m Char => ParsecT s u m ()
spaces
String
_ <- String -> Parser String
forall s (m :: * -> *) u.
Stream s m Char =>
String -> ParsecT s u m String
string String
"}}"
Node String -> Parser (Node String)
forall a. a -> ParsecT String () Identity a
forall (m :: * -> *) a. Monad m => a -> m a
return (LExpr String -> Node String
forall a. LExpr a -> Node a
NExpr LExpr String
expr)
exprP :: Parser (LExpr Var)
exprP :: Parser (LExpr String)
exprP = do
LExpr String
expr <- Parser (LExpr String)
primitiveExprP
[LExpr String]
exprs <- Parser (LExpr String) -> ParsecT String () Identity [LExpr String]
forall a.
ParsecT String () Identity a -> ParsecT String () Identity [a]
forall (f :: * -> *) a. Alternative f => f a -> f [a]
many Parser (LExpr String)
primitiveExprP
LExpr String -> Parser (LExpr String)
forall a. a -> ParsecT String () Identity a
forall (m :: * -> *) a. Monad m => a -> m a
return (LExpr String -> Parser (LExpr String))
-> LExpr String -> Parser (LExpr String)
forall a b. (a -> b) -> a -> b
$ (LExpr String -> LExpr String -> LExpr String)
-> LExpr String -> [LExpr String] -> LExpr String
forall b a. (b -> a -> b) -> b -> [a] -> b
forall (t :: * -> *) b a.
Foldable t =>
(b -> a -> b) -> b -> t a -> b
foldl' (\f :: LExpr String
f@(L Loc
l Expr String
_) LExpr String
x -> Loc -> Expr String -> LExpr String
forall a. Loc -> a -> Located a
L Loc
l (LExpr String -> LExpr String -> Expr String
forall a. LExpr a -> LExpr a -> Expr a
EApp LExpr String
f LExpr String
x)) LExpr String
expr [LExpr String]
exprs
primitiveExprP :: Parser (LExpr Var)
primitiveExprP :: Parser (LExpr String)
primitiveExprP = Parser (LExpr String) -> Parser (LExpr String)
forall a. Parser a -> Parser a
parens Parser (LExpr String)
exprP Parser (LExpr String)
-> Parser (LExpr String) -> Parser (LExpr String)
forall a.
ParsecT String () Identity a
-> ParsecT String () Identity a -> ParsecT String () Identity a
forall (f :: * -> *) a. Alternative f => f a -> f a -> f a
<|> Parser (Expr String) -> Parser (LExpr String)
forall a. Parser a -> Parser (Located a)
located Parser (Expr String)
primitiveExprP'
parens :: Parser a -> Parser a
parens :: forall a. Parser a -> Parser a
parens Parser a
p = do
Char
_ <- Char -> ParsecT String () Identity Char
forall s (m :: * -> *) u.
Stream s m Char =>
Char -> ParsecT s u m Char
char Char
'('
ParsecT String () Identity ()
forall s (m :: * -> *) u. Stream s m Char => ParsecT s u m ()
spaces
a
x <- Parser a
p
Char
_ <- Char -> ParsecT String () Identity Char
forall s (m :: * -> *) u.
Stream s m Char =>
Char -> ParsecT s u m Char
char Char
')'
ParsecT String () Identity ()
forall s (m :: * -> *) u. Stream s m Char => ParsecT s u m ()
spaces
a -> Parser a
forall a. a -> ParsecT String () Identity a
forall (m :: * -> *) a. Monad m => a -> m a
return a
x
primitiveExprP' :: Parser (Expr Var)
primitiveExprP' :: Parser (Expr String)
primitiveExprP' = do
v :: Located String
v@(L Loc
l String
_) <- Parser (Located String)
locVarP
[Located String]
vs <- Parser (Located String)
-> ParsecT String () Identity [Located String]
forall a.
ParsecT String () Identity a -> ParsecT String () Identity [a]
forall (f :: * -> *) a. Alternative f => f a -> f [a]
many (Char -> ParsecT String () Identity Char
forall s (m :: * -> *) u.
Stream s m Char =>
Char -> ParsecT s u m Char
char Char
'.' ParsecT String () Identity Char
-> Parser (Located String) -> Parser (Located String)
forall a b.
ParsecT String () Identity a
-> ParsecT String () Identity b -> ParsecT String () Identity b
forall (f :: * -> *) a b. Applicative f => f a -> f b -> f b
*> Parser (Located String)
locVarP)
ParsecT String () Identity ()
forall s (m :: * -> *) u. Stream s m Char => ParsecT s u m ()
spaces
let expr :: Expr String
expr = (Expr String -> Located String -> Expr String)
-> Expr String -> [Located String] -> Expr String
forall b a. (b -> a -> b) -> b -> [a] -> b
forall (t :: * -> *) b a.
Foldable t =>
(b -> a -> b) -> b -> t a -> b
foldl (\Expr String
e Located String
f -> LExpr String -> Located String -> Expr String
forall a. LExpr a -> Located String -> Expr a
EField (Loc -> Expr String -> LExpr String
forall a. Loc -> a -> Located a
L Loc
l Expr String
e) Located String
f) (Located String -> Expr String
forall a. Located a -> Expr a
EVar Located String
v) [Located String]
vs
Expr String -> Parser (Expr String)
forall a. a -> ParsecT String () Identity a
forall (m :: * -> *) a. Monad m => a -> m a
return Expr String
expr
commentP :: Parser (Node var)
= do
SourcePos
pos <- ParsecT String () Identity SourcePos
forall (m :: * -> *) s u. Monad m => ParsecT s u m SourcePos
getPosition
String
_ <- Parser String -> Parser String
forall s u (m :: * -> *) a. ParsecT s u m a -> ParsecT s u m a
try (String -> Parser String
forall s (m :: * -> *) u.
Stream s m Char =>
String -> ParsecT s u m String
string String
"{#")
SourcePos -> Parser (Node var)
forall {a}. SourcePos -> ParsecT String () Identity (Node a)
go SourcePos
pos
where
go :: SourcePos -> ParsecT String () Identity (Node a)
go SourcePos
pos = do
Char
c <- ParsecT String () Identity Char
forall s (m :: * -> *) u. Stream s m Char => ParsecT s u m Char
anyChar
case Char
c of
Char
'#' -> do
Char
c' <- ParsecT String () Identity Char
forall s (m :: * -> *) u. Stream s m Char => ParsecT s u m Char
anyChar
case Char
c' of
Char
'}' -> Node a
forall a. Node a
NComment Node a
-> ParsecT String () Identity ()
-> ParsecT String () Identity (Node a)
forall a b.
a -> ParsecT String () Identity b -> ParsecT String () Identity a
forall (f :: * -> *) a b. Functor f => a -> f b -> f a
<$ Bool -> ParsecT String () Identity ()
eatNewlineWhen (SourcePos -> Column
sourceColumn SourcePos
pos Column -> Column -> Bool
forall a. Eq a => a -> a -> Bool
== Column
1)
Char
_ -> SourcePos -> ParsecT String () Identity (Node a)
go SourcePos
pos
Char
_ -> SourcePos -> ParsecT String () Identity (Node a)
go SourcePos
pos
eatNewlineWhen :: Bool -> Parser ()
eatNewlineWhen :: Bool -> ParsecT String () Identity ()
eatNewlineWhen Bool
False = () -> ParsecT String () Identity ()
forall a. a -> ParsecT String () Identity a
forall (m :: * -> *) a. Monad m => a -> m a
return ()
eatNewlineWhen Bool
True = ParsecT String () Identity (Maybe Char)
-> ParsecT String () Identity ()
forall (f :: * -> *) a. Functor f => f a -> f ()
void (ParsecT String () Identity Char
-> ParsecT String () Identity (Maybe Char)
forall (f :: * -> *) a. Alternative f => f a -> f (Maybe a)
optional (Char -> ParsecT String () Identity Char
forall s (m :: * -> *) u.
Stream s m Char =>
Char -> ParsecT s u m Char
char Char
'\n'))
directiveP :: Parser (Node Var)
directiveP :: Parser (Node String)
directiveP = Parser (Node String)
forP Parser (Node String)
-> Parser (Node String) -> Parser (Node String)
forall a.
ParsecT String () Identity a
-> ParsecT String () Identity a -> ParsecT String () Identity a
forall (f :: * -> *) a. Alternative f => f a -> f a -> f a
<|> Parser (Node String)
ifP Parser (Node String)
-> Parser (Node String) -> Parser (Node String)
forall a.
ParsecT String () Identity a
-> ParsecT String () Identity a -> ParsecT String () Identity a
forall (f :: * -> *) a. Alternative f => f a -> f a -> f a
<|> Parser (Node String)
defBlockP Parser (Node String)
-> Parser (Node String) -> Parser (Node String)
forall a.
ParsecT String () Identity a
-> ParsecT String () Identity a -> ParsecT String () Identity a
forall (f :: * -> *) a. Alternative f => f a -> f a -> f a
<|> Parser (Node String)
useBlockP
spaces1 :: Parser ()
spaces1 :: ParsecT String () Identity ()
spaces1 = ParsecT String () Identity Char
forall s (m :: * -> *) u. Stream s m Char => ParsecT s u m Char
space ParsecT String () Identity Char
-> ParsecT String () Identity () -> ParsecT String () Identity ()
forall a b.
ParsecT String () Identity a
-> ParsecT String () Identity b -> ParsecT String () Identity b
forall (f :: * -> *) a b. Applicative f => f a -> f b -> f b
*> ParsecT String () Identity ()
forall s (m :: * -> *) u. Stream s m Char => ParsecT s u m ()
spaces
open :: String -> Parser Bool
open :: String -> Parser Bool
open String
n = do
SourcePos
pos <- ParsecT String () Identity SourcePos
forall (m :: * -> *) s u. Monad m => ParsecT s u m SourcePos
getPosition
()
_ <- ParsecT String () Identity () -> ParsecT String () Identity ()
forall s u (m :: * -> *) a. ParsecT s u m a -> ParsecT s u m a
try (ParsecT String () Identity () -> ParsecT String () Identity ())
-> ParsecT String () Identity () -> ParsecT String () Identity ()
forall a b. (a -> b) -> a -> b
$ String -> Parser String
forall s (m :: * -> *) u.
Stream s m Char =>
String -> ParsecT s u m String
string String
"{%" Parser String
-> ParsecT String () Identity () -> ParsecT String () Identity ()
forall a b.
ParsecT String () Identity a
-> ParsecT String () Identity b -> ParsecT String () Identity b
forall (f :: * -> *) a b. Applicative f => f a -> f b -> f b
*> ParsecT String () Identity ()
forall s (m :: * -> *) u. Stream s m Char => ParsecT s u m ()
spaces ParsecT String () Identity () -> Parser String -> Parser String
forall a b.
ParsecT String () Identity a
-> ParsecT String () Identity b -> ParsecT String () Identity b
forall (f :: * -> *) a b. Applicative f => f a -> f b -> f b
*> String -> Parser String
forall s (m :: * -> *) u.
Stream s m Char =>
String -> ParsecT s u m String
string String
n Parser String
-> ParsecT String () Identity () -> ParsecT String () Identity ()
forall a b.
ParsecT String () Identity a
-> ParsecT String () Identity b -> ParsecT String () Identity b
forall (f :: * -> *) a b. Applicative f => f a -> f b -> f b
*> ParsecT String () Identity ()
forall s (m :: * -> *) u. Stream s m Char => ParsecT s u m ()
spaces
Bool -> Parser Bool
forall a. a -> ParsecT String () Identity a
forall (m :: * -> *) a. Monad m => a -> m a
return (Bool -> Parser Bool) -> Bool -> Parser Bool
forall a b. (a -> b) -> a -> b
$ SourcePos -> Column
sourceColumn SourcePos
pos Column -> Column -> Bool
forall a. Eq a => a -> a -> Bool
== Column
1
close :: String -> Parser ()
close :: String -> ParsecT String () Identity ()
close String
n = do
Bool
on0 <- String -> Parser Bool
open (String
"end" String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
n)
Bool -> ParsecT String () Identity ()
close' Bool
on0
close' :: Bool -> Parser ()
close' :: Bool -> ParsecT String () Identity ()
close' Bool
on0 = do
String
_ <- String -> Parser String
forall s (m :: * -> *) u.
Stream s m Char =>
String -> ParsecT s u m String
string String
"%}"
Bool -> ParsecT String () Identity ()
eatNewlineWhen Bool
on0
forP :: Parser (Node Var)
forP :: Parser (Node String)
forP = do
Bool
on0 <- String -> Parser Bool
open String
"for"
String
var <- Parser String
varP
ParsecT String () Identity ()
spaces1
String
_ <- String -> Parser String
forall s (m :: * -> *) u.
Stream s m Char =>
String -> ParsecT s u m String
string String
"in"
ParsecT String () Identity Char -> ParsecT String () Identity ()
forall s (m :: * -> *) t a u.
(Stream s m t, Show a) =>
ParsecT s u m a -> ParsecT s u m ()
notFollowedBy (ParsecT String () Identity Char -> ParsecT String () Identity ())
-> ParsecT String () Identity Char -> ParsecT String () Identity ()
forall a b. (a -> b) -> a -> b
$ (Char -> Bool) -> ParsecT String () Identity Char
forall s (m :: * -> *) u.
Stream s m Char =>
(Char -> Bool) -> ParsecT s u m Char
satisfy Char -> Bool
isAlphaNum
ParsecT String () Identity ()
spaces1
LExpr String
expr <- Parser (LExpr String)
exprP
Bool -> ParsecT String () Identity ()
close' Bool
on0
Nodes String
ns <- Parsec String () (Nodes String)
nodesP
String -> ParsecT String () Identity ()
close String
"for"
Node String -> Parser (Node String)
forall a. a -> ParsecT String () Identity a
forall (m :: * -> *) a. Monad m => a -> m a
return (Node String -> Parser (Node String))
-> Node String -> Parser (Node String)
forall a b. (a -> b) -> a -> b
$ String -> LExpr String -> Nodes (Maybe String) -> Node String
forall a. String -> LExpr a -> Nodes (Maybe a) -> Node a
NFor String
var LExpr String
expr (String -> Node String -> Node (Maybe String)
forall (f :: * -> *) a.
(Functor f, Eq a) =>
a -> f a -> f (Maybe a)
abstract1 String
var (Node String -> Node (Maybe String))
-> Nodes String -> Nodes (Maybe String)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Nodes String
ns)
ifP :: Parser (Node Var)
ifP :: Parser (Node String)
ifP = do
Bool
on0 <- String -> Parser Bool
open String
"if"
LExpr String
expr <- Parser (LExpr String)
exprP
Bool -> ParsecT String () Identity ()
close' Bool
on0
Nodes String
ns <- Parsec String () (Nodes String)
nodesP
(Nodes String -> Node String) -> Parser (Node String)
forall {a}. (Nodes String -> a) -> ParsecT String () Identity a
closing (LExpr String -> Nodes String -> Nodes String -> Node String
forall a. LExpr a -> Nodes a -> Nodes a -> Node a
NIf LExpr String
expr Nodes String
ns)
where
closing :: (Nodes String -> a) -> ParsecT String () Identity a
closing Nodes String -> a
mk = (Nodes String -> a) -> ParsecT String () Identity a
forall {a} {b}. ([a] -> b) -> ParsecT String () Identity b
closeIf Nodes String -> a
mk ParsecT String () Identity a
-> ParsecT String () Identity a -> ParsecT String () Identity a
forall a.
ParsecT String () Identity a
-> ParsecT String () Identity a -> ParsecT String () Identity a
forall (f :: * -> *) a. Alternative f => f a -> f a -> f a
<|> (Nodes String -> a) -> ParsecT String () Identity a
elifP Nodes String -> a
mk ParsecT String () Identity a
-> ParsecT String () Identity a -> ParsecT String () Identity a
forall a.
ParsecT String () Identity a
-> ParsecT String () Identity a -> ParsecT String () Identity a
forall (f :: * -> *) a. Alternative f => f a -> f a -> f a
<|> (Nodes String -> a) -> ParsecT String () Identity a
forall {a}. (Nodes String -> a) -> ParsecT String () Identity a
elseP Nodes String -> a
mk
closeIf :: ([a] -> b) -> ParsecT String () Identity b
closeIf [a] -> b
mk = do
String -> ParsecT String () Identity ()
close String
"if"
b -> ParsecT String () Identity b
forall a. a -> ParsecT String () Identity a
forall (m :: * -> *) a. Monad m => a -> m a
return ([a] -> b
mk [])
elseP :: (Nodes String -> b) -> ParsecT String () Identity b
elseP Nodes String -> b
mk = do
Bool
on0 <- String -> Parser Bool
open String
"else"
Bool -> ParsecT String () Identity ()
close' Bool
on0
Nodes String
ns <- Parsec String () (Nodes String)
nodesP
String -> ParsecT String () Identity ()
close String
"if"
b -> ParsecT String () Identity b
forall a. a -> ParsecT String () Identity a
forall (m :: * -> *) a. Monad m => a -> m a
return (Nodes String -> b
mk Nodes String
ns)
elifP :: (Nodes String -> a) -> ParsecT String () Identity a
elifP Nodes String -> a
mk = do
Bool
on0 <- String -> Parser Bool
open String
"elif"
LExpr String
expr <- Parser (LExpr String)
exprP
Bool -> ParsecT String () Identity ()
close' Bool
on0
Nodes String
ns <- Parsec String () (Nodes String)
nodesP
(Nodes String -> a) -> ParsecT String () Identity a
closing (Nodes String -> a
mk (Nodes String -> a)
-> (Nodes String -> Nodes String) -> Nodes String -> a
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Node String -> Nodes String
forall a. a -> [a]
forall (f :: * -> *) a. Applicative f => a -> f a
pure (Node String -> Nodes String)
-> (Nodes String -> Node String) -> Nodes String -> Nodes String
forall b c a. (b -> c) -> (a -> b) -> a -> c
. LExpr String -> Nodes String -> Nodes String -> Node String
forall a. LExpr a -> Nodes a -> Nodes a -> Node a
NIf LExpr String
expr Nodes String
ns)
defBlockP :: Parser (Node Var)
defBlockP :: Parser (Node String)
defBlockP = do
Loc
l <- Parser Loc
locP
Bool
on0 <- String -> Parser Bool
open String
"defblock"
String
var <- Parser String
varP
ParsecT String () Identity ()
forall s (m :: * -> *) u. Stream s m Char => ParsecT s u m ()
spaces
Bool -> ParsecT String () Identity ()
close' Bool
on0
Nodes String
ns <- Parsec String () (Nodes String)
nodesP
String -> ParsecT String () Identity ()
close String
"block"
Node String -> Parser (Node String)
forall a. a -> ParsecT String () Identity a
forall (m :: * -> *) a. Monad m => a -> m a
return (Loc -> String -> Nodes String -> Node String
forall a. Loc -> String -> Nodes a -> Node a
NDefBlock Loc
l String
var Nodes String
ns)
useBlockP :: Parser (Node Var)
useBlockP :: Parser (Node String)
useBlockP = do
Loc
l <- Parser Loc
locP
Bool
on0 <- String -> Parser Bool
open String
"useblock"
String
var <- Parser String
varP
ParsecT String () Identity ()
forall s (m :: * -> *) u. Stream s m Char => ParsecT s u m ()
spaces
Bool -> ParsecT String () Identity ()
close' Bool
on0
Node String -> Parser (Node String)
forall a. a -> ParsecT String () Identity a
forall (m :: * -> *) a. Monad m => a -> m a
return (Loc -> String -> Node String
forall a. Loc -> String -> Node a
NUseBlock Loc
l String
var)