aboutsummaryrefslogtreecommitdiff
path: root/internal
diff options
context:
space:
mode:
authoralandonovan <adonovan@google.com>2019-06-04 09:08:55 -0400
committerGitHub <noreply@github.com>2019-06-04 09:08:55 -0400
commit6ddc71c0ba77217b518c586dc8589d627c92ebfb (patch)
treecd9983e4142841e9869107c8132782758afa405c /internal
parent30ae18b8564f6cd89b550b19dbdae92e0ec5b0a3 (diff)
downloadstarlark-go-6ddc71c0ba77217b518c586dc8589d627c92ebfb.tar.gz
resolve: move resolver types to resolver package (#211)
The job of the resolver is to compute a binding for each identifer, the local and free variables for each function, and the locals and globals for each module. As a space optimization and for convenience, this information is saved in the syntax tree rather than in a side table. We have a choice between declaring these resolver data structures in the syntax package or the resolve package. Putting them in the syntax package, as we did prior to this change, allowed each Identifier, File, DefStmt, and LambdaExpr to depend directly on the resolver types, even though those types didn't really belong there. This change moves these types to the resolver package where they belong. The dependencies on the types are broken by using an interface{} in each case. (The values are are all pointers, so this does not induce new allocation.) Also, this change eliminates syntax.Function, which was a false abstraction of DefStmt and LambdaExpr. The two syntax nodes are now fully concrete; it is in the resolver that their shared concept of Function belongs. This is a breaking API change, but it should affect very few clients and be trivial to fix.
Diffstat (limited to 'internal')
-rw-r--r--internal/compile/compile.go14
1 files changed, 7 insertions, 7 deletions
diff --git a/internal/compile/compile.go b/internal/compile/compile.go
index 423ae0b..3a8d385 100644
--- a/internal/compile/compile.go
+++ b/internal/compile/compile.go
@@ -985,7 +985,7 @@ func (fcomp *fcomp) setPos(pos syntax.Position) {
// set emits code to store the top-of-stack value
// to the specified local, cell, or global variable.
func (fcomp *fcomp) set(id *syntax.Ident) {
- bind := id.Binding
+ bind := id.Binding.(*resolve.Binding)
switch bind.Scope {
case resolve.Local:
fcomp.emit1(SETLOCAL, uint32(bind.Index))
@@ -1002,7 +1002,7 @@ func (fcomp *fcomp) set(id *syntax.Ident) {
// lookup emits code to push the value of the specified variable.
func (fcomp *fcomp) lookup(id *syntax.Ident) {
- bind := id.Binding
+ bind := id.Binding.(*resolve.Binding)
if bind.Scope != resolve.Universal { // (universal lookup can't fail)
fcomp.setPos(id.NamePos)
}
@@ -1149,7 +1149,7 @@ func (fcomp *fcomp) stmt(stmt syntax.Stmt) {
}
case *syntax.DefStmt:
- fcomp.function(stmt.Def, stmt.Name.Name, &stmt.Function)
+ fcomp.function(stmt.Function.(*resolve.Function))
fcomp.set(stmt.Name)
case *syntax.ForStmt:
@@ -1428,7 +1428,7 @@ func (fcomp *fcomp) expr(e syntax.Expr) {
fcomp.call(e)
case *syntax.LambdaExpr:
- fcomp.function(e.Lambda, "lambda", &e.Function)
+ fcomp.function(e.Function.(*resolve.Function))
default:
start, _ := e.Span()
@@ -1777,9 +1777,9 @@ func (fcomp *fcomp) comprehension(comp *syntax.Comprehension, clauseIndex int) {
log.Fatalf("%s: unexpected comprehension clause %T", start, clause)
}
-func (fcomp *fcomp) function(pos syntax.Position, name string, f *syntax.Function) {
+func (fcomp *fcomp) function(f *resolve.Function) {
// Evaluation of the defaults may fail, so record the position.
- fcomp.setPos(pos)
+ fcomp.setPos(f.Pos)
// To reduce allocation, we emit a combined tuple
// for the defaults and the freevars.
@@ -1821,7 +1821,7 @@ func (fcomp *fcomp) function(pos syntax.Position, name string, f *syntax.Functio
fcomp.emit1(MAKETUPLE, uint32(ndefaults+len(f.FreeVars)))
- funcode := fcomp.pcomp.function(name, pos, f.Body, f.Locals, f.FreeVars)
+ funcode := fcomp.pcomp.function(f.Name, f.Pos, f.Body, f.Locals, f.FreeVars)
if debug {
// TODO(adonovan): do compilations sequentially not as a tree,