packages feed

lhc-0.10: src/Grin/Types.hs

{-# LANGUAGE TemplateHaskell #-}
{-# OPTIONS_GHC -Wwarn #-}
module Grin.Types
    ( module Grin.Types
    , module Grin.SimpleCore.Types
    ) where

import CompactString

import Grin.SimpleCore.Types (Lit(..), FFIType(..))

import Data.Binary
import Data.DeriveTH
import Control.Monad  (ap)

import Traverse

import qualified HashMap as HT

-- Invariants:
--   The nodes referred to by the functions are a subset of the nodes in 'grinNodes'.
data Grin
    = Grin { grinNodes      :: [NodeDef]
           , grinCAFs       :: [CAF]
           , grinFunctions  :: [FuncDef]
           , grinEntryPoint ::Renamed
           , grinUnique     :: Int
           }
    deriving (Eq)

data CAF
    = CAF { cafName  :: Renamed
          , cafValue :: Value
          }
    deriving (Eq)

data FuncDef
    = FuncDef { funcDefName :: Renamed
              , funcDefArgs :: [Renamed]
              , funcDefBody :: Expression
              }
    deriving (Eq)

data NodeDef
    = NodeDef { nodeName :: Renamed
              , nodeType :: NodeType
              , nodeArgs :: [Type]
              }
    deriving (Eq,Ord)

{-
  ConstructorNodes represent data, like: Nil, Cons, Char, etc.
  FunctionNodes represents suspended functions which may be partially applied.
-}
data NodeType
    = ConstructorNode
    | FunctionNode
    deriving (Show,Eq,Ord)

data Type
    = PtrType
    | WordType
    | NodeType
    deriving (Eq,Ord)

data Lambda = Renamed :-> Expression deriving (Show, Eq)
data Alt = Value :> Expression deriving (Show, Eq)

infixr 1 :->
infixr 1 :>>=
infixr 1 :>>

data Expression
    = Expression :>>= Lambda
    | Expression :>> Expression
    | Application { expFunction :: Renamed
                  , expArgs     :: [Renamed] }
    | Case        { expValue    :: Renamed
                  , expAlts     :: [Alt] }
    | Store       Value
    | Update      Int Renamed Renamed -- size, ptr, value
    | Unit        Value
    deriving (Show, Eq)

instance Traverse Expression where
    tmapM fn exp
        = case exp of
            e1 :>>= bind :-> e2
              -> do e1' <- fn e1
                    e2' <- fn e2
                    return (e1' :>>= bind :-> e2')
            e1 :>> e2
              -> do e1' <- fn e1
                    e2' <- fn e2
                    return (e1' :>> e2')
            Application{}
              -> return exp
            Case scrut alts
              -> do alts' <- sequence [ do alt' <- fn alt
                                           return (cond :> alt')
                                        | cond :> alt <- alts]
                    return $ Case scrut alts'
            Store{}
              -> return exp
            Update{}
              -> return exp
            Unit{}
              -> return exp


type Variable = CompactString

-- FIXME: Writer manual Eq and Ord instances for Renamed.
data Renamed = Aliased Int CompactString
             | Anonymous Int
             | Builtin CompactString
             | External String [FFIType]
    deriving (Show,Eq,Ord)

instance HT.Hashable Renamed where
    hash (Aliased uid _alias) = uid
    hash (Anonymous uid)      = uid
    hash Builtin{}            = 0
    hash External{}           = 0


isAliased, isBuiltin, isExternal :: Renamed -> Bool

isAliased Aliased{} = True
isAliased _ = False

isBuiltin Builtin{} = True
isBuiltin _ = False

isExternal External{} = True
isExternal _ = False

alias :: Renamed -> Maybe CompactString
alias (Aliased _ name) = Just name
alias _ = Nothing

numbered :: Renamed -> Bool
numbered Aliased{} = True
numbered Anonymous{} = True
numbered _ = False

uniqueId :: Renamed -> Int
uniqueId (Aliased uid _name) = uid
uniqueId (Anonymous uid)     = uid
uniqueId (Builtin prim)      = error $ "Grin.Types.uniqueId: Primitive: " ++ show prim
uniqueId (External fn tys)   = error $ "Grin.Types.uniqueId: External: " ++ show fn

data Value
    = Node Renamed NodeType Int [Renamed]
    | Vector [Renamed]
    | Lit Lit
    | Variable Renamed
    | Hole Int
    | Empty
    deriving (Show,Eq)


$(derive makeBinary ''NodeType)
$(derive makeBinary ''Renamed)
$(derive makeBinary ''Value)
$(derive makeBinary ''CAF)
$(derive makeBinary ''FuncDef)
$(derive makeBinary ''NodeDef)
$(derive makeBinary ''Expression)
$(derive makeBinary ''Type)
$(derive makeBinary ''Alt)
$(derive makeBinary ''Lambda)
$(derive makeBinary ''Grin)