implement evaluation for HasAttr

This commit is contained in:
Anders Papitto 2015-12-13 13:23:17 -08:00
parent 9d33172ba4
commit 5a7991f5b6
2 changed files with 13 additions and 8 deletions

View File

@ -75,7 +75,12 @@ evalExpr = cata phi
_ -> error $ "unsupported argument types for binary operator " ++ show op
phi (NSelect _x _attr _or) = error "Select expressions are not yet supported"
phi (NHasAttr _x _attr) = error "Has attr expressions are not yet supported"
phi (NHasAttr aset attr) = \env -> aset env >>= \case
Fix (NVSet s) -> evalSelector True env attr >>= \case
[keyName] -> pure $ Fix $ NVConstant $ NBool $ keyName `Map.member` s
_ -> error $ "attribute name argument to hasAttr is not a single-part name"
_ -> error $ "argument to hasAttr has wrong type"
phi (NList l) = \env ->
Fix . NVList <$> mapM ($ env) l
@ -162,9 +167,9 @@ evalBinds allowDynamic env xs = buildResult <$> sequence (concatMap go xs) where
go (NamedVar x y) = [liftM2 (,) (evalSelector allowDynamic env x) (y env)]
go _ = [] -- HACK! But who cares right now
evalSelector :: Bool -> NValue -> NSelector (NValue -> IO NValue) -> IO [Text]
evalSelector dyn e = mapM evalKeyName where
evalKeyName (StaticKey k) = return k
evalKeyName (DynamicKey k)
| dyn = runAntiquoted (evalString e) (fmap valueText . ($ e)) k
| otherwise = error "dynamic attribute not allowed in this context"
evalSelector :: Bool -> NValue -> NSelector (NValue -> IO NValue) -> IO [Text]
evalSelector dyn e = mapM evalKeyName where
evalKeyName (StaticKey k) = return k
evalKeyName (DynamicKey k)
| dyn = runAntiquoted (evalString e) (fmap valueText . ($ e)) k
| otherwise = error "dynamic attribute not allowed in this context"

View File

@ -151,7 +151,7 @@ instance IsString (NString r) where
fromString "" = NString DoubleQuoted []
fromString x = NString DoubleQuoted . (:[]) . Plain . pack $ x
-- | A 'KeyName' is something that can appear at the right side of an equals sign.
-- | A 'KeyName' is something that can appear on the left side of an equals sign.
-- For example, @a@ is a 'KeyName' in @{ a = 3; }@, @let a = 3; in ...@, @{}.a@ or @{} ? a@.
--
-- Nix supports both static keynames (just an identifier) and dynamic identifiers.