% % (c) The Foo Project, University of Glasgow, 1998 % % @(#) $Docid: Feb. 8th 2003 06:45 Sigbjorn Finne $ % @(#) $Contactid: sof@galois.com $ % A (restricted) abstract syntax for Haskell. \begin{code} module AbstractH where import Literal import BasicTypes \end{code} The @HTopDecl@ includes Haskell modules, but also an escape mechanism for inserting stuff that goes outside it (literate markup/pragmas etc.) \begin{code} data HTopDecl = HMod HModule | HInclude String | HLit String -- ToDo: nuke. | CLit String -- literal code/comments/whatever that appears outside a module block. \end{code} Represent a Haskell module abstractly by @HModule@, which \begin{code} data HModule = HModule Name Bool -- True => module contains FFI declarations (of some sort). [HExport] [HImport] HDecl \end{code} \begin{code} data HExport = HExport HIEEntity (Maybe String) data HIEEntity = IEModule Name | IEVal Name | IEClass Name | IEType Name Bool{-abstractly?-} deriving Eq \end{code} \begin{code} data HImport = HImport Bool --qualified? (Maybe Name) --qualify as Name --module name (Maybe [HIEEntity]) -- stuff to import, -- Nothing => the lot. -- Just [] => () (i.e., bring instances into scope.) \end{code} \begin{code} data HDecl = AndDecl HDecl HDecl -- for easy glomming together -- of code fragments. -- function signature foo :: ctxt => type | TypeSig Name (Maybe Context) Type -- f a1 .. an -- | g_1 = rhs_1 -- ... -- | g_n = rhs_n -- -- -- Note: allow qualified names here, which is -- illegal for toplevel valdecls in Haskell, but -- required (by Haskell 98 and ghc) for class -- methods in instance decls if the module that -- defines the class is imported qualified. -- (Unfortunately, Hugs does not currently allow -- said qualified method names, so a separate option -- is provided for turning off the use of qualified -- names on valdecls.) | ValDecl QualName [Pat] [GuardedExpr] -- primitive stdcall ["winmm.TimeGetTime"] [safe] timeGetTime :: ty | Primitive Bool{-safe?-} CallConv LocSpec Name Type Bool [(Bool,String)] (Bool,String) -- primcast stdcall applyIntFun :: Addr -> (Int -> IO Int) | PrimCast CallConv Name Type Bool [(Bool,String)] (Bool,String) -- entry stdcall ["tmgtm"] timeGetTime :: ty | Entry CallConv Name{-C name-} Name{-H name-} Type -- callback stdcall mkIntFun :: (Int -> IO Int) -> IO Addr | Callback CallConv Name Type -- 'foreign label' | ExtLabel Name{-C name-} Name{-H name-} Type -- (type|newtype|data) Nm a1..an = ty | TyD TyDecl -- class ctxt => CName a1 [..an] where { decls } | Class Context ClassName [TyVar] [HDecl] -- sigs and def. meths -- instance ctxt => CName ty where { .. decls .. } | Instance Context ClassName Type [HDecl] -- val decls only. -- %#include "foo" or {-# OPTIONS -#include "foo" #-} | Include String -- ghc/gc specific - will disappear eventually. | Haskell String -- Haskell code brought along from source file. | CCode String -- C code | EmptyDecl type LocSpec = (String, Maybe Integer, String, Maybe Int) type ClassName = QualName data Context = CtxtTuple [Context] -- (C1 .., C2 ..) => | CtxtClass ClassName [Type] deriving ( Eq, Show ) \end{code} @Type@ represent Haskell types - no explicit management of the scoping of type variables. \begin{code} data Type = TyVar Bool TyVar | TyCon TyCon | TyApply Type [Type] | TyList Type | TyTuple [Type] | TyFun Type Type -- abstract syntax allows contexts to be added to any types - makes -- generation of overloaded tysigs easier. | TyCtxt Context Type deriving ( Eq, Show ) \end{code} Patterned on @HsDecls.TyDecl@ (no support for tycon contexts tho') \begin{code} data TyDecl = TypeSyn Name [Name] Type | TyDecl TyDeclKind Name -- type constructor [Name] -- type vars [ConDecl] -- data constructors [QualName] -- derivings data TyDeclKind = Data | Newtype data ConDecl = ConDecl Name [BangType] | RecDecl Name [(Name, BangType)] data BangType = Banged Type | Unbanged Type type TyVar = QualName type TyCon = QualName \end{code} \begin{code} data GuardedExpr = GExpr [Expr] Expr data Expr = Lit Literal | Lam [Pat] Expr | Apply Expr [Expr] | RApply Expr Expr | Tup [Expr] | List [Expr] | InfixOp Expr VarName Expr | BinOp BinaryOp Expr Expr | UnOp UnaryOp Expr | Bind Expr Pat Expr | Bind_ Expr Expr | Return Expr | Case Expr [CaseAlt] | If Expr Expr Expr | Let [Binding] Expr | Var VarName | Con ConName | WithTy Expr Type data Binding = Binder Name Expr type VarName = QualName type ConName = QualName \end{code} \begin{code} data Pat = PatVar VarName | PatLit Literal | PatWildCard | PatTuple [Pat] | PatAs VarName Pat | PatCon ConName [Pat] | PatList [Pat] | PatIrrefut Pat | PatRecord VarName [(VarName,Pat)] data CaseAlt = Alt Pat [GuardedExpr] | Default (Maybe VarName) Expr \end{code}