From 54945a2950174ded83d58336061b4a9990cdbbfd Mon Sep 17 00:00:00 2001 From: Eelco Dolstra Date: Sat, 6 Aug 2011 13:02:55 +0000 Subject: [PATCH] * Refactoring: move parseExprFromFile() and parseExprFromString() into the EvalState class. --- src/libexpr/Makefile.am | 2 +- src/libexpr/common-opts.cc | 3 +-- src/libexpr/eval.cc | 9 ++------- src/libexpr/eval.hh | 10 ++++++++++ src/libexpr/parser.hh | 21 --------------------- src/libexpr/parser.y | 24 +++++++++++++++--------- src/libexpr/primops.cc | 3 +-- src/nix-env/nix-env.cc | 7 +++---- src/nix-env/user-env.cc | 5 ++--- src/nix-instantiate/nix-instantiate.cc | 5 ++--- 10 files changed, 37 insertions(+), 52 deletions(-) delete mode 100644 src/libexpr/parser.hh diff --git a/src/libexpr/Makefile.am b/src/libexpr/Makefile.am index f9da9ac01b..c159757774 100644 --- a/src/libexpr/Makefile.am +++ b/src/libexpr/Makefile.am @@ -6,7 +6,7 @@ libexpr_la_SOURCES = \ names.cc pkginclude_HEADERS = \ - nixexpr.hh eval.hh parser.hh lexer-tab.hh parser-tab.hh \ + nixexpr.hh eval.hh lexer-tab.hh parser-tab.hh \ get-drvs.hh attr-path.hh value-to-xml.hh common-opts.hh \ names.hh symbol-table.hh diff --git a/src/libexpr/common-opts.cc b/src/libexpr/common-opts.cc index c364aa9cb5..bab31f4935 100644 --- a/src/libexpr/common-opts.cc +++ b/src/libexpr/common-opts.cc @@ -1,7 +1,6 @@ #include "common-opts.hh" #include "../libmain/shared.hh" #include "util.hh" -#include "parser.hh" namespace nix { @@ -25,7 +24,7 @@ bool parseOptionArg(const string & arg, Strings::iterator & i, autoArgs.push_back(Attr(state.symbols.create(name), v)); if (arg == "--arg") - state.mkThunk_(*v, parseExprFromString(state, value, absPath("."))); + state.mkThunk_(*v, state.parseExprFromString(value, absPath("."))); else mkString(*v, value); diff --git a/src/libexpr/eval.cc b/src/libexpr/eval.cc index acf5d7a8ae..5701452f94 100644 --- a/src/libexpr/eval.cc +++ b/src/libexpr/eval.cc @@ -1,5 +1,4 @@ #include "eval.hh" -#include "parser.hh" #include "hash.hh" #include "util.hh" #include "store-api.hh" @@ -427,14 +426,10 @@ void EvalState::evalFile(const Path & path, Value & v) { startNest(nest, lvlTalkative, format("evaluating file `%1%'") % path); - Expr * e = parseTrees[path]; - - if (!e) { - e = parseExprFromFile(*this, path); - parseTrees[path] = e; - } + Expr * e = parseExprFromFile(path); try { + /* !!! Maybe we should cache the evaluation result. */ eval(e, v); } catch (Error & e) { addErrorPrefix(e, "while evaluating the file `%1%':\n", path); diff --git a/src/libexpr/eval.hh b/src/libexpr/eval.hh index 7b7fea9345..e900217fa4 100644 --- a/src/libexpr/eval.hh +++ b/src/libexpr/eval.hh @@ -218,6 +218,13 @@ public: EvalState(); ~EvalState(); + /* Parse a Nix expression from the specified file. If `path' + refers to a directory, then "/default.nix" is appended. */ + Expr * parseExprFromFile(Path path); + + /* Parse a Nix expression from the specified string. */ + Expr * parseExprFromString(const string & s, const Path & basePath); + /* Evaluate an expression read from the given file to normal form. */ void evalFile(const Path & path, Value & v); @@ -296,6 +303,9 @@ private: friend class ExprAttrs; friend class ExprLet; + Expr * parse(const char * text, + const Path & path, const Path & basePath); + public: /* Do a deep equality test between two values. That is, list diff --git a/src/libexpr/parser.hh b/src/libexpr/parser.hh deleted file mode 100644 index c8c8ad8090..0000000000 --- a/src/libexpr/parser.hh +++ /dev/null @@ -1,21 +0,0 @@ -#ifndef __PARSER_H -#define __PARSER_H - -#include "eval.hh" - - -namespace nix { - - -/* Parse a Nix expression from the specified file. If `path' refers - to a directory, then "/default.nix" is appended. */ -Expr * parseExprFromFile(EvalState & state, Path path); - -/* Parse a Nix expression from the specified string. */ -Expr * parseExprFromString(EvalState & state, const string & s, const Path & basePath); - - -} - - -#endif /* !__PARSER_H */ diff --git a/src/libexpr/parser.y b/src/libexpr/parser.y index e5c586266f..a64d327b45 100644 --- a/src/libexpr/parser.y +++ b/src/libexpr/parser.y @@ -450,11 +450,11 @@ formal namespace nix { -static Expr * parse(EvalState & state, const char * text, +Expr * EvalState::parse(const char * text, const Path & path, const Path & basePath) { yyscan_t scanner; - ParseData data(state.symbols); + ParseData data(symbols); data.basePath = basePath; data.path = path; @@ -466,7 +466,7 @@ static Expr * parse(EvalState & state, const char * text, if (res) throw ParseError(data.error); try { - data.result->bindVars(state.staticBaseEnv); + data.result->bindVars(staticBaseEnv); } catch (Error & e) { throw ParseError(format("%1%, in `%2%'") % e.msg() % path); } @@ -475,7 +475,7 @@ static Expr * parse(EvalState & state, const char * text, } -Expr * parseExprFromFile(EvalState & state, Path path) +Expr * EvalState::parseExprFromFile(Path path) { assert(path[0] == '/'); @@ -493,15 +493,21 @@ Expr * parseExprFromFile(EvalState & state, Path path) if (S_ISDIR(st.st_mode)) path = canonPath(path + "/default.nix"); - /* Read and parse the input file. */ - return parse(state, readFile(path).c_str(), path, dirOf(path)); + /* Read and parse the input file, unless it's already in the parse + tree cache. */ + Expr * e = parseTrees[path]; + if (!e) { + e = parse(readFile(path).c_str(), path, dirOf(path)); + parseTrees[path] = e; + } + + return e; } -Expr * parseExprFromString(EvalState & state, - const string & s, const Path & basePath) +Expr * EvalState::parseExprFromString(const string & s, const Path & basePath) { - return parse(state, s.c_str(), "(string)", basePath); + return parse(s.c_str(), "(string)", basePath); } diff --git a/src/libexpr/primops.cc b/src/libexpr/primops.cc index 11c67e1383..9d226a3270 100644 --- a/src/libexpr/primops.cc +++ b/src/libexpr/primops.cc @@ -5,7 +5,6 @@ #include "util.hh" #include "archive.hh" #include "value-to-xml.hh" -#include "parser.hh" #include "names.hh" #include @@ -1059,7 +1058,7 @@ void EvalState::createBaseEnv() /* Add a wrapper around the derivation primop that computes the `drvPath' and `outPath' attributes lazily. */ string s = "attrs: let res = derivationStrict attrs; in attrs // { drvPath = res.drvPath; outPath = res.outPath; type = \"derivation\"; }"; - mkThunk_(v, parseExprFromString(*this, s, "/")); + mkThunk_(v, parseExprFromString(s, "/")); addConstant("derivation", v); // Paths diff --git a/src/nix-env/nix-env.cc b/src/nix-env/nix-env.cc index 9cfc69547a..4ea301def0 100644 --- a/src/nix-env/nix-env.cc +++ b/src/nix-env/nix-env.cc @@ -3,7 +3,6 @@ #include "globals.hh" #include "misc.hh" #include "shared.hh" -#include "parser.hh" #include "eval.hh" #include "help.txt.hh" #include "get-drvs.hh" @@ -129,7 +128,7 @@ static void getAllExprs(EvalState & state, if (hasSuffix(attrName, ".nix")) attrName = string(attrName, 0, attrName.size() - 4); attrs.attrs[state.symbols.create(attrName)] = - ExprAttrs::AttrDef(parseExprFromFile(state, absPath(path2)), noPos); + ExprAttrs::AttrDef(state.parseExprFromFile(absPath(path2)), noPos); } else /* `path2' is a directory (with no default.nix in it); @@ -141,7 +140,7 @@ static void getAllExprs(EvalState & state, static Expr * loadSourceExpr(EvalState & state, const Path & path) { - if (isNixExpr(path)) return parseExprFromFile(state, absPath(path)); + if (isNixExpr(path)) return state.parseExprFromFile(absPath(path)); /* The path is a directory. Put the Nix expressions in the directory in an attribute set, with the file name of each @@ -354,7 +353,7 @@ static void queryInstSources(EvalState & state, Expr * e1 = loadSourceExpr(state, instSource.nixExprPath); foreach (Strings::const_iterator, i, args) { - Expr * e2 = parseExprFromString(state, *i, absPath(".")); + Expr * e2 = state.parseExprFromString(*i, absPath(".")); Expr * call = new ExprApp(e2, e1); Value v; state.eval(call, v); getDerivations(state, v, "", instSource.autoArgs, elems); diff --git a/src/nix-env/user-env.cc b/src/nix-env/user-env.cc index 865d24e2f9..670052bcbb 100644 --- a/src/nix-env/user-env.cc +++ b/src/nix-env/user-env.cc @@ -5,7 +5,6 @@ #include "globals.hh" #include "shared.hh" #include "eval.hh" -#include "parser.hh" #include "profiles.hh" @@ -24,7 +23,7 @@ DrvInfos queryInstalled(EvalState & state, const Path & userEnv) if (pathExists(manifestFile)) { Value v; - state.eval(parseExprFromFile(state, manifestFile), v); + state.evalFile(manifestFile, v); Bindings bindings; getDerivations(state, v, "", bindings, elems); } else if (pathExists(oldManifestFile)) @@ -113,7 +112,7 @@ bool createUserEnv(EvalState & state, DrvInfos & elems, /* Get the environment builder expression. */ Value envBuilder; - state.eval(parseExprFromFile(state, nixDataDir + "/nix/corepkgs/buildenv"), envBuilder); + state.evalFile(nixDataDir + "/nix/corepkgs/buildenv", envBuilder); /* Construct a Nix expression that calls the user environment builder with the manifest as argument. */ diff --git a/src/nix-instantiate/nix-instantiate.cc b/src/nix-instantiate/nix-instantiate.cc index 3d3b643cfd..1f90595391 100644 --- a/src/nix-instantiate/nix-instantiate.cc +++ b/src/nix-instantiate/nix-instantiate.cc @@ -1,7 +1,6 @@ #include "globals.hh" #include "shared.hh" #include "eval.hh" -#include "parser.hh" #include "get-drvs.hh" #include "attr-path.hh" #include "value-to-xml.hh" @@ -28,7 +27,7 @@ static Expr * parseStdin(EvalState & state) startNest(nest, lvlTalkative, format("parsing standard input")); string s, s2; while (getline(std::cin, s2)) s += s2 + "\n"; - return parseExprFromString(state, s, absPath(".")); + return state.parseExprFromString(s, absPath(".")); } @@ -139,7 +138,7 @@ void run(Strings args) foreach (Strings::iterator, i, files) { Path path = absPath(*i); - Expr * e = parseExprFromFile(state, path); + Expr * e = state.parseExprFromFile(path); processExpr(state, attrPaths, parseOnly, strict, autoArgs, evalOnly, xmlOutput, xmlOutputSourceLocation, e); }