* String/path concatenation operator (`+').
This commit is contained in:
		
							parent
							
								
									ee401afad8
								
							
						
					
					
						commit
						9fa07b376d
					
				
					 6 changed files with 43 additions and 5 deletions
				
			
		
							
								
								
									
										5
									
								
								NEWS
									
										
									
									
									
								
							
							
						
						
									
										5
									
								
								NEWS
									
										
									
									
									
								
							|  | @ -49,8 +49,13 @@ Major changes include the following: | ||||||
| 
 | 
 | ||||||
| * Nix expression language changes: | * Nix expression language changes: | ||||||
| 
 | 
 | ||||||
|  |   * New language construct: `with E1; E2' brings all attributes | ||||||
|  |     defined in the attribute set E1 in scope in E2. | ||||||
|  | 
 | ||||||
|   * Added a `map' function. |   * Added a `map' function. | ||||||
| 
 | 
 | ||||||
|  |   * Various new operators (e.g., string concatenation). | ||||||
|  | 
 | ||||||
| * An Emacs mode for editing Nix expressions (with syntax highlighting | * An Emacs mode for editing Nix expressions (with syntax highlighting | ||||||
|   and indentation) has been added. |   and indentation) has been added. | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
|  | @ -338,6 +338,20 @@ Expr evalExpr2(EvalState & state, Expr e) | ||||||
|         return makeBool(attrs.get(name) != 0); |         return makeBool(attrs.get(name) != 0); | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|  |     /* String or path concatenation. */ | ||||||
|  |     if (atMatch(m, e) >> "OpPlus" >> e1 >> e2) { | ||||||
|  |         e1 = evalExpr(state, e1); | ||||||
|  |         e2 = evalExpr(state, e2); | ||||||
|  |         string s1, s2; | ||||||
|  |         if (atMatch(m, e1) >> "Str" >> s1 && | ||||||
|  |             atMatch(m, e2) >> "Str" >> s2) | ||||||
|  |             return makeString(s1 + s2); | ||||||
|  |         else if (atMatch(m, e1) >> "Path" >> s1 && | ||||||
|  |             atMatch(m, e2) >> "Path" >> s2) | ||||||
|  |             return makeString(canonPath(s1 + "/" + s2)); | ||||||
|  |         else throw Error("wrong argument types in `+' operator"); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|     /* Barf. */ |     /* Barf. */ | ||||||
|     throw badTerm("invalid expression", e); |     throw badTerm("invalid expression", e); | ||||||
| } | } | ||||||
|  |  | ||||||
|  | @ -364,3 +364,15 @@ Expr makeBool(bool b) | ||||||
| { | { | ||||||
|     return b ? ATmake("Bool(True)") : ATmake("Bool(False)"); |     return b ? ATmake("Bool(True)") : ATmake("Bool(False)"); | ||||||
| } | } | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | Expr makeString(const string & s) | ||||||
|  | { | ||||||
|  |     return ATmake("Str(<str>)", s.c_str()); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | Expr makePath(const Path & path) | ||||||
|  | { | ||||||
|  |     return ATmake("Path(<str>)", path.c_str()); | ||||||
|  | } | ||||||
|  |  | ||||||
|  | @ -92,5 +92,11 @@ void checkVarDefs(const ATermMap & def, Expr e); | ||||||
| /* Create an expression representing a boolean. */ | /* Create an expression representing a boolean. */ | ||||||
| Expr makeBool(bool b); | Expr makeBool(bool b); | ||||||
| 
 | 
 | ||||||
|  | /* Create an expression representing a string. */ | ||||||
|  | Expr makeString(const string & s); | ||||||
|  | 
 | ||||||
|  | /* Create an expression representing a path. */ | ||||||
|  | Expr makePath(const Path & path); | ||||||
|  | 
 | ||||||
| 
 | 
 | ||||||
| #endif /* !__NIXEXPR_H */ | #endif /* !__NIXEXPR_H */ | ||||||
|  |  | ||||||
|  | @ -53,6 +53,7 @@ ATerm makePos(YYLTYPE * loc, void * data) | ||||||
| %nonassoc EQ NEQ | %nonassoc EQ NEQ | ||||||
| %right UPDATE | %right UPDATE | ||||||
| %left NEG | %left NEG | ||||||
|  | %left '+' | ||||||
| %nonassoc '?' | %nonassoc '?' | ||||||
| %nonassoc '~' | %nonassoc '~' | ||||||
| 
 | 
 | ||||||
|  | @ -90,6 +91,7 @@ expr_op | ||||||
|   | expr_op UPDATE expr_op { $$ = ATmake("OpUpdate(<term>, <term>)", $1, $3); } |   | expr_op UPDATE expr_op { $$ = ATmake("OpUpdate(<term>, <term>)", $1, $3); } | ||||||
|   | expr_op '~' expr_op { $$ = ATmake("SubPath(<term>, <term>)", $1, $3); } |   | expr_op '~' expr_op { $$ = ATmake("SubPath(<term>, <term>)", $1, $3); } | ||||||
|   | expr_op '?' ID { $$ = ATmake("OpHasAttr(<term>, <term>)", $1, $3); } |   | expr_op '?' ID { $$ = ATmake("OpHasAttr(<term>, <term>)", $1, $3); } | ||||||
|  |   | expr_op '+' expr_op { $$ = ATmake("OpPlus(<term>, <term>)", $1, $3); } | ||||||
|   | expr_app |   | expr_app | ||||||
|   ; |   ; | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
|  | @ -273,8 +273,8 @@ static Expr primDerivation(EvalState & state, const ATermVector & _args) | ||||||
| 
 | 
 | ||||||
|     attrs.set("outPath", ATmake("(Path(<str>), NoPos)", outPath.c_str())); |     attrs.set("outPath", ATmake("(Path(<str>), NoPos)", outPath.c_str())); | ||||||
|     attrs.set("drvPath", ATmake("(Path(<str>), NoPos)", drvPath.c_str())); |     attrs.set("drvPath", ATmake("(Path(<str>), NoPos)", drvPath.c_str())); | ||||||
|     attrs.set("drvHash", ATmake("(Str(<str>), NoPos)", ((string) drvHash).c_str())); |     attrs.set("drvHash", ATmake("(<term>, NoPos)", makeString(drvHash))); | ||||||
|     attrs.set("type", ATmake("(Str(\"derivation\"), NoPos)")); |     attrs.set("type", ATmake("(<term>, NoPos)", makeString("derivation"))); | ||||||
| 
 | 
 | ||||||
|     return makeAttrs(attrs); |     return makeAttrs(attrs); | ||||||
| } | } | ||||||
|  | @ -284,8 +284,7 @@ static Expr primDerivation(EvalState & state, const ATermVector & _args) | ||||||
|    following the last slash. */ |    following the last slash. */ | ||||||
| static Expr primBaseNameOf(EvalState & state, const ATermVector & args) | static Expr primBaseNameOf(EvalState & state, const ATermVector & args) | ||||||
| { | { | ||||||
|     string s = evalString(state, args[0]); |     return makeString(baseNameOf(evalString(state, args[0]))); | ||||||
|     return ATmake("Str(<str>)", baseNameOf(s).c_str()); |  | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
|  | @ -298,7 +297,7 @@ static Expr primToString(EvalState & state, const ATermVector & args) | ||||||
|     if (atMatch(m, arg) >> "Str" >> s || |     if (atMatch(m, arg) >> "Str" >> s || | ||||||
|         atMatch(m, arg) >> "Path" >> s || |         atMatch(m, arg) >> "Path" >> s || | ||||||
|         atMatch(m, arg) >> "Uri" >> s) |         atMatch(m, arg) >> "Uri" >> s) | ||||||
|         return ATmake("Str(<str>)", s.c_str()); |         return makeString(s); | ||||||
|     else throw Error("cannot coerce value to string"); |     else throw Error("cannot coerce value to string"); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue