about summary refs log tree commit diff
path: root/src/libexpr/eval-test.cc
diff options
context:
space:
mode:
Diffstat (limited to 'src/libexpr/eval-test.cc')
-rw-r--r--src/libexpr/eval-test.cc40
1 files changed, 38 insertions, 2 deletions
diff --git a/src/libexpr/eval-test.cc b/src/libexpr/eval-test.cc
index c4e205682a3a..c4fb7d1846ca 100644
--- a/src/libexpr/eval-test.cc
+++ b/src/libexpr/eval-test.cc
@@ -25,7 +25,8 @@ struct Env_
 typedef enum {
     tInt = 1,
     tAttrs,
-    tThunk
+    tThunk,
+    tLambda
 } ValueType;
 
 
@@ -40,6 +41,11 @@ struct Value_
             Env env;
             Expr expr;
         } thunk;
+        struct {
+            Env env;
+            Pattern pat;
+            Expr body;
+        } lambda;
     };
 };
 
@@ -144,7 +150,7 @@ Value eval(Env env, Expr e)
         return v;
     }
 
-    ATerm e2;
+    Expr e2;
     if (matchSelect(e, e2, name)) {
         Value v = eval(env, e2);
         if (v->type != tAttrs) throw TypeError("expected attribute set");
@@ -154,6 +160,34 @@ Value eval(Env env, Expr e)
         return v2;
     }
 
+    Pattern pat; Expr body; Pos pos;
+    if (matchFunction(e, pat, body, pos)) {
+        Value v = new Value_;
+        v->type = tLambda;
+        v->lambda.env = env;
+        v->lambda.pat = pat;
+        v->lambda.body = body;
+        return v;
+    }
+
+    Expr fun, arg;
+    if (matchCall(e, fun, arg)) {
+        Value fun_ = eval(env, fun);
+        if (fun_->type != tLambda) throw TypeError("expected function");
+        if (!matchVarPat(fun_->lambda.pat, name)) throw Error("not implemented");
+
+        Value arg_ = new Value_;
+        arg_->type = tThunk;
+        arg_->thunk.env = env;
+        arg_->thunk.expr = arg;
+        
+        Env env2 = new Env_;
+        env2->up = env;
+        env2->bindings[aterm2String(name)] = arg_;
+
+        return eval(env2, fun_->lambda.body);
+    }
+
     abort();
 }
 
@@ -176,6 +210,8 @@ void run(Strings args)
     doTest("{ x = 1; y = 2; }");
     doTest("{ x = 1; y = 2; }.y");
     doTest("rec { x = 1; y = x; }.y");
+    doTest("(x: x) 1");
+    doTest("(x: y: y) 1 2");
     //Expr e = parseExprFromString(state, "let x = \"a\"; in x + \"b\"", "/");
     //Expr e = parseExprFromString(state, "(x: x + \"b\") \"a\"", "/");
     //Expr e = parseExprFromString(state, "\"a\" + \"b\"", "/");