* Evaluate lets directly (i.e. without desugaring to `rec { attrs...;
<let-body> = e; }.<let-body>). This prevents the unnecessary allocation of an attribute set.
This commit is contained in:
		
							parent
							
								
									ac1e8f40d4
								
							
						
					
					
						commit
						7d47498b5e
					
				
					 5 changed files with 45 additions and 1 deletions
				
			
		|  | @ -456,6 +456,31 @@ void ExprAttrs::eval(EvalState & state, Env & env, Value & v) | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
|  | void ExprLet::eval(EvalState & state, Env & env, Value & v) | ||||||
|  | { | ||||||
|  |     /* Create a new environment that contains the attributes in this
 | ||||||
|  |        `let'. */ | ||||||
|  |     Env & env2(state.allocEnv()); | ||||||
|  |     env2.up = &env; | ||||||
|  |          | ||||||
|  |     /* The recursive attributes are evaluated in the new
 | ||||||
|  |        environment. */ | ||||||
|  |     foreach (ExprAttrs::Attrs::iterator, i, attrs->attrs) { | ||||||
|  |         Value & v2 = env2.bindings[i->first]; | ||||||
|  |         mkThunk(v2, env2, i->second); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     /* The inherited attributes, on the other hand, are evaluated in
 | ||||||
|  |        the original environment. */ | ||||||
|  |     foreach (list<Symbol>::iterator, i, attrs->inherited) { | ||||||
|  |         Value & v2 = env2.bindings[*i]; | ||||||
|  |         mkCopy(v2, *state.lookupVar(&env, *i)); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     state.eval(env2, body, v); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
| void ExprList::eval(EvalState & state, Env & env, Value & v) | void ExprList::eval(EvalState & state, Env & env, Value & v) | ||||||
| { | { | ||||||
|     state.mkList(v, elems.size()); |     state.mkList(v, elems.size()); | ||||||
|  |  | ||||||
|  | @ -244,6 +244,7 @@ private: | ||||||
| 
 | 
 | ||||||
|     friend class ExprVar; |     friend class ExprVar; | ||||||
|     friend class ExprAttrs; |     friend class ExprAttrs; | ||||||
|  |     friend class ExprLet; | ||||||
| 
 | 
 | ||||||
| public: | public: | ||||||
|      |      | ||||||
|  |  | ||||||
|  | @ -87,6 +87,16 @@ void ExprLambda::show(std::ostream & str) | ||||||
|     str << ": " << *body << ")"; |     str << ": " << *body << ")"; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | void ExprLet::show(std::ostream & str) | ||||||
|  | { | ||||||
|  |     str << "let "; | ||||||
|  |     foreach (list<Symbol>::iterator, i, attrs->inherited) | ||||||
|  |         str << "inherit " << *i << "; "; | ||||||
|  |     foreach (ExprAttrs::Attrs::iterator, i, attrs->attrs) | ||||||
|  |         str << i->first << " = " << *i->second << "; "; | ||||||
|  |     str << "in " << *body; | ||||||
|  | } | ||||||
|  | 
 | ||||||
| void ExprWith::show(std::ostream & str) | void ExprWith::show(std::ostream & str) | ||||||
| { | { | ||||||
|     str << "with " << *attrs << "; " << *body; |     str << "with " << *attrs << "; " << *body; | ||||||
|  |  | ||||||
|  | @ -139,6 +139,14 @@ struct ExprLambda : Expr | ||||||
|     COMMON_METHODS |     COMMON_METHODS | ||||||
| }; | }; | ||||||
| 
 | 
 | ||||||
|  | struct ExprLet : Expr | ||||||
|  | { | ||||||
|  |     ExprAttrs * attrs; | ||||||
|  |     Expr * body; | ||||||
|  |     ExprLet(ExprAttrs * attrs, Expr * body) : attrs(attrs), body(body) { }; | ||||||
|  |     COMMON_METHODS | ||||||
|  | }; | ||||||
|  | 
 | ||||||
| struct ExprWith : Expr | struct ExprWith : Expr | ||||||
| { | { | ||||||
|     Pos pos; |     Pos pos; | ||||||
|  |  | ||||||
|  | @ -306,7 +306,7 @@ expr_function | ||||||
|   | WITH expr ';' expr_function |   | WITH expr ';' expr_function | ||||||
|     { $$ = new ExprWith(CUR_POS, $2, $4); } |     { $$ = new ExprWith(CUR_POS, $2, $4); } | ||||||
|   | LET binds IN expr_function |   | LET binds IN expr_function | ||||||
|     { $2->attrs[data->sLetBody] = $4; $2->recursive = true; $$ = new ExprSelect($2, data->sLetBody); } |     { $$ = new ExprLet($2, $4); } | ||||||
|   | expr_if |   | expr_if | ||||||
|   ; |   ; | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue