* Update autoCallFunction() and findAlongAttrPath().
This commit is contained in:
		
							parent
							
								
									9a64454faa
								
							
						
					
					
						commit
						af2a372bb0
					
				
					 10 changed files with 120 additions and 188 deletions
				
			
		|  | @ -6,19 +6,8 @@ | |||
| namespace nix { | ||||
| 
 | ||||
| 
 | ||||
| #if 0 | ||||
| bool isAttrs(EvalState & state, Expr e, ATermMap & attrs) | ||||
| { | ||||
|     e = evalExpr(state, e); | ||||
|     ATermList dummy; | ||||
|     if (!matchAttrs(e, dummy)) return false; | ||||
|     queryAllAttrs(e, attrs, false); | ||||
|     return true; | ||||
| } | ||||
| 
 | ||||
| 
 | ||||
| Expr findAlongAttrPath(EvalState & state, const string & attrPath, | ||||
|     const ATermMap & autoArgs, Expr e) | ||||
| void findAlongAttrPath(EvalState & state, const string & attrPath, | ||||
|     const Bindings & autoArgs, Expr e, Value & v) | ||||
| { | ||||
|     Strings tokens = tokenizeString(attrPath, "."); | ||||
| 
 | ||||
|  | @ -27,7 +16,9 @@ Expr findAlongAttrPath(EvalState & state, const string & attrPath, | |||
| 
 | ||||
|     string curPath; | ||||
| 
 | ||||
|     for (Strings::iterator i = tokens.begin(); i != tokens.end(); ++i) { | ||||
|     state.mkThunk_(v, e); | ||||
|      | ||||
|     foreach (Strings::iterator, i, tokens) { | ||||
| 
 | ||||
|         if (!curPath.empty()) curPath += "."; | ||||
|         curPath += *i; | ||||
|  | @ -39,7 +30,10 @@ Expr findAlongAttrPath(EvalState & state, const string & attrPath, | |||
|         if (string2Int(attr, attrIndex)) apType = apIndex; | ||||
| 
 | ||||
|         /* Evaluate the expression. */ | ||||
|         e = evalExpr(state, autoCallFunction(evalExpr(state, e), autoArgs)); | ||||
|         Value vTmp; | ||||
|         state.autoCallFunction(autoArgs, v, vTmp); | ||||
|         v = vTmp; | ||||
|         state.forceValue(v); | ||||
| 
 | ||||
|         /* It should evaluate to either an attribute set or an
 | ||||
|            expression, according to what is specified in the | ||||
|  | @ -47,38 +41,32 @@ Expr findAlongAttrPath(EvalState & state, const string & attrPath, | |||
| 
 | ||||
|         if (apType == apAttr) { | ||||
| 
 | ||||
|             ATermMap attrs; | ||||
| 
 | ||||
|             if (!isAttrs(state, e, attrs)) | ||||
|             if (v.type != tAttrs) | ||||
|                 throw TypeError( | ||||
|                     format("the expression selected by the selection path `%1%' should be an attribute set but is %2%") | ||||
|                     % curPath % showType(e)); | ||||
|                     % curPath % showType(v)); | ||||
| 
 | ||||
|             e = attrs.get(toATerm(attr)); | ||||
|             if (!e) | ||||
|             Bindings::iterator a = v.attrs->find(toATerm(attr)); | ||||
|             if (a == v.attrs->end()) | ||||
|                 throw Error(format("attribute `%1%' in selection path `%2%' not found") % attr % curPath); | ||||
| 
 | ||||
|             v = a->second; | ||||
|         } | ||||
| 
 | ||||
|         else if (apType == apIndex) { | ||||
| 
 | ||||
|             ATermList es; | ||||
|             if (!matchList(e, es)) | ||||
|             if (v.type != tList) | ||||
|                 throw TypeError( | ||||
|                     format("the expression selected by the selection path `%1%' should be a list but is %2%") | ||||
|                     % curPath % showType(e)); | ||||
|                     % curPath % showType(v)); | ||||
| 
 | ||||
|             e = ATelementAt(es, attrIndex); | ||||
|             if (!e) | ||||
|                 throw Error(format("list index %1% in selection path `%2%' not found") % attrIndex % curPath); | ||||
|             if (attrIndex >= v.list.length) | ||||
|                 throw Error(format("list index %1% in selection path `%2%' is out of range") % attrIndex % curPath); | ||||
| 
 | ||||
|             v = v.list.elems[attrIndex]; | ||||
|         } | ||||
|          | ||||
|     } | ||||
|      | ||||
|     return e; | ||||
| } | ||||
| #endif | ||||
| 
 | ||||
|   | ||||
| } | ||||
|  |  | |||
|  | @ -10,8 +10,8 @@ | |||
| namespace nix { | ||||
| 
 | ||||
|      | ||||
| Expr findAlongAttrPath(EvalState & state, const string & attrPath, | ||||
|     const ATermMap & autoArgs, Expr e); | ||||
| void findAlongAttrPath(EvalState & state, const string & attrPath, | ||||
|     const Bindings & autoArgs, Expr e, Value & v); | ||||
| 
 | ||||
|      | ||||
| } | ||||
|  |  | |||
|  | @ -9,7 +9,7 @@ namespace nix { | |||
| 
 | ||||
| bool parseOptionArg(const string & arg, Strings::iterator & i, | ||||
|     const Strings::iterator & argsEnd, EvalState & state, | ||||
|     ATermMap & autoArgs) | ||||
|     Bindings & autoArgs) | ||||
| { | ||||
|     if (arg != "--arg" && arg != "--argstr") return false; | ||||
| 
 | ||||
|  | @ -20,10 +20,12 @@ bool parseOptionArg(const string & arg, Strings::iterator & i, | |||
|     if (i == argsEnd) throw error; | ||||
|     string value = *i++; | ||||
| 
 | ||||
|     Expr e = arg == "--arg" | ||||
|         ? parseExprFromString(state, value, absPath(".")) | ||||
|         : makeStr(value); | ||||
|     autoArgs.set(toATerm(name), e); | ||||
|     Value & v(autoArgs[toATerm(name)]); | ||||
| 
 | ||||
|     if (arg == "--arg") | ||||
|         state.mkThunk_(v, parseExprFromString(state, value, absPath("."))); | ||||
|     else | ||||
|         mkString(v, value); | ||||
|      | ||||
|     return true; | ||||
| } | ||||
|  |  | |||
|  | @ -9,7 +9,7 @@ namespace nix { | |||
| /* Some common option parsing between nix-env and nix-instantiate. */ | ||||
| bool parseOptionArg(const string & arg, Strings::iterator & i, | ||||
|     const Strings::iterator & argsEnd, EvalState & state, | ||||
|     ATermMap & autoArgs); | ||||
|     Bindings & autoArgs); | ||||
|      | ||||
| } | ||||
| 
 | ||||
|  |  | |||
|  | @ -260,6 +260,12 @@ void EvalState::mkAttrs(Value & v) | |||
| } | ||||
| 
 | ||||
| 
 | ||||
| void EvalState::mkThunk_(Value & v, Expr expr) | ||||
| { | ||||
|     mkThunk(v, baseEnv, expr); | ||||
| } | ||||
| 
 | ||||
| 
 | ||||
| void EvalState::cloneAttrs(Value & src, Value & dst) | ||||
| { | ||||
|     mkAttrs(dst); | ||||
|  | @ -625,6 +631,37 @@ void EvalState::callFunction(Value & fun, Value & arg, Value & v) | |||
| } | ||||
| 
 | ||||
| 
 | ||||
| void EvalState::autoCallFunction(const Bindings & args, Value & fun, Value & res) | ||||
| { | ||||
|     forceValue(fun); | ||||
| 
 | ||||
|     ATerm name; | ||||
|     ATermList formals; | ||||
|     ATermBool ellipsis; | ||||
|      | ||||
|     if (fun.type != tLambda || !matchAttrsPat(fun.lambda.pat, formals, ellipsis, name)) { | ||||
|         res = fun; | ||||
|         return; | ||||
|     } | ||||
| 
 | ||||
|     Value actualArgs; | ||||
|     mkAttrs(actualArgs); | ||||
|      | ||||
|     for (ATermIterator i(formals); i; ++i) { | ||||
|         Expr name, def; ATerm def2; | ||||
|         if (!matchFormal(*i, name, def2)) abort(); | ||||
|         Bindings::const_iterator j = args.find(name); | ||||
|         if (j != args.end()) | ||||
|             (*actualArgs.attrs)[name] = j->second; | ||||
|         else if (!matchDefaultValue(def2, def)) | ||||
|             throw TypeError(format("cannot auto-call a function that has an argument without a default value (`%1%      ')") | ||||
|                 % aterm2String(name)); | ||||
|     } | ||||
| 
 | ||||
|     callFunction(fun, actualArgs, res); | ||||
| } | ||||
| 
 | ||||
| 
 | ||||
| void EvalState::eval(Expr e, Value & v) | ||||
| { | ||||
|     eval(baseEnv, e, v); | ||||
|  | @ -1058,33 +1095,6 @@ ATermList flattenList(EvalState & state, Expr e) | |||
| } | ||||
| 
 | ||||
| 
 | ||||
| Expr autoCallFunction(Expr e, const ATermMap & args) | ||||
| { | ||||
|     Pattern pat; | ||||
|     ATerm body, pos, name; | ||||
|     ATermList formals; | ||||
|     ATermBool ellipsis; | ||||
|      | ||||
|     if (matchFunction(e, pat, body, pos) && matchAttrsPat(pat, formals, ellipsis, name)) { | ||||
|         ATermMap actualArgs(ATgetLength(formals)); | ||||
|          | ||||
|         for (ATermIterator i(formals); i; ++i) { | ||||
|             Expr name, def, value; ATerm def2; | ||||
|             if (!matchFormal(*i, name, def2)) abort(); | ||||
|             if ((value = args.get(name))) | ||||
|                 actualArgs.set(name, makeAttrRHS(value, makeNoPos())); | ||||
|             else if (!matchDefaultValue(def2, def)) | ||||
|                 throw TypeError(format("cannot auto-call a function that has an argument without a default value (`%1%')") | ||||
|                     % aterm2String(name)); | ||||
|         } | ||||
|          | ||||
|         e = makeCall(e, makeAttrs(actualArgs)); | ||||
|     } | ||||
|      | ||||
|     return e; | ||||
| } | ||||
| 
 | ||||
| 
 | ||||
| /* Evaluation of various language constructs.  These have been taken
 | ||||
|    out of evalExpr2 to reduce stack space usage.  (GCC is really dumb | ||||
|    about stack space: it just adds up all the local variables and | ||||
|  |  | |||
|  | @ -226,12 +226,17 @@ public: | |||
|      | ||||
|     void callFunction(Value & fun, Value & arg, Value & v); | ||||
| 
 | ||||
|     /* Automatically call a function for which each argument has a
 | ||||
|        default value or has a binding in the `args' map. */ | ||||
|     void autoCallFunction(const Bindings & args, Value & fun, Value & res); | ||||
|      | ||||
|     /* Allocation primitives. */ | ||||
|     Value * allocValues(unsigned int count); | ||||
|     Env & allocEnv(); | ||||
| 
 | ||||
|     void mkList(Value & v, unsigned int length); | ||||
|     void mkAttrs(Value & v); | ||||
|     void mkThunk_(Value & v, Expr expr); | ||||
|      | ||||
|     void cloneAttrs(Value & src, Value & dst); | ||||
| 
 | ||||
|  | @ -244,33 +249,6 @@ public: | |||
| string showType(Value & v); | ||||
| 
 | ||||
| 
 | ||||
| #if 0 | ||||
| /* Evaluate an expression to normal form. */ | ||||
| Expr evalExpr(EvalState & state, Expr e); | ||||
| 
 | ||||
| /* Evaluate an expression, and recursively evaluate list elements and
 | ||||
|    attributes.  If `canonicalise' is true, we remove things like | ||||
|    position information and make sure that attribute sets are in | ||||
|    sorded order. */ | ||||
| Expr strictEvalExpr(EvalState & state, Expr e); | ||||
| 
 | ||||
| /* Specific results. */ | ||||
| string evalString(EvalState & state, Expr e, PathSet & context); | ||||
| int evalInt(EvalState & state, Expr e); | ||||
| bool evalBool(EvalState & state, Expr e); | ||||
| ATermList evalList(EvalState & state, Expr e); | ||||
| 
 | ||||
| /* Flatten nested lists into a single list (or expand a singleton into
 | ||||
|    a list). */ | ||||
| ATermList flattenList(EvalState & state, Expr e); | ||||
| 
 | ||||
| /* Automatically call a function for which each argument has a default
 | ||||
|    value or has a binding in the `args' map.  Note: result is a call, | ||||
|    not a normal form; it should be evaluated by calling evalExpr(). */ | ||||
| Expr autoCallFunction(Expr e, const ATermMap & args); | ||||
| #endif | ||||
| 
 | ||||
| 
 | ||||
| } | ||||
| 
 | ||||
| 
 | ||||
|  |  | |||
|  | @ -155,11 +155,12 @@ static string addToPath(const string & s1, const string & s2) | |||
| } | ||||
| 
 | ||||
| 
 | ||||
| static void getDerivations(EvalState & state, Value & v, | ||||
|     const string & pathPrefix, const ATermMap & autoArgs, | ||||
| static void getDerivations(EvalState & state, Value & vIn, | ||||
|     const string & pathPrefix, const Bindings & autoArgs, | ||||
|     DrvInfos & drvs, Done & done) | ||||
| { | ||||
|     // !!! autoCallFunction(evalExpr(state, e), autoArgs)
 | ||||
|     Value v; | ||||
|     state.autoCallFunction(autoArgs, vIn, v); | ||||
|      | ||||
|     /* Process the expression. */ | ||||
|     DrvInfo drv; | ||||
|  | @ -216,7 +217,7 @@ static void getDerivations(EvalState & state, Value & v, | |||
| 
 | ||||
| 
 | ||||
| void getDerivations(EvalState & state, Value & v, const string & pathPrefix, | ||||
|     const ATermMap & autoArgs, DrvInfos & drvs) | ||||
|     const Bindings & autoArgs, DrvInfos & drvs) | ||||
| { | ||||
|     Done done; | ||||
|     getDerivations(state, v, pathPrefix, autoArgs, drvs, done); | ||||
|  |  | |||
|  | @ -65,7 +65,7 @@ typedef list<DrvInfo> DrvInfos; | |||
| bool getDerivation(EvalState & state, Value & v, DrvInfo & drv); | ||||
| 
 | ||||
| void getDerivations(EvalState & state, Value & v, const string & pathPrefix, | ||||
|     const ATermMap & autoArgs, DrvInfos & drvs); | ||||
|     const Bindings & autoArgs, DrvInfos & drvs); | ||||
| 
 | ||||
|   | ||||
| } | ||||
|  |  | |||
|  | @ -47,7 +47,7 @@ struct InstallSourceInfo | |||
|     Path profile; /* for srcProfile */ | ||||
|     string systemFilter; /* for srcNixExprDrvs */ | ||||
|     bool prebuiltOnly; | ||||
|     ATermMap autoArgs; | ||||
|     Bindings autoArgs; | ||||
|     InstallSourceInfo() : prebuiltOnly(false) { }; | ||||
| }; | ||||
| 
 | ||||
|  | @ -161,13 +161,11 @@ static Expr loadSourceExpr(EvalState & state, const Path & path) | |||
| 
 | ||||
| 
 | ||||
| static void loadDerivations(EvalState & state, Path nixExprPath, | ||||
|     string systemFilter, const ATermMap & autoArgs, | ||||
|     string systemFilter, const Bindings & autoArgs, | ||||
|     const string & pathPrefix, DrvInfos & elems) | ||||
| { | ||||
|     Value v; | ||||
|     state.eval(loadSourceExpr(state, nixExprPath), v); | ||||
| 
 | ||||
|     // !!! findAlongAttrPath(state, pathPrefix, autoArgs, loadSourceExpr(state, nixExprPath))
 | ||||
|     findAlongAttrPath(state, pathPrefix, autoArgs, loadSourceExpr(state, nixExprPath), v); | ||||
|      | ||||
|     getDerivations(state, v, pathPrefix, autoArgs, elems); | ||||
| 
 | ||||
|  | @ -579,14 +577,12 @@ static void queryInstSources(EvalState & state, | |||
|         } | ||||
| 
 | ||||
|         case srcAttrPath: { | ||||
|             throw Error("not implemented"); | ||||
| #if 0            
 | ||||
|             foreach (Strings::const_iterator, i, args) | ||||
|                 getDerivations(state, | ||||
|             foreach (Strings::const_iterator, i, args) { | ||||
|                 Value v; | ||||
|                 findAlongAttrPath(state, *i, instSource.autoArgs, | ||||
|                         loadSourceExpr(state, instSource.nixExprPath)), | ||||
|                     "", instSource.autoArgs, elems); | ||||
| #endif | ||||
|                     loadSourceExpr(state, instSource.nixExprPath), v); | ||||
|                 getDerivations(state, v, "", instSource.autoArgs, elems); | ||||
|             } | ||||
|             break; | ||||
|         } | ||||
|     } | ||||
|  |  | |||
|  | @ -37,46 +37,19 @@ static int rootNr = 0; | |||
| static bool indirectRoot = false; | ||||
| 
 | ||||
| 
 | ||||
| #if 0 | ||||
| static void printResult(EvalState & state, Expr e, | ||||
|     bool evalOnly, bool xmlOutput, const ATermMap & autoArgs) | ||||
| { | ||||
|     PathSet context; | ||||
|      | ||||
|     if (evalOnly) | ||||
|         if (xmlOutput) | ||||
|             printTermAsXML(e, std::cout, context); | ||||
|         else | ||||
|             std::cout << format("%1%\n") % canonicaliseExpr(e); | ||||
|      | ||||
|     else { | ||||
|         DrvInfos drvs; | ||||
|         getDerivations(state, e, "", autoArgs, drvs); | ||||
|         for (DrvInfos::iterator i = drvs.begin(); i != drvs.end(); ++i) { | ||||
|             Path drvPath = i->queryDrvPath(state); | ||||
|             if (gcRoot == "") | ||||
|                 printGCWarning(); | ||||
|             else | ||||
|                 drvPath = addPermRoot(drvPath, | ||||
|                     makeRootName(gcRoot, rootNr), | ||||
|                     indirectRoot); | ||||
|             std::cout << format("%1%\n") % drvPath; | ||||
|         } | ||||
|     } | ||||
| } | ||||
| #endif | ||||
| 
 | ||||
| 
 | ||||
| void processExpr(EvalState & state, const Strings & attrPaths, | ||||
|     bool parseOnly, bool strict, const ATermMap & autoArgs, | ||||
|     bool parseOnly, bool strict, const Bindings & autoArgs, | ||||
|     bool evalOnly, bool xmlOutput, Expr e) | ||||
| { | ||||
|     if (parseOnly) | ||||
|         std::cout << format("%1%\n") % canonicaliseExpr(e); | ||||
|     else { | ||||
|     else | ||||
|         foreach (Strings::const_iterator, i, attrPaths) { | ||||
|             Value v; | ||||
|             findAlongAttrPath(state, *i, autoArgs, e, v); | ||||
|             state.forceValue(v); | ||||
| 
 | ||||
|             PathSet context; | ||||
|         state.eval(e, v); | ||||
|             if (evalOnly) | ||||
|                 if (xmlOutput) | ||||
|                     printValueAsXML(state, strict, v, std::cout, context); | ||||
|  | @ -99,18 +72,6 @@ void processExpr(EvalState & state, const Strings & attrPaths, | |||
|                 } | ||||
|             } | ||||
|         } | ||||
|      | ||||
| #if 0 | ||||
|     for (Strings::const_iterator i = attrPaths.begin(); i != attrPaths.end(); ++i) { | ||||
|         Expr e2 = findAlongAttrPath(state, *i, autoArgs, e); | ||||
|         if (!parseOnly) | ||||
|             if (strict) | ||||
|                 e2 = state.strictEval(e2); | ||||
|             else | ||||
|                 e2 = evalExpr(state, e2); | ||||
|         printResult(state, e2, evalOnly, xmlOutput, autoArgs); | ||||
|     } | ||||
| #endif | ||||
| } | ||||
| 
 | ||||
| 
 | ||||
|  | @ -124,11 +85,9 @@ void run(Strings args) | |||
|     bool xmlOutput = false; | ||||
|     bool strict = false; | ||||
|     Strings attrPaths; | ||||
|     ATermMap autoArgs(128); | ||||
|     Bindings autoArgs; | ||||
| 
 | ||||
|     for (Strings::iterator i = args.begin(); | ||||
|          i != args.end(); ) | ||||
|     { | ||||
|     for (Strings::iterator i = args.begin(); i != args.end(); ) { | ||||
|         string arg = *i++; | ||||
| 
 | ||||
|         if (arg == "-") | ||||
|  | @ -175,9 +134,7 @@ void run(Strings args) | |||
|             evalOnly, xmlOutput, e); | ||||
|     } | ||||
| 
 | ||||
|     for (Strings::iterator i = files.begin(); | ||||
|          i != files.end(); i++) | ||||
|     { | ||||
|     foreach (Strings::iterator, i, files) { | ||||
|         Path path = absPath(*i); | ||||
|         Expr e = parseExprFromFile(state, path); | ||||
|         processExpr(state, attrPaths, parseOnly, strict, autoArgs, | ||||
|  |  | |||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue