{-# LANGUAGE Rank2Types #-}
{-# LANGUAGE FlexibleContexts #-}
{-# LANGUAGE LambdaCase #-}
{-# LANGUAGE OverloadedStrings #-}
module JL.Parser where
import Control.Monad.Catch
import Data.Functor
import qualified Data.HashMap.Strict as HM
import Data.Text (Text)
import qualified Data.Text as T
import qualified Data.Vector as V
import JL.Tokenizer
import JL.Types
import Text.Parsec hiding (satisfy, anyToken)
parseText :: MonadThrow m => SourceName -> Text -> m Expression
parseText :: forall (m :: * -> *).
MonadThrow m =>
SourceName -> Text -> m Expression
parseText SourceName
fp Text
inp =
case Parsec Text () [(Token, Location)]
-> SourceName -> Text -> Either ParseError [(Token, Location)]
forall s t a.
Stream s Identity t =>
Parsec s () a -> SourceName -> s -> Either ParseError a
parse Parsec Text () [(Token, Location)]
tokensTokenizer SourceName
fp (Text
inp) of
Left ParseError
e -> ParseException -> m Expression
forall e a. (HasCallStack, Exception e) => e -> m a
forall (m :: * -> *) e a.
(MonadThrow m, HasCallStack, Exception e) =>
e -> m a
throwM (ParseError -> ParseException
TokenizerError ParseError
e)
Right [(Token, Location)]
tokens' ->
case Parsec [(Token, Location)] Int Expression
-> Int
-> SourceName
-> [(Token, Location)]
-> Either ParseError Expression
forall s t u a.
Stream s Identity t =>
Parsec s u a -> u -> SourceName -> s -> Either ParseError a
runParser (Parsec [(Token, Location)] Int Expression
TokenParser Expression
expressionParser Parsec [(Token, Location)] Int Expression
-> ParsecT [(Token, Location)] Int Identity ()
-> Parsec [(Token, Location)] Int Expression
forall a b.
ParsecT [(Token, Location)] Int Identity a
-> ParsecT [(Token, Location)] Int Identity b
-> ParsecT [(Token, Location)] Int Identity a
forall (f :: * -> *) a b. Applicative f => f a -> f b -> f a
<* ParsecT [(Token, Location)] Int Identity ()
TokenParser ()
endOfTokens) Int
0 SourceName
fp [(Token, Location)]
tokens' of
Left ParseError
e -> ParseException -> m Expression
forall e a. (HasCallStack, Exception e) => e -> m a
forall (m :: * -> *) e a.
(MonadThrow m, HasCallStack, Exception e) =>
e -> m a
throwM (ParseError -> ParseException
ParserError ParseError
e)
Right Expression
ast -> Expression -> m Expression
forall a. a -> m a
forall (f :: * -> *) a. Applicative f => a -> f a
pure Expression
ast
expressionParser :: TokenParser Expression
expressionParser :: TokenParser Expression
expressionParser = ParsecT s Int m Expression
pipes
where
pipes :: ParsecT s Int m Expression
pipes = do
ps <- ParsecT s Int m Expression
-> ParsecT s Int m Location -> ParsecT s Int m [Expression]
forall s (m :: * -> *) t u a sep.
Stream s m t =>
ParsecT s u m a -> ParsecT s u m sep -> ParsecT s u m [a]
sepBy1 ParsecT s Int m Expression
dollars (Token -> TokenParser Location
equalToken Token
Bar)
case ps of
[Expression
p] -> Expression -> ParsecT s Int m Expression
forall a. a -> ParsecT s Int m a
forall (f :: * -> *) a. Applicative f => a -> f a
pure Expression
p
[] -> SourceName -> ParsecT s Int m Expression
forall s (m :: * -> *) t u a.
Stream s m t =>
SourceName -> ParsecT s u m a
unexpected SourceName
"empty expression"
(Expression
p:[Expression]
ps') ->
Expression -> ParsecT s Int m Expression
forall a. a -> ParsecT s Int m a
forall (f :: * -> *) a. Applicative f => a -> f a
pure
((Expression -> Expression -> Expression)
-> Expression -> [Expression] -> Expression
forall b a. (b -> a -> b) -> b -> [a] -> b
forall (t :: * -> *) b a.
Foldable t =>
(b -> a -> b) -> b -> t a -> b
foldl
(\Expression
x Expression
y ->
Expression -> Expression -> Expression
ApplicationExpression
(Expression -> Expression -> Expression
ApplicationExpression
(Variable -> Expression
VariableExpression (Text -> Variable
Variable Text
"compose"))
Expression
x)
Expression
y)
Expression
p
[Expression]
ps')
dollars :: ParsecT s Int m Expression
dollars = do
ps <- ParsecT s Int m Expression
-> ParsecT s Int m Location -> ParsecT s Int m [Expression]
forall s (m :: * -> *) t u a sep.
Stream s m t =>
ParsecT s u m a -> ParsecT s u m sep -> ParsecT s u m [a]
sepBy1 ParsecT s Int m Expression
dollarable (Token -> TokenParser Location
equalToken Token
Dollar)
case ps of
[Expression
p] -> Expression -> ParsecT s Int m Expression
forall a. a -> ParsecT s Int m a
forall (f :: * -> *) a. Applicative f => a -> f a
pure Expression
p
(Expression
p:[Expression]
ps') -> Expression -> ParsecT s Int m Expression
forall a. a -> ParsecT s Int m a
forall (f :: * -> *) a. Applicative f => a -> f a
pure ((Expression -> Expression -> Expression)
-> Expression -> [Expression] -> Expression
forall b a. (b -> a -> b) -> b -> [a] -> b
forall (t :: * -> *) b a.
Foldable t =>
(b -> a -> b) -> b -> t a -> b
foldl Expression -> Expression -> Expression
ApplicationExpression Expression
p [Expression]
ps')
[] -> SourceName -> ParsecT s Int m Expression
forall s (m :: * -> *) t u a.
Stream s m t =>
SourceName -> ParsecT s u m a
unexpected SourceName
"empty expression"
where
dollarable :: ParsecT s Int m Expression
dollarable =
ParsecT s Int m Expression
array ParsecT s Int m Expression
-> ParsecT s Int m Expression -> ParsecT s Int m Expression
forall s u (m :: * -> *) a.
ParsecT s u m a -> ParsecT s u m a -> ParsecT s u m a
<|> ParsecT s Int m Expression
record ParsecT s Int m Expression
-> ParsecT s Int m Expression -> ParsecT s Int m Expression
forall s u (m :: * -> *) a.
ParsecT s u m a -> ParsecT s u m a -> ParsecT s u m a
<|> ParsecT s Int m Expression
TokenParser Expression
lambda ParsecT s Int m Expression
-> ParsecT s Int m Expression -> ParsecT s Int m Expression
forall s u (m :: * -> *) a.
ParsecT s u m a -> ParsecT s u m a -> ParsecT s u m a
<|> ParsecT s Int m Expression
TokenParser Expression
ifParser ParsecT s Int m Expression
-> ParsecT s Int m Expression -> ParsecT s Int m Expression
forall s u (m :: * -> *) a.
ParsecT s u m a -> ParsecT s u m a -> ParsecT s u m a
<|> ParsecT s Int m Expression
infix' ParsecT s Int m Expression
-> ParsecT s Int m Expression -> ParsecT s Int m Expression
forall s u (m :: * -> *) a.
ParsecT s u m a -> ParsecT s u m a -> ParsecT s u m a
<|> ParsecT s Int m Expression
app ParsecT s Int m Expression
-> ParsecT s Int m Expression -> ParsecT s Int m Expression
forall s u (m :: * -> *) a.
ParsecT s u m a -> ParsecT s u m a -> ParsecT s u m a
<|> ParsecT s Int m Expression
TokenParser Expression
atomic
array :: ParsecT s Int m Expression
array = do
ParsecT s Int m Location -> ParsecT s Int m ()
forall (f :: * -> *) a. Functor f => f a -> f ()
void (Token -> TokenParser Location
equalToken Token
OpenBracket) ParsecT s Int m () -> SourceName -> ParsecT s Int m ()
forall s u (m :: * -> *) a.
ParsecT s u m a -> SourceName -> ParsecT s u m a
<?> (SourceName
"open bracket " SourceName -> SourceName -> SourceName
forall a. Semigroup a => a -> a -> a
<> SourceName -> SourceName
curlyQuotes SourceName
"[")
es <- ParsecT s Int m Expression
-> ParsecT s Int m () -> ParsecT s Int m [Expression]
forall s (m :: * -> *) t u a sep.
Stream s m t =>
ParsecT s u m a -> ParsecT s u m sep -> ParsecT s u m [a]
sepBy ParsecT s Int m Expression
TokenParser Expression
expressionParser (ParsecT s Int m Location -> ParsecT s Int m ()
forall (f :: * -> *) a. Functor f => f a -> f ()
void (Token -> TokenParser Location
equalToken Token
Comma))
void (equalToken CloseBracket) <?> ("closing bracket " <> curlyQuotes "]")
pure (ArrayExpression (V.fromList es))
record :: ParsecT s Int m Expression
record = do
_ <- Token -> TokenParser Location
equalToken Token
OpenBrace
pairs' <- sepBy pair (equalToken Comma <?> curlyQuotes ",")
_ <- equalToken CloseBrace <?> ("closing brace " <> curlyQuotes "}")
pure (RecordExpression (HM.fromList pairs'))
where
pair :: ParsecT s Int m (Text, Expression)
pair = do
var <-
((Text, Location) -> Text)
-> ParsecT s Int m (Text, Location) -> ParsecT s Int m Text
forall a b. (a -> b) -> ParsecT s Int m a -> ParsecT s Int m b
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap
(Text, Location) -> Text
forall a b. (a, b) -> a
fst
((Token -> Maybe Text) -> TokenParser (Text, Location)
forall a. (Token -> Maybe a) -> TokenParser (a, Location)
consumeToken
(\case
VariableToken Text
i -> Text -> Maybe Text
forall a. a -> Maybe a
Just Text
i
Token
_ -> Maybe Text
forall a. Maybe a
Nothing)) ParsecT s Int m Text
-> ParsecT s Int m Text -> ParsecT s Int m Text
forall s u (m :: * -> *) a.
ParsecT s u m a -> ParsecT s u m a -> ParsecT s u m a
<|>
((Text, Location) -> Text)
-> ParsecT s Int m (Text, Location) -> ParsecT s Int m Text
forall a b. (a -> b) -> ParsecT s Int m a -> ParsecT s Int m b
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap
(Text, Location) -> Text
forall a b. (a, b) -> a
fst
((Token -> Maybe Text) -> TokenParser (Text, Location)
forall a. (Token -> Maybe a) -> TokenParser (a, Location)
consumeToken
(\case
StringToken Text
c -> Text -> Maybe Text
forall a. a -> Maybe a
Just Text
c
Token
_ -> Maybe Text
forall a. Maybe a
Nothing))
_ <- equalToken Colon
e <- expressionParser
pure (var, e)
app :: ParsecT s Int m Expression
app = do
left <- ParsecT s Int m Expression
funcOp ParsecT s Int m Expression
-> SourceName -> ParsecT s Int m Expression
forall s u (m :: * -> *) a.
ParsecT s u m a -> SourceName -> ParsecT s u m a
<?> SourceName
"function expression"
right <- many unambiguous <?> "function arguments"
case right of
[] -> Expression -> ParsecT s Int m Expression
forall a. a -> ParsecT s Int m a
forall (f :: * -> *) a. Applicative f => a -> f a
pure Expression
left
[Expression]
_ -> Expression -> ParsecT s Int m Expression
forall a. a -> ParsecT s Int m a
forall (f :: * -> *) a. Applicative f => a -> f a
pure ((Expression -> Expression -> Expression)
-> Expression -> [Expression] -> Expression
forall b a. (b -> a -> b) -> b -> [a] -> b
forall (t :: * -> *) b a.
Foldable t =>
(b -> a -> b) -> b -> t a -> b
foldl (Expression -> Expression -> Expression
ApplicationExpression) Expression
left [Expression]
right)
infix' :: ParsecT s Int m Expression
infix' =
(do left <- (ParsecT s Int m Expression
app ParsecT s Int m Expression
-> ParsecT s Int m Expression -> ParsecT s Int m Expression
forall s u (m :: * -> *) a.
ParsecT s u m a -> ParsecT s u m a -> ParsecT s u m a
<|> ParsecT s Int m Expression
unambiguous) ParsecT s Int m Expression
-> SourceName -> ParsecT s Int m Expression
forall s u (m :: * -> *) a.
ParsecT s u m a -> SourceName -> ParsecT s u m a
<?> SourceName
"left-hand side of operator"
tok <- fmap Just (operator <?> "infix operator") <|> pure Nothing
case tok of
Just (Operator Text
t, Location
_) -> do
right <-
(ParsecT s Int m Expression
app ParsecT s Int m Expression
-> ParsecT s Int m Expression -> ParsecT s Int m Expression
forall s u (m :: * -> *) a.
ParsecT s u m a -> ParsecT s u m a -> ParsecT s u m a
<|> ParsecT s Int m Expression
unambiguous) ParsecT s Int m Expression
-> SourceName -> ParsecT s Int m Expression
forall s u (m :: * -> *) a.
ParsecT s u m a -> SourceName -> ParsecT s u m a
<?>
(SourceName
"right-hand side of " SourceName -> SourceName -> SourceName
forall a. [a] -> [a] -> [a]
++
SourceName -> SourceName
curlyQuotes (Text -> SourceName
T.unpack Text
t) SourceName -> SourceName -> SourceName
forall a. [a] -> [a] -> [a]
++ SourceName
" operator")
badop <- fmap Just (lookAhead operator) <|> pure Nothing
let infixexp = Expression -> Variable -> Expression -> Expression
InfixExpression Expression
left (Text -> Variable
Variable Text
t) Expression
right
maybe
(return ())
(\(Token, Location)
op ->
SourceName -> ParsecT s Int m ()
forall s (m :: * -> *) t u a.
Stream s m t =>
SourceName -> ParsecT s u m a
unexpected
([SourceName] -> SourceName
forall (t :: * -> *) a. Foldable t => t [a] -> [a]
concat
[ (Token, Location) -> SourceName
tokenString (Token, Location)
op SourceName -> SourceName -> SourceName
forall a. [a] -> [a] -> [a]
++
SourceName
". When more than one operator is used\n"
, SourceName
"in the same expression, use parentheses."
]))
badop
pure infixexp
Maybe (Token, Location)
_ -> Expression -> ParsecT s Int m Expression
forall a. a -> ParsecT s Int m a
forall (f :: * -> *) a. Applicative f => a -> f a
pure Expression
left) ParsecT s Int m Expression
-> SourceName -> ParsecT s Int m Expression
forall s u (m :: * -> *) a.
ParsecT s u m a -> SourceName -> ParsecT s u m a
<?>
SourceName
"infix expression (e.g. x * y)"
where
operator :: ParsecT s Int m (Token, Location)
operator =
(Token -> Bool) -> TokenParser (Token, Location)
satisfyToken
(\case
Operator {} -> Bool
True
Token
_ -> Bool
False)
funcOp :: ParsecT s Int m Expression
funcOp = do
let collectsubscripts :: ([Subscript] -> a) -> b -> ParsecT s Int m (a, b)
collectsubscripts [Subscript] -> a
ks b
a = do
bracket' <-
(Location -> Bool)
-> ParsecT s Int m Location -> ParsecT s Int m Bool
forall a b. (a -> b) -> ParsecT s Int m a -> ParsecT s Int m b
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap (Bool -> Location -> Bool
forall a b. a -> b -> a
const Bool
True) (Token -> TokenParser Location
equalToken Token
OpenBracket) ParsecT s Int m Bool
-> ParsecT s Int m Bool -> ParsecT s Int m Bool
forall s u (m :: * -> *) a.
ParsecT s u m a -> ParsecT s u m a -> ParsecT s u m a
<|> Bool -> ParsecT s Int m Bool
forall a. a -> ParsecT s Int m a
forall (f :: * -> *) a. Applicative f => a -> f a
pure Bool
False
if bracket'
then do
k <- expressionParser
_ <- equalToken CloseBracket
collectsubscripts (ks . (ExpressionSubscript k :)) a
else do
dot <- fmap (const True) (equalToken Period) <|> pure False
if dot
then do
k <-
fmap
fst
(consumeToken
(\case
VariableToken Text
i -> Text -> Maybe Text
forall a. a -> Maybe a
Just Text
i
Integer Integer
i -> Text -> Maybe Text
forall a. a -> Maybe a
Just (SourceName -> Text
T.pack (Integer -> SourceName
forall a. Show a => a -> SourceName
show Integer
i))
Token
_ -> Maybe Text
forall a. Maybe a
Nothing))
collectsubscripts (ks . (PropertySubscript k :)) a
else pure (ks [], a)
a <- ParsecT s Int m Expression
TokenParser Expression
varParser ParsecT s Int m Expression
-> ParsecT s Int m Expression -> ParsecT s Int m Expression
forall s u (m :: * -> *) a.
ParsecT s u m a -> ParsecT s u m a -> ParsecT s u m a
<|> ParsecT s Int m Expression
parensExpr
(subscripts, b) <- collectsubscripts id a
if null subscripts
then case b of
VariableExpression (Variable Text
"_") -> SourceName -> ParsecT s Int m Expression
forall s (m :: * -> *) t u a.
Stream s m t =>
SourceName -> ParsecT s u m a
unexpected SourceName
"wildcard without subscript"
Expression
_ -> Expression -> ParsecT s Int m Expression
forall a. a -> ParsecT s Int m a
forall (f :: * -> *) a. Applicative f => a -> f a
pure Expression
a
else pure (SubscriptExpression
(case b of
VariableExpression (Variable Text
"_") -> Subscripted
WildcardSubscripted
Expression
_ -> Expression -> Subscripted
ExpressionSubscripted Expression
b)
subscripts)
unambiguous :: ParsecT s Int m Expression
unambiguous = ParsecT s Int m Expression
funcOp ParsecT s Int m Expression
-> ParsecT s Int m Expression -> ParsecT s Int m Expression
forall s u (m :: * -> *) a.
ParsecT s u m a -> ParsecT s u m a -> ParsecT s u m a
<|> ParsecT s Int m Expression
record ParsecT s Int m Expression
-> ParsecT s Int m Expression -> ParsecT s Int m Expression
forall s u (m :: * -> *) a.
ParsecT s u m a -> ParsecT s u m a -> ParsecT s u m a
<|> ParsecT s Int m Expression
TokenParser Expression
atomic
parensExpr :: ParsecT s Int m Expression
parensExpr = TokenParser Expression -> TokenParser Expression
forall a. TokenParser a -> TokenParser a
parens ParsecT s Int m Expression
TokenParser Expression
expressionParser
parens :: TokenParser a -> TokenParser a
parens :: forall a. TokenParser a -> TokenParser a
parens TokenParser a
p = ParsecT s Int m a
go ParsecT s Int m a -> SourceName -> ParsecT s Int m a
forall s u (m :: * -> *) a.
ParsecT s u m a -> SourceName -> ParsecT s u m a
<?> SourceName
"parens e.g. (x)"
where
go :: ParsecT s Int m a
go = do
_ <- Token -> TokenParser Location
equalToken Token
OpenParen
e <- p <?> "expression inside parentheses e.g. (foo)"
_ <- equalToken CloseParen <?> "closing parenthesis ‘)’"
pure e
varParser :: TokenParser Expression
varParser :: TokenParser Expression
varParser = ParsecT s Int m Expression
go ParsecT s Int m Expression
-> SourceName -> ParsecT s Int m Expression
forall s u (m :: * -> *) a.
ParsecT s u m a -> SourceName -> ParsecT s u m a
<?> SourceName
"variable (e.g. ‘foo’, ‘id’, etc.)"
where
go :: ParsecT s Int m Expression
go = do
(v, _) <-
(Token -> Maybe Text) -> TokenParser (Text, Location)
forall a. (Token -> Maybe a) -> TokenParser (a, Location)
consumeToken
(\case
VariableToken Text
i -> Text -> Maybe Text
forall a. a -> Maybe a
Just Text
i
Token
_ -> Maybe Text
forall a. Maybe a
Nothing)
pure
(VariableExpression (Variable v))
ifParser :: TokenParser Expression
ifParser :: TokenParser Expression
ifParser = ParsecT s Int m Expression
go ParsecT s Int m Expression
-> SourceName -> ParsecT s Int m Expression
forall s u (m :: * -> *) a.
ParsecT s u m a -> SourceName -> ParsecT s u m a
<?> SourceName
"if expression (e.g. ‘if p then x else y’)"
where
go :: ParsecT s Int m Expression
go = do
_ <- Token -> TokenParser Location
equalToken Token
If
p <- expressionParser <?> "condition expresion of if-expression"
_ <- equalToken Then <?> "‘then’ keyword for if-expression"
e1 <- expressionParser <?> "‘then’ clause of if-expression"
_ <- equalToken Else <?> "‘else’ keyword for if-expression"
e2 <- expressionParser <?> "‘else’ clause of if-expression"
pure (IfExpression p e1 e2)
atomic :: TokenParser Expression
atomic :: TokenParser Expression
atomic =
ParsecT s Int m Expression
nullParser ParsecT s Int m Expression
-> ParsecT s Int m Expression -> ParsecT s Int m Expression
forall s u (m :: * -> *) a.
ParsecT s u m a -> ParsecT s u m a -> ParsecT s u m a
<|> ParsecT s Int m Expression
boolParser ParsecT s Int m Expression
-> ParsecT s Int m Expression -> ParsecT s Int m Expression
forall s u (m :: * -> *) a.
ParsecT s u m a -> ParsecT s u m a -> ParsecT s u m a
<|> ParsecT s Int m Expression
TokenParser Expression
varParser ParsecT s Int m Expression
-> ParsecT s Int m Expression -> ParsecT s Int m Expression
forall s u (m :: * -> *) a.
ParsecT s u m a -> ParsecT s u m a -> ParsecT s u m a
<|> ParsecT s Int m Expression
TokenParser Expression
stringParser ParsecT s Int m Expression
-> ParsecT s Int m Expression -> ParsecT s Int m Expression
forall s u (m :: * -> *) a.
ParsecT s u m a -> ParsecT s u m a -> ParsecT s u m a
<|> ParsecT s Int m Expression
integerParser ParsecT s Int m Expression
-> ParsecT s Int m Expression -> ParsecT s Int m Expression
forall s u (m :: * -> *) a.
ParsecT s u m a -> ParsecT s u m a -> ParsecT s u m a
<|>
ParsecT s Int m Expression
decimalParser
where
integerParser :: ParsecT s Int m Expression
integerParser = ParsecT s Int m Expression
go ParsecT s Int m Expression
-> SourceName -> ParsecT s Int m Expression
forall s u (m :: * -> *) a.
ParsecT s u m a -> SourceName -> ParsecT s u m a
<?> SourceName
"integer (e.g. 42, 123)"
where
go :: ParsecT s Int m Expression
go = do
(c, _) <-
(Token -> Maybe Integer) -> TokenParser (Integer, Location)
forall a. (Token -> Maybe a) -> TokenParser (a, Location)
consumeToken
(\case
Integer Integer
c -> Integer -> Maybe Integer
forall a. a -> Maybe a
Just Integer
c
Token
_ -> Maybe Integer
forall a. Maybe a
Nothing)
pure (ConstantExpression (NumberConstant (fromIntegral c)))
decimalParser :: ParsecT s Int m Expression
decimalParser = ParsecT s Int m Expression
go ParsecT s Int m Expression
-> SourceName -> ParsecT s Int m Expression
forall s u (m :: * -> *) a.
ParsecT s u m a -> SourceName -> ParsecT s u m a
<?> SourceName
"decimal (e.g. 42, 123)"
where
go :: ParsecT s Int m Expression
go = do
(c, _) <-
(Token -> Maybe Double) -> TokenParser (Double, Location)
forall a. (Token -> Maybe a) -> TokenParser (a, Location)
consumeToken
(\case
Decimal Double
c -> Double -> Maybe Double
forall a. a -> Maybe a
Just Double
c
Token
_ -> Maybe Double
forall a. Maybe a
Nothing)
pure (ConstantExpression (NumberConstant (realToFrac c)))
boolParser :: ParsecT s Int m Expression
boolParser = ParsecT s Int m Expression
go ParsecT s Int m Expression
-> SourceName -> ParsecT s Int m Expression
forall s u (m :: * -> *) a.
ParsecT s u m a -> SourceName -> ParsecT s u m a
<?> SourceName
"boolean (e.g. true, false)"
where
go :: ParsecT s Int m Expression
go = do
(c, _) <-
(Token -> Maybe Bool) -> TokenParser (Bool, Location)
forall a. (Token -> Maybe a) -> TokenParser (a, Location)
consumeToken
(\case
Token
TrueToken -> Bool -> Maybe Bool
forall a. a -> Maybe a
forall (f :: * -> *) a. Applicative f => a -> f a
pure Bool
True
Token
FalseToken -> Bool -> Maybe Bool
forall a. a -> Maybe a
forall (f :: * -> *) a. Applicative f => a -> f a
pure Bool
False
Token
_ -> Maybe Bool
forall a. Maybe a
Nothing)
pure (ConstantExpression (BoolConstant c))
nullParser :: ParsecT s Int m Expression
nullParser = ParsecT s Int m Expression
go ParsecT s Int m Expression
-> SourceName -> ParsecT s Int m Expression
forall s u (m :: * -> *) a.
ParsecT s u m a -> SourceName -> ParsecT s u m a
<?> SourceName
"null"
where
go :: ParsecT s Int m Expression
go = do
((), _) <-
(Token -> Maybe ()) -> TokenParser ((), Location)
forall a. (Token -> Maybe a) -> TokenParser (a, Location)
consumeToken
(\case
Token
NullToken -> () -> Maybe ()
forall a. a -> Maybe a
forall (f :: * -> *) a. Applicative f => a -> f a
pure ()
Token
_ -> Maybe ()
forall a. Maybe a
Nothing)
pure (ConstantExpression NullConstant)
stringParser :: TokenParser Expression
stringParser :: TokenParser Expression
stringParser = ParsecT s Int m Expression
go ParsecT s Int m Expression
-> SourceName -> ParsecT s Int m Expression
forall s u (m :: * -> *) a.
ParsecT s u m a -> SourceName -> ParsecT s u m a
<?> SourceName
"string (e.g. \"a\")"
where
go :: ParsecT s Int m Expression
go = do
(c, _) <-
(Token -> Maybe Text) -> TokenParser (Text, Location)
forall a. (Token -> Maybe a) -> TokenParser (a, Location)
consumeToken
(\case
StringToken Text
c -> Text -> Maybe Text
forall a. a -> Maybe a
Just Text
c
Token
_ -> Maybe Text
forall a. Maybe a
Nothing)
pure (ConstantExpression (StringConstant c))
lambda :: TokenParser (Expression)
lambda :: TokenParser Expression
lambda = do
_ <- Token -> TokenParser Location
equalToken Token
Backslash ParsecT s Int m Location -> SourceName -> ParsecT s Int m Location
forall s u (m :: * -> *) a.
ParsecT s u m a -> SourceName -> ParsecT s u m a
<?> SourceName
"lambda expression (e.g. \\x -> x)"
args <- many1 funcParam <?> "lambda parameters"
_ <- equalToken RightArrow
e <- expressionParser
pure (foldl (\Expression
e' Variable
arg -> Variable -> Expression -> Expression
LambdaExpression Variable
arg Expression
e') e (reverse args))
funcParam :: TokenParser Variable
funcParam :: TokenParser Variable
funcParam = ParsecT s Int m Variable
go ParsecT s Int m Variable -> SourceName -> ParsecT s Int m Variable
forall s u (m :: * -> *) a.
ParsecT s u m a -> SourceName -> ParsecT s u m a
<?> SourceName
"function parameter (e.g. ‘x’, ‘limit’, etc.)"
where
go :: ParsecT s Int m Variable
go = do
(v, _) <-
(Token -> Maybe Text) -> TokenParser (Text, Location)
forall a. (Token -> Maybe a) -> TokenParser (a, Location)
consumeToken
(\case
VariableToken Text
i -> Text -> Maybe Text
forall a. a -> Maybe a
Just Text
i
Token
_ -> Maybe Text
forall a. Maybe a
Nothing)
pure (Variable v)