module SyntaxTrees.Haskell.FnDef where

import SyntaxTrees.Haskell.Common  (Literal, QCtor, QCtorOp, QVar, QVarOp, Var,
                                    VarOp)
import SyntaxTrees.Haskell.Pattern (Pattern)
import SyntaxTrees.Haskell.Type    (Type)



data FnSig
  = FnSig
      { FnSig -> Var
name  :: Var
      , FnSig -> Type
type' :: Type
      }
  deriving (Int -> FnSig -> ShowS
[FnSig] -> ShowS
FnSig -> String
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [FnSig] -> ShowS
$cshowList :: [FnSig] -> ShowS
show :: FnSig -> String
$cshow :: FnSig -> String
showsPrec :: Int -> FnSig -> ShowS
$cshowsPrec :: Int -> FnSig -> ShowS
Show)

data FnDef
  = FnDef
      { FnDef -> [Var]
names :: [Var]
      , FnDef -> [Pattern]
args  :: [Pattern]
      , FnDef -> MaybeGuardedFnBody
body  :: MaybeGuardedFnBody
      }
  deriving (Int -> FnDef -> ShowS
[FnDef] -> ShowS
FnDef -> String
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [FnDef] -> ShowS
$cshowList :: [FnDef] -> ShowS
show :: FnDef -> String
$cshow :: FnDef -> String
showsPrec :: Int -> FnDef -> ShowS
$cshowsPrec :: Int -> FnDef -> ShowS
Show)

data InfixFnAnnotation
  = InfixFnAnnotation
      { InfixFnAnnotation -> Associativity
associativity :: Associativity
      , InfixFnAnnotation -> Integer
precedence    :: Integer
      , InfixFnAnnotation -> VarOp
name          :: VarOp
      }
  deriving (Int -> InfixFnAnnotation -> ShowS
[InfixFnAnnotation] -> ShowS
InfixFnAnnotation -> String
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [InfixFnAnnotation] -> ShowS
$cshowList :: [InfixFnAnnotation] -> ShowS
show :: InfixFnAnnotation -> String
$cshow :: InfixFnAnnotation -> String
showsPrec :: Int -> InfixFnAnnotation -> ShowS
$cshowsPrec :: Int -> InfixFnAnnotation -> ShowS
Show)

data FnDefOrSig
  = Def FnDef
  | Sig FnSig
  deriving (Int -> FnDefOrSig -> ShowS
[FnDefOrSig] -> ShowS
FnDefOrSig -> String
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [FnDefOrSig] -> ShowS
$cshowList :: [FnDefOrSig] -> ShowS
show :: FnDefOrSig -> String
$cshow :: FnDefOrSig -> String
showsPrec :: Int -> FnDefOrSig -> ShowS
$cshowsPrec :: Int -> FnDefOrSig -> ShowS
Show)

data FnBody
  = FnApply
      { FnBody -> FnBody
fn   :: FnBody
      , FnBody -> [FnBody]
args :: [FnBody]
      }
  | InfixFnApply
      { FnBody -> [FnOp]
fnOps :: [FnOp]
      , args  :: [FnBody]
      }
  | LeftOpSection
      { FnBody -> FnOp
fnOp :: FnOp
      , FnBody -> FnBody
arg  :: FnBody
      }
  | RightOpSection
      { arg  :: FnBody
      , fnOp :: FnOp
      }
  | LambdaExpr
      { FnBody -> [Pattern]
patterns :: [Pattern]
      , FnBody -> FnBody
body     :: FnBody
      }
  | LetExpr
      { FnBody -> [FnDefOrSig]
fnBindings :: [FnDefOrSig]
      , body       :: FnBody
      }
  | WhereExpr
      { body       :: FnBody
      , fnBindings :: [FnDefOrSig]
      }
  | IfExpr
      { FnBody -> FnBody
cond       :: FnBody
      , FnBody -> FnBody
ifBranch   :: FnBody
      , FnBody -> FnBody
elseBranch :: FnBody
      }
  | MultiWayIfExpr
      { FnBody -> [GuardedFnBody]
whenExprs :: [GuardedFnBody]
      }
  | DoExpr
      { FnBody -> [DoStep]
steps :: [DoStep]
      }
  | CaseOfExpr
      { FnBody -> FnBody
matchee :: FnBody
      , FnBody -> [CaseBinding]
cases   :: [CaseBinding]
      }
  | LambdaCaseExpr
      { cases :: [CaseBinding]
      }
  | RecordCreate
      { FnBody -> FnBody
ctor        :: FnBody
      , FnBody -> [(Var, FnBody)]
namedFields :: [(Var, FnBody)]
      }
  | RecordUpdate
      { FnBody -> FnBody
var         :: FnBody
      , namedFields :: [(Var, FnBody)]
      }
  | TypeAnnotation FnBody Type
  | ListRange FnBody (Maybe FnBody)
  | Tuple [FnBody]
  | List [FnBody]
  | FnVar' FnVar
  | FnOp' FnOp
  | Literal' Literal
  deriving (Int -> FnBody -> ShowS
[FnBody] -> ShowS
FnBody -> String
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [FnBody] -> ShowS
$cshowList :: [FnBody] -> ShowS
show :: FnBody -> String
$cshow :: FnBody -> String
showsPrec :: Int -> FnBody -> ShowS
$cshowsPrec :: Int -> FnBody -> ShowS
Show)

data FnVar
  = Selector Var
  | Selection QVar [Var]
  | Var' QVar
  | Ctor' QCtor
  deriving (Int -> FnVar -> ShowS
[FnVar] -> ShowS
FnVar -> String
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [FnVar] -> ShowS
$cshowList :: [FnVar] -> ShowS
show :: FnVar -> String
$cshow :: FnVar -> String
showsPrec :: Int -> FnVar -> ShowS
$cshowsPrec :: Int -> FnVar -> ShowS
Show)

data FnOp
  = VarOp' QVarOp
  | CtorOp' QCtorOp
  deriving (Int -> FnOp -> ShowS
[FnOp] -> ShowS
FnOp -> String
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [FnOp] -> ShowS
$cshowList :: [FnOp] -> ShowS
show :: FnOp -> String
$cshow :: FnOp -> String
showsPrec :: Int -> FnOp -> ShowS
$cshowsPrec :: Int -> FnOp -> ShowS
Show)

data DoStep
  = DoBinding [Var] FnBody
  | LetBinding [FnDefOrSig]
  | Body FnBody
  deriving (Int -> DoStep -> ShowS
[DoStep] -> ShowS
DoStep -> String
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [DoStep] -> ShowS
$cshowList :: [DoStep] -> ShowS
show :: DoStep -> String
$cshow :: DoStep -> String
showsPrec :: Int -> DoStep -> ShowS
$cshowsPrec :: Int -> DoStep -> ShowS
Show)

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

data MaybeGuardedFnBody
  = Guarded [GuardedFnBody]
  | Standard FnBody
  deriving (Int -> MaybeGuardedFnBody -> ShowS
[MaybeGuardedFnBody] -> ShowS
MaybeGuardedFnBody -> String
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [MaybeGuardedFnBody] -> ShowS
$cshowList :: [MaybeGuardedFnBody] -> ShowS
show :: MaybeGuardedFnBody -> String
$cshow :: MaybeGuardedFnBody -> String
showsPrec :: Int -> MaybeGuardedFnBody -> ShowS
$cshowsPrec :: Int -> MaybeGuardedFnBody -> ShowS
Show)

data GuardedFnBody
  = GuardedFnBody
      { GuardedFnBody -> Guard
guard :: Guard
      , GuardedFnBody -> FnBody
body  :: FnBody
      }
  deriving (Int -> GuardedFnBody -> ShowS
[GuardedFnBody] -> ShowS
GuardedFnBody -> String
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [GuardedFnBody] -> ShowS
$cshowList :: [GuardedFnBody] -> ShowS
show :: GuardedFnBody -> String
$cshow :: GuardedFnBody -> String
showsPrec :: Int -> GuardedFnBody -> ShowS
$cshowsPrec :: Int -> GuardedFnBody -> ShowS
Show)

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

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

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