Skip to content

Commit

Permalink
Introduce Expr::evalAttr
Browse files Browse the repository at this point in the history
This is a version of Expr::eval that doesn't necessarily have to
evaluate the value into a non-thunk, while returning a specific
attribute

The evalAttr of expressions that evaluate to a subexpression should call
evalAttr on that subexpression, therefore bubbling up any potential
thunks
  • Loading branch information
infinisil committed Oct 19, 2020
1 parent 5ddfd1a commit e8fbaf6
Show file tree
Hide file tree
Showing 4 changed files with 320 additions and 6 deletions.
20 changes: 14 additions & 6 deletions src/libexpr/eval-inline.hh
Original file line number Diff line number Diff line change
Expand Up @@ -54,15 +54,23 @@ void EvalState::forceValue(Value & v, const Pos & pos)

Attr * EvalState::evalValueAttr(Value & v, const Symbol & name, const Pos & pos)
{
forceValue(v, pos);
if (v.type != tAttrs)
return nullptr;

Bindings::iterator j;
if ((j = v.attrs->find(name)) == v.attrs->end()) {
// TODO: Handle inf rec
if (v.type == tThunk) {
return v.thunk.expr->evalAttr(*this, *v.thunk.env, v, name);
}
else if (v.type == tApp) {
return callFunctionAttr(*v.app.left, *v.app.right, v, name, pos);
}
else if (v.type == tAttrs) {
Bindings::iterator j;
if ((j = v.attrs->find(name)) == v.attrs->end()) {
return nullptr;
}
return j;
} else {
return nullptr;
}
return j;
}

inline void EvalState::forceAttrs(Value & v)
Expand Down
Loading

0 comments on commit e8fbaf6

Please sign in to comment.