diff options
author | alandonovan <adonovan@google.com> | 2017-10-11 13:04:47 -0400 |
---|---|---|
committer | GitHub <noreply@github.com> | 2017-10-11 13:04:47 -0400 |
commit | 631f7b543a37d302fcfc62793b6e756faa6b34bb (patch) | |
tree | 56401b712a19a92485d64204f5ebb3f72c3a6189 /resolve | |
parent | 13998aa7464402849172959d67ded8527c7d9370 (diff) | |
download | starlark-go-631f7b543a37d302fcfc62793b6e756faa6b34bb.tar.gz |
resolve: clarify is{PredeclaredGlobal,Builtin} parameters (#11)
* resolve: clarify is{PredeclaredGlobal,Builtin} parameters
- document these parameters
- rename isBuiltin to isUniversal to avoid overloading 'builtin' (as in functions)
- export StringDict.Has method, and simplify.
Change-Id: I3b9396b879be960c08c3200fe1f6a2ac683d66e0
* resolve: fix typo
Change-Id: Id5b88f5dcf55ed4733b74990419ef7cfcacfae2c
Diffstat (limited to 'resolve')
-rw-r--r-- | resolve/resolve.go | 44 | ||||
-rw-r--r-- | resolve/resolve_test.go | 8 |
2 files changed, 32 insertions, 20 deletions
diff --git a/resolve/resolve.go b/resolve/resolve.go index 9ccf482..d0c818a 100644 --- a/resolve/resolve.go +++ b/resolve/resolve.go @@ -13,7 +13,7 @@ package resolve // All references to names are statically resolved. Names may be -// built-in (e.g. None, len), global and predeclared (e.g. glob in the +// universal (e.g. None, len), global and predeclared (e.g. glob in the // build language), global and user-defined (e.g. x=1 at toplevel), or // local to a function or module-level comprehension. The resolver maps // each local name to a small integer for fast and compact @@ -36,7 +36,7 @@ package resolve // As we finish resolving each function, we inspect all the uses within // that function and discard ones that were found to be local. The // remaining ones must be either free (local to some lexically enclosing -// function) or global/built-in, but we cannot tell which until we have +// function) or global/universal, but we cannot tell which until we have // finished inspecting the outermost enclosing function. At that point, // we can distinguish local from global names (and this is when Python // would compute free variables). @@ -90,8 +90,14 @@ var ( ) // File resolves the specified file. -func File(file *syntax.File, isPredeclaredGlobal, isBuiltin func(name string) bool) error { - r := newResolver(isPredeclaredGlobal, isBuiltin) +// +// The isPredeclaredGlobal and isUniversal predicates report whether a +// name is a pre-declared global identifier (in the current module) or a +// universal identifier (in every module). +// Typical values are globals.Has and Universe.Has, respectively, where +// globals is the current module's StringDict. +func File(file *syntax.File, isPredeclaredGlobal, isUniversal func(name string) bool) error { + r := newResolver(isPredeclaredGlobal, isUniversal) r.stmts(file.Stmts) r.env.resolveLocalUses() @@ -111,11 +117,17 @@ func File(file *syntax.File, isPredeclaredGlobal, isBuiltin func(name string) bo // Expr resolves the specified expression. // It returns the local variables bound within the expression. -func Expr(expr syntax.Expr, isPredeclaredGlobal, isBuiltin func(name string) bool) ([]*syntax.Ident, error) { - r := newResolver(isPredeclaredGlobal, isBuiltin) +// +// The isPredeclaredGlobal and isUniversal predicates report whether a +// name is a pre-declared global identifier (in the current module) or a +// universal identifier (in every module). +// Typical values are globals.Has and Universe.Has, respectively, where +// globals is the current module's StringDict. +func Expr(expr syntax.Expr, isPredeclaredGlobal, isUniversal func(name string) bool) ([]*syntax.Ident, error) { + r := newResolver(isPredeclaredGlobal, isUniversal) r.expr(expr) r.env.resolveLocalUses() - r.resolveNonLocalUses(r.env) // globals & builtins + r.resolveNonLocalUses(r.env) // globals & universals if len(r.errors) > 0 { return nil, r.errors } @@ -143,7 +155,7 @@ const ( Local // name is local to its function Free // name is local to some enclosing function Global // name is global to module - Builtin // name is universal (e.g. len) + Universal // name is universal (e.g. len) ) var scopeNames = [...]string{ @@ -151,16 +163,16 @@ var scopeNames = [...]string{ Local: "local", Free: "free", Global: "global", - Builtin: "builtin", + Universal: "universal", } func (scope Scope) String() string { return scopeNames[scope] } -func newResolver(isPredeclaredGlobal, isBuiltin func(name string) bool) *resolver { +func newResolver(isPredeclaredGlobal, isUniversal func(name string) bool) *resolver { return &resolver{ env: new(block), // module block isPredeclaredGlobal: isPredeclaredGlobal, - isBuiltin: isBuiltin, + isUniversal: isUniversal, globals: make(map[string]syntax.Position), } } @@ -181,8 +193,8 @@ type resolver struct { globals map[string]syntax.Position // These predicates report whether a name is - // a pre-declared global or built-in. - isPredeclaredGlobal, isBuiltin func(name string) bool + // a pre-declared global or universal. + isPredeclaredGlobal, isUniversal func(name string) bool loops int // number of enclosing for loops @@ -326,8 +338,8 @@ func (r *resolver) useGlobal(id *syntax.Ident) (scope Scope) { scope = Global // use of pre-declared global } else if id.Name == "PACKAGE_NAME" { scope = Global // nasty hack in Skylark spec; will go away (b/34240042). - } else if r.isBuiltin(id.Name) { - scope = Builtin // use of built-in + } else if r.isUniversal(id.Name) { + scope = Universal // use of universal name if !AllowFloat && id.Name == "float" { r.errorf(id.NamePos, doesnt+"support floating point") } @@ -737,7 +749,7 @@ func (r *resolver) lookupLexical(id *syntax.Ident, env *block) (bind binding) { // Is this the module block? if env.isModule() { - return binding{r.useGlobal(id), 0} // global or builtin, or not found + return binding{r.useGlobal(id), 0} // global or universal, or not found } // Defined in this block? diff --git a/resolve/resolve_test.go b/resolve/resolve_test.go index 6223515..11e953c 100644 --- a/resolve/resolve_test.go +++ b/resolve/resolve_test.go @@ -31,7 +31,7 @@ func TestResolve(t *testing.T) { resolve.AllowSet = option(chunk.Source, "set") resolve.AllowGlobalReassign = option(chunk.Source, "global_reassign") - if err := resolve.File(f, isPredeclaredGlobal, isBuiltin); err != nil { + if err := resolve.File(f, isPredeclaredGlobal, isUniversal); err != nil { for _, err := range err.(resolve.ErrorList) { chunk.GotError(int(err.Pos.Line), err.Msg) } @@ -50,7 +50,7 @@ func TestDefVarargsAndKwargsSet(t *testing.T) { if err != nil { t.Fatal(err) } - if err := resolve.File(file, isPredeclaredGlobal, isBuiltin); err != nil { + if err := resolve.File(file, isPredeclaredGlobal, isUniversal); err != nil { t.Fatal(err) } fn := file.Stmts[0].(*syntax.DefStmt) @@ -69,7 +69,7 @@ func TestLambdaVarargsAndKwargsSet(t *testing.T) { if err != nil { t.Fatal(err) } - if err := resolve.File(file, isPredeclaredGlobal, isBuiltin); err != nil { + if err := resolve.File(file, isPredeclaredGlobal, isUniversal); err != nil { t.Fatal(err) } lam := file.Stmts[0].(*syntax.AssignStmt).RHS.(*syntax.LambdaExpr) @@ -82,6 +82,6 @@ func TestLambdaVarargsAndKwargsSet(t *testing.T) { } func isPredeclaredGlobal(name string) bool { return strings.HasPrefix(name, "G") } -func isBuiltin(name string) bool { +func isUniversal(name string) bool { return strings.HasPrefix(name, "B") || name == "float" } |