Skip to content

Commit

Permalink
More position info
Browse files Browse the repository at this point in the history
  • Loading branch information
infinisil committed Dec 3, 2020
1 parent 53124da commit 5d50971
Show file tree
Hide file tree
Showing 4 changed files with 54 additions and 14 deletions.
11 changes: 7 additions & 4 deletions src/libexpr/eval-inline.hh
Original file line number Diff line number Diff line change
Expand Up @@ -37,8 +37,8 @@ void EvalState::forceValue(Value & v, const Pos & pos)
v.lazyBinOp->expr->evalLazyBinOp(*this, *v.lazyBinOp->env, v);
} else if (v.type == tValue) {
v.type = tBlackhole;
forceValue(*v.value, pos);
v = *v.value;
forceValue(*v.value.value, pos != noPos ? pos : *v.value.pos);
v = *v.value.value;
}
}

Expand Down Expand Up @@ -84,8 +84,11 @@ Attr * EvalState::evalValueAttr(Value & v, const Symbol & name, const Pos & pos)
} else if (v.type == tLazyBinOp) {
return v.lazyBinOp->expr->evalLazyBinOpAttr(*this, *v.lazyBinOp->env, name, v);
} else if (v.type == tValue) {
return evalValueAttr(*v.value, name, pos);
// TODO: Set v to v.value if it's in WHNF, for efficiency
Attr * result = evalValueAttr(*v.value.value, name, pos != noPos ? pos : *v.value.pos);
if (v.value.value->type != tLazyBinOp) {
v = *v.value.value;
}
return result;
} else {
return nullptr;
}
Expand Down
41 changes: 32 additions & 9 deletions src/libexpr/eval.cc
Original file line number Diff line number Diff line change
Expand Up @@ -960,7 +960,12 @@ void Expr::evalMinimal(EvalState & state, Env & env, Value & v)
void Expr::eval(EvalState & state, Env & env, Value & v)
{
evalMinimal(state, env, v);
state.forceValue(v, noPos);
state.forceValue(v, getPos());
}

Pos Expr::getPos()
{
return noPos;
}


Expand Down Expand Up @@ -1107,8 +1112,9 @@ void ExprList::evalMinimal(EvalState & state, Env & env, Value & v)
void ExprVar::evalMinimal(EvalState & state, Env & env, Value & v)
{
v.type = tValue;
v.value = state.lookupVar(&env, *this, false);
state.evalValueMinimal(*v.value, pos);
v.value.value = state.lookupVar(&env, *this, false);
v.value.pos = &pos;
state.evalValueMinimal(*v.value.value, pos);
}

static string showAttrPath(EvalState & state, Env & env, const AttrPath & attrPath)
Expand Down Expand Up @@ -1170,8 +1176,9 @@ void ExprSelect::evalMinimal(EvalState & state, Env & env, Value & v)
}

v.type = tValue;
v.value = vAttrs;
state.evalValueMinimal(*vAttrs, ( pos2 != NULL ? *pos2 : this->pos ));
v.value.value = vAttrs;
v.value.pos = pos2 != NULL ? pos2 : &pos;
state.evalValueMinimal(*vAttrs, *v.value.pos);
}


Expand Down Expand Up @@ -1517,15 +1524,23 @@ void ExprOpUpdate::evalMinimal(EvalState & state, Env & env, Value & v)
void ExprOpUpdate::evalLazyBinOp(EvalState & state, Env & env, Value & v)
{
if (v.lazyBinOp->rightBlackhole) {
throwEvalError(pos, "infinite recursion encountered while recursing into the right side of a lazy binop (evalLazyBinOp)");
Pos pos2 = e2->getPos();
if (pos2 == noPos) {
pos2 = pos;
}
throwEvalError(pos2, "infinite recursion encountered while recursing into the right side of a lazy binop (evalLazyBinOp)");
}
v.lazyBinOp->rightBlackhole = true;
state.forceAttrs(*v.lazyBinOp->right);
v.lazyBinOp->rightBlackhole = false;


if (v.lazyBinOp->leftBlackhole) {
throwEvalError(pos, "infinite recursion encountered while recursing into the left side of a lazy binop (evalLazyBinOp)");
Pos pos2 = e1->getPos();
if (pos2 == noPos) {
pos2 = pos;
}
throwEvalError(pos2, "infinite recursion encountered while recursing into the left side of a lazy binop (evalLazyBinOp)");
}
v.lazyBinOp->leftBlackhole = true;
state.forceAttrs(*v.lazyBinOp->left);
Expand All @@ -1545,7 +1560,11 @@ Attr * ExprOpUpdate::evalLazyBinOpAttr(EvalState & state, Env & env, const Symbo
*/

if (v.lazyBinOp->rightBlackhole) {
throwEvalError(pos, "infinite recursion encountered while recursing into the right side of a lazy binop");
Pos pos2 = e2->getPos();
if (pos2 == noPos) {
pos2 = pos;
}
throwEvalError(pos2, "infinite recursion encountered while recursing into the right side of a lazy binop");
}
v.lazyBinOp->rightBlackhole = true;
Attr * onRight = state.evalValueAttr(*v.lazyBinOp->right, name, pos);
Expand All @@ -1555,7 +1574,11 @@ Attr * ExprOpUpdate::evalLazyBinOpAttr(EvalState & state, Env & env, const Symbo
};

if (v.lazyBinOp->leftBlackhole) {
throwEvalError(pos, "infinite recursion encountered while recursing into the left side of a lazy binop");
Pos pos2 = e1->getPos();
if (pos2 == noPos) {
pos2 = pos;
}
throwEvalError(pos2, "infinite recursion encountered while recursing into the left side of a lazy binop");
}
v.lazyBinOp->leftBlackhole = true;
Attr * onLeft = state.evalValueAttr(*v.lazyBinOp->left, name, pos);
Expand Down
11 changes: 11 additions & 0 deletions src/libexpr/nixexpr.hh
Original file line number Diff line number Diff line change
Expand Up @@ -78,6 +78,7 @@ string showAttrPath(const AttrPath & attrPath);
struct Expr
{
virtual ~Expr() { };
virtual Pos getPos();
virtual void show(std::ostream & str) const;
virtual void bindVars(const StaticEnv & env);
virtual void evalMinimal(EvalState & state, Env & env, Value & v);
Expand Down Expand Up @@ -178,6 +179,7 @@ struct ExprVar : Expr
ExprVar(const Symbol & name) : name(name) { };
ExprVar(const Pos & pos, const Symbol & name) : pos(pos), name(name) { };
COMMON_METHODS
Pos getPos() { return pos; }
Value * noAllocationValue(EvalState & state, Env & env);
};

Expand All @@ -188,6 +190,7 @@ struct ExprSelect : Expr
AttrPath attrPath;
ExprSelect(const Pos & pos, Expr * e, const AttrPath & attrPath, Expr * def) : pos(pos), e(e), def(def), attrPath(attrPath) { };
ExprSelect(const Pos & pos, Expr * e, const Symbol & name) : pos(pos), e(e), def(0) { attrPath.push_back(AttrName(name)); };
Pos getPos() { return pos; }
COMMON_METHODS
};

Expand Down Expand Up @@ -267,6 +270,7 @@ struct ExprLambda : Expr
};
void setName(Symbol & name);
string showNamePos() const;
Pos getPos() { return pos; }
COMMON_METHODS
};

Expand All @@ -284,6 +288,7 @@ struct ExprWith : Expr
Expr * attrs, * body;
size_t prevWith;
ExprWith(const Pos & pos, Expr * attrs, Expr * body) : pos(pos), attrs(attrs), body(body) { };
Pos getPos() { return pos; }
COMMON_METHODS
};

Expand All @@ -292,6 +297,7 @@ struct ExprIf : Expr
Pos pos;
Expr * cond, * then, * else_;
ExprIf(const Pos & pos, Expr * cond, Expr * then, Expr * else_) : pos(pos), cond(cond), then(then), else_(else_) { };
Pos getPos() { return pos; }
COMMON_METHODS
};

Expand All @@ -300,6 +306,7 @@ struct ExprAssert : Expr
Pos pos;
Expr * cond, * body;
ExprAssert(const Pos & pos, Expr * cond, Expr * body) : pos(pos), cond(cond), body(body) { };
Pos getPos() { return pos; }
COMMON_METHODS
};

Expand All @@ -326,6 +333,7 @@ struct ExprOpNot : Expr
e1->bindVars(env); e2->bindVars(env); \
} \
void evalMinimal(EvalState & state, Env & env, Value & v); \
Pos getPos() { return pos; } \
};

MakeBinOp(ExprApp, "")
Expand Down Expand Up @@ -360,6 +368,7 @@ struct ExprOpUpdate : ExprLazyBinOp
Attr * evalLazyBinOpAttr(EvalState & state, Env & env, const Symbol & name, Value & v);

void updateAttrs(EvalState & state, const Value & v1, const Value & v2, Value & v);
Pos getPos() { return pos; }
};

struct ExprConcatStrings : Expr
Expand All @@ -369,13 +378,15 @@ struct ExprConcatStrings : Expr
vector<Expr *> * es;
ExprConcatStrings(const Pos & pos, bool forceString, vector<Expr *> * es)
: pos(pos), forceString(forceString), es(es) { };
Pos getPos() { return pos; }
COMMON_METHODS
};

struct ExprPos : Expr
{
Pos pos;
ExprPos(const Pos & pos) : pos(pos) { };
Pos getPos() { return pos; }
COMMON_METHODS
};

Expand Down
5 changes: 4 additions & 1 deletion src/libexpr/value.hh
Original file line number Diff line number Diff line change
Expand Up @@ -160,7 +160,10 @@ struct Value
} primOpApp;
ExternalValueBase * external;
NixFloat fpoint;
Value * value;
struct {
Value * value;
const Pos * pos;
} value;
};

bool isList() const
Expand Down

0 comments on commit 5d50971

Please sign in to comment.