Add functors (callable attribute sets).
With this, attribute sets with a `__functor` attribute can be applied just like normal functions. This can be used to attach arbitrary metadata to a function without callers needing to treat it specially.
This commit is contained in:
		
							parent
							
								
									8cfe939b0f
								
							
						
					
					
						commit
						997defa166
					
				
					 4 changed files with 15 additions and 1 deletions
				
			
		|  | @ -180,6 +180,7 @@ EvalState::EvalState(const Strings & _searchPath) | ||||||
|     , sFile(symbols.create("file")) |     , sFile(symbols.create("file")) | ||||||
|     , sLine(symbols.create("line")) |     , sLine(symbols.create("line")) | ||||||
|     , sColumn(symbols.create("column")) |     , sColumn(symbols.create("column")) | ||||||
|  |     , sFunctor(symbols.create("__functor")) | ||||||
|     , repair(false) |     , repair(false) | ||||||
|     , baseEnv(allocEnv(128)) |     , baseEnv(allocEnv(128)) | ||||||
|     , staticBaseEnv(false, 0) |     , staticBaseEnv(false, 0) | ||||||
|  | @ -885,6 +886,17 @@ void EvalState::callFunction(Value & fun, Value & arg, Value & v, const Pos & po | ||||||
|         return; |         return; | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|  |     if (fun.type == tAttrs) { | ||||||
|  |       auto found = fun.attrs->find(sFunctor); | ||||||
|  |       if (found != fun.attrs->end()) { | ||||||
|  |         forceValue(*found->value); | ||||||
|  |         Value * v2 = allocValue(); | ||||||
|  |         callFunction(*found->value, fun, *v2, pos); | ||||||
|  |         forceValue(*v2); | ||||||
|  |         return callFunction(*v2, arg, v, pos); | ||||||
|  |       } | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|     if (fun.type != tLambda) |     if (fun.type != tLambda) | ||||||
|         throwTypeError("attempt to call something which is not a function but %1%, at %2%", fun, pos); |         throwTypeError("attempt to call something which is not a function but %1%, at %2%", fun, pos); | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
|  | @ -126,7 +126,7 @@ public: | ||||||
| 
 | 
 | ||||||
|     const Symbol sWith, sOutPath, sDrvPath, sType, sMeta, sName, sValue, |     const Symbol sWith, sOutPath, sDrvPath, sType, sMeta, sName, sValue, | ||||||
|         sSystem, sOverrides, sOutputs, sOutputName, sIgnoreNulls, |         sSystem, sOverrides, sOutputs, sOutputName, sIgnoreNulls, | ||||||
|         sFile, sLine, sColumn; |         sFile, sLine, sColumn, sFunctor; | ||||||
|     Symbol sDerivationNix; |     Symbol sDerivationNix; | ||||||
| 
 | 
 | ||||||
|     /* If set, force copying files to the Nix store even if they
 |     /* If set, force copying files to the Nix store even if they
 | ||||||
|  |  | ||||||
							
								
								
									
										1
									
								
								tests/lang/eval-okay-callable-attrs.exp
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										1
									
								
								tests/lang/eval-okay-callable-attrs.exp
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1 @@ | ||||||
|  | true | ||||||
							
								
								
									
										1
									
								
								tests/lang/eval-okay-callable-attrs.nix
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										1
									
								
								tests/lang/eval-okay-callable-attrs.nix
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1 @@ | ||||||
|  | ({ __functor = self: x: self.foo && x; foo = false; } // { foo = true; }) true | ||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue