-
Notifications
You must be signed in to change notification settings - Fork 153
/
env.go
68 lines (60 loc) · 1.35 KB
/
env.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
package semantic
// Env is a type environment mapping identifiers in scope to their type schemes.
type Env struct {
parent *Env
m map[string]Scheme
}
func NewEnv() *Env {
return &Env{
m: make(map[string]Scheme),
}
}
// LocalLookup search for the identifier in the local scope only, it does not recurse to parents.
func (e *Env) LocalLookup(ident string) (Scheme, bool) {
s, ok := e.m[ident]
return s, ok
}
// Lookup searchs for the closest identifier in scope.
func (e *Env) Lookup(ident string) (Scheme, bool) {
s, ok := e.m[ident]
if ok {
return s, true
}
if e.parent != nil {
return e.parent.Lookup(ident)
}
return Scheme{}, false
}
// Set writes the scheme to the scope with the identifier.
func (e *Env) Set(ident string, s Scheme) {
e.m[ident] = s
}
// Nest creates a child env.
func (e *Env) Nest() *Env {
n := NewEnv()
n.parent = e
return n
}
// freeVars reports all free variables in the env.
func (e *Env) freeVars(c *Constraints) TvarSet {
var ftv TvarSet
if e == nil {
return ftv
}
for _, s := range e.m {
ftv = ftv.union(s.freeVars(c))
}
if e.parent != nil {
return ftv.union(e.parent.freeVars(c))
}
return ftv
}
// RangeSet updates the env recursing through parents.
func (e *Env) RangeSet(f func(k string, v Scheme) Scheme) {
for k, v := range e.m {
e.m[k] = f(k, v)
}
if e.parent != nil {
e.parent.RangeSet(f)
}
}