func (e *Environment) Get(name string) *NameInfo {
	for i := len(e.Blocks) - 1; i >= 0; i-- {
		if ret, ok := e.Blocks[i][name]; ok {
			return &ret
		}
	}
	return nil
}
Get resolves the name and resolves information about the binding (or nil if it's not defined).
package bzlenv
import (
	"github.com/bazelbuild/buildtools/build"
)
type ValueKind int
const (
	Builtin   ValueKind = iota  
	Imported                    
	Global                      
	Function                    
	Parameter                   
	Local                       
)
func (k ValueKind) String() string {
	switch k {
	case Builtin:
		return "builtin"
	case Imported:
		return "imported"
	case Global:
		return "global"
	case Function:
		return "function"
	case Parameter:
		return "parameter"
	case Local:
		return "local"
	default:
		panic(k)
	}
}
type NameInfo struct {
	ID         int     
	Name       string  
	Kind       ValueKind
	Definition build.Expr  
}
type block map[string]NameInfo
type Environment struct {
	Blocks   []block
	Function *build.DefStmt  
	nextID   int             
	Stack    []build.Expr    
}
func NewEnvironment() *Environment {
	sc := block{}
	return &Environment{[]block{sc}, nil, 0, []build.Expr{}}
}
func (e *Environment) enterBlock() {
	e.Blocks = append(e.Blocks, block{})
}
func (e *Environment) exitBlock() {
	if len(e.Blocks) < 1 {
		panic("no block to close")
	}
	e.Blocks = e.Blocks[:len(e.Blocks)-1]
}
func (e *Environment) currentBlock() block {
	return e.Blocks[len(e.Blocks)-1]
}
func (sc *block) declare(name string, kind ValueKind, definition build.Expr, id int) {
	(*sc)[name] = NameInfo{
		ID:         id,
		Name:       name,
		Definition: definition,
		Kind:       kind}
}