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 "eval.hh"
#include "parser.hh" #include "parser.hh"
#include "hash.hh" #include "hash.hh"
@ -13,6 +15,9 @@
namespace nix { namespace nix {
int cacheTerms;
EvalState::EvalState() EvalState::EvalState()
@ -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. */

View file

@ -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 */

View file

@ -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 |

View file

@ -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"
@ -399,5 +400,18 @@ string showValue(Expr e)
return "<unknown>"; return "<unknown>";
} }
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

@ -116,6 +116,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)
} }

View file

@ -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); }
; ;

View file

@ -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>; }")