Add level / displacement types
This commit is contained in:
parent
81e7c40264
commit
bcf4780006
3 changed files with 16 additions and 13 deletions
|
@ -787,7 +787,7 @@ void mkPath(Value & v, const char * s)
|
||||||
|
|
||||||
inline Value * EvalState::lookupVar(Env * env, const ExprVar & var, bool noEval)
|
inline Value * EvalState::lookupVar(Env * env, const ExprVar & var, bool noEval)
|
||||||
{
|
{
|
||||||
for (size_t l = var.level; l; --l, env = env->up) ;
|
for (auto l = var.level; l; --l, env = env->up) ;
|
||||||
|
|
||||||
if (!var.fromWith) return env->values[var.displ];
|
if (!var.fromWith) return env->values[var.displ];
|
||||||
|
|
||||||
|
@ -1060,7 +1060,7 @@ void ExprAttrs::eval(EvalState & state, Env & env, Value & v)
|
||||||
/* The recursive attributes are evaluated in the new
|
/* The recursive attributes are evaluated in the new
|
||||||
environment, while the inherited attributes are evaluated
|
environment, while the inherited attributes are evaluated
|
||||||
in the original environment. */
|
in the original environment. */
|
||||||
size_t displ = 0;
|
Displacement displ = 0;
|
||||||
for (auto & i : attrs) {
|
for (auto & i : attrs) {
|
||||||
Value * vAttr;
|
Value * vAttr;
|
||||||
if (hasOverrides && !i.second.inherited) {
|
if (hasOverrides && !i.second.inherited) {
|
||||||
|
@ -1136,7 +1136,7 @@ void ExprLet::eval(EvalState & state, Env & env, Value & v)
|
||||||
/* The recursive attributes are evaluated in the new environment,
|
/* The recursive attributes are evaluated in the new environment,
|
||||||
while the inherited attributes are evaluated in the original
|
while the inherited attributes are evaluated in the original
|
||||||
environment. */
|
environment. */
|
||||||
size_t displ = 0;
|
Displacement displ = 0;
|
||||||
for (auto & i : attrs->attrs)
|
for (auto & i : attrs->attrs)
|
||||||
env2.values[displ++] = i.second.e->maybeThunk(state, i.second.inherited ? env : env2);
|
env2.values[displ++] = i.second.e->maybeThunk(state, i.second.inherited ? env : env2);
|
||||||
|
|
||||||
|
@ -1283,7 +1283,7 @@ void EvalState::callFunction(Value & fun, size_t nrArgs, Value * * args, Value &
|
||||||
Env & env2(allocEnv(size));
|
Env & env2(allocEnv(size));
|
||||||
env2.up = vCur.lambda.env;
|
env2.up = vCur.lambda.env;
|
||||||
|
|
||||||
size_t displ = 0;
|
Displacement displ = 0;
|
||||||
|
|
||||||
if (!lambda.hasFormals())
|
if (!lambda.hasFormals())
|
||||||
env2.values[displ++] = args[0];
|
env2.values[displ++] = args[0];
|
||||||
|
|
|
@ -273,7 +273,7 @@ void ExprVar::bindVars(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. */
|
||||||
const StaticEnv * curEnv;
|
const StaticEnv * curEnv;
|
||||||
unsigned int level;
|
Level level;
|
||||||
int withLevel = -1;
|
int withLevel = -1;
|
||||||
for (curEnv = &env, level = 0; curEnv; curEnv = curEnv->up, level++) {
|
for (curEnv = &env, level = 0; curEnv; curEnv = curEnv->up, level++) {
|
||||||
if (curEnv->isWith) {
|
if (curEnv->isWith) {
|
||||||
|
@ -326,7 +326,7 @@ void ExprAttrs::bindVars(const StaticEnv & env)
|
||||||
if (recursive) {
|
if (recursive) {
|
||||||
dynamicEnv = &newEnv;
|
dynamicEnv = &newEnv;
|
||||||
|
|
||||||
unsigned int displ = 0;
|
Displacement displ = 0;
|
||||||
for (auto & i : attrs)
|
for (auto & i : attrs)
|
||||||
newEnv.vars.emplace_back(i.first, i.second.displ = displ++);
|
newEnv.vars.emplace_back(i.first, i.second.displ = displ++);
|
||||||
|
|
||||||
|
@ -359,7 +359,7 @@ void ExprLambda::bindVars(const StaticEnv & env)
|
||||||
(hasFormals() ? formals->formals.size() : 0) +
|
(hasFormals() ? formals->formals.size() : 0) +
|
||||||
(arg.empty() ? 0 : 1));
|
(arg.empty() ? 0 : 1));
|
||||||
|
|
||||||
unsigned int displ = 0;
|
Displacement displ = 0;
|
||||||
|
|
||||||
if (!arg.empty()) newEnv.vars.emplace_back(arg, displ++);
|
if (!arg.empty()) newEnv.vars.emplace_back(arg, displ++);
|
||||||
|
|
||||||
|
@ -387,7 +387,7 @@ void ExprLet::bindVars(const StaticEnv & env)
|
||||||
{
|
{
|
||||||
StaticEnv newEnv(false, &env, attrs->attrs.size());
|
StaticEnv newEnv(false, &env, attrs->attrs.size());
|
||||||
|
|
||||||
unsigned int displ = 0;
|
Displacement displ = 0;
|
||||||
for (auto & i : attrs->attrs)
|
for (auto & i : attrs->attrs)
|
||||||
newEnv.vars.emplace_back(i.first, i.second.displ = displ++);
|
newEnv.vars.emplace_back(i.first, i.second.displ = displ++);
|
||||||
|
|
||||||
|
@ -405,7 +405,7 @@ void ExprWith::bindVars(const StaticEnv & env)
|
||||||
level so that `lookupVar' can look up variables in the previous
|
level so that `lookupVar' can look up variables in the previous
|
||||||
`with' if this one doesn't contain the desired attribute. */
|
`with' if this one doesn't contain the desired attribute. */
|
||||||
const StaticEnv * curEnv;
|
const StaticEnv * curEnv;
|
||||||
unsigned int level;
|
Level level;
|
||||||
prevWith = 0;
|
prevWith = 0;
|
||||||
for (curEnv = &env, level = 1; curEnv; curEnv = curEnv->up, level++)
|
for (curEnv = &env, level = 1; curEnv; curEnv = curEnv->up, level++)
|
||||||
if (curEnv->isWith) {
|
if (curEnv->isWith) {
|
||||||
|
|
|
@ -133,6 +133,9 @@ struct ExprPath : Expr
|
||||||
Value * maybeThunk(EvalState & state, Env & env);
|
Value * maybeThunk(EvalState & state, Env & env);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
typedef uint32_t Level;
|
||||||
|
typedef uint32_t Displacement;
|
||||||
|
|
||||||
struct ExprVar : Expr
|
struct ExprVar : Expr
|
||||||
{
|
{
|
||||||
Pos pos;
|
Pos pos;
|
||||||
|
@ -148,8 +151,8 @@ struct ExprVar : Expr
|
||||||
value is obtained by getting the attribute named `name' from
|
value is obtained by getting the attribute named `name' from
|
||||||
the set stored in the environment that is `level' levels up
|
the set stored in the environment that is `level' levels up
|
||||||
from the current one.*/
|
from the current one.*/
|
||||||
unsigned int level;
|
Level level;
|
||||||
unsigned int displ;
|
Displacement displ;
|
||||||
|
|
||||||
ExprVar(const Symbol & name) : name(name) { };
|
ExprVar(const Symbol & name) : name(name) { };
|
||||||
ExprVar(const Pos & pos, const Symbol & name) : pos(pos), name(name) { };
|
ExprVar(const Pos & pos, const Symbol & name) : pos(pos), name(name) { };
|
||||||
|
@ -183,7 +186,7 @@ struct ExprAttrs : Expr
|
||||||
bool inherited;
|
bool inherited;
|
||||||
Expr * e;
|
Expr * e;
|
||||||
Pos pos;
|
Pos pos;
|
||||||
unsigned int displ; // displacement
|
Displacement displ; // displacement
|
||||||
AttrDef(Expr * e, const Pos & pos, bool inherited=false)
|
AttrDef(Expr * e, const Pos & pos, bool inherited=false)
|
||||||
: inherited(inherited), e(e), pos(pos) { };
|
: inherited(inherited), e(e), pos(pos) { };
|
||||||
AttrDef() { };
|
AttrDef() { };
|
||||||
|
@ -352,7 +355,7 @@ struct StaticEnv
|
||||||
const StaticEnv * up;
|
const StaticEnv * up;
|
||||||
|
|
||||||
// Note: these must be in sorted order.
|
// Note: these must be in sorted order.
|
||||||
typedef std::vector<std::pair<Symbol, unsigned int>> Vars;
|
typedef std::vector<std::pair<Symbol, Displacement>> Vars;
|
||||||
Vars vars;
|
Vars vars;
|
||||||
|
|
||||||
StaticEnv(bool isWith, const StaticEnv * up, size_t expectedSize = 0) : isWith(isWith), up(up) {
|
StaticEnv(bool isWith, const StaticEnv * up, size_t expectedSize = 0) : isWith(isWith), up(up) {
|
||||||
|
|
Loading…
Reference in a new issue