You cannot select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
68 lines
1.6 KiB
Go
68 lines
1.6 KiB
Go
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
|
|
}
|
|
|
|
// ancestor returns the environment at a given distance.
|
|
func (e *environment) ancestor(distance int) *environment {
|
|
env := e
|
|
for i := 0; i < distance; i++ {
|
|
env = env.enclosing
|
|
}
|
|
|
|
return env
|
|
}
|
|
|
|
// getAt gets the value of a variable at a given distance.
|
|
func (e *environment) getAt(distance int, name string) any {
|
|
return e.ancestor(distance).values[name]
|
|
}
|
|
|
|
// 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
|
|
}
|
|
|
|
// assignAt assigns a new value to a variable at a given distance.
|
|
func (e *environment) assignAt(distance int, name string, value any) {
|
|
e.ancestor(distance).values[name] = 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
|
|
}
|