* More primops.
This commit is contained in:
		
							parent
							
								
									c3aa615a5f
								
							
						
					
					
						commit
						c9170be2bd
					
				
					 4 changed files with 92 additions and 184 deletions
				
			
		|  | @ -405,21 +405,35 @@ void EvalState::eval(Env & env, Expr e, Value & v) | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     if (matchConcatStrings(e, es)) { |     if (matchConcatStrings(e, es)) { | ||||||
|         unsigned int n = ATgetLength(es), j = 0; |         PathSet context; | ||||||
|         Value vs[n]; |         std::ostringstream s; | ||||||
|         unsigned int len = 0; |          | ||||||
|         for (ATermIterator i(es); i; ++i, ++j) { |         bool first = true, isPath; | ||||||
|             eval(env, *i, vs[j]); |          | ||||||
|             if (vs[j].type != tString) throw TypeError("string expected"); |         for (ATermIterator i(es); i; ++i) { | ||||||
|             len += strlen(vs[j].string.s); |             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; | ||||||
|             } |             } | ||||||
|         char * s = new char[len + 1], * t = s; |              | ||||||
|         for (unsigned int i = 0; i < j; ++i) { |             s << coerceToString(v, context, false, !isPath); | ||||||
|             strcpy(t, vs[i].string.s); |  | ||||||
|             t += strlen(vs[i].string.s); |  | ||||||
|         } |         } | ||||||
|         *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; |         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) | Expr autoCallFunction(Expr e, const ATermMap & args) | ||||||
| { | { | ||||||
|     Pattern pat; |     Pattern pat; | ||||||
|  | @ -1515,16 +1419,16 @@ Expr strictEvalExpr(EvalState & state, Expr e) | ||||||
| #endif | #endif | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
| void printEvalStats(EvalState & state) | void EvalState::printStats() | ||||||
| { | { | ||||||
|     char x; |     char x; | ||||||
|     bool showStats = getEnv("NIX_SHOW_STATS", "0") != "0"; |     bool showStats = getEnv("NIX_SHOW_STATS", "0") != "0"; | ||||||
|     printMsg(showStats ? lvlInfo : lvlDebug, |     printMsg(showStats ? lvlInfo : lvlDebug, | ||||||
|         format("evaluated %1% expressions, used %2% bytes of stack space, allocated %3% values, allocated %4% environments") |         format("evaluated %1% expressions, used %2% bytes of stack space, allocated %3% values, allocated %4% environments") | ||||||
|         % state.nrEvaluated |         % nrEvaluated | ||||||
|         % (&x - deepestStack) |         % (&x - deepestStack) | ||||||
|         % state.nrValues |         % nrValues | ||||||
|         % state.nrEnvs); |         % nrEnvs); | ||||||
|     if (showStats) |     if (showStats) | ||||||
|         printATermMapStats(); |         printATermMapStats(); | ||||||
| } | } | ||||||
|  |  | ||||||
|  | @ -132,7 +132,7 @@ struct EvalState; | ||||||
| std::ostream & operator << (std::ostream & str, Value & v); | std::ostream & operator << (std::ostream & str, Value & v); | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
| struct EvalState  | class EvalState  | ||||||
| { | { | ||||||
|     DrvRoots drvRoots; |     DrvRoots drvRoots; | ||||||
|     DrvHashes drvHashes; /* normalised derivation hashes */ |     DrvHashes drvHashes; /* normalised derivation hashes */ | ||||||
|  | @ -144,6 +144,8 @@ struct EvalState | ||||||
| 
 | 
 | ||||||
|     bool allowUnsafeEquality; |     bool allowUnsafeEquality; | ||||||
| 
 | 
 | ||||||
|  | public: | ||||||
|  |      | ||||||
|     EvalState(); |     EvalState(); | ||||||
| 
 | 
 | ||||||
|     /* Evaluate an expression read from the given file to normal
 |     /* Evaluate an expression read from the given file to normal
 | ||||||
|  | @ -214,6 +216,9 @@ public: | ||||||
|     Env & allocEnv(); |     Env & allocEnv(); | ||||||
| 
 | 
 | ||||||
|     void mkList(Value & v, unsigned int length); |     void mkList(Value & v, unsigned int length); | ||||||
|  | 
 | ||||||
|  |     /* Print statistics. */ | ||||||
|  |     void printStats(); | ||||||
| }; | }; | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
|  | @ -244,9 +249,6 @@ ATermList flattenList(EvalState & state, Expr e); | ||||||
| Expr autoCallFunction(Expr e, const ATermMap & args); | Expr autoCallFunction(Expr e, const ATermMap & args); | ||||||
| #endif | #endif | ||||||
| 
 | 
 | ||||||
| /* Print statistics. */ |  | ||||||
| void printEvalStats(EvalState & state); |  | ||||||
| 
 |  | ||||||
| 
 | 
 | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
|  | @ -47,14 +47,14 @@ static void prim_import(EvalState & state, Value * * args, Value & v) | ||||||
| 
 | 
 | ||||||
| #if 0 | #if 0 | ||||||
| /* Determine whether the argument is the null value. */ | /* Determine whether the argument is the null value. */ | ||||||
| static Expr prim_isNull(EvalState & state, const ATermVector & args) | static void prim_isNull(EvalState & state, Value * * args, Value & v) | ||||||
| { | { | ||||||
|     return makeBool(matchNull(evalExpr(state, args[0]))); |     return makeBool(matchNull(evalExpr(state, args[0]))); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
| /* Determine whether the argument is a function. */ | /* Determine whether the argument is a function. */ | ||||||
| static Expr prim_isFunction(EvalState & state, const ATermVector & args) | static void prim_isFunction(EvalState & state, Value * * args, Value & v) | ||||||
| { | { | ||||||
|     Expr e = evalExpr(state, args[0]); |     Expr e = evalExpr(state, args[0]); | ||||||
|     Pattern pat; |     Pattern pat; | ||||||
|  | @ -63,14 +63,14 @@ static Expr prim_isFunction(EvalState & state, const ATermVector & args) | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| /* Determine whether the argument is an Int. */ | /* Determine whether the argument is an Int. */ | ||||||
| static Expr prim_isInt(EvalState & state, const ATermVector & args) | static void prim_isInt(EvalState & state, Value * * args, Value & v) | ||||||
| { | { | ||||||
|     int i; |     int i; | ||||||
|     return makeBool(matchInt(evalExpr(state, args[0]), i)); |     return makeBool(matchInt(evalExpr(state, args[0]), i)); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| /* Determine whether the argument is an String. */ | /* Determine whether the argument is an String. */ | ||||||
| static Expr prim_isString(EvalState & state, const ATermVector & args) | static void prim_isString(EvalState & state, Value * * args, Value & v) | ||||||
| { | { | ||||||
|     string s; |     string s; | ||||||
|     PathSet l; |     PathSet l; | ||||||
|  | @ -78,13 +78,13 @@ static Expr prim_isString(EvalState & state, const ATermVector & args) | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| /* Determine whether the argument is an Bool. */ | /* Determine whether the argument is an Bool. */ | ||||||
| static Expr prim_isBool(EvalState & state, const ATermVector & args) | static void prim_isBool(EvalState & state, Value * * args, Value & v) | ||||||
| { | { | ||||||
|     ATermBool b; |     ATermBool b; | ||||||
|     return makeBool(matchBool(evalExpr(state, args[0]), b)); |     return makeBool(matchBool(evalExpr(state, args[0]), b)); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| static Expr prim_genericClosure(EvalState & state, const ATermVector & args) | static void prim_genericClosure(EvalState & state, Value * * args, Value & v) | ||||||
| { | { | ||||||
|     startNest(nest, lvlDebug, "finding dependencies"); |     startNest(nest, lvlDebug, "finding dependencies"); | ||||||
| 
 | 
 | ||||||
|  | @ -132,7 +132,7 @@ static Expr prim_genericClosure(EvalState & state, const ATermVector & args) | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
| static Expr prim_abort(EvalState & state, const ATermVector & args) | static void prim_abort(EvalState & state, Value * * args, Value & v) | ||||||
| { | { | ||||||
|     PathSet context; |     PathSet context; | ||||||
|     throw Abort(format("evaluation aborted with the following error message: `%1%'") % |     throw Abort(format("evaluation aborted with the following error message: `%1%'") % | ||||||
|  | @ -140,7 +140,7 @@ static Expr prim_abort(EvalState & state, const ATermVector & args) | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
| static Expr prim_throw(EvalState & state, const ATermVector & args) | static void prim_throw(EvalState & state, Value * * args, Value & v) | ||||||
| { | { | ||||||
|     PathSet context; |     PathSet context; | ||||||
|     throw ThrownError(format("user-thrown exception: %1%") % |     throw ThrownError(format("user-thrown exception: %1%") % | ||||||
|  | @ -148,7 +148,7 @@ static Expr prim_throw(EvalState & state, const ATermVector & args) | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
| static Expr prim_addErrorContext(EvalState & state, const ATermVector & args) | static void prim_addErrorContext(EvalState & state, Value * * args, Value & v) | ||||||
| { | { | ||||||
|     PathSet context; |     PathSet context; | ||||||
|     try { |     try { | ||||||
|  | @ -162,7 +162,7 @@ static Expr prim_addErrorContext(EvalState & state, const ATermVector & args) | ||||||
| 
 | 
 | ||||||
| /* Try evaluating the argument. Success => {success=true; value=something;}, 
 | /* Try evaluating the argument. Success => {success=true; value=something;}, 
 | ||||||
|  * else => {success=false; value=false;} */ |  * else => {success=false; value=false;} */ | ||||||
| static Expr prim_tryEval(EvalState & state, const ATermVector & args) | static void prim_tryEval(EvalState & state, Value * * args, Value & v) | ||||||
| { | { | ||||||
|     ATermMap res = ATermMap(); |     ATermMap res = ATermMap(); | ||||||
|     try { |     try { | ||||||
|  | @ -179,7 +179,7 @@ static Expr prim_tryEval(EvalState & state, const ATermVector & args) | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
| /* Return an environment variable.  Use with care. */ | /* Return an environment variable.  Use with care. */ | ||||||
| static Expr prim_getEnv(EvalState & state, const ATermVector & args) | static void prim_getEnv(EvalState & state, Value * * args, Value & v) | ||||||
| { | { | ||||||
|     string name = evalStringNoCtx(state, args[0]); |     string name = evalStringNoCtx(state, args[0]); | ||||||
|     return makeStr(getEnv(name)); |     return makeStr(getEnv(name)); | ||||||
|  | @ -190,7 +190,7 @@ static Expr prim_getEnv(EvalState & state, const ATermVector & args) | ||||||
|    on standard error.  Then return the second expression.  Useful for |    on standard error.  Then return the second expression.  Useful for | ||||||
|    debugging. |    debugging. | ||||||
|  */ |  */ | ||||||
| static Expr prim_trace(EvalState & state, const ATermVector & args) | static void prim_trace(EvalState & state, Value * * args, Value & v) | ||||||
| { | { | ||||||
|     Expr e = evalExpr(state, args[0]); |     Expr e = evalExpr(state, args[0]); | ||||||
|     string s; |     string s; | ||||||
|  | @ -272,7 +272,7 @@ static Hash hashDerivationModulo(EvalState & state, Derivation drv) | ||||||
|    derivation; `drvPath' containing the path of the Nix expression; |    derivation; `drvPath' containing the path of the Nix expression; | ||||||
|    and `type' set to `derivation' to indicate that this is a |    and `type' set to `derivation' to indicate that this is a | ||||||
|    derivation. */ |    derivation. */ | ||||||
| static Expr prim_derivationStrict(EvalState & state, const ATermVector & args) | static void prim_derivationStrict(EvalState & state, Value * * args, Value & v) | ||||||
| { | { | ||||||
|     startNest(nest, lvlVomit, "evaluating derivation"); |     startNest(nest, lvlVomit, "evaluating derivation"); | ||||||
| 
 | 
 | ||||||
|  | @ -470,7 +470,7 @@ static Expr prim_derivationStrict(EvalState & state, const ATermVector & args) | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
| static Expr prim_derivationLazy(EvalState & state, const ATermVector & args) | static void prim_derivationLazy(EvalState & state, Value * * args, Value & v) | ||||||
| { | { | ||||||
|     Expr eAttrs = evalExpr(state, args[0]); |     Expr eAttrs = evalExpr(state, args[0]); | ||||||
|     ATermMap attrs;     |     ATermMap attrs;     | ||||||
|  | @ -496,7 +496,7 @@ static Expr prim_derivationLazy(EvalState & state, const ATermVector & args) | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
| /* Convert the argument to a path.  !!! obsolete? */ | /* Convert the argument to a path.  !!! obsolete? */ | ||||||
| static Expr prim_toPath(EvalState & state, const ATermVector & args) | static void prim_toPath(EvalState & state, Value * * args, Value & v) | ||||||
| { | { | ||||||
|     PathSet context; |     PathSet context; | ||||||
|     string path = coerceToPath(state, args[0], context); |     string path = coerceToPath(state, args[0], context); | ||||||
|  | @ -512,7 +512,7 @@ static Expr prim_toPath(EvalState & state, const ATermVector & args) | ||||||
|    /nix/store/newhash-oldhash-oldname.  In the past, `toPath' had |    /nix/store/newhash-oldhash-oldname.  In the past, `toPath' had | ||||||
|    special case behaviour for store paths, but that created weird |    special case behaviour for store paths, but that created weird | ||||||
|    corner cases. */ |    corner cases. */ | ||||||
| static Expr prim_storePath(EvalState & state, const ATermVector & args) | static void prim_storePath(EvalState & state, Value * * args, Value & v) | ||||||
| { | { | ||||||
|     PathSet context; |     PathSet context; | ||||||
|     Path path = canonPath(coerceToPath(state, args[0], context)); |     Path path = canonPath(coerceToPath(state, args[0], context)); | ||||||
|  | @ -526,7 +526,7 @@ static Expr prim_storePath(EvalState & state, const ATermVector & args) | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
| static Expr prim_pathExists(EvalState & state, const ATermVector & args) | static void prim_pathExists(EvalState & state, Value * * args, Value & v) | ||||||
| { | { | ||||||
|     PathSet context; |     PathSet context; | ||||||
|     Path path = coerceToPath(state, args[0], context); |     Path path = coerceToPath(state, args[0], context); | ||||||
|  | @ -538,7 +538,7 @@ static Expr prim_pathExists(EvalState & state, const ATermVector & args) | ||||||
| 
 | 
 | ||||||
| /* Return the base name of the given string, i.e., everything
 | /* Return the base name of the given string, i.e., everything
 | ||||||
|    following the last slash. */ |    following the last slash. */ | ||||||
| static Expr prim_baseNameOf(EvalState & state, const ATermVector & args) | static void prim_baseNameOf(EvalState & state, Value * * args, Value & v) | ||||||
| { | { | ||||||
|     PathSet context; |     PathSet context; | ||||||
|     return makeStr(baseNameOf(coerceToString(state, args[0], context)), context); |     return makeStr(baseNameOf(coerceToString(state, args[0], context)), context); | ||||||
|  | @ -548,7 +548,7 @@ static Expr prim_baseNameOf(EvalState & state, const ATermVector & args) | ||||||
| /* Return the directory of the given path, i.e., everything before the
 | /* Return the directory of the given path, i.e., everything before the
 | ||||||
|    last slash.  Return either a path or a string depending on the type |    last slash.  Return either a path or a string depending on the type | ||||||
|    of the argument. */ |    of the argument. */ | ||||||
| static Expr prim_dirOf(EvalState & state, const ATermVector & args) | static void prim_dirOf(EvalState & state, Value * * args, Value & v) | ||||||
| { | { | ||||||
|     PathSet context; |     PathSet context; | ||||||
|     Expr e = evalExpr(state, args[0]); ATerm dummy; |     Expr e = evalExpr(state, args[0]); ATerm dummy; | ||||||
|  | @ -559,7 +559,7 @@ static Expr prim_dirOf(EvalState & state, const ATermVector & args) | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
| /* Return the contents of a file as a string. */ | /* Return the contents of a file as a string. */ | ||||||
| static Expr prim_readFile(EvalState & state, const ATermVector & args) | static void prim_readFile(EvalState & state, Value * * args, Value & v) | ||||||
| { | { | ||||||
|     PathSet context; |     PathSet context; | ||||||
|     Path path = coerceToPath(state, args[0], context); |     Path path = coerceToPath(state, args[0], context); | ||||||
|  | @ -577,7 +577,7 @@ static Expr prim_readFile(EvalState & state, const ATermVector & args) | ||||||
| /* Convert the argument (which can be any Nix expression) to an XML
 | /* Convert the argument (which can be any Nix expression) to an XML
 | ||||||
|    representation returned in a string.  Not all Nix expressions can |    representation returned in a string.  Not all Nix expressions can | ||||||
|    be sensibly or completely represented (e.g., functions). */ |    be sensibly or completely represented (e.g., functions). */ | ||||||
| static Expr prim_toXML(EvalState & state, const ATermVector & args) | static void prim_toXML(EvalState & state, Value * * args, Value & v) | ||||||
| { | { | ||||||
|     std::ostringstream out; |     std::ostringstream out; | ||||||
|     PathSet context; |     PathSet context; | ||||||
|  | @ -588,7 +588,7 @@ static Expr prim_toXML(EvalState & state, const ATermVector & args) | ||||||
| 
 | 
 | ||||||
| /* Store a string in the Nix store as a source file that can be used
 | /* Store a string in the Nix store as a source file that can be used
 | ||||||
|    as an input by derivations. */ |    as an input by derivations. */ | ||||||
| static Expr prim_toFile(EvalState & state, const ATermVector & args) | static void prim_toFile(EvalState & state, Value * * args, Value & v) | ||||||
| { | { | ||||||
|     PathSet context; |     PathSet context; | ||||||
|     string name = evalStringNoCtx(state, args[0]); |     string name = evalStringNoCtx(state, args[0]); | ||||||
|  | @ -647,7 +647,7 @@ struct FilterFromExpr : PathFilter | ||||||
| }; | }; | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
| static Expr prim_filterSource(EvalState & state, const ATermVector & args) | static void prim_filterSource(EvalState & state, Value * * args, Value & v) | ||||||
| { | { | ||||||
|     PathSet context; |     PathSet context; | ||||||
|     Path path = coerceToPath(state, args[1], context); |     Path path = coerceToPath(state, args[1], context); | ||||||
|  | @ -671,7 +671,7 @@ static Expr prim_filterSource(EvalState & state, const ATermVector & args) | ||||||
| 
 | 
 | ||||||
| /* Return the names of the attributes in an attribute set as a sorted
 | /* Return the names of the attributes in an attribute set as a sorted
 | ||||||
|    list of strings. */ |    list of strings. */ | ||||||
| static Expr prim_attrNames(EvalState & state, const ATermVector & args) | static void prim_attrNames(EvalState & state, Value * * args, Value & v) | ||||||
| { | { | ||||||
|     ATermMap attrs; |     ATermMap attrs; | ||||||
|     queryAllAttrs(evalExpr(state, args[0]), attrs); |     queryAllAttrs(evalExpr(state, args[0]), attrs); | ||||||
|  | @ -690,7 +690,7 @@ static Expr prim_attrNames(EvalState & state, const ATermVector & args) | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
| /* Dynamic version of the `.' operator. */ | /* Dynamic version of the `.' operator. */ | ||||||
| static Expr prim_getAttr(EvalState & state, const ATermVector & args) | static void prim_getAttr(EvalState & state, Value * * args, Value & v) | ||||||
| { | { | ||||||
|     string attr = evalStringNoCtx(state, args[0]); |     string attr = evalStringNoCtx(state, args[0]); | ||||||
|     return evalExpr(state, makeSelect(args[1], toATerm(attr))); |     return evalExpr(state, makeSelect(args[1], toATerm(attr))); | ||||||
|  | @ -698,7 +698,7 @@ static Expr prim_getAttr(EvalState & state, const ATermVector & args) | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
| /* Dynamic version of the `?' operator. */ | /* Dynamic version of the `?' operator. */ | ||||||
| static Expr prim_hasAttr(EvalState & state, const ATermVector & args) | static void prim_hasAttr(EvalState & state, Value * * args, Value & v) | ||||||
| { | { | ||||||
|     string attr = evalStringNoCtx(state, args[0]); |     string attr = evalStringNoCtx(state, args[0]); | ||||||
|     return evalExpr(state, makeOpHasAttr(args[1], toATerm(attr))); |     return evalExpr(state, makeOpHasAttr(args[1], toATerm(attr))); | ||||||
|  | @ -709,7 +709,7 @@ static Expr prim_hasAttr(EvalState & state, const ATermVector & args) | ||||||
|    pairs.  To be precise, a list [{name = "name1"; value = value1;} |    pairs.  To be precise, a list [{name = "name1"; value = value1;} | ||||||
|    ... {name = "nameN"; value = valueN;}] is transformed to {name1 = |    ... {name = "nameN"; value = valueN;}] is transformed to {name1 = | ||||||
|    value1; ... nameN = valueN;}. */ |    value1; ... nameN = valueN;}. */ | ||||||
| static Expr prim_listToAttrs(EvalState & state, const ATermVector & args) | static void prim_listToAttrs(EvalState & state, Value * * args, Value & v) | ||||||
| { | { | ||||||
|     try { |     try { | ||||||
|         ATermMap res = ATermMap(); |         ATermMap res = ATermMap(); | ||||||
|  | @ -739,7 +739,7 @@ static Expr prim_listToAttrs(EvalState & state, const ATermVector & args) | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
| static Expr prim_removeAttrs(EvalState & state, const ATermVector & args) | static void prim_removeAttrs(EvalState & state, Value * * args, Value & v) | ||||||
| { | { | ||||||
|     ATermMap attrs; |     ATermMap attrs; | ||||||
|     queryAllAttrs(evalExpr(state, args[0]), attrs, true); |     queryAllAttrs(evalExpr(state, args[0]), attrs, true); | ||||||
|  | @ -755,7 +755,7 @@ static Expr prim_removeAttrs(EvalState & state, const ATermVector & args) | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
| /* Determine whether the argument is an attribute set. */ | /* Determine whether the argument is an attribute set. */ | ||||||
| static Expr prim_isAttrs(EvalState & state, const ATermVector & args) | static void prim_isAttrs(EvalState & state, Value * * args, Value & v) | ||||||
| { | { | ||||||
|     ATermList list; |     ATermList list; | ||||||
|     return makeBool(matchAttrs(evalExpr(state, args[0]), list)); |     return makeBool(matchAttrs(evalExpr(state, args[0]), list)); | ||||||
|  | @ -765,7 +765,7 @@ static Expr prim_isAttrs(EvalState & state, const ATermVector & args) | ||||||
| /* Return the right-biased intersection of two attribute sets as1 and
 | /* Return the right-biased intersection of two attribute sets as1 and
 | ||||||
|    as2, i.e. a set that contains every attribute from as2 that is also |    as2, i.e. a set that contains every attribute from as2 that is also | ||||||
|    a member of as1. */ |    a member of as1. */ | ||||||
| static Expr prim_intersectAttrs(EvalState & state, const ATermVector & args) | static void prim_intersectAttrs(EvalState & state, Value * * args, Value & v) | ||||||
| { | { | ||||||
|     ATermMap as1, as2; |     ATermMap as1, as2; | ||||||
|     queryAllAttrs(evalExpr(state, args[0]), as1, true); |     queryAllAttrs(evalExpr(state, args[0]), as1, true); | ||||||
|  | @ -807,7 +807,7 @@ static void attrsInPattern(ATermMap & map, Pattern pat) | ||||||
|       functionArgs (x: ...) |       functionArgs (x: ...) | ||||||
|    => { } |    => { } | ||||||
| */ | */ | ||||||
| static Expr prim_functionArgs(EvalState & state, const ATermVector & args) | static void prim_functionArgs(EvalState & state, Value * * args, Value & v) | ||||||
| { | { | ||||||
|     Expr f = evalExpr(state, args[0]); |     Expr f = evalExpr(state, args[0]); | ||||||
|     ATerm pat, body, pos; |     ATerm pat, body, pos; | ||||||
|  | @ -827,7 +827,7 @@ static Expr prim_functionArgs(EvalState & state, const ATermVector & args) | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
| /* Determine whether the argument is a list. */ | /* Determine whether the argument is a list. */ | ||||||
| static Expr prim_isList(EvalState & state, const ATermVector & args) | static void prim_isList(EvalState & state, Value * * args, Value & v) | ||||||
| { | { | ||||||
|     ATermList list; |     ATermList list; | ||||||
|     return makeBool(matchList(evalExpr(state, args[0]), list)); |     return makeBool(matchList(evalExpr(state, args[0]), list)); | ||||||
|  | @ -877,7 +877,7 @@ static void prim_map(EvalState & state, Value * * args, Value & v) | ||||||
| 
 | 
 | ||||||
| #if 0 | #if 0 | ||||||
| /* Return the length of a list.  This is an O(1) time operation. */ | /* Return the length of a list.  This is an O(1) time operation. */ | ||||||
| static Expr prim_length(EvalState & state, const ATermVector & args) | static void prim_length(EvalState & state, Value * * args, Value & v) | ||||||
| { | { | ||||||
|     ATermList list = evalList(state, args[0]); |     ATermList list = evalList(state, args[0]); | ||||||
|     return makeInt(ATgetLength(list)); |     return makeInt(ATgetLength(list)); | ||||||
|  | @ -897,7 +897,7 @@ static void prim_add(EvalState & state, Value * * args, Value & v) | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
| #if 0 | #if 0 | ||||||
| static Expr prim_sub(EvalState & state, const ATermVector & args) | static void prim_sub(EvalState & state, Value * * args, Value & v) | ||||||
| { | { | ||||||
|     int i1 = evalInt(state, args[0]); |     int i1 = evalInt(state, args[0]); | ||||||
|     int i2 = evalInt(state, args[1]); |     int i2 = evalInt(state, args[1]); | ||||||
|  | @ -905,7 +905,7 @@ static Expr prim_sub(EvalState & state, const ATermVector & args) | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
| static Expr prim_mul(EvalState & state, const ATermVector & args) | static void prim_mul(EvalState & state, Value * * args, Value & v) | ||||||
| { | { | ||||||
|     int i1 = evalInt(state, args[0]); |     int i1 = evalInt(state, args[0]); | ||||||
|     int i2 = evalInt(state, args[1]); |     int i2 = evalInt(state, args[1]); | ||||||
|  | @ -913,20 +913,19 @@ static Expr prim_mul(EvalState & state, const ATermVector & args) | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
| static Expr prim_div(EvalState & state, const ATermVector & args) | static void prim_div(EvalState & state, Value * * args, Value & v) | ||||||
| { | { | ||||||
|     int i1 = evalInt(state, args[0]); |     int i1 = evalInt(state, args[0]); | ||||||
|     int i2 = evalInt(state, args[1]); |     int i2 = evalInt(state, args[1]); | ||||||
|     if (i2 == 0) throw EvalError("division by zero"); |     if (i2 == 0) throw EvalError("division by zero"); | ||||||
|     return makeInt(i1 / i2); |     return makeInt(i1 / i2); | ||||||
| } | } | ||||||
|  | #endif | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
| static Expr prim_lessThan(EvalState & state, const ATermVector & args) | static void prim_lessThan(EvalState & state, Value * * args, Value & v) | ||||||
| { | { | ||||||
|     int i1 = evalInt(state, args[0]); |     mkBool(v, state.forceInt(*args[0]) < state.forceInt(*args[1])); | ||||||
|     int i2 = evalInt(state, args[1]); |  | ||||||
|     return makeBool(i1 < i2); |  | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
|  | @ -938,19 +937,20 @@ static Expr prim_lessThan(EvalState & state, const ATermVector & args) | ||||||
| /* Convert the argument to a string.  Paths are *not* copied to the
 | /* Convert the argument to a string.  Paths are *not* copied to the
 | ||||||
|    store, so `toString /foo/bar' yields `"/foo/bar"', not |    store, so `toString /foo/bar' yields `"/foo/bar"', not | ||||||
|    `"/nix/store/whatever..."'. */ |    `"/nix/store/whatever..."'. */ | ||||||
| static Expr prim_toString(EvalState & state, const ATermVector & args) | static void prim_toString(EvalState & state, Value * * args, Value & v) | ||||||
| { | { | ||||||
|     PathSet context; |     PathSet context; | ||||||
|     string s = coerceToString(state, args[0], context, true, false); |     string s = state.coerceToString(*args[0], context, true, false); | ||||||
|     return makeStr(s, context); |     mkString(v, strdup(s.c_str())); // !!! context
 | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
|  | #if 0 | ||||||
| /* `substring start len str' returns the substring of `str' starting
 | /* `substring start len str' returns the substring of `str' starting
 | ||||||
|    at character position `min(start, stringLength str)' inclusive and |    at character position `min(start, stringLength str)' inclusive and | ||||||
|    ending at `min(start + len, stringLength str)'.  `start' must be |    ending at `min(start + len, stringLength str)'.  `start' must be | ||||||
|    non-negative. */ |    non-negative. */ | ||||||
| static Expr prim_substring(EvalState & state, const ATermVector & args) | static void prim_substring(EvalState & state, Value * * args, Value & v) | ||||||
| { | { | ||||||
|     int start = evalInt(state, args[0]); |     int start = evalInt(state, args[0]); | ||||||
|     int len = evalInt(state, args[1]); |     int len = evalInt(state, args[1]); | ||||||
|  | @ -963,7 +963,7 @@ static Expr prim_substring(EvalState & state, const ATermVector & args) | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
| static Expr prim_stringLength(EvalState & state, const ATermVector & args) | static void prim_stringLength(EvalState & state, Value * * args, Value & v) | ||||||
| { | { | ||||||
|     PathSet context; |     PathSet context; | ||||||
|     string s = coerceToString(state, args[0], context); |     string s = coerceToString(state, args[0], context); | ||||||
|  | @ -971,7 +971,7 @@ static Expr prim_stringLength(EvalState & state, const ATermVector & args) | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
| static Expr prim_unsafeDiscardStringContext(EvalState & state, const ATermVector & args) | static void prim_unsafeDiscardStringContext(EvalState & state, Value * * args, Value & v) | ||||||
| { | { | ||||||
|     PathSet context; |     PathSet context; | ||||||
|     string s = coerceToString(state, args[0], context); |     string s = coerceToString(state, args[0], context); | ||||||
|  | @ -985,7 +985,7 @@ static Expr prim_unsafeDiscardStringContext(EvalState & state, const ATermVector | ||||||
|    source-only deployment).  This primop marks the string context so |    source-only deployment).  This primop marks the string context so | ||||||
|    that builtins.derivation adds the path to drv.inputSrcs rather than |    that builtins.derivation adds the path to drv.inputSrcs rather than | ||||||
|    drv.inputDrvs. */ |    drv.inputDrvs. */ | ||||||
| static Expr prim_unsafeDiscardOutputDependency(EvalState & state, const ATermVector & args) | static void prim_unsafeDiscardOutputDependency(EvalState & state, Value * * args, Value & v) | ||||||
| { | { | ||||||
|     PathSet context; |     PathSet context; | ||||||
|     string s = coerceToString(state, args[0], context); |     string s = coerceToString(state, args[0], context); | ||||||
|  | @ -1004,14 +1004,14 @@ static Expr prim_unsafeDiscardOutputDependency(EvalState & state, const ATermVec | ||||||
| /* Expression serialization/deserialization */ | /* Expression serialization/deserialization */ | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
| static Expr prim_exprToString(EvalState & state, const ATermVector & args) | static void prim_exprToString(EvalState & state, Value * * args, Value & v) | ||||||
| { | { | ||||||
|     /* !!! this disregards context */ |     /* !!! this disregards context */ | ||||||
|     return makeStr(atPrint(evalExpr(state, args[0]))); |     return makeStr(atPrint(evalExpr(state, args[0]))); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
| static Expr prim_stringToExpr(EvalState & state, const ATermVector & args) | static void prim_stringToExpr(EvalState & state, Value * * args, Value & v) | ||||||
| { | { | ||||||
|     /* !!! this can introduce arbitrary garbage terms in the
 |     /* !!! this can introduce arbitrary garbage terms in the
 | ||||||
|        evaluator! */; |        evaluator! */; | ||||||
|  | @ -1028,7 +1028,7 @@ static Expr prim_stringToExpr(EvalState & state, const ATermVector & args) | ||||||
|  *************************************************************/ |  *************************************************************/ | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
| static Expr prim_parseDrvName(EvalState & state, const ATermVector & args) | static void prim_parseDrvName(EvalState & state, Value * * args, Value & v) | ||||||
| { | { | ||||||
|     string name = evalStringNoCtx(state, args[0]); |     string name = evalStringNoCtx(state, args[0]); | ||||||
|     DrvName parsed(name); |     DrvName parsed(name); | ||||||
|  | @ -1039,7 +1039,7 @@ static Expr prim_parseDrvName(EvalState & state, const ATermVector & args) | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
| static Expr prim_compareVersions(EvalState & state, const ATermVector & args) | static void prim_compareVersions(EvalState & state, Value * * args, Value & v) | ||||||
| { | { | ||||||
|     string version1 = evalStringNoCtx(state, args[0]); |     string version1 = evalStringNoCtx(state, args[0]); | ||||||
|     string version2 = evalStringNoCtx(state, args[1]); |     string version2 = evalStringNoCtx(state, args[1]); | ||||||
|  | @ -1144,10 +1144,12 @@ void EvalState::createBaseEnv() | ||||||
|     addPrimOp("__sub", 2, prim_sub); |     addPrimOp("__sub", 2, prim_sub); | ||||||
|     addPrimOp("__mul", 2, prim_mul); |     addPrimOp("__mul", 2, prim_mul); | ||||||
|     addPrimOp("__div", 2, prim_div); |     addPrimOp("__div", 2, prim_div); | ||||||
|  | #endif | ||||||
|     addPrimOp("__lessThan", 2, prim_lessThan); |     addPrimOp("__lessThan", 2, prim_lessThan); | ||||||
| 
 | 
 | ||||||
|     // String manipulation
 |     // String manipulation
 | ||||||
|     addPrimOp("toString", 1, prim_toString); |     addPrimOp("toString", 1, prim_toString); | ||||||
|  | #if 0    
 | ||||||
|     addPrimOp("__substring", 3, prim_substring); |     addPrimOp("__substring", 3, prim_substring); | ||||||
|     addPrimOp("__stringLength", 1, prim_stringLength); |     addPrimOp("__stringLength", 1, prim_stringLength); | ||||||
|     addPrimOp("__unsafeDiscardStringContext", 1, prim_unsafeDiscardStringContext); |     addPrimOp("__unsafeDiscardStringContext", 1, prim_unsafeDiscardStringContext); | ||||||
|  |  | ||||||
|  | @ -159,7 +159,7 @@ void run(Strings args) | ||||||
|             evalOnly, xmlOutput, e); |             evalOnly, xmlOutput, e); | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     printEvalStats(state); |     state.printStats(); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue