From 9210d4d530b68b5f19ac7062f129c88ccdc03e04 Mon Sep 17 00:00:00 2001 From: Eelco Dolstra Date: Fri, 31 Oct 2003 17:09:31 +0000 Subject: * Working evaluator. * Mutually recursive attribute sets. * Print evaluator efficiency statistics. --- src/fix-ng/fix.cc | 319 ++++-------------------------------------------------- 1 file changed, 19 insertions(+), 300 deletions(-) (limited to 'src/fix-ng/fix.cc') diff --git a/src/fix-ng/fix.cc b/src/fix-ng/fix.cc index fb98dc697824..d791461bd557 100644 --- a/src/fix-ng/fix.cc +++ b/src/fix-ng/fix.cc @@ -8,7 +8,6 @@ #include "eval.hh" -#if 0 #if 0 static Path searchPath(const Paths & searchDirs, const Path & relPath) { @@ -28,178 +27,9 @@ static Path searchPath(const Paths & searchDirs, const Path & relPath) #endif -static Expr substExpr(string x, Expr rep, Expr e) -{ - char * s; - Expr e2; - - if (ATmatch(e, "Var()", &s)) - if (x == s) - return rep; - else - return e; - - ATermList formals; - if (ATmatch(e, "Function([], )", &formals, &e2)) { - while (!ATisEmpty(formals)) { - if (!ATmatch(ATgetFirst(formals), "", &s)) - throw badTerm("not a list of formals", (ATerm) formals); - if (x == (string) s) - return e; - formals = ATgetNext(formals); - } - } - - /* Generically substitute in subterms. */ - - if (ATgetType(e) == AT_APPL) { - AFun fun = ATgetAFun(e); - int arity = ATgetArity(fun); - ATermList args = ATempty; - - for (int i = arity - 1; i >= 0; i--) - args = ATinsert(args, substExpr(x, rep, ATgetArgument(e, i))); - - return (ATerm) ATmakeApplList(fun, args); - } - - if (ATgetType(e) == AT_LIST) { - ATermList in = (ATermList) e; - ATermList out = ATempty; - - while (!ATisEmpty(in)) { - out = ATinsert(out, substExpr(x, rep, ATgetFirst(in))); - in = ATgetNext(in); - } - - return (ATerm) ATreverse(out); - } - - throw badTerm("do not know how to substitute", e); -} - - -static Expr substExprMany(ATermList formals, ATermList args, Expr body) -{ - char * s; - Expr e; - - /* !!! check args against formals */ - - while (!ATisEmpty(args)) { - ATerm tup = ATgetFirst(args); - if (!ATmatch(tup, "(, )", &s, &e)) - throw badTerm("expected an argument tuple", tup); - - body = substExpr(s, e, body); - - args = ATgetNext(args); - } - - return body; -} - - -static PathSet nixExprRootsCached(EvalState & state, const Path & nePath) -{ - PkgPaths::iterator i = state.pkgPaths.find(nePath); - if (i != state.pkgPaths.end()) - return i->second; - else { - PathSet paths = nixExprRoots(nePath); - state.pkgPaths[nePath] = paths; - return paths; - } -} - - -static Hash hashPackage(EvalState & state, NixExpr ne) -{ - if (ne.type == NixExpr::neDerivation) { - PathSet inputs2; - for (PathSet::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("don't know expression `%1%'") % (string) *i); - inputs2.insert(j->second); - } - ne.derivation.inputs = inputs2; - } - return hashTerm(unparseNixExpr(ne)); -} - - -static string processBinding(EvalState & state, Expr e, NixExpr & ne) -{ - char * s1; - - if (ATmatch(e, "NixExpr()", &s1)) { - Path nePath(s1); - PathSet paths = nixExprRootsCached(state, nePath); - if (paths.size() != 1) abort(); - Path path = *(paths.begin()); - ne.derivation.inputs.insert(nePath); - return path; - } - - if (ATmatch(e, "", &s1)) - return s1; - - if (ATmatch(e, "True")) return "1"; - - if (ATmatch(e, "False")) return ""; - - ATermList l; - if (ATmatch(e, "[]", &l)) { - string s; - bool first = true; - while (!ATisEmpty(l)) { - if (!first) s = s + " "; else first = false; - s += processBinding(state, evalExpr(state, ATgetFirst(l)), ne); - l = ATgetNext(l); - } - return s; - } - - throw badTerm("invalid package binding", e); -} - - +#if 0 static Expr evalExpr2(EvalState & state, Expr e) { - char * s1; - Expr e1, e2, e3, e4; - ATermList bnds; - - /* Normal forms. */ - if (ATmatch(e, "", &s1) || - ATmatch(e, "[]", &e1) || - ATmatch(e, "True") || - ATmatch(e, "False") || - ATmatch(e, "Function([], )", &e1, &e2) || - ATmatch(e, "NixExpr()", &s1)) - return e; - - try { - Hash pkgHash = hashPackage(state, parseNixExpr(e)); - Path pkgPath = writeTerm(e, ""); - state.pkgHashes[pkgPath] = pkgHash; - return ATmake("NixExpr()", pkgPath.c_str()); - } catch (...) { /* !!! catch parse errors only */ - } - - /* Application. */ - if (ATmatch(e, "Call(, [])", &e1, &e2) || - ATmatch(e, "App(, [])", &e1, &e2)) { - e1 = evalExpr(state, e1); - if (!ATmatch(e1, "Function([], )", &e3, &e4)) - throw badTerm("expecting a function", e1); - return evalExpr(state, - substExprMany((ATermList) e3, (ATermList) e2, e4)); - } - /* Conditional. */ if (ATmatch(e, "If(, , )", &e1, &e2, &e3)) { e1 = evalExpr(state, e1); @@ -226,127 +56,6 @@ static Expr evalExpr2(EvalState & state, Expr e) ATmake("True") : ATmake("False"); } - /* Platform constant. */ - if (ATmatch(e, "Platform")) { - return ATmake("", thisSystem.c_str()); - } - - /* Fix inclusion. */ - if (ATmatch(e, "IncludeFix()", &s1)) { - Path fileName(s1); - return evalFile(state, s1); - } - - /* Relative files. */ - if (ATmatch(e, "Relative()", &s1)) { - Path srcPath = s1; - Path dstPath = addToStore(srcPath); - - ClosureElem elem; - NixExpr ne; - ne.type = NixExpr::neClosure; - ne.closure.roots.insert(dstPath); - ne.closure.elems[dstPath] = elem; - - Hash pkgHash = hashPackage(state, ne); - Path pkgPath = writeTerm(unparseNixExpr(ne), ""); - state.pkgHashes[pkgPath] = pkgHash; - - msg(lvlChatty, format("copied `%1%' -> closure `%2%'") - % srcPath % pkgPath); - - return ATmake("NixExpr()", pkgPath.c_str()); - } - - /* Packages are transformed into Nix derivation expressions. */ - if (ATmatch(e, "Package([])", &bnds)) { - - /* Evaluate the bindings and put them in a map. */ - map bndMap; - bndMap["platform"] = ATmake("", thisSystem.c_str()); - while (!ATisEmpty(bnds)) { - ATerm bnd = ATgetFirst(bnds); - if (!ATmatch(bnd, "(, )", &s1, &e1)) - throw badTerm("binding expected", bnd); - bndMap[s1] = evalExpr(state, e1); - bnds = ATgetNext(bnds); - } - - /* Gather information for building the derivation - expression. */ - NixExpr ne; - ne.type = NixExpr::neDerivation; - ne.derivation.platform = thisSystem; - string name; - Path outPath; - Hash outHash; - bool outHashGiven = false; - bnds = ATempty; - - for (map::iterator it = bndMap.begin(); - it != bndMap.end(); it++) - { - string key = it->first; - ATerm value = it->second; - - if (key == "args") { - ATermList args; - if (!ATmatch(value, "[]", &args)) - throw badTerm("list expected", value); - - while (!ATisEmpty(args)) { - Expr arg = evalExpr(state, ATgetFirst(args)); - ne.derivation.args.push_back(processBinding(state, arg, ne)); - args = ATgetNext(args); - } - } - - else { - string s = processBinding(state, value, ne); - ne.derivation.env[key] = s; - - if (key == "build") ne.derivation.builder = s; - if (key == "name") name = s; - if (key == "outPath") outPath = s; - if (key == "id") { - outHash = parseHash(s); - outHashGiven = true; - } - } - - bnds = ATinsert(bnds, - ATmake("(, )", key.c_str(), value)); - } - - if (ne.derivation.builder == "") - throw badTerm("no builder specified", e); - - if (name == "") - throw badTerm("no package name specified", e); - - /* Determine the output path. */ - if (!outHashGiven) outHash = hashPackage(state, ne); - if (outPath == "") - /* Hash the Nix expression with no outputs to produce a - unique but deterministic path name for this package. */ - outPath = - canonPath(nixStore + "/" + ((string) outHash).c_str() + "-" + name); - ne.derivation.env["out"] = outPath; - ne.derivation.outputs.insert(outPath); - - /* Write the resulting term into the Nix store directory. */ - Hash pkgHash = outHashGiven - ? hashString((string) outHash + outPath) - : hashPackage(state, ne); - Path pkgPath = writeTerm(unparseNixExpr(ne), "-d-" + name); - state.pkgHashes[pkgPath] = pkgHash; - - msg(lvlChatty, format("instantiated `%1%' -> `%2%'") - % name % pkgPath); - - return ATmake("NixExpr()", pkgPath.c_str()); - } - /* BaseName primitive function. */ if (ATmatch(e, "BaseName()", &e1)) { e1 = evalExpr(state, e1); @@ -355,8 +64,6 @@ static Expr evalExpr2(EvalState & state, Expr e) return ATmake("", baseNameOf(s1).c_str()); } - /* Barf. */ - throw badTerm("invalid expression", e); } #endif @@ -374,17 +81,27 @@ static Expr evalStdin(EvalState & state) static void printNixExpr(EvalState & state, Expr e) { ATermList es; - char * s; - if (ATmatch(e, "NixExpr()", &s)) { - cout << format("%1%\n") % s; - } - else if (ATmatch(e, "[]", &es)) { + + if (ATmatch(e, "Attrs([])", &es)) { + Expr a = queryAttr(e, "type"); + if (a && evalString(state, a) == "derivation") { + a = queryAttr(e, "drvPath"); + if (a) { + cout << format("%1%\n") % evalPath(state, a); + return; + } + } + } + + if (ATmatch(e, "[]", &es)) { while (!ATisEmpty(es)) { printNixExpr(state, evalExpr(state, ATgetFirst(es))); es = ATgetNext(es); } + return; } - else throw badTerm("top level does not evaluate to a (list of) Nix expression(s)", e); + + throw badTerm("top level does not evaluate to one or more Nix expressions", e); } @@ -435,6 +152,8 @@ void run(Strings args) Expr e = evalFile(state, absPath(*it)); printNixExpr(state, e); } + + printEvalStats(state); } -- cgit 1.4.1