hnix/Nix.hs

95 lines
3.4 KiB
Haskell
Raw Normal View History

{-# LANGUAGE FlexibleContexts #-}
{-# LANGUAGE FlexibleInstances #-}
{-# LANGUAGE GeneralizedNewtypeDeriving #-}
{-# LANGUAGE LambdaCase #-}
{-# LANGUAGE MultiParamTypeClasses #-}
{-# LANGUAGE OverloadedStrings #-}
{-# LANGUAGE TypeFamilies #-}
{-# LANGUAGE TypeSynonymInstances #-}
module Nix where
import Control.Monad
import Control.Monad.Fix
import Control.Monad.IO.Class
import Control.Monad.Reader (MonadReader)
import Control.Monad.Trans.Reader
import qualified Data.HashMap.Lazy as M
import Data.Text (Text)
import Nix.Builtins
import Nix.Eval
import Nix.Expr.Types.Annotated (NExprLoc, stripAnnotation)
import Nix.Lint
import Nix.Monad
import Nix.Monad.Instance
import Nix.Scope
import Nix.Utils
-- | Evaluate a nix expression in the default context
evalTopLevelExpr :: MonadBuiltins e m
=> Maybe FilePath -> NExprLoc -> m (NValueNF m)
evalTopLevelExpr mpath expr = do
base <- baseEnv
(normalForm =<<) $ pushScopes base $ case mpath of
Nothing -> framedEvalExpr eval expr
Just path -> do
traceM $ "Setting __cur_file = " ++ show path
ref <- valueThunk $ NVLiteralPath path
pushScope (M.singleton "__cur_file" ref)
(framedEvalExpr eval expr)
evalTopLevelExprIO :: Maybe FilePath -> NExprLoc -> IO (NValueNF (Lazy IO))
evalTopLevelExprIO mpath = runLazyIO . evalTopLevelExpr mpath
tracingEvalTopLevelExprIO :: Maybe FilePath -> NExprLoc
-> IO (NValueNF (Lazy IO))
tracingEvalTopLevelExprIO mpath expr = do
traced <- tracingEvalExpr eval expr
case mpath of
Nothing ->
runLazyIO (normalForm =<< (`pushScopes` traced) =<< baseEnv)
Just path -> do
traceM $ "Setting __cur_file = " ++ show path
ref <- runLazyIO (valueThunk $ NVLiteralPath path)
let m = M.singleton "__cur_file" ref
runLazyIO (baseEnv >>= (`pushScopes` pushScope m traced)
>>= normalForm)
newtype Lint m a = Lint
{ runLint :: ReaderT (Context (Lint m) (SThunk (Lint m))) m a }
deriving (Functor, Applicative, Monad, MonadFix, MonadIO,
MonadReader (Context (Lint m) (SThunk (Lint m))))
instance (MonadFix m, MonadIO m)
=> MonadEval (SThunk (Lint m)) (Symbolic (Lint m)) (Lint m) where
embedSet s = mkSymbolic [TSet (Just s)]
projectSet = unpackSymbolic >=> \case
NMany [TSet s] -> return s
_ -> return Nothing
type MText (Lint m) = Text
wrapText = return
unwrapText = return
embedText = const $ mkSymbolic [TStr]
projectText = const $ return Nothing
runLintIO :: Lint IO a -> IO a
runLintIO = flip runReaderT (Context emptyScopes []) . runLint
symbolicBaseEnv :: Monad m => m (Scopes m (SThunk m))
symbolicBaseEnv = return [] -- jww (2018-04-02): TODO
lintExprIO :: NExprLoc -> IO (Symbolic (Lint IO))
lintExprIO expr =
runLintIO $ symbolicBaseEnv
>>= (`pushScopes` lintExpr (stripAnnotation expr))
tracingLintExprIO :: NExprLoc -> IO (Symbolic (Lint IO))
tracingLintExprIO expr = do
traced <- tracingEvalExpr lint expr
ref <- runLintIO $ sthunk $ mkSymbolic [TPath]
let m = M.singleton "__cur_file" ref
runLintIO $ symbolicBaseEnv >>= (`pushScopes` pushScope m traced)