1package main
2
3//-------------------------------------------------------------------------
4// scope
5//-------------------------------------------------------------------------
6
7type scope struct {
8	// the package name that this scope resides in
9	pkgname  string
10	parent   *scope // nil for universe scope
11	entities map[string]*decl
12}
13
14func new_named_scope(outer *scope, name string) *scope {
15	s := new_scope(outer)
16	s.pkgname = name
17	return s
18}
19
20func new_scope(outer *scope) *scope {
21	s := new(scope)
22	if outer != nil {
23		s.pkgname = outer.pkgname
24	}
25	s.parent = outer
26	s.entities = make(map[string]*decl)
27	return s
28}
29
30// returns: new, prev
31func advance_scope(s *scope) (*scope, *scope) {
32	if len(s.entities) == 0 {
33		return s, s.parent
34	}
35	return new_scope(s), s
36}
37
38// adds declaration or returns an existing one
39func (s *scope) add_named_decl(d *decl) *decl {
40	return s.add_decl(d.name, d)
41}
42
43func (s *scope) add_decl(name string, d *decl) *decl {
44	decl, ok := s.entities[name]
45	if !ok {
46		s.entities[name] = d
47		return d
48	}
49	return decl
50}
51
52func (s *scope) replace_decl(name string, d *decl) {
53	s.entities[name] = d
54}
55
56func (s *scope) merge_decl(d *decl) {
57	decl, ok := s.entities[d.name]
58	if !ok {
59		s.entities[d.name] = d
60	} else {
61		decl := decl.deep_copy()
62		decl.expand_or_replace(d)
63		s.entities[d.name] = decl
64	}
65}
66
67func (s *scope) lookup(name string) *decl {
68	decl, ok := s.entities[name]
69	if !ok {
70		if s.parent != nil {
71			return s.parent.lookup(name)
72		} else {
73			return nil
74		}
75	}
76	return decl
77}
78