module Berp.Base.StdTypes.Generator (generator, generatorClass) where
import Berp.Base.Monad (constantIO)
import Berp.Base.SemanticTypes (Object (..), Eval)
import Berp.Base.Identity (newIdentity)
import Berp.Base.Attributes (mkAttributes)
import Berp.Base.StdNames
import Berp.Base.Prims (generatorNext, primitive)
import Berp.Base.LiftedIO (newIORef)
import Berp.Base.StdTypes.Type (newType)
import Berp.Base.StdTypes.ObjectBase (objectBase)
import Berp.Base.StdTypes.String (string)
import Berp.Base.StdTypes.Function (function)
generator :: Eval Object -> Eval Object
generator continuation = do
identity <- newIdentity
contRef <- newIORef continuation
stackRef <- newIORef id
return $
Generator
{ object_identity = identity
, object_continuation = contRef
, object_stack_context = stackRef
}
generatorClass :: Object
generatorClass = constantIO $ do
dict <- attributes
newType [string "generator", objectBase, dict]
attributes :: IO Object
attributes = mkAttributes
[ (iterName, iter)
, (strName, str)
, (nextName, next)
]
str :: Object
str = primitive 1 $ \_ -> return $ string $ "Generator"
iter :: Object
iter = primitive 1 $ \(x:_) -> return x
next :: Object
next = function 1 generatorNext