{-# OPTIONS_GHC -fglasgow-exts -cpp #-}
-----------------------------------------------------------------------------
-- |
-- Module : Language.Haskell.Exts.Syntax
-- Original : Language.Haskell.Syntax
-- Copyright : (c) Niklas Broberg 2004,
-- (c) The GHC Team, 1997-2000
-- License : BSD-style (see the file LICENSE.txt)
--
-- Maintainer : Niklas Broberg, d00nibro@dtek.chalmers.se
-- Stability : experimental
-- Portability : portable
--
-- A suite of datatypes describing the abstract syntax of Haskell 98
-- plus some extensions:
--
-- * multi-parameter type classes with functional dependencies
--
-- * parameters of type class assertions are unrestricted
--
-- * 'forall' types as universal and existential quantification
--
-- * pattern guards
--
-- * implicit parameters
--
-- * generalised algebraic data types
--
-- * template haskell
--
-- * empty data type declarations
--
-- * unboxed tuples
--
-- * regular patterns (HaRP)
--
-- * HSP-style XML expressions and patterns (HSP)
--
-- Also worth noting is that (n+k) patterns from Haskell 98 are not supported
-----------------------------------------------------------------------------
module Language.Haskell.Exts.Syntax (
-- * Modules
HsModule(..), HsExportSpec(..),
HsImportDecl(..), HsImportSpec(..), HsAssoc(..),
-- * Declarations
HsDecl(..), HsBinds(..), HsIPBind(..),
HsClassDecl(..), HsInstDecl(..),
HsGadtDecl(..), HsConDecl(..), HsQualConDecl(..), HsBangType(..),
HsMatch(..), HsRhs(..), HsGuardedRhs(..), DataOrNew(..),
-- * Class Assertions and Contexts
HsContext, HsFunDep(..), HsAsst(..),
-- * Types
HsType(..), HsBoxed(..), HsKind(..), HsTyVarBind(..),
-- * Expressions
HsExp(..), HsStmt(..), HsFieldUpdate(..),
HsAlt(..), HsGuardedAlts(..), HsGuardedAlt(..),
-- * Patterns
HsPat(..), HsPatField(..),
-- * Literals
HsLiteral(..),
-- * Variables, Constructors and Operators
Module(..), HsQName(..), HsName(..), HsQOp(..), HsOp(..),
HsSpecialCon(..), HsCName(..), HsIPName(..),
-- * Template Haskell
-- HsReify(..),
HsBracket(..), HsSplice(..),
-- * HaRP
HsRPat(..), HsRPatOp(..),
-- * Hsx
HsXAttr(..), HsXName(..), HsPXAttr(..),
-- * FFI
HsSafety(..), HsCallConv(..),
-- * Builtin names
-- ** Modules
prelude_mod, main_mod,
-- ** Main function of a program
main_name,
-- ** Constructors
unit_con_name, tuple_con_name, list_cons_name,
unit_con, tuple_con,
-- ** Special identifiers
as_name, qualified_name, hiding_name, minus_name, pling_name, dot_name, star_name,
export_name, safe_name, unsafe_name, threadsafe_name, stdcall_name, ccall_name,
-- ** Type constructors
unit_tycon_name, fun_tycon_name, list_tycon_name, tuple_tycon_name,
unit_tycon, fun_tycon, list_tycon, tuple_tycon,
-- * Source coordinates
SrcLoc(..),
) where
#ifdef __GLASGOW_HASKELL__
import Data.Generics.Basics
import Data.Generics.Instances
#endif
-- | A position in the source.
data SrcLoc = SrcLoc {
srcFilename :: String,
srcLine :: Int,
srcColumn :: Int
}
#ifdef __GLASGOW_HASKELL__
deriving (Eq,Ord,Show,Typeable,Data)
#else
deriving (Eq,Ord,Show)
#endif
-- | The name of a Haskell module.
newtype Module = Module String
#ifdef __GLASGOW_HASKELL__
deriving (Eq,Ord,Show,Typeable,Data)
#else
deriving (Eq,Ord,Show)
#endif
-- | Constructors with special syntax.
-- These names are never qualified, and always refer to builtin type or
-- data constructors.
data HsSpecialCon
= HsUnitCon -- ^ unit type and data constructor @()@
| HsListCon -- ^ list type constructor @[]@
| HsFunCon -- ^ function type constructor @->@
| HsTupleCon Int -- ^ /n/-ary tuple type and data
-- constructors @(,)@ etc
| HsCons -- ^ list data constructor @(:)@
#ifdef __GLASGOW_HASKELL__
deriving (Eq,Ord,Show,Typeable,Data)
#else
deriving (Eq,Ord,Show)
#endif
-- | This type is used to represent qualified variables, and also
-- qualified constructors.
data HsQName
= Qual Module HsName -- ^ name qualified with a module name
| UnQual HsName -- ^ unqualified name
| Special HsSpecialCon -- ^ built-in constructor with special syntax
#ifdef __GLASGOW_HASKELL__
deriving (Eq,Ord,Show,Typeable,Data)
#else
deriving (Eq,Ord,Show)
#endif
-- | This type is used to represent variables, and also constructors.
data HsName
= HsIdent String -- ^ /varid/ or /conid/.
| HsSymbol String -- ^ /varsym/ or /consym/
#ifdef __GLASGOW_HASKELL__
deriving (Eq,Ord,Show,Typeable,Data)
#else
deriving (Eq,Ord,Show)
#endif
-- | This type is used to represent implicit parameter names.
data HsIPName
= HsIPDup String -- ?x
| HsIPLin String -- %x
#ifdef __GLASGOW_HASKELL__
deriving (Eq,Ord,Show,Typeable,Data)
#else
deriving (Eq,Ord,Show)
#endif
-- | Possibly qualified infix operators (/qop/), appearing in expressions.
data HsQOp
= HsQVarOp HsQName -- ^ variable operator (/qvarop/)
| HsQConOp HsQName -- ^ constructor operator (/qconop/)
#ifdef __GLASGOW_HASKELL__
deriving (Eq,Ord,Show,Typeable,Data)
#else
deriving (Eq,Ord,Show)
#endif
-- | Operators, appearing in @infix@ declarations.
data HsOp
= HsVarOp HsName -- ^ variable operator (/varop/)
| HsConOp HsName -- ^ constructor operator (/conop/)
#ifdef __GLASGOW_HASKELL__
deriving (Eq,Ord,Show,Typeable,Data)
#else
deriving (Eq,Ord,Show)
#endif
-- | A name (/cname/) of a component of a class or data type in an @import@
-- or export specification.
data HsCName
= HsVarName HsName -- ^ name of a method or field
| HsConName HsName -- ^ name of a data constructor
#ifdef __GLASGOW_HASKELL__
deriving (Eq,Ord,Show,Typeable,Data)
#else
deriving (Eq,Ord,Show)
#endif
-- | A Haskell source module.
data HsModule = HsModule SrcLoc Module (Maybe [HsExportSpec])
[HsImportDecl] [HsDecl]
#ifdef __GLASGOW_HASKELL__
deriving (Show,Typeable,Data)
#else
deriving (Show)
#endif
-- | Export specification.
data HsExportSpec
= HsEVar HsQName -- ^ variable
| HsEAbs HsQName -- ^ @T@:
-- a class or datatype exported abstractly,
-- or a type synonym.
| HsEThingAll HsQName -- ^ @T(..)@:
-- a class exported with all of its methods, or
-- a datatype exported with all of its constructors.
| HsEThingWith HsQName [HsCName] -- ^ @T(C_1,...,C_n)@:
-- a class exported with some of its methods, or
-- a datatype exported with some of its constructors.
| HsEModuleContents Module -- ^ @module M@:
-- re-export a module.
#ifdef __GLASGOW_HASKELL__
deriving (Eq,Show,Typeable,Data)
#else
deriving (Eq,Show)
#endif
-- | Import declaration.
data HsImportDecl = HsImportDecl
{ importLoc :: SrcLoc -- ^ position of the @import@ keyword.
, importModule :: Module -- ^ name of the module imported.
, importQualified :: Bool -- ^ imported @qualified@?
, importAs :: Maybe Module -- ^ optional alias name in an
-- @as@ clause.
, importSpecs :: Maybe (Bool,[HsImportSpec])
-- ^ optional list of import specifications.
-- The 'Bool' is 'True' if the names are excluded
-- by @hiding@.
}
#ifdef __GLASGOW_HASKELL__
deriving (Eq,Show,Typeable,Data)
#else
deriving (Eq,Show)
#endif
-- | Import specification.
data HsImportSpec
= HsIVar HsName -- ^ variable
| HsIAbs HsName -- ^ @T@:
-- the name of a class, datatype or type synonym.
| HsIThingAll HsName -- ^ @T(..)@:
-- a class imported with all of its methods, or
-- a datatype imported with all of its constructors.
| HsIThingWith HsName [HsCName] -- ^ @T(C_1,...,C_n)@:
-- a class imported with some of its methods, or
-- a datatype imported with some of its constructors.
#ifdef __GLASGOW_HASKELL__
deriving (Eq,Show,Typeable,Data)
#else
deriving (Eq,Show)
#endif
-- | Associativity of an operator.
data HsAssoc
= HsAssocNone -- ^ non-associative operator (declared with @infix@)
| HsAssocLeft -- ^ left-associative operator (declared with @infixl@).
| HsAssocRight -- ^ right-associative operator (declared with @infixr@)
#ifdef __GLASGOW_HASKELL__
deriving (Eq,Show,Typeable,Data)
#else
deriving (Eq,Show)
#endif
data HsDecl
= HsTypeDecl SrcLoc HsName [HsName] HsType
| HsDataDecl SrcLoc DataOrNew HsContext HsName [HsName] [HsQualConDecl] [HsQName]
| HsGDataDecl SrcLoc DataOrNew HsContext HsName [HsName] (Maybe HsKind) [HsGadtDecl] {-no deriving-}
| HsTypeFamDecl SrcLoc HsName [HsName] (Maybe HsKind)
| HsDataFamDecl SrcLoc HsContext HsName [HsName] (Maybe HsKind)
| HsTypeInsDecl SrcLoc HsType HsType
| HsDataInsDecl SrcLoc DataOrNew HsType [HsQualConDecl] [HsQName]
| HsGDataInsDecl SrcLoc DataOrNew HsType (Maybe HsKind) [HsGadtDecl] {-no deriving-}
| HsInfixDecl SrcLoc HsAssoc Int [HsOp]
| HsClassDecl SrcLoc HsContext HsName [HsName] [HsFunDep] [HsClassDecl]
| HsInstDecl SrcLoc HsContext HsQName [HsType] [HsInstDecl]
| HsDerivDecl SrcLoc HsContext HsQName [HsType]
| HsDefaultDecl SrcLoc [HsType]
| HsSpliceDecl SrcLoc HsSplice
| HsTypeSig SrcLoc [HsName] HsType
| HsFunBind [HsMatch]
| HsPatBind SrcLoc HsPat HsRhs {-where-} HsBinds
| HsForImp SrcLoc HsCallConv HsSafety String HsName HsType
| HsForExp SrcLoc HsCallConv String HsName HsType
#ifdef __GLASGOW_HASKELL__
deriving (Eq,Show,Typeable,Data)
#else
deriving (Eq,Show)
#endif
data DataOrNew = DataType | NewType
#ifdef __GLASGOW_HASKELL__
deriving (Eq,Show,Typeable,Data)
#else
deriving (Eq,Show)
#endif
data HsBinds
= HsBDecls [HsDecl]
| HsIPBinds [HsIPBind]
#ifdef __GLASGOW_HASKELL__
deriving (Eq,Show,Typeable,Data)
#else
deriving (Eq,Show)
#endif
data HsIPBind = HsIPBind SrcLoc HsIPName HsExp
#ifdef __GLASGOW_HASKELL__
deriving (Eq,Show,Typeable,Data)
#else
deriving (Eq,Show)
#endif
-- | Clauses of a function binding.
data HsMatch
= HsMatch SrcLoc HsName [HsPat] HsRhs {-where-} HsBinds
#ifdef __GLASGOW_HASKELL__
deriving (Eq,Show,Typeable,Data)
#else
deriving (Eq,Show)
#endif
data HsQualConDecl
= HsQualConDecl SrcLoc
{-forall-} [HsTyVarBind] {- . -} HsContext
{- => -} HsConDecl
#ifdef __GLASGOW_HASKELL__
deriving (Eq,Show,Typeable,Data)
#else
deriving (Eq,Show)
#endif
data HsGadtDecl
= HsGadtDecl SrcLoc HsName HsType
#ifdef __GLASGOW_HASKELL__
deriving (Eq,Show,Typeable,Data)
#else
deriving (Eq,Show)
#endif
-- | Declaration of a data constructor.
data HsConDecl
= HsConDecl HsName [HsBangType]
-- ^ ordinary data constructor
| HsRecDecl HsName [([HsName],HsBangType)]
-- ^ record constructor
#ifdef __GLASGOW_HASKELL__
deriving (Eq,Show,Typeable,Data)
#else
deriving (Eq,Show)
#endif
-- | Declarations inside a class declaration
data HsClassDecl
= HsClsDecl HsDecl
| HsClsDataFam SrcLoc HsContext HsName [HsName] (Maybe HsKind)
| HsClsTyFam SrcLoc HsName [HsName] (Maybe HsKind)
| HsClsTyDef SrcLoc HsType HsType
#ifdef __GLASGOW_HASKELL__
deriving (Eq,Show,Typeable,Data)
#else
deriving (Eq,Show)
#endif
-- | Declarations inside an instance declaration
data HsInstDecl
= HsInsDecl HsDecl
| HsInsType SrcLoc HsType HsType
| HsInsData SrcLoc DataOrNew HsType [HsQualConDecl] [HsQName]
| HsInsGData SrcLoc DataOrNew HsType (Maybe HsKind) [HsGadtDecl] {-no deriving-}
#ifdef __GLASGOW_HASKELL__
deriving (Eq,Show,Typeable,Data)
#else
deriving (Eq,Show)
#endif
-- | The type of a constructor argument or field, optionally including
-- a strictness annotation.
data HsBangType
= HsBangedTy HsType -- ^ strict component, marked with \"@!@\"
| HsUnBangedTy HsType -- ^ non-strict component
#ifdef __GLASGOW_HASKELL__
deriving (Eq,Show,Typeable,Data)
#else
deriving (Eq,Show)
#endif
-- | The right hand side of a function or pattern binding.
data HsRhs
= HsUnGuardedRhs HsExp -- ^ unguarded right hand side (/exp/)
| HsGuardedRhss [HsGuardedRhs]
-- ^ guarded right hand side (/gdrhs/)
#ifdef __GLASGOW_HASKELL__
deriving (Eq,Show,Typeable,Data)
#else
deriving (Eq,Show)
#endif
-- | A guarded right hand side @|@ /exp/ @=@ /exp/.
-- The first expression will be Boolean-valued.
data HsGuardedRhs
= HsGuardedRhs SrcLoc [HsStmt] HsExp
#ifdef __GLASGOW_HASKELL__
deriving (Eq,Show,Typeable,Data)
#else
deriving (Eq,Show)
#endif
-- | A type qualified with a context.
-- An unqualified type has an empty context.
data HsType
= HsTyForall
(Maybe [HsTyVarBind])
HsContext
HsType
| HsTyFun HsType HsType -- ^ function type
| HsTyTuple HsBoxed [HsType] -- ^ tuple type, possibly boxed
| HsTyApp HsType HsType -- ^ application of a type constructor
| HsTyVar HsName -- ^ type variable
| HsTyCon HsQName -- ^ named type or type constructor
| HsTyPred HsAsst -- ^ assertion of an implicit parameter
| HsTyInfix HsType HsQName HsType -- ^ infix type constructor
| HsTyKind HsType HsKind -- ^ type with explicit kind signature
#ifdef __GLASGOW_HASKELL__
deriving (Eq,Show,Typeable,Data)
#else
deriving (Eq,Show)
#endif
data HsBoxed = Boxed | Unboxed
#ifdef __GLASGOW_HASKELL__
deriving (Eq,Show,Typeable,Data)
#else
deriving (Eq,Show)
#endif
data HsTyVarBind
= HsKindedVar HsName HsKind
| HsUnkindedVar HsName
#ifdef __GLASGOW_HASKELL__
deriving (Eq,Show,Typeable,Data)
#else
deriving (Eq,Show)
#endif
data HsKind
= HsKindStar
| HsKindBang
| HsKindFn HsKind HsKind
#ifdef __GLASGOW_HASKELL__
deriving (Eq,Show,Typeable,Data)
#else
deriving (Eq,Show)
#endif
-- | A functional dependency, given on the form
-- l1 l2 ... ln -> r2 r3 .. rn
data HsFunDep
= HsFunDep [HsName] [HsName]
#ifdef __GLASGOW_HASKELL__
deriving (Eq,Show,Typeable,Data)
#else
deriving (Eq,Show)
#endif
type HsContext = [HsAsst]
-- | Class assertions.
-- In Haskell 98, the argument would be a /tyvar/, but this definition
-- allows multiple parameters, and allows them to be /type/s.
-- Also extended with support for implicit parameters and equality constraints.
data HsAsst = HsClassA HsQName [HsType]
| HsIParam HsIPName HsType
| HsEqualP HsType HsType
#ifdef __GLASGOW_HASKELL__
deriving (Eq,Show,Typeable,Data)
#else
deriving (Eq,Show)
#endif
-- | /literal/
-- Values of this type hold the abstract value of the literal, not the
-- precise string representation used. For example, @10@, @0o12@ and @0xa@
-- have the same representation.
data HsLiteral
= HsChar Char -- ^ character literal
| HsString String -- ^ string literal
| HsInt Integer -- ^ integer literal
| HsFrac Rational -- ^ floating point literal
| HsCharPrim Char -- ^ GHC unboxed character literal
| HsStringPrim String -- ^ GHC unboxed string literal
| HsIntPrim Integer -- ^ GHC unboxed integer literal
| HsFloatPrim Rational -- ^ GHC unboxed float literal
| HsDoublePrim Rational -- ^ GHC unboxed double literal
#ifdef __GLASGOW_HASKELL__
deriving (Eq,Show,Typeable,Data)
#else
deriving (Eq,Show)
#endif
-- | Haskell expressions.
--
-- /Notes:/
--
-- * Because it is difficult for parsers to distinguish patterns from
-- expressions, they typically parse them in the same way and then check
-- that they have the appropriate form. Hence the expression type
-- includes some forms that are found only in patterns. After these
-- checks, these constructors should not be used.
--
-- * The parser does not take precedence and associativity into account,
-- so it will leave 'HsInfixApp's associated to the left.
--
-- * The 'Language.Haskell.Pretty.Pretty' instance for 'HsExp' does not
-- add parentheses in printing.
data HsExp
= HsVar HsQName -- ^ variable
| HsIPVar HsIPName -- ^ implicit parameter variable
| HsCon HsQName -- ^ data constructor
| HsLit HsLiteral -- ^ literal constant
| HsInfixApp HsExp HsQOp HsExp -- ^ infix application
| HsApp HsExp HsExp -- ^ ordinary application
| HsNegApp HsExp -- ^ negation expression @-@ /exp/
| HsLambda SrcLoc [HsPat] HsExp -- ^ lambda expression
| HsLet HsBinds HsExp -- ^ local declarations with @let@
| HsDLet [HsIPBind] HsExp -- ^ local declarations of implicit parameters (hugs)
| HsWith HsExp [HsIPBind] -- ^ local declarations of implicit parameters
| HsIf HsExp HsExp HsExp -- ^ @if@ /exp/ @then@ /exp/ @else@ /exp/
| HsCase HsExp [HsAlt] -- ^ @case@ /exp/ @of@ /alts/
| HsDo [HsStmt] -- ^ @do@-expression:
-- the last statement in the list
-- should be an expression.
| HsMDo [HsStmt] -- ^ @mdo@-expression
| HsTuple [HsExp] -- ^ tuple expression
| HsList [HsExp] -- ^ list expression
| HsParen HsExp -- ^ parenthesized expression
| HsLeftSection HsExp HsQOp -- ^ left section @(@/exp/ /qop/@)@
| HsRightSection HsQOp HsExp -- ^ right section @(@/qop/ /exp/@)@
| HsRecConstr HsQName [HsFieldUpdate]
-- ^ record construction expression
| HsRecUpdate HsExp [HsFieldUpdate]
-- ^ record update expression
| HsEnumFrom HsExp -- ^ unbounded arithmetic sequence,
-- incrementing by 1
| HsEnumFromTo HsExp HsExp -- ^ bounded arithmetic sequence,
-- incrementing by 1
| HsEnumFromThen HsExp HsExp -- ^ unbounded arithmetic sequence,
-- with first two elements given
| HsEnumFromThenTo HsExp HsExp HsExp
-- ^ bounded arithmetic sequence,
-- with first two elements given
| HsListComp HsExp [HsStmt] -- ^ list comprehension
| HsExpTypeSig SrcLoc HsExp HsType
-- ^ expression type signature
| HsAsPat HsName HsExp -- ^ patterns only
| HsWildCard -- ^ patterns only
| HsIrrPat HsExp -- ^ patterns only
-- Post-ops for parsing left sections and regular patterns. Not to be left in the final tree.
| HsPostOp HsExp HsQOp -- ^ post-ops
-- HaRP
| HsSeqRP [HsExp] -- ^ regular patterns only
| HsGuardRP HsExp [HsStmt] -- ^ regular patterns only
| HsEitherRP HsExp HsExp -- ^ regular patterns only
| HsCAsRP HsName HsExp -- ^ regular patterns only
-- Template Haskell
-- | HsReifyExp HsReify
| HsVarQuote HsQName -- ^ 'x
| HsTypQuote HsQName -- ^ ''T
| HsBracketExp HsBracket
| HsSpliceExp HsSplice
-- Hsx
| HsXTag SrcLoc HsXName [HsXAttr] (Maybe HsExp) [HsExp]
| HsXETag SrcLoc HsXName [HsXAttr] (Maybe HsExp)
| HsXPcdata String
| HsXExpTag HsExp
| HsXRPats [HsExp]
#ifdef __GLASGOW_HASKELL__
deriving (Eq,Show,Typeable,Data)
#else
deriving (Eq,Show)
#endif
data HsXName
= HsXName String -- @ /exp/
| HsGuardedAlts [HsGuardedAlt] -- ^ /gdpat/
#ifdef __GLASGOW_HASKELL__
deriving (Eq,Show,Typeable,Data)
#else
deriving (Eq,Show)
#endif
-- | A guarded alternative @|@ /stmt/, ... , /stmt/ @->@ /exp/.
data HsGuardedAlt
= HsGuardedAlt SrcLoc [HsStmt] HsExp
#ifdef __GLASGOW_HASKELL__
deriving (Eq,Show,Typeable,Data)
#else
deriving (Eq,Show)
#endif
-----------------------------------------------------------------------------
-- Builtin names.
prelude_mod, main_mod :: Module
prelude_mod = Module "Prelude"
main_mod = Module "Main"
main_name :: HsName
main_name = HsIdent "main"
unit_con_name :: HsQName
unit_con_name = Special HsUnitCon
tuple_con_name :: Int -> HsQName
tuple_con_name i = Special (HsTupleCon (i+1))
list_cons_name :: HsQName
list_cons_name = Special HsCons
unit_con :: HsExp
unit_con = HsCon unit_con_name
tuple_con :: Int -> HsExp
tuple_con i = HsCon (tuple_con_name i)
as_name, qualified_name, hiding_name, minus_name, pling_name, dot_name, star_name :: HsName
as_name = HsIdent "as"
qualified_name = HsIdent "qualified"
hiding_name = HsIdent "hiding"
minus_name = HsSymbol "-"
pling_name = HsSymbol "!"
dot_name = HsSymbol "."
star_name = HsSymbol "*"
export_name, safe_name, unsafe_name, threadsafe_name, stdcall_name, ccall_name :: HsName
export_name = HsIdent "export"
safe_name = HsIdent "safe"
unsafe_name = HsIdent "unsafe"
threadsafe_name = HsIdent "threadsafe"
stdcall_name = HsIdent "stdcall"
ccall_name = HsIdent "ccall"
unit_tycon_name, fun_tycon_name, list_tycon_name :: HsQName
unit_tycon_name = unit_con_name
fun_tycon_name = Special HsFunCon
list_tycon_name = Special HsListCon
tuple_tycon_name :: Int -> HsQName
tuple_tycon_name i = tuple_con_name i
unit_tycon, fun_tycon, list_tycon :: HsType
unit_tycon = HsTyCon unit_tycon_name
fun_tycon = HsTyCon fun_tycon_name
list_tycon = HsTyCon list_tycon_name
tuple_tycon :: Int -> HsType
tuple_tycon i = HsTyCon (tuple_tycon_name i)