about summary refs log tree commit diff
diff options
context:
space:
mode:
authorEelco Dolstra <e.dolstra@tudelft.nl>2010-03-29T10·13+0000
committerEelco Dolstra <e.dolstra@tudelft.nl>2010-03-29T10·13+0000
commit52090d24185f5092bfd5f8f1fdf0d0890e19a09d (patch)
tree403de8fca397bcc363de5a4e8eb49c4be8ee91cc
parente3f32ac5af69641d12ad07a52f3ab495f61938f1 (diff)
-rw-r--r--src/libexpr/eval-test.cc32
1 files changed, 32 insertions, 0 deletions
diff --git a/src/libexpr/eval-test.cc b/src/libexpr/eval-test.cc
index 983cac9515fe..543a9cf85298 100644
--- a/src/libexpr/eval-test.cc
+++ b/src/libexpr/eval-test.cc
@@ -125,6 +125,9 @@ std::ostream & operator << (std::ostream & str, Value & v)
     case tString:
         str << "\"" << v.string.s << "\""; // !!! escaping
         break;
+    case tNull:
+        str << "true";
+        break;
     case tAttrs:
         str << "{ ";
         foreach (Bindings::iterator, i, *v.attrs)
@@ -308,6 +311,16 @@ static Env & allocEnv()
 char * p1 = 0, * p2 = 0;
 
 
+static bool evalBool(Env & env, Expr e)
+{
+    Value v;
+    eval(env, e, v);
+    if (v.type != tBool)
+        throw TypeError(format("value is %1% while a Boolean was expected") % showType(v));
+    return v.boolean;
+}
+
+
 static void eval(Env & env, Expr e, Value & v)
 {
     char c;
@@ -569,6 +582,17 @@ static void eval(Env & env, Expr e, Value & v)
         return;
     }
 
+    Expr e3;
+    if (matchIf(e, e1, e2, e3)) {
+        eval(env, evalBool(env, e1) ? e2 : e3, v);
+        return;
+    }
+
+    if (matchOpOr(e, e1, e2)) {
+        mkBool(v, evalBool(env, e1) || evalBool(env, e2));
+        return;
+    }
+
     throw Error("unsupported term");
 }
 
@@ -633,6 +657,10 @@ void doTest(string s)
         v.type = tBool;
         v.boolean = false;
     }
+    {
+        Value & v = baseEnv.bindings[toATerm("null")];
+        v.type = tNull;
+    }
 
     /* Add primops to the base environment. */
     addPrimOp(baseEnv, "__head", 1, prim_head);
@@ -689,6 +717,10 @@ void run(Strings args)
     doTest("null");
     doTest("\"foo\"");
     doTest("let s = \"bar\"; in \"foo${s}\"");
+    doTest("if true then 1 else 2");
+    doTest("if false then 1 else 2");
+    doTest("if false || true then 1 else 2");
+    doTest("let x = x; in if true || x then 1 else 2");
     
     printMsg(lvlError, format("alloced %1% values") % nrValues);
     printMsg(lvlError, format("alloced %1% environments") % nrEnvs);