1
1
Fork 0
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:
Eelco Dolstra 2007-10-11 21:58:37 +00:00
parent cd9d10d4e3
commit 981afe821c
7 changed files with 47 additions and 10 deletions

View file

@ -1,3 +1,5 @@
#include <iostream>
#include "eval.hh"
#include "parser.hh"
#include "hash.hh"
@ -15,6 +17,9 @@
namespace nix {
int cacheTerms;
EvalState::EvalState()
: normalForms(32768), primOps(128)
{
@ -24,7 +29,7 @@ EvalState::EvalState()
addPrimOps();
cacheTerms = getEnv("NIX_TERM_CACHE", "1") == "1";
if (!string2Int(getEnv("NIX_TERM_CACHE"), cacheTerms)) cacheTerms = 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;
if (!matchFormal(*i, name, values, def2)) abort();
if ((value = args.get(name)))
actualArgs.set(name, makeAttrRHS(value, makeNoPos()));
actualArgs.set(name, makeAttrRHS(allocCell(value), makeNoPos()));
else if (!matchDefaultValue(def2, def))
throw TypeError(format("cannot auto-call a function that has an argument without a default value (`%1%')")
% aterm2String(name));
@ -485,7 +490,7 @@ LocalNoInline(Expr evalCall(EvalState & state, Expr fun, Expr arg))
try {
arg = speculativeEval(state, arg);
ATermMap subs(1);
subs.set(name, arg);
subs.set(name, allocCell(arg));
return evalExpr(state, substitute(Substitution(0, &subs), body));
} catch (Error & e) {
addErrorPrefix(e, "while evaluating the function at %1%:\n",
@ -641,6 +646,10 @@ Expr evalExpr2(EvalState & state, Expr e)
Expr e1, e2, e3;
ATerm name, pos;
int bla;
if (matchCell(e, bla, e1)) e = e1;
AFun sym = ATgetAFun(e);
/* Normal forms. */
@ -732,6 +741,7 @@ Expr evalExpr2(EvalState & state, Expr e)
if (matchOpConcat(e, e1, e2)) return evalOpConcat(state, e1, e2);
/* Barf. */
//printMsg(lvlError, format("%1%") % e);
abort();
}
@ -747,7 +757,13 @@ Expr evalExpr(EvalState & state, Expr e)
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
previously evaluated expressions. */

View file

@ -27,6 +27,9 @@ struct EvalState;
typedef Expr (* PrimOp) (EvalState &, const ATermVector & args);
extern int cacheTerms; // 0 = don't, 1 = do, 2 = "cell" terms only
struct EvalState
{
ATermMap normalForms;
@ -38,7 +41,6 @@ struct EvalState
unsigned int nrEvaluated;
unsigned int nrCached;
bool cacheTerms;
bool strictMode;
ATermMap parsings; /* path -> expr mapping */

View file

@ -73,6 +73,8 @@ Inherit | Expr ATermList Pos | ATerm |
Scope | | Expr |
Cell | int Expr | Expr |
Formal | string ValidValues DefaultValue | ATerm |
ValidValues | ATermList | ValidValues |

View file

@ -2,6 +2,7 @@
#include "derivations.hh"
#include "util.hh"
#include "aterm.hh"
#include "eval.hh" // !!! urgh
#include "nixexpr-ast.hh"
#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);
}
}

View file

@ -117,6 +117,9 @@ string showType(Expr e);
string showValue(Expr e);
Expr allocCell(Expr e); // make an updateable cell (for simulating conventional laziness)
}

View file

@ -57,7 +57,7 @@ static Expr fixAttrs(int recursive, ATermList as)
bool fromScope = matchScope(src);
for (ATermIterator j(names); j; ++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);
}
@ -226,7 +226,7 @@ binds
bind
: ID '=' expr ';'
{ $$ = makeBind($1, $3, CUR_POS); }
{ $$ = makeBind($1, allocCell($3), CUR_POS); }
| INHERIT inheritsrc ids ';'
{ $$ = makeInherit($2, $3, CUR_POS); }
;

View file

@ -567,9 +567,9 @@ static Expr prim_derivationLazy(EvalState & state, const ATermVector & args)
Expr drvStrict = makeCall(makeVar(toATerm("derivation!")), eAttrs);
attrs.set(toATerm("outPath"),
makeAttrRHS(makeSelect(drvStrict, toATerm("outPath")), makeNoPos()));
makeAttrRHS(allocCell(makeSelect(drvStrict, toATerm("outPath"))), makeNoPos()));
attrs.set(toATerm("drvPath"),
makeAttrRHS(makeSelect(drvStrict, toATerm("drvPath")), makeNoPos()));
makeAttrRHS(allocCell(makeSelect(drvStrict, toATerm("drvPath"))), makeNoPos()));
return makeAttrs(attrs);
}
@ -773,7 +773,7 @@ static Expr prim_listToAttrs(EvalState & state, const ATermVector & args)
Expr e = evalExpr(state, makeSelect(evaledExpr, toATerm("name")));
string attr = evalStringNoCtx(state,e);
Expr r = makeSelect(evaledExpr, toATerm("value"));
res.set(toATerm(attr), makeAttrRHS(r, makeNoPos()));
res.set(toATerm(attr), makeAttrRHS(allocCell(r), makeNoPos()));
}
else
throw TypeError(format("list element in `listToAttrs' is %s, expected a set { name = \"<name>\"; value = <value>; }")