package types type Scope struct { parent *Scope elems map[string]Object } func NewScope(parent *Scope) (s *Scope) { return &Scope{parent: parent, elems: map[string]Object{}} } func (s *Scope) Parent() (sv *Scope) { return s.parent } func (s *Scope) Len() (n int32) { return len(s.elems) } func (s *Scope) Release() { s.elems = nil s.parent = nil } func (s *Scope) Lookup(name string) (o Object) { if s == nil { return nil } return s.elems[name] } // LookupParent looks up name starting at s, walking the parent chain. // Returns the scope where it was found and the object, or nil, nil. func (s *Scope) LookupParent(name string) (found *Scope, obj Object) { for sc := s; sc != nil; sc = sc.parent { obj = sc.elems[name] if obj != nil { return sc, obj } } return nil, nil } // Insert inserts obj into s. Returns an existing object with the same name // if there is one (caller must report the error). func (s *Scope) Insert(obj Object) (o Object) { if s == nil { return nil } if s.elems == nil { s.elems = map[string]Object{} } name := ObjectName(obj) if alt, ok := s.elems[name]; ok { return alt } s.elems[name] = obj return nil } func (s *Scope) Names() (ss []string) { names := []string{:0:len(s.elems)} for n := range s.elems { push(names, n) } for i := 1; i < len(names); i++ { for j := i; j > 0 && names[j] < names[j-1]; j-- { names[j], names[j-1] = names[j-1], names[j] } } return names }