tc_scope.mx raw

   1  package types
   2  
   3  
   4  type Scope struct {
   5  	parent *Scope
   6  	elems  map[string]Object
   7  }
   8  
   9  func NewScope(parent *Scope) (s *Scope) {
  10  	return &Scope{parent: parent, elems: map[string]Object{}}
  11  }
  12  
  13  func (s *Scope) Parent() (sv *Scope) { return s.parent }
  14  func (s *Scope) Len() (n int32) { return len(s.elems) }
  15  
  16  func (s *Scope) Release() {
  17  	s.elems = nil
  18  	s.parent = nil
  19  }
  20  
  21  func (s *Scope) Lookup(name string) (o Object) {
  22  	if s == nil { return nil }
  23  	return s.elems[name]
  24  }
  25  
  26  // LookupParent looks up name starting at s, walking the parent chain.
  27  // Returns the scope where it was found and the object, or nil, nil.
  28  func (s *Scope) LookupParent(name string) (found *Scope, obj Object) {
  29  	for sc := s; sc != nil; sc = sc.parent {
  30  		obj = sc.elems[name]
  31  		if obj != nil {
  32  			return sc, obj
  33  		}
  34  	}
  35  	return nil, nil
  36  }
  37  
  38  // Insert inserts obj into s. Returns an existing object with the same name
  39  // if there is one (caller must report the error).
  40  func (s *Scope) Insert(obj Object) (o Object) {
  41  	if s == nil { return nil }
  42  	if s.elems == nil {
  43  		s.elems = map[string]Object{}
  44  	}
  45  	name := ObjectName(obj)
  46  	if alt, ok := s.elems[name]; ok {
  47  		return alt
  48  	}
  49  	s.elems[name] = obj
  50  	return nil
  51  }
  52  
  53  func (s *Scope) Names() (ss []string) {
  54  	names := []string{:0:len(s.elems)}
  55  	for n := range s.elems {
  56  		push(names, n)
  57  	}
  58  	for i := 1; i < len(names); i++ {
  59  		for j := i; j > 0 && names[j] < names[j-1]; j-- {
  60  			names[j], names[j-1] = names[j-1], names[j]
  61  		}
  62  	}
  63  	return names
  64  }
  65