* 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 e1, e2, e3, e4; | ||||
|  | @ -336,6 +345,13 @@ Expr evalExpr2(EvalState & state, Expr e) | |||
|         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. */ | ||||
|     throw badTerm("invalid expression", e); | ||||
| } | ||||
|  |  | |||
|  | @ -46,6 +46,7 @@ Expr evalFile(EvalState & state, const Path & path); | |||
| /* Specific results. */ | ||||
| string evalString(EvalState & state, Expr e); | ||||
| Path evalPath(EvalState & state, Expr e); | ||||
| ATermList evalList(EvalState & state, Expr e); | ||||
| 
 | ||||
| /* Print statistics. */ | ||||
| void printEvalStats(EvalState & state); | ||||
|  |  | |||
|  | @ -59,6 +59,7 @@ inherit     { return INHERIT; } | |||
| \|\|        { return OR; } | ||||
| \-\>        { return IMPL; } | ||||
| \/\/        { return UPDATE; } | ||||
| \+\+        { return CONCAT; } | ||||
| 
 | ||||
| {ID}        { yylval->t = ATmake("<str>", yytext); return ID; /* !!! alloc */ } | ||||
| {INT}       { int n = atoi(yytext); /* !!! overflow */ | ||||
|  |  | |||
|  | @ -18,6 +18,7 @@ OpUpdate | Expr Expr | Expr | | |||
| SubPath | Expr Expr | Expr | | ||||
| OpHasAttr | Expr string | Expr | | ||||
| OpPlus | Expr Expr | Expr | | ||||
| OpConcat | Expr Expr | Expr | | ||||
| Call | Expr Expr | Expr | | ||||
| Select | Expr string | Expr | | ||||
| Var | string | Expr | | ||||
|  |  | |||
|  | @ -64,6 +64,7 @@ static Pos makeCurPos(YYLTYPE * loc, void * data) | |||
| %right UPDATE | ||||
| %left NEG | ||||
| %left '+' | ||||
| %left CONCAT | ||||
| %nonassoc '?' | ||||
| %nonassoc '~' | ||||
| 
 | ||||
|  | @ -102,6 +103,7 @@ expr_op | |||
|   | expr_op '~' expr_op { $$ = makeSubPath($1, $3); } | ||||
|   | expr_op '?' ID { $$ = makeOpHasAttr($1, $3); } | ||||
|   | expr_op '+' expr_op { $$ = makeOpPlus($1, $3); } | ||||
|   | expr_op CONCAT expr_op { $$ = makeOpConcat($1, $3); } | ||||
|   | expr_app | ||||
|   ; | ||||
| 
 | ||||
|  |  | |||
|  | @ -414,17 +414,13 @@ static Expr primIsNull(EvalState & state, const ATermVector & args) | |||
| static Expr primMap(EvalState & state, const ATermVector & args) | ||||
| { | ||||
|     Expr fun = evalExpr(state, args[0]); | ||||
|     Expr list = evalExpr(state, args[1]); | ||||
|     ATermList list = evalList(state, args[1]); | ||||
| 
 | ||||
|     ATermList list2; | ||||
|     if (!matchList(list, list2)) | ||||
|         throw Error("`map' expects a list as its second argument"); | ||||
|     ATermList res = ATempty; | ||||
|     for (ATermIterator i(list); i; ++i) | ||||
|         res = ATinsert(res, makeCall(fun, *i)); | ||||
| 
 | ||||
|     ATermList list3 = ATempty; | ||||
|     for (ATermIterator i(list2); i; ++i) | ||||
|         list3 = ATinsert(list3, makeCall(fun, *i)); | ||||
| 
 | ||||
|     return makeList(ATreverse(list3)); | ||||
|     return makeList(ATreverse(res)); | ||||
| } | ||||
| 
 | ||||
| 
 | ||||
|  | @ -449,9 +445,7 @@ static Expr primRemoveAttrs(EvalState & state, const ATermVector & args) | |||
|     ATermMap attrs; | ||||
|     queryAllAttrs(evalExpr(state, args[0]), attrs, true); | ||||
|      | ||||
|     ATermList list; | ||||
|     if (!matchList(evalExpr(state, args[1]), list)) | ||||
|         throw Error("`removeAttrs' expects a list as its second argument"); | ||||
|     ATermList list = evalList(state, args[1]); | ||||
| 
 | ||||
|     for (ATermIterator i(list); i; ++i) | ||||
|         /* 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