mirror of
https://github.com/NixOS/nix
synced 2025-06-26 20:01:15 +02:00
* Don't use ATmake / ATmatch anymore, nor the ATMatcher class.
Instead we generate data bindings (build and match functions) for the constructors specified in `constructors.def'. In particular this removes the conversions between AFuns and strings, and Nix expression evaluation now seems 3 to 4 times faster.
This commit is contained in:
parent
eb8284ddaa
commit
5fe9222b36
11 changed files with 410 additions and 304 deletions
|
@ -1,18 +1,18 @@
|
|||
#include "normalise.hh"
|
||||
#include "eval.hh"
|
||||
#include "globals.hh"
|
||||
#include "constructors.hh"
|
||||
|
||||
|
||||
/* Load and evaluate an expression from path specified by the
|
||||
argument. */
|
||||
static Expr primImport(EvalState & state, const ATermVector & args)
|
||||
{
|
||||
ATMatcher m;
|
||||
string path;
|
||||
ATerm path;
|
||||
Expr fn = evalExpr(state, args[0]);
|
||||
if (!(atMatch(m, fn) >> "Path" >> path))
|
||||
if (!matchPath(fn, path))
|
||||
throw Error("path expected");
|
||||
return evalFile(state, path);
|
||||
return evalFile(state, aterm2String(path));
|
||||
}
|
||||
|
||||
|
||||
|
@ -86,24 +86,23 @@ static void processBinding(EvalState & state, Expr e, StoreExpr & ne,
|
|||
{
|
||||
e = evalExpr(state, e);
|
||||
|
||||
ATMatcher m;
|
||||
string s;
|
||||
ATerm s;
|
||||
ATermList es;
|
||||
int n;
|
||||
Expr e1, e2;
|
||||
|
||||
if (atMatch(m, e) >> "Str" >> s) ss.push_back(s);
|
||||
else if (atMatch(m, e) >> "Uri" >> s) ss.push_back(s);
|
||||
else if (atMatch(m, e) >> "Bool" >> "True") ss.push_back("1");
|
||||
else if (atMatch(m, e) >> "Bool" >> "False") ss.push_back("");
|
||||
if (matchStr(e, s)) ss.push_back(aterm2String(s));
|
||||
else if (matchUri(e, s)) ss.push_back(aterm2String(s));
|
||||
else if (e == eTrue) ss.push_back("1");
|
||||
else if (e == eFalse) ss.push_back("");
|
||||
|
||||
else if (atMatch(m, e) >> "Int" >> n) {
|
||||
else if (matchInt(e, n)) {
|
||||
ostringstream st;
|
||||
st << n;
|
||||
ss.push_back(st.str());
|
||||
}
|
||||
|
||||
else if (atMatch(m, e) >> "Attrs") {
|
||||
else if (matchAttrs(e, es)) {
|
||||
Expr a = queryAttr(e, "type");
|
||||
if (a && evalString(state, a) == "derivation") {
|
||||
a = queryAttr(e, "drvPath");
|
||||
|
@ -127,30 +126,29 @@ static void processBinding(EvalState & state, Expr e, StoreExpr & ne,
|
|||
throw Error("invalid derivation attribute");
|
||||
}
|
||||
|
||||
else if (atMatch(m, e) >> "Path" >> s) {
|
||||
Path drvPath = copyAtom(state, s);
|
||||
else if (matchPath(e, s)) {
|
||||
Path drvPath = copyAtom(state, aterm2String(s));
|
||||
ss.push_back(addInput(state, drvPath, ne));
|
||||
}
|
||||
|
||||
else if (atMatch(m, e) >> "List" >> es) {
|
||||
else if (matchList(e, es)) {
|
||||
for (ATermIterator i(es); i; ++i) {
|
||||
startNest(nest, lvlVomit, format("processing list element"));
|
||||
processBinding(state, evalExpr(state, *i), ne, ss);
|
||||
}
|
||||
}
|
||||
|
||||
else if (atMatch(m, e) >> "Null") ss.push_back("");
|
||||
else if (matchNull(e)) ss.push_back("");
|
||||
|
||||
else if (atMatch(m, e) >> "SubPath" >> e1 >> e2) {
|
||||
else if (matchSubPath(e, e1, e2)) {
|
||||
Strings ss2;
|
||||
processBinding(state, evalExpr(state, e1), ne, ss2);
|
||||
if (ss2.size() != 1)
|
||||
throw Error("left-hand side of `~' operator cannot be a list");
|
||||
e2 = evalExpr(state, e2);
|
||||
if (!(atMatch(m, e2) >> "Str" >> s ||
|
||||
(atMatch(m, e2) >> "Path" >> s)))
|
||||
if (!(matchStr(e2, s) || matchPath(e2, s)))
|
||||
throw Error("right-hand side of `~' operator must be a path or string");
|
||||
ss.push_back(canonPath(ss2.front() + "/" + s));
|
||||
ss.push_back(canonPath(ss2.front() + "/" + aterm2String(s)));
|
||||
}
|
||||
|
||||
else throw Error("invalid derivation attribute");
|
||||
|
@ -198,8 +196,7 @@ static Expr primDerivation(EvalState & state, const ATermVector & _args)
|
|||
ATerm value;
|
||||
Expr pos;
|
||||
ATerm rhs = attrs.get(key);
|
||||
ATMatcher m;
|
||||
if (!(atMatch(m, rhs) >> "" >> value >> pos)) abort();
|
||||
if (!matchAttrRHS(rhs, value, pos)) abort();
|
||||
startNest(nest, lvlVomit, format("processing attribute `%1%'") % key);
|
||||
|
||||
Strings ss;
|
||||
|
@ -272,10 +269,11 @@ static Expr primDerivation(EvalState & state, const ATermVector & _args)
|
|||
printMsg(lvlChatty, format("instantiated `%1%' -> `%2%'")
|
||||
% drvName % drvPath);
|
||||
|
||||
attrs.set("outPath", ATmake("(Path(<str>), NoPos)", outPath.c_str()));
|
||||
attrs.set("drvPath", ATmake("(Path(<str>), NoPos)", drvPath.c_str()));
|
||||
attrs.set("drvHash", ATmake("(<term>, NoPos)", makeString(drvHash)));
|
||||
attrs.set("type", ATmake("(<term>, NoPos)", makeString("derivation")));
|
||||
attrs.set("outPath", makeAttrRHS(makePath(string2ATerm(outPath.c_str())), makeNoPos()));
|
||||
attrs.set("drvPath", makeAttrRHS(makePath(string2ATerm(drvPath.c_str())), makeNoPos()));
|
||||
attrs.set("drvHash",
|
||||
makeAttrRHS(makeStr(string2ATerm(((string) drvHash).c_str())), makeNoPos()));
|
||||
attrs.set("type", makeAttrRHS(makeStr(string2ATerm("derivation")), makeNoPos()));
|
||||
|
||||
return makeAttrs(attrs);
|
||||
}
|
||||
|
@ -285,7 +283,7 @@ static Expr primDerivation(EvalState & state, const ATermVector & _args)
|
|||
following the last slash. */
|
||||
static Expr primBaseNameOf(EvalState & state, const ATermVector & args)
|
||||
{
|
||||
return makeString(baseNameOf(evalString(state, args[0])));
|
||||
return makeStr(string2ATerm(baseNameOf(evalString(state, args[0])).c_str()));
|
||||
}
|
||||
|
||||
|
||||
|
@ -293,12 +291,9 @@ static Expr primBaseNameOf(EvalState & state, const ATermVector & args)
|
|||
static Expr primToString(EvalState & state, const ATermVector & args)
|
||||
{
|
||||
Expr arg = evalExpr(state, args[0]);
|
||||
ATMatcher m;
|
||||
string s;
|
||||
if (atMatch(m, arg) >> "Str" >> s ||
|
||||
atMatch(m, arg) >> "Path" >> s ||
|
||||
atMatch(m, arg) >> "Uri" >> s)
|
||||
return makeString(s);
|
||||
ATerm s;
|
||||
if (matchStr(arg, s) || matchPath(arg, s) || matchUri(arg, s))
|
||||
return makeStr(s);
|
||||
else throw Error("cannot coerce value to string");
|
||||
}
|
||||
|
||||
|
@ -306,29 +301,27 @@ static Expr primToString(EvalState & state, const ATermVector & args)
|
|||
/* Boolean constructors. */
|
||||
static Expr primTrue(EvalState & state, const ATermVector & args)
|
||||
{
|
||||
return ATmake("Bool(True)");
|
||||
return eTrue;
|
||||
}
|
||||
|
||||
|
||||
static Expr primFalse(EvalState & state, const ATermVector & args)
|
||||
{
|
||||
return ATmake("Bool(False)");
|
||||
return eFalse;
|
||||
}
|
||||
|
||||
|
||||
/* Return the null value. */
|
||||
Expr primNull(EvalState & state, const ATermVector & args)
|
||||
{
|
||||
return ATmake("Null");
|
||||
return makeNull();
|
||||
}
|
||||
|
||||
|
||||
/* Determine whether the argument is the null value. */
|
||||
Expr primIsNull(EvalState & state, const ATermVector & args)
|
||||
{
|
||||
Expr arg = evalExpr(state, args[0]);
|
||||
ATMatcher m;
|
||||
return makeBool(atMatch(m, arg) >> "Null");
|
||||
return makeBool(matchNull(evalExpr(state, args[0])));
|
||||
}
|
||||
|
||||
|
||||
|
@ -338,18 +331,15 @@ Expr primMap(EvalState & state, const ATermVector & args)
|
|||
Expr fun = evalExpr(state, args[0]);
|
||||
Expr list = evalExpr(state, args[1]);
|
||||
|
||||
ATMatcher m;
|
||||
|
||||
ATermList list2;
|
||||
if (!(atMatch(m, list) >> "List" >> list2))
|
||||
if (!matchList(list, list2))
|
||||
throw Error("`map' expects a list as its second argument");
|
||||
|
||||
ATermList list3 = ATempty;
|
||||
for (ATermIterator i(list2); i; ++i)
|
||||
list3 = ATinsert(list3,
|
||||
ATmake("Call(<term>, <term>)", fun, *i));
|
||||
list3 = ATinsert(list3, makeCall(fun, *i));
|
||||
|
||||
return ATmake("List(<term>)", ATreverse(list3));
|
||||
return makeList(ATreverse(list3));
|
||||
}
|
||||
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue