packages feed

plugins-1.0: src/Language/Hi/Syntax.hs

-- 
-- Copyright (C) 2004 Don Stewart - http://www.cse.unsw.edu.au/~dons
-- 
-- This library is free software; you can redistribute it and/or
-- modify it under the terms of the GNU Lesser General Public
-- License as published by the Free Software Foundation; either
-- version 2.1 of the License, or (at your option) any later version.
-- 
-- This library is distributed in the hope that it will be useful,
-- but WITHOUT ANY WARRANTY; without even the implied warranty of
-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
-- Lesser General Public License for more details.
-- 
-- You should have received a copy of the GNU Lesser General Public
-- License along with this library; if not, write to the Free Software
-- Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307
-- USA
-- 
-- Based on code from $fptools/ghc/compiler/main/HscTypes.lhs
--  (c) The University of Glasgow 2002
--
 
module Language.Hi.Syntax where

import Language.Hi.FastString

import Data.List        ( intersperse )

-- ---------------------------------------------------------------------
-- An Iface, the representation of an .hi file.
--
-- The abstract syntax that we don't need is blanked with a default
-- type, however we must be careful in BinIface to still parse the
-- correct number of bytes for each data type. This involves leaving the
-- code alone, other than to add the types of the sub-constructors of
-- the types we have blanked out (because they can't be inferred
-- anymore).
--

data Iface = Iface {
        mi_package  :: String,          -- what package is this?
        mi_module   :: String,          -- what module is this?
        mi_deps     :: Dependencies,
        mi_usages   :: [Usage],
        mi_exports  :: [IfaceExport] {-,-}

--      mi_decls    :: [(Version,IfaceDecl)] {-,-}

--      mi_mod_vers :: !Version,
--      mi_orphan   :: !Bool,
--      mi_boot     :: !Bool,
--      mi_exp_vers :: !Version,
--      mi_fixities :: [(OccName,Fixity)],
--      mi_deprecs  :: [IfaceDeprec],
--      mi_insts     :: [IfaceInst],
--      mi_rules     :: [IfaceRule],
--      mi_rule_vers :: !Version,
     }

emptyIface = Iface {
        mi_package = undefined,
        mi_module  = undefined,
        mi_deps    = noDependencies,
        mi_usages  = undefined,
        mi_exports = undefined
   }

-- ---------------------------------------------------------------------
-- pretty-print an interface
--
showIface :: Iface -> String
showIface (Iface { mi_package = p, mi_module  = m, 
                   mi_deps = deps, mi_usages = us }) = 
        "interface \"" ++ p ++ "\" " ++ m ++ 
        "\n" ++ pprDeps deps  ++
        "\n" ++ (concat $ intersperse "\n" (map pprUsage us)) 
 --     "\n" ++ (concat $ intersperse "\n" (map pprExport es))

pprDeps :: Dependencies -> String
pprDeps (Deps { dep_mods = mods, dep_pkgs = pkgs }) 
        = "module dependencies: "    ++ (concat $ intersperse ", " mods) ++
          "\npackage dependencies: " ++ (concat $ intersperse ", " pkgs)

pprUsage :: Usage -> String
pprUsage usage = hsep ["import", usg_name usage]

pprExport :: IfaceExport -> String
pprExport (fsmod, items)
        = hsep [ "export", unpackFS fsmod, hsep (map pp_avail items) ]
  where
    pp_avail :: GenAvailInfo OccName -> String
    pp_avail (Avail nm)    = ppr_occ nm
    pp_avail (AvailTC _ []) = empty
    pp_avail (AvailTC n (n':ns))
        | n==n'     = (ppr_occ n) ++ pp_export ns
        | otherwise = (ppr_occ n) ++ "|" ++ pp_export (n':ns)

    pp_export []    = empty
    pp_export names = "{" ++ (hsep (map ppr_occ names)) ++ "}"

    ppr_occ (OccName _ s) = s

--
-- TODO bring in the Pretty library
--
hsep  = \ss -> concat (intersperse " " ss)
empty = ""

-- ---------------------------------------------------------------------
--
-- Dependency info about modules and packages below this one
-- in the import hierarchy.  See TcRnTypes.ImportAvails for details.
--
-- Invariant: the dependencies of a module M never includes M
-- Invariant: the lists are unordered, with no duplicates
--
-- The fields are:
--      Home-package module dependencies
--      External package dependencies
--      Orphan modules (whether home or external pkg)

data Dependencies = Deps { 
        dep_mods  :: [ModuleName],
        dep_pkgs  :: [PackageName] {-,-} 
     } deriving (Show)

noDependencies :: Dependencies
noDependencies = Deps [] []

--
-- Type aliases need to have a real type so the parser can work out how
-- to parse them. You have to find what these are by reading GHC.
--
type ModuleName   = String     {- was FastString -}      -- Module
type PackageName  = String     {- was FastString -}      -- Packages
type Version      = Int                                  -- BasicTypes
type EncodedFS    = FastString                           -- FastString
type IfaceExport  = (EncodedFS, [GenAvailInfo OccName])  -- HscTypes

data GenAvailInfo name  
        = Avail   name   -- An ordinary identifier
        | AvailTC name   -- The name of the type or class
                 [name]  -- The available pieces of type/class.
                         -- NB: If the type or class is itself
                         -- to be in scope, it must be in this list.
                         -- Thus, typically: AvailTC Eq [Eq, ==, /=]
        deriving Show

data OccName      = OccName NameSpace String {- was EncodedFS -}
        deriving Show

instance Eq OccName where
        (OccName sp1 s1) == (OccName sp2 s2) = s1 == s2 && sp1 == sp2

data NameSpace    = VarName     -- variables, and "source" data constructors
                  | DataName    -- "real" data constructors
                  | TvName      -- tyvars
                  | TcClsName   -- type constructors and classes
        deriving (Eq, Show)

data Usage
  = Usage { usg_name     :: ModuleName,		-- Name of the module
	    usg_mod      :: Version,		-- Module version
	    usg_exports  :: Maybe Version,	-- Export-list version, if we depend on it
	    usg_entities :: [(OccName,Version)],-- Sorted by occurrence name
	    usg_rules    :: Version 		-- Orphan-rules version (for non-orphan
						-- modules this will always be initialVersion)
    } deriving Show

------------------------------------------------------------------------
-- TODO parsing type and decl information out of the .hi file
-- complex data structure...
--

{-
data IfaceExtName
  = ExtPkg ModuleName OccName		-- From an external package; no version #
					-- Also used for wired-in things regardless
					-- of whether they are home-pkg or not

  | HomePkg ModuleName OccName Version	-- From another module in home package;
					-- has version #

  | LocalTop OccName			-- Top-level from the same module as 
					-- the enclosing IfaceDecl

  | LocalTopSub		-- Same as LocalTop, but for a class method or constr
	OccName		-- Class-meth/constr name
	OccName		-- Parent class/datatype name
	-- LocalTopSub is written into iface files as LocalTop; the parent 
	-- info is only used when computing version information in MkIface

data IfaceTyCon 	-- Abbreviations for common tycons with known names
  = IfaceTc IfaceExtName	-- The common case
  | IfaceIntTc | IfaceBoolTc | IfaceCharTc
  | IfaceListTc | IfacePArrTc
  | IfaceTupTc Boxity Arity 

type Arity        = Int                                 -- BasicTypes

data Boxity
  = Boxed
  | Unboxed

type IfaceContext = [IfacePredType]

data IfacePredType 	-- NewTypes are handled as ordinary TyConApps
  = IfaceClassP IfaceExtName [IfaceType]
  | IfaceIParam (IPName OccName) IfaceType

data IPName name
  = Dupable   name	-- ?x: you can freely duplicate this implicit parameter
  | Linear name		-- %x: you must use the splitting function to duplicate it
  deriving( Eq, Ord )	-- Ord is used in the IP name cache finite map
			--	(used in HscTypes.OrigIParamCache)

data IfaceType
  = IfaceTyVar    OccName		-- Type variable only, not tycon
  | IfaceAppTy    IfaceType IfaceType
  | IfaceForAllTy IfaceTvBndr IfaceType
  | IfacePredTy IfacePredType
  | IfaceTyConApp IfaceTyCon [IfaceType]	-- Not necessarily saturated
						-- Includes newtypes, synonyms, tuples
  | IfaceFunTy  IfaceType IfaceType

data IfaceBndr 		-- Local (non-top-level) binders
  = IfaceIdBndr IfaceIdBndr
  | IfaceTvBndr IfaceTvBndr

type IfaceIdBndr  = (OccName, IfaceType)	-- OccName, because always local
type IfaceTvBndr  = (OccName, IfaceKind)
type IfaceKind    = Kind			-- Re-use the Kind type, but no KindVars in it

data IfaceIdInfo
  = NoInfo			-- When writing interface file without -O
  | HasInfo [IfaceInfoItem]	-- Has info, and here it is

data IfaceInfoItem
  = HsArity	 Arity
  | HsStrictness StrictSig
  | HsUnfold	 Activation IfaceExpr
  | HsNoCafRefs
  | HsWorker	 IfaceExtName Arity	-- Worker, if any see IdInfo.WorkerInfo
					-- for why we want arity here.
	-- NB: we need IfaceExtName (not just OccName) because the worker
	--     can simplify to a function in another module.
-- NB: Specialisations and rules come in separately and are
-- only later attached to the Id.  Partial reason: some are orphans.

newtype StrictSig = StrictSig DmdType

data IfaceDecl 
  = IfaceId { ifName   :: OccName,
	      ifType   :: IfaceType, 
	      ifIdInfo :: IfaceIdInfo }

  | IfaceData { ifCtxt     :: IfaceContext,	-- Context
		ifName     :: OccName,		-- Type constructor
		ifTyVars   :: [IfaceTvBndr],	-- Type variables
		ifCons	   :: IfaceConDecls,	-- Includes new/data info
	        ifRec	   :: RecFlag,		-- Recursive or not?
		ifVrcs     :: ArgVrcs,
		ifGeneric  :: Bool		-- True <=> generic converter functions available
    }						-- We need this for imported data decls, since the
						-- imported modules may have been compiled with
						-- different flags to the current compilation unit

  | IfaceSyn  {	ifName   :: OccName,		-- Type constructor
		ifTyVars :: [IfaceTvBndr],	-- Type variables
		ifVrcs   :: ArgVrcs,
		ifSynRhs :: IfaceType		-- synonym expansion
    }

  | IfaceClass { ifCtxt    :: IfaceContext, 	 	-- Context...
		 ifName    :: OccName,		    	-- Name of the class
		 ifTyVars  :: [IfaceTvBndr],		-- Type variables
		 ifFDs     :: [FunDep OccName],		-- Functional dependencies
		 ifSigs    :: [IfaceClassOp],		-- Method signatures
	         ifRec	   :: RecFlag,			-- Is newtype/datatype associated with the class recursive?
		 ifVrcs    :: ArgVrcs			-- ... and what are its argument variances ...
    }

  | IfaceForeign { ifName :: OccName,			-- Needs expanding when we move beyond .NET
		   ifExtName :: Maybe FastString }
-}

------------------------------------------------------------------------
--
-- all this stuff may be enabled if we ever want other information out
--

{-
type ArgVrcs      = [(Bool,Bool)]                       -- TyCon
type CLabelString = FastString                          -- CStrings
type CcName       = EncodedFS                           -- CostCentre
type DeprecTxt    = FastString                          -- BasicTypes
type FunDep a     = ([a],[a])                           -- Class
type IfaceAlt     = (IfaceConAlt,[OccName],IfaceExpr)   -- IfaceSyn
type IfaceContext = [IfacePredType]                     -- IfaceType
type IfaceDeprec  = Deprecs [(OccName,DeprecTxt)]       -- HscTypes
type IfaceIdBndr  = (OccName, IfaceType)                -- IfaceType
type IfaceKind    = Kind                                -- IfaceType
type IfaceTvBndr  = (OccName, IfaceKind)                -- IfaceType
type RuleName     = FastString                          -- CoreSyn

--
-- Empty definitions for the various types we need, but whose results we
-- don't care about.
--
-- 'data' types that have a parsing method associated with them
-- This list corresponds to each instance in BinIface
--
-- Try to keep this list ordered by the order they appear in BinIface
--
data Deprecs a          = Deprecs 
data Activation         = Activation 
data StrictnessMark     = StrictnessMark
data Boxity             = Boxity 
data TupCon             = TupCon
data RecFlag            = RecFlag
data DefMeth            = DefMeth
data FixityDirection    = FixityDirection
data Fixity             = Fixity
data DmdType            = DmdType
data Demand             = Demand
data Demands            = Demands
data DmdResult          = DmdResult
data StrictSig          = StrictSig
data IsCafCC            = IsCafCC
data IsDupdCC           = IsDupdCC
data CostCentre         = CostCentre
data IfaceExtName       = IfaceExtName
data IfaceBndr          = IfaceBndr
data Kind               = Kind
data IfaceTyCon         = IfaceTyCon
data IfacePredType      = IfacePredType
data IfaceExpr          = IfaceExpr
data IfaceConAlt        = IfaceConAlt
data IfaceBinding       = IfaceBinding
data IfaceIdInfo        = IfaceIdInfo
data IfaceNoteItem      = IfaceNoteItem
data IfaceInfoItem      = IfaceInfoItem
data IfaceNote          = IfaceNote
data IfaceInst          = IfaceInst
data IfaceConDecls      = IfaceConDecls
data IfaceConDecl       = IfaceConDecl
data IfaceClassOp       = IfaceClassOp
data IfaceRule          = IfaceRule
data Literal            = Literal
data ForeignCall        = ForeignCall
data Safety             = Safety
data CExportSpec        = CExportSpec
data CCallSpec          = CCallSpec
data CCallTarget        = CCallTarget
data CCallConv          = CCallConv
data DNCallSpec         = DNCallSpec
data DNKind             = DNKind
data DNType             = DNType

-}