{-# language AllowAmbiguousTypes #-}
{-# language ConstraintKinds #-}
{-# language RankNTypes #-}


module Nix.Eval where

import           Nix.Prelude
import           Relude.Extra                   ( set )
import           Control.Monad                  ( foldM )
import           Control.Monad.Fix              ( MonadFix )
import           GHC.Exception                  ( ErrorCall(ErrorCall) )
import           Data.Semialign.Indexed         ( ialignWith )
import qualified Data.HashMap.Lazy             as M
import           Data.List                      ( partition )
import           Data.These                     ( These(..) )
import           Nix.Atoms
import           Nix.Convert
import           Nix.Expr.Types
import           Nix.Expr.Types.Annotated
import           Nix.Expr.Strings               ( runAntiquoted )
import           Nix.Frames
import           Nix.String
import           Nix.Scope
import           Nix.Value.Monad

class (Show v, Monad m) => MonadEval v m where
  freeVariable    :: VarName -> m v
  synHole         :: VarName -> m v
  attrMissing     :: NonEmpty VarName -> Maybe v -> m v
  evaledSym       :: VarName -> v -> m v
  evalCurPos      :: m v
  evalConstant    :: NAtom -> m v
  evalString      :: NString (m v) -> m v
  evalLiteralPath :: Path -> m v
  evalEnvPath     :: Path -> m v
  evalUnary       :: NUnaryOp -> v -> m v
  evalBinary      :: NBinaryOp -> v -> m v -> m v
  -- ^ The second argument is an action because operators such as boolean &&
  -- and || may not evaluate the second argument.
  evalWith        :: m v -> m v -> m v
  evalIf          :: v -> m v -> m v -> m v
  evalAssert      :: v -> m v -> m v
  evalApp         :: v -> m v -> m v
  evalAbs         :: Params (m v)
                  -> ( forall a
                    . m v
                    -> ( AttrSet (m v)
                      -> m v
                      -> m (a, v)
                      )
                    -> m (a, v)
                    )
                  -> m v
{-
  evalSelect     :: v -> NonEmpty Text -> Maybe (m v) -> m v
  evalHasAttr    :: v -> NonEmpty Text -> m v

  -- | This and the following methods are intended to allow things like
  --   adding provenance information.
  evalListElem   :: [m v] -> Int -> m v -> m v
  evalList       :: [v] -> m v
  evalSetElem    :: AttrSet (m v) -> Text -> m v -> m v
  evalSet        :: AttrSet v -> PositionSet -> m v
  evalRecSetElem :: AttrSet (m v) -> Text -> m v -> m v
  evalRecSet     :: AttrSet v -> PositionSet -> m v
  evalLetElem    :: Text -> m v -> m v
  evalLet        :: m v -> m v
-}
  evalError :: Exception s => s -> m a

type MonadNixEval v m
  = ( MonadEval v m
  , Scoped v m
  , MonadValue v m
  , MonadFix m
  , ToValue Bool m v
  , ToValue [v] m v
  , FromValue NixString m v
  , ToValue (AttrSet v, PositionSet) m v
  , FromValue (AttrSet v, PositionSet) m v
  )

data EvalFrame m v
  = EvaluatingExpr (Scopes m v) NExprLoc
  | ForcingExpr (Scopes m v) NExprLoc
  | Calling VarName SrcSpan
  | SynHole (SynHoleInfo m v)
  deriving (Int -> EvalFrame m v -> ShowS
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
forall (m :: * -> *) v. Int -> EvalFrame m v -> ShowS
forall (m :: * -> *) v. [EvalFrame m v] -> ShowS
forall (m :: * -> *) v. EvalFrame m v -> String
showList :: [EvalFrame m v] -> ShowS
$cshowList :: forall (m :: * -> *) v. [EvalFrame m v] -> ShowS
show :: EvalFrame m v -> String
$cshow :: forall (m :: * -> *) v. EvalFrame m v -> String
showsPrec :: Int -> EvalFrame m v -> ShowS
$cshowsPrec :: forall (m :: * -> *) v. Int -> EvalFrame m v -> ShowS
Show, Typeable)

instance (Typeable m, Typeable v) => Exception (EvalFrame m v)

data SynHoleInfo m v = SynHoleInfo
  { forall (m :: * -> *) v. SynHoleInfo m v -> NExprLoc
_synHoleInfo_expr :: NExprLoc
  , forall (m :: * -> *) v. SynHoleInfo m v -> Scopes m v
_synHoleInfo_scope :: Scopes m v
  }
  deriving (Int -> SynHoleInfo m v -> ShowS
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
forall (m :: * -> *) v. Int -> SynHoleInfo m v -> ShowS
forall (m :: * -> *) v. [SynHoleInfo m v] -> ShowS
forall (m :: * -> *) v. SynHoleInfo m v -> String
showList :: [SynHoleInfo m v] -> ShowS
$cshowList :: forall (m :: * -> *) v. [SynHoleInfo m v] -> ShowS
show :: SynHoleInfo m v -> String
$cshow :: forall (m :: * -> *) v. SynHoleInfo m v -> String
showsPrec :: Int -> SynHoleInfo m v -> ShowS
$cshowsPrec :: forall (m :: * -> *) v. Int -> SynHoleInfo m v -> ShowS
Show, Typeable)

instance (Typeable m, Typeable v) => Exception (SynHoleInfo m v)

-- jww (2019-03-18): By deferring only those things which must wait until
-- context of us, this can be written as:
-- eval :: forall v m . MonadNixEval v m => NExprF v -> m v
eval :: forall v m . MonadNixEval v m => NExprF (m v) -> m v

eval :: forall v (m :: * -> *). MonadNixEval v m => NExprF (m v) -> m v
eval (NSym VarName
"__curPos") = forall v (m :: * -> *). MonadEval v m => m v
evalCurPos

eval (NSym VarName
var       ) =
  do
    Maybe v
mVal <- forall a (m :: * -> *). Scoped a m => VarName -> m (Maybe a)
lookupVar VarName
var
    forall b a. b -> (a -> b) -> Maybe a -> b
maybe
      (forall v (m :: * -> *). MonadEval v m => VarName -> m v
freeVariable VarName
var)
      (forall v (m :: * -> *). MonadEval v m => VarName -> v -> m v
evaledSym VarName
var forall (m :: * -> *) b c a.
Monad m =>
(b -> m c) -> (a -> m b) -> a -> m c
<=< forall v (m :: * -> *). MonadValue v m => v -> m v
demand)
      Maybe v
mVal

eval (NConstant    NAtom
x      ) = forall v (m :: * -> *). MonadEval v m => NAtom -> m v
evalConstant NAtom
x
eval (NStr         NString (m v)
str    ) = forall v (m :: * -> *). MonadEval v m => NString (m v) -> m v
evalString NString (m v)
str
eval (NLiteralPath Path
p      ) = forall v (m :: * -> *). MonadEval v m => Path -> m v
evalLiteralPath Path
p
eval (NEnvPath     Path
p      ) = forall v (m :: * -> *). MonadEval v m => Path -> m v
evalEnvPath Path
p
eval (NUnary NUnaryOp
op m v
arg       ) = forall v (m :: * -> *). MonadEval v m => NUnaryOp -> v -> m v
evalUnary NUnaryOp
op forall (m :: * -> *) a b. Monad m => (a -> m b) -> m a -> m b
=<< m v
arg

eval (NApp m v
fun m v
arg        ) =
  do
    v
f <- m v
fun
    Scopes m v
scope <- forall a (m :: * -> *). Scoped a m => m (Scopes m a)
askScopes
    forall v (m :: * -> *). MonadEval v m => v -> m v -> m v
evalApp v
f forall a b. (a -> b) -> a -> b
$ forall a (m :: * -> *) r. Scoped a m => Scopes m a -> m r -> m r
withScopes Scopes m v
scope m v
arg

eval (NBinary NBinaryOp
op   m v
larg m v
rarg) =
  do
    v
lav <- m v
larg
    forall v (m :: * -> *).
MonadEval v m =>
NBinaryOp -> v -> m v -> m v
evalBinary NBinaryOp
op v
lav m v
rarg

eval (NSelect Maybe (m v)
alt m v
aset NAttrPath (m v)
attr) =
  do
    let useAltOrReportMissing :: (v, NonEmpty VarName) -> m v
useAltOrReportMissing (v
s, NonEmpty VarName
ks) = forall a. a -> Maybe a -> a
fromMaybe (forall v (m :: * -> *).
MonadEval v m =>
NonEmpty VarName -> Maybe v -> m v
attrMissing NonEmpty VarName
ks forall a b. (a -> b) -> a -> b
$ forall (f :: * -> *) a. Applicative f => a -> f a
pure v
s) Maybe (m v)
alt

    Either (v, NonEmpty VarName) (m v)
eAttr <- forall v (m :: * -> *).
MonadNixEval v m =>
m v -> NAttrPath (m v) -> m (Either (v, NonEmpty VarName) (m v))
evalSelect m v
aset NAttrPath (m v)
attr
    forall a c b. (a -> c) -> (b -> c) -> Either a b -> c
either (v, NonEmpty VarName) -> m v
useAltOrReportMissing forall a. a -> a
id (coerce :: forall a b. Coercible a b => a -> b
coerce Either (v, NonEmpty VarName) (m v)
eAttr)

eval (NHasAttr m v
aset NAttrPath (m v)
attr) =
  do
    Either (v, NonEmpty VarName) (m v)
eAttr <- forall v (m :: * -> *).
MonadNixEval v m =>
m v -> NAttrPath (m v) -> m (Either (v, NonEmpty VarName) (m v))
evalSelect m v
aset NAttrPath (m v)
attr
    forall a (m :: * -> *) v. ToValue a m v => a -> m v
toValue forall a b. (a -> b) -> a -> b
$ forall a b. Either a b -> Bool
isRight Either (v, NonEmpty VarName) (m v)
eAttr

eval (NList [m v]
l           ) =
  do
    Scopes m v
scope <- forall a (m :: * -> *). Scoped a m => m (Scopes m a)
askScopes
    forall a (m :: * -> *) v. ToValue a m v => a -> m v
toValue forall (m :: * -> *) a b. Monad m => (a -> m b) -> m a -> m b
=<< forall (t :: * -> *) (f :: * -> *) a b.
(Traversable t, Applicative f) =>
(a -> f b) -> t a -> f (t b)
traverse (forall v (m :: * -> *). MonadValue v m => m v -> m v
defer @v @m forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a (m :: * -> *) r. Scoped a m => Scopes m a -> m r -> m r
withScopes @v Scopes m v
scope) [m v]
l

eval (NSet Recursivity
r [Binding (m v)]
binds) =
  do
    (AttrSet v, PositionSet)
attrSet <- forall v (m :: * -> *).
MonadNixEval v m =>
Bool -> [Binding (m v)] -> m (AttrSet v, PositionSet)
evalBinds (Recursivity
r forall a. Eq a => a -> a -> Bool
== Recursivity
Recursive) forall a b. (a -> b) -> a -> b
$ forall r. ([Binding r] -> r) -> [Binding r] -> [Binding r]
desugarBinds (forall v (m :: * -> *). MonadNixEval v m => NExprF (m v) -> m v
eval forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall r. Recursivity -> [Binding r] -> NExprF r
NSet forall a. Monoid a => a
mempty) [Binding (m v)]
binds
    forall a (m :: * -> *) v. ToValue a m v => a -> m v
toValue (AttrSet v, PositionSet)
attrSet

eval (NLet [Binding (m v)]
binds m v
body    ) =
  do
    (AttrSet v
attrSet, PositionSet
_) <- forall v (m :: * -> *).
MonadNixEval v m =>
Bool -> [Binding (m v)] -> m (AttrSet v, PositionSet)
evalBinds Bool
True [Binding (m v)]
binds
    forall a (m :: * -> *) r. Scoped a m => Scope a -> m r -> m r
pushScope (coerce :: forall a b. Coercible a b => a -> b
coerce AttrSet v
attrSet) m v
body

eval (NIf m v
cond m v
t m v
f       ) =
  do
    v
v <- m v
cond
    forall v (m :: * -> *). MonadEval v m => v -> m v -> m v -> m v
evalIf v
v m v
t m v
f

eval (NWith   m v
scope  m v
body) = forall v (m :: * -> *). MonadEval v m => m v -> m v -> m v
evalWith m v
scope m v
body

eval (NAssert m v
cond   m v
body) =
  do
    v
x <- m v
cond
    forall v (m :: * -> *). MonadEval v m => v -> m v -> m v
evalAssert v
x m v
body

eval (NAbs    Params (m v)
params m v
body) = do
  -- It is the environment at the definition site, not the call site, that
  -- needs to be used when evaluating the body and default arguments, hence we
  -- defer here so the present scope is restored when the parameters and body
  -- are forced during application.
  Scopes m v
curScope <- forall a (m :: * -> *). Scoped a m => m (Scopes m a)
askScopes
  let
    withCurScope :: m r -> m r
withCurScope = forall a (m :: * -> *) r. Scoped a m => Scopes m a -> m r -> m r
withScopes Scopes m v
curScope

    fun :: m v -> (AttrSet (m v) -> m v -> m r) -> m r
    fun :: forall r. m v -> (AttrSet (m v) -> m v -> m r) -> m r
fun m v
arg AttrSet (m v) -> m v -> m r
k =
      forall {r}. m r -> m r
withCurScope forall a b. (a -> b) -> a -> b
$
        do
          (coerce :: forall a b. Coercible a b => a -> b
coerce -> Scope v
newScopeToAdd) <- forall v (m :: * -> *).
MonadNixEval v m =>
Params (m v) -> m v -> m (AttrSet v)
buildArgument Params (m v)
params m v
arg
          forall a (m :: * -> *) r. Scoped a m => Scope a -> m r -> m r
pushScope
            Scope v
newScopeToAdd forall a b. (a -> b) -> a -> b
$
            AttrSet (m v) -> m v -> m r
k
              (coerce :: forall a b. Coercible a b => a -> b
coerce forall a b. (a -> b) -> a -> b
$ forall {r}. m r -> m r
withCurScope forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall v (m :: * -> *). MonadValue v m => v -> m v
inform forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Scope v
newScopeToAdd)
              m v
body

  forall v (m :: * -> *).
MonadEval v m =>
Params (m v)
-> (forall a.
    m v -> (AttrSet (m v) -> m v -> m (a, v)) -> m (a, v))
-> m v
evalAbs
    Params (m v)
params
    forall r. m v -> (AttrSet (m v) -> m v -> m r) -> m r
fun

eval (NSynHole VarName
name) = forall v (m :: * -> *). MonadEval v m => VarName -> m v
synHole VarName
name

-- | If you know that the 'scope' action will result in an 'AttrSet v', then
--   this implementation may be used as an implementation for 'evalWith'.
evalWithAttrSet :: forall v m . MonadNixEval v m => m v -> m v -> m v
evalWithAttrSet :: forall v (m :: * -> *). MonadNixEval v m => m v -> m v -> m v
evalWithAttrSet m v
aset m v
body = do
  Scopes m v
scopes <- forall a (m :: * -> *). Scoped a m => m (Scopes m a)
askScopes
  -- The scope is deliberately wrapped in a thunk here, since it is demanded
  -- each time a name is looked up within the weak scope, and we want to be
  -- sure the action it evaluates is to force a thunk, so its value is only
  -- computed once.
  v
deferredAset <- forall v (m :: * -> *). MonadValue v m => m v -> m v
defer forall a b. (a -> b) -> a -> b
$ forall a (m :: * -> *) r. Scoped a m => Scopes m a -> m r -> m r
withScopes Scopes m v
scopes m v
aset
  let weakscope :: m (Scope v)
weakscope = coerce :: forall a b. Coercible a b => a -> b
coerce forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a b. (a, b) -> a
fst forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> (forall a (m :: * -> *) v. FromValue a m v => v -> m a
fromValue @(AttrSet v, PositionSet) forall (m :: * -> *) a b. Monad m => (a -> m b) -> m a -> m b
=<< forall v (m :: * -> *). MonadValue v m => v -> m v
demand v
deferredAset)

  forall (m :: * -> *) a r.
(Functor m, Scoped a m) =>
m (Scope a) -> m r -> m r
pushWeakScope m (Scope v)
weakscope m v
body

attrSetAlter
  :: forall v m
   . MonadNixEval v m
  => [VarName]
  -> NSourcePos
  -> AttrSet (m v)
  -> PositionSet
  -> m v
  -> m (AttrSet (m v), PositionSet)
attrSetAlter :: forall v (m :: * -> *).
MonadNixEval v m =>
[VarName]
-> NSourcePos
-> AttrSet (m v)
-> PositionSet
-> m v
-> m (AttrSet (m v), PositionSet)
attrSetAlter [VarName]
ks' NSourcePos
pos AttrSet (m v)
m' PositionSet
p' m v
val =
  forall a b. (a, b) -> (b, a)
swap forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> PositionSet
-> AttrSet (m v) -> [VarName] -> m (PositionSet, AttrSet (m v))
go PositionSet
p' AttrSet (m v)
m' [VarName]
ks'
 where
  -- This `go` does traverse in disquise. Notice how it traverses `ks`.
  go
    :: PositionSet
    -> AttrSet (m v)
    -> [VarName]
    -> m (PositionSet, AttrSet (m v))
  go :: PositionSet
-> AttrSet (m v) -> [VarName] -> m (PositionSet, AttrSet (m v))
go PositionSet
_ AttrSet (m v)
_ [] = forall v (m :: * -> *) s a.
(MonadEval v m, Exception s) =>
s -> m a
evalError @v forall a b. (a -> b) -> a -> b
$ String -> ErrorCall
ErrorCall String
"invalid selector with no components"
  go PositionSet
p AttrSet (m v)
m (VarName
k : [VarName]
ks) =
    forall a. a -> a -> Bool -> a
bool
      (forall (f :: * -> *) a. Applicative f => a -> f a
pure forall a b. (a -> b) -> a -> b
$ m v -> (PositionSet, AttrSet (m v))
insertVal m v
val)
      (forall b a. b -> (a -> b) -> Maybe a -> b
maybe
        (PositionSet -> AttrSet (m v) -> m (PositionSet, AttrSet (m v))
recurse forall a. Monoid a => a
mempty forall a. Monoid a => a
mempty)
        (\m v
x ->
          do
            --  2021-10-12: NOTE: swapping sourcewide into (PositionSet, AttrSet) would optimize code and remove this `swap`
            (forall a b. (a, b) -> (b, a)
swap -> (PositionSet
sp, AttrSet v
st)) <- forall a (m :: * -> *) v. FromValue a m v => v -> m a
fromValue @(AttrSet v, PositionSet) forall (m :: * -> *) a b. Monad m => (a -> m b) -> m a -> m b
=<< m v
x
            PositionSet -> AttrSet (m v) -> m (PositionSet, AttrSet (m v))
recurse PositionSet
sp forall a b. (a -> b) -> a -> b
$ forall v (m :: * -> *). MonadValue v m => v -> m v
demand forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> AttrSet v
st
        )
        ((forall k v. (Eq k, Hashable k) => k -> HashMap k v -> Maybe v
`M.lookup` AttrSet (m v)
m) VarName
k)
      )
      (forall (t :: * -> *) a. Foldable t => t a -> Bool
isPresent [VarName]
ks)
   where
    insertVal :: m v -> (PositionSet, AttrSet (m v))
    insertVal :: m v -> (PositionSet, AttrSet (m v))
insertVal m v
v =
      ( PositionSet
insertPos
      , m v -> AttrSet (m v)
insertV m v
v
      )
     where
      insertV :: m v -> AttrSet (m v)
insertV m v
v' = forall k v.
(Eq k, Hashable k) =>
k -> v -> HashMap k v -> HashMap k v
M.insert VarName
k m v
v' AttrSet (m v)
m
      insertPos :: PositionSet
insertPos = forall k v.
(Eq k, Hashable k) =>
k -> v -> HashMap k v -> HashMap k v
M.insert VarName
k NSourcePos
pos PositionSet
p

    recurse
      :: PositionSet
      -> AttrSet (m v)
      -> m ( PositionSet
          , AttrSet (m v)
          )
    recurse :: PositionSet -> AttrSet (m v) -> m (PositionSet, AttrSet (m v))
recurse PositionSet
p'' AttrSet (m v)
m'' =
      m v -> (PositionSet, AttrSet (m v))
insertVal forall b c a. (b -> c) -> (a -> b) -> a -> c
. ((forall a (m :: * -> *) v. ToValue a m v => a -> m v
toValue @(AttrSet v, PositionSet)) forall (m :: * -> *) b c a.
Monad m =>
(b -> m c) -> (a -> m b) -> a -> m c
<=< ((,forall a. Monoid a => a
mempty) forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$>) forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall (t :: * -> *) (f :: * -> *) a.
(Traversable t, Applicative f) =>
t (f a) -> f (t a)
sequenceA forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a b. (a, b) -> b
snd) forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> PositionSet
-> AttrSet (m v) -> [VarName] -> m (PositionSet, AttrSet (m v))
go PositionSet
p'' AttrSet (m v)
m'' [VarName]
ks

desugarBinds :: forall r . ([Binding r] -> r) -> [Binding r] -> [Binding r]
desugarBinds :: forall r. ([Binding r] -> r) -> [Binding r] -> [Binding r]
desugarBinds [Binding r] -> r
embed = (forall s a. State s a -> s -> a
`evalState` forall a. Monoid a => a
mempty) forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall (t :: * -> *) (f :: * -> *) a b.
(Traversable t, Applicative f) =>
(a -> f b) -> t a -> f (t b)
traverse (Either VarName (Binding r)
-> StateT (AttrSet (NSourcePos, [Binding r])) Identity (Binding r)
findBinding forall (m :: * -> *) b c a.
Monad m =>
(b -> m c) -> (a -> m b) -> a -> m c
<=< Binding r
-> State
     (AttrSet (NSourcePos, [Binding r])) (Either VarName (Binding r))
collect)
 where
  collect
    :: Binding r
    -> State
         (AttrSet (NSourcePos, [Binding r]))
         (Either VarName (Binding r))
  collect :: Binding r
-> State
     (AttrSet (NSourcePos, [Binding r])) (Either VarName (Binding r))
collect (NamedVar (StaticKey VarName
x :| NKeyName r
y : [NKeyName r]
ys) r
val NSourcePos
oldPosition) =
    do
      forall s (m :: * -> *). MonadState s m => (s -> s) -> m ()
modify AttrSet (NSourcePos, [Binding r])
-> AttrSet (NSourcePos, [Binding r])
updateBindingInformation
      pure $ forall a b. a -> Either a b
Left VarName
x
   where
    updateBindingInformation
      :: AttrSet (NSourcePos, [Binding r])
      -> AttrSet (NSourcePos, [Binding r])
    updateBindingInformation :: AttrSet (NSourcePos, [Binding r])
-> AttrSet (NSourcePos, [Binding r])
updateBindingInformation =
      forall k v.
(Eq k, Hashable k) =>
k -> v -> HashMap k v -> HashMap k v
M.insert VarName
x
        forall (m :: * -> *) a b. Monad m => (a -> m b) -> m a -> m b
=<< forall b a. b -> (a -> b) -> Maybe a -> b
maybe
            (NSourcePos -> (NSourcePos, [Binding r])
mkBindingSingleton NSourcePos
oldPosition)
            (\ (NSourcePos
foundPosition, [Binding r]
newBindings) -> forall (p :: * -> * -> *) b c a.
Bifunctor p =>
(b -> c) -> p a b -> p a c
second (forall a. Semigroup a => a -> a -> a
<> [Binding r]
newBindings) forall a b. (a -> b) -> a -> b
$ NSourcePos -> (NSourcePos, [Binding r])
mkBindingSingleton NSourcePos
foundPosition)
            forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall k v. (Eq k, Hashable k) => k -> HashMap k v -> Maybe v
M.lookup VarName
x
    mkBindingSingleton :: NSourcePos -> (NSourcePos, [Binding r])
    mkBindingSingleton :: NSourcePos -> (NSourcePos, [Binding r])
mkBindingSingleton NSourcePos
np = (NSourcePos
np , forall x. One x => OneItem x -> x
one forall a b. (a -> b) -> a -> b
$ NSourcePos -> Binding r
bindValAt NSourcePos
np)
     where
      bindValAt :: NSourcePos -> Binding r
      bindValAt :: NSourcePos -> Binding r
bindValAt = forall r. NAttrPath r -> r -> NSourcePos -> Binding r
NamedVar (NKeyName r
y forall a. a -> [a] -> NonEmpty a
:| [NKeyName r]
ys) r
val
  collect Binding r
x = forall (f :: * -> *) a. Applicative f => a -> f a
pure forall a b. (a -> b) -> a -> b
$ forall (f :: * -> *) a. Applicative f => a -> f a
pure Binding r
x

  findBinding
    :: Either VarName (Binding r)
    -> State (AttrSet (NSourcePos, [Binding r])) (Binding r)
  findBinding :: Either VarName (Binding r)
-> StateT (AttrSet (NSourcePos, [Binding r])) Identity (Binding r)
findBinding =
    forall a c b. (a -> c) -> (b -> c) -> Either a b -> c
either
      (\ VarName
x ->
        forall b a. b -> (a -> b) -> Maybe a -> b
maybe
          (forall a t. (HasCallStack, IsText t) => t -> a
error forall a b. (a -> b) -> a -> b
$ Text
"No binding " forall a. Semigroup a => a -> a -> a
<> forall b a. (Show a, IsString b) => a -> b
show VarName
x)
          (\ (NSourcePos
p, [Binding r]
v) -> forall (f :: * -> *) a. Applicative f => a -> f a
pure forall a b. (a -> b) -> a -> b
$ forall r. NAttrPath r -> r -> NSourcePos -> Binding r
NamedVar (forall x. One x => OneItem x -> x
one forall a b. (a -> b) -> a -> b
$ forall r. VarName -> NKeyName r
StaticKey VarName
x) ([Binding r] -> r
embed [Binding r]
v) NSourcePos
p)
          forall (m :: * -> *) a b. Monad m => (a -> m b) -> m a -> m b
=<< forall s (m :: * -> *) a. MonadState s m => (s -> a) -> m a
gets (forall k v. (Eq k, Hashable k) => k -> HashMap k v -> Maybe v
M.lookup VarName
x)
      )
      forall (f :: * -> *) a. Applicative f => a -> f a
pure

evalBinds
  :: forall v m
   . MonadNixEval v m
--  2021-07-19: NOTE: Recutsivity data type
  => Bool
  -> [Binding (m v)]
--  2021-07-19: NOTE: AttrSet is a Scope
  -> m (AttrSet v, PositionSet)
evalBinds :: forall v (m :: * -> *).
MonadNixEval v m =>
Bool -> [Binding (m v)] -> m (AttrSet v, PositionSet)
evalBinds Bool
isRecursive [Binding (m v)]
binds =
  do
    Scopes m v
scope <- forall a (m :: * -> *). Scoped a m => m (Scopes m a)
askScopes

    Scopes m v
-> [([VarName], NSourcePos, m v)]
-> m (HashMap VarName v, PositionSet)
buildResult Scopes m v
scope forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall (t :: * -> *) m. (Foldable t, Monoid m) => t m -> m
fold forall (m :: * -> *) a b. Monad m => (a -> m b) -> m a -> m b
=<< (forall (t :: * -> *) (f :: * -> *) a b.
(Traversable t, Applicative f) =>
(a -> f b) -> t a -> f (t b)
`traverse` forall {r}. [Binding r] -> [Binding r]
moveOverridesLast [Binding (m v)]
binds) (Scopes m v -> Binding (m v) -> m [([VarName], NSourcePos, m v)]
applyBindToAdt Scopes m v
scope)

 where
  buildResult
    :: Scopes m v
    -> [([VarName], NSourcePos, m v)]
    -> m (AttrSet v, PositionSet)
  buildResult :: Scopes m v
-> [([VarName], NSourcePos, m v)]
-> m (HashMap VarName v, PositionSet)
buildResult Scopes m v
scopes [([VarName], NSourcePos, m v)]
bindings =
    do
      (coerce :: forall a b. Coercible a b => a -> b
coerce -> Scope (m v)
scope, PositionSet
p) <- forall (t :: * -> *) (m :: * -> *) b a.
(Foldable t, Monad m) =>
(b -> a -> m b) -> b -> t a -> m b
foldM (AttrSet (m v), PositionSet)
-> ([VarName], NSourcePos, m v) -> m (AttrSet (m v), PositionSet)
insert forall a. Monoid a => a
mempty [([VarName], NSourcePos, m v)]
bindings
      Scope v
res <-
        forall a. a -> a -> Bool -> a
bool
          (forall (t :: * -> *) (f :: * -> *) a b.
(Traversable t, Applicative f) =>
(a -> f b) -> t a -> f (t b)
traverse m v -> m v
mkThunk)
          (forall (m :: * -> *) (t :: * -> *) a.
(MonadFix m, Traversable t) =>
t (t a -> m a) -> m (t a)
loebM forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap forall {a}. Scoped a m => m v -> Scope a -> m v
encapsulate)
          Bool
isRecursive
          Scope (m v)
scope

      pure (coerce :: forall a b. Coercible a b => a -> b
coerce Scope v
res, PositionSet
p)

   where
    insert :: (AttrSet (m v), PositionSet) -> ([VarName], NSourcePos, m v) -> m (AttrSet (m v), PositionSet)
    insert :: (AttrSet (m v), PositionSet)
-> ([VarName], NSourcePos, m v) -> m (AttrSet (m v), PositionSet)
insert (AttrSet (m v)
m, PositionSet
p) ([VarName]
path, NSourcePos
pos, m v
value) = forall v (m :: * -> *).
MonadNixEval v m =>
[VarName]
-> NSourcePos
-> AttrSet (m v)
-> PositionSet
-> m v
-> m (AttrSet (m v), PositionSet)
attrSetAlter [VarName]
path NSourcePos
pos AttrSet (m v)
m PositionSet
p m v
value

    mkThunk :: m v -> m v
mkThunk = forall v (m :: * -> *). MonadValue v m => m v -> m v
defer forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a (m :: * -> *) r. Scoped a m => Scopes m a -> m r -> m r
withScopes Scopes m v
scopes

    encapsulate :: m v -> Scope a -> m v
encapsulate m v
f Scope a
attrs = m v -> m v
mkThunk forall a b. (a -> b) -> a -> b
$ forall a (m :: * -> *) r. Scoped a m => Scope a -> m r -> m r
pushScope Scope a
attrs m v
f

  applyBindToAdt :: Scopes m v -> Binding (m v) -> m [([VarName], NSourcePos, m v)]
  applyBindToAdt :: Scopes m v -> Binding (m v) -> m [([VarName], NSourcePos, m v)]
applyBindToAdt Scopes m v
_ (NamedVar (StaticKey VarName
"__overrides" :| []) m v
finalValue NSourcePos
pos) =
    do
      (HashMap VarName v
o', PositionSet
p') <- forall a (m :: * -> *) v. FromValue a m v => v -> m a
fromValue forall (m :: * -> *) a b. Monad m => (a -> m b) -> m a -> m b
=<< m v
finalValue
      -- jww (2018-05-09): What to do with the key position here?
      forall (f :: * -> *) a. Applicative f => a -> f a
pure forall a b. (a -> b) -> a -> b
$
        (\ (VarName
k, v
v) ->
          ( forall x. One x => OneItem x -> x
one VarName
k
          , forall a. a -> Maybe a -> a
fromMaybe NSourcePos
pos forall a b. (a -> b) -> a -> b
$ forall k v. (Eq k, Hashable k) => k -> HashMap k v -> Maybe v
M.lookup VarName
k PositionSet
p'
          , forall v (m :: * -> *). MonadValue v m => v -> m v
demand v
v
          )
        ) forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> forall k v. HashMap k v -> [(k, v)]
M.toList HashMap VarName v
o'

  applyBindToAdt Scopes m v
_ (NamedVar NonEmpty (NKeyName (m v))
pathExpr m v
finalValue NSourcePos
pos) =
    (\case
      -- When there are no path segments, e.g. `${null} = 5;`, we don't
      -- bind anything
      ([], NSourcePos
_, m v
_) -> forall a. Monoid a => a
mempty
      ([VarName], NSourcePos, m v)
result     -> forall x. One x => OneItem x -> x
one ([VarName], NSourcePos, m v)
result
    ) forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> NonEmpty (NKeyName (m v)) -> m ([VarName], NSourcePos, m v)
processAttrSetKeys NonEmpty (NKeyName (m v))
pathExpr

   where
    processAttrSetKeys :: NAttrPath (m v) -> m ([VarName], NSourcePos, m v)
    processAttrSetKeys :: NonEmpty (NKeyName (m v)) -> m ([VarName], NSourcePos, m v)
processAttrSetKeys (NKeyName (m v)
h :| [NKeyName (m v)]
t) =
      forall b a. b -> (a -> b) -> Maybe a -> b
maybe
        -- Empty attrset - return a stub.
        (forall (f :: * -> *) a. Applicative f => a -> f a
pure (forall a. Monoid a => a
mempty, NSourcePos
nullPos, forall a (m :: * -> *) v. ToValue a m v => a -> m v
toValue @(AttrSet v, PositionSet) forall a. Monoid a => a
mempty) )
        (\ VarName
k ->
          forall (t :: * -> *) b a. Foldable t => b -> (t a -> b) -> t a -> b
handlePresence
            -- No more keys in the attrset - return the result
            (forall (f :: * -> *) a. Applicative f => a -> f a
pure ( forall x. One x => OneItem x -> x
one VarName
k, NSourcePos
pos, m v
finalValue ) )
            -- There are unprocessed keys in attrset - recurse appending the results
            (\ (NKeyName (m v)
x : [NKeyName (m v)]
xs) ->
              do
                ([VarName]
restOfPath, NSourcePos
_, m v
v) <- NonEmpty (NKeyName (m v)) -> m ([VarName], NSourcePos, m v)
processAttrSetKeys (NKeyName (m v)
x forall a. a -> [a] -> NonEmpty a
:| [NKeyName (m v)]
xs)
                forall (f :: * -> *) a. Applicative f => a -> f a
pure ( VarName
k forall a. a -> [a] -> [a]
: [VarName]
restOfPath, NSourcePos
pos, m v
v )
            )
            [NKeyName (m v)]
t
        )
        forall (m :: * -> *) a b. Monad m => (a -> m b) -> m a -> m b
=<< forall v (m :: * -> *).
(MonadEval v m, FromValue NixString m v) =>
NKeyName (m v) -> m (Maybe VarName)
evalSetterKeyName NKeyName (m v)
h

  applyBindToAdt Scopes m v
scopes (Inherit Maybe (m v)
ms [VarName]
names NSourcePos
pos) =
    forall (f :: * -> *) a. Applicative f => a -> f a
pure forall a b. (a -> b) -> a -> b
$ VarName -> ([VarName], NSourcePos, m v)
processScope forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> [VarName]
names
   where
    processScope
      :: VarName
      -> ([VarName], NSourcePos, m v)
    processScope :: VarName -> ([VarName], NSourcePos, m v)
processScope VarName
var =
      ( forall x. One x => OneItem x -> x
one VarName
var
      , NSourcePos
pos
      , forall b a. b -> (a -> b) -> Maybe a -> b
maybe
          (forall v (m :: * -> *).
MonadEval v m =>
NonEmpty VarName -> Maybe v -> m v
attrMissing (forall x. One x => OneItem x -> x
one VarName
var) forall a. Maybe a
Nothing)
          forall v (m :: * -> *). MonadValue v m => v -> m v
demand
          forall (m :: * -> *) a b. Monad m => (a -> m b) -> m a -> m b
=<< forall b a. b -> (a -> b) -> Maybe a -> b
maybe
              (forall a (m :: * -> *) r. Scoped a m => Scopes m a -> m r -> m r
withScopes Scopes m v
scopes forall a b. (a -> b) -> a -> b
$ forall a (m :: * -> *). Scoped a m => VarName -> m (Maybe a)
lookupVar VarName
var)
              (\ m v
s ->
                do
                  (coerce :: forall a b. Coercible a b => a -> b
coerce -> Scope v
scope, PositionSet
_) <- forall a (m :: * -> *) v. FromValue a m v => v -> m a
fromValue @(AttrSet v, PositionSet) forall (m :: * -> *) a b. Monad m => (a -> m b) -> m a -> m b
=<< m v
s

                  forall a (m :: * -> *) r. Scoped a m => m r -> m r
clearScopes forall a b. (a -> b) -> a -> b
$ forall a (m :: * -> *) r. Scoped a m => Scope a -> m r -> m r
pushScope @v Scope v
scope forall a b. (a -> b) -> a -> b
$ forall a (m :: * -> *). Scoped a m => VarName -> m (Maybe a)
lookupVar VarName
var
              )
              Maybe (m v)
ms
      )

  moveOverridesLast :: [Binding r] -> [Binding r]
moveOverridesLast = forall a b c. (a -> b -> c) -> (a, b) -> c
uncurry forall a. Semigroup a => a -> a -> a
(<>) forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a. (a -> Bool) -> [a] -> ([a], [a])
partition
    (\case
      NamedVar (StaticKey VarName
"__overrides" :| []) r
_ NSourcePos
_ -> Bool
False
      Binding r
_ -> Bool
True
    )

evalSelect
  :: forall v m
   . MonadNixEval v m
  => m v
  -> NAttrPath (m v)
  -> m (Either (v, NonEmpty VarName) (m v))
evalSelect :: forall v (m :: * -> *).
MonadNixEval v m =>
m v -> NAttrPath (m v) -> m (Either (v, NonEmpty VarName) (m v))
evalSelect m v
aset NAttrPath (m v)
attr =
  do
    v
s    <- m v
aset
    NonEmpty VarName
path <- forall (t :: * -> *) (f :: * -> *) a b.
(Traversable t, Applicative f) =>
(a -> f b) -> t a -> f (t b)
traverse forall v (m :: * -> *).
(MonadEval v m, FromValue NixString m v) =>
NKeyName (m v) -> m VarName
evalGetterKeyName NAttrPath (m v)
attr

    NonEmpty VarName -> v -> m (Either (v, NonEmpty VarName) (m v))
extract NonEmpty VarName
path v
s

 where
  extract :: NonEmpty VarName -> v -> m (Either (v, NonEmpty VarName) (m v))
  extract :: NonEmpty VarName -> v -> m (Either (v, NonEmpty VarName) (m v))
extract path :: NonEmpty VarName
path@(VarName
k :| [VarName]
ks) v
x =
    forall b a. b -> (a -> b) -> Maybe a -> b
maybe
      forall b. m (Either (v, NonEmpty VarName) b)
left
      (forall b a. b -> (a -> b) -> Maybe a -> b
maybe
        forall b. m (Either (v, NonEmpty VarName) b)
left
        (forall (t :: * -> *) b a. Foldable t => b -> (t a -> b) -> t a -> b
handlePresence
          (forall (f :: * -> *) a. Applicative f => a -> f a
pure forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall (f :: * -> *) a. Applicative f => a -> f a
pure)
          (\ (VarName
y : [VarName]
ys) -> (NonEmpty VarName -> v -> m (Either (v, NonEmpty VarName) (m v))
extract (VarName
y forall a. a -> [a] -> NonEmpty a
:| [VarName]
ys) forall (m :: * -> *) a b. Monad m => (a -> m b) -> m a -> m b
=<<))
          [VarName]
ks
          forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall v (m :: * -> *). MonadValue v m => v -> m v
demand
        )
        forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall k v. (Eq k, Hashable k) => k -> HashMap k v -> Maybe v
M.lookup VarName
k forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a b. (a, b) -> a
fst
      )
      forall (m :: * -> *) a b. Monad m => (a -> m b) -> m a -> m b
=<< forall a (m :: * -> *) v. FromValue a m v => v -> m (Maybe a)
fromValueMay @(AttrSet v, PositionSet) v
x
   where
    left :: m (Either (v, NonEmpty VarName) b)
    left :: forall b. m (Either (v, NonEmpty VarName) b)
left = forall (f :: * -> *) a. Applicative f => a -> f a
pure forall a b. (a -> b) -> a -> b
$ forall a b. a -> Either a b
Left (v
x, NonEmpty VarName
path)

-- | Evaluate a component of an attribute path in a context where we are
-- *retrieving* a value
evalGetterKeyName
  :: forall v m
   . (MonadEval v m, FromValue NixString m v)
  => NKeyName (m v)
  -> m VarName
evalGetterKeyName :: forall v (m :: * -> *).
(MonadEval v m, FromValue NixString m v) =>
NKeyName (m v) -> m VarName
evalGetterKeyName =
  forall b a. b -> (a -> b) -> Maybe a -> b
maybe
    (forall v (m :: * -> *) s a.
(MonadEval v m, Exception s) =>
s -> m a
evalError @v forall a b. (a -> b) -> a -> b
$ String -> ErrorCall
ErrorCall String
"value is null while a string was expected")
    forall (f :: * -> *) a. Applicative f => a -> f a
pure
    forall (m :: * -> *) b c a.
Monad m =>
(b -> m c) -> (a -> m b) -> a -> m c
<=< forall v (m :: * -> *).
(MonadEval v m, FromValue NixString m v) =>
NKeyName (m v) -> m (Maybe VarName)
evalSetterKeyName

-- | Evaluate a component of an attribute path in a context where we are
-- *binding* a value
evalSetterKeyName
  :: (MonadEval v m, FromValue NixString m v)
  => NKeyName (m v)
  -> m (Maybe VarName)
evalSetterKeyName :: forall v (m :: * -> *).
(MonadEval v m, FromValue NixString m v) =>
NKeyName (m v) -> m (Maybe VarName)
evalSetterKeyName =
  \case
    StaticKey VarName
k -> forall (f :: * -> *) a. Applicative f => a -> f a
pure forall a b. (a -> b) -> a -> b
$ forall (f :: * -> *) a. Applicative f => a -> f a
pure VarName
k
    DynamicKey Antiquoted (NString (m v)) (m v)
k ->
      coerce :: forall a b. Coercible a b => a -> b
coerce forall b c a. (b -> c) -> (a -> b) -> a -> c
. NixString -> Text
ignoreContext forall (f :: * -> *) (g :: * -> *) a b.
(Functor f, Functor g) =>
(a -> b) -> f (g a) -> f (g b)
<<$>> forall v a r. v -> (v -> a) -> (r -> a) -> Antiquoted v r -> a
runAntiquoted NString (m v)
"\n" forall v (m :: * -> *).
(MonadEval v m, FromValue NixString m v) =>
NString (m v) -> m (Maybe NixString)
assembleString (forall a (m :: * -> *) v. FromValue a m v => v -> m (Maybe a)
fromValueMay forall (m :: * -> *) a b. Monad m => (a -> m b) -> m a -> m b
=<<) Antiquoted (NString (m v)) (m v)
k

assembleString
  :: forall v m
   . (MonadEval v m, FromValue NixString m v)
  => NString (m v)
  -> m (Maybe NixString)
assembleString :: forall v (m :: * -> *).
(MonadEval v m, FromValue NixString m v) =>
NString (m v) -> m (Maybe NixString)
assembleString = [Antiquoted Text (m v)] -> m (Maybe NixString)
fromParts forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall r. NString r -> [Antiquoted Text r]
stringParts
 where
  fromParts :: [Antiquoted Text (m v)] -> m (Maybe NixString)
  fromParts :: [Antiquoted Text (m v)] -> m (Maybe NixString)
fromParts [Antiquoted Text (m v)]
xs = forall (t :: * -> *) m. (Foldable t, Monoid m) => t m -> m
fold forall (f :: * -> *) (g :: * -> *) a b.
(Functor f, Functor g) =>
(a -> b) -> f (g a) -> f (g b)
<<$>> forall (m :: * -> *) (n :: * -> *) (t :: * -> *) a b.
(Applicative m, Applicative n, Traversable t) =>
(a -> m (n b)) -> t a -> m (n (t b))
traverse2 Antiquoted Text (m v) -> m (Maybe NixString)
fun [Antiquoted Text (m v)]
xs

  fun :: Antiquoted Text (m v) -> m (Maybe NixString)
  fun :: Antiquoted Text (m v) -> m (Maybe NixString)
fun =
    forall v a r. v -> (v -> a) -> (r -> a) -> Antiquoted v r -> a
runAntiquoted
      Text
"\n"
      (forall (f :: * -> *) a. Applicative f => a -> f a
pure forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall (f :: * -> *) a. Applicative f => a -> f a
pure forall b c a. (b -> c) -> (a -> b) -> a -> c
. Text -> NixString
mkNixStringWithoutContext)
      (forall a (m :: * -> *) v. FromValue a m v => v -> m (Maybe a)
fromValueMay forall (m :: * -> *) a b. Monad m => (a -> m b) -> m a -> m b
=<<)

buildArgument
  :: forall v m . MonadNixEval v m => Params (m v) -> m v -> m (AttrSet v)
buildArgument :: forall v (m :: * -> *).
MonadNixEval v m =>
Params (m v) -> m v -> m (AttrSet v)
buildArgument Params (m v)
params m v
arg =
  do
    Scopes m v
scope <- forall a (m :: * -> *). Scoped a m => m (Scopes m a)
askScopes
    let
      argThunk :: m v
argThunk = forall v (m :: * -> *). MonadValue v m => m v -> m v
defer forall a b. (a -> b) -> a -> b
$ forall a (m :: * -> *) r. Scoped a m => Scopes m a -> m r -> m r
withScopes Scopes m v
scope m v
arg
    case Params (m v)
params of
      Param VarName
name -> forall x. One x => OneItem x -> x
one forall b c a. (b -> c) -> (a -> b) -> a -> c
. (VarName
name,) forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> m v
argThunk
      ParamSet Maybe VarName
mname Variadic
variadic ParamSet (m v)
pset ->
        do
          (AttrSet v
args, PositionSet
_) <- forall a (m :: * -> *) v. FromValue a m v => v -> m a
fromValue @(AttrSet v, PositionSet) forall (m :: * -> *) a b. Monad m => (a -> m b) -> m a -> m b
=<< m v
arg
          let
            inject :: HashMap VarName (b -> m v) -> HashMap VarName (b -> m v)
inject =
              forall b a. b -> (a -> b) -> Maybe a -> b
maybe
                forall a. a -> a
id
                (forall k v.
(Eq k, Hashable k) =>
k -> v -> HashMap k v -> HashMap k v
`M.insert` forall a b. a -> b -> a
const m v
argThunk) -- why insert into const? Thunk value getting magic point?
                Maybe VarName
mname
          forall (m :: * -> *) (t :: * -> *) a.
(MonadFix m, Traversable t) =>
t (t a -> m a) -> m (t a)
loebM forall a b. (a -> b) -> a -> b
$
            forall {b}.
HashMap VarName (b -> m v) -> HashMap VarName (b -> m v)
inject forall a b. (a -> b) -> a -> b
$
              forall v1 v2 k. (v1 -> Maybe v2) -> HashMap k v1 -> HashMap k v2
M.mapMaybe
                forall a. a -> a
id
                forall a b. (a -> b) -> a -> b
$ forall i (f :: * -> *) a b c.
SemialignWithIndex i f =>
(i -> These a b -> c) -> f a -> f b -> f c
ialignWith
                    (Scopes m v
-> Variadic
-> VarName
-> These v (Maybe (m v))
-> Maybe (AttrSet v -> m v)
assemble Scopes m v
scope Variadic
variadic)
                    AttrSet v
args
                    forall a b. (a -> b) -> a -> b
$ forall k v. (Eq k, Hashable k) => [(k, v)] -> HashMap k v
M.fromList ParamSet (m v)
pset
 where
  assemble
    :: Scopes m v
    -> Variadic
    -> VarName
    -> These v (Maybe (m v))
    -> Maybe (AttrSet v -> m v)
  assemble :: Scopes m v
-> Variadic
-> VarName
-> These v (Maybe (m v))
-> Maybe (AttrSet v -> m v)
assemble Scopes m v
_ Variadic
Variadic VarName
_ (This v
_) = forall a. Maybe a
Nothing
  assemble Scopes m v
scope Variadic
_ VarName
k These v (Maybe (m v))
t =
    forall (f :: * -> *) a. Applicative f => a -> f a
pure forall a b. (a -> b) -> a -> b
$
      case These v (Maybe (m v))
t of
        That Maybe (m v)
Nothing -> forall a b. a -> b -> a
const forall a b. (a -> b) -> a -> b
$ forall v (m :: * -> *) s a.
(MonadEval v m, Exception s) =>
s -> m a
evalError @v forall a b. (a -> b) -> a -> b
$ String -> ErrorCall
ErrorCall forall a b. (a -> b) -> a -> b
$ String
"Missing value for parameter: ''" forall a. Semigroup a => a -> a -> a
<> forall b a. (Show a, IsString b) => a -> b
show VarName
k
        That (Just m v
f) -> coerce :: forall a b. Coercible a b => a -> b
coerce forall a b. (a -> b) -> a -> b
$ forall v (m :: * -> *). MonadValue v m => m v -> m v
defer forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a (m :: * -> *) r. Scoped a m => Scopes m a -> m r -> m r
withScopes Scopes m v
scope forall b c a. (b -> c) -> (a -> b) -> a -> c
. (forall a (m :: * -> *) r. Scoped a m => Scope a -> m r -> m r
`pushScope` m v
f)
        This v
_ -> forall a b. a -> b -> a
const forall a b. (a -> b) -> a -> b
$ forall v (m :: * -> *) s a.
(MonadEval v m, Exception s) =>
s -> m a
evalError @v forall a b. (a -> b) -> a -> b
$ String -> ErrorCall
ErrorCall forall a b. (a -> b) -> a -> b
$ String
"Unexpected parameter: " forall a. Semigroup a => a -> a -> a
<> forall b a. (Show a, IsString b) => a -> b
show VarName
k
        These v
x Maybe (m v)
_ -> forall a b. a -> b -> a
const forall a b. (a -> b) -> a -> b
$ forall (f :: * -> *) a. Applicative f => a -> f a
pure v
x

-- | Add source positions to @NExprLoc@.
--
-- Takes @NExprLoc@, by itself takes source position informatoin, does transformation,
-- returns @NExprLoc@ with source positions.
--
-- Actually:
--
-- > => (NExprLoc -> m a)
-- > -> NExprLoc -> m a
addSourcePositions
  :: (MonadReader e m, Has e SrcSpan) => Transform NExprLocF (m a)
addSourcePositions :: forall e (m :: * -> *) a.
(MonadReader e m, Has e SrcSpan) =>
Transform (Compose (AnnUnit SrcSpan) NExprF) (m a)
addSourcePositions NExprLoc -> m a
f (v :: NExprLoc
v@(Ann SrcSpan
ann NExprF NExprLoc
_) :: NExprLoc) =
  forall r (m :: * -> *) a. MonadReader r m => (r -> r) -> m a -> m a
local (forall s a. Lens' s a -> a -> s -> s
set forall a b. Has a b => Lens' a b
hasLens SrcSpan
ann) forall a b. (a -> b) -> a -> b
$ NExprLoc -> m a
f NExprLoc
v

addStackFrames
  :: forall v e m a
   . (Scoped v m, Framed e m, Typeable v, Typeable m)
  => TransformF NExprLoc (m a)
addStackFrames :: forall v e (m :: * -> *) a.
(Scoped v m, Framed e m, Typeable v, Typeable m) =>
TransformF NExprLoc (m a)
addStackFrames NExprLoc -> m a
f NExprLoc
v =
  do
    Scopes m v
scopes <- forall a (m :: * -> *). Scoped a m => m (Scopes m a)
askScopes

    -- sectioning gives GHC optimization
    -- If opimization question would arrive again, check the @(`withFrameInfo` f v) $ EvaluatingExpr scopes v@
    -- for possible @scopes@ implementation @v@ type arguments sharing between runs.
    (forall {a}. EvalFrame m v -> m a -> m a
`withFrameInfo` NExprLoc -> m a
f NExprLoc
v) forall a b. (a -> b) -> a -> b
$ (forall (m :: * -> *) v. Scopes m v -> NExprLoc -> EvalFrame m v
`EvaluatingExpr` NExprLoc
v) Scopes m v
scopes
 where
  withFrameInfo :: EvalFrame m v -> m a -> m a
withFrameInfo = forall s e (m :: * -> *) a.
(Framed e m, Exception s) =>
NixLevel -> s -> m a -> m a
withFrame NixLevel
Info

evalWithMetaInfo
  :: forall e v m
  . (MonadNixEval v m, Framed e m, Has e SrcSpan, Typeable m, Typeable v)
  => NExprLoc
  -> m v
evalWithMetaInfo :: forall e v (m :: * -> *).
(MonadNixEval v m, Framed e m, Has e SrcSpan, Typeable m,
 Typeable v) =>
NExprLoc -> m v
evalWithMetaInfo =
  forall (f :: * -> *) a.
Functor f =>
Transform f a -> Alg f a -> Fix f -> a
adi forall v (m :: * -> *) e a.
(Framed e m, Scoped v m, Has e SrcSpan, Typeable m, Typeable v) =>
TransformF NExprLoc (m a)
addMetaInfo forall v (m :: * -> *) ann.
MonadNixEval v m =>
AnnF ann NExprF (m v) -> m v
evalContent

-- | Add source positions & frame context system.
addMetaInfo
  :: forall v m e a
  . (Framed e m, Scoped v m, Has e SrcSpan, Typeable m, Typeable v)
  => TransformF NExprLoc (m a)
addMetaInfo :: forall v (m :: * -> *) e a.
(Framed e m, Scoped v m, Has e SrcSpan, Typeable m, Typeable v) =>
TransformF NExprLoc (m a)
addMetaInfo = forall v e (m :: * -> *) a.
(Scoped v m, Framed e m, Typeable v, Typeable m) =>
TransformF NExprLoc (m a)
addStackFrames @v forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall e (m :: * -> *) a.
(MonadReader e m, Has e SrcSpan) =>
Transform (Compose (AnnUnit SrcSpan) NExprF) (m a)
addSourcePositions

-- | Takes annotated expression. Strip from annotation. Evaluate.
evalContent
  :: MonadNixEval v m
  => AnnF ann NExprF (m v)
  -> m v
evalContent :: forall v (m :: * -> *) ann.
MonadNixEval v m =>
AnnF ann NExprF (m v) -> m v
evalContent = forall v (m :: * -> *). MonadNixEval v m => NExprF (m v) -> m v
eval forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall ann (f :: * -> *) r. AnnF ann f r -> f r
stripAnnF