* Added plain lambdas, e.g., `let { id = x: x; const = x: y: x; }'.
`bla:' is now no longer parsed as a URL.
* Re-enabled support for the `args' attribute in derivations to
  specify command line arguments to the builder, e.g.,
    ...
    builder = /usr/bin/python;
    args = ["-c" ./builder.py];
    ...
			
			
This commit is contained in:
		
							parent
							
								
									f8cd904e05
								
							
						
					
					
						commit
						db3e644c1c
					
				
					 5 changed files with 64 additions and 38 deletions
				
			
		|  | @ -195,6 +195,7 @@ Expr evalExpr2(EvalState & state, Expr e) | ||||||
|          cons == "Int" || |          cons == "Int" || | ||||||
|          cons == "Bool" || |          cons == "Bool" || | ||||||
|          cons == "Function" || |          cons == "Function" || | ||||||
|  |          cons == "Function1" || | ||||||
|          cons == "Attrs" || |          cons == "Attrs" || | ||||||
|          cons == "List")) |          cons == "List")) | ||||||
|         return e; |         return e; | ||||||
|  | @ -226,6 +227,12 @@ Expr evalExpr2(EvalState & state, Expr e) | ||||||
|             return evalExpr(state,  |             return evalExpr(state,  | ||||||
|                 substArgs(e4, formals, evalExpr(state, e2))); |                 substArgs(e4, formals, evalExpr(state, e2))); | ||||||
|          |          | ||||||
|  |         else if (atMatch(m, e1) >> "Function1" >> name >> e4) { | ||||||
|  |             ATermMap subs; | ||||||
|  |             subs.set(name, e2); | ||||||
|  |             return evalExpr(state, substitute(subs, e4)); | ||||||
|  |         } | ||||||
|  |          | ||||||
|         else throw badTerm("expecting a function or primop", e1); |         else throw badTerm("expecting a function or primop", e1); | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
|  | @ -38,7 +38,7 @@ ID          [a-zA-Z\_][a-zA-Z0-9\_\']* | ||||||
| INT         [0-9]+ | INT         [0-9]+ | ||||||
| STR         \"[^\n\"]*\" | STR         \"[^\n\"]*\" | ||||||
| PATH        [a-zA-Z0-9\.\_\-\+]*(\/[a-zA-Z0-9\.\_\-\+]+)+ | PATH        [a-zA-Z0-9\.\_\-\+]*(\/[a-zA-Z0-9\.\_\-\+]+)+ | ||||||
| URI         [a-zA-Z][a-zA-Z0-9\+\-\.]*\:[a-zA-Z0-9\%\/\?\:\@\&\=\+\$\,\-\_\.\!\~\*\']* | URI         [a-zA-Z][a-zA-Z0-9\+\-\.]*\:[a-zA-Z0-9\%\/\?\:\@\&\=\+\$\,\-\_\.\!\~\*\']+ | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
| %% | %% | ||||||
|  |  | ||||||
|  | @ -194,7 +194,15 @@ Expr substitute(const ATermMap & subs, Expr e) | ||||||
|                 abort(); |                 abort(); | ||||||
|             subs2.remove(name); |             subs2.remove(name); | ||||||
|         } |         } | ||||||
|         return ATmake("Function(<term>, <term>)", formals, |         return ATmake("Function(<term>, <term>)", | ||||||
|  |             substitute(subs, (ATerm) formals), | ||||||
|  |             substitute(subs2, body)); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     if (atMatch(m, e) >> "Function" >> name >> body) { | ||||||
|  |         ATermMap subs2(subs); | ||||||
|  |         subs2.remove(name); | ||||||
|  |         return ATmake("Function1(<term>, <term>)", name, | ||||||
|             substitute(subs2, body)); |             substitute(subs2, body)); | ||||||
|     } |     } | ||||||
|          |          | ||||||
|  | @ -249,7 +257,6 @@ void checkVarDefs(const ATermMap & defs, Expr e) | ||||||
|         if (!defs.get(name)) |         if (!defs.get(name)) | ||||||
|             throw Error(format("undefined variable `%1%'") |             throw Error(format("undefined variable `%1%'") | ||||||
|                 % aterm2String(name)); |                 % aterm2String(name)); | ||||||
|         return; |  | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     else if (atMatch(m, e) >> "Function" >> formals >> body) { |     else if (atMatch(m, e) >> "Function" >> formals >> body) { | ||||||
|  | @ -263,7 +270,13 @@ void checkVarDefs(const ATermMap & defs, Expr e) | ||||||
|                     abort(); |                     abort(); | ||||||
|             defs2.set(name, (ATerm) ATempty); |             defs2.set(name, (ATerm) ATempty); | ||||||
|         } |         } | ||||||
|         return checkVarDefs(defs2, body); |         checkVarDefs(defs2, body); | ||||||
|  |     } | ||||||
|  |          | ||||||
|  |     else if (atMatch(m, e) >> "Function1" >> name >> body) { | ||||||
|  |         ATermMap defs2(defs); | ||||||
|  |         defs2.set(name, (ATerm) ATempty); | ||||||
|  |         checkVarDefs(defs2, body); | ||||||
|     } |     } | ||||||
|          |          | ||||||
|     else if (atMatch(m, e) >> "Rec" >> rbnds >> nrbnds) { |     else if (atMatch(m, e) >> "Rec" >> rbnds >> nrbnds) { | ||||||
|  |  | ||||||
|  | @ -54,6 +54,8 @@ expr: expr_function; | ||||||
| expr_function | expr_function | ||||||
|   : '{' formals '}' ':' expr_function |   : '{' formals '}' ':' expr_function | ||||||
|     { $$ = ATmake("Function(<term>, <term>)", $2, $5); } |     { $$ = ATmake("Function(<term>, <term>)", $2, $5); } | ||||||
|  |   | ID ':' expr_function | ||||||
|  |     { $$ = ATmake("Function1(<term>, <term>)", $1, $3); } | ||||||
|   | expr_assert |   | expr_assert | ||||||
|   ; |   ; | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
|  | @ -76,27 +76,28 @@ static string addInput(EvalState & state, | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
| static string processBinding(EvalState & state, Expr e, StoreExpr & ne) | static void processBinding(EvalState & state, Expr e, StoreExpr & ne, | ||||||
|  |     Strings & ss) | ||||||
| { | { | ||||||
|     e = evalExpr(state, e); |     e = evalExpr(state, e); | ||||||
| 
 | 
 | ||||||
|     ATMatcher m; |     ATMatcher m; | ||||||
|     string s; |     string s; | ||||||
|     ATermList es; |     ATermList es; | ||||||
| 
 |  | ||||||
|     if (atMatch(m, e) >> "Str" >> s) return s; |  | ||||||
|     if (atMatch(m, e) >> "Uri" >> s) return s; |  | ||||||
|     if (atMatch(m, e) >> "Bool" >> "True") return "1"; |  | ||||||
|     if (atMatch(m, e) >> "Bool" >> "False") return ""; |  | ||||||
| 
 |  | ||||||
|     int n; |     int n; | ||||||
|     if (atMatch(m, e) >> "Int" >> n) { | 
 | ||||||
|  |     if (atMatch(m, e) >> "Str" >> s) ss.push_back(s); | ||||||
|  |     else if (atMatch(m, e) >> "Uri" >> s) ss.push_back(s); | ||||||
|  |     else if (atMatch(m, e) >> "Bool" >> "True") ss.push_back("1"); | ||||||
|  |     else if (atMatch(m, e) >> "Bool" >> "False") ss.push_back(""); | ||||||
|  | 
 | ||||||
|  |     else if (atMatch(m, e) >> "Int" >> n) { | ||||||
|         ostringstream st; |         ostringstream st; | ||||||
|         st << n; |         st << n; | ||||||
|         return st.str(); |         ss.push_back(st.str()); | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     if (atMatch(m, e) >> "Attrs") { |     else if (atMatch(m, e) >> "Attrs") { | ||||||
|         Expr a = queryAttr(e, "type"); |         Expr a = queryAttr(e, "type"); | ||||||
|         if (a && evalString(state, a) == "derivation") { |         if (a && evalString(state, a) == "derivation") { | ||||||
|             a = queryAttr(e, "drvPath"); |             a = queryAttr(e, "drvPath"); | ||||||
|  | @ -109,31 +110,40 @@ static string processBinding(EvalState & state, Expr e, StoreExpr & ne) | ||||||
| 
 | 
 | ||||||
|             state.drvHashes[drvPath] = drvHash; |             state.drvHashes[drvPath] = drvHash; | ||||||
|              |              | ||||||
|             return addInput(state, drvPath, ne); |             ss.push_back(addInput(state, drvPath, ne)); | ||||||
|         } |         } else | ||||||
|  |             throw badTerm("invalid derivation binding", e); | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     if (atMatch(m, e) >> "Path" >> s) { |     else if (atMatch(m, e) >> "Path" >> s) { | ||||||
|         Path drvPath = copyAtom(state, s); |         Path drvPath = copyAtom(state, s); | ||||||
|         return addInput(state, drvPath, ne); |         ss.push_back(addInput(state, drvPath, ne)); | ||||||
|     } |     } | ||||||
|      |      | ||||||
|     if (atMatch(m, e) >> "List" >> es) { |     else if (atMatch(m, e) >> "List" >> es) { | ||||||
| 	string s; |  | ||||||
| 	bool first = true; |  | ||||||
|         for (ATermIterator i(es); i; ++i) { |         for (ATermIterator i(es); i; ++i) { | ||||||
|             startNest(nest, lvlVomit, format("processing list element")); |             startNest(nest, lvlVomit, format("processing list element")); | ||||||
| 	    if (!first) s = s + " "; else first = false; | 	    processBinding(state, evalExpr(state, *i), ne, ss); | ||||||
| 	    s += processBinding(state, evalExpr(state, *i), ne); |         } | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     else if (atMatch(m, e) >> "Null") ss.push_back(""); | ||||||
|  |      | ||||||
|  |     else throw badTerm("invalid derivation binding", e); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | static string concatStrings(const Strings & ss) | ||||||
|  | { | ||||||
|  |     string s; | ||||||
|  |     bool first = true; | ||||||
|  |     for (Strings::const_iterator i = ss.begin(); i != ss.end(); ++i) { | ||||||
|  |         if (!first) s += " "; else first = false; | ||||||
|  |         s += *i; | ||||||
|     } |     } | ||||||
|     return s; |     return s; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|     if (atMatch(m, e) >> "Null") return ""; |  | ||||||
|      |  | ||||||
|     throw badTerm("invalid derivation binding", e); |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| 
 | 
 | ||||||
| Expr primDerivation(EvalState & state, Expr args) | Expr primDerivation(EvalState & state, Expr args) | ||||||
| { | { | ||||||
|  | @ -157,26 +167,20 @@ Expr primDerivation(EvalState & state, Expr args) | ||||||
|         Expr value = attrs.get(key); |         Expr value = attrs.get(key); | ||||||
|         startNest(nest, lvlVomit, format("processing attribute `%1%'") % key); |         startNest(nest, lvlVomit, format("processing attribute `%1%'") % key); | ||||||
| 
 | 
 | ||||||
|  |         Strings ss; | ||||||
|  |         processBinding(state, value, ne, ss); | ||||||
|  | 
 | ||||||
|         /* The `args' attribute is special: it supplies the
 |         /* The `args' attribute is special: it supplies the
 | ||||||
|            command-line arguments to the builder. */ |            command-line arguments to the builder. */ | ||||||
|         if (key == "args") { |         if (key == "args") { | ||||||
|             throw Error("args not implemented"); |             for (Strings::iterator i = ss.begin(); i != ss.end(); ++i) | ||||||
| #if 0 |                 ne.derivation.args.push_back(*i); | ||||||
|             ATermList args; |  | ||||||
|             if (!(ATmatch(value, "[<list>]", &args)) |  | ||||||
|                 throw badTerm("list expected", value); |  | ||||||
|             while (!ATisEmpty(args)) { |  | ||||||
|                 Expr arg = evalExpr(state, ATgetFirst(args)); |  | ||||||
|                 ne.derivation.args.push_back(processBinding(state, arg, ne)); |  | ||||||
|                 args = ATgetNext(args); |  | ||||||
|             } |  | ||||||
| #endif |  | ||||||
|         } |         } | ||||||
| 
 | 
 | ||||||
|         /* All other attributes are passed to the builder through the
 |         /* All other attributes are passed to the builder through the
 | ||||||
|            environment. */ |            environment. */ | ||||||
|         else { |         else { | ||||||
|             string s = processBinding(state, value, ne); |             string s = concatStrings(ss); | ||||||
|             ne.derivation.env[key] = s; |             ne.derivation.env[key] = s; | ||||||
|             if (key == "builder") ne.derivation.builder = s; |             if (key == "builder") ne.derivation.builder = s; | ||||||
|             else if (key == "system") ne.derivation.platform = s; |             else if (key == "system") ne.derivation.platform = s; | ||||||
|  |  | ||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue