package edit

import (
	
	

	
	
	
	
	
)

var errValueShouldBeFn = errors.New("value should be function")

// A special Map that converts its key to ui.Key and ensures that its values
// satisfy eval.CallableValue.
type bindingsMap struct {
	hashmap.Map
}

var emptyBindingsMap = bindingsMap{vals.EmptyMap}

// Repr returns the representation of the binding table as if it were an
// ordinary map keyed by strings.
func ( bindingsMap) ( int) string {
	var  ui.Keys
	for  := .Map.Iterator(); .HasElem(); .Next() {
		,  := .Elem()
		 = append(, .(ui.Key))
	}
	sort.Sort()

	 := vals.NewMapReprBuilder()

	for ,  := range  {
		,  := .Map.Index()
		.WritePair(parse.Quote(.String()), +2, vals.Repr(, +2))
	}

	return .String()
}

// Index converts the index to ui.Key and uses the Index of the inner Map.
func ( bindingsMap) ( interface{}) (interface{}, error) {
	,  := toKey()
	if  != nil {
		return nil, 
	}
	return vals.Index(.Map, )
}

func ( bindingsMap) ( interface{}) bool {
	,  := .Map.Index()
	return 
}

func ( bindingsMap) ( ui.Key) eval.Callable {
	,  := .Map.Index()
	if ! {
		panic("get called when key not present")
	}
	return .(eval.Callable)
}

// Assoc converts the index to ui.Key, ensures that the value is CallableValue,
// uses the Assoc of the inner Map and converts the result to a BindingTable.
func ( bindingsMap) (,  interface{}) (interface{}, error) {
	,  := toKey()
	if  != nil {
		return nil, 
	}
	,  := .(eval.Callable)
	if ! {
		return nil, errValueShouldBeFn
	}
	 := .Map.Assoc(, )
	return bindingsMap{}, nil
}

// Dissoc converts the key to ui.Key and calls the Dissoc method of the inner
// map.
func ( bindingsMap) ( interface{}) interface{} {
	,  := toKey()
	if  != nil {
		// Key is invalid; dissoc is no-op.
		return 
	}
	return bindingsMap{.Map.Dissoc()}
}

func ( hashmap.Map) (bindingsMap, error) {
	 := vals.EmptyMap
	for  := .Iterator(); .HasElem(); .Next() {
		,  := .Elem()
		,  := .(eval.Callable)
		if ! {
			return emptyBindingsMap, errValueShouldBeFn
		}
		,  := toKey()
		if  != nil {
			return bindingsMap{}, 
		}
		 = .Assoc(, )
	}

	return bindingsMap{}, nil
}