mirror of
https://github.com/NixOS/nix.git
synced 2025-11-26 04:00:59 +01:00
* Some hacks to simulate conventional laziness.
This commit is contained in:
parent
cd9d10d4e3
commit
981afe821c
7 changed files with 47 additions and 10 deletions
|
|
@ -1,3 +1,5 @@
|
||||||
|
#include <iostream>
|
||||||
|
|
||||||
#include "eval.hh"
|
#include "eval.hh"
|
||||||
#include "parser.hh"
|
#include "parser.hh"
|
||||||
#include "hash.hh"
|
#include "hash.hh"
|
||||||
|
|
@ -15,6 +17,9 @@
|
||||||
namespace nix {
|
namespace nix {
|
||||||
|
|
||||||
|
|
||||||
|
int cacheTerms;
|
||||||
|
|
||||||
|
|
||||||
EvalState::EvalState()
|
EvalState::EvalState()
|
||||||
: normalForms(32768), primOps(128)
|
: normalForms(32768), primOps(128)
|
||||||
{
|
{
|
||||||
|
|
@ -24,7 +29,7 @@ EvalState::EvalState()
|
||||||
|
|
||||||
addPrimOps();
|
addPrimOps();
|
||||||
|
|
||||||
cacheTerms = getEnv("NIX_TERM_CACHE", "1") == "1";
|
if (!string2Int(getEnv("NIX_TERM_CACHE"), cacheTerms)) cacheTerms = 1;
|
||||||
strictMode = getEnv("NIX_STRICT", "0") == "1";
|
strictMode = getEnv("NIX_STRICT", "0") == "1";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -405,7 +410,7 @@ Expr autoCallFunction(Expr e, const ATermMap & args)
|
||||||
Expr name, def, value; ATerm values, def2;
|
Expr name, def, value; ATerm values, def2;
|
||||||
if (!matchFormal(*i, name, values, def2)) abort();
|
if (!matchFormal(*i, name, values, def2)) abort();
|
||||||
if ((value = args.get(name)))
|
if ((value = args.get(name)))
|
||||||
actualArgs.set(name, makeAttrRHS(value, makeNoPos()));
|
actualArgs.set(name, makeAttrRHS(allocCell(value), makeNoPos()));
|
||||||
else if (!matchDefaultValue(def2, def))
|
else if (!matchDefaultValue(def2, def))
|
||||||
throw TypeError(format("cannot auto-call a function that has an argument without a default value (`%1%')")
|
throw TypeError(format("cannot auto-call a function that has an argument without a default value (`%1%')")
|
||||||
% aterm2String(name));
|
% aterm2String(name));
|
||||||
|
|
@ -485,7 +490,7 @@ LocalNoInline(Expr evalCall(EvalState & state, Expr fun, Expr arg))
|
||||||
try {
|
try {
|
||||||
arg = speculativeEval(state, arg);
|
arg = speculativeEval(state, arg);
|
||||||
ATermMap subs(1);
|
ATermMap subs(1);
|
||||||
subs.set(name, arg);
|
subs.set(name, allocCell(arg));
|
||||||
return evalExpr(state, substitute(Substitution(0, &subs), body));
|
return evalExpr(state, substitute(Substitution(0, &subs), body));
|
||||||
} catch (Error & e) {
|
} catch (Error & e) {
|
||||||
addErrorPrefix(e, "while evaluating the function at %1%:\n",
|
addErrorPrefix(e, "while evaluating the function at %1%:\n",
|
||||||
|
|
@ -641,6 +646,10 @@ Expr evalExpr2(EvalState & state, Expr e)
|
||||||
|
|
||||||
Expr e1, e2, e3;
|
Expr e1, e2, e3;
|
||||||
ATerm name, pos;
|
ATerm name, pos;
|
||||||
|
|
||||||
|
int bla;
|
||||||
|
if (matchCell(e, bla, e1)) e = e1;
|
||||||
|
|
||||||
AFun sym = ATgetAFun(e);
|
AFun sym = ATgetAFun(e);
|
||||||
|
|
||||||
/* Normal forms. */
|
/* Normal forms. */
|
||||||
|
|
@ -732,6 +741,7 @@ Expr evalExpr2(EvalState & state, Expr e)
|
||||||
if (matchOpConcat(e, e1, e2)) return evalOpConcat(state, e1, e2);
|
if (matchOpConcat(e, e1, e2)) return evalOpConcat(state, e1, e2);
|
||||||
|
|
||||||
/* Barf. */
|
/* Barf. */
|
||||||
|
//printMsg(lvlError, format("%1%") % e);
|
||||||
abort();
|
abort();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -747,7 +757,13 @@ Expr evalExpr(EvalState & state, Expr e)
|
||||||
|
|
||||||
state.nrEvaluated++;
|
state.nrEvaluated++;
|
||||||
|
|
||||||
if (!state.cacheTerms) return evalExpr2(state, e);
|
if (cacheTerms == 0) return evalExpr2(state, e);
|
||||||
|
|
||||||
|
if (cacheTerms == 2) {
|
||||||
|
int pseudoAddr;
|
||||||
|
Expr e2;
|
||||||
|
if (!matchCell(e, pseudoAddr, e2)) return evalExpr2(state, e);
|
||||||
|
}
|
||||||
|
|
||||||
/* Consult the memo table to quickly get the normal form of
|
/* Consult the memo table to quickly get the normal form of
|
||||||
previously evaluated expressions. */
|
previously evaluated expressions. */
|
||||||
|
|
|
||||||
|
|
@ -27,6 +27,9 @@ struct EvalState;
|
||||||
typedef Expr (* PrimOp) (EvalState &, const ATermVector & args);
|
typedef Expr (* PrimOp) (EvalState &, const ATermVector & args);
|
||||||
|
|
||||||
|
|
||||||
|
extern int cacheTerms; // 0 = don't, 1 = do, 2 = "cell" terms only
|
||||||
|
|
||||||
|
|
||||||
struct EvalState
|
struct EvalState
|
||||||
{
|
{
|
||||||
ATermMap normalForms;
|
ATermMap normalForms;
|
||||||
|
|
@ -38,7 +41,6 @@ struct EvalState
|
||||||
unsigned int nrEvaluated;
|
unsigned int nrEvaluated;
|
||||||
unsigned int nrCached;
|
unsigned int nrCached;
|
||||||
|
|
||||||
bool cacheTerms;
|
|
||||||
bool strictMode;
|
bool strictMode;
|
||||||
|
|
||||||
ATermMap parsings; /* path -> expr mapping */
|
ATermMap parsings; /* path -> expr mapping */
|
||||||
|
|
|
||||||
|
|
@ -73,6 +73,8 @@ Inherit | Expr ATermList Pos | ATerm |
|
||||||
|
|
||||||
Scope | | Expr |
|
Scope | | Expr |
|
||||||
|
|
||||||
|
Cell | int Expr | Expr |
|
||||||
|
|
||||||
Formal | string ValidValues DefaultValue | ATerm |
|
Formal | string ValidValues DefaultValue | ATerm |
|
||||||
|
|
||||||
ValidValues | ATermList | ValidValues |
|
ValidValues | ATermList | ValidValues |
|
||||||
|
|
|
||||||
|
|
@ -2,6 +2,7 @@
|
||||||
#include "derivations.hh"
|
#include "derivations.hh"
|
||||||
#include "util.hh"
|
#include "util.hh"
|
||||||
#include "aterm.hh"
|
#include "aterm.hh"
|
||||||
|
#include "eval.hh" // !!! urgh
|
||||||
|
|
||||||
#include "nixexpr-ast.hh"
|
#include "nixexpr-ast.hh"
|
||||||
#include "nixexpr-ast.cc"
|
#include "nixexpr-ast.cc"
|
||||||
|
|
@ -400,4 +401,17 @@ string showValue(Expr e)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static unsigned int cellCount = 0;
|
||||||
|
|
||||||
|
|
||||||
|
Expr allocCell(Expr e)
|
||||||
|
{
|
||||||
|
if (cacheTerms != 2) return e;
|
||||||
|
int i;
|
||||||
|
Expr e2;
|
||||||
|
if (matchCell(e, i, e2)) return e;
|
||||||
|
return makeCell(cellCount++, e);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -117,6 +117,9 @@ string showType(Expr e);
|
||||||
string showValue(Expr e);
|
string showValue(Expr e);
|
||||||
|
|
||||||
|
|
||||||
|
Expr allocCell(Expr e); // make an updateable cell (for simulating conventional laziness)
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -57,7 +57,7 @@ static Expr fixAttrs(int recursive, ATermList as)
|
||||||
bool fromScope = matchScope(src);
|
bool fromScope = matchScope(src);
|
||||||
for (ATermIterator j(names); j; ++j) {
|
for (ATermIterator j(names); j; ++j) {
|
||||||
Expr rhs = fromScope ? makeVar(*j) : makeSelect(src, *j);
|
Expr rhs = fromScope ? makeVar(*j) : makeSelect(src, *j);
|
||||||
*is = ATinsert(*is, makeBind(*j, rhs, pos));
|
*is = ATinsert(*is, makeBind(*j, allocCell(rhs), pos));
|
||||||
}
|
}
|
||||||
} else bs = ATinsert(bs, *i);
|
} else bs = ATinsert(bs, *i);
|
||||||
}
|
}
|
||||||
|
|
@ -226,7 +226,7 @@ binds
|
||||||
|
|
||||||
bind
|
bind
|
||||||
: ID '=' expr ';'
|
: ID '=' expr ';'
|
||||||
{ $$ = makeBind($1, $3, CUR_POS); }
|
{ $$ = makeBind($1, allocCell($3), CUR_POS); }
|
||||||
| INHERIT inheritsrc ids ';'
|
| INHERIT inheritsrc ids ';'
|
||||||
{ $$ = makeInherit($2, $3, CUR_POS); }
|
{ $$ = makeInherit($2, $3, CUR_POS); }
|
||||||
;
|
;
|
||||||
|
|
|
||||||
|
|
@ -567,9 +567,9 @@ static Expr prim_derivationLazy(EvalState & state, const ATermVector & args)
|
||||||
Expr drvStrict = makeCall(makeVar(toATerm("derivation!")), eAttrs);
|
Expr drvStrict = makeCall(makeVar(toATerm("derivation!")), eAttrs);
|
||||||
|
|
||||||
attrs.set(toATerm("outPath"),
|
attrs.set(toATerm("outPath"),
|
||||||
makeAttrRHS(makeSelect(drvStrict, toATerm("outPath")), makeNoPos()));
|
makeAttrRHS(allocCell(makeSelect(drvStrict, toATerm("outPath"))), makeNoPos()));
|
||||||
attrs.set(toATerm("drvPath"),
|
attrs.set(toATerm("drvPath"),
|
||||||
makeAttrRHS(makeSelect(drvStrict, toATerm("drvPath")), makeNoPos()));
|
makeAttrRHS(allocCell(makeSelect(drvStrict, toATerm("drvPath"))), makeNoPos()));
|
||||||
|
|
||||||
return makeAttrs(attrs);
|
return makeAttrs(attrs);
|
||||||
}
|
}
|
||||||
|
|
@ -773,7 +773,7 @@ static Expr prim_listToAttrs(EvalState & state, const ATermVector & args)
|
||||||
Expr e = evalExpr(state, makeSelect(evaledExpr, toATerm("name")));
|
Expr e = evalExpr(state, makeSelect(evaledExpr, toATerm("name")));
|
||||||
string attr = evalStringNoCtx(state,e);
|
string attr = evalStringNoCtx(state,e);
|
||||||
Expr r = makeSelect(evaledExpr, toATerm("value"));
|
Expr r = makeSelect(evaledExpr, toATerm("value"));
|
||||||
res.set(toATerm(attr), makeAttrRHS(r, makeNoPos()));
|
res.set(toATerm(attr), makeAttrRHS(allocCell(r), makeNoPos()));
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
throw TypeError(format("list element in `listToAttrs' is %s, expected a set { name = \"<name>\"; value = <value>; }")
|
throw TypeError(format("list element in `listToAttrs' is %s, expected a set { name = \"<name>\"; value = <value>; }")
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue