forked from lix-project/lix
* Updated some more primops.
This commit is contained in:
parent
8bb0210fea
commit
5c31995bb8
3 changed files with 37 additions and 58 deletions
|
@ -367,6 +367,14 @@ bool EvalState::evalBool(Env & env, Expr * e)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void EvalState::evalAttrs(Env & env, Expr * e, Value & v)
|
||||||
|
{
|
||||||
|
eval(env, e, v);
|
||||||
|
if (v.type != tAttrs)
|
||||||
|
throwTypeError("value is %1% while an attribute set was expected", showType(v));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
void Expr::eval(EvalState & state, Env & env, Value & v)
|
void Expr::eval(EvalState & state, Env & env, Value & v)
|
||||||
{
|
{
|
||||||
abort();
|
abort();
|
||||||
|
@ -481,8 +489,7 @@ void ExprVar::eval(EvalState & state, Env & env, Value & v)
|
||||||
void ExprSelect::eval(EvalState & state, Env & env, Value & v)
|
void ExprSelect::eval(EvalState & state, Env & env, Value & v)
|
||||||
{
|
{
|
||||||
Value v2;
|
Value v2;
|
||||||
state.eval(env, e, v2);
|
state.evalAttrs(env, e, v2);
|
||||||
state.forceAttrs(v2); // !!! eval followed by force is slightly inefficient
|
|
||||||
Bindings::iterator i = v2.attrs->find(name);
|
Bindings::iterator i = v2.attrs->find(name);
|
||||||
if (i == v2.attrs->end())
|
if (i == v2.attrs->end())
|
||||||
throwEvalError("attribute `%1%' missing", name);
|
throwEvalError("attribute `%1%' missing", name);
|
||||||
|
@ -499,8 +506,7 @@ void ExprSelect::eval(EvalState & state, Env & env, Value & v)
|
||||||
void ExprOpHasAttr::eval(EvalState & state, Env & env, Value & v)
|
void ExprOpHasAttr::eval(EvalState & state, Env & env, Value & v)
|
||||||
{
|
{
|
||||||
Value vAttrs;
|
Value vAttrs;
|
||||||
state.eval(env, e, vAttrs);
|
state.evalAttrs(env, e, vAttrs);
|
||||||
state.forceAttrs(vAttrs);
|
|
||||||
mkBool(v, vAttrs.attrs->find(name) != vAttrs.attrs->end());
|
mkBool(v, vAttrs.attrs->find(name) != vAttrs.attrs->end());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -640,8 +646,7 @@ void ExprWith::eval(EvalState & state, Env & env, Value & v)
|
||||||
Env & env2(state.allocEnv(1));
|
Env & env2(state.allocEnv(1));
|
||||||
env2.up = &env;
|
env2.up = &env;
|
||||||
|
|
||||||
state.eval(env, attrs, env2.values[0]);
|
state.evalAttrs(env, attrs, env2.values[0]);
|
||||||
state.forceAttrs(env2.values[0]);
|
|
||||||
|
|
||||||
/* If there is an enclosing `with', copy all attributes that don't
|
/* If there is an enclosing `with', copy all attributes that don't
|
||||||
appear in this `with'. */
|
appear in this `with'. */
|
||||||
|
@ -725,13 +730,11 @@ void ExprOpImpl::eval(EvalState & state, Env & env, Value & v)
|
||||||
void ExprOpUpdate::eval(EvalState & state, Env & env, Value & v)
|
void ExprOpUpdate::eval(EvalState & state, Env & env, Value & v)
|
||||||
{
|
{
|
||||||
Value v2;
|
Value v2;
|
||||||
state.eval(env, e1, v2);
|
state.evalAttrs(env, e1, v2);
|
||||||
state.forceAttrs(v2);
|
|
||||||
|
|
||||||
state.cloneAttrs(v2, v);
|
state.cloneAttrs(v2, v);
|
||||||
|
|
||||||
state.eval(env, e2, v2);
|
state.evalAttrs(env, e2, v2);
|
||||||
state.forceAttrs(v2);
|
|
||||||
|
|
||||||
foreach (Bindings::iterator, i, *v2.attrs)
|
foreach (Bindings::iterator, i, *v2.attrs)
|
||||||
mkCopy((*v.attrs)[i->first], i->second);
|
mkCopy((*v.attrs)[i->first], i->second);
|
||||||
|
|
|
@ -188,6 +188,7 @@ public:
|
||||||
/* Evaluation the expression, then verify that it has the expected
|
/* Evaluation the expression, then verify that it has the expected
|
||||||
type. */
|
type. */
|
||||||
bool evalBool(Env & env, Expr * e);
|
bool evalBool(Env & env, Expr * e);
|
||||||
|
void evalAttrs(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
|
||||||
|
|
|
@ -462,12 +462,11 @@ static void prim_derivationStrict(EvalState & state, Value * * args, Value & v)
|
||||||
static void prim_toPath(EvalState & state, Value * * args, Value & v)
|
static void prim_toPath(EvalState & state, Value * * args, Value & v)
|
||||||
{
|
{
|
||||||
PathSet context;
|
PathSet context;
|
||||||
string path = state.coerceToPath(*args[0], context);
|
Path path = state.coerceToPath(*args[0], context);
|
||||||
mkString(v, canonPath(path), context);
|
mkString(v, canonPath(path), context);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
#if 0
|
|
||||||
/* Allow a valid store path to be used in an expression. This is
|
/* Allow a valid store path to be used in an expression. This is
|
||||||
useful in some generated expressions such as in nix-push, which
|
useful in some generated expressions such as in nix-push, which
|
||||||
generates a call to a function with an already existing store path
|
generates a call to a function with an already existing store path
|
||||||
|
@ -479,16 +478,15 @@ static void prim_toPath(EvalState & state, Value * * args, Value & v)
|
||||||
static void prim_storePath(EvalState & state, Value * * args, Value & v)
|
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(state.coerceToPath(*args[0], context));
|
||||||
if (!isInStore(path))
|
if (!isInStore(path))
|
||||||
throw EvalError(format("path `%1%' is not in the Nix store") % path);
|
throw EvalError(format("path `%1%' is not in the Nix store") % path);
|
||||||
Path path2 = toStorePath(path);
|
Path path2 = toStorePath(path);
|
||||||
if (!store->isValidPath(path2))
|
if (!store->isValidPath(path2))
|
||||||
throw EvalError(format("store path `%1%' is not valid") % path2);
|
throw EvalError(format("store path `%1%' is not valid") % path2);
|
||||||
context.insert(path2);
|
context.insert(path2);
|
||||||
return makeStr(path, context);
|
mkString(v, path, context);
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
|
|
||||||
|
|
||||||
static void prim_pathExists(EvalState & state, Value * * args, Value & v)
|
static void prim_pathExists(EvalState & state, Value * * args, Value & v)
|
||||||
|
@ -738,35 +736,20 @@ static void prim_listToAttrs(EvalState & state, Value * * args, Value & v)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
#if 0
|
|
||||||
/* 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 void prim_intersectAttrs(EvalState & state, Value * * args, Value & v)
|
static void prim_intersectAttrs(EvalState & state, Value * * args, Value & v)
|
||||||
{
|
{
|
||||||
ATermMap as1, as2;
|
state.forceAttrs(*args[0]);
|
||||||
queryAllAttrs(evalExpr(state, args[0]), as1, true);
|
state.forceAttrs(*args[1]);
|
||||||
queryAllAttrs(evalExpr(state, args[1]), as2, true);
|
|
||||||
|
state.mkAttrs(v);
|
||||||
ATermMap res;
|
|
||||||
foreach (ATermMap::const_iterator, i, as2)
|
foreach (Bindings::iterator, i, *args[1]->attrs) {
|
||||||
if (as1[i->key]) res.set(i->key, i->value);
|
Bindings::iterator j = args[0]->attrs->find(i->first);
|
||||||
|
if (j != args[0]->attrs->end())
|
||||||
return makeAttrs(res);
|
mkCopy((*v.attrs)[i->first], i->second);
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
static void attrsInPattern(ATermMap & map, Pattern pat)
|
|
||||||
{
|
|
||||||
ATerm name;
|
|
||||||
ATermList formals;
|
|
||||||
ATermBool ellipsis;
|
|
||||||
if (matchAttrsPat(pat, formals, ellipsis, name)) {
|
|
||||||
for (ATermIterator i(formals); i; ++i) {
|
|
||||||
ATerm def;
|
|
||||||
if (!matchFormal(*i, name, def)) abort();
|
|
||||||
map.set(name, makeAttrRHS(makeBool(def != constNoDefaultValue), makeNoPos()));
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -786,17 +769,17 @@ static void attrsInPattern(ATermMap & map, Pattern pat)
|
||||||
*/
|
*/
|
||||||
static void prim_functionArgs(EvalState & state, Value * * args, Value & v)
|
static void prim_functionArgs(EvalState & state, Value * * args, Value & v)
|
||||||
{
|
{
|
||||||
Expr f = evalExpr(state, args[0]);
|
state.forceValue(*args[0]);
|
||||||
ATerm pat, body, pos;
|
if (args[0]->type != tLambda)
|
||||||
if (!matchFunction(f, pat, body, pos))
|
throw TypeError("`functionArgs' requires a function");
|
||||||
throw TypeError("`functionArgs' required a function");
|
|
||||||
|
|
||||||
ATermMap as;
|
|
||||||
attrsInPattern(as, pat);
|
|
||||||
|
|
||||||
return makeAttrs(as);
|
state.mkAttrs(v);
|
||||||
|
|
||||||
|
if (!args[0]->lambda.fun->matchAttrs) return;
|
||||||
|
|
||||||
|
foreach (Formals::Formals_::iterator, i, args[0]->lambda.fun->formals->formals)
|
||||||
|
mkBool((*v.attrs)[i->name], i->def);
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
|
|
||||||
|
|
||||||
/*************************************************************
|
/*************************************************************
|
||||||
|
@ -948,7 +931,6 @@ static void prim_unsafeDiscardStringContext(EvalState & state, Value * * args, V
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
#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
|
||||||
|
@ -958,7 +940,7 @@ static void prim_unsafeDiscardStringContext(EvalState & state, Value * * args, V
|
||||||
static void prim_unsafeDiscardOutputDependency(EvalState & state, Value * * args, Value & v)
|
static void prim_unsafeDiscardOutputDependency(EvalState & state, Value * * args, Value & v)
|
||||||
{
|
{
|
||||||
PathSet context;
|
PathSet context;
|
||||||
string s = coerceToString(state, args[0], context);
|
string s = state.coerceToString(*args[0], context);
|
||||||
|
|
||||||
PathSet context2;
|
PathSet context2;
|
||||||
foreach (PathSet::iterator, i, context) {
|
foreach (PathSet::iterator, i, context) {
|
||||||
|
@ -967,9 +949,8 @@ static void prim_unsafeDiscardOutputDependency(EvalState & state, Value * * args
|
||||||
context2.insert(p);
|
context2.insert(p);
|
||||||
}
|
}
|
||||||
|
|
||||||
return makeStr(s, context2);
|
mkString(v, s, context2);
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
|
|
||||||
|
|
||||||
/*************************************************************
|
/*************************************************************
|
||||||
|
@ -1056,9 +1037,7 @@ void EvalState::createBaseEnv()
|
||||||
|
|
||||||
// Paths
|
// Paths
|
||||||
addPrimOp("__toPath", 1, prim_toPath);
|
addPrimOp("__toPath", 1, prim_toPath);
|
||||||
#if 0
|
|
||||||
addPrimOp("__storePath", 1, prim_storePath);
|
addPrimOp("__storePath", 1, prim_storePath);
|
||||||
#endif
|
|
||||||
addPrimOp("__pathExists", 1, prim_pathExists);
|
addPrimOp("__pathExists", 1, prim_pathExists);
|
||||||
addPrimOp("baseNameOf", 1, prim_baseNameOf);
|
addPrimOp("baseNameOf", 1, prim_baseNameOf);
|
||||||
addPrimOp("dirOf", 1, prim_dirOf);
|
addPrimOp("dirOf", 1, prim_dirOf);
|
||||||
|
@ -1076,10 +1055,8 @@ void EvalState::createBaseEnv()
|
||||||
addPrimOp("__isAttrs", 1, prim_isAttrs);
|
addPrimOp("__isAttrs", 1, prim_isAttrs);
|
||||||
addPrimOp("removeAttrs", 2, prim_removeAttrs);
|
addPrimOp("removeAttrs", 2, prim_removeAttrs);
|
||||||
addPrimOp("__listToAttrs", 1, prim_listToAttrs);
|
addPrimOp("__listToAttrs", 1, prim_listToAttrs);
|
||||||
#if 0
|
|
||||||
addPrimOp("__intersectAttrs", 2, prim_intersectAttrs);
|
addPrimOp("__intersectAttrs", 2, prim_intersectAttrs);
|
||||||
addPrimOp("__functionArgs", 1, prim_functionArgs);
|
addPrimOp("__functionArgs", 1, prim_functionArgs);
|
||||||
#endif
|
|
||||||
|
|
||||||
// Lists
|
// Lists
|
||||||
addPrimOp("__isList", 1, prim_isList);
|
addPrimOp("__isList", 1, prim_isList);
|
||||||
|
@ -1100,9 +1077,7 @@ void EvalState::createBaseEnv()
|
||||||
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);
|
||||||
#if 0
|
|
||||||
addPrimOp("__unsafeDiscardOutputDependency", 1, prim_unsafeDiscardOutputDependency);
|
addPrimOp("__unsafeDiscardOutputDependency", 1, prim_unsafeDiscardOutputDependency);
|
||||||
#endif
|
|
||||||
|
|
||||||
// Versions
|
// Versions
|
||||||
addPrimOp("__parseDrvName", 1, prim_parseDrvName);
|
addPrimOp("__parseDrvName", 1, prim_parseDrvName);
|
||||||
|
|
Loading…
Reference in a new issue