42 lines
950 B
Go
42 lines
950 B
Go
// 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
|
|
|
|
import (
|
|
"git.sr.ht/~cco/go-scopes/common/funky"
|
|
)
|
|
|
|
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]) 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) funky.Maybe[V] {
|
|
vi, ok := voc.data[name]
|
|
if ok {
|
|
return funky.Just(vi[len(vi)-1])
|
|
}
|
|
if voc.parent != nil {
|
|
return voc.parent.Lookup(name)
|
|
}
|
|
return funky.Nothing[V]()
|
|
}
|