package object

func NewEnclosedEnvironment(outer *Environment) *Environment {
	env := NewEnvironment()
	env.outer = outer
	return env
}

func NewEnvironment() *Environment {
	s := make(map[string]Object)
	return &Environment{store: s, outer: nil}
}

type Environment struct {
	store map[string]Object
	outer *Environment
}

func (e *Environment) Get(name string) (Object, bool) {
	obj, ok := e.store[name]

	if !ok && e.outer != nil {
		obj, ok = e.outer.Get(name)
	}

	return obj, ok
}

func (e *Environment) Set(name string, val Object) Object {
	e.store[name] = val
	return val
}

func (e *Environment) GetLastFunctionName() string {
	functname := ""
	for key, val := range e.store {
		switch val.(type) {
		case *Function:
			functname = key
		}
	}
	return functname
}

func (e *Environment) GetLastScope() *Scope {
	var scope = &Scope{}
	for _, val := range e.store {
		switch ty := val.(type) {
		case *Scope:
			scope = ty
		}
	}
	return scope
}
