{-# LANGUAGE DeriveTraversable #-}

{- |
Module      : Language.Egison.AST
Licence     : MIT

This module defines the syntax of Egison.
-}

module Language.Egison.AST
  ( TopExpr (..)
  , ConstantExpr (..)
  , Expr (..)
  , Pattern (..)
  , VarWithIndices (..)
  , makeApply
  , Arg (..)
  , ArgPattern (..)
  , IndexExpr (..)
  , VarIndex (..)
  , PMMode (..)
  , BindingExpr (..)
  , MatchClause
  , PatternDef
  , LoopRange (..)
  , PrimitivePatPattern (..)
  , PDPatternBase (..)
  , PrimitiveDataPattern
  , Op (..)
  , Assoc (..)
  , reservedExprOp
  , reservedPatternOp
  , findOpFrom
  , stringToVarWithIndices
  , extractNameFromVarWithIndices
  ) where

import           Data.List  (find)
import           Data.Maybe (fromJust)
import           Data.Text  (Text)

data TopExpr
  = Define VarWithIndices Expr
  | Test Expr
  | Execute Expr
    -- temporary : we will replace load to import and export
  | LoadFile String
  | Load String
  | InfixDecl Bool Op -- True for pattern infix; False for expression infix
 deriving Int -> TopExpr -> ShowS
[TopExpr] -> ShowS
TopExpr -> String
(Int -> TopExpr -> ShowS)
-> (TopExpr -> String) -> ([TopExpr] -> ShowS) -> Show TopExpr
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [TopExpr] -> ShowS
$cshowList :: [TopExpr] -> ShowS
show :: TopExpr -> String
$cshow :: TopExpr -> String
showsPrec :: Int -> TopExpr -> ShowS
$cshowsPrec :: Int -> TopExpr -> ShowS
Show

data ConstantExpr
  = CharExpr Char
  | StringExpr Text
  | BoolExpr Bool
  | IntegerExpr Integer
  | FloatExpr Double
  | SomethingExpr
  | UndefinedExpr
  deriving Int -> ConstantExpr -> ShowS
[ConstantExpr] -> ShowS
ConstantExpr -> String
(Int -> ConstantExpr -> ShowS)
-> (ConstantExpr -> String)
-> ([ConstantExpr] -> ShowS)
-> Show ConstantExpr
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [ConstantExpr] -> ShowS
$cshowList :: [ConstantExpr] -> ShowS
show :: ConstantExpr -> String
$cshow :: ConstantExpr -> String
showsPrec :: Int -> ConstantExpr -> ShowS
$cshowsPrec :: Int -> ConstantExpr -> ShowS
Show

data Expr
  = ConstantExpr ConstantExpr
  | VarExpr String
  | FreshVarExpr
  | IndexedExpr Bool Expr [IndexExpr Expr]  -- True -> delete old index and append new one
  | SubrefsExpr Bool Expr Expr
  | SuprefsExpr Bool Expr Expr
  | UserrefsExpr Bool Expr Expr
  | TupleExpr [Expr]
  | CollectionExpr [Expr]
  | ConsExpr Expr Expr
  | JoinExpr Expr Expr
  | HashExpr [(Expr, Expr)]
  | VectorExpr [Expr]

  | LambdaExpr [Arg ArgPattern] Expr
  | LambdaExpr' [Arg VarWithIndices] Expr
  | MemoizedLambdaExpr [String] Expr
  | CambdaExpr String Expr
  | PatternFunctionExpr [String] Pattern

  | IfExpr Expr Expr Expr
  | LetExpr [BindingExpr] Expr
  | LetRecExpr [BindingExpr] Expr
  | WithSymbolsExpr [String] Expr

  | MatchExpr PMMode Expr Expr [MatchClause]
  | MatchAllExpr PMMode Expr Expr [MatchClause]
  | MatchLambdaExpr Expr [MatchClause]
  | MatchAllLambdaExpr Expr [MatchClause]

  | MatcherExpr [PatternDef]
  | AlgebraicDataMatcherExpr [(String, [Expr])]

  | QuoteExpr Expr
  | QuoteSymbolExpr Expr
  | WedgeApplyExpr Expr [Expr]

  | DoExpr [BindingExpr] Expr

  | PrefixExpr String Expr
  | InfixExpr Op Expr Expr
  | SectionExpr Op (Maybe Expr) (Maybe Expr) -- There cannot be 'SectionExpr op (Just _) (Just _)'

  | SeqExpr Expr Expr
  | ApplyExpr Expr [Expr]
  | CApplyExpr Expr Expr
  | AnonParamFuncExpr Integer Expr
  | AnonTupleParamFuncExpr Integer Expr
  | AnonListParamFuncExpr Integer Expr
  | AnonParamExpr Integer

  | GenerateTensorExpr Expr Expr
  | TensorExpr Expr Expr
  | TensorContractExpr Expr
  | TensorMapExpr Expr Expr
  | TensorMap2Expr Expr Expr Expr
  | TransposeExpr Expr Expr
  | FlipIndicesExpr Expr                              -- Does not appear in user program

  | FunctionExpr [String]
  deriving Int -> Expr -> ShowS
[Expr] -> ShowS
Expr -> String
(Int -> Expr -> ShowS)
-> (Expr -> String) -> ([Expr] -> ShowS) -> Show Expr
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [Expr] -> ShowS
$cshowList :: [Expr] -> ShowS
show :: Expr -> String
$cshow :: Expr -> String
showsPrec :: Int -> Expr -> ShowS
$cshowsPrec :: Int -> Expr -> ShowS
Show

data VarWithIndices = VarWithIndices String [VarIndex]
  deriving (Int -> VarWithIndices -> ShowS
[VarWithIndices] -> ShowS
VarWithIndices -> String
(Int -> VarWithIndices -> ShowS)
-> (VarWithIndices -> String)
-> ([VarWithIndices] -> ShowS)
-> Show VarWithIndices
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [VarWithIndices] -> ShowS
$cshowList :: [VarWithIndices] -> ShowS
show :: VarWithIndices -> String
$cshow :: VarWithIndices -> String
showsPrec :: Int -> VarWithIndices -> ShowS
$cshowsPrec :: Int -> VarWithIndices -> ShowS
Show, VarWithIndices -> VarWithIndices -> Bool
(VarWithIndices -> VarWithIndices -> Bool)
-> (VarWithIndices -> VarWithIndices -> Bool) -> Eq VarWithIndices
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: VarWithIndices -> VarWithIndices -> Bool
$c/= :: VarWithIndices -> VarWithIndices -> Bool
== :: VarWithIndices -> VarWithIndices -> Bool
$c== :: VarWithIndices -> VarWithIndices -> Bool
Eq)

data Arg a
  = ScalarArg a
  | InvertedScalarArg a
  | TensorArg a
  deriving Int -> Arg a -> ShowS
[Arg a] -> ShowS
Arg a -> String
(Int -> Arg a -> ShowS)
-> (Arg a -> String) -> ([Arg a] -> ShowS) -> Show (Arg a)
forall a. Show a => Int -> Arg a -> ShowS
forall a. Show a => [Arg a] -> ShowS
forall a. Show a => Arg a -> String
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [Arg a] -> ShowS
$cshowList :: forall a. Show a => [Arg a] -> ShowS
show :: Arg a -> String
$cshow :: forall a. Show a => Arg a -> String
showsPrec :: Int -> Arg a -> ShowS
$cshowsPrec :: forall a. Show a => Int -> Arg a -> ShowS
Show

data ArgPattern
  = APWildCard
  | APPatVar VarWithIndices
  | APInductivePat String [Arg ArgPattern]
  | APTuplePat [Arg ArgPattern]
  | APEmptyPat
  | APConsPat (Arg ArgPattern) ArgPattern
  | APSnocPat ArgPattern (Arg ArgPattern)
  deriving Int -> ArgPattern -> ShowS
[ArgPattern] -> ShowS
ArgPattern -> String
(Int -> ArgPattern -> ShowS)
-> (ArgPattern -> String)
-> ([ArgPattern] -> ShowS)
-> Show ArgPattern
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [ArgPattern] -> ShowS
$cshowList :: [ArgPattern] -> ShowS
show :: ArgPattern -> String
$cshow :: ArgPattern -> String
showsPrec :: Int -> ArgPattern -> ShowS
$cshowsPrec :: Int -> ArgPattern -> ShowS
Show

data VarIndex
  = VSubscript String
  | VSuperscript String
  | VMultiSubscript String Integer String   -- _(a_1)..._(a_n) -> VMultiSubscript "a" 1 "n"
  | VMultiSuperscript String Integer String -- ~(a_1)...~(a_n) -> VMultiSuperscript "a" 1 "n"
  | VGroupScripts [VarIndex]
  | VSymmScripts [VarIndex]
  | VAntiSymmScripts [VarIndex]
  deriving (Int -> VarIndex -> ShowS
[VarIndex] -> ShowS
VarIndex -> String
(Int -> VarIndex -> ShowS)
-> (VarIndex -> String) -> ([VarIndex] -> ShowS) -> Show VarIndex
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [VarIndex] -> ShowS
$cshowList :: [VarIndex] -> ShowS
show :: VarIndex -> String
$cshow :: VarIndex -> String
showsPrec :: Int -> VarIndex -> ShowS
$cshowsPrec :: Int -> VarIndex -> ShowS
Show, VarIndex -> VarIndex -> Bool
(VarIndex -> VarIndex -> Bool)
-> (VarIndex -> VarIndex -> Bool) -> Eq VarIndex
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: VarIndex -> VarIndex -> Bool
$c/= :: VarIndex -> VarIndex -> Bool
== :: VarIndex -> VarIndex -> Bool
$c== :: VarIndex -> VarIndex -> Bool
Eq)

data IndexExpr a
  = Subscript a
  | Superscript a
  | SupSubscript a
  | MultiSubscript a a
  | MultiSuperscript a a
  | Userscript a
  deriving (Int -> IndexExpr a -> ShowS
[IndexExpr a] -> ShowS
IndexExpr a -> String
(Int -> IndexExpr a -> ShowS)
-> (IndexExpr a -> String)
-> ([IndexExpr a] -> ShowS)
-> Show (IndexExpr a)
forall a. Show a => Int -> IndexExpr a -> ShowS
forall a. Show a => [IndexExpr a] -> ShowS
forall a. Show a => IndexExpr a -> String
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [IndexExpr a] -> ShowS
$cshowList :: forall a. Show a => [IndexExpr a] -> ShowS
show :: IndexExpr a -> String
$cshow :: forall a. Show a => IndexExpr a -> String
showsPrec :: Int -> IndexExpr a -> ShowS
$cshowsPrec :: forall a. Show a => Int -> IndexExpr a -> ShowS
Show, IndexExpr a -> IndexExpr a -> Bool
(IndexExpr a -> IndexExpr a -> Bool)
-> (IndexExpr a -> IndexExpr a -> Bool) -> Eq (IndexExpr a)
forall a. Eq a => IndexExpr a -> IndexExpr a -> Bool
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: IndexExpr a -> IndexExpr a -> Bool
$c/= :: forall a. Eq a => IndexExpr a -> IndexExpr a -> Bool
== :: IndexExpr a -> IndexExpr a -> Bool
$c== :: forall a. Eq a => IndexExpr a -> IndexExpr a -> Bool
Eq, a -> IndexExpr b -> IndexExpr a
(a -> b) -> IndexExpr a -> IndexExpr b
(forall a b. (a -> b) -> IndexExpr a -> IndexExpr b)
-> (forall a b. a -> IndexExpr b -> IndexExpr a)
-> Functor IndexExpr
forall a b. a -> IndexExpr b -> IndexExpr a
forall a b. (a -> b) -> IndexExpr a -> IndexExpr b
forall (f :: * -> *).
(forall a b. (a -> b) -> f a -> f b)
-> (forall a b. a -> f b -> f a) -> Functor f
<$ :: a -> IndexExpr b -> IndexExpr a
$c<$ :: forall a b. a -> IndexExpr b -> IndexExpr a
fmap :: (a -> b) -> IndexExpr a -> IndexExpr b
$cfmap :: forall a b. (a -> b) -> IndexExpr a -> IndexExpr b
Functor, IndexExpr a -> Bool
(a -> m) -> IndexExpr a -> m
(a -> b -> b) -> b -> IndexExpr a -> b
(forall m. Monoid m => IndexExpr m -> m)
-> (forall m a. Monoid m => (a -> m) -> IndexExpr a -> m)
-> (forall m a. Monoid m => (a -> m) -> IndexExpr a -> m)
-> (forall a b. (a -> b -> b) -> b -> IndexExpr a -> b)
-> (forall a b. (a -> b -> b) -> b -> IndexExpr a -> b)
-> (forall b a. (b -> a -> b) -> b -> IndexExpr a -> b)
-> (forall b a. (b -> a -> b) -> b -> IndexExpr a -> b)
-> (forall a. (a -> a -> a) -> IndexExpr a -> a)
-> (forall a. (a -> a -> a) -> IndexExpr a -> a)
-> (forall a. IndexExpr a -> [a])
-> (forall a. IndexExpr a -> Bool)
-> (forall a. IndexExpr a -> Int)
-> (forall a. Eq a => a -> IndexExpr a -> Bool)
-> (forall a. Ord a => IndexExpr a -> a)
-> (forall a. Ord a => IndexExpr a -> a)
-> (forall a. Num a => IndexExpr a -> a)
-> (forall a. Num a => IndexExpr a -> a)
-> Foldable IndexExpr
forall a. Eq a => a -> IndexExpr a -> Bool
forall a. Num a => IndexExpr a -> a
forall a. Ord a => IndexExpr a -> a
forall m. Monoid m => IndexExpr m -> m
forall a. IndexExpr a -> Bool
forall a. IndexExpr a -> Int
forall a. IndexExpr a -> [a]
forall a. (a -> a -> a) -> IndexExpr a -> a
forall m a. Monoid m => (a -> m) -> IndexExpr a -> m
forall b a. (b -> a -> b) -> b -> IndexExpr a -> b
forall a b. (a -> b -> b) -> b -> IndexExpr a -> b
forall (t :: * -> *).
(forall m. Monoid m => t m -> m)
-> (forall m a. Monoid m => (a -> m) -> t a -> m)
-> (forall m a. Monoid m => (a -> m) -> t a -> m)
-> (forall a b. (a -> b -> b) -> b -> t a -> b)
-> (forall a b. (a -> b -> b) -> b -> t a -> b)
-> (forall b a. (b -> a -> b) -> b -> t a -> b)
-> (forall b a. (b -> a -> b) -> b -> t a -> b)
-> (forall a. (a -> a -> a) -> t a -> a)
-> (forall a. (a -> a -> a) -> t a -> a)
-> (forall a. t a -> [a])
-> (forall a. t a -> Bool)
-> (forall a. t a -> Int)
-> (forall a. Eq a => a -> t a -> Bool)
-> (forall a. Ord a => t a -> a)
-> (forall a. Ord a => t a -> a)
-> (forall a. Num a => t a -> a)
-> (forall a. Num a => t a -> a)
-> Foldable t
product :: IndexExpr a -> a
$cproduct :: forall a. Num a => IndexExpr a -> a
sum :: IndexExpr a -> a
$csum :: forall a. Num a => IndexExpr a -> a
minimum :: IndexExpr a -> a
$cminimum :: forall a. Ord a => IndexExpr a -> a
maximum :: IndexExpr a -> a
$cmaximum :: forall a. Ord a => IndexExpr a -> a
elem :: a -> IndexExpr a -> Bool
$celem :: forall a. Eq a => a -> IndexExpr a -> Bool
length :: IndexExpr a -> Int
$clength :: forall a. IndexExpr a -> Int
null :: IndexExpr a -> Bool
$cnull :: forall a. IndexExpr a -> Bool
toList :: IndexExpr a -> [a]
$ctoList :: forall a. IndexExpr a -> [a]
foldl1 :: (a -> a -> a) -> IndexExpr a -> a
$cfoldl1 :: forall a. (a -> a -> a) -> IndexExpr a -> a
foldr1 :: (a -> a -> a) -> IndexExpr a -> a
$cfoldr1 :: forall a. (a -> a -> a) -> IndexExpr a -> a
foldl' :: (b -> a -> b) -> b -> IndexExpr a -> b
$cfoldl' :: forall b a. (b -> a -> b) -> b -> IndexExpr a -> b
foldl :: (b -> a -> b) -> b -> IndexExpr a -> b
$cfoldl :: forall b a. (b -> a -> b) -> b -> IndexExpr a -> b
foldr' :: (a -> b -> b) -> b -> IndexExpr a -> b
$cfoldr' :: forall a b. (a -> b -> b) -> b -> IndexExpr a -> b
foldr :: (a -> b -> b) -> b -> IndexExpr a -> b
$cfoldr :: forall a b. (a -> b -> b) -> b -> IndexExpr a -> b
foldMap' :: (a -> m) -> IndexExpr a -> m
$cfoldMap' :: forall m a. Monoid m => (a -> m) -> IndexExpr a -> m
foldMap :: (a -> m) -> IndexExpr a -> m
$cfoldMap :: forall m a. Monoid m => (a -> m) -> IndexExpr a -> m
fold :: IndexExpr m -> m
$cfold :: forall m. Monoid m => IndexExpr m -> m
Foldable, Functor IndexExpr
Foldable IndexExpr
Functor IndexExpr
-> Foldable IndexExpr
-> (forall (f :: * -> *) a b.
    Applicative f =>
    (a -> f b) -> IndexExpr a -> f (IndexExpr b))
-> (forall (f :: * -> *) a.
    Applicative f =>
    IndexExpr (f a) -> f (IndexExpr a))
-> (forall (m :: * -> *) a b.
    Monad m =>
    (a -> m b) -> IndexExpr a -> m (IndexExpr b))
-> (forall (m :: * -> *) a.
    Monad m =>
    IndexExpr (m a) -> m (IndexExpr a))
-> Traversable IndexExpr
(a -> f b) -> IndexExpr a -> f (IndexExpr b)
forall (t :: * -> *).
Functor t
-> Foldable t
-> (forall (f :: * -> *) a b.
    Applicative f =>
    (a -> f b) -> t a -> f (t b))
-> (forall (f :: * -> *) a. Applicative f => t (f a) -> f (t a))
-> (forall (m :: * -> *) a b.
    Monad m =>
    (a -> m b) -> t a -> m (t b))
-> (forall (m :: * -> *) a. Monad m => t (m a) -> m (t a))
-> Traversable t
forall (m :: * -> *) a.
Monad m =>
IndexExpr (m a) -> m (IndexExpr a)
forall (f :: * -> *) a.
Applicative f =>
IndexExpr (f a) -> f (IndexExpr a)
forall (m :: * -> *) a b.
Monad m =>
(a -> m b) -> IndexExpr a -> m (IndexExpr b)
forall (f :: * -> *) a b.
Applicative f =>
(a -> f b) -> IndexExpr a -> f (IndexExpr b)
sequence :: IndexExpr (m a) -> m (IndexExpr a)
$csequence :: forall (m :: * -> *) a.
Monad m =>
IndexExpr (m a) -> m (IndexExpr a)
mapM :: (a -> m b) -> IndexExpr a -> m (IndexExpr b)
$cmapM :: forall (m :: * -> *) a b.
Monad m =>
(a -> m b) -> IndexExpr a -> m (IndexExpr b)
sequenceA :: IndexExpr (f a) -> f (IndexExpr a)
$csequenceA :: forall (f :: * -> *) a.
Applicative f =>
IndexExpr (f a) -> f (IndexExpr a)
traverse :: (a -> f b) -> IndexExpr a -> f (IndexExpr b)
$ctraverse :: forall (f :: * -> *) a b.
Applicative f =>
(a -> f b) -> IndexExpr a -> f (IndexExpr b)
$cp2Traversable :: Foldable IndexExpr
$cp1Traversable :: Functor IndexExpr
Traversable)

data PMMode = BFSMode | DFSMode
  deriving Int -> PMMode -> ShowS
[PMMode] -> ShowS
PMMode -> String
(Int -> PMMode -> ShowS)
-> (PMMode -> String) -> ([PMMode] -> ShowS) -> Show PMMode
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [PMMode] -> ShowS
$cshowList :: [PMMode] -> ShowS
show :: PMMode -> String
$cshow :: PMMode -> String
showsPrec :: Int -> PMMode -> ShowS
$cshowsPrec :: Int -> PMMode -> ShowS
Show

data BindingExpr
  = Bind PrimitiveDataPattern Expr
  | BindWithIndices VarWithIndices Expr
  deriving Int -> BindingExpr -> ShowS
[BindingExpr] -> ShowS
BindingExpr -> String
(Int -> BindingExpr -> ShowS)
-> (BindingExpr -> String)
-> ([BindingExpr] -> ShowS)
-> Show BindingExpr
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [BindingExpr] -> ShowS
$cshowList :: [BindingExpr] -> ShowS
show :: BindingExpr -> String
$cshow :: BindingExpr -> String
showsPrec :: Int -> BindingExpr -> ShowS
$cshowsPrec :: Int -> BindingExpr -> ShowS
Show

type MatchClause = (Pattern, Expr)
type PatternDef  = (PrimitivePatPattern, Expr, [(PrimitiveDataPattern, Expr)])

data Pattern
  = WildCard
  | PatVar String
  | ValuePat Expr
  | PredPat Expr
  | IndexedPat Pattern [Expr]
  | LetPat [BindingExpr] Pattern
  | InfixPat Op Pattern Pattern -- Includes AndPat,OrPat,InductivePat(cons/join)
  | NotPat Pattern
  | AndPat Pattern Pattern
  | OrPat Pattern Pattern
  | ForallPat Pattern Pattern
  | TuplePat [Pattern]
  | InductivePat String [Pattern]
  | LoopPat String LoopRange Pattern Pattern
  | ContPat
  | PApplyPat Expr [Pattern]
  | VarPat String
  | InductiveOrPApplyPat String [Pattern]
  | SeqNilPat
  | SeqConsPat Pattern Pattern
  | LaterPatVar
  -- For symbolic computing
  | DApplyPat Pattern [Pattern]
  deriving Int -> Pattern -> ShowS
[Pattern] -> ShowS
Pattern -> String
(Int -> Pattern -> ShowS)
-> (Pattern -> String) -> ([Pattern] -> ShowS) -> Show Pattern
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [Pattern] -> ShowS
$cshowList :: [Pattern] -> ShowS
show :: Pattern -> String
$cshow :: Pattern -> String
showsPrec :: Int -> Pattern -> ShowS
$cshowsPrec :: Int -> Pattern -> ShowS
Show

data LoopRange = LoopRange Expr Expr Pattern
  deriving Int -> LoopRange -> ShowS
[LoopRange] -> ShowS
LoopRange -> String
(Int -> LoopRange -> ShowS)
-> (LoopRange -> String)
-> ([LoopRange] -> ShowS)
-> Show LoopRange
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [LoopRange] -> ShowS
$cshowList :: [LoopRange] -> ShowS
show :: LoopRange -> String
$cshow :: LoopRange -> String
showsPrec :: Int -> LoopRange -> ShowS
$cshowsPrec :: Int -> LoopRange -> ShowS
Show

data PrimitivePatPattern
  = PPWildCard
  | PPPatVar
  | PPValuePat String
  | PPInductivePat String [PrimitivePatPattern]
  | PPTuplePat [PrimitivePatPattern]
  deriving Int -> PrimitivePatPattern -> ShowS
[PrimitivePatPattern] -> ShowS
PrimitivePatPattern -> String
(Int -> PrimitivePatPattern -> ShowS)
-> (PrimitivePatPattern -> String)
-> ([PrimitivePatPattern] -> ShowS)
-> Show PrimitivePatPattern
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [PrimitivePatPattern] -> ShowS
$cshowList :: [PrimitivePatPattern] -> ShowS
show :: PrimitivePatPattern -> String
$cshow :: PrimitivePatPattern -> String
showsPrec :: Int -> PrimitivePatPattern -> ShowS
$cshowsPrec :: Int -> PrimitivePatPattern -> ShowS
Show

data PDPatternBase var
  = PDWildCard
  | PDPatVar var
  | PDInductivePat String [PDPatternBase var]
  | PDTuplePat [PDPatternBase var]
  | PDEmptyPat
  | PDConsPat (PDPatternBase var) (PDPatternBase var)
  | PDSnocPat (PDPatternBase var) (PDPatternBase var)
  | PDConstantPat ConstantExpr
  deriving (a -> PDPatternBase b -> PDPatternBase a
(a -> b) -> PDPatternBase a -> PDPatternBase b
(forall a b. (a -> b) -> PDPatternBase a -> PDPatternBase b)
-> (forall a b. a -> PDPatternBase b -> PDPatternBase a)
-> Functor PDPatternBase
forall a b. a -> PDPatternBase b -> PDPatternBase a
forall a b. (a -> b) -> PDPatternBase a -> PDPatternBase b
forall (f :: * -> *).
(forall a b. (a -> b) -> f a -> f b)
-> (forall a b. a -> f b -> f a) -> Functor f
<$ :: a -> PDPatternBase b -> PDPatternBase a
$c<$ :: forall a b. a -> PDPatternBase b -> PDPatternBase a
fmap :: (a -> b) -> PDPatternBase a -> PDPatternBase b
$cfmap :: forall a b. (a -> b) -> PDPatternBase a -> PDPatternBase b
Functor, PDPatternBase a -> Bool
(a -> m) -> PDPatternBase a -> m
(a -> b -> b) -> b -> PDPatternBase a -> b
(forall m. Monoid m => PDPatternBase m -> m)
-> (forall m a. Monoid m => (a -> m) -> PDPatternBase a -> m)
-> (forall m a. Monoid m => (a -> m) -> PDPatternBase a -> m)
-> (forall a b. (a -> b -> b) -> b -> PDPatternBase a -> b)
-> (forall a b. (a -> b -> b) -> b -> PDPatternBase a -> b)
-> (forall b a. (b -> a -> b) -> b -> PDPatternBase a -> b)
-> (forall b a. (b -> a -> b) -> b -> PDPatternBase a -> b)
-> (forall a. (a -> a -> a) -> PDPatternBase a -> a)
-> (forall a. (a -> a -> a) -> PDPatternBase a -> a)
-> (forall a. PDPatternBase a -> [a])
-> (forall a. PDPatternBase a -> Bool)
-> (forall a. PDPatternBase a -> Int)
-> (forall a. Eq a => a -> PDPatternBase a -> Bool)
-> (forall a. Ord a => PDPatternBase a -> a)
-> (forall a. Ord a => PDPatternBase a -> a)
-> (forall a. Num a => PDPatternBase a -> a)
-> (forall a. Num a => PDPatternBase a -> a)
-> Foldable PDPatternBase
forall a. Eq a => a -> PDPatternBase a -> Bool
forall a. Num a => PDPatternBase a -> a
forall a. Ord a => PDPatternBase a -> a
forall m. Monoid m => PDPatternBase m -> m
forall a. PDPatternBase a -> Bool
forall a. PDPatternBase a -> Int
forall a. PDPatternBase a -> [a]
forall a. (a -> a -> a) -> PDPatternBase a -> a
forall m a. Monoid m => (a -> m) -> PDPatternBase a -> m
forall b a. (b -> a -> b) -> b -> PDPatternBase a -> b
forall a b. (a -> b -> b) -> b -> PDPatternBase a -> b
forall (t :: * -> *).
(forall m. Monoid m => t m -> m)
-> (forall m a. Monoid m => (a -> m) -> t a -> m)
-> (forall m a. Monoid m => (a -> m) -> t a -> m)
-> (forall a b. (a -> b -> b) -> b -> t a -> b)
-> (forall a b. (a -> b -> b) -> b -> t a -> b)
-> (forall b a. (b -> a -> b) -> b -> t a -> b)
-> (forall b a. (b -> a -> b) -> b -> t a -> b)
-> (forall a. (a -> a -> a) -> t a -> a)
-> (forall a. (a -> a -> a) -> t a -> a)
-> (forall a. t a -> [a])
-> (forall a. t a -> Bool)
-> (forall a. t a -> Int)
-> (forall a. Eq a => a -> t a -> Bool)
-> (forall a. Ord a => t a -> a)
-> (forall a. Ord a => t a -> a)
-> (forall a. Num a => t a -> a)
-> (forall a. Num a => t a -> a)
-> Foldable t
product :: PDPatternBase a -> a
$cproduct :: forall a. Num a => PDPatternBase a -> a
sum :: PDPatternBase a -> a
$csum :: forall a. Num a => PDPatternBase a -> a
minimum :: PDPatternBase a -> a
$cminimum :: forall a. Ord a => PDPatternBase a -> a
maximum :: PDPatternBase a -> a
$cmaximum :: forall a. Ord a => PDPatternBase a -> a
elem :: a -> PDPatternBase a -> Bool
$celem :: forall a. Eq a => a -> PDPatternBase a -> Bool
length :: PDPatternBase a -> Int
$clength :: forall a. PDPatternBase a -> Int
null :: PDPatternBase a -> Bool
$cnull :: forall a. PDPatternBase a -> Bool
toList :: PDPatternBase a -> [a]
$ctoList :: forall a. PDPatternBase a -> [a]
foldl1 :: (a -> a -> a) -> PDPatternBase a -> a
$cfoldl1 :: forall a. (a -> a -> a) -> PDPatternBase a -> a
foldr1 :: (a -> a -> a) -> PDPatternBase a -> a
$cfoldr1 :: forall a. (a -> a -> a) -> PDPatternBase a -> a
foldl' :: (b -> a -> b) -> b -> PDPatternBase a -> b
$cfoldl' :: forall b a. (b -> a -> b) -> b -> PDPatternBase a -> b
foldl :: (b -> a -> b) -> b -> PDPatternBase a -> b
$cfoldl :: forall b a. (b -> a -> b) -> b -> PDPatternBase a -> b
foldr' :: (a -> b -> b) -> b -> PDPatternBase a -> b
$cfoldr' :: forall a b. (a -> b -> b) -> b -> PDPatternBase a -> b
foldr :: (a -> b -> b) -> b -> PDPatternBase a -> b
$cfoldr :: forall a b. (a -> b -> b) -> b -> PDPatternBase a -> b
foldMap' :: (a -> m) -> PDPatternBase a -> m
$cfoldMap' :: forall m a. Monoid m => (a -> m) -> PDPatternBase a -> m
foldMap :: (a -> m) -> PDPatternBase a -> m
$cfoldMap :: forall m a. Monoid m => (a -> m) -> PDPatternBase a -> m
fold :: PDPatternBase m -> m
$cfold :: forall m. Monoid m => PDPatternBase m -> m
Foldable, Int -> PDPatternBase var -> ShowS
[PDPatternBase var] -> ShowS
PDPatternBase var -> String
(Int -> PDPatternBase var -> ShowS)
-> (PDPatternBase var -> String)
-> ([PDPatternBase var] -> ShowS)
-> Show (PDPatternBase var)
forall var. Show var => Int -> PDPatternBase var -> ShowS
forall var. Show var => [PDPatternBase var] -> ShowS
forall var. Show var => PDPatternBase var -> String
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [PDPatternBase var] -> ShowS
$cshowList :: forall var. Show var => [PDPatternBase var] -> ShowS
show :: PDPatternBase var -> String
$cshow :: forall var. Show var => PDPatternBase var -> String
showsPrec :: Int -> PDPatternBase var -> ShowS
$cshowsPrec :: forall var. Show var => Int -> PDPatternBase var -> ShowS
Show)

type PrimitiveDataPattern = PDPatternBase String

data Op
  = Op { Op -> String
repr     :: String  -- syntastic representation
       , Op -> Int
priority :: Int
       , Op -> Assoc
assoc    :: Assoc
       , Op -> Bool
isWedge  :: Bool    -- True if operator is prefixed with '!'. Only used for expression infix.
       }
  deriving (Op -> Op -> Bool
(Op -> Op -> Bool) -> (Op -> Op -> Bool) -> Eq Op
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: Op -> Op -> Bool
$c/= :: Op -> Op -> Bool
== :: Op -> Op -> Bool
$c== :: Op -> Op -> Bool
Eq, Eq Op
Eq Op
-> (Op -> Op -> Ordering)
-> (Op -> Op -> Bool)
-> (Op -> Op -> Bool)
-> (Op -> Op -> Bool)
-> (Op -> Op -> Bool)
-> (Op -> Op -> Op)
-> (Op -> Op -> Op)
-> Ord Op
Op -> Op -> Bool
Op -> Op -> Ordering
Op -> Op -> Op
forall a.
Eq a
-> (a -> a -> Ordering)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> a)
-> (a -> a -> a)
-> Ord a
min :: Op -> Op -> Op
$cmin :: Op -> Op -> Op
max :: Op -> Op -> Op
$cmax :: Op -> Op -> Op
>= :: Op -> Op -> Bool
$c>= :: Op -> Op -> Bool
> :: Op -> Op -> Bool
$c> :: Op -> Op -> Bool
<= :: Op -> Op -> Bool
$c<= :: Op -> Op -> Bool
< :: Op -> Op -> Bool
$c< :: Op -> Op -> Bool
compare :: Op -> Op -> Ordering
$ccompare :: Op -> Op -> Ordering
$cp1Ord :: Eq Op
Ord, Int -> Op -> ShowS
[Op] -> ShowS
Op -> String
(Int -> Op -> ShowS)
-> (Op -> String) -> ([Op] -> ShowS) -> Show Op
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [Op] -> ShowS
$cshowList :: [Op] -> ShowS
show :: Op -> String
$cshow :: Op -> String
showsPrec :: Int -> Op -> ShowS
$cshowsPrec :: Int -> Op -> ShowS
Show)

data Assoc
  = InfixL
  | InfixR
  | InfixN
  | Prefix
  deriving (Assoc -> Assoc -> Bool
(Assoc -> Assoc -> Bool) -> (Assoc -> Assoc -> Bool) -> Eq Assoc
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: Assoc -> Assoc -> Bool
$c/= :: Assoc -> Assoc -> Bool
== :: Assoc -> Assoc -> Bool
$c== :: Assoc -> Assoc -> Bool
Eq, Eq Assoc
Eq Assoc
-> (Assoc -> Assoc -> Ordering)
-> (Assoc -> Assoc -> Bool)
-> (Assoc -> Assoc -> Bool)
-> (Assoc -> Assoc -> Bool)
-> (Assoc -> Assoc -> Bool)
-> (Assoc -> Assoc -> Assoc)
-> (Assoc -> Assoc -> Assoc)
-> Ord Assoc
Assoc -> Assoc -> Bool
Assoc -> Assoc -> Ordering
Assoc -> Assoc -> Assoc
forall a.
Eq a
-> (a -> a -> Ordering)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> a)
-> (a -> a -> a)
-> Ord a
min :: Assoc -> Assoc -> Assoc
$cmin :: Assoc -> Assoc -> Assoc
max :: Assoc -> Assoc -> Assoc
$cmax :: Assoc -> Assoc -> Assoc
>= :: Assoc -> Assoc -> Bool
$c>= :: Assoc -> Assoc -> Bool
> :: Assoc -> Assoc -> Bool
$c> :: Assoc -> Assoc -> Bool
<= :: Assoc -> Assoc -> Bool
$c<= :: Assoc -> Assoc -> Bool
< :: Assoc -> Assoc -> Bool
$c< :: Assoc -> Assoc -> Bool
compare :: Assoc -> Assoc -> Ordering
$ccompare :: Assoc -> Assoc -> Ordering
$cp1Ord :: Eq Assoc
Ord)

instance Show Assoc where
  show :: Assoc -> String
show Assoc
InfixL = String
"infixl"
  show Assoc
InfixR = String
"infixr"
  show Assoc
InfixN = String
"infix"
  show Assoc
Prefix = String
"prefix"

reservedExprOp :: [Op]
reservedExprOp :: [Op]
reservedExprOp =
  [ String -> Int -> Assoc -> Bool -> Op
Op String
"!"  Int
8 Assoc
Prefix Bool
False -- Wedge
  , String -> Int -> Assoc -> Bool -> Op
Op String
"-"  Int
7 Assoc
Prefix Bool
False -- Negate
  , String -> Int -> Assoc -> Bool -> Op
Op String
"%"  Int
7 Assoc
InfixL Bool
False -- primitive function
  , String -> Int -> Assoc -> Bool -> Op
Op String
"*$" Int
7 Assoc
Prefix Bool
False -- For InvertedScalarArg
  , String -> Int -> Assoc -> Bool -> Op
Op String
"*$" Int
7 Assoc
InfixL Bool
False -- For InvertedScalarArg
  , String -> Int -> Assoc -> Bool -> Op
Op String
"++" Int
5 Assoc
InfixR Bool
False
  , String -> Int -> Assoc -> Bool -> Op
Op String
"::" Int
5 Assoc
InfixR Bool
False
  , String -> Int -> Assoc -> Bool -> Op
Op String
"="  Int
4 Assoc
InfixL Bool
False -- primitive function
  , String -> Int -> Assoc -> Bool -> Op
Op String
"<=" Int
4 Assoc
InfixL Bool
False -- primitive function
  , String -> Int -> Assoc -> Bool -> Op
Op String
">=" Int
4 Assoc
InfixL Bool
False -- primitive function
  , String -> Int -> Assoc -> Bool -> Op
Op String
"<"  Int
4 Assoc
InfixL Bool
False -- primitive function
  , String -> Int -> Assoc -> Bool -> Op
Op String
">"  Int
4 Assoc
InfixL Bool
False -- primitive function
  ]

reservedPatternOp :: [Op]
reservedPatternOp :: [Op]
reservedPatternOp =
  [ String -> Int -> Assoc -> Bool -> Op
Op String
"::" Int
5 Assoc
InfixR Bool
False  -- required for desugaring collection pattern
  , String -> Int -> Assoc -> Bool -> Op
Op String
"&"  Int
3 Assoc
InfixR Bool
False
  , String -> Int -> Assoc -> Bool -> Op
Op String
"|"  Int
2 Assoc
InfixR Bool
False
  ]

findOpFrom :: String -> [Op] -> Op
findOpFrom :: String -> [Op] -> Op
findOpFrom String
op [Op]
table = Maybe Op -> Op
forall a. HasCallStack => Maybe a -> a
fromJust (Maybe Op -> Op) -> Maybe Op -> Op
forall a b. (a -> b) -> a -> b
$ (Op -> Bool) -> [Op] -> Maybe Op
forall (t :: * -> *) a. Foldable t => (a -> Bool) -> t a -> Maybe a
find ((String -> String -> Bool
forall a. Eq a => a -> a -> Bool
== String
op) (String -> Bool) -> (Op -> String) -> Op -> Bool
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Op -> String
repr) [Op]
table

makeApply :: String -> [Expr] -> Expr
makeApply :: String -> [Expr] -> Expr
makeApply String
func [Expr]
args = Expr -> [Expr] -> Expr
ApplyExpr (String -> Expr
VarExpr String
func) [Expr]
args

stringToVarWithIndices :: String -> VarWithIndices
stringToVarWithIndices :: String -> VarWithIndices
stringToVarWithIndices String
name = String -> [VarIndex] -> VarWithIndices
VarWithIndices String
name []

extractNameFromVarWithIndices :: VarWithIndices -> String
extractNameFromVarWithIndices :: VarWithIndices -> String
extractNameFromVarWithIndices (VarWithIndices String
name [VarIndex]
_) = String
name