* 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");
/* 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);

View file

@ -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);
}

View file

@ -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;
}

View file

@ -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);

View file

@ -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

View file

@ -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;