2003-10-30 16:48:26 +00:00
|
|
|
#ifndef __EVAL_H
|
|
|
|
#define __EVAL_H
|
|
|
|
|
|
|
|
#include <map>
|
|
|
|
|
2003-11-18 11:22:29 +00:00
|
|
|
#include "aterm.hh"
|
2003-11-18 12:06:07 +00:00
|
|
|
#include "nixexpr.hh"
|
2003-10-30 16:48:26 +00:00
|
|
|
|
|
|
|
|
2006-09-04 21:06:23 +00:00
|
|
|
namespace nix {
|
|
|
|
|
|
|
|
|
|
|
|
class Hash;
|
2010-03-29 14:37:56 +00:00
|
|
|
class EvalState;
|
|
|
|
struct Env;
|
|
|
|
struct Value;
|
|
|
|
|
|
|
|
typedef ATerm Sym;
|
|
|
|
|
|
|
|
typedef std::map<Sym, Value> Bindings;
|
|
|
|
|
|
|
|
|
|
|
|
struct Env
|
|
|
|
{
|
|
|
|
Env * up;
|
|
|
|
Bindings bindings;
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
typedef enum {
|
|
|
|
tInt = 1,
|
|
|
|
tBool,
|
|
|
|
tString,
|
|
|
|
tPath,
|
|
|
|
tNull,
|
|
|
|
tAttrs,
|
|
|
|
tList,
|
|
|
|
tThunk,
|
2010-03-30 13:47:59 +00:00
|
|
|
tApp,
|
2010-03-29 14:37:56 +00:00
|
|
|
tLambda,
|
|
|
|
tCopy,
|
|
|
|
tBlackhole,
|
|
|
|
tPrimOp,
|
|
|
|
tPrimOpApp,
|
|
|
|
} ValueType;
|
|
|
|
|
|
|
|
|
|
|
|
typedef void (* PrimOp) (EvalState & state, Value * * args, Value & v);
|
|
|
|
|
|
|
|
|
|
|
|
struct Value
|
|
|
|
{
|
|
|
|
ValueType type;
|
|
|
|
union
|
|
|
|
{
|
|
|
|
int integer;
|
|
|
|
bool boolean;
|
|
|
|
struct {
|
|
|
|
const char * s;
|
|
|
|
const char * * context;
|
|
|
|
} string;
|
2010-03-30 09:22:33 +00:00
|
|
|
const char * path;
|
2010-03-29 14:37:56 +00:00
|
|
|
Bindings * attrs;
|
|
|
|
struct {
|
|
|
|
unsigned int length;
|
|
|
|
Value * elems;
|
|
|
|
} list;
|
|
|
|
struct {
|
|
|
|
Env * env;
|
|
|
|
Expr expr;
|
|
|
|
} thunk;
|
2010-03-30 13:47:59 +00:00
|
|
|
struct {
|
|
|
|
Value * left, * right;
|
|
|
|
} app;
|
2010-03-29 14:37:56 +00:00
|
|
|
struct {
|
|
|
|
Env * env;
|
|
|
|
Pattern pat;
|
|
|
|
Expr body;
|
|
|
|
} lambda;
|
|
|
|
Value * val;
|
|
|
|
struct {
|
|
|
|
PrimOp fun;
|
|
|
|
unsigned int arity;
|
|
|
|
} primOp;
|
|
|
|
struct {
|
|
|
|
Value * left, * right;
|
|
|
|
unsigned int argsLeft;
|
|
|
|
} primOpApp;
|
|
|
|
};
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
static inline void mkInt(Value & v, int n)
|
|
|
|
{
|
|
|
|
v.type = tInt;
|
|
|
|
v.integer = n;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
static inline void mkBool(Value & v, bool b)
|
|
|
|
{
|
|
|
|
v.type = tBool;
|
|
|
|
v.boolean = b;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2010-04-01 09:55:57 +00:00
|
|
|
static inline void mkThunk(Value & v, Env & env, Expr expr)
|
|
|
|
{
|
|
|
|
v.type = tThunk;
|
|
|
|
v.thunk.env = &env;
|
|
|
|
v.thunk.expr = expr;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2010-04-01 12:04:57 +00:00
|
|
|
static inline void mkCopy(Value & v, Value & src)
|
|
|
|
{
|
|
|
|
v.type = tCopy;
|
|
|
|
v.val = &src;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2010-03-30 18:05:54 +00:00
|
|
|
void mkString(Value & v, const char * s);
|
2010-03-30 22:39:48 +00:00
|
|
|
void mkString(Value & v, const string & s, const PathSet & context = PathSet());
|
2010-03-30 18:05:54 +00:00
|
|
|
void mkPath(Value & v, const char * s);
|
2010-03-30 09:22:33 +00:00
|
|
|
|
|
|
|
|
2006-09-04 21:06:23 +00:00
|
|
|
typedef std::map<Path, Hash> DrvHashes;
|
2003-10-30 16:48:26 +00:00
|
|
|
|
2006-03-09 15:09:18 +00:00
|
|
|
/* Cache for calls to addToStore(); maps source paths to the store
|
|
|
|
paths. */
|
2006-09-04 21:06:23 +00:00
|
|
|
typedef std::map<Path, Path> SrcToStore;
|
2006-03-09 15:09:18 +00:00
|
|
|
|
2004-02-04 16:03:29 +00:00
|
|
|
struct EvalState;
|
2004-08-04 10:59:20 +00:00
|
|
|
|
2010-03-29 14:37:56 +00:00
|
|
|
|
|
|
|
std::ostream & operator << (std::ostream & str, Value & v);
|
2004-02-04 16:03:29 +00:00
|
|
|
|
|
|
|
|
2010-03-30 15:18:20 +00:00
|
|
|
class EvalState
|
2003-10-30 16:48:26 +00:00
|
|
|
{
|
2010-03-31 15:38:03 +00:00
|
|
|
public:
|
2003-10-31 17:09:31 +00:00
|
|
|
DrvHashes drvHashes; /* normalised derivation hashes */
|
2010-03-31 15:38:03 +00:00
|
|
|
|
|
|
|
private:
|
2006-03-09 15:09:18 +00:00
|
|
|
SrcToStore srcToStore;
|
2003-10-30 16:48:26 +00:00
|
|
|
|
2009-05-12 11:06:24 +00:00
|
|
|
bool allowUnsafeEquality;
|
|
|
|
|
2010-03-31 16:14:32 +00:00
|
|
|
ATermMap parseTrees;
|
|
|
|
|
2010-03-30 15:18:20 +00:00
|
|
|
public:
|
|
|
|
|
2003-10-30 16:48:26 +00:00
|
|
|
EvalState();
|
2010-04-09 12:00:49 +00:00
|
|
|
~EvalState();
|
2004-02-04 16:03:29 +00:00
|
|
|
|
2010-03-30 09:22:33 +00:00
|
|
|
/* Evaluate an expression read from the given file to normal
|
|
|
|
form. */
|
|
|
|
void evalFile(const Path & path, Value & v);
|
|
|
|
|
2010-03-29 14:37:56 +00:00
|
|
|
/* Evaluate an expression to normal form, storing the result in
|
|
|
|
value `v'. */
|
|
|
|
void eval(Expr e, Value & v);
|
|
|
|
void eval(Env & env, Expr e, Value & v);
|
|
|
|
|
|
|
|
/* Evaluation the expression, then verify that it has the expected
|
|
|
|
type. */
|
|
|
|
bool evalBool(Env & env, Expr e);
|
|
|
|
|
|
|
|
/* If `v' is a thunk, enter it and overwrite `v' with the result
|
2010-03-30 13:47:59 +00:00
|
|
|
of the evaluation of the thunk. If `v' is a delayed function
|
|
|
|
application, call the function and overwrite `v' with the
|
|
|
|
result. Otherwise, this is a no-op. */
|
2010-03-29 14:37:56 +00:00
|
|
|
void forceValue(Value & v);
|
|
|
|
|
2010-04-07 13:55:46 +00:00
|
|
|
/* Force a value, then recursively force list elements and
|
|
|
|
attributes. */
|
|
|
|
void strictForceValue(Value & v);
|
|
|
|
|
2010-03-29 14:37:56 +00:00
|
|
|
/* Force `v', and then verify that it has the expected type. */
|
|
|
|
int forceInt(Value & v);
|
2010-03-31 15:38:03 +00:00
|
|
|
bool forceBool(Value & v);
|
2010-03-29 14:37:56 +00:00
|
|
|
void forceAttrs(Value & v);
|
|
|
|
void forceList(Value & v);
|
2010-03-30 13:47:59 +00:00
|
|
|
void forceFunction(Value & v); // either lambda or primop
|
2010-03-31 15:38:03 +00:00
|
|
|
string forceString(Value & v);
|
2010-03-31 19:52:29 +00:00
|
|
|
string forceString(Value & v, PathSet & context);
|
2010-03-30 18:05:54 +00:00
|
|
|
string forceStringNoCtx(Value & v);
|
2010-03-29 14:37:56 +00:00
|
|
|
|
2010-04-07 13:55:46 +00:00
|
|
|
/* Return true iff the value `v' denotes a derivation (i.e. a
|
|
|
|
set with attribute `type = "derivation"'). */
|
|
|
|
bool isDerivation(Value & v);
|
|
|
|
|
2010-03-30 09:22:33 +00:00
|
|
|
/* String coercion. Converts strings, paths and derivations to a
|
|
|
|
string. If `coerceMore' is set, also converts nulls, integers,
|
|
|
|
booleans and lists to a string. If `copyToStore' is set,
|
|
|
|
referenced paths are copied to the Nix store as a side effect.q */
|
|
|
|
string coerceToString(Value & v, PathSet & context,
|
|
|
|
bool coerceMore = false, bool copyToStore = true);
|
|
|
|
|
|
|
|
/* Path coercion. Converts strings, paths and derivations to a
|
|
|
|
path. The result is guaranteed to be a canonicalised, absolute
|
|
|
|
path. Nothing is copied to the store. */
|
|
|
|
Path coerceToPath(Value & v, PathSet & context);
|
|
|
|
|
2010-03-29 14:37:56 +00:00
|
|
|
private:
|
|
|
|
|
|
|
|
/* The base environment, containing the builtin functions and
|
|
|
|
values. */
|
|
|
|
Env & baseEnv;
|
|
|
|
|
|
|
|
void createBaseEnv();
|
|
|
|
|
2010-03-30 14:39:27 +00:00
|
|
|
void addConstant(const string & name, Value & v);
|
|
|
|
|
2004-08-04 10:59:20 +00:00
|
|
|
void addPrimOp(const string & name,
|
|
|
|
unsigned int arity, PrimOp primOp);
|
2010-03-29 14:37:56 +00:00
|
|
|
|
|
|
|
/* Do a deep equality test between two values. That is, list
|
|
|
|
elements and attributes are compared recursively. */
|
|
|
|
bool eqValues(Value & v1, Value & v2);
|
|
|
|
|
2010-03-30 13:47:59 +00:00
|
|
|
public:
|
|
|
|
|
2010-04-07 13:55:46 +00:00
|
|
|
void callFunction(Value & fun, Value & arg, Value & v);
|
|
|
|
|
2010-04-07 15:47:06 +00:00
|
|
|
/* Automatically call a function for which each argument has a
|
|
|
|
default value or has a binding in the `args' map. */
|
|
|
|
void autoCallFunction(const Bindings & args, Value & fun, Value & res);
|
|
|
|
|
2010-03-29 14:37:56 +00:00
|
|
|
/* Allocation primitives. */
|
|
|
|
Value * allocValues(unsigned int count);
|
|
|
|
Env & allocEnv();
|
2010-03-30 14:39:27 +00:00
|
|
|
|
|
|
|
void mkList(Value & v, unsigned int length);
|
2010-03-30 22:39:48 +00:00
|
|
|
void mkAttrs(Value & v);
|
2010-04-07 15:47:06 +00:00
|
|
|
void mkThunk_(Value & v, Expr expr);
|
|
|
|
|
2010-03-31 15:38:03 +00:00
|
|
|
void cloneAttrs(Value & src, Value & dst);
|
|
|
|
|
2010-03-30 15:18:20 +00:00
|
|
|
/* Print statistics. */
|
|
|
|
void printStats();
|
2010-04-09 12:00:49 +00:00
|
|
|
|
|
|
|
private:
|
|
|
|
|
|
|
|
unsigned long nrValues;
|
|
|
|
unsigned long nrEnvs;
|
|
|
|
unsigned long nrEvaluated;
|
|
|
|
unsigned int recursionDepth;
|
|
|
|
unsigned int maxRecursionDepth;
|
|
|
|
char * deepestStack; /* for measuring stack usage */
|
|
|
|
|
|
|
|
friend class RecursionCounter;
|
2003-10-30 16:48:26 +00:00
|
|
|
};
|
2010-04-07 13:55:46 +00:00
|
|
|
|
|
|
|
|
|
|
|
/* Return a string representing the type of the value `v'. */
|
|
|
|
string showType(Value & v);
|
2003-10-30 16:48:26 +00:00
|
|
|
|
|
|
|
|
2006-09-04 21:06:23 +00:00
|
|
|
}
|
|
|
|
|
2003-10-30 16:48:26 +00:00
|
|
|
|
|
|
|
#endif /* !__EVAL_H */
|