-- {-# OPTIONS_GHC -cpp -DDEBUG #-} {-# OPTIONS_GHC -cpp #-} -- uncomment one of the two above lines to turn debugging on/off for this module ----------------------------------------------------------------------------- -- | -- Module : Berp.Base.Class -- Copyright : (c) 2010 Bernie Pope -- License : BSD-style -- Maintainer : florbitous@gmail.com -- Stability : experimental -- Portability : ghc -- -- Implementation of the Python "class" keyword. We call it "klass" (with a k) -- because "class" is a keyword in Haskell. -- ----------------------------------------------------------------------------- #include "BerpDebug.h" module Berp.Base.Class (klass) where import Berp.Base.LiftedIO (liftIO, MonadIO, writeIORef, readIORef) import Berp.Base.Ident import Berp.Base.SemanticTypes (Eval, Object (..), ObjectRef) #ifdef DEBUG import Berp.Base.Prims (printObject) #endif import Berp.Base.Hash (Hashed) import Berp.Base.Attributes (mkAttributes) import Berp.Base.StdTypes.Type (newType) import Berp.Base.StdTypes.String (string) import Berp.Base.StdTypes.Tuple (tuple) import Berp.Base.StdTypes.None (none) import Berp.Base.StdTypes.Object (object) klass :: Ident -> ObjectRef -> [Object] -> Eval [(Hashed String, ObjectRef)] -> Eval Object klass className ident srcBases attributesComp = do -- if the source lists no bases for the class, then force it to be (object) let trueBases = if null srcBases then [object] else srcBases attributes <- attributesComp attributesObjects <- mapM getIdentObj attributes classDict <- mkAttributes attributesObjects typeObject <- liftIO $ newType [string className, tuple trueBases, classDict] writeIORef ident $ typeObject IF_DEBUG((printObject $ object_mro typeObject) >> putStr "\n") return none where getIdentObj :: MonadIO m => (a, ObjectRef) -> m (a, Object) getIdentObj (ident, ref) = do obj <- readIORef ref return (ident, obj)