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