This commit is contained in:
		
							parent
							
								
									3d2b835f30
								
							
						
					
					
						commit
						d96cdcea6b
					
				
					 1 changed files with 51 additions and 53 deletions
				
			
		|  | @ -75,6 +75,28 @@ struct Value | ||||||
| }; | }; | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
|  | static void mkThunk(Value & v, Env & env, Expr expr) | ||||||
|  | { | ||||||
|  |     v.type = tThunk; | ||||||
|  |     v.thunk.env = &env; | ||||||
|  |     v.thunk.expr = expr; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | static void mkInt(Value & v, int n) | ||||||
|  | { | ||||||
|  |     v.type = tInt; | ||||||
|  |     v.integer = n; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | static void mkBool(Value & v, bool b) | ||||||
|  | { | ||||||
|  |     v.type = tBool; | ||||||
|  |     v.boolean = b; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
| std::ostream & operator << (std::ostream & str, Value & v) | std::ostream & operator << (std::ostream & str, Value & v) | ||||||
| { | { | ||||||
|     switch (v.type) { |     switch (v.type) { | ||||||
|  | @ -176,13 +198,6 @@ static Value * lookupVar(Env * env, Sym name) | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
| static void setBoolValue(Value & v, bool b) |  | ||||||
| { |  | ||||||
|     v.type = tBool; |  | ||||||
|     v.boolean = b; |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| 
 |  | ||||||
| static bool eqValues(Value & v1, Value & v2) | static bool eqValues(Value & v1, Value & v2) | ||||||
| { | { | ||||||
|     forceValue(v1); |     forceValue(v1); | ||||||
|  | @ -223,10 +238,10 @@ static Value * allocValues(unsigned int count) | ||||||
|     return new Value[count]; // !!! check destructor
 |     return new Value[count]; // !!! check destructor
 | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| static Env * allocEnv() | static Env & allocEnv() | ||||||
| { | { | ||||||
|     nrEnvs++; |     nrEnvs++; | ||||||
|     return new Env; |     return *(new Env); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
|  | @ -250,8 +265,7 @@ static void eval(Env & env, Expr e, Value & v) | ||||||
| 
 | 
 | ||||||
|     int n; |     int n; | ||||||
|     if (matchInt(e, n)) { |     if (matchInt(e, n)) { | ||||||
|         v.type = tInt; |         mkInt(v, n); | ||||||
|         v.integer = n; |  | ||||||
|         return; |         return; | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|  | @ -264,28 +278,24 @@ static void eval(Env & env, Expr e, Value & v) | ||||||
|             if (!matchBind(*i, name, e2, pos)) abort(); /* can't happen */ |             if (!matchBind(*i, name, e2, pos)) abort(); /* can't happen */ | ||||||
|             Value & v2 = (*v.attrs)[name]; |             Value & v2 = (*v.attrs)[name]; | ||||||
|             nrValues++; |             nrValues++; | ||||||
|             v2.type = tThunk; |             mkThunk(v2, env, e2); | ||||||
|             v2.thunk.env = &env; |  | ||||||
|             v2.thunk.expr = e2; |  | ||||||
|         } |         } | ||||||
|         return; |         return; | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     ATermList rbnds, nrbnds; |     ATermList rbnds, nrbnds; | ||||||
|     if (matchRec(e, rbnds, nrbnds)) { |     if (matchRec(e, rbnds, nrbnds)) { | ||||||
|         Env * env2 = allocEnv(); |         Env & env2(allocEnv()); | ||||||
|         env2->up = &env; |         env2.up = &env; | ||||||
|          |          | ||||||
|         v.type = tAttrs; |         v.type = tAttrs; | ||||||
|         v.attrs = &env2->bindings; |         v.attrs = &env2.bindings; | ||||||
|         ATerm name, e2, pos; |         ATerm name, e2, pos; | ||||||
|         for (ATermIterator i(rbnds); i; ++i) { |         for (ATermIterator i(rbnds); i; ++i) { | ||||||
|             if (!matchBind(*i, name, e2, pos)) abort(); /* can't happen */ |             if (!matchBind(*i, name, e2, pos)) abort(); /* can't happen */ | ||||||
|             Value & v2 = env2->bindings[name]; |             Value & v2 = env2.bindings[name]; | ||||||
|             nrValues++; |             nrValues++; | ||||||
|             v2.type = tThunk; |             mkThunk(v2, env2, e2); | ||||||
|             v2.thunk.env = env2; |  | ||||||
|             v2.thunk.expr = e2; |  | ||||||
|         } |         } | ||||||
|          |          | ||||||
|         return; |         return; | ||||||
|  | @ -327,9 +337,7 @@ static void eval(Env & env, Expr e, Value & v) | ||||||
|                 unsigned int arity = primOp->primOp.arity; |                 unsigned int arity = primOp->primOp.arity; | ||||||
|                  |                  | ||||||
|                 Value vLastArg; |                 Value vLastArg; | ||||||
|                 vLastArg.type = tThunk; |                 mkThunk(vLastArg, env, arg); | ||||||
|                 vLastArg.thunk.env = &env; |  | ||||||
|                 vLastArg.thunk.expr = arg; |  | ||||||
| 
 | 
 | ||||||
|                 /* Put all the arguments in an array. */ |                 /* Put all the arguments in an array. */ | ||||||
|                 Value * vArgs[arity]; |                 Value * vArgs[arity]; | ||||||
|  | @ -343,9 +351,7 @@ static void eval(Env & env, Expr e, Value & v) | ||||||
|             } else { |             } else { | ||||||
|                 Value * v2 = allocValues(2); |                 Value * v2 = allocValues(2); | ||||||
|                 v2[0] = v; |                 v2[0] = v; | ||||||
|                 v2[1].type = tThunk; |                 mkThunk(v2[1], env, arg); | ||||||
|                 v2[1].thunk.env = &env; |  | ||||||
|                 v2[1].thunk.expr = arg; |  | ||||||
|                 v.type = tPrimOpApp; |                 v.type = tPrimOpApp; | ||||||
|                 v.primOpApp.left = &v2[0]; |                 v.primOpApp.left = &v2[0]; | ||||||
|                 v.primOpApp.right = &v2[1]; |                 v.primOpApp.right = &v2[1]; | ||||||
|  | @ -356,17 +362,15 @@ static void eval(Env & env, Expr e, Value & v) | ||||||
|          |          | ||||||
|         if (v.type != tLambda) throw TypeError("expected function"); |         if (v.type != tLambda) throw TypeError("expected function"); | ||||||
| 
 | 
 | ||||||
|         Env * env2 = allocEnv(); |         Env & env2(allocEnv()); | ||||||
|         env2->up = &env; |         env2.up = &env; | ||||||
| 
 | 
 | ||||||
|         ATermList formals; ATerm ellipsis; |         ATermList formals; ATerm ellipsis; | ||||||
| 
 | 
 | ||||||
|         if (matchVarPat(v.lambda.pat, name)) { |         if (matchVarPat(v.lambda.pat, name)) { | ||||||
|             Value & vArg = env2->bindings[name]; |             Value & vArg = env2.bindings[name]; | ||||||
|             nrValues++; |             nrValues++; | ||||||
|             vArg.type = tThunk; |             mkThunk(vArg, env, arg); | ||||||
|             vArg.thunk.env = &env; |  | ||||||
|             vArg.thunk.expr = arg; |  | ||||||
|         } |         } | ||||||
| 
 | 
 | ||||||
|         else if (matchAttrsPat(v.lambda.pat, formals, ellipsis, name)) { |         else if (matchAttrsPat(v.lambda.pat, formals, ellipsis, name)) { | ||||||
|  | @ -376,7 +380,7 @@ static void eval(Env & env, Expr e, Value & v) | ||||||
|             if (name == sNoAlias) |             if (name == sNoAlias) | ||||||
|                 vArg = &vArg_; |                 vArg = &vArg_; | ||||||
|             else { |             else { | ||||||
|                 vArg = &env2->bindings[name]; |                 vArg = &env2.bindings[name]; | ||||||
|                 nrValues++; |                 nrValues++; | ||||||
|             }                 |             }                 | ||||||
| 
 | 
 | ||||||
|  | @ -394,16 +398,14 @@ static void eval(Env & env, Expr e, Value & v) | ||||||
| 
 | 
 | ||||||
|                 Bindings::iterator j = vArg->attrs->find(name); |                 Bindings::iterator j = vArg->attrs->find(name); | ||||||
|                  |                  | ||||||
|                 Value & v = env2->bindings[name]; |                 Value & v = env2.bindings[name]; | ||||||
|                 nrValues++; |                 nrValues++; | ||||||
|                  |                  | ||||||
|                 if (j == vArg->attrs->end()) { |                 if (j == vArg->attrs->end()) { | ||||||
|                     if (!matchDefaultValue(def2, def)) def = 0; |                     if (!matchDefaultValue(def2, def)) def = 0; | ||||||
|                     if (def == 0) throw TypeError(format("the argument named `%1%' required by the function is missing") |                     if (def == 0) throw TypeError(format("the argument named `%1%' required by the function is missing") | ||||||
|                         % aterm2String(name)); |                         % aterm2String(name)); | ||||||
|                     v.type = tThunk; |                     mkThunk(v, env2, def); | ||||||
|                     v.thunk.env = env2; |  | ||||||
|                     v.thunk.expr = def; |  | ||||||
|                 } else { |                 } else { | ||||||
|                     attrsUsed++; |                     attrsUsed++; | ||||||
|                     v.type = tCopy; |                     v.type = tCopy; | ||||||
|  | @ -421,21 +423,21 @@ static void eval(Env & env, Expr e, Value & v) | ||||||
| 
 | 
 | ||||||
|         else abort(); |         else abort(); | ||||||
|          |          | ||||||
|         eval(*env2, v.lambda.body, v); |         eval(env2, v.lambda.body, v); | ||||||
|         return; |         return; | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     Expr attrs; |     Expr attrs; | ||||||
|     if (matchWith(e, attrs, body, pos)) { |     if (matchWith(e, attrs, body, pos)) { | ||||||
|         Env * env2 = allocEnv(); |         Env & env2(allocEnv()); | ||||||
|         env2->up = &env; |         env2.up = &env; | ||||||
| 
 | 
 | ||||||
|         Value & vAttrs = env2->bindings[sWith]; |         Value & vAttrs = env2.bindings[sWith]; | ||||||
|         nrValues++; |         nrValues++; | ||||||
|         eval(env, attrs, vAttrs); |         eval(env, attrs, vAttrs); | ||||||
|         if (vAttrs.type != tAttrs) throw TypeError("`with' should evaluate to an attribute set"); |         if (vAttrs.type != tAttrs) throw TypeError("`with' should evaluate to an attribute set"); | ||||||
|          |          | ||||||
|         eval(*env2, body, v); |         eval(env2, body, v); | ||||||
|         return; |         return; | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|  | @ -443,25 +445,22 @@ static void eval(Env & env, Expr e, Value & v) | ||||||
|         v.type = tList; |         v.type = tList; | ||||||
|         v.list.length = ATgetLength(es); |         v.list.length = ATgetLength(es); | ||||||
|         v.list.elems = allocValues(v.list.length); |         v.list.elems = allocValues(v.list.length); | ||||||
|         for (unsigned int n = 0; n < v.list.length; ++n, es = ATgetNext(es)) { |         for (unsigned int n = 0; n < v.list.length; ++n, es = ATgetNext(es)) | ||||||
|             v.list.elems[n].type = tThunk; |             mkThunk(v.list.elems[n], env, ATgetFirst(es)); | ||||||
|             v.list.elems[n].thunk.env = &env; |  | ||||||
|             v.list.elems[n].thunk.expr = ATgetFirst(es); |  | ||||||
|         } |  | ||||||
|         return; |         return; | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     if (matchOpEq(e, e1, e2)) { |     if (matchOpEq(e, e1, e2)) { | ||||||
|         Value v1; eval(env, e1, v1); |         Value v1; eval(env, e1, v1); | ||||||
|         Value v2; eval(env, e2, v2); |         Value v2; eval(env, e2, v2); | ||||||
|         setBoolValue(v, eqValues(v1, v2)); |         mkBool(v, eqValues(v1, v2)); | ||||||
|         return; |         return; | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     if (matchOpNEq(e, e1, e2)) { |     if (matchOpNEq(e, e1, e2)) { | ||||||
|         Value v1; eval(env, e1, v1); |         Value v1; eval(env, e1, v1); | ||||||
|         Value v2; eval(env, e2, v2); |         Value v2; eval(env, e2, v2); | ||||||
|         setBoolValue(v, !eqValues(v1, v2)); |         mkBool(v, !eqValues(v1, v2)); | ||||||
|         return; |         return; | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|  | @ -519,8 +518,7 @@ static void prim_add(Value * * args, Value & v) | ||||||
|     if (args[0]->type != tInt) throw TypeError("integer expected"); |     if (args[0]->type != tInt) throw TypeError("integer expected"); | ||||||
|     forceValue(*args[1]); |     forceValue(*args[1]); | ||||||
|     if (args[1]->type != tInt) throw TypeError("integer expected"); |     if (args[1]->type != tInt) throw TypeError("integer expected"); | ||||||
|     v.type = tInt; |     mkInt(v, args[0]->integer + args[1]->integer); | ||||||
|     v.integer = args[0]->integer + args[1]->integer; |  | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue