about summary refs log tree commit diff
path: root/src/libexpr/eval.hh
diff options
context:
space:
mode:
authorEelco Dolstra <e.dolstra@tudelft.nl>2010-03-29T14·37+0000
committerEelco Dolstra <e.dolstra@tudelft.nl>2010-03-29T14·37+0000
commit31428c3a0675f7223470af726bc697dc7a228927 (patch)
tree53957859a3470820461966d2e89ad1563674ba0c /src/libexpr/eval.hh
parent52090d24185f5092bfd5f8f1fdf0d0890e19a09d (diff)
* Started integrating the new evaluator.
Diffstat (limited to 'src/libexpr/eval.hh')
-rw-r--r--src/libexpr/eval.hh152
1 files changed, 142 insertions, 10 deletions
diff --git a/src/libexpr/eval.hh b/src/libexpr/eval.hh
index fed6d34726..8ca997f140 100644
--- a/src/libexpr/eval.hh
+++ b/src/libexpr/eval.hh
@@ -11,7 +11,101 @@ namespace nix {
 
 
 class Hash;
-    
+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,
+    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;
+        Bindings * attrs;
+        struct {
+            unsigned int length;
+            Value * elems;
+        } list;
+        struct {
+            Env * env;
+            Expr expr;
+        } thunk;
+        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;
+}
+
+
+static inline void mkString(Value & v, const char * s)
+{
+    v.type = tString;
+    v.string.s = s;
+    v.string.context = 0;
+}
+
 
 typedef std::map<Path, PathSet> DrvRoots;
 typedef std::map<Path, Hash> DrvHashes;
@@ -22,32 +116,69 @@ typedef std::map<Path, Path> SrcToStore;
 
 struct EvalState;
 
-/* Note: using a ATermVector is safe here, since when we call a primop
-   we also have an ATermList on the stack. */
-typedef Expr (* PrimOp) (EvalState &, const ATermVector & args);
+
+std::ostream & operator << (std::ostream & str, Value & v);
 
 
 struct EvalState 
 {
-    ATermMap normalForms;
-    ATermMap primOps;
     DrvRoots drvRoots;
     DrvHashes drvHashes; /* normalised derivation hashes */
     SrcToStore srcToStore; 
 
-    unsigned int nrEvaluated;
-    unsigned int nrCached;
+    unsigned long nrValues;
+    unsigned long nrEnvs;
+    unsigned long nrEvaluated;
 
     bool allowUnsafeEquality;
 
     EvalState();
 
-    void addPrimOps();
+    /* 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);
+
+    /* Evaluate an expression, and recursively evaluate list elements
+       and attributes. */
+    void strictEval(Expr e, Value & v);
+    void strictEval(Env & env, Expr e, Value & v);
+
+    /* If `v' is a thunk, enter it and overwrite `v' with the result
+       of the evaluation of the thunk.  Otherwise, this is a no-op. */
+    void forceValue(Value & v);
+
+    /* Force `v', and then verify that it has the expected type. */
+    int forceInt(Value & v);
+    void forceAttrs(Value & v);
+    void forceList(Value & v);
+
+private:
+
+    /* The base environment, containing the builtin functions and
+       values. */
+    Env & baseEnv;
+
+    void createBaseEnv();
+    
     void addPrimOp(const string & name,
         unsigned int arity, PrimOp primOp);
+
+    /* Do a deep equality test between two values.  That is, list
+       elements and attributes are compared recursively. */
+    bool eqValues(Value & v1, Value & v2);
+
+    /* Allocation primitives. */
+    Value * allocValues(unsigned int count);
+    Env & allocEnv();
 };
 
 
+#if 0
 /* Evaluate an expression to normal form. */
 Expr evalExpr(EvalState & state, Expr e);
 
@@ -86,11 +217,12 @@ Path coerceToPath(EvalState & state, Expr e, PathSet & context);
    value or has a binding in the `args' map.  Note: result is a call,
    not a normal form; it should be evaluated by calling evalExpr(). */
 Expr autoCallFunction(Expr e, const ATermMap & args);
+#endif
 
 /* Print statistics. */
 void printEvalStats(EvalState & state);
 
- 
+
 }