From bddc83a1487e9f3c1bb3ac2279c0238e8e6c3ff3 Mon Sep 17 00:00:00 2001 From: Eelco Dolstra Date: Wed, 16 May 2007 16:17:04 +0000 Subject: [PATCH] * New builtin function "isFunction". You're not supposed to use it ;-) * Channels: fix channels that are plain lists of derivations (like strategoxt-unstable) instead of functions (like nixpkgs-unstable). This fixes the error message "error: the left-hand side of the function call is neither a function nor a primop (built-in operation) but a list". --- corepkgs/channels/unpack.sh.in | 2 +- src/libexpr/eval.cc | 2 +- src/libexpr/primops.cc | 13 +++++++++++++ 3 files changed, 15 insertions(+), 2 deletions(-) diff --git a/corepkgs/channels/unpack.sh.in b/corepkgs/channels/unpack.sh.in index 03c6e5b2f8..1f2886a6ab 100644 --- a/corepkgs/channels/unpack.sh.in +++ b/corepkgs/channels/unpack.sh.in @@ -24,7 +24,7 @@ for ((n = 0; n < ${#inputs[*]}; n += 2)); do @coreutils@/mv * ../$dirName # !!! hacky attrName=$(echo $dirName | @tr@ -- '- ' '__') - echo "$attrName = import ./$dirName {};" >> $expr + echo "$attrName = let e = import ./$dirName; in if builtins.isFunction e then e {} else e;" >> $expr done echo '} // {_combineChannels = true;}' >> $expr diff --git a/src/libexpr/eval.cc b/src/libexpr/eval.cc index 552b586250..a8a22e2f2c 100644 --- a/src/libexpr/eval.cc +++ b/src/libexpr/eval.cc @@ -478,7 +478,7 @@ LocalNoInline(Expr evalCall(EvalState & state, Expr fun, Expr arg)) } else throwTypeError( - "the left-hand side of the function call is neither a function nor a primop (built-in operation) but %1%", + "attempt to call something which is neither a function nor a primop (built-in operation) but %1%", showType(fun)); } diff --git a/src/libexpr/primops.cc b/src/libexpr/primops.cc index c7fbca0bb5..95440c9bf6 100644 --- a/src/libexpr/primops.cc +++ b/src/libexpr/primops.cc @@ -114,6 +114,18 @@ static Expr prim_isNull(EvalState & state, const ATermVector & args) } +/* Determine whether the argument is a function. */ +static Expr prim_isFunction(EvalState & state, const ATermVector & args) +{ + Expr e = evalExpr(state, args[0]); + ATermList formals; + ATerm name, body, pos; + return makeBool( + matchFunction(e, formals, body, pos) || + matchFunction1(e, name, body, pos)); +} + + static Path findDependency(Path dir, string dep) { if (dep[0] == '/') throw EvalError( @@ -884,6 +896,7 @@ void EvalState::addPrimOps() // Miscellaneous addPrimOp("import", 1, prim_import); addPrimOp("isNull", 1, prim_isNull); + addPrimOp("__isFunction", 1, prim_isFunction); addPrimOp("dependencyClosure", 1, prim_dependencyClosure); addPrimOp("abort", 1, prim_abort); addPrimOp("throw", 1, prim_throw);