diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/libexpr/eval-test.cc | 40 |
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\"", "/"); |