packages feed

hgom-0.5.1: Gom/Sig.hs

------------------------------------------------------------------
-- |
-- Module      : Gom.Sig
-- Copyright   : (c) Paul Brauner 2009
--               (c) Emilie Balland 2009
--               (c) INRIA 2009
-- Licence     : GPL (see COPYING)
--
-- Maintainer  : paul.brauner@inria.fr
-- Stability   : provisional
-- Portability : non-portable (requires generalized newtype deriving)
--
-- This module exposes 'Module', the datatype representing gom modules
-- after parsing, and several helper functions.
--------------------------------------------------------------------

{-# LANGUAGE GeneralizedNewtypeDeriving #-}

module Gom.Sig (
  SortId(),
  ClassId(),
  FieldId(),
  CtorId(),
  Module(..),
  SortDef(..),
  Ctor(..),
  GomId(..),
  -- * Building identifiers
  makeSortId,
  makeClassId,
  makeFieldId,
  makeCtorId,
  prependEmpty,
  prependCons,
  prependHead,
  prependTail,
  lowerId,
  -- * Recovering information in a module
  definedSorts,
  exportedSorts,
  constructorNames,
  vconstructorNames,
  simpleFieldsNames,
  simpleFieldsOf,
  getClassName
) where

import Data.Char(toLower)
import Text.PrettyPrint.Leijen

-- | Sort name (e.g. @Expr@) identifier.
newtype SortId  = SortId String 
  deriving (Ord,Eq)
-- | Java Class name (e.g. @p.c<...>@) identifier.
data ClassId = ClassId String String 
  deriving (Ord,Eq)
-- | Field name (e.g. @x@) identifier.
newtype FieldId = FieldId String 
  deriving (Ord,Eq)
-- | Constructor name (e.g. @f@) identifier.
newtype CtorId  = CtorId String 
  deriving (Ord,Eq)

instance Show SortId  where show (SortId s)      = s
instance Show ClassId where show (ClassId s1 s2) = s1 ++ s2
instance Show FieldId where show (FieldId s)     = s
instance Show CtorId  where show (CtorId s)      = s

instance Pretty SortId  where pretty = text . show
instance Pretty ClassId where pretty = text . show
instance Pretty FieldId where pretty = text . show
instance Pretty CtorId  where pretty = text . show

class GomId a where
  idStr :: a -> String

instance GomId SortId  where idStr (SortId x)  = x
instance GomId FieldId where idStr (FieldId x) = x
instance GomId CtorId  where idStr (CtorId x)  = x

-- | Represents a gom module.
data Module = Module {
  moduleName :: String,    -- ^ module name
  imports    :: [SortId],  -- ^ list of imported sorts
  sortDefs   :: [SortDef]  -- ^ sort definitions
} deriving (Eq)

-- | Represents a sort definition, 
-- e.g. @List = nil() | cons(x:int, xs:List)@.
data SortDef = SortDef {
  sortName :: SortId,      -- ^ sort name (e.g. @List@)
  concreteSortName :: Maybe ClassId,      -- ^ sort name (e.g. @List@)
  ctors    :: [Ctor]       -- ^ constructors
                           -- (e.g. @nil()@ and @cons(x:int, xs:List)@)
} deriving (Eq)

-- | Represents a constructor definition.
data Ctor = 
    -- | non-variadic constructor, e.g. @f(x:int,y:T)@
    Simple { 
      ctorName :: CtorId,          -- ^ constructor name (e.g. @f@)
      fields :: [(FieldId,SortId)] 
        -- ^ constructor fields (e.g. @x:int@ and @y:T@)
    }
    -- | variadic constructor, e.g. @plus(Expr*)@
  | Variadic { 
      ctorName :: CtorId, -- ^ constructor name (e.g. @plus@)
      field :: SortId     -- ^ sort of the only field (e.g. @Expr@)
    }
 deriving (Eq)

makeSortId :: String -> SortId
makeSortId = SortId

-- | @makeClassId c p@ builds the @c\<p\>@ identifier.
-- (e.g. @makeClassId \"HashMap\" \"Int,Float\"@)
makeClassId :: String -> String -> ClassId
makeClassId = ClassId

makeFieldId :: String -> FieldId
makeFieldId = FieldId

makeCtorId :: String -> CtorId
makeCtorId = CtorId

-- | Turns @C@ into @EmptyC@.
prependEmpty :: CtorId -> CtorId
prependEmpty (CtorId s) = CtorId ("Empty" ++ s)

-- | Turns @C@ into @ConsC@.
prependCons :: CtorId -> CtorId
prependCons (CtorId s) = CtorId ("Cons" ++ s)

-- | Turns @C@ into @HeadC@.
prependHead :: CtorId -> FieldId
prependHead (CtorId s) = FieldId ("Head" ++ s)

-- | Turns @C@ into @TailC@.
prependTail :: CtorId -> FieldId
prependTail (CtorId s) = FieldId ("Tail" ++ s)

-- | Turns the id into lowercase
lowerId :: SortId -> SortId
lowerId (SortId x) = SortId (map toLower x)


getClassName :: ClassId -> String
getClassName (ClassId qualifiedname _) = qualifiedname

-- | @simpleFields def@ is the list of fields of non-variadic 
-- constructors of @def@, along with their sorts.
simpleFieldsOf :: SortDef -> [(FieldId, SortId)]
simpleFieldsOf def = ctors def >>= getfields
  where getfields (Simple _ f) = f
        getfields _            = []

-- | @vconstructorNames m@ returns the list of all the variadic constructors
-- declared in @m@.
--
-- As an example, for the following signature
--
-- > T = f(A*) | g(x:B)
-- > U = h(C*)
--
-- it returns @A@ and @C@.
vconstructorNames :: Module -> [CtorId]
vconstructorNames m = sortDefs m >>= ctors >>= getvtors
  where getvtors (Variadic f _) = [f]
        getvtors _              = []

-- | @exportedSorts m@ returns the list of sort names exported by @m@,
-- i.e. the sorts that appear in the left-hand sides of definitions
-- and the imported sorts.
exportedSorts :: Module -> [SortId]
exportedSorts sig = imports sig ++ definedSorts sig

-- | @definedSorts m@ returns the list of sort names defined by @m@,
-- i.e. the sorts that appear in the left-hand sides of definitions.
definedSorts :: Module -> [SortId]
definedSorts = map sortName . sortDefs

-- | @constructorNames m@ returns the list of all the constructors declared
-- in @m@ (variadic or not).
constructorNames :: Module -> [CtorId]
constructorNames = map ctorName . concatMap ctors . sortDefs

-- | All declared simple fields, duplicates removed
simpleFieldsNames :: Module -> [FieldId]
simpleFieldsNames m = sortDefs m >>= ctors >>= getfields
  where getfields (Simple _ fs) = map fst fs
        getfields _             = []