* Refactoring: move variable uses to a separate class.

This commit is contained in:
Eelco Dolstra 2010-04-14 15:14:23 +00:00
parent 110d155778
commit 81de12bc8f
4 changed files with 31 additions and 35 deletions

View file

@ -236,24 +236,17 @@ void mkPath(Value & v, const char * s)
} }
Value * EvalState::lookupVar(Env * env, const Symbol & name) Value * EvalState::lookupVar(Env * env, const VarRef & var)
{ {
#if 0 for (unsigned int l = var.level; l; --l, env = env->up) ;
/* First look for a regular variable binding for `name'. */
Bindings::iterator i = env2->bindings.find(name); if (var.fromWith) {
if (i != env2->bindings.end()) return &i->second; Bindings::iterator j = env->values[0].attrs->find(var.name);
} if (j == env->values[0].attrs->end())
throwEvalError("undefined variable `%1%'", var.name);
/* Otherwise, look for a `with' attribute set containing `name'. return &j->second;
Inner `withs' take precedence (i.e. `with {x=1;}; with {x=2;}; } else
x' evaluates to 2). */ return &env->values[var.displ];
for (Env * env2 = env; env2; env2 = env2->up) {
Bindings::iterator i = env2->bindings.find(sWith);
if (i == env2->bindings.end()) continue;
Bindings::iterator j = i->second.attrs->find(name);
if (j != i->second.attrs->end()) return &j->second;
}
#endif
} }
@ -481,18 +474,9 @@ void ExprList::eval(EvalState & state, Env & env, Value & v)
void ExprVar::eval(EvalState & state, Env & env, Value & v) void ExprVar::eval(EvalState & state, Env & env, Value & v)
{ {
Env * env2 = &env; Value * v2 = state.lookupVar(&env, info);
for (unsigned int l = level; l; --l, env2 = env2->up) ; state.forceValue(*v2);
v = *v2;
if (fromWith) {
Bindings::iterator j = env2->values[0].attrs->find(name);
if (j == env2->values[0].attrs->end())
throwEvalError("undefined variable `%1%'", name);
v = j->second;
} else {
state.forceValue(env2->values[displ]);
v = env2->values[displ];
}
} }

View file

@ -238,7 +238,7 @@ private:
void addPrimOp(const string & name, void addPrimOp(const string & name,
unsigned int arity, PrimOp primOp); unsigned int arity, PrimOp primOp);
Value * lookupVar(Env * env, const Symbol & name); Value * lookupVar(Env * env, const VarRef & var);
friend class ExprVar; friend class ExprVar;
friend class ExprAttrs; friend class ExprAttrs;

View file

@ -38,7 +38,7 @@ void ExprPath::show(std::ostream & str)
void ExprVar::show(std::ostream & str) void ExprVar::show(std::ostream & str)
{ {
str << name; str << info.name;
} }
void ExprSelect::show(std::ostream & str) void ExprSelect::show(std::ostream & str)
@ -157,7 +157,7 @@ void ExprPath::bindVars(const StaticEnv & env)
{ {
} }
void ExprVar::bindVars(const StaticEnv & env) void VarRef::bind(const StaticEnv & env)
{ {
/* Check whether the variable appears in the environment. If so, /* Check whether the variable appears in the environment. If so,
set its level and displacement. */ set its level and displacement. */
@ -187,6 +187,11 @@ void ExprVar::bindVars(const StaticEnv & env)
this->level = withLevel; this->level = withLevel;
} }
void ExprVar::bindVars(const StaticEnv & env)
{
info.bind(env);
}
void ExprSelect::bindVars(const StaticEnv & env) void ExprSelect::bindVars(const StaticEnv & env)
{ {
e->bindVars(env); e->bindVars(env);

View file

@ -78,7 +78,7 @@ struct ExprPath : Expr
COMMON_METHODS COMMON_METHODS
}; };
struct ExprVar : Expr struct VarRef
{ {
Symbol name; Symbol name;
@ -94,8 +94,15 @@ struct ExprVar : Expr
levels up from the current one.*/ levels up from the current one.*/
unsigned int level; unsigned int level;
unsigned int displ; unsigned int displ;
ExprVar(const Symbol & name) : name(name) { }; VarRef(const Symbol & name) : name(name) { };
void bind(const StaticEnv & env);
};
struct ExprVar : Expr
{
VarRef info;
ExprVar(const Symbol & name) : info(name) { };
COMMON_METHODS COMMON_METHODS
}; };