Allow using RegisterPrimop to define constants.
This enables plugins to add new constants, as well as new primops.
This commit is contained in:
		
							parent
							
								
									88cd2d41ac
								
							
						
					
					
						commit
						081f14a169
					
				
					 6 changed files with 15 additions and 6 deletions
				
			
		|  | @ -750,7 +750,7 @@ builtins.fetchurl { | ||||||
|         files will be dlopened by Nix, allowing them to affect |         files will be dlopened by Nix, allowing them to affect | ||||||
|         execution through static initialization. In particular, these |         execution through static initialization. In particular, these | ||||||
|         plugins may construct static instances of RegisterPrimOp to |         plugins may construct static instances of RegisterPrimOp to | ||||||
|         add new primops to the expression language, |         add new primops or constants to the expression language, | ||||||
|         RegisterStoreImplementation to add new store implementations, |         RegisterStoreImplementation to add new store implementations, | ||||||
|         and RegisterCommand to add new subcommands to the |         and RegisterCommand to add new subcommands to the | ||||||
|         <literal>nix</literal> command. See the constructors for those |         <literal>nix</literal> command. See the constructors for those | ||||||
|  |  | ||||||
|  | @ -404,7 +404,7 @@ Path EvalState::toRealPath(const Path & path, const PathSet & context) | ||||||
| }; | }; | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
| void EvalState::addConstant(const string & name, Value & v) | Value * EvalState::addConstant(const string & name, Value & v) | ||||||
| { | { | ||||||
|     Value * v2 = allocValue(); |     Value * v2 = allocValue(); | ||||||
|     *v2 = v; |     *v2 = v; | ||||||
|  | @ -412,12 +412,18 @@ void EvalState::addConstant(const string & name, Value & v) | ||||||
|     baseEnv.values[baseEnvDispl++] = v2; |     baseEnv.values[baseEnvDispl++] = v2; | ||||||
|     string name2 = string(name, 0, 2) == "__" ? string(name, 2) : name; |     string name2 = string(name, 0, 2) == "__" ? string(name, 2) : name; | ||||||
|     baseEnv.values[0]->attrs->push_back(Attr(symbols.create(name2), v2)); |     baseEnv.values[0]->attrs->push_back(Attr(symbols.create(name2), v2)); | ||||||
|  |     return v2; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
| Value * EvalState::addPrimOp(const string & name, | Value * EvalState::addPrimOp(const string & name, | ||||||
|     unsigned int arity, PrimOpFun primOp) |     unsigned int arity, PrimOpFun primOp) | ||||||
| { | { | ||||||
|  |     if (arity == 0) { | ||||||
|  |         Value v; | ||||||
|  |         primOp(*this, noPos, nullptr, v); | ||||||
|  |         return addConstant(name, v); | ||||||
|  |     } | ||||||
|     Value * v = allocValue(); |     Value * v = allocValue(); | ||||||
|     string name2 = string(name, 0, 2) == "__" ? string(name, 2) : name; |     string name2 = string(name, 0, 2) == "__" ? string(name, 2) : name; | ||||||
|     Symbol sym = symbols.create(name2); |     Symbol sym = symbols.create(name2); | ||||||
|  |  | ||||||
|  | @ -210,7 +210,7 @@ private: | ||||||
| 
 | 
 | ||||||
|     void createBaseEnv(); |     void createBaseEnv(); | ||||||
| 
 | 
 | ||||||
|     void addConstant(const string & name, Value & v); |     Value * addConstant(const string & name, Value & v); | ||||||
| 
 | 
 | ||||||
|     Value * addPrimOp(const string & name, |     Value * addPrimOp(const string & name, | ||||||
|         unsigned int arity, PrimOpFun primOp); |         unsigned int arity, PrimOpFun primOp); | ||||||
|  |  | ||||||
|  | @ -9,6 +9,9 @@ struct RegisterPrimOp | ||||||
| { | { | ||||||
|     typedef std::vector<std::tuple<std::string, size_t, PrimOpFun>> PrimOps; |     typedef std::vector<std::tuple<std::string, size_t, PrimOpFun>> PrimOps; | ||||||
|     static PrimOps * primOps; |     static PrimOps * primOps; | ||||||
|  |     /* You can register a constant by passing an arity of 0. fun
 | ||||||
|  |        will get called during EvalState initialization, so there | ||||||
|  |        may be primops not yet added and builtins is not yet sorted. */ | ||||||
|     RegisterPrimOp(std::string name, size_t arity, PrimOpFun fun); |     RegisterPrimOp(std::string name, size_t arity, PrimOpFun fun); | ||||||
| }; | }; | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
|  | @ -2,6 +2,6 @@ source common.sh | ||||||
| 
 | 
 | ||||||
| set -o pipefail | set -o pipefail | ||||||
| 
 | 
 | ||||||
| res=$(nix eval '(builtins.constNull true)' --option plugin-files $PWD/plugins/plugintest.so) | res=$(nix eval '(builtins.anotherNull)' --option plugin-files $PWD/plugins/plugintest.so) | ||||||
| 
 | 
 | ||||||
| [ "$res"x = "nullx" ] | [ "$res"x = "nullx" ] | ||||||
|  |  | ||||||
|  | @ -2,9 +2,9 @@ | ||||||
| 
 | 
 | ||||||
| using namespace nix; | using namespace nix; | ||||||
| 
 | 
 | ||||||
| static void prim_constNull (EvalState & state, const Pos & pos, Value ** args, Value & v) | static void prim_anotherNull (EvalState & state, const Pos & pos, Value ** args, Value & v) | ||||||
| { | { | ||||||
|     mkNull(v); |     mkNull(v); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| static RegisterPrimOp r("constNull", 1, prim_constNull); | static RegisterPrimOp r("anotherNull", 0, prim_anotherNull); | ||||||
|  |  | ||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue