You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
types.Eval claims to let you evaluate an expression in a given scope, but it's much more restricted than it appears.
In particular, in the terminology of the spec, it appears that there is a *types.Scope for each block, and it represents the scope at the end of that block. If you want to use a scope in the middle of that block, I don't see any easy way to pass it in. For example, suppose I have this program:
{
const x = 1
{
const y = 2
/* MARK */
const x = 3
use(x)
use(y)
}
use(x)
}
I would like to evaluate "x" at the mark. If I walk the AST and the scope tree I can find out that the ** is in the inner block, but evaluating "x" in types.Scopes[that block] will give me 3. Since x has not yet been defined, the inner block's *Scope is not the right one. Maybe I could figure out a way to use an outer block to get the right "x".
But then suppose I want to evaluate "x + y" at the mark. I think that's impossible with the current API. My choices are to evaluate "x+y" at any closing brace of my choice. No closing brace gives me the value of x+y at the mark.
I think there's a simple fix. If there were an EvalPos that got both a *Scope and a token.Pos, then it could use the token.Pos of the identifiers it finds to filter out the ones that appear later in the scope than that position (in that case the search would walk outer scopes).
Similarly it might be nice to have a Scope.LookupPos that let you do the lookup at a given Pos within the scope.
The Eval* functionality was an afterthought - it indeed does only provide the state of scopes at the end of a block. I agree that providing position information as well should make it possible to use it as suggested.
types.Eval claims to let you evaluate an expression in a given scope, but it's much more restricted than it appears.
In particular, in the terminology of the spec, it appears that there is a *types.Scope for each block, and it represents the scope at the end of that block. If you want to use a scope in the middle of that block, I don't see any easy way to pass it in. For example, suppose I have this program:
I would like to evaluate "x" at the mark. If I walk the AST and the scope tree I can find out that the ** is in the inner block, but evaluating "x" in types.Scopes[that block] will give me 3. Since x has not yet been defined, the inner block's *Scope is not the right one. Maybe I could figure out a way to use an outer block to get the right "x".
But then suppose I want to evaluate "x + y" at the mark. I think that's impossible with the current API. My choices are to evaluate "x+y" at any closing brace of my choice. No closing brace gives me the value of x+y at the mark.
I think there's a simple fix. If there were an EvalPos that got both a *Scope and a token.Pos, then it could use the token.Pos of the identifiers it finds to filter out the ones that appear later in the scope than that position (in that case the search would walk outer scopes).
Similarly it might be nice to have a Scope.LookupPos that let you do the lookup at a given Pos within the scope.
@griesemer
The text was updated successfully, but these errors were encountered: