about summary refs log tree commit diff
path: root/src/libexpr/eval.cc
diff options
context:
space:
mode:
authorEelco Dolstra <e.dolstra@tudelft.nl>2010-03-30T15·18+0000
committerEelco Dolstra <e.dolstra@tudelft.nl>2010-03-30T15·18+0000
commitc9170be2bd2e735b37db7e7b4ccaca86835cb5c5 (patch)
treec3351fae157aea73085ec17aebe75decdbf921eb /src/libexpr/eval.cc
parentc3aa615a5f4a8bdde5d836ce91d5daa743ded065 (diff)
* More primops.
Diffstat (limited to 'src/libexpr/eval.cc')
-rw-r--r--src/libexpr/eval.cc160
1 files changed, 32 insertions, 128 deletions
diff --git a/src/libexpr/eval.cc b/src/libexpr/eval.cc
index 06ca01ff44..34c4203390 100644
--- a/src/libexpr/eval.cc
+++ b/src/libexpr/eval.cc
@@ -405,21 +405,35 @@ void EvalState::eval(Env & env, Expr e, Value & v)
     }
 
     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);
+        PathSet context;
+        std::ostringstream s;
+        
+        bool first = true, isPath;
+        
+        for (ATermIterator i(es); i; ++i) {
+            eval(env, *i, v);
+
+            /* If the first element is a path, then the result will
+               also be a path, we don't copy anything (yet - that's
+               done later, since paths are copied when they are used
+               in a derivation), and none of the strings are allowed
+               to have contexts. */
+            if (first) {
+                isPath = v.type == tPath;
+                first = false;
+            }
+            
+            s << coerceToString(v, context, false, !isPath);
         }
-        *t = 0;
-        mkString(v, s);
+        
+        if (isPath && !context.empty())
+            throw EvalError(format("a string that refers to a store path cannot be appended to a path, in `%1%'")
+                % s.str());
+
+        if (isPath)
+            mkPath(v, strdup(s.str().c_str()));
+        else
+            mkString(v, strdup(s.str().c_str())); // !!! context
         return;
     }
 
@@ -969,116 +983,6 @@ ATermList flattenList(EvalState & state, Expr e)
 }
 
 
-string coerceToString(EvalState & state, Expr e, PathSet & context,
-    bool coerceMore, bool copyToStore)
-{
-    e = evalExpr(state, e);
-
-    string s;
-
-    if (matchStr(e, s, context)) return s;
-
-    ATerm s2;
-    if (matchPath(e, s2)) {
-        Path path(canonPath(aterm2String(s2)));
-
-        if (!copyToStore) return path;
-        
-        if (isDerivation(path))
-            throw EvalError(format("file names are not allowed to end in `%1%'")
-                % drvExtension);
-
-        Path dstPath;
-        if (state.srcToStore[path] != "")
-            dstPath = state.srcToStore[path];
-        else {
-            dstPath = readOnlyMode
-                ? computeStorePathForPath(path).first
-                : store->addToStore(path);
-            state.srcToStore[path] = dstPath;
-            printMsg(lvlChatty, format("copied source `%1%' -> `%2%'")
-                % path % dstPath);
-        }
-
-        context.insert(dstPath);
-        return dstPath;
-    }
-        
-    ATermList es;
-    if (matchAttrs(e, es)) {
-        Expr e2 = queryAttr(e, "outPath");
-        if (!e2) throwTypeError("cannot coerce an attribute set (except a derivation) to a string");
-        return coerceToString(state, e2, context, coerceMore, copyToStore);
-    }
-
-    if (coerceMore) {
-
-        /* Note that `false' is represented as an empty string for
-           shell scripting convenience, just like `null'. */
-        if (e == eTrue) return "1";
-        if (e == eFalse) return "";
-        int n;
-        if (matchInt(e, n)) return int2String(n);
-        if (matchNull(e)) return "";
-
-        if (matchList(e, es)) {
-            string result;
-            es = flattenList(state, e);
-            bool first = true;
-            for (ATermIterator i(es); i; ++i) {
-                if (!first) result += " "; else first = false;
-                result += coerceToString(state, *i,
-                    context, coerceMore, copyToStore);
-            }
-            return result;
-        }
-    }
-    
-    throwTypeError("cannot coerce %1% to a string", showType(e));
-}
-
-
-/* Common implementation of `+', ConcatStrings and `~'. */
-static ATerm concatStrings(EvalState & state, ATermVector & args,
-    string separator = "")
-{
-    if (args.empty()) return makeStr("", PathSet());
-    
-    PathSet context;
-    std::ostringstream s;
-
-    /* If the first element is a path, then the result will also be a
-       path, we don't copy anything (yet - that's done later, since
-       paths are copied when they are used in a derivation), and none
-       of the strings are allowed to have contexts. */
-    ATerm dummy;
-    args.front() = evalExpr(state, args.front());
-    bool isPath = matchPath(args.front(), dummy);
-
-    for (ATermVector::const_iterator i = args.begin(); i != args.end(); ++i) {
-        if (i != args.begin()) s << separator;
-        s << coerceToString(state, *i, context, false, !isPath);
-    }
-
-    if (isPath && !context.empty())
-        throw EvalError(format("a string that refers to a store path cannot be appended to a path, in `%1%'")
-            % s.str());
-    
-    return isPath
-        ? makePath(toATerm(s.str()))
-        : makeStr(s.str(), context);
-}
-
-
-Path coerceToPath(EvalState & state, Expr e, PathSet & context)
-{
-    string path = coerceToString(state, e, context, false, false);
-    if (path == "" || path[0] != '/')
-        throw EvalError(format("string `%1%' doesn't represent an absolute path") % path);
-    return path;
-}
-
-
 Expr autoCallFunction(Expr e, const ATermMap & args)
 {
     Pattern pat;
@@ -1515,16 +1419,16 @@ Expr strictEvalExpr(EvalState & state, Expr e)
 #endif
 
 
-void printEvalStats(EvalState & state)
+void EvalState::printStats()
 {
     char x;
     bool showStats = getEnv("NIX_SHOW_STATS", "0") != "0";
     printMsg(showStats ? lvlInfo : lvlDebug,
         format("evaluated %1% expressions, used %2% bytes of stack space, allocated %3% values, allocated %4% environments")
-        % state.nrEvaluated
+        % nrEvaluated
         % (&x - deepestStack)
-        % state.nrValues
-        % state.nrEnvs);
+        % nrValues
+        % nrEnvs);
     if (showStats)
         printATermMapStats();
 }