* 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, "."); | ||||
| 
 | ||||
|  | @ -26,8 +15,10 @@ Expr findAlongAttrPath(EvalState & state, const string & attrPath, | |||
|         Error(format("attribute selection path `%1%' does not match expression") % attrPath); | ||||
| 
 | ||||
|     string curPath; | ||||
| 
 | ||||
|     state.mkThunk_(v, e); | ||||
|      | ||||
|     for (Strings::iterator i = tokens.begin(); i != tokens.end(); ++i) { | ||||
|     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)); | ||||
|                  | ||||
|             e = attrs.get(toATerm(attr)); | ||||
|             if (!e) | ||||
|                 throw Error(format("attribute `%1%' in selection path `%2%' not found") % attr % curPath); | ||||
|                     % curPath % showType(v)); | ||||
| 
 | ||||
|             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; | ||||
| 
 | ||||
|  | @ -19,11 +19,13 @@ bool parseOptionArg(const string & arg, Strings::iterator & i, | |||
|     string name = *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,13 +226,18 @@ 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); | ||||
| 
 | ||||
|     /* Print statistics. */ | ||||
|  | @ -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); | ||||
| 
 | ||||
|   | ||||
| } | ||||
|  |  | |||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue