{-# LANGUAGE OverloadedStrings #-}
{-# LANGUAGE TupleSections #-}

module Parser.Parser (parseProgram) where

import Control.Monad.Combinators.Expr (Operator (..), makeExprParser)
import Data.List.NonEmpty (some1)
import Data.Text (Text)
import Parser.Ast
import Parser.Lexer
import Parser.Utils
import Text.Megaparsec (MonadParsec (..), many, parseMaybe)
import Trees.Common

-- * Program Parser

-- | Parser entry point
parseProgram :: Text -> Maybe Program
parseProgram :: Text -> Maybe Program
parseProgram = Parsec Void Text Program -> Text -> Maybe Program
forall e s a. (Ord e, Stream s) => Parsec e s a -> s -> Maybe a
parseMaybe (Parsec Void Text Program -> Text -> Maybe Program)
-> Parsec Void Text Program -> Text -> Maybe Program
forall a b. (a -> b) -> a -> b
$ Parser ()
sc Parser () -> Parsec Void Text Program -> Parsec Void Text Program
forall a b.
ParsecT Void Text Identity a
-> ParsecT Void Text Identity b -> ParsecT Void Text Identity b
forall (f :: * -> *) a b. Applicative f => f a -> f b -> f b
*> Parsec Void Text Program
programP Parsec Void Text Program -> Parser () -> Parsec Void Text Program
forall a b.
ParsecT Void Text Identity a
-> ParsecT Void Text Identity b -> ParsecT Void Text Identity a
forall (f :: * -> *) a b. Applicative f => f a -> f b -> f a
<* Parser ()
forall e s (m :: * -> *). MonadParsec e s m => m ()
eof

-- * Internal

programP :: Parser Program
programP :: Parsec Void Text Program
programP = [Statement] -> Program
Program ([Statement] -> Program)
-> ParsecT Void Text Identity [Statement]
-> Parsec Void Text Program
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> (ParsecT Void Text Identity Text
-> ParsecT Void Text Identity [Text]
forall (m :: * -> *) a. MonadPlus m => m a -> m [a]
many ParsecT Void Text Identity Text
semicolon2 ParsecT Void Text Identity [Text]
-> ParsecT Void Text Identity [Statement]
-> ParsecT Void Text Identity [Statement]
forall a b.
ParsecT Void Text Identity a
-> ParsecT Void Text Identity b -> ParsecT Void Text Identity b
forall (f :: * -> *) a b. Applicative f => f a -> f b -> f b
*> ParsecT Void Text Identity Statement
-> ParsecT Void Text Identity [Statement]
forall (m :: * -> *) a. MonadPlus m => m a -> m [a]
many (ParsecT Void Text Identity Statement
stmtP ParsecT Void Text Identity Statement
-> ParsecT Void Text Identity [Text]
-> ParsecT Void Text Identity Statement
forall a b.
ParsecT Void Text Identity a
-> ParsecT Void Text Identity b -> ParsecT Void Text Identity a
forall (f :: * -> *) a b. Applicative f => f a -> f b -> f a
<* ParsecT Void Text Identity Text
-> ParsecT Void Text Identity [Text]
forall (m :: * -> *) a. MonadPlus m => m a -> m [a]
many ParsecT Void Text Identity Text
semicolon2))

stmtP :: Parser Statement
stmtP :: ParsecT Void Text Identity Statement
stmtP = [ParsecT Void Text Identity Statement]
-> ParsecT Void Text Identity Statement
forall (f :: * -> *) a.
(Foldable f, Functor f) =>
f (Parser a) -> Parser a
choice' [Expression -> Statement
StmtExpr (Expression -> Statement)
-> ParsecT Void Text Identity Expression
-> ParsecT Void Text Identity Statement
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> ParsecT Void Text Identity Expression
exprP, Declaration -> Statement
StmtDecl (Declaration -> Statement)
-> ParsecT Void Text Identity Declaration
-> ParsecT Void Text Identity Statement
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> ParsecT Void Text Identity Declaration
declP]

-- ** User Declaration Parsers

declP :: Parser Declaration
declP :: ParsecT Void Text Identity Declaration
declP = [ParsecT Void Text Identity Declaration]
-> ParsecT Void Text Identity Declaration
forall (f :: * -> *) a.
(Foldable f, Functor f) =>
f (Parser a) -> Parser a
choice' [ParsecT Void Text Identity Declaration
recFunDeclP, ParsecT Void Text Identity Declaration
funDeclP, ParsecT Void Text Identity Declaration
varDeclP]
  where
    varDeclP :: ParsecT Void Text Identity Declaration
varDeclP = (Text, Maybe Type) -> Expression -> Declaration
DeclVar ((Text, Maybe Type) -> Expression -> Declaration)
-> ParsecT Void Text Identity Text
-> ParsecT
     Void
     Text
     Identity
     ((Text, Maybe Type) -> Expression -> Declaration)
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
<$ ParsecT Void Text Identity Text
kwLet ParsecT
  Void
  Text
  Identity
  ((Text, Maybe Type) -> Expression -> Declaration)
-> ParsecT Void Text Identity (Text, Maybe Type)
-> ParsecT Void Text Identity (Expression -> Declaration)
forall a b.
ParsecT Void Text Identity (a -> b)
-> ParsecT Void Text Identity a -> ParsecT Void Text Identity b
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> ParsecT Void Text Identity (Text, Maybe Type)
varSigP ParsecT Void Text Identity (Expression -> Declaration)
-> ParsecT Void Text Identity Text
-> ParsecT Void Text Identity (Expression -> Declaration)
forall a b.
ParsecT Void Text Identity a
-> ParsecT Void Text Identity b -> ParsecT Void Text Identity a
forall (f :: * -> *) a b. Applicative f => f a -> f b -> f a
<* ParsecT Void Text Identity Text
eq ParsecT Void Text Identity (Expression -> Declaration)
-> ParsecT Void Text Identity Expression
-> ParsecT Void Text Identity Declaration
forall a b.
ParsecT Void Text Identity (a -> b)
-> ParsecT Void Text Identity a -> ParsecT Void Text Identity b
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> ParsecT Void Text Identity Expression
exprP
    funDeclP :: ParsecT Void Text Identity Declaration
funDeclP = (Text -> IsRec -> Fun -> Declaration)
-> IsRec -> Text -> Fun -> Declaration
forall a b c. (a -> b -> c) -> b -> a -> c
flip Text -> IsRec -> Fun -> Declaration
DeclFun IsRec
False (Text -> Fun -> Declaration)
-> ParsecT Void Text Identity Text
-> ParsecT Void Text Identity (Text -> Fun -> Declaration)
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
<$ ParsecT Void Text Identity Text
kwLet ParsecT Void Text Identity (Text -> Fun -> Declaration)
-> ParsecT Void Text Identity Text
-> ParsecT Void Text Identity (Fun -> Declaration)
forall a b.
ParsecT Void Text Identity (a -> b)
-> ParsecT Void Text Identity a -> ParsecT Void Text Identity b
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> ParsecT Void Text Identity Text
identifierP ParsecT Void Text Identity (Fun -> Declaration)
-> ParsecT Void Text Identity Fun
-> ParsecT Void Text Identity Declaration
forall a b.
ParsecT Void Text Identity (a -> b)
-> ParsecT Void Text Identity a -> ParsecT Void Text Identity b
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> ParsecT Void Text Identity Text -> ParsecT Void Text Identity Fun
funP ParsecT Void Text Identity Text
eq
    recFunDeclP :: ParsecT Void Text Identity Declaration
recFunDeclP = (Text -> IsRec -> Fun -> Declaration)
-> IsRec -> Text -> Fun -> Declaration
forall a b c. (a -> b -> c) -> b -> a -> c
flip Text -> IsRec -> Fun -> Declaration
DeclFun IsRec
True (Text -> Fun -> Declaration)
-> ParsecT Void Text Identity Text
-> ParsecT Void Text Identity (Text -> Fun -> Declaration)
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
<$ ParsecT Void Text Identity Text
kwLet ParsecT Void Text Identity (Text -> Fun -> Declaration)
-> ParsecT Void Text Identity Text
-> ParsecT Void Text Identity (Text -> Fun -> Declaration)
forall a b.
ParsecT Void Text Identity a
-> ParsecT Void Text Identity b -> ParsecT Void Text Identity a
forall (f :: * -> *) a b. Applicative f => f a -> f b -> f a
<* ParsecT Void Text Identity Text
kwRec ParsecT Void Text Identity (Text -> Fun -> Declaration)
-> ParsecT Void Text Identity Text
-> ParsecT Void Text Identity (Fun -> Declaration)
forall a b.
ParsecT Void Text Identity (a -> b)
-> ParsecT Void Text Identity a -> ParsecT Void Text Identity b
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> ParsecT Void Text Identity Text
identifierP ParsecT Void Text Identity (Fun -> Declaration)
-> ParsecT Void Text Identity Fun
-> ParsecT Void Text Identity Declaration
forall a b.
ParsecT Void Text Identity (a -> b)
-> ParsecT Void Text Identity a -> ParsecT Void Text Identity b
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> ParsecT Void Text Identity Text -> ParsecT Void Text Identity Fun
funP ParsecT Void Text Identity Text
eq

    varSigP :: ParsecT Void Text Identity (Text, Maybe Type)
varSigP = ParsecT Void Text Identity (Text, Maybe Type)
-> ParsecT Void Text Identity (Text, Maybe Type)
forall a. Parser a -> Parser a
manyParens (ParsecT Void Text Identity (Text, Maybe Type)
 -> ParsecT Void Text Identity (Text, Maybe Type))
-> ParsecT Void Text Identity (Text, Maybe Type)
-> ParsecT Void Text Identity (Text, Maybe Type)
forall a b. (a -> b) -> a -> b
$ (,) (Text -> Maybe Type -> (Text, Maybe Type))
-> ParsecT Void Text Identity Text
-> ParsecT Void Text Identity (Maybe Type -> (Text, Maybe Type))
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> ParsecT Void Text Identity Text -> ParsecT Void Text Identity Text
forall a. Parser a -> Parser a
manyParens ParsecT Void Text Identity Text
identifierP ParsecT Void Text Identity (Maybe Type -> (Text, Maybe Type))
-> ParsecT Void Text Identity (Maybe Type)
-> ParsecT Void Text Identity (Text, Maybe Type)
forall a b.
ParsecT Void Text Identity (a -> b)
-> ParsecT Void Text Identity a -> ParsecT Void Text Identity b
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> ParsecT Void Text Identity (Maybe Type)
optionalTypeAnnotationP

-- ** Expression Parsers

exprP :: Parser Expression
exprP :: ParsecT Void Text Identity Expression
exprP = ParsecT Void Text Identity Expression
-> [[Operator (ParsecT Void Text Identity) Expression]]
-> ParsecT Void Text Identity Expression
forall (m :: * -> *) a.
MonadPlus m =>
m a -> [[Operator m a]] -> m a
makeExprParser ParsecT Void Text Identity Expression
exprTerm [[Operator (ParsecT Void Text Identity) Expression]]
opsTable

exprTerm :: Parser Expression
exprTerm :: ParsecT Void Text Identity Expression
exprTerm =
  [ParsecT Void Text Identity Expression]
-> ParsecT Void Text Identity Expression
forall (f :: * -> *) a.
(Foldable f, Functor f) =>
f (Parser a) -> Parser a
choice'
    [ ParsecT Void Text Identity Expression
-> ParsecT Void Text Identity Expression
forall a. Parser a -> Parser a
parens ParsecT Void Text Identity Expression
exprP,
      Declaration -> Expression -> Expression
ExprLetIn (Declaration -> Expression -> Expression)
-> ParsecT Void Text Identity Declaration
-> ParsecT Void Text Identity (Expression -> Expression)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> ParsecT Void Text Identity Declaration
declP ParsecT Void Text Identity (Expression -> Expression)
-> ParsecT Void Text Identity Text
-> ParsecT Void Text Identity (Expression -> Expression)
forall a b.
ParsecT Void Text Identity a
-> ParsecT Void Text Identity b -> ParsecT Void Text Identity a
forall (f :: * -> *) a b. Applicative f => f a -> f b -> f a
<* ParsecT Void Text Identity Text
kwIn ParsecT Void Text Identity (Expression -> Expression)
-> ParsecT Void Text Identity Expression
-> ParsecT Void Text Identity Expression
forall a b.
ParsecT Void Text Identity (a -> b)
-> ParsecT Void Text Identity a -> ParsecT Void Text Identity b
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> ParsecT Void Text Identity Expression
exprP,
      PrimitiveValue -> Expression
ExprPrimVal (PrimitiveValue -> Expression)
-> ParsecT Void Text Identity PrimitiveValue
-> ParsecT Void Text Identity Expression
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> ParsecT Void Text Identity PrimitiveValue
primValExprP,
      Fun -> Expression
ExprFun (Fun -> Expression)
-> ParsecT Void Text Identity Text
-> ParsecT Void Text Identity (Fun -> Expression)
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
<$ ParsecT Void Text Identity Text
kwFun ParsecT Void Text Identity (Fun -> Expression)
-> ParsecT Void Text Identity Fun
-> ParsecT Void Text Identity Expression
forall a b.
ParsecT Void Text Identity (a -> b)
-> ParsecT Void Text Identity a -> ParsecT Void Text Identity b
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> ParsecT Void Text Identity Text -> ParsecT Void Text Identity Fun
funP ParsecT Void Text Identity Text
arrow,
      Expression -> Expression -> Expression -> Expression
ExprIte (Expression -> Expression -> Expression -> Expression)
-> ParsecT Void Text Identity Text
-> ParsecT
     Void
     Text
     Identity
     (Expression -> Expression -> Expression -> Expression)
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
<$ ParsecT Void Text Identity Text
kwIf ParsecT
  Void
  Text
  Identity
  (Expression -> Expression -> Expression -> Expression)
-> ParsecT Void Text Identity Expression
-> ParsecT
     Void Text Identity (Expression -> Expression -> Expression)
forall a b.
ParsecT Void Text Identity (a -> b)
-> ParsecT Void Text Identity a -> ParsecT Void Text Identity b
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> ParsecT Void Text Identity Expression
exprP ParsecT Void Text Identity (Expression -> Expression -> Expression)
-> ParsecT Void Text Identity Text
-> ParsecT
     Void Text Identity (Expression -> Expression -> Expression)
forall a b.
ParsecT Void Text Identity a
-> ParsecT Void Text Identity b -> ParsecT Void Text Identity a
forall (f :: * -> *) a b. Applicative f => f a -> f b -> f a
<* ParsecT Void Text Identity Text
kwThen ParsecT Void Text Identity (Expression -> Expression -> Expression)
-> ParsecT Void Text Identity Expression
-> ParsecT Void Text Identity (Expression -> Expression)
forall a b.
ParsecT Void Text Identity (a -> b)
-> ParsecT Void Text Identity a -> ParsecT Void Text Identity b
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> ParsecT Void Text Identity Expression
exprP ParsecT Void Text Identity (Expression -> Expression)
-> ParsecT Void Text Identity Text
-> ParsecT Void Text Identity (Expression -> Expression)
forall a b.
ParsecT Void Text Identity a
-> ParsecT Void Text Identity b -> ParsecT Void Text Identity a
forall (f :: * -> *) a b. Applicative f => f a -> f b -> f a
<* ParsecT Void Text Identity Text
kwElse ParsecT Void Text Identity (Expression -> Expression)
-> ParsecT Void Text Identity Expression
-> ParsecT Void Text Identity Expression
forall a b.
ParsecT Void Text Identity (a -> b)
-> ParsecT Void Text Identity a -> ParsecT Void Text Identity b
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> ParsecT Void Text Identity Expression
exprP,
      Text -> Expression
ExprId (Text -> Expression)
-> ParsecT Void Text Identity Text
-> ParsecT Void Text Identity Expression
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> ParsecT Void Text Identity Text
identifierP
    ]

-- ** Operation Parsers

opsTable :: [[Operator Parser Expression]]
opsTable :: [[Operator (ParsecT Void Text Identity) Expression]]
opsTable =
  [ [Operator (ParsecT Void Text Identity) Expression
appOp],
    [Text
-> UnaryOperator
-> Operator (ParsecT Void Text Identity) Expression
unOp Text
"-" UnaryOperator
UnMinusOp],
    [Text
-> ArithmeticOperator
-> Operator (ParsecT Void Text Identity) Expression
arithOp Text
"*" ArithmeticOperator
MulOp, Text
-> ArithmeticOperator
-> Operator (ParsecT Void Text Identity) Expression
arithOp Text
"/" ArithmeticOperator
DivOp],
    [Text
-> ArithmeticOperator
-> Operator (ParsecT Void Text Identity) Expression
arithOp Text
"+" ArithmeticOperator
PlusOp, Text
-> ArithmeticOperator
-> Operator (ParsecT Void Text Identity) Expression
arithOp Text
"-" ArithmeticOperator
MinusOp],
    [ Text
-> ComparisonOperator
-> Operator (ParsecT Void Text Identity) Expression
compOp Text
"=" ComparisonOperator
EqOp,
      Text
-> ComparisonOperator
-> Operator (ParsecT Void Text Identity) Expression
compOp Text
"<>" ComparisonOperator
NeOp,
      Text
-> ComparisonOperator
-> Operator (ParsecT Void Text Identity) Expression
compOp Text
"<=" ComparisonOperator
LeOp,
      Text
-> ComparisonOperator
-> Operator (ParsecT Void Text Identity) Expression
compOp Text
"<" ComparisonOperator
LtOp,
      Text
-> ComparisonOperator
-> Operator (ParsecT Void Text Identity) Expression
compOp Text
">=" ComparisonOperator
GeOp,
      Text
-> ComparisonOperator
-> Operator (ParsecT Void Text Identity) Expression
compOp Text
">" ComparisonOperator
GtOp
    ],
    [Text
-> BooleanOperator
-> Operator (ParsecT Void Text Identity) Expression
boolOp Text
"&&" BooleanOperator
AndOp],
    [Text
-> BooleanOperator
-> Operator (ParsecT Void Text Identity) Expression
boolOp Text
"||" BooleanOperator
OrOp]
  ]

appOp :: Operator Parser Expression
appOp :: Operator (ParsecT Void Text Identity) Expression
appOp = ParsecT Void Text Identity (Expression -> Expression -> Expression)
-> Operator (ParsecT Void Text Identity) Expression
forall (m :: * -> *) a. m (a -> a -> a) -> Operator m a
InfixL (ParsecT
   Void Text Identity (Expression -> Expression -> Expression)
 -> Operator (ParsecT Void Text Identity) Expression)
-> ParsecT
     Void Text Identity (Expression -> Expression -> Expression)
-> Operator (ParsecT Void Text Identity) Expression
forall a b. (a -> b) -> a -> b
$ (Expression -> Expression -> Expression)
-> ParsecT
     Void Text Identity (Expression -> Expression -> Expression)
forall a. a -> ParsecT Void Text Identity a
forall (m :: * -> *) a. Monad m => a -> m a
return Expression -> Expression -> Expression
ExprApp

binLeftOp :: Text -> BinaryOperator -> Operator Parser Expression
binLeftOp :: Text
-> BinaryOperator
-> Operator (ParsecT Void Text Identity) Expression
binLeftOp Text
name BinaryOperator
op = ParsecT Void Text Identity (Expression -> Expression -> Expression)
-> Operator (ParsecT Void Text Identity) Expression
forall (m :: * -> *) a. m (a -> a -> a) -> Operator m a
InfixL (ParsecT
   Void Text Identity (Expression -> Expression -> Expression)
 -> Operator (ParsecT Void Text Identity) Expression)
-> ParsecT
     Void Text Identity (Expression -> Expression -> Expression)
-> Operator (ParsecT Void Text Identity) Expression
forall a b. (a -> b) -> a -> b
$ BinaryOperator -> Expression -> Expression -> Expression
ExprBinOp BinaryOperator
op (Expression -> Expression -> Expression)
-> ParsecT Void Text Identity Text
-> ParsecT
     Void Text Identity (Expression -> Expression -> Expression)
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 -> ParsecT Void Text Identity Text
symbol Text
name

boolOp :: Text -> BooleanOperator -> Operator Parser Expression
boolOp :: Text
-> BooleanOperator
-> Operator (ParsecT Void Text Identity) Expression
boolOp Text
name BooleanOperator
op = Text
-> BinaryOperator
-> Operator (ParsecT Void Text Identity) Expression
binLeftOp Text
name (BinaryOperator
 -> Operator (ParsecT Void Text Identity) Expression)
-> BinaryOperator
-> Operator (ParsecT Void Text Identity) Expression
forall a b. (a -> b) -> a -> b
$ BooleanOperator -> BinaryOperator
BoolOp BooleanOperator
op

arithOp :: Text -> ArithmeticOperator -> Operator Parser Expression
arithOp :: Text
-> ArithmeticOperator
-> Operator (ParsecT Void Text Identity) Expression
arithOp Text
name ArithmeticOperator
op = Text
-> BinaryOperator
-> Operator (ParsecT Void Text Identity) Expression
binLeftOp Text
name (BinaryOperator
 -> Operator (ParsecT Void Text Identity) Expression)
-> BinaryOperator
-> Operator (ParsecT Void Text Identity) Expression
forall a b. (a -> b) -> a -> b
$ ArithmeticOperator -> BinaryOperator
ArithOp ArithmeticOperator
op

compOp :: Text -> ComparisonOperator -> Operator Parser Expression
compOp :: Text
-> ComparisonOperator
-> Operator (ParsecT Void Text Identity) Expression
compOp Text
name ComparisonOperator
op = Text
-> BinaryOperator
-> Operator (ParsecT Void Text Identity) Expression
binLeftOp Text
name (BinaryOperator
 -> Operator (ParsecT Void Text Identity) Expression)
-> BinaryOperator
-> Operator (ParsecT Void Text Identity) Expression
forall a b. (a -> b) -> a -> b
$ ComparisonOperator -> BinaryOperator
CompOp ComparisonOperator
op

unOp :: Text -> UnaryOperator -> Operator Parser Expression
unOp :: Text
-> UnaryOperator
-> Operator (ParsecT Void Text Identity) Expression
unOp Text
name UnaryOperator
op = ParsecT Void Text Identity (Expression -> Expression)
-> Operator (ParsecT Void Text Identity) Expression
forall (m :: * -> *) a. m (a -> a) -> Operator m a
Prefix (ParsecT Void Text Identity (Expression -> Expression)
 -> Operator (ParsecT Void Text Identity) Expression)
-> ParsecT Void Text Identity (Expression -> Expression)
-> Operator (ParsecT Void Text Identity) Expression
forall a b. (a -> b) -> a -> b
$ UnaryOperator -> Expression -> Expression
ExprUnOp UnaryOperator
op (Expression -> Expression)
-> ParsecT Void Text Identity Text
-> ParsecT Void Text Identity (Expression -> Expression)
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 -> ParsecT Void Text Identity Text
symbol Text
name

-- ** Type Parsers

typeP :: Parser Type
typeP :: Parser Type
typeP =
  [Parser Type] -> Parser Type
forall (f :: * -> *) a.
(Foldable f, Functor f) =>
f (Parser a) -> Parser a
choice'
    [ Type -> Type -> Type
TFun (Type -> Type -> Type)
-> Parser Type -> ParsecT Void Text Identity (Type -> Type)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Parser Type
primitiveOrInParensTypeP ParsecT Void Text Identity (Type -> Type)
-> ParsecT Void Text Identity Text
-> ParsecT Void Text Identity (Type -> Type)
forall a b.
ParsecT Void Text Identity a
-> ParsecT Void Text Identity b -> ParsecT Void Text Identity a
forall (f :: * -> *) a b. Applicative f => f a -> f b -> f a
<* ParsecT Void Text Identity Text
arrow ParsecT Void Text Identity (Type -> Type)
-> Parser Type -> Parser Type
forall a b.
ParsecT Void Text Identity (a -> b)
-> ParsecT Void Text Identity a -> ParsecT Void Text Identity b
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> Parser Type
typeP,
      Parser Type
primitiveOrInParensTypeP
    ]
  where
    primitiveOrInParensTypeP :: Parser Type
primitiveOrInParensTypeP = [Parser Type] -> Parser Type
forall (f :: * -> *) a.
(Foldable f, Functor f) =>
f (Parser a) -> Parser a
choice' [Parser Type -> Parser Type
forall a. Parser a -> Parser a
parens Parser Type
typeP, Parser Type
primitiveTypeP]
    primitiveTypeP :: Parser Type
primitiveTypeP =
      [Parser Type] -> Parser Type
forall (f :: * -> *) a.
(Foldable f, Functor f) =>
f (Parser a) -> Parser a
choice'
        [ Type
TUnit Type -> ParsecT Void Text Identity Text -> Parser Type
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
<$ ParsecT Void Text Identity Text
kwUnit,
          Type
TBool Type -> ParsecT Void Text Identity Text -> Parser Type
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
<$ ParsecT Void Text Identity Text
kwBool,
          Type
TInt Type -> ParsecT Void Text Identity Text -> Parser Type
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
<$ ParsecT Void Text Identity Text
kwInt
        ]

-- ** Primitive Value Parser

primValExprP :: Parser PrimitiveValue
primValExprP :: ParsecT Void Text Identity PrimitiveValue
primValExprP =
  [ParsecT Void Text Identity PrimitiveValue]
-> ParsecT Void Text Identity PrimitiveValue
forall (f :: * -> *) a.
(Foldable f, Functor f) =>
f (Parser a) -> Parser a
choice'
    [ PrimitiveValue
PrimValUnit PrimitiveValue
-> ParsecT Void Text Identity Text
-> ParsecT Void Text Identity PrimitiveValue
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
<$ ParsecT Void Text Identity Text
unitLitP,
      IsRec -> PrimitiveValue
PrimValBool (IsRec -> PrimitiveValue)
-> ParsecT Void Text Identity IsRec
-> ParsecT Void Text Identity PrimitiveValue
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> ParsecT Void Text Identity IsRec
boolLitP,
      Int64 -> PrimitiveValue
PrimValInt (Int64 -> PrimitiveValue)
-> ParsecT Void Text Identity Int64
-> ParsecT Void Text Identity PrimitiveValue
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> ParsecT Void Text Identity Int64
intLitP
    ]

-- ** Function Parser

funP :: Parser Text -> Parser Fun
funP :: ParsecT Void Text Identity Text -> ParsecT Void Text Identity Fun
funP ParsecT Void Text Identity Text
sepSymbolP = NonEmpty (Text, Maybe Type) -> Maybe Type -> Expression -> Fun
Fun (NonEmpty (Text, Maybe Type) -> Maybe Type -> Expression -> Fun)
-> ParsecT Void Text Identity (NonEmpty (Text, Maybe Type))
-> ParsecT Void Text Identity (Maybe Type -> Expression -> Fun)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> ParsecT Void Text Identity (Text, Maybe Type)
-> ParsecT Void Text Identity (NonEmpty (Text, Maybe Type))
forall (f :: * -> *) a. Alternative f => f a -> f (NonEmpty a)
some1 ParsecT Void Text Identity (Text, Maybe Type)
parameterP ParsecT Void Text Identity (Maybe Type -> Expression -> Fun)
-> ParsecT Void Text Identity (Maybe Type)
-> ParsecT Void Text Identity (Expression -> Fun)
forall a b.
ParsecT Void Text Identity (a -> b)
-> ParsecT Void Text Identity a -> ParsecT Void Text Identity b
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> ParsecT Void Text Identity (Maybe Type)
optionalTypeAnnotationP ParsecT Void Text Identity (Expression -> Fun)
-> ParsecT Void Text Identity Text
-> ParsecT Void Text Identity (Expression -> Fun)
forall a b.
ParsecT Void Text Identity a
-> ParsecT Void Text Identity b -> ParsecT Void Text Identity a
forall (f :: * -> *) a b. Applicative f => f a -> f b -> f a
<* ParsecT Void Text Identity Text
sepSymbolP ParsecT Void Text Identity (Expression -> Fun)
-> ParsecT Void Text Identity Expression
-> ParsecT Void Text Identity Fun
forall a b.
ParsecT Void Text Identity (a -> b)
-> ParsecT Void Text Identity a -> ParsecT Void Text Identity b
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> ParsecT Void Text Identity Expression
exprP

parameterP :: Parser (Identifier, Maybe Type)
parameterP :: ParsecT Void Text Identity (Text, Maybe Type)
parameterP =
  [ParsecT Void Text Identity (Text, Maybe Type)]
-> ParsecT Void Text Identity (Text, Maybe Type)
forall (f :: * -> *) a.
(Foldable f, Functor f) =>
f (Parser a) -> Parser a
choice'
    [ ParsecT Void Text Identity (Text, Maybe Type)
-> ParsecT Void Text Identity (Text, Maybe Type)
forall a. Parser a -> Parser a
someParens (ParsecT Void Text Identity (Text, Maybe Type)
 -> ParsecT Void Text Identity (Text, Maybe Type))
-> ParsecT Void Text Identity (Text, Maybe Type)
-> ParsecT Void Text Identity (Text, Maybe Type)
forall a b. (a -> b) -> a -> b
$ (,) (Text -> Maybe Type -> (Text, Maybe Type))
-> ParsecT Void Text Identity Text
-> ParsecT Void Text Identity (Maybe Type -> (Text, Maybe Type))
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> ParsecT Void Text Identity Text -> ParsecT Void Text Identity Text
forall a. Parser a -> Parser a
manyParens ParsecT Void Text Identity Text
identifierP ParsecT Void Text Identity (Maybe Type -> (Text, Maybe Type))
-> ParsecT Void Text Identity Text
-> ParsecT Void Text Identity (Maybe Type -> (Text, Maybe Type))
forall a b.
ParsecT Void Text Identity a
-> ParsecT Void Text Identity b -> ParsecT Void Text Identity a
forall (f :: * -> *) a b. Applicative f => f a -> f b -> f a
<* ParsecT Void Text Identity Text
colon ParsecT Void Text Identity (Maybe Type -> (Text, Maybe Type))
-> ParsecT Void Text Identity (Maybe Type)
-> ParsecT Void Text Identity (Text, Maybe Type)
forall a b.
ParsecT Void Text Identity (a -> b)
-> ParsecT Void Text Identity a -> ParsecT Void Text Identity b
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> (Type -> Maybe Type
forall a. a -> Maybe a
Just (Type -> Maybe Type)
-> Parser Type -> ParsecT Void Text Identity (Maybe Type)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Parser Type
typeP),
      (,Maybe Type
forall a. Maybe a
Nothing) (Text -> (Text, Maybe Type))
-> ParsecT Void Text Identity Text
-> ParsecT Void Text Identity (Text, Maybe Type)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> ParsecT Void Text Identity Text -> ParsecT Void Text Identity Text
forall a. Parser a -> Parser a
manyParens ParsecT Void Text Identity Text
identifierP
    ]

optionalTypeAnnotationP :: Parser (Maybe Type)
optionalTypeAnnotationP :: ParsecT Void Text Identity (Maybe Type)
optionalTypeAnnotationP = Parser Type -> ParsecT Void Text Identity (Maybe Type)
forall a. Parser a -> Parser (Maybe a)
optional' (ParsecT Void Text Identity Text
colon ParsecT Void Text Identity Text -> Parser Type -> Parser Type
forall a b.
ParsecT Void Text Identity a
-> ParsecT Void Text Identity b -> ParsecT Void Text Identity b
forall (f :: * -> *) a b. Applicative f => f a -> f b -> f b
*> Parser Type
typeP)