* An forward non-random access input iterator class for ATermLists.

This commit is contained in:
Eelco Dolstra 2003-11-16 18:31:29 +00:00
parent 3e5a019a07
commit 45610ae675
6 changed files with 68 additions and 88 deletions

View file

@ -21,25 +21,21 @@ static Expr substArgs(Expr body, ATermList formals, Expr arg)
Expr undefined = ATmake("Undefined"); Expr undefined = ATmake("Undefined");
/* Get the formal arguments. */ /* Get the formal arguments. */
while (!ATisEmpty(formals)) { for (ATermIterator i(formals); i; ++i) {
ATerm t = ATgetFirst(formals);
Expr name, def; Expr name, def;
if (atMatch(m, t) >> "NoDefFormal" >> name) if (atMatch(m, *i) >> "NoDefFormal" >> name)
subs.set(name, undefined); subs.set(name, undefined);
else if (atMatch(m, t) >> "DefFormal" >> name >> def) else if (atMatch(m, *i) >> "DefFormal" >> name >> def)
subs.set(name, def); subs.set(name, def);
else abort(); /* can't happen */ else abort(); /* can't happen */
formals = ATgetNext(formals);
} }
/* Get the actual arguments, and check that they match with the /* Get the actual arguments, and check that they match with the
formals. */ formals. */
ATermMap args; ATermMap args;
queryAllAttrs(arg, args); queryAllAttrs(arg, args);
for (ATermList keys = args.keys(); !ATisEmpty(keys); for (ATermIterator i(args.keys()); i; ++i) {
keys = ATgetNext(keys)) Expr key = *i;
{
Expr key = ATgetFirst(keys);
Expr cur = subs.get(key); Expr cur = subs.get(key);
if (!cur) if (!cur)
throw badTerm(format("function has no formal argument `%1%'") 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. */ /* Check that all arguments are defined. */
for (ATermList keys = subs.keys(); !ATisEmpty(keys); for (ATermIterator i(subs.keys()); i; ++i)
keys = ATgetNext(keys)) if (subs.get(*i) == undefined)
{
Expr key = ATgetFirst(keys);
if (subs.get(key) == undefined)
throw badTerm(format("formal argument `%1%' missing") throw badTerm(format("formal argument `%1%' missing")
% aterm2String(key), arg); % aterm2String(*i), arg);
}
return substitute(subs, body); return substitute(subs, body);
} }
@ -72,26 +64,22 @@ ATerm expandRec(ATerm e, ATermList bnds)
/* Create the substitution list. */ /* Create the substitution list. */
ATermMap subs; ATermMap subs;
ATermList bs = bnds; for (ATermIterator i(bnds); i; ++i) {
while (!ATisEmpty(bs)) {
string s; string s;
Expr e2; Expr e2;
if (!(atMatch(m, ATgetFirst(bs)) >> "Bind" >> s >> e2)) if (!(atMatch(m, *i) >> "Bind" >> s >> e2))
abort(); /* can't happen */ abort(); /* can't happen */
subs.set(s, ATmake("Select(<term>, <str>)", e, s.c_str())); subs.set(s, ATmake("Select(<term>, <str>)", e, s.c_str()));
bs = ATgetNext(bs);
} }
/* Create the non-recursive set. */ /* Create the non-recursive set. */
ATermMap as; ATermMap as;
bs = bnds; for (ATermIterator i(bnds); i; ++i) {
while (!ATisEmpty(bs)) {
string s; string s;
Expr e2; Expr e2;
if (!(atMatch(m, ATgetFirst(bs)) >> "Bind" >> s >> e2)) if (!(atMatch(m, *i) >> "Bind" >> s >> e2))
abort(); /* can't happen */ abort(); /* can't happen */
as.set(s, substitute(subs, e2)); as.set(s, substitute(subs, e2));
bs = ATgetNext(bs);
} }
return makeAttrs(as); return makeAttrs(as);

View file

@ -18,10 +18,8 @@ ATermMap::ATermMap(const ATermMap & map)
table = ATtableCreate(ATgetLength(keys), map.maxLoadPct); table = ATtableCreate(ATgetLength(keys), map.maxLoadPct);
if (!table) throw Error("cannot create ATerm table"); if (!table) throw Error("cannot create ATerm table");
for (; !ATisEmpty(keys); keys = ATgetNext(keys)) { for (ATermIterator i(keys); i; ++i)
ATerm key = ATgetFirst(keys); set(*i, map.get(*i));
set(key, map.get(key));
}
} }
@ -104,10 +102,8 @@ ATerm bottomupRewrite(TermFun & f, ATerm e)
ATermList in = (ATermList) e; ATermList in = (ATermList) e;
ATermList out = ATempty; ATermList out = ATempty;
while (!ATisEmpty(in)) { for (ATermIterator i(in); i; ++i)
out = ATinsert(out, bottomupRewrite(f, ATgetFirst(in))); out = ATinsert(out, bottomupRewrite(f, *i));
in = ATgetNext(in);
}
e = (ATerm) ATreverse(out); e = (ATerm) ATreverse(out);
} }
@ -123,13 +119,12 @@ void queryAllAttrs(Expr e, ATermMap & attrs)
if (!(atMatch(m, e) >> "Attrs" >> bnds)) if (!(atMatch(m, e) >> "Attrs" >> bnds))
throw badTerm("expected attribute set", e); throw badTerm("expected attribute set", e);
while (!ATisEmpty(bnds)) { for (ATermIterator i(bnds); i; ++i) {
string s; string s;
Expr e; Expr e;
if (!(atMatch(m, ATgetFirst(bnds)) >> "Bind" >> s >> e)) if (!(atMatch(m, *i) >> "Bind" >> s >> e))
abort(); /* can't happen */ abort(); /* can't happen */
attrs.set(s, e); attrs.set(s, e);
bnds = ATgetNext(bnds);
} }
} }
@ -144,13 +139,10 @@ Expr queryAttr(Expr e, const string & name)
Expr makeAttrs(const ATermMap & attrs) Expr makeAttrs(const ATermMap & attrs)
{ {
ATermList bnds = ATempty, keys = attrs.keys(); ATermList bnds = ATempty;
while (!ATisEmpty(keys)) { for (ATermIterator i(attrs.keys()); i; ++i)
Expr key = ATgetFirst(keys);
bnds = ATinsert(bnds, bnds = ATinsert(bnds,
ATmake("Bind(<term>, <term>)", key, attrs.get(key))); ATmake("Bind(<term>, <term>)", *i, attrs.get(*i)));
keys = ATgetNext(keys);
}
return ATmake("Attrs(<term>)", ATreverse(bnds)); return ATmake("Attrs(<term>)", ATreverse(bnds));
} }
@ -171,14 +163,12 @@ Expr substitute(const ATermMap & subs, Expr e)
ATerm body; ATerm body;
if (atMatch(m, e) >> "Function" >> formals >> body) { if (atMatch(m, e) >> "Function" >> formals >> body) {
ATermMap subs2(subs); ATermMap subs2(subs);
ATermList fs = formals; for (ATermIterator i(formals); i; ++i) {
while (!ATisEmpty(fs)) {
Expr def; Expr def;
if (!(atMatch(m, ATgetFirst(fs)) >> "NoDefFormal" >> s) && if (!(atMatch(m, *i) >> "NoDefFormal" >> s) &&
!(atMatch(m, ATgetFirst(fs)) >> "DefFormal" >> s >> def)) !(atMatch(m, *i) >> "DefFormal" >> s >> def))
abort(); abort();
subs2.remove(s); subs2.remove(s);
fs = ATgetNext(fs);
} }
return ATmake("Function(<term>, <term>)", formals, return ATmake("Function(<term>, <term>)", formals,
substitute(subs2, body)); substitute(subs2, body));
@ -188,13 +178,11 @@ Expr substitute(const ATermMap & subs, Expr e)
ATermList bindings; ATermList bindings;
if (atMatch(m, e) >> "Rec" >> bindings) { if (atMatch(m, e) >> "Rec" >> bindings) {
ATermMap subs2(subs); ATermMap subs2(subs);
ATermList bnds = bindings; for (ATermIterator i(bindings); i; ++i) {
while (!ATisEmpty(bnds)) {
Expr e; Expr e;
if (!(atMatch(m, ATgetFirst(bnds)) >> "Bind" >> s >> e)) if (!(atMatch(m, *i) >> "Bind" >> s >> e))
abort(); /* can't happen */ abort(); /* can't happen */
subs2.remove(s); subs2.remove(s);
bnds = ATgetNext(bnds);
} }
return ATmake("Rec(<term>)", substitute(subs2, (ATerm) bindings)); return ATmake("Rec(<term>)", substitute(subs2, (ATerm) bindings));
} }
@ -211,14 +199,9 @@ Expr substitute(const ATermMap & subs, Expr e)
} }
if (ATgetType(e) == AT_LIST) { if (ATgetType(e) == AT_LIST) {
ATermList in = (ATermList) e;
ATermList out = ATempty; ATermList out = ATempty;
for (ATermIterator i((ATermList) e); i; ++i)
while (!ATisEmpty(in)) { out = ATinsert(out, substitute(subs, *i));
out = ATinsert(out, substitute(subs, ATgetFirst(in)));
in = ATgetNext(in);
}
return (ATerm) ATreverse(out); return (ATerm) ATreverse(out);
} }

View file

@ -54,10 +54,8 @@ static void printNixExpr(EvalState & state, Expr e)
} }
if (ATgetType(e) == AT_LIST) { if (ATgetType(e) == AT_LIST) {
while (!ATisEmpty(es)) { for (ATermIterator i((ATermList) e); i; ++i)
printNixExpr(state, evalExpr(state, ATgetFirst(es))); printNixExpr(state, evalExpr(state, *i));
es = ATgetNext(es);
}
return; return;
} }

View file

@ -108,11 +108,10 @@ static string processBinding(EvalState & state, Expr e, NixExpr & ne)
if (atMatch(m, e) >> "List" >> es) { if (atMatch(m, e) >> "List" >> es) {
string s; string s;
bool first = true; bool first = true;
while (!ATisEmpty(es)) { for (ATermIterator i(es); i; ++i) {
startNest(nest, lvlVomit, format("processing list element")); startNest(nest, lvlVomit, format("processing list element"));
if (!first) s = s + " "; else first = false; if (!first) s = s + " "; else first = false;
s += processBinding(state, evalExpr(state, ATgetFirst(es)), ne); s += processBinding(state, evalExpr(state, *i), ne);
es = ATgetNext(es);
} }
return s; return s;
} }
@ -140,10 +139,8 @@ Expr primDerivation(EvalState & state, Expr args)
Hash outHash; Hash outHash;
bool outHashGiven = false; bool outHashGiven = false;
for (ATermList keys = attrs.keys(); !ATisEmpty(keys); for (ATermIterator i(attrs.keys()); i; ++i) {
keys = ATgetNext(keys)) string key = aterm2String(*i);
{
string key = aterm2String(ATgetFirst(keys));
Expr value = attrs.get(key); Expr value = attrs.get(key);
startNest(nest, lvlVomit, format("processing attribute `%1%'") % key); startNest(nest, lvlVomit, format("processing attribute `%1%'") % key);

View file

@ -14,6 +14,28 @@ string atPrint(ATerm t);
/* Write an ATerm to an output stream. */ /* Write an ATerm to an output stream. */
ostream & operator << (ostream & stream, ATerm e); 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. */ /* Type-safe matching. */
struct ATMatcher struct ATMatcher

View file

@ -43,13 +43,11 @@ Path writeTerm(ATerm t, const string & suffix)
static void parsePaths(ATermList paths, PathSet & out) static void parsePaths(ATermList paths, PathSet & out)
{ {
ATMatcher m; ATMatcher m;
while (!ATisEmpty(paths)) { for (ATermIterator i(paths); i; ++i) {
string s; string s;
ATerm t = ATgetFirst(paths); if (!(atMatch(m, *i) >> s))
if (!(atMatch(m, t) >> s)) throw badTerm("not a path", *i);
throw badTerm("not a path", t);
out.insert(s); out.insert(s);
paths = ATgetNext(paths);
} }
} }
@ -91,16 +89,14 @@ static bool parseClosure(ATerm t, Closure & closure)
parsePaths(roots, closure.roots); parsePaths(roots, closure.roots);
while (!ATisEmpty(elems)) { for (ATermIterator i(elems); i; ++i) {
string path; string path;
ATermList refs; ATermList refs;
ATerm t = ATgetFirst(elems); if (!(atMatch(m, *i) >> "" >> path >> refs))
if (!(atMatch(m, t) >> "" >> path >> refs)) throw badTerm("not a closure element", *i);
throw badTerm("not a closure element", t);
ClosureElem elem; ClosureElem elem;
parsePaths(refs, elem.refs); parsePaths(refs, elem.refs);
closure.elems[path] = elem; closure.elems[path] = elem;
elems = ATgetNext(elems);
} }
checkClosure(closure); checkClosure(closure);
@ -124,22 +120,18 @@ static bool parseDerivation(ATerm t, Derivation & derivation)
derivation.builder = builder; derivation.builder = builder;
derivation.platform = platform; derivation.platform = platform;
while (!ATisEmpty(args)) { for (ATermIterator i(args); i; ++i) {
string s; string s;
ATerm arg = ATgetFirst(args); if (!(atMatch(m, *i) >> s))
if (!(atMatch(m, arg) >> s)) throw badTerm("string expected", *i);
throw badTerm("string expected", arg);
derivation.args.push_back(s); derivation.args.push_back(s);
args = ATgetNext(args);
} }
while (!ATisEmpty(bnds)) { for (ATermIterator i(bnds); i; ++i) {
string s1, s2; string s1, s2;
ATerm bnd = ATgetFirst(bnds); if (!(atMatch(m, *i) >> "" >> s1 >> s2))
if (!(atMatch(m, bnd) >> "" >> s1 >> s2)) throw badTerm("tuple of strings expected", *i);
throw badTerm("tuple of strings expected", bnd);
derivation.env[s1] = s2; derivation.env[s1] = s2;
bnds = ATgetNext(bnds);
} }
return true; return true;