* Implemented the primops necessary for generating the NixOS manual.
This commit is contained in:
parent
a353aef0b1
commit
fc92244ba8
8 changed files with 160 additions and 146 deletions
|
@ -16,7 +16,8 @@ void doTest(string s)
|
||||||
Expr e = parseExprFromString(state, s, absPath("."));
|
Expr e = parseExprFromString(state, s, absPath("."));
|
||||||
printMsg(lvlError, format(">>>>> %1%") % e);
|
printMsg(lvlError, format(">>>>> %1%") % e);
|
||||||
Value v;
|
Value v;
|
||||||
state.strictEval(e, v);
|
state.eval(e, v);
|
||||||
|
state.strictForceValue(v);
|
||||||
printMsg(lvlError, format("result: %1%") % v);
|
printMsg(lvlError, format("result: %1%") % v);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -76,6 +77,8 @@ void run(Strings args)
|
||||||
doTest("let x = 1; as = rec { inherit x; y = as.x; }; in as.y");
|
doTest("let x = 1; as = rec { inherit x; y = as.x; }; in as.y");
|
||||||
doTest("let as = { x = 1; }; bs = rec { inherit (as) x; y = x; }; in bs.y");
|
doTest("let as = { x = 1; }; bs = rec { inherit (as) x; y = x; }; in bs.y");
|
||||||
doTest("let as = rec { inherit (y) x; y = { x = 1; }; }; in as.x");
|
doTest("let as = rec { inherit (y) x; y = { x = 1; }; }; in as.x");
|
||||||
|
doTest("builtins.toXML 123");
|
||||||
|
doTest("builtins.toXML { a.b = \"x\" + \"y\"; c = [ 1 2 ] ++ [ 3 4 ]; }");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -302,6 +302,8 @@ void EvalState::eval(Env & env, Expr e, Value & v)
|
||||||
|
|
||||||
//debug(format("eval: %1%") % e);
|
//debug(format("eval: %1%") % e);
|
||||||
|
|
||||||
|
checkInterrupt();
|
||||||
|
|
||||||
nrEvaluated++;
|
nrEvaluated++;
|
||||||
|
|
||||||
Sym name;
|
Sym name;
|
||||||
|
@ -639,28 +641,6 @@ bool EvalState::evalBool(Env & env, Expr e)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void EvalState::strictEval(Env & env, Expr e, Value & v)
|
|
||||||
{
|
|
||||||
eval(env, e, v);
|
|
||||||
|
|
||||||
if (v.type == tAttrs) {
|
|
||||||
foreach (Bindings::iterator, i, *v.attrs)
|
|
||||||
forceValue(i->second);
|
|
||||||
}
|
|
||||||
|
|
||||||
else if (v.type == tList) {
|
|
||||||
for (unsigned int n = 0; n < v.list.length; ++n)
|
|
||||||
forceValue(v.list.elems[n]);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void EvalState::strictEval(Expr e, Value & v)
|
|
||||||
{
|
|
||||||
strictEval(baseEnv, e, v);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void EvalState::forceValue(Value & v)
|
void EvalState::forceValue(Value & v)
|
||||||
{
|
{
|
||||||
if (v.type == tThunk) {
|
if (v.type == tThunk) {
|
||||||
|
@ -678,6 +658,22 @@ void EvalState::forceValue(Value & v)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void EvalState::strictForceValue(Value & v)
|
||||||
|
{
|
||||||
|
forceValue(v);
|
||||||
|
|
||||||
|
if (v.type == tAttrs) {
|
||||||
|
foreach (Bindings::iterator, i, *v.attrs)
|
||||||
|
strictForceValue(i->second);
|
||||||
|
}
|
||||||
|
|
||||||
|
else if (v.type == tList) {
|
||||||
|
for (unsigned int n = 0; n < v.list.length; ++n)
|
||||||
|
strictForceValue(v.list.elems[n]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
int EvalState::forceInt(Value & v)
|
int EvalState::forceInt(Value & v)
|
||||||
{
|
{
|
||||||
forceValue(v);
|
forceValue(v);
|
||||||
|
@ -750,6 +746,14 @@ string EvalState::forceStringNoCtx(Value & v)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool EvalState::isDerivation(Value & v)
|
||||||
|
{
|
||||||
|
if (v.type != tAttrs) return false;
|
||||||
|
Bindings::iterator i = v.attrs->find(toATerm("type"));
|
||||||
|
return i != v.attrs->end() && forceStringNoCtx(i->second) == "derivation";
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
string EvalState::coerceToString(Value & v, PathSet & context,
|
string EvalState::coerceToString(Value & v, PathSet & context,
|
||||||
bool coerceMore, bool copyToStore)
|
bool coerceMore, bool copyToStore)
|
||||||
{
|
{
|
||||||
|
@ -769,7 +773,7 @@ string EvalState::coerceToString(Value & v, PathSet & context,
|
||||||
|
|
||||||
if (!copyToStore) return path;
|
if (!copyToStore) return path;
|
||||||
|
|
||||||
if (isDerivation(path))
|
if (nix::isDerivation(path))
|
||||||
throw EvalError(format("file names are not allowed to end in `%1%'")
|
throw EvalError(format("file names are not allowed to end in `%1%'")
|
||||||
% drvExtension);
|
% drvExtension);
|
||||||
|
|
||||||
|
|
|
@ -169,17 +169,16 @@ public:
|
||||||
type. */
|
type. */
|
||||||
bool evalBool(Env & env, Expr e);
|
bool evalBool(Env & env, Expr e);
|
||||||
|
|
||||||
/* Evaluate an expression, and recursively evaluate list elements
|
|
||||||
and attributes. */
|
|
||||||
void strictEval(Expr e, Value & v);
|
|
||||||
void strictEval(Env & env, Expr e, Value & v);
|
|
||||||
|
|
||||||
/* If `v' is a thunk, enter it and overwrite `v' with the result
|
/* If `v' is a thunk, enter it and overwrite `v' with the result
|
||||||
of the evaluation of the thunk. If `v' is a delayed function
|
of the evaluation of the thunk. If `v' is a delayed function
|
||||||
application, call the function and overwrite `v' with the
|
application, call the function and overwrite `v' with the
|
||||||
result. Otherwise, this is a no-op. */
|
result. Otherwise, this is a no-op. */
|
||||||
void forceValue(Value & v);
|
void forceValue(Value & v);
|
||||||
|
|
||||||
|
/* Force a value, then recursively force list elements and
|
||||||
|
attributes. */
|
||||||
|
void strictForceValue(Value & v);
|
||||||
|
|
||||||
/* Force `v', and then verify that it has the expected type. */
|
/* Force `v', and then verify that it has the expected type. */
|
||||||
int forceInt(Value & v);
|
int forceInt(Value & v);
|
||||||
bool forceBool(Value & v);
|
bool forceBool(Value & v);
|
||||||
|
@ -190,6 +189,10 @@ public:
|
||||||
string forceString(Value & v, PathSet & context);
|
string forceString(Value & v, PathSet & context);
|
||||||
string forceStringNoCtx(Value & v);
|
string forceStringNoCtx(Value & v);
|
||||||
|
|
||||||
|
/* Return true iff the value `v' denotes a derivation (i.e. a
|
||||||
|
set with attribute `type = "derivation"'). */
|
||||||
|
bool isDerivation(Value & v);
|
||||||
|
|
||||||
/* String coercion. Converts strings, paths and derivations to a
|
/* String coercion. Converts strings, paths and derivations to a
|
||||||
string. If `coerceMore' is set, also converts nulls, integers,
|
string. If `coerceMore' is set, also converts nulls, integers,
|
||||||
booleans and lists to a string. If `copyToStore' is set,
|
booleans and lists to a string. If `copyToStore' is set,
|
||||||
|
@ -219,10 +222,10 @@ private:
|
||||||
elements and attributes are compared recursively. */
|
elements and attributes are compared recursively. */
|
||||||
bool eqValues(Value & v1, Value & v2);
|
bool eqValues(Value & v1, Value & v2);
|
||||||
|
|
||||||
void callFunction(Value & fun, Value & arg, Value & v);
|
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
|
void callFunction(Value & fun, Value & arg, Value & v);
|
||||||
|
|
||||||
/* Allocation primitives. */
|
/* Allocation primitives. */
|
||||||
Value * allocValues(unsigned int count);
|
Value * allocValues(unsigned int count);
|
||||||
Env & allocEnv();
|
Env & allocEnv();
|
||||||
|
@ -237,6 +240,10 @@ public:
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
/* Return a string representing the type of the value `v'. */
|
||||||
|
string showType(Value & v);
|
||||||
|
|
||||||
|
|
||||||
#if 0
|
#if 0
|
||||||
/* Evaluate an expression to normal form. */
|
/* Evaluate an expression to normal form. */
|
||||||
Expr evalExpr(EvalState & state, Expr e);
|
Expr evalExpr(EvalState & state, Expr e);
|
||||||
|
|
|
@ -18,24 +18,19 @@ static XMLAttrs singletonAttrs(const string & name, const string & value)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/* set<Expr> is safe because all the expressions are also reachable
|
static void printValueAsXML(EvalState & state, bool strict, Value & v,
|
||||||
from the stack, therefore can't be garbage-collected. */
|
XMLWriter & doc, PathSet & context, PathSet & drvsSeen);
|
||||||
typedef set<Expr> ExprSet;
|
|
||||||
|
|
||||||
|
|
||||||
static void printTermAsXML(Expr e, XMLWriter & doc, PathSet & context,
|
static void showAttrs(EvalState & state, bool strict, Bindings & attrs,
|
||||||
ExprSet & drvsSeen);
|
XMLWriter & doc, PathSet & context, PathSet & drvsSeen)
|
||||||
|
|
||||||
|
|
||||||
static void showAttrs(const ATermMap & attrs, XMLWriter & doc,
|
|
||||||
PathSet & context, ExprSet & drvsSeen)
|
|
||||||
{
|
{
|
||||||
StringSet names;
|
StringSet names;
|
||||||
for (ATermMap::const_iterator i = attrs.begin(); i != attrs.end(); ++i)
|
foreach (Bindings::iterator, i, attrs)
|
||||||
names.insert(aterm2String(i->key));
|
names.insert(aterm2String(i->first));
|
||||||
for (StringSet::iterator i = names.begin(); i != names.end(); ++i) {
|
foreach (StringSet::iterator, i, names) {
|
||||||
XMLOpenElement _(doc, "attr", singletonAttrs("name", *i));
|
XMLOpenElement _(doc, "attr", singletonAttrs("name", *i));
|
||||||
printTermAsXML(attrs.get(toATerm(*i)), doc, context, drvsSeen);
|
printValueAsXML(state, strict, attrs[toATerm(*i)], doc, context, drvsSeen);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -61,91 +56,93 @@ static void printPatternAsXML(Pattern pat, XMLWriter & doc)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static void printTermAsXML(Expr e, XMLWriter & doc, PathSet & context,
|
static void printValueAsXML(EvalState & state, bool strict, Value & v,
|
||||||
ExprSet & drvsSeen)
|
XMLWriter & doc, PathSet & context, PathSet & drvsSeen)
|
||||||
{
|
{
|
||||||
XMLAttrs attrs;
|
|
||||||
string s;
|
|
||||||
ATerm s2;
|
|
||||||
int i;
|
|
||||||
ATermList as, es;
|
|
||||||
ATerm pat, body, pos;
|
|
||||||
|
|
||||||
checkInterrupt();
|
checkInterrupt();
|
||||||
|
|
||||||
if (matchStr(e, s, context)) /* !!! show the context? */
|
if (strict) state.forceValue(v);
|
||||||
doc.writeEmptyElement("string", singletonAttrs("value", s));
|
|
||||||
|
|
||||||
else if (matchPath(e, s2))
|
switch (v.type) {
|
||||||
doc.writeEmptyElement("path", singletonAttrs("value", aterm2String(s2)));
|
|
||||||
|
|
||||||
else if (matchNull(e))
|
case tInt:
|
||||||
|
doc.writeEmptyElement("int", singletonAttrs("value", (format("%1%") % v.integer).str()));
|
||||||
|
break;
|
||||||
|
|
||||||
|
case tBool:
|
||||||
|
doc.writeEmptyElement("bool", singletonAttrs("value", v.boolean ? "true" : "false"));
|
||||||
|
break;
|
||||||
|
|
||||||
|
case tString:
|
||||||
|
/* !!! show the context? */
|
||||||
|
doc.writeEmptyElement("string", singletonAttrs("value", v.string.s));
|
||||||
|
break;
|
||||||
|
|
||||||
|
case tPath:
|
||||||
|
doc.writeEmptyElement("path", singletonAttrs("value", v.path));
|
||||||
|
break;
|
||||||
|
|
||||||
|
case tNull:
|
||||||
doc.writeEmptyElement("null");
|
doc.writeEmptyElement("null");
|
||||||
|
break;
|
||||||
|
|
||||||
else if (matchInt(e, i))
|
case tAttrs:
|
||||||
doc.writeEmptyElement("int", singletonAttrs("value", (format("%1%") % i).str()));
|
if (state.isDerivation(v)) {
|
||||||
|
|
||||||
else if (e == eTrue)
|
|
||||||
doc.writeEmptyElement("bool", singletonAttrs("value", "true"));
|
|
||||||
|
|
||||||
else if (e == eFalse)
|
|
||||||
doc.writeEmptyElement("bool", singletonAttrs("value", "false"));
|
|
||||||
|
|
||||||
else if (matchAttrs(e, as)) {
|
|
||||||
ATermMap attrs;
|
|
||||||
queryAllAttrs(e, attrs);
|
|
||||||
|
|
||||||
Expr a = attrs.get(toATerm("type"));
|
|
||||||
if (a && matchStr(a, s, context) && s == "derivation") {
|
|
||||||
|
|
||||||
XMLAttrs xmlAttrs;
|
XMLAttrs xmlAttrs;
|
||||||
Path outPath, drvPath;
|
|
||||||
|
|
||||||
a = attrs.get(toATerm("drvPath"));
|
Bindings::iterator a = v.attrs->find(toATerm("derivation"));
|
||||||
if (matchStr(a, drvPath, context))
|
|
||||||
xmlAttrs["drvPath"] = drvPath;
|
|
||||||
|
|
||||||
a = attrs.get(toATerm("outPath"));
|
Path drvPath;
|
||||||
if (matchStr(a, outPath, context))
|
a = v.attrs->find(toATerm("drvPath"));
|
||||||
xmlAttrs["outPath"] = outPath;
|
if (a != v.attrs->end() && a->second.type == tString)
|
||||||
|
xmlAttrs["drvPath"] = drvPath = a->second.string.s;
|
||||||
|
|
||||||
|
a = v.attrs->find(toATerm("outPath"));
|
||||||
|
if (a != v.attrs->end() && a->second.type == tString)
|
||||||
|
xmlAttrs["outPath"] = a->second.string.s;
|
||||||
|
|
||||||
XMLOpenElement _(doc, "derivation", xmlAttrs);
|
XMLOpenElement _(doc, "derivation", xmlAttrs);
|
||||||
|
|
||||||
if (drvsSeen.find(e) == drvsSeen.end()) {
|
if (drvPath != "" && drvsSeen.find(drvPath) == drvsSeen.end()) {
|
||||||
drvsSeen.insert(e);
|
drvsSeen.insert(drvPath);
|
||||||
showAttrs(attrs, doc, context, drvsSeen);
|
showAttrs(state, strict, *v.attrs, doc, context, drvsSeen);
|
||||||
} else
|
} else
|
||||||
doc.writeEmptyElement("repeated");
|
doc.writeEmptyElement("repeated");
|
||||||
}
|
}
|
||||||
|
|
||||||
else {
|
else {
|
||||||
XMLOpenElement _(doc, "attrs");
|
XMLOpenElement _(doc, "attrs");
|
||||||
showAttrs(attrs, doc, context, drvsSeen);
|
showAttrs(state, strict, *v.attrs, doc, context, drvsSeen);
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
else if (matchList(e, es)) {
|
break;
|
||||||
|
|
||||||
|
case tList: {
|
||||||
XMLOpenElement _(doc, "list");
|
XMLOpenElement _(doc, "list");
|
||||||
for (ATermIterator i(es); i; ++i)
|
for (unsigned int n = 0; n < v.list.length; ++n)
|
||||||
printTermAsXML(*i, doc, context, drvsSeen);
|
printValueAsXML(state, strict, v.list.elems[n], doc, context, drvsSeen);
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
else if (matchFunction(e, pat, body, pos)) {
|
case tLambda: {
|
||||||
XMLOpenElement _(doc, "function");
|
XMLOpenElement _(doc, "function");
|
||||||
printPatternAsXML(pat, doc);
|
printPatternAsXML(v.lambda.pat, doc);
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
else
|
default:
|
||||||
doc.writeEmptyElement("unevaluated");
|
doc.writeEmptyElement("unevaluated");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void printTermAsXML(Expr e, std::ostream & out, PathSet & context)
|
void printValueAsXML(EvalState & state, bool strict,
|
||||||
|
Value & v, std::ostream & out, PathSet & context)
|
||||||
{
|
{
|
||||||
XMLWriter doc(true, out);
|
XMLWriter doc(true, out);
|
||||||
XMLOpenElement root(doc, "expr");
|
XMLOpenElement root(doc, "expr");
|
||||||
ExprSet drvsSeen;
|
PathSet drvsSeen;
|
||||||
printTermAsXML(e, doc, context, drvsSeen);
|
printValueAsXML(state, strict, v, doc, context, drvsSeen);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -5,11 +5,12 @@
|
||||||
#include <map>
|
#include <map>
|
||||||
|
|
||||||
#include "nixexpr.hh"
|
#include "nixexpr.hh"
|
||||||
#include "aterm.hh"
|
#include "eval.hh"
|
||||||
|
|
||||||
namespace nix {
|
namespace nix {
|
||||||
|
|
||||||
void printTermAsXML(Expr e, std::ostream & out, PathSet & context);
|
void printValueAsXML(EvalState & state, bool strict,
|
||||||
|
Value & v, std::ostream & out, PathSet & context);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -105,10 +105,7 @@ static bool getDerivation(EvalState & state, Value & v,
|
||||||
{
|
{
|
||||||
try {
|
try {
|
||||||
state.forceValue(v);
|
state.forceValue(v);
|
||||||
if (v.type != tAttrs) return true;
|
if (!state.isDerivation(v)) return true;
|
||||||
|
|
||||||
Bindings::iterator i = v.attrs->find(toATerm("type"));
|
|
||||||
if (i == v.attrs->end() || state.forceStringNoCtx(i->second) != "derivation") return true;
|
|
||||||
|
|
||||||
/* Remove spurious duplicates (e.g., an attribute set like
|
/* Remove spurious duplicates (e.g., an attribute set like
|
||||||
`rec { x = derivation {...}; y = x;}'. */
|
`rec { x = derivation {...}; y = x;}'. */
|
||||||
|
@ -117,7 +114,7 @@ static bool getDerivation(EvalState & state, Value & v,
|
||||||
|
|
||||||
DrvInfo drv;
|
DrvInfo drv;
|
||||||
|
|
||||||
i = v.attrs->find(toATerm("name"));
|
Bindings::iterator i = v.attrs->find(toATerm("name"));
|
||||||
/* !!! We really would like to have a decent back trace here. */
|
/* !!! We really would like to have a decent back trace here. */
|
||||||
if (i == v.attrs->end()) throw TypeError("derivation name missing");
|
if (i == v.attrs->end()) throw TypeError("derivation name missing");
|
||||||
drv.name = state.forceStringNoCtx(i->second);
|
drv.name = state.forceStringNoCtx(i->second);
|
||||||
|
|
|
@ -538,7 +538,6 @@ static void prim_readFile(EvalState & state, Value * * args, Value & v)
|
||||||
*************************************************************/
|
*************************************************************/
|
||||||
|
|
||||||
|
|
||||||
#if 0
|
|
||||||
/* Convert the argument (which can be any Nix expression) to an XML
|
/* Convert the argument (which can be any Nix expression) to an XML
|
||||||
representation returned in a string. Not all Nix expressions can
|
representation returned in a string. Not all Nix expressions can
|
||||||
be sensibly or completely represented (e.g., functions). */
|
be sensibly or completely represented (e.g., functions). */
|
||||||
|
@ -546,10 +545,9 @@ static void prim_toXML(EvalState & state, Value * * args, Value & v)
|
||||||
{
|
{
|
||||||
std::ostringstream out;
|
std::ostringstream out;
|
||||||
PathSet context;
|
PathSet context;
|
||||||
printTermAsXML(strictEvalExpr(state, args[0]), out, context);
|
printValueAsXML(state, true, *args[0], out, context);
|
||||||
return makeStr(out.str(), context);
|
mkString(v, out.str(), context);
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
|
|
||||||
|
|
||||||
/* Store a string in the Nix store as a source file that can be used
|
/* Store a string in the Nix store as a source file that can be used
|
||||||
|
@ -582,13 +580,12 @@ static void prim_toFile(EvalState & state, Value * * args, Value & v)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
#if 0
|
|
||||||
struct FilterFromExpr : PathFilter
|
struct FilterFromExpr : PathFilter
|
||||||
{
|
{
|
||||||
EvalState & state;
|
EvalState & state;
|
||||||
Expr filter;
|
Value & filter;
|
||||||
|
|
||||||
FilterFromExpr(EvalState & state, Expr filter)
|
FilterFromExpr(EvalState & state, Value & filter)
|
||||||
: state(state), filter(filter)
|
: state(state), filter(filter)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
@ -599,17 +596,25 @@ struct FilterFromExpr : PathFilter
|
||||||
if (lstat(path.c_str(), &st))
|
if (lstat(path.c_str(), &st))
|
||||||
throw SysError(format("getting attributes of path `%1%'") % path);
|
throw SysError(format("getting attributes of path `%1%'") % path);
|
||||||
|
|
||||||
Expr call =
|
/* Call the filter function. The first argument is the path,
|
||||||
makeCall(
|
the second is a string indicating the type of the file. */
|
||||||
makeCall(filter, makeStr(path)),
|
Value arg1;
|
||||||
makeStr(
|
mkString(arg1, path);
|
||||||
|
|
||||||
|
Value fun2;
|
||||||
|
state.callFunction(filter, arg1, fun2);
|
||||||
|
|
||||||
|
Value arg2;
|
||||||
|
mkString(arg2,
|
||||||
S_ISREG(st.st_mode) ? "regular" :
|
S_ISREG(st.st_mode) ? "regular" :
|
||||||
S_ISDIR(st.st_mode) ? "directory" :
|
S_ISDIR(st.st_mode) ? "directory" :
|
||||||
S_ISLNK(st.st_mode) ? "symlink" :
|
S_ISLNK(st.st_mode) ? "symlink" :
|
||||||
"unknown" /* not supported, will fail! */
|
"unknown" /* not supported, will fail! */);
|
||||||
));
|
|
||||||
|
|
||||||
return evalBool(state, call);
|
Value res;
|
||||||
|
state.callFunction(fun2, arg2, res);
|
||||||
|
|
||||||
|
return state.forceBool(res);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -617,19 +622,22 @@ struct FilterFromExpr : PathFilter
|
||||||
static void prim_filterSource(EvalState & state, Value * * args, Value & v)
|
static void prim_filterSource(EvalState & state, Value * * args, Value & v)
|
||||||
{
|
{
|
||||||
PathSet context;
|
PathSet context;
|
||||||
Path path = coerceToPath(state, args[1], context);
|
Path path = state.coerceToPath(*args[1], context);
|
||||||
if (!context.empty())
|
if (!context.empty())
|
||||||
throw EvalError(format("string `%1%' cannot refer to other paths") % path);
|
throw EvalError(format("string `%1%' cannot refer to other paths") % path);
|
||||||
|
|
||||||
FilterFromExpr filter(state, args[0]);
|
state.forceValue(*args[0]);
|
||||||
|
if (args[0]->type != tLambda)
|
||||||
|
throw TypeError(format("first argument in call to `filterSource' is not a function but %1%") % showType(*args[0]));
|
||||||
|
|
||||||
|
FilterFromExpr filter(state, *args[0]);
|
||||||
|
|
||||||
Path dstPath = readOnlyMode
|
Path dstPath = readOnlyMode
|
||||||
? computeStorePathForPath(path, true, htSHA256, filter).first
|
? computeStorePathForPath(path, true, htSHA256, filter).first
|
||||||
: store->addToStore(path, true, htSHA256, filter);
|
: store->addToStore(path, true, htSHA256, filter);
|
||||||
|
|
||||||
return makeStr(dstPath, singleton<PathSet>(dstPath));
|
mkString(v, dstPath, singleton<PathSet>(dstPath));
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
|
|
||||||
|
|
||||||
/*************************************************************
|
/*************************************************************
|
||||||
|
@ -927,15 +935,15 @@ static void prim_stringLength(EvalState & state, Value * * args, Value & v)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
#if 0
|
|
||||||
static void prim_unsafeDiscardStringContext(EvalState & state, Value * * args, Value & v)
|
static void prim_unsafeDiscardStringContext(EvalState & state, Value * * args, Value & v)
|
||||||
{
|
{
|
||||||
PathSet context;
|
PathSet context;
|
||||||
string s = coerceToString(state, args[0], context);
|
string s = state.coerceToString(*args[0], context);
|
||||||
return makeStr(s, PathSet());
|
mkString(v, s, PathSet());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
#if 0
|
||||||
/* Sometimes we want to pass a derivation path (i.e. pkg.drvPath) to a
|
/* Sometimes we want to pass a derivation path (i.e. pkg.drvPath) to a
|
||||||
builder without causing the derivation to be built (for instance,
|
builder without causing the derivation to be built (for instance,
|
||||||
in the derivation that builds NARs in nix-push, when doing
|
in the derivation that builds NARs in nix-push, when doing
|
||||||
|
@ -1053,13 +1061,9 @@ void EvalState::createBaseEnv()
|
||||||
addPrimOp("__readFile", 1, prim_readFile);
|
addPrimOp("__readFile", 1, prim_readFile);
|
||||||
|
|
||||||
// Creating files
|
// Creating files
|
||||||
#if 0
|
|
||||||
addPrimOp("__toXML", 1, prim_toXML);
|
addPrimOp("__toXML", 1, prim_toXML);
|
||||||
#endif
|
|
||||||
addPrimOp("__toFile", 2, prim_toFile);
|
addPrimOp("__toFile", 2, prim_toFile);
|
||||||
#if 0
|
|
||||||
addPrimOp("__filterSource", 2, prim_filterSource);
|
addPrimOp("__filterSource", 2, prim_filterSource);
|
||||||
#endif
|
|
||||||
|
|
||||||
// Attribute sets
|
// Attribute sets
|
||||||
addPrimOp("__attrNames", 1, prim_attrNames);
|
addPrimOp("__attrNames", 1, prim_attrNames);
|
||||||
|
@ -1091,8 +1095,8 @@ void EvalState::createBaseEnv()
|
||||||
addPrimOp("toString", 1, prim_toString);
|
addPrimOp("toString", 1, prim_toString);
|
||||||
addPrimOp("__substring", 3, prim_substring);
|
addPrimOp("__substring", 3, prim_substring);
|
||||||
addPrimOp("__stringLength", 1, prim_stringLength);
|
addPrimOp("__stringLength", 1, prim_stringLength);
|
||||||
#if 0
|
|
||||||
addPrimOp("__unsafeDiscardStringContext", 1, prim_unsafeDiscardStringContext);
|
addPrimOp("__unsafeDiscardStringContext", 1, prim_unsafeDiscardStringContext);
|
||||||
|
#if 0
|
||||||
addPrimOp("__unsafeDiscardOutputDependency", 1, prim_unsafeDiscardOutputDependency);
|
addPrimOp("__unsafeDiscardOutputDependency", 1, prim_unsafeDiscardOutputDependency);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
|
@ -75,7 +75,8 @@ void processExpr(EvalState & state, const Strings & attrPaths,
|
||||||
std::cout << format("%1%\n") % canonicaliseExpr(e);
|
std::cout << format("%1%\n") % canonicaliseExpr(e);
|
||||||
else {
|
else {
|
||||||
Value v;
|
Value v;
|
||||||
if (strict) state.strictEval(e, v); else state.eval(e, v);
|
state.eval(e, v);
|
||||||
|
if (strict) state.strictForceValue(v);
|
||||||
if (evalOnly)
|
if (evalOnly)
|
||||||
std::cout << v << std::endl;
|
std::cout << v << std::endl;
|
||||||
else {
|
else {
|
||||||
|
|
Loading…
Reference in a new issue