github.com/google/skylark@v0.0.0-20181101142754-a5f7082aabed/resolve/resolve.go (about)

     1  // Copyright 2017 The Bazel Authors. All rights reserved.
     2  // Use of this source code is governed by a BSD-style
     3  // license that can be found in the LICENSE file.
     4  
     5  // Package resolve defines a name-resolution pass for Skylark abstract
     6  // syntax trees.
     7  //
     8  // The resolver sets the Locals and FreeVars arrays of each DefStmt and
     9  // the LocalIndex field of each syntax.Ident that refers to a local or
    10  // free variable.  It also sets the Locals array of a File for locals
    11  // bound by comprehensions outside any function.  Identifiers for global
    12  // variables do not get an index.
    13  package resolve
    14  
    15  // All references to names are statically resolved.  Names may be
    16  // predeclared, global, or local to a function or module-level comprehension.
    17  // The resolver maps each global name to a small integer and each local
    18  // name to a small integer; these integers enable a fast and compact
    19  // representation of globals and locals in the evaluator.
    20  //
    21  // As an optimization, the resolver classifies each predeclared name as
    22  // either universal (e.g. None, len) or per-module (e.g. glob in Bazel's
    23  // build language), enabling the evaluator to share the representation
    24  // of the universal environment across all modules.
    25  //
    26  // The lexical environment is a tree of blocks with the module block at
    27  // its root.  The module's child blocks may be of two kinds: functions
    28  // and comprehensions, and these may have further children of either
    29  // kind.
    30  //
    31  // Python-style resolution requires multiple passes because a name is
    32  // determined to be local to a function only if the function contains a
    33  // "binding" use of it; similarly, a name is determined be global (as
    34  // opposed to predeclared) if the module contains a binding use at the
    35  // top level. For both locals and globals, a non-binding use may
    36  // lexically precede the binding to which it is resolved.
    37  // In the first pass, we inspect each function, recording in
    38  // 'uses' each identifier and the environment block in which it occurs.
    39  // If a use of a name is binding, such as a function parameter or
    40  // assignment, we add the name to the block's bindings mapping and add a
    41  // local variable to the enclosing function.
    42  //
    43  // As we finish resolving each function, we inspect all the uses within
    44  // that function and discard ones that were found to be local. The
    45  // remaining ones must be either free (local to some lexically enclosing
    46  // function), or nonlocal (global or predeclared), but we cannot tell
    47  // which until we have finished inspecting the outermost enclosing
    48  // function. At that point, we can distinguish local from global names
    49  // (and this is when Python would compute free variables).
    50  //
    51  // However, Skylark additionally requires that all references to global
    52  // names are satisfied by some declaration in the current module;
    53  // Skylark permits a function to forward-reference a global that has not
    54  // been declared yet so long as it is declared before the end of the
    55  // module.  So, instead of re-resolving the unresolved references after
    56  // each top-level function, we defer this until the end of the module
    57  // and ensure that all such references are satisfied by some definition.
    58  //
    59  // At the end of the module, we visit each of the nested function blocks
    60  // in bottom-up order, doing a recursive lexical lookup for each
    61  // unresolved name.  If the name is found to be local to some enclosing
    62  // function, we must create a DefStmt.FreeVar (capture) parameter for
    63  // each intervening function.  We enter these synthetic bindings into
    64  // the bindings map so that we create at most one freevar per name.  If
    65  // the name was not local, we check that it was defined at module level.
    66  //
    67  // We resolve all uses of locals in the module (due to comprehensions)
    68  // in a similar way and compute the set of its local variables.
    69  //
    70  // Skylark enforces that all global names are assigned at most once on
    71  // all control flow paths by forbidding if/else statements and loops at
    72  // top level. A global may be used before it is defined, leading to a
    73  // dynamic error.
    74  //
    75  // TODO(adonovan): opt: reuse local slots once locals go out of scope.
    76  
    77  import (
    78  	"fmt"
    79  	"log"
    80  	"strings"
    81  
    82  	"github.com/google/skylark/syntax"
    83  )
    84  
    85  const debug = false
    86  const doesnt = "this Skylark dialect does not "
    87  
    88  // global options
    89  // These features are either not standard Skylark (yet), or deprecated
    90  // features of the BUILD language, so we put them behind flags.
    91  var (
    92  	AllowNestedDef      = false // allow def statements within function bodies
    93  	AllowLambda         = false // allow lambda expressions
    94  	AllowFloat          = false // allow floating point literals, the 'float' built-in, and x / y
    95  	AllowSet            = false // allow the 'set' built-in
    96  	AllowGlobalReassign = false // allow reassignment to globals declared in same file (deprecated)
    97  	AllowBitwise        = false // allow bitwise operations (&, |, ^, ~, <<, and >>)
    98  )
    99  
   100  // File resolves the specified file.
   101  //
   102  // The isPredeclared and isUniversal predicates report whether a name is
   103  // a pre-declared identifier (visible in the current module) or a
   104  // universal identifier (visible in every module).
   105  // Clients should typically pass predeclared.Has for the first and
   106  // skylark.Universe.Has for the second, where predeclared is the
   107  // module's StringDict of predeclared names and skylark.Universe is the
   108  // standard set of built-ins.
   109  // The isUniverse predicate is supplied a parameter to avoid a cyclic
   110  // dependency upon skylark.Universe, not because users should ever need
   111  // to redefine it.
   112  func File(file *syntax.File, isPredeclared, isUniversal func(name string) bool) error {
   113  	r := newResolver(isPredeclared, isUniversal)
   114  	r.stmts(file.Stmts)
   115  
   116  	r.env.resolveLocalUses()
   117  
   118  	// At the end of the module, resolve all non-local variable references,
   119  	// computing closures.
   120  	// Function bodies may contain forward references to later global declarations.
   121  	r.resolveNonLocalUses(r.env)
   122  
   123  	file.Locals = r.moduleLocals
   124  	file.Globals = r.moduleGlobals
   125  
   126  	if len(r.errors) > 0 {
   127  		return r.errors
   128  	}
   129  	return nil
   130  }
   131  
   132  // Expr resolves the specified expression.
   133  // It returns the local variables bound within the expression.
   134  //
   135  // The isPredeclared and isUniversal predicates behave as for the File function.
   136  func Expr(expr syntax.Expr, isPredeclared, isUniversal func(name string) bool) ([]*syntax.Ident, error) {
   137  	r := newResolver(isPredeclared, isUniversal)
   138  	r.expr(expr)
   139  	r.env.resolveLocalUses()
   140  	r.resolveNonLocalUses(r.env) // globals & universals
   141  	if len(r.errors) > 0 {
   142  		return nil, r.errors
   143  	}
   144  	return r.moduleLocals, nil
   145  }
   146  
   147  // An ErrorList is a non-empty list of resolver error messages.
   148  type ErrorList []Error // len > 0
   149  
   150  func (e ErrorList) Error() string { return e[0].Error() }
   151  
   152  // An Error describes the nature and position of a resolver error.
   153  type Error struct {
   154  	Pos syntax.Position
   155  	Msg string
   156  }
   157  
   158  func (e Error) Error() string { return e.Pos.String() + ": " + e.Msg }
   159  
   160  // The Scope of a syntax.Ident indicates what kind of scope it has.
   161  type Scope uint8
   162  
   163  const (
   164  	Undefined   Scope = iota // name is not defined
   165  	Local                    // name is local to its function
   166  	Free                     // name is local to some enclosing function
   167  	Global                   // name is global to module
   168  	Predeclared              // name is predeclared for this module (e.g. glob)
   169  	Universal                // name is universal (e.g. len)
   170  )
   171  
   172  var scopeNames = [...]string{
   173  	Undefined:   "undefined",
   174  	Local:       "local",
   175  	Free:        "free",
   176  	Global:      "global",
   177  	Predeclared: "predeclared",
   178  	Universal:   "universal",
   179  }
   180  
   181  func (scope Scope) String() string { return scopeNames[scope] }
   182  
   183  func newResolver(isPredeclared, isUniversal func(name string) bool) *resolver {
   184  	return &resolver{
   185  		env:           new(block), // module block
   186  		isPredeclared: isPredeclared,
   187  		isUniversal:   isUniversal,
   188  		globals:       make(map[string]*syntax.Ident),
   189  	}
   190  }
   191  
   192  type resolver struct {
   193  	// env is the current local environment:
   194  	// a linked list of blocks, innermost first.
   195  	// The tail of the list is the module block.
   196  	env *block
   197  
   198  	// moduleLocals contains the local variables of the module
   199  	// (due to comprehensions outside any function).
   200  	// moduleGlobals contains the global variables of the module.
   201  	moduleLocals  []*syntax.Ident
   202  	moduleGlobals []*syntax.Ident
   203  
   204  	// globals maps each global name in the module
   205  	// to its first binding occurrence.
   206  	globals map[string]*syntax.Ident
   207  
   208  	// These predicates report whether a name is
   209  	// pre-declared, either in this module or universally.
   210  	isPredeclared, isUniversal func(name string) bool
   211  
   212  	loops int // number of enclosing for loops
   213  
   214  	errors ErrorList
   215  }
   216  
   217  // container returns the innermost enclosing "container" block:
   218  // a function (function != nil) or module (function == nil).
   219  // Container blocks accumulate local variable bindings.
   220  func (r *resolver) container() *block {
   221  	for b := r.env; ; b = b.parent {
   222  		if b.function != nil || b.isModule() {
   223  			return b
   224  		}
   225  	}
   226  }
   227  
   228  func (r *resolver) push(b *block) {
   229  	r.env.children = append(r.env.children, b)
   230  	b.parent = r.env
   231  	r.env = b
   232  }
   233  
   234  func (r *resolver) pop() { r.env = r.env.parent }
   235  
   236  type block struct {
   237  	parent *block // nil for module block
   238  
   239  	// In the module (root) block, both these fields are nil.
   240  	function *syntax.Function      // only for function blocks
   241  	comp     *syntax.Comprehension // only for comprehension blocks
   242  
   243  	// bindings maps a name to its binding.
   244  	// A local binding has an index into its innermost enclosing container's locals array.
   245  	// A free binding has an index into its innermost enclosing function's freevars array.
   246  	bindings map[string]binding
   247  
   248  	// children records the child blocks of the current one.
   249  	children []*block
   250  
   251  	// uses records all identifiers seen in this container (function or module),
   252  	// and a reference to the environment in which they appear.
   253  	// As we leave each container block, we resolve them,
   254  	// so that only free and global ones remain.
   255  	// At the end of each top-level function we compute closures.
   256  	uses []use
   257  }
   258  
   259  type binding struct {
   260  	scope Scope
   261  	index int
   262  }
   263  
   264  func (b *block) isModule() bool { return b.parent == nil }
   265  
   266  func (b *block) bind(name string, bind binding) {
   267  	if b.bindings == nil {
   268  		b.bindings = make(map[string]binding)
   269  	}
   270  	b.bindings[name] = bind
   271  }
   272  
   273  func (b *block) String() string {
   274  	if b.function != nil {
   275  		return "function block at " + fmt.Sprint(b.function.Span())
   276  	}
   277  	if b.comp != nil {
   278  		return "comprehension block at " + fmt.Sprint(b.comp.Span())
   279  	}
   280  	return "module block"
   281  }
   282  
   283  func (r *resolver) errorf(posn syntax.Position, format string, args ...interface{}) {
   284  	r.errors = append(r.errors, Error{posn, fmt.Sprintf(format, args...)})
   285  }
   286  
   287  // A use records an identifier and the environment in which it appears.
   288  type use struct {
   289  	id  *syntax.Ident
   290  	env *block
   291  }
   292  
   293  // bind creates a binding for id in the current block,
   294  // if there is not one already, and reports an error if
   295  // a global was re-bound and allowRebind is false.
   296  // It returns whether a binding already existed.
   297  func (r *resolver) bind(id *syntax.Ident, allowRebind bool) bool {
   298  	// Binding outside any local (comprehension/function) block?
   299  	if r.env.isModule() {
   300  		id.Scope = uint8(Global)
   301  		prev, ok := r.globals[id.Name]
   302  		if ok {
   303  			// Global reassignments are permitted only if
   304  			// they are of the form x += y.  We can't tell
   305  			// statically whether it's a reassignment
   306  			// (e.g. int += int) or a mutation (list += list).
   307  			if !allowRebind && !AllowGlobalReassign {
   308  				r.errorf(id.NamePos, "cannot reassign global %s declared at %s", id.Name, prev.NamePos)
   309  			}
   310  			id.Index = prev.Index
   311  		} else {
   312  			// first global binding of this name
   313  			r.globals[id.Name] = id
   314  			id.Index = len(r.moduleGlobals)
   315  			r.moduleGlobals = append(r.moduleGlobals, id)
   316  		}
   317  		return ok
   318  	}
   319  
   320  	// Mark this name as local to current block.
   321  	// Assign it a new local (positive) index in the current container.
   322  	_, ok := r.env.bindings[id.Name]
   323  	if !ok {
   324  		var locals *[]*syntax.Ident
   325  		if fn := r.container().function; fn != nil {
   326  			locals = &fn.Locals
   327  		} else {
   328  			locals = &r.moduleLocals
   329  		}
   330  		r.env.bind(id.Name, binding{Local, len(*locals)})
   331  		*locals = append(*locals, id)
   332  	}
   333  
   334  	r.use(id)
   335  	return ok
   336  }
   337  
   338  func (r *resolver) use(id *syntax.Ident) {
   339  	b := r.container()
   340  	b.uses = append(b.uses, use{id, r.env})
   341  }
   342  
   343  func (r *resolver) useGlobal(id *syntax.Ident) binding {
   344  	var scope Scope
   345  	if prev, ok := r.globals[id.Name]; ok {
   346  		scope = Global // use of global declared by module
   347  		id.Index = prev.Index
   348  	} else if r.isPredeclared(id.Name) {
   349  		scope = Predeclared // use of pre-declared
   350  	} else if r.isUniversal(id.Name) {
   351  		scope = Universal // use of universal name
   352  		if !AllowFloat && id.Name == "float" {
   353  			r.errorf(id.NamePos, doesnt+"support floating point")
   354  		}
   355  		if !AllowSet && id.Name == "set" {
   356  			r.errorf(id.NamePos, doesnt+"support sets")
   357  		}
   358  	} else {
   359  		scope = Undefined
   360  		r.errorf(id.NamePos, "undefined: %s", id.Name)
   361  	}
   362  	id.Scope = uint8(scope)
   363  	return binding{scope, id.Index}
   364  }
   365  
   366  // resolveLocalUses is called when leaving a container (function/module)
   367  // block.  It resolves all uses of locals within that block.
   368  func (b *block) resolveLocalUses() {
   369  	unresolved := b.uses[:0]
   370  	for _, use := range b.uses {
   371  		if bind := lookupLocal(use); bind.scope == Local {
   372  			use.id.Scope = uint8(bind.scope)
   373  			use.id.Index = bind.index
   374  		} else {
   375  			unresolved = append(unresolved, use)
   376  		}
   377  	}
   378  	b.uses = unresolved
   379  }
   380  
   381  func (r *resolver) stmts(stmts []syntax.Stmt) {
   382  	for _, stmt := range stmts {
   383  		r.stmt(stmt)
   384  	}
   385  }
   386  
   387  func (r *resolver) stmt(stmt syntax.Stmt) {
   388  	switch stmt := stmt.(type) {
   389  	case *syntax.ExprStmt:
   390  		r.expr(stmt.X)
   391  
   392  	case *syntax.BranchStmt:
   393  		if r.loops == 0 && (stmt.Token == syntax.BREAK || stmt.Token == syntax.CONTINUE) {
   394  			r.errorf(stmt.TokenPos, "%s not in a loop", stmt.Token)
   395  		}
   396  
   397  	case *syntax.IfStmt:
   398  		if r.container().function == nil {
   399  			r.errorf(stmt.If, "if statement not within a function")
   400  		}
   401  		r.expr(stmt.Cond)
   402  		r.stmts(stmt.True)
   403  		r.stmts(stmt.False)
   404  
   405  	case *syntax.AssignStmt:
   406  		if !AllowBitwise {
   407  			switch stmt.Op {
   408  			case syntax.AMP_EQ, syntax.PIPE_EQ, syntax.CIRCUMFLEX_EQ, syntax.LTLT_EQ, syntax.GTGT_EQ:
   409  				r.errorf(stmt.OpPos, doesnt+"support bitwise operations")
   410  			}
   411  		}
   412  		r.expr(stmt.RHS)
   413  		// x += y may be a re-binding of a global variable,
   414  		// but we cannot tell without knowing the type of x.
   415  		// (If x is a list it's equivalent to x.extend(y).)
   416  		// The use is conservatively treated as binding,
   417  		// but we suppress the error if it's an already-bound global.
   418  		isAugmented := stmt.Op != syntax.EQ
   419  		r.assign(stmt.LHS, isAugmented)
   420  
   421  	case *syntax.DefStmt:
   422  		if !AllowNestedDef && r.container().function != nil {
   423  			r.errorf(stmt.Def, doesnt+"support nested def")
   424  		}
   425  		const allowRebind = false
   426  		r.bind(stmt.Name, allowRebind)
   427  		r.function(stmt.Def, stmt.Name.Name, &stmt.Function)
   428  
   429  	case *syntax.ForStmt:
   430  		if r.container().function == nil {
   431  			r.errorf(stmt.For, "for loop not within a function")
   432  		}
   433  		r.expr(stmt.X)
   434  		const allowRebind = false
   435  		r.assign(stmt.Vars, allowRebind)
   436  		r.loops++
   437  		r.stmts(stmt.Body)
   438  		r.loops--
   439  
   440  	case *syntax.ReturnStmt:
   441  		if r.container().function == nil {
   442  			r.errorf(stmt.Return, "return statement not within a function")
   443  		}
   444  		if stmt.Result != nil {
   445  			r.expr(stmt.Result)
   446  		}
   447  
   448  	case *syntax.LoadStmt:
   449  		if r.container().function != nil {
   450  			r.errorf(stmt.Load, "load statement within a function")
   451  		}
   452  
   453  		const allowRebind = false
   454  		for i, from := range stmt.From {
   455  			if from.Name == "" {
   456  				r.errorf(from.NamePos, "load: empty identifier")
   457  				continue
   458  			}
   459  			if from.Name[0] == '_' {
   460  				r.errorf(from.NamePos, "load: names with leading underscores are not exported: %s", from.Name)
   461  			}
   462  			r.bind(stmt.To[i], allowRebind)
   463  		}
   464  
   465  	default:
   466  		log.Fatalf("unexpected stmt %T", stmt)
   467  	}
   468  }
   469  
   470  func (r *resolver) assign(lhs syntax.Expr, isAugmented bool) {
   471  	switch lhs := lhs.(type) {
   472  	case *syntax.Ident:
   473  		// x = ...
   474  		allowRebind := isAugmented
   475  		r.bind(lhs, allowRebind)
   476  
   477  	case *syntax.IndexExpr:
   478  		// x[i] = ...
   479  		r.expr(lhs.X)
   480  		r.expr(lhs.Y)
   481  
   482  	case *syntax.DotExpr:
   483  		// x.f = ...
   484  		r.expr(lhs.X)
   485  
   486  	case *syntax.TupleExpr:
   487  		// (x, y) = ...
   488  		if len(lhs.List) == 0 {
   489  			r.errorf(syntax.Start(lhs), "can't assign to ()")
   490  		}
   491  		if isAugmented {
   492  			r.errorf(syntax.Start(lhs), "can't use tuple expression in augmented assignment")
   493  		}
   494  		for _, elem := range lhs.List {
   495  			r.assign(elem, isAugmented)
   496  		}
   497  
   498  	case *syntax.ListExpr:
   499  		// [x, y, z] = ...
   500  		if len(lhs.List) == 0 {
   501  			r.errorf(syntax.Start(lhs), "can't assign to []")
   502  		}
   503  		if isAugmented {
   504  			r.errorf(syntax.Start(lhs), "can't use list expression in augmented assignment")
   505  		}
   506  		for _, elem := range lhs.List {
   507  			r.assign(elem, isAugmented)
   508  		}
   509  
   510  	case *syntax.ParenExpr:
   511  		r.assign(lhs.X, isAugmented)
   512  
   513  	default:
   514  		name := strings.ToLower(strings.TrimPrefix(fmt.Sprintf("%T", lhs), "*syntax."))
   515  		r.errorf(syntax.Start(lhs), "can't assign to %s", name)
   516  	}
   517  }
   518  
   519  func (r *resolver) expr(e syntax.Expr) {
   520  	switch e := e.(type) {
   521  	case *syntax.Ident:
   522  		r.use(e)
   523  
   524  	case *syntax.Literal:
   525  		if !AllowFloat && e.Token == syntax.FLOAT {
   526  			r.errorf(e.TokenPos, doesnt+"support floating point")
   527  		}
   528  
   529  	case *syntax.ListExpr:
   530  		for _, x := range e.List {
   531  			r.expr(x)
   532  		}
   533  
   534  	case *syntax.CondExpr:
   535  		r.expr(e.Cond)
   536  		r.expr(e.True)
   537  		r.expr(e.False)
   538  
   539  	case *syntax.IndexExpr:
   540  		r.expr(e.X)
   541  		r.expr(e.Y)
   542  
   543  	case *syntax.DictEntry:
   544  		r.expr(e.Key)
   545  		r.expr(e.Value)
   546  
   547  	case *syntax.SliceExpr:
   548  		r.expr(e.X)
   549  		if e.Lo != nil {
   550  			r.expr(e.Lo)
   551  		}
   552  		if e.Hi != nil {
   553  			r.expr(e.Hi)
   554  		}
   555  		if e.Step != nil {
   556  			r.expr(e.Step)
   557  		}
   558  
   559  	case *syntax.Comprehension:
   560  		// The 'in' operand of the first clause (always a ForClause)
   561  		// is resolved in the outer block; consider: [x for x in x].
   562  		clause := e.Clauses[0].(*syntax.ForClause)
   563  		r.expr(clause.X)
   564  
   565  		// A list/dict comprehension defines a new lexical block.
   566  		// Locals defined within the block will be allotted
   567  		// distinct slots in the locals array of the innermost
   568  		// enclosing container (function/module) block.
   569  		r.push(&block{comp: e})
   570  
   571  		const allowRebind = false
   572  		r.assign(clause.Vars, allowRebind)
   573  
   574  		for _, clause := range e.Clauses[1:] {
   575  			switch clause := clause.(type) {
   576  			case *syntax.IfClause:
   577  				r.expr(clause.Cond)
   578  			case *syntax.ForClause:
   579  				r.assign(clause.Vars, allowRebind)
   580  				r.expr(clause.X)
   581  			}
   582  		}
   583  		r.expr(e.Body) // body may be *DictEntry
   584  		r.pop()
   585  
   586  	case *syntax.TupleExpr:
   587  		for _, x := range e.List {
   588  			r.expr(x)
   589  		}
   590  
   591  	case *syntax.DictExpr:
   592  		for _, entry := range e.List {
   593  			entry := entry.(*syntax.DictEntry)
   594  			r.expr(entry.Key)
   595  			r.expr(entry.Value)
   596  		}
   597  
   598  	case *syntax.UnaryExpr:
   599  		if !AllowBitwise && e.Op == syntax.TILDE {
   600  			r.errorf(e.OpPos, doesnt+"support bitwise operations")
   601  		}
   602  		r.expr(e.X)
   603  
   604  	case *syntax.BinaryExpr:
   605  		if !AllowFloat && e.Op == syntax.SLASH {
   606  			r.errorf(e.OpPos, doesnt+"support floating point (use //)")
   607  		}
   608  		if !AllowBitwise {
   609  			switch e.Op {
   610  			case syntax.AMP, syntax.PIPE, syntax.CIRCUMFLEX, syntax.LTLT, syntax.GTGT:
   611  				r.errorf(e.OpPos, doesnt+"support bitwise operations")
   612  			}
   613  		}
   614  		r.expr(e.X)
   615  		r.expr(e.Y)
   616  
   617  	case *syntax.DotExpr:
   618  		r.expr(e.X)
   619  		// ignore e.Name
   620  
   621  	case *syntax.CallExpr:
   622  		r.expr(e.Fn)
   623  		var seenVarargs, seenKwargs, seenNamed bool
   624  		for _, arg := range e.Args {
   625  			pos, _ := arg.Span()
   626  			if unop, ok := arg.(*syntax.UnaryExpr); ok && unop.Op == syntax.STARSTAR {
   627  				// **kwargs
   628  				if seenKwargs {
   629  					r.errorf(pos, "multiple **kwargs not allowed")
   630  				}
   631  				seenKwargs = true
   632  				r.expr(arg)
   633  			} else if ok && unop.Op == syntax.STAR {
   634  				// *args
   635  				if seenKwargs {
   636  					r.errorf(pos, "*args may not follow **kwargs")
   637  				} else if seenVarargs {
   638  					r.errorf(pos, "multiple *args not allowed")
   639  				}
   640  				seenVarargs = true
   641  				r.expr(arg)
   642  			} else if binop, ok := arg.(*syntax.BinaryExpr); ok && binop.Op == syntax.EQ {
   643  				// k=v
   644  				if seenKwargs {
   645  					r.errorf(pos, "argument may not follow **kwargs")
   646  				}
   647  				// ignore binop.X
   648  				r.expr(binop.Y)
   649  				seenNamed = true
   650  			} else {
   651  				// positional argument
   652  				if seenVarargs {
   653  					r.errorf(pos, "argument may not follow *args")
   654  				} else if seenKwargs {
   655  					r.errorf(pos, "argument may not follow **kwargs")
   656  				} else if seenNamed {
   657  					r.errorf(pos, "positional argument may not follow named")
   658  				}
   659  				r.expr(arg)
   660  			}
   661  		}
   662  
   663  	case *syntax.LambdaExpr:
   664  		if !AllowLambda {
   665  			r.errorf(e.Lambda, doesnt+"support lambda")
   666  		}
   667  		r.function(e.Lambda, "lambda", &e.Function)
   668  
   669  	case *syntax.ParenExpr:
   670  		r.expr(e.X)
   671  
   672  	default:
   673  		log.Fatalf("unexpected expr %T", e)
   674  	}
   675  }
   676  
   677  func (r *resolver) function(pos syntax.Position, name string, function *syntax.Function) {
   678  	// Resolve defaults in enclosing environment.
   679  	for _, param := range function.Params {
   680  		if binary, ok := param.(*syntax.BinaryExpr); ok {
   681  			r.expr(binary.Y)
   682  		}
   683  	}
   684  
   685  	// Enter function block.
   686  	b := &block{function: function}
   687  	r.push(b)
   688  
   689  	const allowRebind = false
   690  	var seenVarargs, seenKwargs, seenOptional bool
   691  	for _, param := range function.Params {
   692  		switch param := param.(type) {
   693  		case *syntax.Ident:
   694  			// e.g. x
   695  			if seenKwargs {
   696  				r.errorf(pos, "parameter may not follow **kwargs")
   697  			} else if seenVarargs {
   698  				r.errorf(pos, "parameter may not follow *args")
   699  			} else if seenOptional {
   700  				r.errorf(pos, "required parameter may not follow optional")
   701  			}
   702  			if r.bind(param, allowRebind) {
   703  				r.errorf(pos, "duplicate parameter: %s", param.Name)
   704  			}
   705  
   706  		case *syntax.BinaryExpr:
   707  			// e.g. y=dflt
   708  			if seenKwargs {
   709  				r.errorf(pos, "parameter may not follow **kwargs")
   710  			} else if seenVarargs {
   711  				r.errorf(pos, "parameter may not follow *args")
   712  			}
   713  			if id := param.X.(*syntax.Ident); r.bind(id, allowRebind) {
   714  				r.errorf(pos, "duplicate parameter: %s", id.Name)
   715  			}
   716  			seenOptional = true
   717  
   718  		case *syntax.UnaryExpr:
   719  			// *args or **kwargs
   720  			if param.Op == syntax.STAR {
   721  				if seenKwargs {
   722  					r.errorf(pos, "*args may not follow **kwargs")
   723  				} else if seenVarargs {
   724  					r.errorf(pos, "multiple *args not allowed")
   725  				}
   726  				seenVarargs = true
   727  			} else {
   728  				if seenKwargs {
   729  					r.errorf(pos, "multiple **kwargs not allowed")
   730  				}
   731  				seenKwargs = true
   732  			}
   733  			if id := param.X.(*syntax.Ident); r.bind(id, allowRebind) {
   734  				r.errorf(pos, "duplicate parameter: %s", id.Name)
   735  			}
   736  		}
   737  	}
   738  	function.HasVarargs = seenVarargs
   739  	function.HasKwargs = seenKwargs
   740  	r.stmts(function.Body)
   741  
   742  	// Resolve all uses of this function's local vars,
   743  	// and keep just the remaining uses of free/global vars.
   744  	b.resolveLocalUses()
   745  
   746  	// Leave function block.
   747  	r.pop()
   748  
   749  	// References within the function body to globals are not
   750  	// resolved until the end of the module.
   751  }
   752  
   753  func (r *resolver) resolveNonLocalUses(b *block) {
   754  	// First resolve inner blocks.
   755  	for _, child := range b.children {
   756  		r.resolveNonLocalUses(child)
   757  	}
   758  	for _, use := range b.uses {
   759  		bind := r.lookupLexical(use.id, use.env)
   760  		use.id.Scope = uint8(bind.scope)
   761  		use.id.Index = bind.index
   762  	}
   763  }
   764  
   765  // lookupLocal looks up an identifier within its immediately enclosing function.
   766  func lookupLocal(use use) binding {
   767  	for env := use.env; env != nil; env = env.parent {
   768  		if bind, ok := env.bindings[use.id.Name]; ok {
   769  			if bind.scope == Free {
   770  				// shouldn't exist till later
   771  				log.Fatalf("%s: internal error: %s, %d", use.id.NamePos, use.id.Name, bind)
   772  			}
   773  			return bind // found
   774  		}
   775  		if env.function != nil {
   776  			break
   777  		}
   778  	}
   779  	return binding{} // not found in this function
   780  }
   781  
   782  // lookupLexical looks up an identifier within its lexically enclosing environment.
   783  func (r *resolver) lookupLexical(id *syntax.Ident, env *block) (bind binding) {
   784  	if debug {
   785  		fmt.Printf("lookupLexical %s in %s = ...\n", id.Name, env)
   786  		defer func() { fmt.Printf("= %d\n", bind) }()
   787  	}
   788  
   789  	// Is this the module block?
   790  	if env.isModule() {
   791  		return r.useGlobal(id) // global, predeclared, or not found
   792  	}
   793  
   794  	// Defined in this block?
   795  	bind, ok := env.bindings[id.Name]
   796  	if !ok {
   797  		// Defined in parent block?
   798  		bind = r.lookupLexical(id, env.parent)
   799  		if env.function != nil && (bind.scope == Local || bind.scope == Free) {
   800  			// Found in parent block, which belongs to enclosing function.
   801  			id := &syntax.Ident{
   802  				Name:  id.Name,
   803  				Scope: uint8(bind.scope),
   804  				Index: bind.index,
   805  			}
   806  			bind.scope = Free
   807  			bind.index = len(env.function.FreeVars)
   808  			env.function.FreeVars = append(env.function.FreeVars, id)
   809  			if debug {
   810  				fmt.Printf("creating freevar %v in function at %s: %s\n",
   811  					len(env.function.FreeVars), fmt.Sprint(env.function.Span()), id.Name)
   812  			}
   813  		}
   814  
   815  		// Memoize, to avoid duplicate free vars
   816  		// and redundant global (failing) lookups.
   817  		env.bind(id.Name, bind)
   818  	}
   819  	return bind
   820  }