package interpreter // environment represents the environment in which the interpreter operates. type environment struct { values map[string]any enclosing *environment } // newEnvironment creates a new environment. // e is the enclosing environment and is nil for the global environment. func newEnvironment(e *environment) *environment { return &environment{values: make(map[string]any), enclosing: e} } // define defines a new variable in the environment. func (e *environment) define(name string, value any) { e.values[name] = value } // get gets the value of a variable in the environment. func (e *environment) get(name string) any { value, ok := e.values[name] if !ok { if e.enclosing != nil { return e.enclosing.get(name) } panic("Undefined variable '" + name + "'.") } return value } // assign assigns a new value to a variable in the environment. func (e *environment) assign(name string, value any) { _, ok := e.values[name] if !ok { if e.enclosing != nil { e.enclosing.assign(name, value) return } panic("Undefined variable '" + name + "'.") } e.values[name] = value }