* Added a list concatenation operator:
[1 2 3] ++ [4 5 6] => [1 2 3 4 5 6]
This commit is contained in:
		
							parent
							
								
									e6899794ae
								
							
						
					
					
						commit
						991a130b1e
					
				
					 8 changed files with 29 additions and 12 deletions
				
			
		|  | @ -140,6 +140,15 @@ bool evalBool(EvalState & state, Expr e) | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
|  | ATermList evalList(EvalState & state, Expr e) | ||||||
|  | { | ||||||
|  |     e = evalExpr(state, e); | ||||||
|  |     ATermList list; | ||||||
|  |     if (!matchList(e, list)) throw Error("list expected"); | ||||||
|  |     return list; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
| Expr evalExpr2(EvalState & state, Expr e) | Expr evalExpr2(EvalState & state, Expr e) | ||||||
| { | { | ||||||
|     Expr e1, e2, e3, e4; |     Expr e1, e2, e3, e4; | ||||||
|  | @ -336,6 +345,13 @@ Expr evalExpr2(EvalState & state, Expr e) | ||||||
|         else throw Error("wrong argument types in `+' operator"); |         else throw Error("wrong argument types in `+' operator"); | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|  |     /* List concatenation. */ | ||||||
|  |     if (matchOpConcat(e, e1, e2)) { | ||||||
|  |         ATermList l1 = evalList(state, e1); | ||||||
|  |         ATermList l2 = evalList(state, e2); | ||||||
|  |         return makeList(ATconcat(l1, l2)); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|     /* Barf. */ |     /* Barf. */ | ||||||
|     throw badTerm("invalid expression", e); |     throw badTerm("invalid expression", e); | ||||||
| } | } | ||||||
|  |  | ||||||
|  | @ -46,6 +46,7 @@ Expr evalFile(EvalState & state, const Path & path); | ||||||
| /* Specific results. */ | /* Specific results. */ | ||||||
| string evalString(EvalState & state, Expr e); | string evalString(EvalState & state, Expr e); | ||||||
| Path evalPath(EvalState & state, Expr e); | Path evalPath(EvalState & state, Expr e); | ||||||
|  | ATermList evalList(EvalState & state, Expr e); | ||||||
| 
 | 
 | ||||||
| /* Print statistics. */ | /* Print statistics. */ | ||||||
| void printEvalStats(EvalState & state); | void printEvalStats(EvalState & state); | ||||||
|  |  | ||||||
|  | @ -59,6 +59,7 @@ inherit     { return INHERIT; } | ||||||
| \|\|        { return OR; } | \|\|        { return OR; } | ||||||
| \-\>        { return IMPL; } | \-\>        { return IMPL; } | ||||||
| \/\/        { return UPDATE; } | \/\/        { return UPDATE; } | ||||||
|  | \+\+        { return CONCAT; } | ||||||
| 
 | 
 | ||||||
| {ID}        { yylval->t = ATmake("<str>", yytext); return ID; /* !!! alloc */ } | {ID}        { yylval->t = ATmake("<str>", yytext); return ID; /* !!! alloc */ } | ||||||
| {INT}       { int n = atoi(yytext); /* !!! overflow */ | {INT}       { int n = atoi(yytext); /* !!! overflow */ | ||||||
|  |  | ||||||
|  | @ -18,6 +18,7 @@ OpUpdate | Expr Expr | Expr | | ||||||
| SubPath | Expr Expr | Expr | | SubPath | Expr Expr | Expr | | ||||||
| OpHasAttr | Expr string | Expr | | OpHasAttr | Expr string | Expr | | ||||||
| OpPlus | Expr Expr | Expr | | OpPlus | Expr Expr | Expr | | ||||||
|  | OpConcat | Expr Expr | Expr | | ||||||
| Call | Expr Expr | Expr | | Call | Expr Expr | Expr | | ||||||
| Select | Expr string | Expr | | Select | Expr string | Expr | | ||||||
| Var | string | Expr | | Var | string | Expr | | ||||||
|  |  | ||||||
|  | @ -64,6 +64,7 @@ static Pos makeCurPos(YYLTYPE * loc, void * data) | ||||||
| %right UPDATE | %right UPDATE | ||||||
| %left NEG | %left NEG | ||||||
| %left '+' | %left '+' | ||||||
|  | %left CONCAT | ||||||
| %nonassoc '?' | %nonassoc '?' | ||||||
| %nonassoc '~' | %nonassoc '~' | ||||||
| 
 | 
 | ||||||
|  | @ -102,6 +103,7 @@ expr_op | ||||||
|   | expr_op '~' expr_op { $$ = makeSubPath($1, $3); } |   | expr_op '~' expr_op { $$ = makeSubPath($1, $3); } | ||||||
|   | expr_op '?' ID { $$ = makeOpHasAttr($1, $3); } |   | expr_op '?' ID { $$ = makeOpHasAttr($1, $3); } | ||||||
|   | expr_op '+' expr_op { $$ = makeOpPlus($1, $3); } |   | expr_op '+' expr_op { $$ = makeOpPlus($1, $3); } | ||||||
|  |   | expr_op CONCAT expr_op { $$ = makeOpConcat($1, $3); } | ||||||
|   | expr_app |   | expr_app | ||||||
|   ; |   ; | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
|  | @ -414,17 +414,13 @@ static Expr primIsNull(EvalState & state, const ATermVector & args) | ||||||
| static Expr primMap(EvalState & state, const ATermVector & args) | static Expr primMap(EvalState & state, const ATermVector & args) | ||||||
| { | { | ||||||
|     Expr fun = evalExpr(state, args[0]); |     Expr fun = evalExpr(state, args[0]); | ||||||
|     Expr list = evalExpr(state, args[1]); |     ATermList list = evalList(state, args[1]); | ||||||
| 
 | 
 | ||||||
|     ATermList list2; |     ATermList res = ATempty; | ||||||
|     if (!matchList(list, list2)) |     for (ATermIterator i(list); i; ++i) | ||||||
|         throw Error("`map' expects a list as its second argument"); |         res = ATinsert(res, makeCall(fun, *i)); | ||||||
| 
 | 
 | ||||||
|     ATermList list3 = ATempty; |     return makeList(ATreverse(res)); | ||||||
|     for (ATermIterator i(list2); i; ++i) |  | ||||||
|         list3 = ATinsert(list3, makeCall(fun, *i)); |  | ||||||
| 
 |  | ||||||
|     return makeList(ATreverse(list3)); |  | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
|  | @ -449,9 +445,7 @@ static Expr primRemoveAttrs(EvalState & state, const ATermVector & args) | ||||||
|     ATermMap attrs; |     ATermMap attrs; | ||||||
|     queryAllAttrs(evalExpr(state, args[0]), attrs, true); |     queryAllAttrs(evalExpr(state, args[0]), attrs, true); | ||||||
|      |      | ||||||
|     ATermList list; |     ATermList list = evalList(state, args[1]); | ||||||
|     if (!matchList(evalExpr(state, args[1]), list)) |  | ||||||
|         throw Error("`removeAttrs' expects a list as its second argument"); |  | ||||||
| 
 | 
 | ||||||
|     for (ATermIterator i(list); i; ++i) |     for (ATermIterator i(list); i; ++i) | ||||||
|         /* It's not an error for *i not to exist. */ |         /* It's not an error for *i not to exist. */ | ||||||
|  |  | ||||||
							
								
								
									
										1
									
								
								tests/lang/eval-okay-concat.exp
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										1
									
								
								tests/lang/eval-okay-concat.exp
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1 @@ | ||||||
|  | List([Int(1),Int(2),Int(3),Int(4),Int(5),Int(6),Int(7),Int(8),Int(9)]) | ||||||
							
								
								
									
										1
									
								
								tests/lang/eval-okay-concat.nix
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										1
									
								
								tests/lang/eval-okay-concat.nix
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1 @@ | ||||||
|  | [1 2 3] ++ [4 5 6] ++ [7 8 9] | ||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue