about summary refs log tree commit diff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/Makefile.am2
-rw-r--r--src/dotgraph.cc30
-rw-r--r--src/dotgraph.hh2
-rw-r--r--src/expr.cc (renamed from src/fstate.cc)110
-rw-r--r--src/expr.hh (renamed from src/fstate.hh)32
-rw-r--r--src/fix.cc73
-rw-r--r--src/globals.hh7
-rw-r--r--src/nix-help.txt4
-rw-r--r--src/nix.cc13
-rw-r--r--src/normalise.cc181
-rw-r--r--src/normalise.hh25
-rw-r--r--src/store.cc2
-rwxr-xr-xsrc/test-builder-2.sh2
-rw-r--r--src/test.cc35
14 files changed, 252 insertions, 266 deletions
diff --git a/src/Makefile.am b/src/Makefile.am
index e5aa15fd9f84..216d664e880e 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -23,7 +23,7 @@ test_LDADD = libshared.a libnix.a $(LDADD)
 noinst_LIBRARIES = libnix.a libshared.a
 
 libnix_a_SOURCES = util.cc hash.cc archive.cc md5.c \
- store.cc fstate.cc normalise.cc exec.cc \
+ store.cc expr.cc normalise.cc exec.cc \
  globals.cc db.cc references.cc pathlocks.cc
 
 libshared_a_SOURCES = shared.cc
diff --git a/src/dotgraph.cc b/src/dotgraph.cc
index 1b352e3ff384..f9ff51b909c4 100644
--- a/src/dotgraph.cc
+++ b/src/dotgraph.cc
@@ -51,9 +51,9 @@ string pathLabel(const FSId & id, const string & path)
 }
 
 
-void printSlice(const FSId & id, const FState & fs)
+void printClosure(const FSId & id, const NixExpr & fs)
 {
-    Strings workList(fs.slice.roots.begin(), fs.slice.roots.end());
+    Strings workList(fs.closure.roots.begin(), fs.closure.roots.end());
     StringSet doneSet;
 
     for (Strings::iterator i = workList.begin(); i != workList.end(); i++) {
@@ -67,9 +67,9 @@ void printSlice(const FSId & id, const FState & fs)
 	if (doneSet.find(path) == doneSet.end()) {
 	    doneSet.insert(path);
 
-	    SliceElems::const_iterator elem = fs.slice.elems.find(path);
-	    if (elem == fs.slice.elems.end())
-		throw Error(format("bad slice, missing path `%1%'") % path);
+	    ClosureElems::const_iterator elem = fs.closure.elems.find(path);
+	    if (elem == fs.closure.elems.end())
+		throw Error(format("bad closure, missing path `%1%'") % path);
 
 	    for (StringSet::const_iterator i = elem->second.refs.begin();
 		 i != elem->second.refs.end(); i++)
@@ -99,29 +99,29 @@ void printDotGraph(const FSIds & roots)
 	if (doneSet.find(id) == doneSet.end()) {
 	    doneSet.insert(id);
                     
-	    FState fs = parseFState(termFromId(id));
+	    NixExpr ne = parseNixExpr(termFromId(id));
 
 	    string label, colour;
                     
-	    if (fs.type == FState::fsDerive) {
-		for (FSIdSet::iterator i = fs.derive.inputs.begin();
-		     i != fs.derive.inputs.end(); i++)
+	    if (ne.type == NixExpr::neDerivation) {
+		for (FSIdSet::iterator i = ne.derivation.inputs.begin();
+		     i != ne.derivation.inputs.end(); i++)
 		{
 		    workList.push_back(*i);
 		    cout << makeEdge(*i, id);
 		}
 
-		label = "derive";
+		label = "derivation";
 		colour = "#00ff00";
-		for (StringPairs::iterator i = fs.derive.env.begin();
-		     i != fs.derive.env.end(); i++)
+		for (StringPairs::iterator i = ne.derivation.env.begin();
+		     i != ne.derivation.env.end(); i++)
 		    if (i->first == "name") label = i->second;
 	    }
 
-	    else if (fs.type == FState::fsSlice) {
-		label = "<slice>";
+	    else if (ne.type == NixExpr::neClosure) {
+		label = "<closure>";
 		colour = "#00ffff";
-		printSlice(id, fs);
+		printClosure(id, ne);
 	    }
 
 	    else abort();
diff --git a/src/dotgraph.hh b/src/dotgraph.hh
index d88e04e09794..e1678da967d4 100644
--- a/src/dotgraph.hh
+++ b/src/dotgraph.hh
@@ -1,7 +1,7 @@
 #ifndef __DOTGRAPH_H
 #define __DOTGRAPH_H
 
-#include "fstate.hh"
+#include "expr.hh"
 
 void printDotGraph(const FSIds & roots);
 
diff --git a/src/fstate.cc b/src/expr.cc
index 0502a8524fa5..7d79d1654f05 100644
--- a/src/fstate.cc
+++ b/src/expr.cc
@@ -1,4 +1,4 @@
-#include "fstate.hh"
+#include "expr.hh"
 #include "globals.hh"
 #include "store.hh"
 
@@ -65,23 +65,23 @@ static void parsePaths(ATermList paths, StringSet & out)
 }
 
 
-static void checkSlice(const Slice & slice)
+static void checkClosure(const Closure & closure)
 {
-    if (slice.elems.size() == 0)
-        throw Error("empty slice");
+    if (closure.elems.size() == 0)
+        throw Error("empty closure");
 
     StringSet decl;
-    for (SliceElems::const_iterator i = slice.elems.begin();
-         i != slice.elems.end(); i++)
+    for (ClosureElems::const_iterator i = closure.elems.begin();
+         i != closure.elems.end(); i++)
         decl.insert(i->first);
     
-    for (StringSet::const_iterator i = slice.roots.begin();
-         i != slice.roots.end(); i++)
+    for (StringSet::const_iterator i = closure.roots.begin();
+         i != closure.roots.end(); i++)
         if (decl.find(*i) == decl.end())
             throw Error(format("undefined root path `%1%'") % *i);
     
-    for (SliceElems::const_iterator i = slice.elems.begin();
-         i != slice.elems.end(); i++)
+    for (ClosureElems::const_iterator i = closure.elems.begin();
+         i != closure.elems.end(); i++)
         for (StringSet::const_iterator j = i->second.refs.begin();
              j != i->second.refs.end(); j++)
             if (decl.find(*j) == decl.end())
@@ -91,35 +91,35 @@ static void checkSlice(const Slice & slice)
 }
 
 
-/* Parse a slice. */
-static bool parseSlice(ATerm t, Slice & slice)
+/* Parse a closure. */
+static bool parseClosure(ATerm t, Closure & closure)
 {
     ATermList roots, elems;
     
-    if (!ATmatch(t, "Slice([<list>], [<list>])", &roots, &elems))
+    if (!ATmatch(t, "Closure([<list>], [<list>])", &roots, &elems))
         return false;
 
-    parsePaths(roots, slice.roots);
+    parsePaths(roots, closure.roots);
 
     while (!ATisEmpty(elems)) {
         char * s1, * s2;
         ATermList refs;
         ATerm t = ATgetFirst(elems);
         if (!ATmatch(t, "(<str>, <str>, [<list>])", &s1, &s2, &refs))
-            throw badTerm("not a slice element", t);
-        SliceElem elem;
+            throw badTerm("not a closure element", t);
+        ClosureElem elem;
         elem.id = parseHash(s2);
         parsePaths(refs, elem.refs);
-        slice.elems[s1] = elem;
+        closure.elems[s1] = elem;
         elems = ATgetNext(elems);
     }
 
-    checkSlice(slice);
+    checkClosure(closure);
     return true;
 }
 
 
-static bool parseDerive(ATerm t, Derive & derive)
+static bool parseDerivation(ATerm t, Derivation & derivation)
 {
     ATermList outs, ins, args, bnds;
     char * builder;
@@ -139,8 +139,8 @@ static bool parseDerive(ATerm t, Derive & derive)
         char * s1, * s2;
         ATerm t = ATgetFirst(outs);
         if (!ATmatch(t, "(<str>, <str>)", &s1, &s2))
-            throw badTerm("not a derive output", t);
-        derive.outputs[s1] = parseHash(s2);
+            throw badTerm("not a derivation output", t);
+        derivation.outputs[s1] = parseHash(s2);
         outs = ATgetNext(outs);
     }
 
@@ -149,19 +149,19 @@ static bool parseDerive(ATerm t, Derive & derive)
         ATerm t = ATgetFirst(ins);
         if (!ATmatch(t, "<str>", &s))
             throw badTerm("not an id", t);
-        derive.inputs.insert(parseHash(s));
+        derivation.inputs.insert(parseHash(s));
         ins = ATgetNext(ins);
     }
 
-    derive.builder = builder;
-    derive.platform = platform;
+    derivation.builder = builder;
+    derivation.platform = platform;
     
     while (!ATisEmpty(args)) {
         char * s;
         ATerm arg = ATgetFirst(args);
         if (!ATmatch(arg, "<str>", &s))
             throw badTerm("string expected", arg);
-        derive.args.push_back(s);
+        derivation.args.push_back(s);
         args = ATgetNext(args);
     }
 
@@ -170,7 +170,7 @@ static bool parseDerive(ATerm t, Derive & derive)
         ATerm bnd = ATgetFirst(bnds);
         if (!ATmatch(bnd, "(<str>, <str>)", &s1, &s2))
             throw badTerm("tuple of strings expected", bnd);
-        derive.env[s1] = s2;
+        derivation.env[s1] = s2;
         bnds = ATgetNext(bnds);
     }
 
@@ -178,15 +178,15 @@ static bool parseDerive(ATerm t, Derive & derive)
 }
 
 
-FState parseFState(ATerm t)
+NixExpr parseNixExpr(ATerm t)
 {
-    FState fs;
-    if (parseSlice(t, fs.slice))
-        fs.type = FState::fsSlice;
-    else if (parseDerive(t, fs.derive))
-        fs.type = FState::fsDerive;
-    else throw badTerm("not an fstate-expression", t);
-    return fs;
+    NixExpr ne;
+    if (parseClosure(t, ne.closure))
+        ne.type = NixExpr::neClosure;
+    else if (parseDerivation(t, ne.derivation))
+        ne.type = NixExpr::neDerivation;
+    else throw badTerm("not a Nix expression", t);
+    return ne;
 }
 
 
@@ -200,45 +200,45 @@ static ATermList unparsePaths(const StringSet & paths)
 }
 
 
-static ATerm unparseSlice(const Slice & slice)
+static ATerm unparseClosure(const Closure & closure)
 {
-    ATermList roots = unparsePaths(slice.roots);
+    ATermList roots = unparsePaths(closure.roots);
     
     ATermList elems = ATempty;
-    for (SliceElems::const_iterator i = slice.elems.begin();
-         i != slice.elems.end(); i++)
+    for (ClosureElems::const_iterator i = closure.elems.begin();
+         i != closure.elems.end(); i++)
         elems = ATinsert(elems,
             ATmake("(<str>, <str>, <term>)",
                 i->first.c_str(),
                 ((string) i->second.id).c_str(),
                 unparsePaths(i->second.refs)));
 
-    return ATmake("Slice(<term>, <term>)", roots, elems);
+    return ATmake("Closure(<term>, <term>)", roots, elems);
 }
 
 
-static ATerm unparseDerive(const Derive & derive)
+static ATerm unparseDerivation(const Derivation & derivation)
 {
     ATermList outs = ATempty;
-    for (DeriveOutputs::const_iterator i = derive.outputs.begin();
-         i != derive.outputs.end(); i++)
+    for (DerivationOutputs::const_iterator i = derivation.outputs.begin();
+         i != derivation.outputs.end(); i++)
         outs = ATinsert(outs,
             ATmake("(<str>, <str>)", 
                 i->first.c_str(), ((string) i->second).c_str()));
     
     ATermList ins = ATempty;
-    for (FSIdSet::const_iterator i = derive.inputs.begin();
-         i != derive.inputs.end(); i++)
+    for (FSIdSet::const_iterator i = derivation.inputs.begin();
+         i != derivation.inputs.end(); i++)
         ins = ATinsert(ins, ATmake("<str>", ((string) *i).c_str()));
 
     ATermList args = ATempty;
-    for (Strings::const_iterator i = derive.args.begin();
-         i != derive.args.end(); i++)
+    for (Strings::const_iterator i = derivation.args.begin();
+         i != derivation.args.end(); i++)
         args = ATinsert(args, ATmake("<str>", i->c_str()));
 
     ATermList env = ATempty;
-    for (StringPairs::const_iterator i = derive.env.begin();
-         i != derive.env.end(); i++)
+    for (StringPairs::const_iterator i = derivation.env.begin();
+         i != derivation.env.end(); i++)
         env = ATinsert(env,
             ATmake("(<str>, <str>)", 
                 i->first.c_str(), i->second.c_str()));
@@ -246,18 +246,18 @@ static ATerm unparseDerive(const Derive & derive)
     return ATmake("Derive(<term>, <term>, <str>, <str>, <term>, <term>)",
         ATreverse(outs),
         ATreverse(ins),
-        derive.platform.c_str(),
-        derive.builder.c_str(),
+        derivation.platform.c_str(),
+        derivation.builder.c_str(),
         ATreverse(args),
         ATreverse(env));
 }
 
 
-ATerm unparseFState(const FState & fs)
+ATerm unparseNixExpr(const NixExpr & ne)
 {
-    if (fs.type == FState::fsSlice)
-        return unparseSlice(fs.slice);
-    else if (fs.type == FState::fsDerive)
-        return unparseDerive(fs.derive);
+    if (ne.type == NixExpr::neClosure)
+        return unparseClosure(ne.closure);
+    else if (ne.type == NixExpr::neDerivation)
+        return unparseDerivation(ne.derivation);
     else abort();
 }
diff --git a/src/fstate.hh b/src/expr.hh
index a7935be5250e..2a6a06a0a924 100644
--- a/src/fstate.hh
+++ b/src/expr.hh
@@ -8,30 +8,30 @@ extern "C" {
 #include "store.hh"
 
 
-/* Abstract syntax of fstate-expressions. */
+/* Abstract syntax of Nix expressions. */
 
 typedef list<FSId> FSIds;
 
-struct SliceElem
+struct ClosureElem
 {
     FSId id;
     StringSet refs;
 };
 
-typedef map<string, SliceElem> SliceElems;
+typedef map<string, ClosureElem> ClosureElems;
 
-struct Slice
+struct Closure
 {
     StringSet roots;
-    SliceElems elems;
+    ClosureElems elems;
 };
 
-typedef map<string, FSId> DeriveOutputs;
+typedef map<string, FSId> DerivationOutputs;
 typedef map<string, string> StringPairs;
 
-struct Derive
+struct Derivation
 {
-    DeriveOutputs outputs;
+    DerivationOutputs outputs;
     FSIdSet inputs;
     string platform;
     string builder;
@@ -39,11 +39,11 @@ struct Derive
     StringPairs env;
 };
 
-struct FState
+struct NixExpr
 {
-    enum { fsSlice, fsDerive } type;
-    Slice slice;
-    Derive derive;
+    enum { neClosure, neDerivation } type;
+    Closure closure;
+    Derivation derivation;
 };
 
 
@@ -63,11 +63,11 @@ ATerm termFromId(const FSId & id);
 /* Write an aterm to the Nix store directory, and return its hash. */
 FSId writeTerm(ATerm t, const string & suffix, FSId id = FSId());
 
-/* Parse an fstate-expression. */
-FState parseFState(ATerm t);
+/* Parse a Nix expression. */
+NixExpr parseNixExpr(ATerm t);
 
-/* Parse an fstate-expression. */
-ATerm unparseFState(const FState & fs);
+/* Parse a Nix expression. */
+ATerm unparseNixExpr(const NixExpr & ne);
 
 
 #endif /* !__FSTATE_H */
diff --git a/src/fix.cc b/src/fix.cc
index 38c53c6d79a7..66438464cdbe 100644
--- a/src/fix.cc
+++ b/src/fix.cc
@@ -121,47 +121,47 @@ static Expr substExprMany(ATermList formals, ATermList args, Expr body)
 }
 
 
-static Strings fstatePathsCached(EvalState & state, const FSId & id)
+static Strings nixExprPathsCached(EvalState & state, const FSId & id)
 {
     PkgPaths::iterator i = state.pkgPaths.find(id);
     if (i != state.pkgPaths.end())
         return i->second;
     else {
-        Strings paths = fstatePaths(id);
+        Strings paths = nixExprPaths(id);
         state.pkgPaths[id] = paths;
         return paths;
     }
 }
 
 
-static Hash hashPackage(EvalState & state, FState fs)
+static Hash hashPackage(EvalState & state, NixExpr ne)
 {
-    if (fs.type == FState::fsDerive) {
+    if (ne.type == NixExpr::neDerivation) {
 	FSIdSet inputs2;
-        for (FSIdSet::iterator i = fs.derive.inputs.begin();
-             i != fs.derive.inputs.end(); i++)
+        for (FSIdSet::iterator i = ne.derivation.inputs.begin();
+             i != ne.derivation.inputs.end(); i++)
         {
             PkgHashes::iterator j = state.pkgHashes.find(*i);
             if (j == state.pkgHashes.end())
                 throw Error(format("unknown package id %1%") % (string) *i);
             inputs2.insert(j->second);
         }
-	fs.derive.inputs = inputs2;
+	ne.derivation.inputs = inputs2;
     }
-    return hashTerm(unparseFState(fs));
+    return hashTerm(unparseNixExpr(ne));
 }
 
 
-static string processBinding(EvalState & state, Expr e, FState & fs)
+static string processBinding(EvalState & state, Expr e, NixExpr & ne)
 {
     char * s1;
 
     if (ATmatch(e, "FSId(<str>)", &s1)) {
         FSId id = parseHash(s1);
-        Strings paths = fstatePathsCached(state, id);
+        Strings paths = nixExprPathsCached(state, id);
         if (paths.size() != 1) abort();
         string path = *(paths.begin());
-        fs.derive.inputs.insert(id);
+        ne.derivation.inputs.insert(id);
         return path;
     }
     
@@ -178,7 +178,7 @@ static string processBinding(EvalState & state, Expr e, FState & fs)
 	bool first = true;
         while (!ATisEmpty(l)) {
 	    if (!first) s = s + " "; else first = false;
-	    s += processBinding(state, evalExpr(state, ATgetFirst(l)), fs);
+	    s += processBinding(state, evalExpr(state, ATgetFirst(l)), ne);
             l = ATgetNext(l);
         }
 	return s;
@@ -204,7 +204,7 @@ static Expr evalExpr2(EvalState & state, Expr e)
         return e;
 
     try {
-        Hash pkgHash = hashPackage(state, parseFState(e));
+        Hash pkgHash = hashPackage(state, parseNixExpr(e));
         FSId pkgId = writeTerm(e, "");
         state.pkgHashes[pkgId] = pkgHash;
         return ATmake("FSId(<str>)", ((string) pkgId).c_str());
@@ -265,15 +265,15 @@ static Expr evalExpr2(EvalState & state, Expr e)
         FSId id;
         addToStore(srcPath, dstPath, id, true);
 
-        SliceElem elem;
+        ClosureElem elem;
         elem.id = id;
-        FState fs;
-        fs.type = FState::fsSlice;
-        fs.slice.roots.insert(dstPath);
-        fs.slice.elems[dstPath] = elem;
+        NixExpr ne;
+        ne.type = NixExpr::neClosure;
+        ne.closure.roots.insert(dstPath);
+        ne.closure.elems[dstPath] = elem;
 
-        Hash pkgHash = hashPackage(state, fs);
-        FSId pkgId = writeTerm(unparseFState(fs), "");
+        Hash pkgHash = hashPackage(state, ne);
+        FSId pkgId = writeTerm(unparseNixExpr(ne), "");
         state.pkgHashes[pkgId] = pkgHash;
 
         msg(lvlChatty, format("copied `%1%' -> %2%")
@@ -282,7 +282,7 @@ static Expr evalExpr2(EvalState & state, Expr e)
         return ATmake("FSId(<str>)", ((string) pkgId).c_str());
     }
 
-    /* Packages are transformed into Derive fstate expressions. */
+    /* Packages are transformed into Nix derivation expressions. */
     if (ATmatch(e, "Package([<list>])", &bnds)) {
 
         /* Evaluate the bindings and put them in a map. */
@@ -296,10 +296,11 @@ static Expr evalExpr2(EvalState & state, Expr e)
             bnds = ATgetNext(bnds);
         }
 
-        /* Gather information for building the Derive expression. */
-        FState fs;
-        fs.type = FState::fsDerive;
-        fs.derive.platform = SYSTEM;
+        /* Gather information for building the derivation
+           expression. */
+        NixExpr ne;
+        ne.type = NixExpr::neDerivation;
+        ne.derivation.platform = SYSTEM;
         string name;
         FSId outId;
         bool outIdGiven = false;
@@ -318,16 +319,16 @@ static Expr evalExpr2(EvalState & state, Expr e)
                 
                 while (!ATisEmpty(args)) {
                     Expr arg = evalExpr(state, ATgetFirst(args));
-                    fs.derive.args.push_back(processBinding(state, arg, fs));
+                    ne.derivation.args.push_back(processBinding(state, arg, ne));
                     args = ATgetNext(args);
                 }
             } 
 
             else {
-                string s = processBinding(state, value, fs);
-                fs.derive.env[key] = s;
+                string s = processBinding(state, value, ne);
+                ne.derivation.env[key] = s;
 
-                if (key == "build") fs.derive.builder = s;
+                if (key == "build") ne.derivation.builder = s;
                 if (key == "name") name = s;
                 if (key == "id") { 
                     outId = parseHash(s);
@@ -339,25 +340,25 @@ static Expr evalExpr2(EvalState & state, Expr e)
                 ATmake("(<str>, <term>)", key.c_str(), value));
         }
 
-        if (fs.derive.builder == "")
+        if (ne.derivation.builder == "")
             throw badTerm("no builder specified", e);
         
         if (name == "")
             throw badTerm("no package name specified", e);
         
-        /* Hash the fstate-expression with no outputs to produce a
+        /* Hash the Nix expression with no outputs to produce a
            unique but deterministic path name for this package. */
-        if (!outIdGiven) outId = hashPackage(state, fs);
+        if (!outIdGiven) outId = hashPackage(state, ne);
         string outPath = 
             canonPath(nixStore + "/" + ((string) outId).c_str() + "-" + name);
-        fs.derive.env["out"] = outPath;
-        fs.derive.outputs[outPath] = outId;
+        ne.derivation.env["out"] = outPath;
+        ne.derivation.outputs[outPath] = outId;
 
         /* Write the resulting term into the Nix store directory. */
         Hash pkgHash = outIdGiven
             ? hashString((string) outId + outPath)
-            : hashPackage(state, fs);
-        FSId pkgId = writeTerm(unparseFState(fs), "-d-" + name);
+            : hashPackage(state, ne);
+        FSId pkgId = writeTerm(unparseNixExpr(ne), "-d-" + name);
         state.pkgHashes[pkgId] = pkgHash;
 
         msg(lvlChatty, format("instantiated `%1%' -> %2%")
diff --git a/src/globals.hh b/src/globals.hh
index 107d617bc895..b140f136c9cb 100644
--- a/src/globals.hh
+++ b/src/globals.hh
@@ -29,7 +29,7 @@ extern TableId dbId2Paths;
 /* dbSuccessors :: FSId -> FSId
 
    Each pair $(id_1, id_2)$ in this mapping records the fact that a
-   successor of an fstate expression stored in a file with identifier
+   successor of a Nix expression stored in a file with identifier
    $id_1$ is stored in a file with identifier $id_2$.
 
    Note that a term $y$ is successor of $x$ iff there exists a
@@ -41,15 +41,14 @@ extern TableId dbSuccessors;
 /* dbSubstitutes :: FSId -> [FSId]
 
    Each pair $(id, [ids])$ tells Nix that it can realise any of the
-   fstate expressions referenced by the identifiers in $ids$ to
+   Nix expressions referenced by the identifiers in $ids$ to
    generate a path with identifier $id$.
 
    The main purpose of this is for distributed caching of derivates.
    One system can compute a derivate with hash $h$ and put it on a
    website (as a Nix archive), for instance, and then another system
    can register a substitute for that derivate.  The substitute in
-   this case might be an fstate expression that fetches the Nix
-   archive. 
+   this case might be a Nix expression that fetches the Nix archive.
 */
 extern TableId dbSubstitutes;
 
diff --git a/src/nix-help.txt b/src/nix-help.txt
index 4e1d707c8926..be8ecf0a15be 100644
--- a/src/nix-help.txt
+++ b/src/nix-help.txt
@@ -2,7 +2,7 @@ nix [OPTIONS...] [ARGUMENTS...]
 
 Operations:
 
-  --install / -i: realise an fstate
+  --install / -i: realise a Nix expression
   --delete / -d: delete paths from the Nix store
   --add / -A: copy a path to the Nix store
   --query / -q: query information
@@ -25,7 +25,7 @@ Source selection for --install, --dump:
 
 Query flags:
 
-  --list / -l: query the output paths (roots) of an fstate (default)
+  --list / -l: query the output paths (roots) of a Nix expression (default)
   --requisites / -r: print all paths necessary to realise expression
   --generators / -g: find expressions producing a subset of given ids
   --expansion / -e: print a path containing id
diff --git a/src/nix.cc b/src/nix.cc
index 12a01fd3616e..87553de2d65e 100644
--- a/src/nix.cc
+++ b/src/nix.cc
@@ -37,8 +37,7 @@ static FSId argToId(const string & arg)
 }
 
 
-/* Realise (or install) paths from the given Nix fstate
-   expressions. */
+/* Realise (or install) paths from the given Nix expressions. */
 static void opInstall(Strings opFlags, Strings opArgs)
 {
     if (!opFlags.empty()) throw UsageError("unknown flag");
@@ -46,8 +45,8 @@ static void opInstall(Strings opFlags, Strings opArgs)
     for (Strings::iterator it = opArgs.begin();
          it != opArgs.end(); it++)
     {
-        FSId id = normaliseFState(argToId(*it));
-        realiseSlice(id);
+        FSId id = normaliseNixExpr(argToId(*it));
+        realiseClosure(id);
         cout << format("%1%\n") % (string) id;
     }
 }
@@ -83,7 +82,7 @@ static void opAdd(Strings opFlags, Strings opArgs)
 
 FSId maybeNormalise(const FSId & id, bool normalise)
 {
-    return normalise ? normaliseFState(id) : id;
+    return normalise ? normaliseNixExpr(id) : id;
 }
 
 
@@ -115,7 +114,7 @@ static void opQuery(Strings opFlags, Strings opArgs)
             for (Strings::iterator i = opArgs.begin();
                  i != opArgs.end(); i++)
             {
-                Strings paths2 = fstatePaths(
+                Strings paths2 = nixExprPaths(
                     maybeNormalise(argToId(*i), normalise));
                 paths.insert(paths2.begin(), paths2.end());
             }
@@ -130,7 +129,7 @@ static void opQuery(Strings opFlags, Strings opArgs)
             for (Strings::iterator i = opArgs.begin();
                  i != opArgs.end(); i++)
             {
-                Strings paths2 = fstateRequisites(
+                Strings paths2 = nixExprRequisites(
                     maybeNormalise(argToId(*i), normalise),
                     includeExprs, includeSuccessors);
                 paths.insert(paths2.begin(), paths2.end());
diff --git a/src/normalise.cc b/src/normalise.cc
index 39867bfe5738..994a07df1c0d 100644
--- a/src/normalise.cc
+++ b/src/normalise.cc
@@ -26,40 +26,41 @@ static FSId useSuccessor(const FSId & id)
 }
 
 
-Strings pathsFromOutputs(const DeriveOutputs & ps)
+Strings pathsFromOutputs(const DerivationOutputs & ps)
 {
     Strings ss;
-    for (DeriveOutputs::const_iterator i = ps.begin();
+    for (DerivationOutputs::const_iterator i = ps.begin();
          i != ps.end(); i++)
         ss.push_back(i->first);
     return ss;
 }
 
 
-FSId normaliseFState(FSId id, FSIdSet pending)
+FSId normaliseNixExpr(FSId id, FSIdSet pending)
 {
-    Nest nest(lvlTalkative, format("normalising fstate %1%") % (string) id);
+    Nest nest(lvlTalkative,
+        format("normalising nix expression %1%") % (string) id);
 
     /* Try to substitute $id$ by any known successors in order to
        speed up the rewrite process. */
     id = useSuccessor(id);
 
-    /* Get the fstate expression. */
-    FState fs = parseFState(termFromId(id));
+    /* Get the Nix expression. */
+    NixExpr ne = parseNixExpr(termFromId(id));
 
-    /* If this is a normal form (i.e., a slice) we are done. */
-    if (fs.type == FState::fsSlice) return id;
-    if (fs.type != FState::fsDerive) abort();
+    /* If this is a normal form (i.e., a closure) we are done. */
+    if (ne.type == NixExpr::neClosure) return id;
+    if (ne.type != NixExpr::neDerivation) abort();
     
 
-    /* Otherwise, it's a derive expression, and we have to build it to
+    /* Otherwise, it's a derivation expression, and we have to build it to
        determine its normal form. */
 
 
     /* Some variables. */
 
-    /* Input paths, with their slice elements. */
-    SliceElems inSlices; 
+    /* Input paths, with their closure elements. */
+    ClosureElems inClosures; 
 
     /* Referencable paths (i.e., input and output paths). */
     StringSet allPaths;
@@ -68,13 +69,13 @@ FSId normaliseFState(FSId id, FSIdSet pending)
     Environment env; 
 
     /* The result. */
-    FState nfFS;
-    nfFS.type = FState::fsSlice;
+    NixExpr nf;
+    nf.type = NixExpr::neClosure;
 
 
     /* Parse the outputs. */
-    for (DeriveOutputs::iterator i = fs.derive.outputs.begin();
-         i != fs.derive.outputs.end(); i++)
+    for (DerivationOutputs::iterator i = ne.derivation.outputs.begin();
+         i != ne.derivation.outputs.end(); i++)
     {
         debug(format("building %1% in `%2%'") % (string) i->second % i->first);
         allPaths.insert(i->first);
@@ -82,7 +83,7 @@ FSId normaliseFState(FSId id, FSIdSet pending)
 
     /* Obtain locks on all output paths.  The locks are automatically
        released when we exit this function or Nix crashes. */
-    PathLocks outputLocks(pathsFromOutputs(fs.derive.outputs));
+    PathLocks outputLocks(pathsFromOutputs(ne.derivation.outputs));
 
     /* Now check again whether there is a successor.  This is because
        another process may have started building in parallel.  After
@@ -95,33 +96,33 @@ FSId normaliseFState(FSId id, FSIdSet pending)
     {
         FSId id2 = useSuccessor(id);
         if (id2 != id) {
-            FState fs = parseFState(termFromId(id2));
+            NixExpr ne = parseNixExpr(termFromId(id2));
             debug(format("skipping build of %1%, someone beat us to it")
 		  % (string) id);
-            if (fs.type != FState::fsSlice) abort();
+            if (ne.type != NixExpr::neClosure) abort();
             return id2;
         }
     }
 
     /* Right platform? */
-    if (fs.derive.platform != thisSystem)
+    if (ne.derivation.platform != thisSystem)
         throw Error(format("a `%1%' is required, but I am a `%2%'")
-		    % fs.derive.platform % thisSystem);
+		    % ne.derivation.platform % thisSystem);
         
     /* Realise inputs (and remember all input paths). */
-    for (FSIdSet::iterator i = fs.derive.inputs.begin();
-         i != fs.derive.inputs.end(); i++)
+    for (FSIdSet::iterator i = ne.derivation.inputs.begin();
+         i != ne.derivation.inputs.end(); i++)
     {
-        FSId nf = normaliseFState(*i, pending);
-        realiseSlice(nf, pending);
+        FSId nf = normaliseNixExpr(*i, pending);
+        realiseClosure(nf, pending);
         /* !!! nf should be a root of the garbage collector while we
            are building */
-        FState fs = parseFState(termFromId(nf));
-        if (fs.type != FState::fsSlice) abort();
-        for (SliceElems::iterator j = fs.slice.elems.begin();
-             j != fs.slice.elems.end(); j++)
+        NixExpr ne = parseNixExpr(termFromId(nf));
+        if (ne.type != NixExpr::neClosure) abort();
+        for (ClosureElems::iterator j = ne.closure.elems.begin();
+             j != ne.closure.elems.end(); j++)
 	{
-            inSlices[j->first] = j->second;
+            inClosures[j->first] = j->second;
 	    allPaths.insert(j->first);
 	}
     }
@@ -140,15 +141,15 @@ FSId normaliseFState(FSId id, FSIdSet pending)
     env["HOME"] = "/homeless-shelter";
 
     /* Build the environment. */
-    for (StringPairs::iterator i = fs.derive.env.begin();
-         i != fs.derive.env.end(); i++)
+    for (StringPairs::iterator i = ne.derivation.env.begin();
+         i != ne.derivation.env.end(); i++)
         env[i->first] = i->second;
 
     /* We can skip running the builder if we can expand all output
        paths from their ids. */
     bool fastBuild = true;
-    for (DeriveOutputs::iterator i = fs.derive.outputs.begin();
-         i != fs.derive.outputs.end(); i++)
+    for (DerivationOutputs::iterator i = ne.derivation.outputs.begin();
+         i != ne.derivation.outputs.end(); i++)
     {
         try {
             expandId(i->second, i->first, "/", pending);
@@ -164,8 +165,8 @@ FSId normaliseFState(FSId id, FSIdSet pending)
 
         /* If any of the outputs already exist but are not registered,
            delete them. */
-        for (DeriveOutputs::iterator i = fs.derive.outputs.begin(); 
-             i != fs.derive.outputs.end(); i++)
+        for (DerivationOutputs::iterator i = ne.derivation.outputs.begin(); 
+             i != ne.derivation.outputs.end(); i++)
         {
             string path = i->first;
             FSId id;
@@ -179,7 +180,7 @@ FSId normaliseFState(FSId id, FSIdSet pending)
 
         /* Run the builder. */
         msg(lvlChatty, format("building..."));
-        runProgram(fs.derive.builder, fs.derive.args, env);
+        runProgram(ne.derivation.builder, ne.derivation.args, env);
         msg(lvlChatty, format("build completed"));
         
     } else
@@ -189,13 +190,13 @@ FSId normaliseFState(FSId id, FSIdSet pending)
        output path to determine what other paths it references.  Also make all
        output paths read-only. */
     StringSet usedPaths;
-    for (DeriveOutputs::iterator i = fs.derive.outputs.begin(); 
-         i != fs.derive.outputs.end(); i++)
+    for (DerivationOutputs::iterator i = ne.derivation.outputs.begin(); 
+         i != ne.derivation.outputs.end(); i++)
     {
         string path = i->first;
         if (!pathExists(path))
             throw Error(format("path `%1%' does not exist") % path);
-        nfFS.slice.roots.insert(path);
+        nf.closure.roots.insert(path);
 
 	makePathReadOnly(path);
 
@@ -204,28 +205,28 @@ FSId normaliseFState(FSId id, FSIdSet pending)
         Strings refPaths = filterReferences(path, 
             Strings(allPaths.begin(), allPaths.end()));
 
-	/* Construct a slice element for this output path. */
-        SliceElem elem;
+	/* Construct a closure element for this output path. */
+        ClosureElem elem;
         elem.id = i->second;
 
 	/* For each path referenced by this output path, add its id to the
-	   slice element and add the id to the `usedPaths' set (so that the
-	   elements referenced by *its* slice are added below). */
+	   closure element and add the id to the `usedPaths' set (so that the
+	   elements referenced by *its* closure are added below). */
         for (Strings::iterator j = refPaths.begin();
 	     j != refPaths.end(); j++)
 	{
 	    string path = *j;
 	    elem.refs.insert(path);
-            if (inSlices.find(path) != inSlices.end())
+            if (inClosures.find(path) != inClosures.end())
                 usedPaths.insert(path);
-	    else if (fs.derive.outputs.find(path) == fs.derive.outputs.end())
+	    else if (ne.derivation.outputs.find(path) == ne.derivation.outputs.end())
 		abort();
         }
 
-        nfFS.slice.elems[path] = elem;
+        nf.closure.elems[path] = elem;
     }
 
-    /* Close the slice.  That is, for any referenced path, add the paths
+    /* Close the closure.  That is, for any referenced path, add the paths
        referenced by it. */
     StringSet donePaths;
 
@@ -237,10 +238,10 @@ FSId normaliseFState(FSId id, FSIdSet pending)
 	if (donePaths.find(path) != donePaths.end()) continue;
 	donePaths.insert(path);
 
-	SliceElems::iterator j = inSlices.find(path);
-	if (j == inSlices.end()) abort();
+	ClosureElems::iterator j = inClosures.find(path);
+	if (j == inClosures.end()) abort();
 
-	nfFS.slice.elems[path] = j->second;
+	nf.closure.elems[path] = j->second;
 
 	for (StringSet::iterator k = j->second.refs.begin();
 	     k != j->second.refs.end(); k++)
@@ -248,8 +249,8 @@ FSId normaliseFState(FSId id, FSIdSet pending)
     }
 
     /* For debugging, print out the referenced and unreferenced paths. */
-    for (SliceElems::iterator i = inSlices.begin();
-         i != inSlices.end(); i++)
+    for (ClosureElems::iterator i = inClosures.begin();
+         i != inClosures.end(); i++)
     {
         StringSet::iterator j = donePaths.find(i->first);
         if (j == donePaths.end())
@@ -260,9 +261,9 @@ FSId normaliseFState(FSId id, FSIdSet pending)
 
     /* Write the normal form.  This does not have to occur in the
        transaction below because writing terms is idem-potent. */
-    ATerm nf = unparseFState(nfFS);
-    msg(lvlVomit, format("normal form: %1%") % printTerm(nf));
-    FSId idNF = writeTerm(nf, "-s-" + (string) id);
+    ATerm nfTerm = unparseNixExpr(nf);
+    msg(lvlVomit, format("normal form: %1%") % printTerm(nfTerm));
+    FSId idNF = writeTerm(nfTerm, "-s-" + (string) id);
 
     /* Register each outpat path, and register the normal form.  This
        is wrapped in one database transaction to ensure that if we
@@ -271,8 +272,8 @@ FSId normaliseFState(FSId id, FSIdSet pending)
        deleted arbitrarily, while registered paths can only be deleted
        by running the garbage collector. */
     Transaction txn(nixDB);
-    for (DeriveOutputs::iterator i = fs.derive.outputs.begin(); 
-         i != fs.derive.outputs.end(); i++)
+    for (DerivationOutputs::iterator i = ne.derivation.outputs.begin(); 
+         i != ne.derivation.outputs.end(); i++)
         registerPath(txn, i->first, i->second);
     registerSuccessor(txn, id, idNF);
     txn.commit();
@@ -281,36 +282,36 @@ FSId normaliseFState(FSId id, FSIdSet pending)
 }
 
 
-void realiseSlice(const FSId & id, FSIdSet pending)
+void realiseClosure(const FSId & id, FSIdSet pending)
 {
     Nest nest(lvlDebug, 
-        format("realising slice %1%") % (string) id);
+        format("realising closure %1%") % (string) id);
 
-    FState fs = parseFState(termFromId(id));
-    if (fs.type != FState::fsSlice)
-        throw Error(format("expected slice in %1%") % (string) id);
+    NixExpr ne = parseNixExpr(termFromId(id));
+    if (ne.type != NixExpr::neClosure)
+        throw Error(format("expected closure in %1%") % (string) id);
     
-    for (SliceElems::const_iterator i = fs.slice.elems.begin();
-         i != fs.slice.elems.end(); i++)
+    for (ClosureElems::const_iterator i = ne.closure.elems.begin();
+         i != ne.closure.elems.end(); i++)
         expandId(i->second.id, i->first, "/", pending);
 }
 
 
-Strings fstatePaths(const FSId & id)
+Strings nixExprPaths(const FSId & id)
 {
     Strings paths;
 
-    FState fs = parseFState(termFromId(id));
+    NixExpr ne = parseNixExpr(termFromId(id));
 
-    if (fs.type == FState::fsSlice) {
-        for (StringSet::const_iterator i = fs.slice.roots.begin();
-             i != fs.slice.roots.end(); i++)
+    if (ne.type == NixExpr::neClosure) {
+        for (StringSet::const_iterator i = ne.closure.roots.begin();
+             i != ne.closure.roots.end(); i++)
 	    paths.push_back(*i);
     }
 
-    else if (fs.type == FState::fsDerive) {
-        for (DeriveOutputs::iterator i = fs.derive.outputs.begin();
-             i != fs.derive.outputs.end(); i++)
+    else if (ne.type == NixExpr::neDerivation) {
+        for (DerivationOutputs::iterator i = ne.derivation.outputs.begin();
+             i != ne.derivation.outputs.end(); i++)
             paths.push_back(i->first);
     }
     
@@ -320,24 +321,24 @@ Strings fstatePaths(const FSId & id)
 }
 
 
-static void fstateRequisitesSet(const FSId & id, 
+static void nixExprRequisitesSet(const FSId & id, 
     bool includeExprs, bool includeSuccessors, StringSet & paths,
     FSIdSet & doneSet)
 {
     if (doneSet.find(id) != doneSet.end()) return;
     doneSet.insert(id);
 
-    FState fs = parseFState(termFromId(id));
+    NixExpr ne = parseNixExpr(termFromId(id));
 
-    if (fs.type == FState::fsSlice)
-        for (SliceElems::iterator i = fs.slice.elems.begin();
-             i != fs.slice.elems.end(); i++)
+    if (ne.type == NixExpr::neClosure)
+        for (ClosureElems::iterator i = ne.closure.elems.begin();
+             i != ne.closure.elems.end(); i++)
             paths.insert(i->first);
     
-    else if (fs.type == FState::fsDerive)
-        for (FSIdSet::iterator i = fs.derive.inputs.begin();
-             i != fs.derive.inputs.end(); i++)
-            fstateRequisitesSet(*i,
+    else if (ne.type == NixExpr::neDerivation)
+        for (FSIdSet::iterator i = ne.derivation.inputs.begin();
+             i != ne.derivation.inputs.end(); i++)
+            nixExprRequisitesSet(*i,
                 includeExprs, includeSuccessors, paths, doneSet);
 
     else abort();
@@ -348,17 +349,17 @@ static void fstateRequisitesSet(const FSId & id,
     string idSucc;
     if (includeSuccessors &&
         nixDB.queryString(noTxn, dbSuccessors, id, idSucc))
-        fstateRequisitesSet(parseHash(idSucc), 
+        nixExprRequisitesSet(parseHash(idSucc), 
             includeExprs, includeSuccessors, paths, doneSet);
 }
 
 
-Strings fstateRequisites(const FSId & id,
+Strings nixExprRequisites(const FSId & id,
     bool includeExprs, bool includeSuccessors)
 {
     StringSet paths;
     FSIdSet doneSet;
-    fstateRequisitesSet(id, includeExprs, includeSuccessors, paths, doneSet);
+    nixExprRequisitesSet(id, includeExprs, includeSuccessors, paths, doneSet);
     return Strings(paths.begin(), paths.end());
 }
 
@@ -381,19 +382,19 @@ FSIds findGenerators(const FSIds & _ids)
         if (!nixDB.queryString(noTxn, dbSuccessors, *i, s)) continue;
         FSId id = parseHash(s);
 
-        FState fs;
+        NixExpr ne;
         try {
             /* !!! should substitutes be used? */
-            fs = parseFState(termFromId(id));
+            ne = parseNixExpr(termFromId(id));
         } catch (...) { /* !!! only catch parse errors */
             continue;
         }
 
-        if (fs.type != FState::fsSlice) continue;
+        if (ne.type != NixExpr::neClosure) continue;
         
         bool okay = true;
-        for (SliceElems::const_iterator i = fs.slice.elems.begin();
-             i != fs.slice.elems.end(); i++)
+        for (ClosureElems::const_iterator i = ne.closure.elems.begin();
+             i != ne.closure.elems.end(); i++)
             if (ids.find(i->second.id) == ids.end()) {
                 okay = false;
                 break;
diff --git a/src/normalise.hh b/src/normalise.hh
index 59ab325739e4..9b827468195c 100644
--- a/src/normalise.hh
+++ b/src/normalise.hh
@@ -1,30 +1,29 @@
 #ifndef __NORMALISE_H
 #define __NORMALISE_H
 
-#include "fstate.hh"
+#include "expr.hh"
 
 
-/* Normalise an fstate-expression, that is, return an equivalent
-   slice.  (For the meaning of `pending', see expandId()). */
-FSId normaliseFState(FSId id, FSIdSet pending = FSIdSet());
+/* Normalise a Nix expression, that is, return an equivalent
+   closure.  (For the meaning of `pending', see expandId()). */
+FSId normaliseNixExpr(FSId id, FSIdSet pending = FSIdSet());
 
-/* Realise a Slice in the file system. */
-void realiseSlice(const FSId & id, FSIdSet pending = FSIdSet());
+/* Realise a Closure in the file system. */
+void realiseClosure(const FSId & id, FSIdSet pending = FSIdSet());
 
-/* Get the list of root (output) paths of the given
-   fstate-expression. */
-Strings fstatePaths(const FSId & id);
+/* Get the list of root (output) paths of the given Nix expression. */
+Strings nixExprPaths(const FSId & id);
 
 /* Get the list of paths that are required to realise the given
    expression.  For a derive expression, this is the union of
-   requisites of the inputs; for a slice expression, it is the path of
-   each element in the slice.  If `includeExprs' is true, include the
+   requisites of the inputs; for a closure expression, it is the path of
+   each element in the closure.  If `includeExprs' is true, include the
    paths of the Nix expressions themselves.  If `includeSuccessors' is
    true, include the requisites of successors. */
-Strings fstateRequisites(const FSId & id,
+Strings nixExprRequisites(const FSId & id,
     bool includeExprs, bool includeSuccessors);
 
-/* Return the list of the ids of all known fstate-expressions whose
+/* Return the list of the ids of all known Nix expressions whose
    output ids are completely contained in `ids'. */
 FSIds findGenerators(const FSIds & ids);
 
diff --git a/src/store.cc b/src/store.cc
index 8a3db12ba93e..f05cdf3ba4dd 100644
--- a/src/store.cc
+++ b/src/store.cc
@@ -246,7 +246,7 @@ string expandId(const FSId & id, const string & target,
 
             debug(format("trying substitute %1%") % (string) subId);
 
-            realiseSlice(normaliseFState(subId, pending), pending);
+            realiseClosure(normaliseNixExpr(subId, pending), pending);
 
             return expandId(id, target, prefix, pending);
         }
diff --git a/src/test-builder-2.sh b/src/test-builder-2.sh
index 1c4ac8494c47..0794fa96a401 100755
--- a/src/test-builder-2.sh
+++ b/src/test-builder-2.sh
@@ -2,7 +2,7 @@
 
 echo "builder 2"
 
-mkdir $out || exit 1
+/bin/mkdir $out || exit 1
 cd $out || exit 1
 echo "Hallo Wereld" > bla
 echo $builder >> bla
diff --git a/src/test.cc b/src/test.cc
index d640e335ae77..fb1e62eb3802 100644
--- a/src/test.cc
+++ b/src/test.cc
@@ -13,23 +13,10 @@
 void realise(FSId id)
 {
     Nest nest(lvlDebug, format("TEST: realising %1%") % (string) id);
-    realiseSlice(normaliseFState(id));
+    realiseClosure(normaliseNixExpr(id));
 }
 
 
-#if 0
-void realiseFail(FState fs)
-{
-    try {
-        realiseFState(fs);
-        abort();
-    } catch (Error e) {
-        cout << "error (expected): " << e.what() << endl;
-    }
-}
-#endif
-
-
 struct MySink : DumpSink
 {
     virtual void operator () (const unsigned char * data, unsigned int len)
@@ -115,8 +102,8 @@ void runTests()
     addToStore("./test-builder-1.sh", builder1fn, builder1id);
 
     ATerm fs1 = ATmake(
-        "Slice([<str>], [(<str>, <str>, [])])",
-        ((string) builder1id).c_str(),
+        "Closure([<str>], [(<str>, <str>, [])])",
+        builder1fn.c_str(),
         builder1fn.c_str(),
         ((string) builder1id).c_str());
     FSId fs1id = writeTerm(fs1, "");
@@ -125,8 +112,8 @@ void runTests()
     realise(fs1id);
 
     ATerm fs2 = ATmake(
-        "Slice([<str>], [(<str>, <str>, [])])",
-        ((string) builder1id).c_str(),
+        "Closure([<str>], [(<str>, <str>, [])])",
+        (builder1fn + "_bla").c_str(),
         (builder1fn + "_bla").c_str(),
         ((string) builder1id).c_str());
     FSId fs2id = writeTerm(fs2, "");
@@ -137,12 +124,12 @@ void runTests()
     string out1id = hashString("foo"); /* !!! bad */
     string out1fn = nixStore + "/" + (string) out1id + "-hello.txt";
     ATerm fs3 = ATmake(
-        "Derive([(<str>, <str>)], [<str>], <str>, <str>, [(\"out\", <str>)])",
+        "Derive([(<str>, <str>)], [<str>], <str>, <str>, [], [(\"out\", <str>)])",
         out1fn.c_str(),
         ((string) out1id).c_str(),
         ((string) fs1id).c_str(),
-        ((string) builder1fn).c_str(),
         thisSystem.c_str(),
+        ((string) builder1fn).c_str(),
         out1fn.c_str());
     debug(printTerm(fs3));
     FSId fs3id = writeTerm(fs3, "");
@@ -156,8 +143,8 @@ void runTests()
     addToStore("./test-builder-2.sh", builder4fn, builder4id);
 
     ATerm fs4 = ATmake(
-        "Slice([<str>], [(<str>, <str>, [])])",
-        ((string) builder4id).c_str(),
+        "Closure([<str>], [(<str>, <str>, [])])",
+        builder4fn.c_str(),
         builder4fn.c_str(),
         ((string) builder4id).c_str());
     FSId fs4id = writeTerm(fs4, "");
@@ -167,12 +154,12 @@ void runTests()
     string out5id = hashString("bar"); /* !!! bad */
     string out5fn = nixStore + "/" + (string) out5id + "-hello2";
     ATerm fs5 = ATmake(
-        "Derive([(<str>, <str>)], [<str>], <str>, <str>, [(\"out\", <str>), (\"builder\", <str>)])",
+        "Derive([(<str>, <str>)], [<str>], <str>, <str>, [], [(\"out\", <str>), (\"builder\", <str>)])",
         out5fn.c_str(),
         ((string) out5id).c_str(),
         ((string) fs4id).c_str(),
-        ((string) builder4fn).c_str(),
         thisSystem.c_str(),
+        ((string) builder4fn).c_str(),
         out5fn.c_str(),
         ((string) builder4fn).c_str());
     debug(printTerm(fs5));