// Package voc implements a generic vocabulary. Vocabularies may be nested // and are searched upwards using the parent vocabulary until this is nil. // Individual entries contain slices of values; the last item in a // slice is the current value. package voc type VocData[V any] map[string][]V type Vocabulary[V any] struct { parent *Vocabulary[V] data VocData[V] } func NewVoc[V any](parent *Vocabulary[V]) *Vocabulary[V] { return &Vocabulary[V]{ parent: parent, data: VocData[V]{}, } } func (voc *Vocabulary[V]) Parent() *Vocabulary[V] { return voc.parent } func (voc *Vocabulary[V]) Register(name string, it V) { vi, ok := voc.data[name] if ok { voc.data[name] = append(vi, it) } else { voc.data[name] = []V{it} } } func (voc *Vocabulary[V]) Lookup(name string) (V, bool) { vi, ok := voc.data[name] if ok { return vi[len(vi)-1], true } if voc.parent != nil { return voc.parent.Lookup(name) } var r V return r, false }