-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathenv.go
49 lines (41 loc) · 995 Bytes
/
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
package main
import (
"errors"
"fmt"
)
type SpecialForm = func(*Env, []Expr) (*Env, Expr, error)
type Env struct {
Parent *Env
Map map[ExprIdent]Expr
}
func newEnv(parent *Env, names []Expr, exprs []Expr) *Env {
if len(names) != len(exprs) {
panic(fmt.Sprintf("NEWLY INTRO'd BUG in go-lisp codebase: %d vs %d", len(names), len(exprs)))
}
ret := Env{Parent: parent, Map: make(map[ExprIdent]Expr, len(names))}
for i, bind := range names {
ret.Map[bind.(ExprIdent)] = exprs[i]
}
return &ret
}
func (me *Env) hasOwn(name ExprIdent) (ret bool) {
_, ret = me.Map[name]
return
}
func (me *Env) set(name ExprIdent, value Expr) {
me.Map[name] = value
}
func (me *Env) find(name ExprIdent) Expr {
found, ok := me.Map[name]
if (!ok) && (me.Parent != nil) {
return me.Parent.find(name)
}
return found
}
func (me *Env) get(name ExprIdent) (Expr, error) {
expr := me.find(name)
if expr == nil {
return nil, errors.New("undefined: " + string(name))
}
return expr, nil
}