about summary refs log tree commit diff
path: root/src
diff options
context:
space:
mode:
authorEelco Dolstra <e.dolstra@tudelft.nl>2010-03-28T18·27+0000
committerEelco Dolstra <e.dolstra@tudelft.nl>2010-03-28T18·27+0000
commit392811eb8fb8125a6ae9661d5a0fb2a8ced31a94 (patch)
treebcb1e6cb75638e1c66570f0e0cb5b821341c846d /src
parentd96cdcea6b910b9ca169bea0b0b71e65532e70cb (diff)
* Strings.
Diffstat (limited to 'src')
-rw-r--r--src/libexpr/eval-test.cc45
1 files changed, 45 insertions, 0 deletions
diff --git a/src/libexpr/eval-test.cc b/src/libexpr/eval-test.cc
index aafb07d3c546..db54011384d6 100644
--- a/src/libexpr/eval-test.cc
+++ b/src/libexpr/eval-test.cc
@@ -5,6 +5,7 @@
 #include "nixexpr-ast.hh"
 
 #include <cstdlib>
+#include <cstring>
 
 using namespace nix;
 
@@ -27,6 +28,7 @@ struct Env
 typedef enum {
     tInt = 1,
     tBool,
+    tString,
     tAttrs,
     tList,
     tThunk,
@@ -48,6 +50,10 @@ struct Value
     {
         int integer;
         bool boolean;
+        struct {
+            const char * s;
+            const char * * context;
+        } string;
         Bindings * attrs;
         struct {
             unsigned int length;
@@ -97,6 +103,14 @@ static void mkBool(Value & v, bool b)
 }
 
 
+static void mkString(Value & v, const char * s)
+{
+    v.type = tString;
+    v.string.s = s;
+    v.string.context = 0;
+}
+
+
 std::ostream & operator << (std::ostream & str, Value & v)
 {
     switch (v.type) {
@@ -106,6 +120,9 @@ std::ostream & operator << (std::ostream & str, Value & v)
     case tBool:
         str << (v.boolean ? "true" : "false");
         break;
+    case tString:
+        str << "\"" << v.string.s << "\""; // !!! escaping
+        break;
     case tAttrs:
         str << "{ ";
         foreach (Bindings::iterator, i, *v.attrs)
@@ -269,6 +286,13 @@ static void eval(Env & env, Expr e, Value & v)
         return;
     }
 
+    ATerm s; ATermList context;
+    if (matchStr(e, s, context)) {
+        assert(context == ATempty);
+        mkString(v, ATgetName(ATgetAFun(s)));
+        return;
+    }
+
     ATermList es;
     if (matchAttrs(e, es)) {
         v.type = tAttrs;
@@ -481,6 +505,25 @@ static void eval(Env & env, Expr e, Value & v)
         return;
     }
 
+    if (matchConcatStrings(e, es)) {
+        unsigned int n = ATgetLength(es), j = 0;
+        Value vs[n];
+        unsigned int len = 0;
+        for (ATermIterator i(es); i; ++i, ++j) {
+            eval(env, *i, vs[j]);
+            if (vs[j].type != tString) throw TypeError("string expected");
+            len += strlen(vs[j].string.s);
+        }
+        char * s = new char[len + 1], * t = s;
+        for (unsigned int i = 0; i < j; ++i) {
+            strcpy(t, vs[i].string.s);
+            t += strlen(vs[i].string.s);
+        }
+        *t = 0;
+        mkString(v, s);
+        return;
+    }
+
     throw Error("unsupported term");
 }
 
@@ -601,6 +644,8 @@ void run(Strings args)
     doTest("true == false");
     doTest("__head [ 1 2 3 ]");
     doTest("__add 1 2");
+    doTest("\"foo\"");
+    doTest("let s = \"bar\"; in \"foo${s}\"");
     
     printMsg(lvlError, format("alloced %1% values") % nrValues);
     printMsg(lvlError, format("alloced %1% environments") % nrEnvs);