haskell-tools-ast-0.1.2.0: Language/Haskell/Tools/AST/Exprs.hs
-- | Representation of Haskell expressions
module Language.Haskell.Tools.AST.Exprs where
import Language.Haskell.Tools.AST.Ann
import Language.Haskell.Tools.AST.Base
import Language.Haskell.Tools.AST.Literals
import Language.Haskell.Tools.AST.Types
import Language.Haskell.Tools.AST.Patterns
import Language.Haskell.Tools.AST.Stmts
import {-# SOURCE #-} Language.Haskell.Tools.AST.TH
import {-# SOURCE #-} Language.Haskell.Tools.AST.Binds (LocalBind, LocalBinds, RhsGuard)
-- | Haskell expressions
data Expr a
= Var { _exprName :: Ann Name a
} -- ^ A variable or a data constructor (@ a @)
| Lit { _exprLit :: Ann Literal a
} -- ^ Primitive literal
| InfixApp { _exprLhs :: Ann Expr a
, _exprOperator :: Ann Operator a
, _exprRhs :: Ann Expr a
} -- ^ Infix operator application (@ a + b @)
| PrefixApp { _exprOperator :: Ann Operator a
, _exprRhs :: Ann Expr a
} -- ^ Prefix operator application (@ -x @)
| App { _exprFun :: Ann Expr a
, _exprArg :: Ann Expr a
} -- ^ Function application (@ f 4 @)
-- unary minus omitted
| Lambda { _exprBindings :: AnnList Pattern a -- ^ at least one
, _exprInner :: Ann Expr a
} -- ^ Lambda expression (@ \a b -> a + b @)
| Let { _exprFunBind :: AnnList LocalBind a -- ^ nonempty
, _exprInner :: Ann Expr a
} -- ^ Local binding (@ let x = 2; y = 3 in e x y @)
| If { _exprCond :: Ann Expr a
, _exprThen :: Ann Expr a
, _exprElse :: Ann Expr a
} -- ^ If expression (@ if a then b else c @)
| MultiIf { _exprIfAlts :: AnnList GuardedCaseRhs a
} -- ^ Multi way if expressions with @MultiWayIf@ extension (@ if | guard1 -> expr1; guard2 -> expr2 @)
| Case { _exprCase :: Ann Expr a
, _exprAlts :: AnnList Alt a
} -- ^ Pattern matching expression (@ case expr of pat1 -> expr1; pat2 -> expr2 @)
| Do { _doKind :: Ann DoKind a
, _exprStmts :: AnnList Stmt a
} -- ^ Do-notation expressions (@ do x <- act1; act2 @)
| Tuple { _tupleElems :: AnnList Expr a
} -- ^ Tuple expression (@ (e1, e2, e3) @)
| UnboxedTuple { _tupleElems :: AnnList Expr a
} -- ^ Unboxed tuple expression (@ (# e1, e2, e3 #) @)
| TupleSection { _tupleSectionElems :: AnnList TupSecElem a
} -- ^ Tuple section, enabled with @TupleSections@ (@ (a,,b) @). One of the elements must be missing.
| UnboxedTupSec { _tupleSectionElems :: AnnList TupSecElem a
}
| List { _listElems :: AnnList Expr a
} -- ^ List expression: @[1,2,3]@
| ParArray { _listElems :: AnnList Expr a
} -- ^ Parallel array expression: @[: 1,2,3 :]@
| Paren { _exprInner :: Ann Expr a
}
| LeftSection { _exprLhs :: Ann Expr a
, _exprOperator :: Ann Operator a
} -- ^ Left operator section: @(1+)@
| RightSection { _exprOperator :: Ann Operator a
, _exprRhs :: Ann Expr a
} -- ^ Right operator section: @(+1)@
| RecCon { _exprRecName :: Ann Name a
, _exprRecFields :: AnnList FieldUpdate a
} -- ^ Record value construction: @Point { x = 3, y = -2 }@
| RecUpdate { _exprInner :: Ann Expr a
, _exprRecFields :: AnnList FieldUpdate a
} -- ^ Record value update: @p1 { x = 3, y = -2 }@
| Enum { _enumFrom :: Ann Expr a
, _enumThen :: AnnMaybe Expr a
, _enumTo :: AnnMaybe Expr a
} -- ^ Enumeration expression (@ [1,3..10] @)
| ParArrayEnum { _enumFrom :: Ann Expr a
, _enumThen :: AnnMaybe Expr a
, _enumToFix :: Ann Expr a
} -- ^ Parallel array enumeration (@ [: 1,3 .. 10 :] @)
| ListComp { _compExpr :: Ann Expr a
, _compBody :: AnnList ListCompBody a -- ^ Can only have 1 element without @ParallelListComp@
} -- ^ List comprehension (@ [ (x, y) | x <- xs | y <- ys ] @)
| ParArrayComp { _compExpr :: Ann Expr a
, _compBody :: AnnList ListCompBody a
} -- ^ Parallel array comprehensions @ [: (x, y) | x <- xs , y <- ys :] @ enabled by @ParallelArrays@
| TypeSig { _exprInner :: Ann Expr a
, _exprSig :: Ann Type a
} -- ^ Explicit type signature (@ _x :: Int @)
| ExplTypeApp { _exprInner :: Ann Expr a
, _exprType :: Ann Type a
} -- ^ Explicit type application (@ show \@Integer (read "5") @)
| VarQuote { _quotedName :: Ann Name a
} -- ^ @'x@ for template haskell reifying of expressions
| TypeQuote { _quotedName :: Ann Name a
} -- ^ @''T@ for template haskell reifying of types
| BracketExpr { _bracket :: Ann Bracket a
} -- ^ Template haskell bracket expression
| Splice { _innerExpr :: Ann Splice a
} -- ^ Template haskell splice expression, for example: @$(gen a)@ or @$x@
| QuasiQuoteExpr { _exprQQ :: Ann QuasiQuote a
} -- ^ Template haskell quasi-quotation: @[$quoter|str]@
| ExprPragma { _exprPragma :: Ann ExprPragma a
}
-- Arrows
| Proc { _procPattern :: Ann Pattern a
, _procExpr :: Ann Cmd a
} -- ^ Arrow definition: @proc a -> f -< a+1@
| ArrowApp { _exprLhs :: Ann Expr a
, _arrowAppl :: Ann ArrowAppl a
, _exprRhs :: Ann Expr a
} -- ^ Arrow application: @f -< a+1@
| LamCase { _exprAlts :: AnnList Alt a
} -- ^ Lambda case ( @\case 0 -> 1; 1 -> 2@ )
| StaticPtr { _exprInner :: Ann Expr a
} -- ^ Static pointer expression (@ static e @). The inner expression must be closed (cannot have variables bound outside)
-- XML expressions omitted
-- | Field update expressions
data FieldUpdate a
= NormalFieldUpdate { _fieldName :: Ann Name a
, _fieldValue :: Ann Expr a
} -- ^ Update of a field (@ x = 1 @)
| FieldPun { _fieldUpdateName :: Ann Name a
} -- ^ Update the field to the value of the same name (@ x @)
| FieldWildcard -- ^ Update the fields of the bounded names to their values (@ .. @). Must be the last update. Cannot be used in a record update expression.
-- | An element of a tuple section that can be an expression or missing (indicating a value from a parameter)
data TupSecElem a
= Present { _tupSecExpr :: Ann Expr a
} -- ^ An existing element in a tuple section
| Missing -- ^ A missing element in a tuple section
-- | Clause of case expression
data Alt' expr a
= Alt { _altPattern :: Ann Pattern a
, _altRhs :: Ann (CaseRhs' expr) a
, _altBinds :: AnnMaybe LocalBinds a
}
type Alt = Alt' Expr
type CmdAlt = Alt' Cmd
-- | Right hand side of a match (possible with guards): (@ = 3 @ or @ | x == 1 = 3; | otherwise = 4 @)
data CaseRhs' expr a
= UnguardedCaseRhs { _rhsCaseExpr :: Ann expr a
}
| GuardedCaseRhss { _rhsCaseGuards :: AnnList (GuardedCaseRhs' expr) a
}
type CaseRhs = CaseRhs' Expr
type CmdCaseRhs = CaseRhs' Cmd
-- | A guarded right-hand side of pattern matches binding (@ | x > 3 -> 2 @)
data GuardedCaseRhs' expr a
= GuardedCaseRhs { _caseGuardStmts :: AnnList RhsGuard a -- ^ Cannot be empty.
, _caseGuardExpr :: Ann expr a
}
type GuardedCaseRhs = GuardedCaseRhs' Expr
type CmdGuardedCaseRhs = GuardedCaseRhs' Cmd
-- | Pragmas that can be applied to expressions
data ExprPragma a
= CorePragma { _pragmaStr :: Ann StringNode a
}
| SccPragma { _pragmaStr :: Ann StringNode a
}
| GeneratedPragma { _pragmaSrcRange :: Ann SourceRange a
}
-- | In-AST source ranges (for generated pragmas)
data SourceRange a
= SourceRange { _srFileName :: Ann StringNode a
, _srFromLine :: Ann Number a
, _srFromCol :: Ann Number a
, _srToLine :: Ann Number a
, _srToCol :: Ann Number a
}
data Number a
= Number { _numberInteger :: Integer
}
data Cmd a
= ArrowAppCmd { _cmdLhs :: Ann Expr a
, _cmdArrowOp :: Ann ArrowAppl a
, _cmdRhs :: Ann Expr a
}
| ArrowFormCmd { _cmdExpr :: Ann Expr a
, _cmdInnerCmds :: AnnList Cmd a
}
| AppCmd { _cmdInnerCmd :: Ann Cmd a
, _cmdApplied :: Ann Expr a
}
| InfixCmd { _cmdLeftCmd :: Ann Cmd a
, _cmdOperator :: Ann Name a
, _cmdRightCmd :: Ann Cmd a
}
| LambdaCmd { _cmdBindings :: AnnList Pattern a -- ^ at least one
, _cmdInner :: Ann Cmd a
}
| ParenCmd { _cmdInner :: Ann Cmd a
}
| CaseCmd { _cmdExpr :: Ann Expr a
, _cmdAlts :: AnnList CmdAlt a
}
| IfCmd { _cmdExpr :: Ann Expr a
, _cmdThen :: Ann Cmd a
, _cmdElse :: Ann Cmd a
}
| LetCmd { _cmdBinds :: AnnList LocalBind a -- ^ nonempty
, _cmdInner :: Ann Cmd a
}
| DoCmd { _cmdStmts :: AnnList (Stmt' Cmd) a
}