module Parser.Expression (pExpr) where
import Text.Megaparsec
import Text.Megaparsec.Char
import Control.Monad.Combinators.Expr
import qualified Data.Text as DT
import Data.Char (ord)
import AST.Ast (Ast(..))
import Common.Type.Integer (fitInteger, IntValue(..))
import qualified Text.Megaparsec.Char.Lexer as L
import Parser.Lexer
prefix :: DT.Text -> (Ast -> Ast)
prefix :: Text -> Ast -> Ast
prefix Text
name = \Ast
a -> Ast -> [Ast] -> Ast
ACall (Text -> Ast
ASymbol Text
name) [Ast
a]
pMemberSuffix :: Parser (Ast -> Ast)
pMemberSuffix :: Parser (Ast -> Ast)
pMemberSuffix = do
_ <- Text -> Parser Text
symbol (String -> Text
DT.pack String
".")
fieldName <- pIdentifier
return (\Ast
obj -> Ast -> Text -> Ast
AAccessStruct Ast
obj Text
fieldName)
pInteger :: Parser Ast
pInteger :: Parser Ast
pInteger = (Parser Ast -> Parser Ast
forall a. Parser a -> Parser a
lexeme (Parser Ast -> Parser Ast) -> Parser Ast -> Parser Ast
forall a b. (a -> b) -> a -> b
$ do
val <- ParsecT Void Text Identity ()
-> ParsecT Void Text Identity Integer
-> ParsecT Void Text Identity Integer
forall e s (m :: * -> *) a.
(MonadParsec e s m, Token s ~ Char, Num a) =>
m () -> m a -> m a
L.signed (() -> ParsecT Void Text Identity ()
forall a. a -> ParsecT Void Text Identity a
forall (m :: * -> *) a. Monad m => a -> m a
return ()) ParsecT Void Text Identity Integer
forall e s (m :: * -> *) a.
(MonadParsec e s m, Token s ~ Char, Num a) =>
m a
L.decimal
return (AInteger (fitInteger val))) Parser Ast -> String -> Parser Ast
forall e s (m :: * -> *) a.
MonadParsec e s m =>
m a -> String -> m a
<?> String
"integer"
pIndexSuffix :: Parser (Ast -> Ast)
pIndexSuffix :: Parser (Ast -> Ast)
pIndexSuffix = do
_ <- Text -> Parser Text
symbol (String -> Text
DT.pack String
"[")
indexExpr <- pExpr
_ <- symbol (DT.pack "]")
return (\Ast
arr -> Ast -> [Ast] -> Ast
ACall (Text -> Ast
ASymbol (String -> Text
DT.pack String
"nth")) [Ast
arr, Ast
indexExpr])
pCallSuffix :: Parser (Ast -> Ast)
pCallSuffix :: Parser (Ast -> Ast)
pCallSuffix = do
args <- Parser [Ast] -> Parser [Ast]
forall a. Parser a -> Parser a
parens (Parser Ast
pExpr Parser Ast -> Parser Text -> Parser [Ast]
forall (m :: * -> *) a sep. MonadPlus m => m a -> m sep -> m [a]
`sepBy` Parser Text
comma)
return (\Ast
func -> Ast -> [Ast] -> Ast
ACall Ast
func [Ast]
args)
pBool :: Parser Ast
pBool :: Parser Ast
pBool = Parser Ast -> Parser Ast
forall a. Parser a -> Parser a
lexeme ([Parser Ast] -> Parser Ast
forall (f :: * -> *) (m :: * -> *) a.
(Foldable f, Alternative m) =>
f (m a) -> m a
choice
[ Bool -> Ast
ABool Bool
True Ast -> ParsecT Void Text Identity (Tokens Text) -> Parser Ast
forall a b.
a -> ParsecT Void Text Identity b -> ParsecT Void Text Identity a
forall (f :: * -> *) a b. Functor f => a -> f b -> f a
<$ Tokens Text -> ParsecT Void Text Identity (Tokens Text)
forall e s (m :: * -> *).
MonadParsec e s m =>
Tokens s -> m (Tokens s)
string (String -> Text
DT.pack String
"True")
, Bool -> Ast
ABool Bool
False Ast -> ParsecT Void Text Identity (Tokens Text) -> Parser Ast
forall a b.
a -> ParsecT Void Text Identity b -> ParsecT Void Text Identity a
forall (f :: * -> *) a b. Functor f => a -> f b -> f a
<$ Tokens Text -> ParsecT Void Text Identity (Tokens Text)
forall e s (m :: * -> *).
MonadParsec e s m =>
Tokens s -> m (Tokens s)
string (String -> Text
DT.pack String
"False")
]) Parser Ast -> String -> Parser Ast
forall e s (m :: * -> *) a.
MonadParsec e s m =>
m a -> String -> m a
<?> String
"boolean"
pString :: Parser Ast
pString :: Parser Ast
pString = (Parser Ast -> Parser Ast
forall a. Parser a -> Parser a
lexeme (Parser Ast -> Parser Ast) -> Parser Ast -> Parser Ast
forall a b. (a -> b) -> a -> b
$ do
content <- ParsecT Void Text Identity Char
-> ParsecT Void Text Identity Char
-> ParsecT Void Text Identity String
-> ParsecT Void Text Identity String
forall (m :: * -> *) open close a.
Applicative m =>
m open -> m close -> m a -> m a
between (Token Text -> ParsecT Void Text Identity (Token Text)
forall e s (m :: * -> *).
(MonadParsec e s m, Token s ~ Char) =>
Token s -> m (Token s)
char Char
Token Text
'"') (Token Text -> ParsecT Void Text Identity (Token Text)
forall e s (m :: * -> *).
(MonadParsec e s m, Token s ~ Char) =>
Token s -> m (Token s)
char Char
Token Text
'"') (ParsecT Void Text Identity Char
-> ParsecT Void Text Identity String
forall (m :: * -> *) a. MonadPlus m => m a -> m [a]
many ParsecT Void Text Identity Char
pStringChar)
return $ AList (map (AInteger . IChar . fromIntegral . ord) content)
) Parser Ast -> String -> Parser Ast
forall e s (m :: * -> *) a.
MonadParsec e s m =>
m a -> String -> m a
<?> String
"string"
pChar :: Parser Ast
pChar :: Parser Ast
pChar = (Parser Ast -> Parser Ast
forall a. Parser a -> Parser a
lexeme (Parser Ast -> Parser Ast) -> Parser Ast -> Parser Ast
forall a b. (a -> b) -> a -> b
$ do
_ <- Token Text -> ParsecT Void Text Identity (Token Text)
forall e s (m :: * -> *).
(MonadParsec e s m, Token s ~ Char) =>
Token s -> m (Token s)
char Char
Token Text
'\''
c <- L.charLiteral
_ <- char '\''
return (AInteger (IChar (fromIntegral (ord c))))) Parser Ast -> String -> Parser Ast
forall e s (m :: * -> *) a.
MonadParsec e s m =>
m a -> String -> m a
<?> String
"character"
pListLiteral :: Parser Ast
pListLiteral :: Parser Ast
pListLiteral = (do
_ <- Text -> Parser Text
symbol (String -> Text
DT.pack String
"[")
exprs <- pExpr `sepBy` comma
_ <- symbol (DT.pack "]")
return (AList exprs)) Parser Ast -> String -> Parser Ast
forall e s (m :: * -> *) a.
MonadParsec e s m =>
m a -> String -> m a
<?> String
"list"
pVarOrCall :: Parser Ast
pVarOrCall :: Parser Ast
pVarOrCall = do
name <- Parser Text
pIdentifier
choice
[ do
args <- parens (pExpr `sepBy` comma)
return (ACall (ASymbol name) args)
, return (ASymbol name)
]
pFieldInit :: Parser (DT.Text, Ast)
pFieldInit :: Parser (Text, Ast)
pFieldInit = do
name <- Parser Text
pIdentifier
_ <- symbol (DT.pack ":")
val <- pExpr
return (name, val)
pNew :: Parser Ast
pNew :: Parser Ast
pNew = do
_ <- Text -> Parser Text
pKeyword (String -> Text
DT.pack String
"new")
className <- pIdentifier
fields <- braces (pFieldInit `sepBy` comma)
return (ASetStruct className fields)
pLambda :: Parser Ast
pLambda :: Parser Ast
pLambda = do
_ <- Text -> Parser Text
pKeyword (String -> Text
DT.pack String
"lambda")
args <- parens (pIdentifier `sepBy` comma)
_ <- optional (symbol (DT.pack "->"))
body <- pExpr
return (ADefineLambda args body)
pIfExpr :: Parser Ast
pIfExpr :: Parser Ast
pIfExpr = do
_ <- Text -> Parser Text
pKeyword (String -> Text
DT.pack String
"if")
cond <- parens pExpr
thenExpr <- braces pExpr
elseExpr <- option AVoid $ do
_ <- pKeyword (DT.pack "else")
braces pExpr
return (AIf cond thenExpr elseExpr)
pEscapeCode :: Parser Char
pEscapeCode :: ParsecT Void Text Identity Char
pEscapeCode = [ParsecT Void Text Identity Char]
-> ParsecT Void Text Identity Char
forall (f :: * -> *) (m :: * -> *) a.
(Foldable f, Alternative m) =>
f (m a) -> m a
choice
[ Token Text -> ParsecT Void Text Identity (Token Text)
forall e s (m :: * -> *).
(MonadParsec e s m, Token s ~ Char) =>
Token s -> m (Token s)
char Char
Token Text
'n' ParsecT Void Text Identity Char
-> ParsecT Void Text Identity Char
-> ParsecT Void Text Identity Char
forall a b.
ParsecT Void Text Identity a
-> ParsecT Void Text Identity b -> ParsecT Void Text Identity b
forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> Char -> ParsecT Void Text Identity Char
forall a. a -> ParsecT Void Text Identity a
forall (m :: * -> *) a. Monad m => a -> m a
return Char
'\n'
, Token Text -> ParsecT Void Text Identity (Token Text)
forall e s (m :: * -> *).
(MonadParsec e s m, Token s ~ Char) =>
Token s -> m (Token s)
char Char
Token Text
'r' ParsecT Void Text Identity Char
-> ParsecT Void Text Identity Char
-> ParsecT Void Text Identity Char
forall a b.
ParsecT Void Text Identity a
-> ParsecT Void Text Identity b -> ParsecT Void Text Identity b
forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> Char -> ParsecT Void Text Identity Char
forall a. a -> ParsecT Void Text Identity a
forall (m :: * -> *) a. Monad m => a -> m a
return Char
'\r'
, Token Text -> ParsecT Void Text Identity (Token Text)
forall e s (m :: * -> *).
(MonadParsec e s m, Token s ~ Char) =>
Token s -> m (Token s)
char Char
Token Text
't' ParsecT Void Text Identity Char
-> ParsecT Void Text Identity Char
-> ParsecT Void Text Identity Char
forall a b.
ParsecT Void Text Identity a
-> ParsecT Void Text Identity b -> ParsecT Void Text Identity b
forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> Char -> ParsecT Void Text Identity Char
forall a. a -> ParsecT Void Text Identity a
forall (m :: * -> *) a. Monad m => a -> m a
return Char
'\t'
, Token Text -> ParsecT Void Text Identity (Token Text)
forall e s (m :: * -> *).
(MonadParsec e s m, Token s ~ Char) =>
Token s -> m (Token s)
char Char
Token Text
'0' ParsecT Void Text Identity Char
-> ParsecT Void Text Identity Char
-> ParsecT Void Text Identity Char
forall a b.
ParsecT Void Text Identity a
-> ParsecT Void Text Identity b -> ParsecT Void Text Identity b
forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> Char -> ParsecT Void Text Identity Char
forall a. a -> ParsecT Void Text Identity a
forall (m :: * -> *) a. Monad m => a -> m a
return Char
'\0'
, Token Text -> ParsecT Void Text Identity (Token Text)
forall e s (m :: * -> *).
(MonadParsec e s m, Token s ~ Char) =>
Token s -> m (Token s)
char Char
Token Text
'\\' ParsecT Void Text Identity Char
-> ParsecT Void Text Identity Char
-> ParsecT Void Text Identity Char
forall a b.
ParsecT Void Text Identity a
-> ParsecT Void Text Identity b -> ParsecT Void Text Identity b
forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> Char -> ParsecT Void Text Identity Char
forall a. a -> ParsecT Void Text Identity a
forall (m :: * -> *) a. Monad m => a -> m a
return Char
'\\'
, Token Text -> ParsecT Void Text Identity (Token Text)
forall e s (m :: * -> *).
(MonadParsec e s m, Token s ~ Char) =>
Token s -> m (Token s)
char Char
Token Text
'"' ParsecT Void Text Identity Char
-> ParsecT Void Text Identity Char
-> ParsecT Void Text Identity Char
forall a b.
ParsecT Void Text Identity a
-> ParsecT Void Text Identity b -> ParsecT Void Text Identity b
forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> Char -> ParsecT Void Text Identity Char
forall a. a -> ParsecT Void Text Identity a
forall (m :: * -> *) a. Monad m => a -> m a
return Char
'"'
]
pStringChar :: Parser Char
pStringChar :: ParsecT Void Text Identity Char
pStringChar =
ParsecT Void Text Identity Char -> ParsecT Void Text Identity Char
forall a. Parser a -> Parser a
forall e s (m :: * -> *) a. MonadParsec e s m => m a -> m a
try (Token Text -> ParsecT Void Text Identity (Token Text)
forall e s (m :: * -> *).
(MonadParsec e s m, Token s ~ Char) =>
Token s -> m (Token s)
char Char
Token Text
'\\' ParsecT Void Text Identity Char
-> ParsecT Void Text Identity Char
-> ParsecT Void Text Identity Char
forall a b.
ParsecT Void Text Identity a
-> ParsecT Void Text Identity b -> ParsecT Void Text Identity b
forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> ParsecT Void Text Identity Char
pEscapeCode)
ParsecT Void Text Identity Char
-> ParsecT Void Text Identity Char
-> ParsecT Void Text Identity Char
forall a.
ParsecT Void Text Identity a
-> ParsecT Void Text Identity a -> ParsecT Void Text Identity a
forall (f :: * -> *) a. Alternative f => f a -> f a -> f a
<|> [Token Text] -> ParsecT Void Text Identity (Token Text)
forall (f :: * -> *) e s (m :: * -> *).
(Foldable f, MonadParsec e s m) =>
f (Token s) -> m (Token s)
noneOf String
[Token Text]
"\""
pTermBase :: Parser Ast
pTermBase :: Parser Ast
pTermBase = Parser Ast -> Parser Ast
withPos (Parser Ast -> Parser Ast) -> Parser Ast -> Parser Ast
forall a b. (a -> b) -> a -> b
$ [Parser Ast] -> Parser Ast
forall (f :: * -> *) (m :: * -> *) a.
(Foldable f, Alternative m) =>
f (m a) -> m a
choice
[ Parser Ast -> Parser Ast
forall a. Parser a -> Parser a
forall e s (m :: * -> *) a. MonadParsec e s m => m a -> m a
try Parser Ast
pNew, Parser Ast -> Parser Ast
forall a. Parser a -> Parser a
forall e s (m :: * -> *) a. MonadParsec e s m => m a -> m a
try Parser Ast
pLambda
, Parser Ast -> Parser Ast
forall a. Parser a -> Parser a
parens Parser Ast
pExpr , Parser Ast -> Parser Ast
forall a. Parser a -> Parser a
forall e s (m :: * -> *) a. MonadParsec e s m => m a -> m a
try Parser Ast
pIfExpr
, Parser Ast
pInteger
, Parser Ast
pBool
, Parser Ast
pChar
, Parser Ast
pString
, Parser Ast
pListLiteral
, Parser Ast
pVarOrCall
]
pTerm :: Parser Ast
pTerm :: Parser Ast
pTerm = do
base <- Parser Ast
pTermBase
suffixes <- many (choice [try pCallSuffix, pIndexSuffix, pMemberSuffix])
return (foldl (\Ast
acc Ast -> Ast
f -> Ast -> Ast
f Ast
acc) base suffixes)
binary :: DT.Text -> (Ast -> Ast -> Ast)
binary :: Text -> Ast -> Ast -> Ast
binary Text
name = \Ast
a Ast
b -> Ast -> [Ast] -> Ast
ACall (Text -> Ast
ASymbol Text
name) [Ast
a, Ast
b]
sugarSyntOps :: [Operator Parser Ast]
sugarSyntOps :: [Operator Parser Ast]
sugarSyntOps =
[ Parser (Ast -> Ast) -> Operator Parser Ast
forall (m :: * -> *) a. m (a -> a) -> Operator m a
Prefix (Text -> Ast -> Ast
prefix (String -> Text
DT.pack String
"!") (Ast -> Ast) -> Parser Text -> Parser (Ast -> Ast)
forall a b.
a -> ParsecT Void Text Identity b -> ParsecT Void Text Identity a
forall (f :: * -> *) a b. Functor f => a -> f b -> f a
<$ Text -> Parser Text
symbol (String -> Text
DT.pack String
"!"))
, Parser (Ast -> Ast) -> Operator Parser Ast
forall (m :: * -> *) a. m (a -> a) -> Operator m a
Prefix (Ast -> Ast
incrementOps (Ast -> Ast) -> Parser Text -> Parser (Ast -> Ast)
forall a b.
a -> ParsecT Void Text Identity b -> ParsecT Void Text Identity a
forall (f :: * -> *) a b. Functor f => a -> f b -> f a
<$ Text -> Parser Text
symbol (String -> Text
DT.pack String
"++"))
, Parser (Ast -> Ast) -> Operator Parser Ast
forall (m :: * -> *) a. m (a -> a) -> Operator m a
Prefix (Ast -> Ast
decrementOps (Ast -> Ast) -> Parser Text -> Parser (Ast -> Ast)
forall a b.
a -> ParsecT Void Text Identity b -> ParsecT Void Text Identity a
forall (f :: * -> *) a b. Functor f => a -> f b -> f a
<$ Text -> Parser Text
symbol (String -> Text
DT.pack String
"--"))
, Parser (Ast -> Ast) -> Operator Parser Ast
forall (m :: * -> *) a. m (a -> a) -> Operator m a
Postfix (Ast -> Ast
incrementOps (Ast -> Ast) -> Parser Text -> Parser (Ast -> Ast)
forall a b.
a -> ParsecT Void Text Identity b -> ParsecT Void Text Identity a
forall (f :: * -> *) a b. Functor f => a -> f b -> f a
<$ Text -> Parser Text
symbol (String -> Text
DT.pack String
"++"))
, Parser (Ast -> Ast) -> Operator Parser Ast
forall (m :: * -> *) a. m (a -> a) -> Operator m a
Postfix (Ast -> Ast
decrementOps (Ast -> Ast) -> Parser Text -> Parser (Ast -> Ast)
forall a b.
a -> ParsecT Void Text Identity b -> ParsecT Void Text Identity a
forall (f :: * -> *) a b. Functor f => a -> f b -> f a
<$ Text -> Parser Text
symbol (String -> Text
DT.pack String
"--"))
]
multiplicativeOps :: [Operator Parser Ast]
multiplicativeOps :: [Operator Parser Ast]
multiplicativeOps =
[ Parser (Ast -> Ast -> Ast) -> Operator Parser Ast
forall (m :: * -> *) a. m (a -> a -> a) -> Operator m a
InfixL (Text -> Ast -> Ast -> Ast
binary (String -> Text
DT.pack String
"*") (Ast -> Ast -> Ast) -> Parser Text -> Parser (Ast -> Ast -> Ast)
forall a b.
a -> ParsecT Void Text Identity b -> ParsecT Void Text Identity a
forall (f :: * -> *) a b. Functor f => a -> f b -> f a
<$ Text -> Parser Text
symbol (String -> Text
DT.pack String
"*"))
, Parser (Ast -> Ast -> Ast) -> Operator Parser Ast
forall (m :: * -> *) a. m (a -> a -> a) -> Operator m a
InfixL (Text -> Ast -> Ast -> Ast
binary (String -> Text
DT.pack String
"div") (Ast -> Ast -> Ast) -> Parser Text -> Parser (Ast -> Ast -> Ast)
forall a b.
a -> ParsecT Void Text Identity b -> ParsecT Void Text Identity a
forall (f :: * -> *) a b. Functor f => a -> f b -> f a
<$ Text -> Parser Text
symbol (String -> Text
DT.pack String
"/"))
, Parser (Ast -> Ast -> Ast) -> Operator Parser Ast
forall (m :: * -> *) a. m (a -> a -> a) -> Operator m a
InfixL (Text -> Ast -> Ast -> Ast
binary (String -> Text
DT.pack String
"mod") (Ast -> Ast -> Ast) -> Parser Text -> Parser (Ast -> Ast -> Ast)
forall a b.
a -> ParsecT Void Text Identity b -> ParsecT Void Text Identity a
forall (f :: * -> *) a b. Functor f => a -> f b -> f a
<$ Text -> Parser Text
symbol (String -> Text
DT.pack String
"%"))
]
additiveOps :: [Operator Parser Ast]
additiveOps :: [Operator Parser Ast]
additiveOps =
[ Parser (Ast -> Ast -> Ast) -> Operator Parser Ast
forall (m :: * -> *) a. m (a -> a -> a) -> Operator m a
InfixL (Text -> Ast -> Ast -> Ast
binary (String -> Text
DT.pack String
"+") (Ast -> Ast -> Ast) -> Parser Text -> Parser (Ast -> Ast -> Ast)
forall a b.
a -> ParsecT Void Text Identity b -> ParsecT Void Text Identity a
forall (f :: * -> *) a b. Functor f => a -> f b -> f a
<$ Text -> Parser Text
symbol (String -> Text
DT.pack String
"+"))
, Parser (Ast -> Ast -> Ast) -> Operator Parser Ast
forall (m :: * -> *) a. m (a -> a -> a) -> Operator m a
InfixL (Text -> Ast -> Ast -> Ast
binary (String -> Text
DT.pack String
"-") (Ast -> Ast -> Ast) -> Parser Text -> Parser (Ast -> Ast -> Ast)
forall a b.
a -> ParsecT Void Text Identity b -> ParsecT Void Text Identity a
forall (f :: * -> *) a b. Functor f => a -> f b -> f a
<$ Text -> Parser Text
symbol (String -> Text
DT.pack String
"-"))
]
comparisonOps :: [Operator Parser Ast]
comparisonOps :: [Operator Parser Ast]
comparisonOps =
[ Parser (Ast -> Ast -> Ast) -> Operator Parser Ast
forall (m :: * -> *) a. m (a -> a -> a) -> Operator m a
InfixL (Text -> Ast -> Ast -> Ast
binary (String -> Text
DT.pack String
"teq?") (Ast -> Ast -> Ast) -> Parser Text -> Parser (Ast -> Ast -> Ast)
forall a b.
a -> ParsecT Void Text Identity b -> ParsecT Void Text Identity a
forall (f :: * -> *) a b. Functor f => a -> f b -> f a
<$ Parser Text -> Parser Text
forall a. Parser a -> Parser a
forall e s (m :: * -> *) a. MonadParsec e s m => m a -> m a
try (Text -> Parser Text
symbol (String -> Text
DT.pack String
"===")))
, Parser (Ast -> Ast -> Ast) -> Operator Parser Ast
forall (m :: * -> *) a. m (a -> a -> a) -> Operator m a
InfixL (Text -> Ast -> Ast -> Ast
binary (String -> Text
DT.pack String
"tneq?") (Ast -> Ast -> Ast) -> Parser Text -> Parser (Ast -> Ast -> Ast)
forall a b.
a -> ParsecT Void Text Identity b -> ParsecT Void Text Identity a
forall (f :: * -> *) a b. Functor f => a -> f b -> f a
<$ Parser Text -> Parser Text
forall a. Parser a -> Parser a
forall e s (m :: * -> *) a. MonadParsec e s m => m a -> m a
try (Text -> Parser Text
symbol (String -> Text
DT.pack String
"!==")))
, Parser (Ast -> Ast -> Ast) -> Operator Parser Ast
forall (m :: * -> *) a. m (a -> a -> a) -> Operator m a
InfixL (Text -> Ast -> Ast -> Ast
binary (String -> Text
DT.pack String
"eq?") (Ast -> Ast -> Ast) -> Parser Text -> Parser (Ast -> Ast -> Ast)
forall a b.
a -> ParsecT Void Text Identity b -> ParsecT Void Text Identity a
forall (f :: * -> *) a b. Functor f => a -> f b -> f a
<$ Text -> Parser Text
symbol (String -> Text
DT.pack String
"=="))
, Parser (Ast -> Ast -> Ast) -> Operator Parser Ast
forall (m :: * -> *) a. m (a -> a -> a) -> Operator m a
InfixL (Text -> Ast -> Ast -> Ast
binary (String -> Text
DT.pack String
"neq?") (Ast -> Ast -> Ast) -> Parser Text -> Parser (Ast -> Ast -> Ast)
forall a b.
a -> ParsecT Void Text Identity b -> ParsecT Void Text Identity a
forall (f :: * -> *) a b. Functor f => a -> f b -> f a
<$ Text -> Parser Text
symbol (String -> Text
DT.pack String
"!="))
, Parser (Ast -> Ast -> Ast) -> Operator Parser Ast
forall (m :: * -> *) a. m (a -> a -> a) -> Operator m a
InfixL (Text -> Ast -> Ast -> Ast
binary (String -> Text
DT.pack String
"<=") (Ast -> Ast -> Ast) -> Parser Text -> Parser (Ast -> Ast -> Ast)
forall a b.
a -> ParsecT Void Text Identity b -> ParsecT Void Text Identity a
forall (f :: * -> *) a b. Functor f => a -> f b -> f a
<$ Parser Text -> Parser Text
forall a. Parser a -> Parser a
forall e s (m :: * -> *) a. MonadParsec e s m => m a -> m a
try (Text -> Parser Text
symbol (String -> Text
DT.pack String
"<=")))
, Parser (Ast -> Ast -> Ast) -> Operator Parser Ast
forall (m :: * -> *) a. m (a -> a -> a) -> Operator m a
InfixL (Text -> Ast -> Ast -> Ast
binary (String -> Text
DT.pack String
">=") (Ast -> Ast -> Ast) -> Parser Text -> Parser (Ast -> Ast -> Ast)
forall a b.
a -> ParsecT Void Text Identity b -> ParsecT Void Text Identity a
forall (f :: * -> *) a b. Functor f => a -> f b -> f a
<$ Parser Text -> Parser Text
forall a. Parser a -> Parser a
forall e s (m :: * -> *) a. MonadParsec e s m => m a -> m a
try (Text -> Parser Text
symbol (String -> Text
DT.pack String
">=")))
, Parser (Ast -> Ast -> Ast) -> Operator Parser Ast
forall (m :: * -> *) a. m (a -> a -> a) -> Operator m a
InfixL (Text -> Ast -> Ast -> Ast
binary (String -> Text
DT.pack String
"<") (Ast -> Ast -> Ast) -> Parser Text -> Parser (Ast -> Ast -> Ast)
forall a b.
a -> ParsecT Void Text Identity b -> ParsecT Void Text Identity a
forall (f :: * -> *) a b. Functor f => a -> f b -> f a
<$ Text -> Parser Text
symbol (String -> Text
DT.pack String
"<"))
, Parser (Ast -> Ast -> Ast) -> Operator Parser Ast
forall (m :: * -> *) a. m (a -> a -> a) -> Operator m a
InfixL (Text -> Ast -> Ast -> Ast
binary (String -> Text
DT.pack String
">") (Ast -> Ast -> Ast) -> Parser Text -> Parser (Ast -> Ast -> Ast)
forall a b.
a -> ParsecT Void Text Identity b -> ParsecT Void Text Identity a
forall (f :: * -> *) a b. Functor f => a -> f b -> f a
<$ Text -> Parser Text
symbol (String -> Text
DT.pack String
">"))
]
logicalAndOps :: [Operator Parser Ast]
logicalAndOps :: [Operator Parser Ast]
logicalAndOps =
[ Parser (Ast -> Ast -> Ast) -> Operator Parser Ast
forall (m :: * -> *) a. m (a -> a -> a) -> Operator m a
InfixL (Text -> Ast -> Ast -> Ast
binary (String -> Text
DT.pack String
"&&") (Ast -> Ast -> Ast) -> Parser Text -> Parser (Ast -> Ast -> Ast)
forall a b.
a -> ParsecT Void Text Identity b -> ParsecT Void Text Identity a
forall (f :: * -> *) a b. Functor f => a -> f b -> f a
<$ Text -> Parser Text
symbol (String -> Text
DT.pack String
"&&")) ]
logicalOrOps :: [Operator Parser Ast]
logicalOrOps :: [Operator Parser Ast]
logicalOrOps =
[ Parser (Ast -> Ast -> Ast) -> Operator Parser Ast
forall (m :: * -> *) a. m (a -> a -> a) -> Operator m a
InfixL (Text -> Ast -> Ast -> Ast
binary (String -> Text
DT.pack String
"||") (Ast -> Ast -> Ast) -> Parser Text -> Parser (Ast -> Ast -> Ast)
forall a b.
a -> ParsecT Void Text Identity b -> ParsecT Void Text Identity a
forall (f :: * -> *) a b. Functor f => a -> f b -> f a
<$ Text -> Parser Text
symbol (String -> Text
DT.pack String
"||")) ]
incrementOps :: Ast -> Ast
incrementOps :: Ast -> Ast
incrementOps (ASymbol Text
name) =
Text -> Text -> Ast -> Ast
ASetVar Text
name (String -> Text
DT.pack String
"auto") (Ast -> [Ast] -> Ast
ACall (Text -> Ast
ASymbol (String -> Text
DT.pack String
"+"))
[Text -> Ast
ASymbol Text
name, IntValue -> Ast
AInteger (Integer -> IntValue
fitInteger Integer
1)])
incrementOps (APos Int
l Int
c Ast
ast) = Int -> Int -> Ast -> Ast
APos Int
l Int
c (Ast -> Ast
incrementOps Ast
ast)
incrementOps Ast
other = Ast -> [Ast] -> Ast
ACall (Text -> Ast
ASymbol (String -> Text
DT.pack String
"++")) [Ast
other]
decrementOps :: Ast -> Ast
decrementOps :: Ast -> Ast
decrementOps (ASymbol Text
name) =
Text -> Text -> Ast -> Ast
ASetVar Text
name (String -> Text
DT.pack String
"auto") (Ast -> [Ast] -> Ast
ACall (Text -> Ast
ASymbol (String -> Text
DT.pack String
"-"))
[Text -> Ast
ASymbol Text
name, IntValue -> Ast
AInteger (Integer -> IntValue
fitInteger Integer
1)])
decrementOps (APos Int
l Int
c Ast
ast) = Int -> Int -> Ast -> Ast
APos Int
l Int
c (Ast -> Ast
decrementOps Ast
ast)
decrementOps Ast
other = Ast -> [Ast] -> Ast
ACall (Text -> Ast
ASymbol (String -> Text
DT.pack String
"--")) [Ast
other]
opTable :: [[Operator Parser Ast]]
opTable :: [[Operator Parser Ast]]
opTable = [[Operator Parser Ast]
sugarSyntOps, [Operator Parser Ast]
multiplicativeOps, [Operator Parser Ast]
additiveOps,
[Operator Parser Ast]
comparisonOps, [Operator Parser Ast]
logicalAndOps, [Operator Parser Ast]
logicalOrOps]
pExpr :: Parser Ast
pExpr :: Parser Ast
pExpr = Parser Ast -> [[Operator Parser Ast]] -> Parser Ast
forall (m :: * -> *) a.
MonadPlus m =>
m a -> [[Operator m a]] -> m a
makeExprParser Parser Ast
pTerm [[Operator Parser Ast]]
opTable