* More primops.
This commit is contained in:
parent
c3aa615a5f
commit
c9170be2bd
4 changed files with 92 additions and 184 deletions
|
@ -405,21 +405,35 @@ void EvalState::eval(Env & env, Expr e, Value & v)
|
||||||
}
|
}
|
||||||
|
|
||||||
if (matchConcatStrings(e, es)) {
|
if (matchConcatStrings(e, es)) {
|
||||||
unsigned int n = ATgetLength(es), j = 0;
|
PathSet context;
|
||||||
Value vs[n];
|
std::ostringstream s;
|
||||||
unsigned int len = 0;
|
|
||||||
for (ATermIterator i(es); i; ++i, ++j) {
|
bool first = true, isPath;
|
||||||
eval(env, *i, vs[j]);
|
|
||||||
if (vs[j].type != tString) throw TypeError("string expected");
|
for (ATermIterator i(es); i; ++i) {
|
||||||
len += strlen(vs[j].string.s);
|
eval(env, *i, v);
|
||||||
|
|
||||||
|
/* If the first element is a path, then the result will
|
||||||
|
also be a path, we don't copy anything (yet - that's
|
||||||
|
done later, since paths are copied when they are used
|
||||||
|
in a derivation), and none of the strings are allowed
|
||||||
|
to have contexts. */
|
||||||
|
if (first) {
|
||||||
|
isPath = v.type == tPath;
|
||||||
|
first = false;
|
||||||
}
|
}
|
||||||
char * s = new char[len + 1], * t = s;
|
|
||||||
for (unsigned int i = 0; i < j; ++i) {
|
s << coerceToString(v, context, false, !isPath);
|
||||||
strcpy(t, vs[i].string.s);
|
|
||||||
t += strlen(vs[i].string.s);
|
|
||||||
}
|
}
|
||||||
*t = 0;
|
|
||||||
mkString(v, s);
|
if (isPath && !context.empty())
|
||||||
|
throw EvalError(format("a string that refers to a store path cannot be appended to a path, in `%1%'")
|
||||||
|
% s.str());
|
||||||
|
|
||||||
|
if (isPath)
|
||||||
|
mkPath(v, strdup(s.str().c_str()));
|
||||||
|
else
|
||||||
|
mkString(v, strdup(s.str().c_str())); // !!! context
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -969,116 +983,6 @@ ATermList flattenList(EvalState & state, Expr e)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
string coerceToString(EvalState & state, Expr e, PathSet & context,
|
|
||||||
bool coerceMore, bool copyToStore)
|
|
||||||
{
|
|
||||||
e = evalExpr(state, e);
|
|
||||||
|
|
||||||
string s;
|
|
||||||
|
|
||||||
if (matchStr(e, s, context)) return s;
|
|
||||||
|
|
||||||
ATerm s2;
|
|
||||||
if (matchPath(e, s2)) {
|
|
||||||
Path path(canonPath(aterm2String(s2)));
|
|
||||||
|
|
||||||
if (!copyToStore) return path;
|
|
||||||
|
|
||||||
if (isDerivation(path))
|
|
||||||
throw EvalError(format("file names are not allowed to end in `%1%'")
|
|
||||||
% drvExtension);
|
|
||||||
|
|
||||||
Path dstPath;
|
|
||||||
if (state.srcToStore[path] != "")
|
|
||||||
dstPath = state.srcToStore[path];
|
|
||||||
else {
|
|
||||||
dstPath = readOnlyMode
|
|
||||||
? computeStorePathForPath(path).first
|
|
||||||
: store->addToStore(path);
|
|
||||||
state.srcToStore[path] = dstPath;
|
|
||||||
printMsg(lvlChatty, format("copied source `%1%' -> `%2%'")
|
|
||||||
% path % dstPath);
|
|
||||||
}
|
|
||||||
|
|
||||||
context.insert(dstPath);
|
|
||||||
return dstPath;
|
|
||||||
}
|
|
||||||
|
|
||||||
ATermList es;
|
|
||||||
if (matchAttrs(e, es)) {
|
|
||||||
Expr e2 = queryAttr(e, "outPath");
|
|
||||||
if (!e2) throwTypeError("cannot coerce an attribute set (except a derivation) to a string");
|
|
||||||
return coerceToString(state, e2, context, coerceMore, copyToStore);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (coerceMore) {
|
|
||||||
|
|
||||||
/* Note that `false' is represented as an empty string for
|
|
||||||
shell scripting convenience, just like `null'. */
|
|
||||||
if (e == eTrue) return "1";
|
|
||||||
if (e == eFalse) return "";
|
|
||||||
int n;
|
|
||||||
if (matchInt(e, n)) return int2String(n);
|
|
||||||
if (matchNull(e)) return "";
|
|
||||||
|
|
||||||
if (matchList(e, es)) {
|
|
||||||
string result;
|
|
||||||
es = flattenList(state, e);
|
|
||||||
bool first = true;
|
|
||||||
for (ATermIterator i(es); i; ++i) {
|
|
||||||
if (!first) result += " "; else first = false;
|
|
||||||
result += coerceToString(state, *i,
|
|
||||||
context, coerceMore, copyToStore);
|
|
||||||
}
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
throwTypeError("cannot coerce %1% to a string", showType(e));
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/* Common implementation of `+', ConcatStrings and `~'. */
|
|
||||||
static ATerm concatStrings(EvalState & state, ATermVector & args,
|
|
||||||
string separator = "")
|
|
||||||
{
|
|
||||||
if (args.empty()) return makeStr("", PathSet());
|
|
||||||
|
|
||||||
PathSet context;
|
|
||||||
std::ostringstream s;
|
|
||||||
|
|
||||||
/* If the first element is a path, then the result will also be a
|
|
||||||
path, we don't copy anything (yet - that's done later, since
|
|
||||||
paths are copied when they are used in a derivation), and none
|
|
||||||
of the strings are allowed to have contexts. */
|
|
||||||
ATerm dummy;
|
|
||||||
args.front() = evalExpr(state, args.front());
|
|
||||||
bool isPath = matchPath(args.front(), dummy);
|
|
||||||
|
|
||||||
for (ATermVector::const_iterator i = args.begin(); i != args.end(); ++i) {
|
|
||||||
if (i != args.begin()) s << separator;
|
|
||||||
s << coerceToString(state, *i, context, false, !isPath);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (isPath && !context.empty())
|
|
||||||
throw EvalError(format("a string that refers to a store path cannot be appended to a path, in `%1%'")
|
|
||||||
% s.str());
|
|
||||||
|
|
||||||
return isPath
|
|
||||||
? makePath(toATerm(s.str()))
|
|
||||||
: makeStr(s.str(), context);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
Path coerceToPath(EvalState & state, Expr e, PathSet & context)
|
|
||||||
{
|
|
||||||
string path = coerceToString(state, e, context, false, false);
|
|
||||||
if (path == "" || path[0] != '/')
|
|
||||||
throw EvalError(format("string `%1%' doesn't represent an absolute path") % path);
|
|
||||||
return path;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
Expr autoCallFunction(Expr e, const ATermMap & args)
|
Expr autoCallFunction(Expr e, const ATermMap & args)
|
||||||
{
|
{
|
||||||
Pattern pat;
|
Pattern pat;
|
||||||
|
@ -1515,16 +1419,16 @@ Expr strictEvalExpr(EvalState & state, Expr e)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
void printEvalStats(EvalState & state)
|
void EvalState::printStats()
|
||||||
{
|
{
|
||||||
char x;
|
char x;
|
||||||
bool showStats = getEnv("NIX_SHOW_STATS", "0") != "0";
|
bool showStats = getEnv("NIX_SHOW_STATS", "0") != "0";
|
||||||
printMsg(showStats ? lvlInfo : lvlDebug,
|
printMsg(showStats ? lvlInfo : lvlDebug,
|
||||||
format("evaluated %1% expressions, used %2% bytes of stack space, allocated %3% values, allocated %4% environments")
|
format("evaluated %1% expressions, used %2% bytes of stack space, allocated %3% values, allocated %4% environments")
|
||||||
% state.nrEvaluated
|
% nrEvaluated
|
||||||
% (&x - deepestStack)
|
% (&x - deepestStack)
|
||||||
% state.nrValues
|
% nrValues
|
||||||
% state.nrEnvs);
|
% nrEnvs);
|
||||||
if (showStats)
|
if (showStats)
|
||||||
printATermMapStats();
|
printATermMapStats();
|
||||||
}
|
}
|
||||||
|
|
|
@ -132,7 +132,7 @@ struct EvalState;
|
||||||
std::ostream & operator << (std::ostream & str, Value & v);
|
std::ostream & operator << (std::ostream & str, Value & v);
|
||||||
|
|
||||||
|
|
||||||
struct EvalState
|
class EvalState
|
||||||
{
|
{
|
||||||
DrvRoots drvRoots;
|
DrvRoots drvRoots;
|
||||||
DrvHashes drvHashes; /* normalised derivation hashes */
|
DrvHashes drvHashes; /* normalised derivation hashes */
|
||||||
|
@ -144,6 +144,8 @@ struct EvalState
|
||||||
|
|
||||||
bool allowUnsafeEquality;
|
bool allowUnsafeEquality;
|
||||||
|
|
||||||
|
public:
|
||||||
|
|
||||||
EvalState();
|
EvalState();
|
||||||
|
|
||||||
/* Evaluate an expression read from the given file to normal
|
/* Evaluate an expression read from the given file to normal
|
||||||
|
@ -214,6 +216,9 @@ public:
|
||||||
Env & allocEnv();
|
Env & allocEnv();
|
||||||
|
|
||||||
void mkList(Value & v, unsigned int length);
|
void mkList(Value & v, unsigned int length);
|
||||||
|
|
||||||
|
/* Print statistics. */
|
||||||
|
void printStats();
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
@ -244,9 +249,6 @@ ATermList flattenList(EvalState & state, Expr e);
|
||||||
Expr autoCallFunction(Expr e, const ATermMap & args);
|
Expr autoCallFunction(Expr e, const ATermMap & args);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* Print statistics. */
|
|
||||||
void printEvalStats(EvalState & state);
|
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -47,14 +47,14 @@ static void prim_import(EvalState & state, Value * * args, Value & v)
|
||||||
|
|
||||||
#if 0
|
#if 0
|
||||||
/* Determine whether the argument is the null value. */
|
/* Determine whether the argument is the null value. */
|
||||||
static Expr prim_isNull(EvalState & state, const ATermVector & args)
|
static void prim_isNull(EvalState & state, Value * * args, Value & v)
|
||||||
{
|
{
|
||||||
return makeBool(matchNull(evalExpr(state, args[0])));
|
return makeBool(matchNull(evalExpr(state, args[0])));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/* Determine whether the argument is a function. */
|
/* Determine whether the argument is a function. */
|
||||||
static Expr prim_isFunction(EvalState & state, const ATermVector & args)
|
static void prim_isFunction(EvalState & state, Value * * args, Value & v)
|
||||||
{
|
{
|
||||||
Expr e = evalExpr(state, args[0]);
|
Expr e = evalExpr(state, args[0]);
|
||||||
Pattern pat;
|
Pattern pat;
|
||||||
|
@ -63,14 +63,14 @@ static Expr prim_isFunction(EvalState & state, const ATermVector & args)
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Determine whether the argument is an Int. */
|
/* Determine whether the argument is an Int. */
|
||||||
static Expr prim_isInt(EvalState & state, const ATermVector & args)
|
static void prim_isInt(EvalState & state, Value * * args, Value & v)
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
return makeBool(matchInt(evalExpr(state, args[0]), i));
|
return makeBool(matchInt(evalExpr(state, args[0]), i));
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Determine whether the argument is an String. */
|
/* Determine whether the argument is an String. */
|
||||||
static Expr prim_isString(EvalState & state, const ATermVector & args)
|
static void prim_isString(EvalState & state, Value * * args, Value & v)
|
||||||
{
|
{
|
||||||
string s;
|
string s;
|
||||||
PathSet l;
|
PathSet l;
|
||||||
|
@ -78,13 +78,13 @@ static Expr prim_isString(EvalState & state, const ATermVector & args)
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Determine whether the argument is an Bool. */
|
/* Determine whether the argument is an Bool. */
|
||||||
static Expr prim_isBool(EvalState & state, const ATermVector & args)
|
static void prim_isBool(EvalState & state, Value * * args, Value & v)
|
||||||
{
|
{
|
||||||
ATermBool b;
|
ATermBool b;
|
||||||
return makeBool(matchBool(evalExpr(state, args[0]), b));
|
return makeBool(matchBool(evalExpr(state, args[0]), b));
|
||||||
}
|
}
|
||||||
|
|
||||||
static Expr prim_genericClosure(EvalState & state, const ATermVector & args)
|
static void prim_genericClosure(EvalState & state, Value * * args, Value & v)
|
||||||
{
|
{
|
||||||
startNest(nest, lvlDebug, "finding dependencies");
|
startNest(nest, lvlDebug, "finding dependencies");
|
||||||
|
|
||||||
|
@ -132,7 +132,7 @@ static Expr prim_genericClosure(EvalState & state, const ATermVector & args)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static Expr prim_abort(EvalState & state, const ATermVector & args)
|
static void prim_abort(EvalState & state, Value * * args, Value & v)
|
||||||
{
|
{
|
||||||
PathSet context;
|
PathSet context;
|
||||||
throw Abort(format("evaluation aborted with the following error message: `%1%'") %
|
throw Abort(format("evaluation aborted with the following error message: `%1%'") %
|
||||||
|
@ -140,7 +140,7 @@ static Expr prim_abort(EvalState & state, const ATermVector & args)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static Expr prim_throw(EvalState & state, const ATermVector & args)
|
static void prim_throw(EvalState & state, Value * * args, Value & v)
|
||||||
{
|
{
|
||||||
PathSet context;
|
PathSet context;
|
||||||
throw ThrownError(format("user-thrown exception: %1%") %
|
throw ThrownError(format("user-thrown exception: %1%") %
|
||||||
|
@ -148,7 +148,7 @@ static Expr prim_throw(EvalState & state, const ATermVector & args)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static Expr prim_addErrorContext(EvalState & state, const ATermVector & args)
|
static void prim_addErrorContext(EvalState & state, Value * * args, Value & v)
|
||||||
{
|
{
|
||||||
PathSet context;
|
PathSet context;
|
||||||
try {
|
try {
|
||||||
|
@ -162,7 +162,7 @@ static Expr prim_addErrorContext(EvalState & state, const ATermVector & args)
|
||||||
|
|
||||||
/* Try evaluating the argument. Success => {success=true; value=something;},
|
/* Try evaluating the argument. Success => {success=true; value=something;},
|
||||||
* else => {success=false; value=false;} */
|
* else => {success=false; value=false;} */
|
||||||
static Expr prim_tryEval(EvalState & state, const ATermVector & args)
|
static void prim_tryEval(EvalState & state, Value * * args, Value & v)
|
||||||
{
|
{
|
||||||
ATermMap res = ATermMap();
|
ATermMap res = ATermMap();
|
||||||
try {
|
try {
|
||||||
|
@ -179,7 +179,7 @@ static Expr prim_tryEval(EvalState & state, const ATermVector & args)
|
||||||
|
|
||||||
|
|
||||||
/* Return an environment variable. Use with care. */
|
/* Return an environment variable. Use with care. */
|
||||||
static Expr prim_getEnv(EvalState & state, const ATermVector & args)
|
static void prim_getEnv(EvalState & state, Value * * args, Value & v)
|
||||||
{
|
{
|
||||||
string name = evalStringNoCtx(state, args[0]);
|
string name = evalStringNoCtx(state, args[0]);
|
||||||
return makeStr(getEnv(name));
|
return makeStr(getEnv(name));
|
||||||
|
@ -190,7 +190,7 @@ static Expr prim_getEnv(EvalState & state, const ATermVector & args)
|
||||||
on standard error. Then return the second expression. Useful for
|
on standard error. Then return the second expression. Useful for
|
||||||
debugging.
|
debugging.
|
||||||
*/
|
*/
|
||||||
static Expr prim_trace(EvalState & state, const ATermVector & args)
|
static void prim_trace(EvalState & state, Value * * args, Value & v)
|
||||||
{
|
{
|
||||||
Expr e = evalExpr(state, args[0]);
|
Expr e = evalExpr(state, args[0]);
|
||||||
string s;
|
string s;
|
||||||
|
@ -272,7 +272,7 @@ static Hash hashDerivationModulo(EvalState & state, Derivation drv)
|
||||||
derivation; `drvPath' containing the path of the Nix expression;
|
derivation; `drvPath' containing the path of the Nix expression;
|
||||||
and `type' set to `derivation' to indicate that this is a
|
and `type' set to `derivation' to indicate that this is a
|
||||||
derivation. */
|
derivation. */
|
||||||
static Expr prim_derivationStrict(EvalState & state, const ATermVector & args)
|
static void prim_derivationStrict(EvalState & state, Value * * args, Value & v)
|
||||||
{
|
{
|
||||||
startNest(nest, lvlVomit, "evaluating derivation");
|
startNest(nest, lvlVomit, "evaluating derivation");
|
||||||
|
|
||||||
|
@ -470,7 +470,7 @@ static Expr prim_derivationStrict(EvalState & state, const ATermVector & args)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static Expr prim_derivationLazy(EvalState & state, const ATermVector & args)
|
static void prim_derivationLazy(EvalState & state, Value * * args, Value & v)
|
||||||
{
|
{
|
||||||
Expr eAttrs = evalExpr(state, args[0]);
|
Expr eAttrs = evalExpr(state, args[0]);
|
||||||
ATermMap attrs;
|
ATermMap attrs;
|
||||||
|
@ -496,7 +496,7 @@ static Expr prim_derivationLazy(EvalState & state, const ATermVector & args)
|
||||||
|
|
||||||
|
|
||||||
/* Convert the argument to a path. !!! obsolete? */
|
/* Convert the argument to a path. !!! obsolete? */
|
||||||
static Expr prim_toPath(EvalState & state, const ATermVector & args)
|
static void prim_toPath(EvalState & state, Value * * args, Value & v)
|
||||||
{
|
{
|
||||||
PathSet context;
|
PathSet context;
|
||||||
string path = coerceToPath(state, args[0], context);
|
string path = coerceToPath(state, args[0], context);
|
||||||
|
@ -512,7 +512,7 @@ static Expr prim_toPath(EvalState & state, const ATermVector & args)
|
||||||
/nix/store/newhash-oldhash-oldname. In the past, `toPath' had
|
/nix/store/newhash-oldhash-oldname. In the past, `toPath' had
|
||||||
special case behaviour for store paths, but that created weird
|
special case behaviour for store paths, but that created weird
|
||||||
corner cases. */
|
corner cases. */
|
||||||
static Expr prim_storePath(EvalState & state, const ATermVector & args)
|
static void prim_storePath(EvalState & state, Value * * args, Value & v)
|
||||||
{
|
{
|
||||||
PathSet context;
|
PathSet context;
|
||||||
Path path = canonPath(coerceToPath(state, args[0], context));
|
Path path = canonPath(coerceToPath(state, args[0], context));
|
||||||
|
@ -526,7 +526,7 @@ static Expr prim_storePath(EvalState & state, const ATermVector & args)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static Expr prim_pathExists(EvalState & state, const ATermVector & args)
|
static void prim_pathExists(EvalState & state, Value * * args, Value & v)
|
||||||
{
|
{
|
||||||
PathSet context;
|
PathSet context;
|
||||||
Path path = coerceToPath(state, args[0], context);
|
Path path = coerceToPath(state, args[0], context);
|
||||||
|
@ -538,7 +538,7 @@ static Expr prim_pathExists(EvalState & state, const ATermVector & args)
|
||||||
|
|
||||||
/* Return the base name of the given string, i.e., everything
|
/* Return the base name of the given string, i.e., everything
|
||||||
following the last slash. */
|
following the last slash. */
|
||||||
static Expr prim_baseNameOf(EvalState & state, const ATermVector & args)
|
static void prim_baseNameOf(EvalState & state, Value * * args, Value & v)
|
||||||
{
|
{
|
||||||
PathSet context;
|
PathSet context;
|
||||||
return makeStr(baseNameOf(coerceToString(state, args[0], context)), context);
|
return makeStr(baseNameOf(coerceToString(state, args[0], context)), context);
|
||||||
|
@ -548,7 +548,7 @@ static Expr prim_baseNameOf(EvalState & state, const ATermVector & args)
|
||||||
/* Return the directory of the given path, i.e., everything before the
|
/* Return the directory of the given path, i.e., everything before the
|
||||||
last slash. Return either a path or a string depending on the type
|
last slash. Return either a path or a string depending on the type
|
||||||
of the argument. */
|
of the argument. */
|
||||||
static Expr prim_dirOf(EvalState & state, const ATermVector & args)
|
static void prim_dirOf(EvalState & state, Value * * args, Value & v)
|
||||||
{
|
{
|
||||||
PathSet context;
|
PathSet context;
|
||||||
Expr e = evalExpr(state, args[0]); ATerm dummy;
|
Expr e = evalExpr(state, args[0]); ATerm dummy;
|
||||||
|
@ -559,7 +559,7 @@ static Expr prim_dirOf(EvalState & state, const ATermVector & args)
|
||||||
|
|
||||||
|
|
||||||
/* Return the contents of a file as a string. */
|
/* Return the contents of a file as a string. */
|
||||||
static Expr prim_readFile(EvalState & state, const ATermVector & args)
|
static void prim_readFile(EvalState & state, Value * * args, Value & v)
|
||||||
{
|
{
|
||||||
PathSet context;
|
PathSet context;
|
||||||
Path path = coerceToPath(state, args[0], context);
|
Path path = coerceToPath(state, args[0], context);
|
||||||
|
@ -577,7 +577,7 @@ static Expr prim_readFile(EvalState & state, const ATermVector & args)
|
||||||
/* 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). */
|
||||||
static Expr prim_toXML(EvalState & state, const ATermVector & args)
|
static void prim_toXML(EvalState & state, Value * * args, Value & v)
|
||||||
{
|
{
|
||||||
std::ostringstream out;
|
std::ostringstream out;
|
||||||
PathSet context;
|
PathSet context;
|
||||||
|
@ -588,7 +588,7 @@ static Expr prim_toXML(EvalState & state, const ATermVector & args)
|
||||||
|
|
||||||
/* 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
|
||||||
as an input by derivations. */
|
as an input by derivations. */
|
||||||
static Expr prim_toFile(EvalState & state, const ATermVector & args)
|
static void prim_toFile(EvalState & state, Value * * args, Value & v)
|
||||||
{
|
{
|
||||||
PathSet context;
|
PathSet context;
|
||||||
string name = evalStringNoCtx(state, args[0]);
|
string name = evalStringNoCtx(state, args[0]);
|
||||||
|
@ -647,7 +647,7 @@ struct FilterFromExpr : PathFilter
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
static Expr prim_filterSource(EvalState & state, const ATermVector & args)
|
static void prim_filterSource(EvalState & state, Value * * args, Value & v)
|
||||||
{
|
{
|
||||||
PathSet context;
|
PathSet context;
|
||||||
Path path = coerceToPath(state, args[1], context);
|
Path path = coerceToPath(state, args[1], context);
|
||||||
|
@ -671,7 +671,7 @@ static Expr prim_filterSource(EvalState & state, const ATermVector & args)
|
||||||
|
|
||||||
/* Return the names of the attributes in an attribute set as a sorted
|
/* Return the names of the attributes in an attribute set as a sorted
|
||||||
list of strings. */
|
list of strings. */
|
||||||
static Expr prim_attrNames(EvalState & state, const ATermVector & args)
|
static void prim_attrNames(EvalState & state, Value * * args, Value & v)
|
||||||
{
|
{
|
||||||
ATermMap attrs;
|
ATermMap attrs;
|
||||||
queryAllAttrs(evalExpr(state, args[0]), attrs);
|
queryAllAttrs(evalExpr(state, args[0]), attrs);
|
||||||
|
@ -690,7 +690,7 @@ static Expr prim_attrNames(EvalState & state, const ATermVector & args)
|
||||||
|
|
||||||
|
|
||||||
/* Dynamic version of the `.' operator. */
|
/* Dynamic version of the `.' operator. */
|
||||||
static Expr prim_getAttr(EvalState & state, const ATermVector & args)
|
static void prim_getAttr(EvalState & state, Value * * args, Value & v)
|
||||||
{
|
{
|
||||||
string attr = evalStringNoCtx(state, args[0]);
|
string attr = evalStringNoCtx(state, args[0]);
|
||||||
return evalExpr(state, makeSelect(args[1], toATerm(attr)));
|
return evalExpr(state, makeSelect(args[1], toATerm(attr)));
|
||||||
|
@ -698,7 +698,7 @@ static Expr prim_getAttr(EvalState & state, const ATermVector & args)
|
||||||
|
|
||||||
|
|
||||||
/* Dynamic version of the `?' operator. */
|
/* Dynamic version of the `?' operator. */
|
||||||
static Expr prim_hasAttr(EvalState & state, const ATermVector & args)
|
static void prim_hasAttr(EvalState & state, Value * * args, Value & v)
|
||||||
{
|
{
|
||||||
string attr = evalStringNoCtx(state, args[0]);
|
string attr = evalStringNoCtx(state, args[0]);
|
||||||
return evalExpr(state, makeOpHasAttr(args[1], toATerm(attr)));
|
return evalExpr(state, makeOpHasAttr(args[1], toATerm(attr)));
|
||||||
|
@ -709,7 +709,7 @@ static Expr prim_hasAttr(EvalState & state, const ATermVector & args)
|
||||||
pairs. To be precise, a list [{name = "name1"; value = value1;}
|
pairs. To be precise, a list [{name = "name1"; value = value1;}
|
||||||
... {name = "nameN"; value = valueN;}] is transformed to {name1 =
|
... {name = "nameN"; value = valueN;}] is transformed to {name1 =
|
||||||
value1; ... nameN = valueN;}. */
|
value1; ... nameN = valueN;}. */
|
||||||
static Expr prim_listToAttrs(EvalState & state, const ATermVector & args)
|
static void prim_listToAttrs(EvalState & state, Value * * args, Value & v)
|
||||||
{
|
{
|
||||||
try {
|
try {
|
||||||
ATermMap res = ATermMap();
|
ATermMap res = ATermMap();
|
||||||
|
@ -739,7 +739,7 @@ static Expr prim_listToAttrs(EvalState & state, const ATermVector & args)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static Expr prim_removeAttrs(EvalState & state, const ATermVector & args)
|
static void prim_removeAttrs(EvalState & state, Value * * args, Value & v)
|
||||||
{
|
{
|
||||||
ATermMap attrs;
|
ATermMap attrs;
|
||||||
queryAllAttrs(evalExpr(state, args[0]), attrs, true);
|
queryAllAttrs(evalExpr(state, args[0]), attrs, true);
|
||||||
|
@ -755,7 +755,7 @@ static Expr prim_removeAttrs(EvalState & state, const ATermVector & args)
|
||||||
|
|
||||||
|
|
||||||
/* Determine whether the argument is an attribute set. */
|
/* Determine whether the argument is an attribute set. */
|
||||||
static Expr prim_isAttrs(EvalState & state, const ATermVector & args)
|
static void prim_isAttrs(EvalState & state, Value * * args, Value & v)
|
||||||
{
|
{
|
||||||
ATermList list;
|
ATermList list;
|
||||||
return makeBool(matchAttrs(evalExpr(state, args[0]), list));
|
return makeBool(matchAttrs(evalExpr(state, args[0]), list));
|
||||||
|
@ -765,7 +765,7 @@ static Expr prim_isAttrs(EvalState & state, const ATermVector & args)
|
||||||
/* Return the right-biased intersection of two attribute sets as1 and
|
/* Return the right-biased intersection of two attribute sets as1 and
|
||||||
as2, i.e. a set that contains every attribute from as2 that is also
|
as2, i.e. a set that contains every attribute from as2 that is also
|
||||||
a member of as1. */
|
a member of as1. */
|
||||||
static Expr prim_intersectAttrs(EvalState & state, const ATermVector & args)
|
static void prim_intersectAttrs(EvalState & state, Value * * args, Value & v)
|
||||||
{
|
{
|
||||||
ATermMap as1, as2;
|
ATermMap as1, as2;
|
||||||
queryAllAttrs(evalExpr(state, args[0]), as1, true);
|
queryAllAttrs(evalExpr(state, args[0]), as1, true);
|
||||||
|
@ -807,7 +807,7 @@ static void attrsInPattern(ATermMap & map, Pattern pat)
|
||||||
functionArgs (x: ...)
|
functionArgs (x: ...)
|
||||||
=> { }
|
=> { }
|
||||||
*/
|
*/
|
||||||
static Expr prim_functionArgs(EvalState & state, const ATermVector & args)
|
static void prim_functionArgs(EvalState & state, Value * * args, Value & v)
|
||||||
{
|
{
|
||||||
Expr f = evalExpr(state, args[0]);
|
Expr f = evalExpr(state, args[0]);
|
||||||
ATerm pat, body, pos;
|
ATerm pat, body, pos;
|
||||||
|
@ -827,7 +827,7 @@ static Expr prim_functionArgs(EvalState & state, const ATermVector & args)
|
||||||
|
|
||||||
|
|
||||||
/* Determine whether the argument is a list. */
|
/* Determine whether the argument is a list. */
|
||||||
static Expr prim_isList(EvalState & state, const ATermVector & args)
|
static void prim_isList(EvalState & state, Value * * args, Value & v)
|
||||||
{
|
{
|
||||||
ATermList list;
|
ATermList list;
|
||||||
return makeBool(matchList(evalExpr(state, args[0]), list));
|
return makeBool(matchList(evalExpr(state, args[0]), list));
|
||||||
|
@ -877,7 +877,7 @@ static void prim_map(EvalState & state, Value * * args, Value & v)
|
||||||
|
|
||||||
#if 0
|
#if 0
|
||||||
/* Return the length of a list. This is an O(1) time operation. */
|
/* Return the length of a list. This is an O(1) time operation. */
|
||||||
static Expr prim_length(EvalState & state, const ATermVector & args)
|
static void prim_length(EvalState & state, Value * * args, Value & v)
|
||||||
{
|
{
|
||||||
ATermList list = evalList(state, args[0]);
|
ATermList list = evalList(state, args[0]);
|
||||||
return makeInt(ATgetLength(list));
|
return makeInt(ATgetLength(list));
|
||||||
|
@ -897,7 +897,7 @@ static void prim_add(EvalState & state, Value * * args, Value & v)
|
||||||
|
|
||||||
|
|
||||||
#if 0
|
#if 0
|
||||||
static Expr prim_sub(EvalState & state, const ATermVector & args)
|
static void prim_sub(EvalState & state, Value * * args, Value & v)
|
||||||
{
|
{
|
||||||
int i1 = evalInt(state, args[0]);
|
int i1 = evalInt(state, args[0]);
|
||||||
int i2 = evalInt(state, args[1]);
|
int i2 = evalInt(state, args[1]);
|
||||||
|
@ -905,7 +905,7 @@ static Expr prim_sub(EvalState & state, const ATermVector & args)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static Expr prim_mul(EvalState & state, const ATermVector & args)
|
static void prim_mul(EvalState & state, Value * * args, Value & v)
|
||||||
{
|
{
|
||||||
int i1 = evalInt(state, args[0]);
|
int i1 = evalInt(state, args[0]);
|
||||||
int i2 = evalInt(state, args[1]);
|
int i2 = evalInt(state, args[1]);
|
||||||
|
@ -913,20 +913,19 @@ static Expr prim_mul(EvalState & state, const ATermVector & args)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static Expr prim_div(EvalState & state, const ATermVector & args)
|
static void prim_div(EvalState & state, Value * * args, Value & v)
|
||||||
{
|
{
|
||||||
int i1 = evalInt(state, args[0]);
|
int i1 = evalInt(state, args[0]);
|
||||||
int i2 = evalInt(state, args[1]);
|
int i2 = evalInt(state, args[1]);
|
||||||
if (i2 == 0) throw EvalError("division by zero");
|
if (i2 == 0) throw EvalError("division by zero");
|
||||||
return makeInt(i1 / i2);
|
return makeInt(i1 / i2);
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
static Expr prim_lessThan(EvalState & state, const ATermVector & args)
|
static void prim_lessThan(EvalState & state, Value * * args, Value & v)
|
||||||
{
|
{
|
||||||
int i1 = evalInt(state, args[0]);
|
mkBool(v, state.forceInt(*args[0]) < state.forceInt(*args[1]));
|
||||||
int i2 = evalInt(state, args[1]);
|
|
||||||
return makeBool(i1 < i2);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -938,19 +937,20 @@ static Expr prim_lessThan(EvalState & state, const ATermVector & args)
|
||||||
/* Convert the argument to a string. Paths are *not* copied to the
|
/* Convert the argument to a string. Paths are *not* copied to the
|
||||||
store, so `toString /foo/bar' yields `"/foo/bar"', not
|
store, so `toString /foo/bar' yields `"/foo/bar"', not
|
||||||
`"/nix/store/whatever..."'. */
|
`"/nix/store/whatever..."'. */
|
||||||
static Expr prim_toString(EvalState & state, const ATermVector & args)
|
static void prim_toString(EvalState & state, Value * * args, Value & v)
|
||||||
{
|
{
|
||||||
PathSet context;
|
PathSet context;
|
||||||
string s = coerceToString(state, args[0], context, true, false);
|
string s = state.coerceToString(*args[0], context, true, false);
|
||||||
return makeStr(s, context);
|
mkString(v, strdup(s.c_str())); // !!! context
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
#if 0
|
||||||
/* `substring start len str' returns the substring of `str' starting
|
/* `substring start len str' returns the substring of `str' starting
|
||||||
at character position `min(start, stringLength str)' inclusive and
|
at character position `min(start, stringLength str)' inclusive and
|
||||||
ending at `min(start + len, stringLength str)'. `start' must be
|
ending at `min(start + len, stringLength str)'. `start' must be
|
||||||
non-negative. */
|
non-negative. */
|
||||||
static Expr prim_substring(EvalState & state, const ATermVector & args)
|
static void prim_substring(EvalState & state, Value * * args, Value & v)
|
||||||
{
|
{
|
||||||
int start = evalInt(state, args[0]);
|
int start = evalInt(state, args[0]);
|
||||||
int len = evalInt(state, args[1]);
|
int len = evalInt(state, args[1]);
|
||||||
|
@ -963,7 +963,7 @@ static Expr prim_substring(EvalState & state, const ATermVector & args)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static Expr prim_stringLength(EvalState & state, const ATermVector & args)
|
static void prim_stringLength(EvalState & state, Value * * args, Value & v)
|
||||||
{
|
{
|
||||||
PathSet context;
|
PathSet context;
|
||||||
string s = coerceToString(state, args[0], context);
|
string s = coerceToString(state, args[0], context);
|
||||||
|
@ -971,7 +971,7 @@ static Expr prim_stringLength(EvalState & state, const ATermVector & args)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static Expr prim_unsafeDiscardStringContext(EvalState & state, const ATermVector & args)
|
static void prim_unsafeDiscardStringContext(EvalState & state, Value * * args, Value & v)
|
||||||
{
|
{
|
||||||
PathSet context;
|
PathSet context;
|
||||||
string s = coerceToString(state, args[0], context);
|
string s = coerceToString(state, args[0], context);
|
||||||
|
@ -985,7 +985,7 @@ static Expr prim_unsafeDiscardStringContext(EvalState & state, const ATermVector
|
||||||
source-only deployment). This primop marks the string context so
|
source-only deployment). This primop marks the string context so
|
||||||
that builtins.derivation adds the path to drv.inputSrcs rather than
|
that builtins.derivation adds the path to drv.inputSrcs rather than
|
||||||
drv.inputDrvs. */
|
drv.inputDrvs. */
|
||||||
static Expr prim_unsafeDiscardOutputDependency(EvalState & state, const ATermVector & args)
|
static void prim_unsafeDiscardOutputDependency(EvalState & state, Value * * args, Value & v)
|
||||||
{
|
{
|
||||||
PathSet context;
|
PathSet context;
|
||||||
string s = coerceToString(state, args[0], context);
|
string s = coerceToString(state, args[0], context);
|
||||||
|
@ -1004,14 +1004,14 @@ static Expr prim_unsafeDiscardOutputDependency(EvalState & state, const ATermVec
|
||||||
/* Expression serialization/deserialization */
|
/* Expression serialization/deserialization */
|
||||||
|
|
||||||
|
|
||||||
static Expr prim_exprToString(EvalState & state, const ATermVector & args)
|
static void prim_exprToString(EvalState & state, Value * * args, Value & v)
|
||||||
{
|
{
|
||||||
/* !!! this disregards context */
|
/* !!! this disregards context */
|
||||||
return makeStr(atPrint(evalExpr(state, args[0])));
|
return makeStr(atPrint(evalExpr(state, args[0])));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static Expr prim_stringToExpr(EvalState & state, const ATermVector & args)
|
static void prim_stringToExpr(EvalState & state, Value * * args, Value & v)
|
||||||
{
|
{
|
||||||
/* !!! this can introduce arbitrary garbage terms in the
|
/* !!! this can introduce arbitrary garbage terms in the
|
||||||
evaluator! */;
|
evaluator! */;
|
||||||
|
@ -1028,7 +1028,7 @@ static Expr prim_stringToExpr(EvalState & state, const ATermVector & args)
|
||||||
*************************************************************/
|
*************************************************************/
|
||||||
|
|
||||||
|
|
||||||
static Expr prim_parseDrvName(EvalState & state, const ATermVector & args)
|
static void prim_parseDrvName(EvalState & state, Value * * args, Value & v)
|
||||||
{
|
{
|
||||||
string name = evalStringNoCtx(state, args[0]);
|
string name = evalStringNoCtx(state, args[0]);
|
||||||
DrvName parsed(name);
|
DrvName parsed(name);
|
||||||
|
@ -1039,7 +1039,7 @@ static Expr prim_parseDrvName(EvalState & state, const ATermVector & args)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static Expr prim_compareVersions(EvalState & state, const ATermVector & args)
|
static void prim_compareVersions(EvalState & state, Value * * args, Value & v)
|
||||||
{
|
{
|
||||||
string version1 = evalStringNoCtx(state, args[0]);
|
string version1 = evalStringNoCtx(state, args[0]);
|
||||||
string version2 = evalStringNoCtx(state, args[1]);
|
string version2 = evalStringNoCtx(state, args[1]);
|
||||||
|
@ -1144,10 +1144,12 @@ void EvalState::createBaseEnv()
|
||||||
addPrimOp("__sub", 2, prim_sub);
|
addPrimOp("__sub", 2, prim_sub);
|
||||||
addPrimOp("__mul", 2, prim_mul);
|
addPrimOp("__mul", 2, prim_mul);
|
||||||
addPrimOp("__div", 2, prim_div);
|
addPrimOp("__div", 2, prim_div);
|
||||||
|
#endif
|
||||||
addPrimOp("__lessThan", 2, prim_lessThan);
|
addPrimOp("__lessThan", 2, prim_lessThan);
|
||||||
|
|
||||||
// String manipulation
|
// String manipulation
|
||||||
addPrimOp("toString", 1, prim_toString);
|
addPrimOp("toString", 1, prim_toString);
|
||||||
|
#if 0
|
||||||
addPrimOp("__substring", 3, prim_substring);
|
addPrimOp("__substring", 3, prim_substring);
|
||||||
addPrimOp("__stringLength", 1, prim_stringLength);
|
addPrimOp("__stringLength", 1, prim_stringLength);
|
||||||
addPrimOp("__unsafeDiscardStringContext", 1, prim_unsafeDiscardStringContext);
|
addPrimOp("__unsafeDiscardStringContext", 1, prim_unsafeDiscardStringContext);
|
||||||
|
|
|
@ -159,7 +159,7 @@ void run(Strings args)
|
||||||
evalOnly, xmlOutput, e);
|
evalOnly, xmlOutput, e);
|
||||||
}
|
}
|
||||||
|
|
||||||
printEvalStats(state);
|
state.printStats();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue