{-# LANGUAGE OverloadedStrings #-}

module Castor.Std.Env (exports) where

import Control.Applicative
import Control.Monad.Error
import Data.IORef
import Data.Maybe
import qualified Data.Map as M

import Castor.Externs
import Castor.Types

locals :: Value
locals = mkBif [Sym "_"] $ \envref cenvref -> do
    env <- liftIO $ readIORef cenvref
    return $ Aggregate $ vars env

let' :: Value
let' = mkBif [Sym "k", Sym "v"] $ \envref cenvref -> do
    Quoted (Symbol k) <- extract (Sym "k") envref
    v <- extract (Sym "v") envref
    cenv <- liftIO $ readIORef cenvref
    liftIO $ writeIORef cenvref cenv { vars = M.insert k v $ vars cenv }
    return v

with :: Value
with = mkBif [Sym "env", Sym "f"] $ \envref cenvref -> do
    Aggregate vars <- extract (Sym "env") envref
    Function formal body (Just fenvref) <- extract (Sym "f") envref
    wenvref <- liftIO $ newIORef Environment { parent = Just fenvref
                                             , vars = vars }
    return $ Function formal body (Just wenvref)

exports :: Exports
exports = Exports $ M.fromList [ (Sym "locals", locals)
                               , (Sym "let!", let')
                               , (Sym "with", with)
                               ]
