mirror of
https://github.com/privatevoid-net/nix-super.git
synced 2024-11-10 08:16:15 +02:00
* An forward non-random access input iterator class for ATermLists.
This commit is contained in:
parent
3e5a019a07
commit
45610ae675
6 changed files with 68 additions and 88 deletions
|
@ -21,25 +21,21 @@ static Expr substArgs(Expr body, ATermList formals, Expr arg)
|
|||
Expr undefined = ATmake("Undefined");
|
||||
|
||||
/* Get the formal arguments. */
|
||||
while (!ATisEmpty(formals)) {
|
||||
ATerm t = ATgetFirst(formals);
|
||||
for (ATermIterator i(formals); i; ++i) {
|
||||
Expr name, def;
|
||||
if (atMatch(m, t) >> "NoDefFormal" >> name)
|
||||
if (atMatch(m, *i) >> "NoDefFormal" >> name)
|
||||
subs.set(name, undefined);
|
||||
else if (atMatch(m, t) >> "DefFormal" >> name >> def)
|
||||
else if (atMatch(m, *i) >> "DefFormal" >> name >> def)
|
||||
subs.set(name, def);
|
||||
else abort(); /* can't happen */
|
||||
formals = ATgetNext(formals);
|
||||
}
|
||||
|
||||
/* Get the actual arguments, and check that they match with the
|
||||
formals. */
|
||||
ATermMap args;
|
||||
queryAllAttrs(arg, args);
|
||||
for (ATermList keys = args.keys(); !ATisEmpty(keys);
|
||||
keys = ATgetNext(keys))
|
||||
{
|
||||
Expr key = ATgetFirst(keys);
|
||||
for (ATermIterator i(args.keys()); i; ++i) {
|
||||
Expr key = *i;
|
||||
Expr cur = subs.get(key);
|
||||
if (!cur)
|
||||
throw badTerm(format("function has no formal argument `%1%'")
|
||||
|
@ -48,14 +44,10 @@ static Expr substArgs(Expr body, ATermList formals, Expr arg)
|
|||
}
|
||||
|
||||
/* Check that all arguments are defined. */
|
||||
for (ATermList keys = subs.keys(); !ATisEmpty(keys);
|
||||
keys = ATgetNext(keys))
|
||||
{
|
||||
Expr key = ATgetFirst(keys);
|
||||
if (subs.get(key) == undefined)
|
||||
for (ATermIterator i(subs.keys()); i; ++i)
|
||||
if (subs.get(*i) == undefined)
|
||||
throw badTerm(format("formal argument `%1%' missing")
|
||||
% aterm2String(key), arg);
|
||||
}
|
||||
% aterm2String(*i), arg);
|
||||
|
||||
return substitute(subs, body);
|
||||
}
|
||||
|
@ -72,26 +64,22 @@ ATerm expandRec(ATerm e, ATermList bnds)
|
|||
|
||||
/* Create the substitution list. */
|
||||
ATermMap subs;
|
||||
ATermList bs = bnds;
|
||||
while (!ATisEmpty(bs)) {
|
||||
for (ATermIterator i(bnds); i; ++i) {
|
||||
string s;
|
||||
Expr e2;
|
||||
if (!(atMatch(m, ATgetFirst(bs)) >> "Bind" >> s >> e2))
|
||||
if (!(atMatch(m, *i) >> "Bind" >> s >> e2))
|
||||
abort(); /* can't happen */
|
||||
subs.set(s, ATmake("Select(<term>, <str>)", e, s.c_str()));
|
||||
bs = ATgetNext(bs);
|
||||
}
|
||||
|
||||
/* Create the non-recursive set. */
|
||||
ATermMap as;
|
||||
bs = bnds;
|
||||
while (!ATisEmpty(bs)) {
|
||||
for (ATermIterator i(bnds); i; ++i) {
|
||||
string s;
|
||||
Expr e2;
|
||||
if (!(atMatch(m, ATgetFirst(bs)) >> "Bind" >> s >> e2))
|
||||
if (!(atMatch(m, *i) >> "Bind" >> s >> e2))
|
||||
abort(); /* can't happen */
|
||||
as.set(s, substitute(subs, e2));
|
||||
bs = ATgetNext(bs);
|
||||
}
|
||||
|
||||
return makeAttrs(as);
|
||||
|
|
|
@ -18,10 +18,8 @@ ATermMap::ATermMap(const ATermMap & map)
|
|||
table = ATtableCreate(ATgetLength(keys), map.maxLoadPct);
|
||||
if (!table) throw Error("cannot create ATerm table");
|
||||
|
||||
for (; !ATisEmpty(keys); keys = ATgetNext(keys)) {
|
||||
ATerm key = ATgetFirst(keys);
|
||||
set(key, map.get(key));
|
||||
}
|
||||
for (ATermIterator i(keys); i; ++i)
|
||||
set(*i, map.get(*i));
|
||||
}
|
||||
|
||||
|
||||
|
@ -104,10 +102,8 @@ ATerm bottomupRewrite(TermFun & f, ATerm e)
|
|||
ATermList in = (ATermList) e;
|
||||
ATermList out = ATempty;
|
||||
|
||||
while (!ATisEmpty(in)) {
|
||||
out = ATinsert(out, bottomupRewrite(f, ATgetFirst(in)));
|
||||
in = ATgetNext(in);
|
||||
}
|
||||
for (ATermIterator i(in); i; ++i)
|
||||
out = ATinsert(out, bottomupRewrite(f, *i));
|
||||
|
||||
e = (ATerm) ATreverse(out);
|
||||
}
|
||||
|
@ -123,13 +119,12 @@ void queryAllAttrs(Expr e, ATermMap & attrs)
|
|||
if (!(atMatch(m, e) >> "Attrs" >> bnds))
|
||||
throw badTerm("expected attribute set", e);
|
||||
|
||||
while (!ATisEmpty(bnds)) {
|
||||
for (ATermIterator i(bnds); i; ++i) {
|
||||
string s;
|
||||
Expr e;
|
||||
if (!(atMatch(m, ATgetFirst(bnds)) >> "Bind" >> s >> e))
|
||||
if (!(atMatch(m, *i) >> "Bind" >> s >> e))
|
||||
abort(); /* can't happen */
|
||||
attrs.set(s, e);
|
||||
bnds = ATgetNext(bnds);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -144,13 +139,10 @@ Expr queryAttr(Expr e, const string & name)
|
|||
|
||||
Expr makeAttrs(const ATermMap & attrs)
|
||||
{
|
||||
ATermList bnds = ATempty, keys = attrs.keys();
|
||||
while (!ATisEmpty(keys)) {
|
||||
Expr key = ATgetFirst(keys);
|
||||
ATermList bnds = ATempty;
|
||||
for (ATermIterator i(attrs.keys()); i; ++i)
|
||||
bnds = ATinsert(bnds,
|
||||
ATmake("Bind(<term>, <term>)", key, attrs.get(key)));
|
||||
keys = ATgetNext(keys);
|
||||
}
|
||||
ATmake("Bind(<term>, <term>)", *i, attrs.get(*i)));
|
||||
return ATmake("Attrs(<term>)", ATreverse(bnds));
|
||||
}
|
||||
|
||||
|
@ -171,14 +163,12 @@ Expr substitute(const ATermMap & subs, Expr e)
|
|||
ATerm body;
|
||||
if (atMatch(m, e) >> "Function" >> formals >> body) {
|
||||
ATermMap subs2(subs);
|
||||
ATermList fs = formals;
|
||||
while (!ATisEmpty(fs)) {
|
||||
for (ATermIterator i(formals); i; ++i) {
|
||||
Expr def;
|
||||
if (!(atMatch(m, ATgetFirst(fs)) >> "NoDefFormal" >> s) &&
|
||||
!(atMatch(m, ATgetFirst(fs)) >> "DefFormal" >> s >> def))
|
||||
if (!(atMatch(m, *i) >> "NoDefFormal" >> s) &&
|
||||
!(atMatch(m, *i) >> "DefFormal" >> s >> def))
|
||||
abort();
|
||||
subs2.remove(s);
|
||||
fs = ATgetNext(fs);
|
||||
}
|
||||
return ATmake("Function(<term>, <term>)", formals,
|
||||
substitute(subs2, body));
|
||||
|
@ -188,13 +178,11 @@ Expr substitute(const ATermMap & subs, Expr e)
|
|||
ATermList bindings;
|
||||
if (atMatch(m, e) >> "Rec" >> bindings) {
|
||||
ATermMap subs2(subs);
|
||||
ATermList bnds = bindings;
|
||||
while (!ATisEmpty(bnds)) {
|
||||
for (ATermIterator i(bindings); i; ++i) {
|
||||
Expr e;
|
||||
if (!(atMatch(m, ATgetFirst(bnds)) >> "Bind" >> s >> e))
|
||||
if (!(atMatch(m, *i) >> "Bind" >> s >> e))
|
||||
abort(); /* can't happen */
|
||||
subs2.remove(s);
|
||||
bnds = ATgetNext(bnds);
|
||||
}
|
||||
return ATmake("Rec(<term>)", substitute(subs2, (ATerm) bindings));
|
||||
}
|
||||
|
@ -211,14 +199,9 @@ Expr substitute(const ATermMap & subs, Expr e)
|
|||
}
|
||||
|
||||
if (ATgetType(e) == AT_LIST) {
|
||||
ATermList in = (ATermList) e;
|
||||
ATermList out = ATempty;
|
||||
|
||||
while (!ATisEmpty(in)) {
|
||||
out = ATinsert(out, substitute(subs, ATgetFirst(in)));
|
||||
in = ATgetNext(in);
|
||||
}
|
||||
|
||||
for (ATermIterator i((ATermList) e); i; ++i)
|
||||
out = ATinsert(out, substitute(subs, *i));
|
||||
return (ATerm) ATreverse(out);
|
||||
}
|
||||
|
||||
|
|
|
@ -54,10 +54,8 @@ static void printNixExpr(EvalState & state, Expr e)
|
|||
}
|
||||
|
||||
if (ATgetType(e) == AT_LIST) {
|
||||
while (!ATisEmpty(es)) {
|
||||
printNixExpr(state, evalExpr(state, ATgetFirst(es)));
|
||||
es = ATgetNext(es);
|
||||
}
|
||||
for (ATermIterator i((ATermList) e); i; ++i)
|
||||
printNixExpr(state, evalExpr(state, *i));
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
|
@ -108,11 +108,10 @@ static string processBinding(EvalState & state, Expr e, NixExpr & ne)
|
|||
if (atMatch(m, e) >> "List" >> es) {
|
||||
string s;
|
||||
bool first = true;
|
||||
while (!ATisEmpty(es)) {
|
||||
for (ATermIterator i(es); i; ++i) {
|
||||
startNest(nest, lvlVomit, format("processing list element"));
|
||||
if (!first) s = s + " "; else first = false;
|
||||
s += processBinding(state, evalExpr(state, ATgetFirst(es)), ne);
|
||||
es = ATgetNext(es);
|
||||
s += processBinding(state, evalExpr(state, *i), ne);
|
||||
}
|
||||
return s;
|
||||
}
|
||||
|
@ -140,10 +139,8 @@ Expr primDerivation(EvalState & state, Expr args)
|
|||
Hash outHash;
|
||||
bool outHashGiven = false;
|
||||
|
||||
for (ATermList keys = attrs.keys(); !ATisEmpty(keys);
|
||||
keys = ATgetNext(keys))
|
||||
{
|
||||
string key = aterm2String(ATgetFirst(keys));
|
||||
for (ATermIterator i(attrs.keys()); i; ++i) {
|
||||
string key = aterm2String(*i);
|
||||
Expr value = attrs.get(key);
|
||||
startNest(nest, lvlVomit, format("processing attribute `%1%'") % key);
|
||||
|
||||
|
|
|
@ -14,6 +14,28 @@ string atPrint(ATerm t);
|
|||
/* Write an ATerm to an output stream. */
|
||||
ostream & operator << (ostream & stream, ATerm e);
|
||||
|
||||
class ATermIterator
|
||||
{
|
||||
ATermList t;
|
||||
|
||||
public:
|
||||
ATermIterator(ATermList _t) : t(_t) { }
|
||||
ATermIterator & operator ++ ()
|
||||
{
|
||||
t = ATgetNext(t);
|
||||
return *this;
|
||||
}
|
||||
ATerm operator * ()
|
||||
{
|
||||
return ATgetFirst(t);
|
||||
}
|
||||
operator bool ()
|
||||
{
|
||||
return t != ATempty;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
/* Type-safe matching. */
|
||||
|
||||
struct ATMatcher
|
||||
|
|
|
@ -43,13 +43,11 @@ Path writeTerm(ATerm t, const string & suffix)
|
|||
static void parsePaths(ATermList paths, PathSet & out)
|
||||
{
|
||||
ATMatcher m;
|
||||
while (!ATisEmpty(paths)) {
|
||||
for (ATermIterator i(paths); i; ++i) {
|
||||
string s;
|
||||
ATerm t = ATgetFirst(paths);
|
||||
if (!(atMatch(m, t) >> s))
|
||||
throw badTerm("not a path", t);
|
||||
if (!(atMatch(m, *i) >> s))
|
||||
throw badTerm("not a path", *i);
|
||||
out.insert(s);
|
||||
paths = ATgetNext(paths);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -91,16 +89,14 @@ static bool parseClosure(ATerm t, Closure & closure)
|
|||
|
||||
parsePaths(roots, closure.roots);
|
||||
|
||||
while (!ATisEmpty(elems)) {
|
||||
for (ATermIterator i(elems); i; ++i) {
|
||||
string path;
|
||||
ATermList refs;
|
||||
ATerm t = ATgetFirst(elems);
|
||||
if (!(atMatch(m, t) >> "" >> path >> refs))
|
||||
throw badTerm("not a closure element", t);
|
||||
if (!(atMatch(m, *i) >> "" >> path >> refs))
|
||||
throw badTerm("not a closure element", *i);
|
||||
ClosureElem elem;
|
||||
parsePaths(refs, elem.refs);
|
||||
closure.elems[path] = elem;
|
||||
elems = ATgetNext(elems);
|
||||
}
|
||||
|
||||
checkClosure(closure);
|
||||
|
@ -124,22 +120,18 @@ static bool parseDerivation(ATerm t, Derivation & derivation)
|
|||
derivation.builder = builder;
|
||||
derivation.platform = platform;
|
||||
|
||||
while (!ATisEmpty(args)) {
|
||||
for (ATermIterator i(args); i; ++i) {
|
||||
string s;
|
||||
ATerm arg = ATgetFirst(args);
|
||||
if (!(atMatch(m, arg) >> s))
|
||||
throw badTerm("string expected", arg);
|
||||
if (!(atMatch(m, *i) >> s))
|
||||
throw badTerm("string expected", *i);
|
||||
derivation.args.push_back(s);
|
||||
args = ATgetNext(args);
|
||||
}
|
||||
|
||||
while (!ATisEmpty(bnds)) {
|
||||
for (ATermIterator i(bnds); i; ++i) {
|
||||
string s1, s2;
|
||||
ATerm bnd = ATgetFirst(bnds);
|
||||
if (!(atMatch(m, bnd) >> "" >> s1 >> s2))
|
||||
throw badTerm("tuple of strings expected", bnd);
|
||||
if (!(atMatch(m, *i) >> "" >> s1 >> s2))
|
||||
throw badTerm("tuple of strings expected", *i);
|
||||
derivation.env[s1] = s2;
|
||||
bnds = ATgetNext(bnds);
|
||||
}
|
||||
|
||||
return true;
|
||||
|
|
Loading…
Reference in a new issue