* Implemented inherit.
This commit is contained in:
		
							parent
							
								
									267dc693d2
								
							
						
					
					
						commit
						d39d3c6264
					
				
					 4 changed files with 34 additions and 29 deletions
				
			
		|  | @ -105,9 +105,12 @@ void run(Strings args) | ||||||
|     doTest(state, "map (x: __add 1 x) [ 1 2 3 ]"); |     doTest(state, "map (x: __add 1 x) [ 1 2 3 ]"); | ||||||
|     doTest(state, "map (builtins.add 1) [ 1 2 3 ]"); |     doTest(state, "map (builtins.add 1) [ 1 2 3 ]"); | ||||||
|     doTest(state, "builtins.hasAttr \"x\" { x = 1; }"); |     doTest(state, "builtins.hasAttr \"x\" { x = 1; }"); | ||||||
|     doTest(state, "let x = 1; as = rec { inherit x; y = as.x; }; in as.y"); |     doTest(state, "let x = 1; as = { inherit x; y = as.x; }; in as.y"); | ||||||
|  |     doTest(state, "let x = 1; as = rec { inherit x; y = x; }; in as.y"); | ||||||
|     doTest(state, "let as = { x = 1; }; bs = rec { inherit (as) x; y = x; }; in bs.y"); |     doTest(state, "let as = { x = 1; }; bs = rec { inherit (as) x; y = x; }; in bs.y"); | ||||||
|     doTest(state, "let as = rec { inherit (y) x; y = { x = 1; }; }; in as.x"); |     doTest(state, "let as = rec { inherit (y) x; y = { x = 1; }; }; in as.x"); | ||||||
|  |     doTest(state, "let x = 1; in let inherit x; in x"); | ||||||
|  |     doTest(state, "with { x = 1; }; let inherit x; y = x; in y"); | ||||||
|     doTest(state, "builtins.toXML 123"); |     doTest(state, "builtins.toXML 123"); | ||||||
|     doTest(state, "builtins.toXML { a.b = \"x\" + \"y\"; c = [ 1 2 ] ++ [ 3 4 ]; }"); |     doTest(state, "builtins.toXML { a.b = \"x\" + \"y\"; c = [ 1 2 ] ++ [ 3 4 ]; }"); | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
|  | @ -338,7 +338,7 @@ void EvalState::eval(Env & env, Expr * e, Value & v) | ||||||
|     char x; |     char x; | ||||||
|     if (&x < deepestStack) deepestStack = &x; |     if (&x < deepestStack) deepestStack = &x; | ||||||
|      |      | ||||||
|     debug(format("eval: %1%") % *e); |     //debug(format("eval: %1%") % *e);
 | ||||||
| 
 | 
 | ||||||
|     checkInterrupt(); |     checkInterrupt(); | ||||||
| 
 | 
 | ||||||
|  | @ -390,15 +390,14 @@ void ExprPath::eval(EvalState & state, Env & env, Value & v) | ||||||
| 
 | 
 | ||||||
| void ExprAttrs::eval(EvalState & state, Env & env, Value & v) | void ExprAttrs::eval(EvalState & state, Env & env, Value & v) | ||||||
| { | { | ||||||
|  |     state.mkAttrs(v); | ||||||
|  | 
 | ||||||
|     if (recursive) { |     if (recursive) { | ||||||
|         /* Create a new environment that contains the attributes in
 |         /* Create a new environment that contains the attributes in
 | ||||||
|            this `rec'. */ |            this `rec'. */ | ||||||
|         Env & env2(state.allocEnv(attrs.size() + inherited.size())); |         Env & env2(state.allocEnv(attrs.size() + inherited.size())); | ||||||
|         env2.up = &env; |         env2.up = &env; | ||||||
| 
 | 
 | ||||||
|         v.type = tAttrs; |  | ||||||
|         v.attrs = new Bindings; |  | ||||||
| 
 |  | ||||||
|         unsigned int displ = 0; |         unsigned int displ = 0; | ||||||
|          |          | ||||||
|         /* The recursive attributes are evaluated in the new
 |         /* The recursive attributes are evaluated in the new
 | ||||||
|  | @ -409,26 +408,25 @@ void ExprAttrs::eval(EvalState & state, Env & env, Value & v) | ||||||
|             mkThunk(env2.values[displ++], env2, i->second); |             mkThunk(env2.values[displ++], env2, i->second); | ||||||
|         } |         } | ||||||
| 
 | 
 | ||||||
| #if 0 |  | ||||||
|         /* The inherited attributes, on the other hand, are
 |         /* The inherited attributes, on the other hand, are
 | ||||||
|            evaluated in the original environment. */ |            evaluated in the original environment. */ | ||||||
|         foreach (list<Symbol>::iterator, i, inherited) { |         foreach (list<VarRef>::iterator, i, inherited) { | ||||||
|             Value & v2 = env2.bindings[*i]; |             Value & v2 = (*v.attrs)[i->name]; | ||||||
|             mkCopy(v2, *state.lookupVar(&env, *i)); |             Value * v3 = state.lookupVar(&env, *i); | ||||||
|  |             mkCopy(v2, *v3); | ||||||
|  |             mkCopy(env2.values[displ++], *v3); | ||||||
|         } |         } | ||||||
| #endif |  | ||||||
| 
 | 
 | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     else { |     else { | ||||||
|         state.mkAttrs(v); |  | ||||||
|         foreach (Attrs::iterator, i, attrs) { |         foreach (Attrs::iterator, i, attrs) { | ||||||
|             Value & v2 = (*v.attrs)[i->first]; |             Value & v2 = (*v.attrs)[i->first]; | ||||||
|             mkThunk(v2, env, i->second); |             mkThunk(v2, env, i->second); | ||||||
|         } |         } | ||||||
| 
 | 
 | ||||||
|         foreach (list<Symbol>::iterator, i, inherited) { |         foreach (list<VarRef>::iterator, i, inherited) { | ||||||
|             Value & v2 = (*v.attrs)[*i]; |             Value & v2 = (*v.attrs)[i->name]; | ||||||
|             mkCopy(v2, *state.lookupVar(&env, *i)); |             mkCopy(v2, *state.lookupVar(&env, *i)); | ||||||
|         } |         } | ||||||
|     } |     } | ||||||
|  | @ -449,14 +447,10 @@ void ExprLet::eval(EvalState & state, Env & env, Value & v) | ||||||
|     foreach (ExprAttrs::Attrs::iterator, i, attrs->attrs) |     foreach (ExprAttrs::Attrs::iterator, i, attrs->attrs) | ||||||
|         mkThunk(env2.values[displ++], env2, i->second); |         mkThunk(env2.values[displ++], env2, i->second); | ||||||
| 
 | 
 | ||||||
| #if 0 |  | ||||||
|     /* The inherited attributes, on the other hand, are evaluated in
 |     /* The inherited attributes, on the other hand, are evaluated in
 | ||||||
|        the original environment. */ |        the original environment. */ | ||||||
|     foreach (list<Symbol>::iterator, i, attrs->inherited) { |     foreach (list<VarRef>::iterator, i, attrs->inherited) | ||||||
|         Value & v2 = env2.bindings[*i]; |         mkCopy(env2.values[displ++], *state.lookupVar(&env, *i)); | ||||||
|         mkCopy(v2, *state.lookupVar(&env, *i)); |  | ||||||
|     } |  | ||||||
| #endif |  | ||||||
| 
 | 
 | ||||||
|     state.eval(env2, body, v); |     state.eval(env2, body, v); | ||||||
| } | } | ||||||
|  |  | ||||||
|  | @ -55,8 +55,8 @@ void ExprAttrs::show(std::ostream & str) | ||||||
| { | { | ||||||
|     if (recursive) str << "rec "; |     if (recursive) str << "rec "; | ||||||
|     str << "{ "; |     str << "{ "; | ||||||
|     foreach (list<Symbol>::iterator, i, inherited) |     foreach (list<VarRef>::iterator, i, inherited) | ||||||
|         str << "inherit " << *i << "; "; |         str << "inherit " << i->name << "; "; | ||||||
|     foreach (Attrs::iterator, i, attrs) |     foreach (Attrs::iterator, i, attrs) | ||||||
|         str << i->first << " = " << *i->second << "; "; |         str << i->first << " = " << *i->second << "; "; | ||||||
|     str << "}"; |     str << "}"; | ||||||
|  | @ -91,8 +91,8 @@ void ExprLambda::show(std::ostream & str) | ||||||
| void ExprLet::show(std::ostream & str) | void ExprLet::show(std::ostream & str) | ||||||
| { | { | ||||||
|     str << "let "; |     str << "let "; | ||||||
|     foreach (list<Symbol>::iterator, i, attrs->inherited) |     foreach (list<VarRef>::iterator, i, attrs->inherited) | ||||||
|         str << "inherit " << *i << "; "; |         str << "inherit " << i->name << "; "; | ||||||
|     foreach (ExprAttrs::Attrs::iterator, i, attrs->attrs) |     foreach (ExprAttrs::Attrs::iterator, i, attrs->attrs) | ||||||
|         str << i->first << " = " << *i->second << "; "; |         str << i->first << " = " << *i->second << "; "; | ||||||
|     str << "in " << *body; |     str << "in " << *body; | ||||||
|  | @ -212,16 +212,22 @@ void ExprAttrs::bindVars(const StaticEnv & env) | ||||||
|         foreach (ExprAttrs::Attrs::iterator, i, attrs) |         foreach (ExprAttrs::Attrs::iterator, i, attrs) | ||||||
|             newEnv.vars[i->first] = displ++; |             newEnv.vars[i->first] = displ++; | ||||||
| 
 | 
 | ||||||
|         foreach (list<Symbol>::iterator, i, inherited) |         foreach (list<VarRef>::iterator, i, inherited) { | ||||||
|             newEnv.vars[*i] = displ++; |             newEnv.vars[i->name] = displ++; | ||||||
|  |             i->bind(env); | ||||||
|  |         } | ||||||
| 
 | 
 | ||||||
|         foreach (ExprAttrs::Attrs::iterator, i, attrs) |         foreach (ExprAttrs::Attrs::iterator, i, attrs) | ||||||
|             i->second->bindVars(newEnv); |             i->second->bindVars(newEnv); | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     else |     else { | ||||||
|         foreach (ExprAttrs::Attrs::iterator, i, attrs) |         foreach (ExprAttrs::Attrs::iterator, i, attrs) | ||||||
|             i->second->bindVars(env); |             i->second->bindVars(env); | ||||||
|  | 
 | ||||||
|  |         foreach (list<VarRef>::iterator, i, inherited) | ||||||
|  |             i->bind(env); | ||||||
|  |     } | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| void ExprList::bindVars(const StaticEnv & env) | void ExprList::bindVars(const StaticEnv & env) | ||||||
|  | @ -258,8 +264,10 @@ void ExprLet::bindVars(const StaticEnv & env) | ||||||
|     foreach (ExprAttrs::Attrs::iterator, i, attrs->attrs) |     foreach (ExprAttrs::Attrs::iterator, i, attrs->attrs) | ||||||
|         newEnv.vars[i->first] = displ++; |         newEnv.vars[i->first] = displ++; | ||||||
| 
 | 
 | ||||||
|     foreach (list<Symbol>::iterator, i, attrs->inherited) |     foreach (list<VarRef>::iterator, i, attrs->inherited) { | ||||||
|         newEnv.vars[*i] = displ++; |         newEnv.vars[i->name] = displ++; | ||||||
|  |         i->bind(env); | ||||||
|  |     } | ||||||
| 
 | 
 | ||||||
|     foreach (ExprAttrs::Attrs::iterator, i, attrs->attrs) |     foreach (ExprAttrs::Attrs::iterator, i, attrs->attrs) | ||||||
|         i->second->bindVars(newEnv); |         i->second->bindVars(newEnv); | ||||||
|  |  | ||||||
|  | @ -127,7 +127,7 @@ struct ExprAttrs : Expr | ||||||
|     bool recursive; |     bool recursive; | ||||||
|     typedef std::map<Symbol, Expr *> Attrs; |     typedef std::map<Symbol, Expr *> Attrs; | ||||||
|     Attrs attrs; |     Attrs attrs; | ||||||
|     list<Symbol> inherited; |     list<VarRef> inherited; | ||||||
|     ExprAttrs() : recursive(false) { }; |     ExprAttrs() : recursive(false) { }; | ||||||
|     COMMON_METHODS |     COMMON_METHODS | ||||||
| }; | }; | ||||||
|  |  | ||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue