package object import "unicode" func NewEnclosedEnvironment(outer *Environment) *Environment { env := NewEnvironment() env.parent = outer return env } func NewEnvironment() *Environment { s := make(map[string]Object) return &Environment{store: s, parent: nil} } type Environment struct { store map[string]Object parent *Environment } // New creates a new copy of the environment with the current environment as parent func (e *Environment) New() *Environment { env := NewEnvironment() env.parent = e return env } func (e *Environment) Get(name string) (Object, bool) { obj, ok := e.store[name] if !ok && e.parent != nil { obj, ok = e.parent.Get(name) } return obj, ok } func (e *Environment) Set(name string, val Object) Object { e.store[name] = val return val } // ExportedHash returns a new Hash with the names and values of every publicly // exported binding in the environment. That is every binding that starts with a // capital letter. This is used by the module import system to wrap up the // evaluated module into an object. func (e *Environment) ExportedHash() *Hash { pairs := make(map[HashKey]HashPair) for k, v := range e.store { if unicode.IsUpper(rune(k[0])) { s := String{Value: k} pairs[s.Hash()] = HashPair{Key: s, Value: v} } } return &Hash{Pairs: pairs} }