From b259ab01257ae24523611fff435308bd1ecfc27f Mon Sep 17 00:00:00 2001 From: "M.V. Hutz" Date: Sat, 7 Feb 2026 20:46:33 -0500 Subject: [PATCH] docs: registry --- internal/registry/registry.go | 23 +++++++++++++++++++++++ pkg/convert/saccharine_to_lambda.go | 5 +++++ pkg/engine/engine.go | 10 ++++++++-- 3 files changed, 36 insertions(+), 2 deletions(-) diff --git a/internal/registry/registry.go b/internal/registry/registry.go index ecbf28f..d0e33ba 100644 --- a/internal/registry/registry.go +++ b/internal/registry/registry.go @@ -1,3 +1,5 @@ +// Package registry defines a structure to hold all available representations, +// engines, and conversions between them. package registry import ( @@ -6,12 +8,15 @@ import ( "maps" ) +// A Registry holds all representations, conversions, codecs, and engines +// available to the program. type Registry struct { codecs map[string]Codec converter *Converter engines map[string]Engine } +// New makes an empty registry. func New() *Registry { return &Registry{ codecs: map[string]Codec{}, @@ -20,6 +25,8 @@ func New() *Registry { } } +// GetEngine finds an engine based on its name. Returns an error if an engine +// with that name cannot be found. func (r Registry) GetEngine(name string) (Engine, error) { e, ok := r.engines[name] if !ok { @@ -29,10 +36,13 @@ func (r Registry) GetEngine(name string) (Engine, error) { return e, nil } +// ListEngines returns all available engines to the registry. func (r Registry) ListEngines() iter.Seq[Engine] { return maps.Values(r.engines) } +// GetDefaultEngine infers the preferred engine for a representation. Returns an +// error if one cannot be chosen. func (r *Registry) GetDefaultEngine(id string) (Engine, error) { for _, engine := range r.engines { if engine.InType() == id { @@ -45,6 +55,12 @@ func (r *Registry) GetDefaultEngine(id string) (Engine, error) { // return nil, fmt.Errorf("no engine for '%s'", id) } +// ConvertTo attempts to convert an expression of one type of representation to +// another. Returns the converted expression, otherwise an error. +// +// It can convert between any two types of representations, given there is a +// valid conversion path between them. It uses BFS to traverse a graph of +// conversion edges, and converts along the shortest path. func (r *Registry) ConvertTo(expr Expr, outType string) (Expr, error) { path, err := r.ConversionPath(expr.Repr(), outType) if err != nil { @@ -62,6 +78,8 @@ func (r *Registry) ConvertTo(expr Expr, outType string) (Expr, error) { return result, err } +// Marshal serializes an expression, given that representation has a codec. +// Returns an error if the representation is not registered, or it has no codec. func (r *Registry) Marshal(expr Expr) (string, error) { m, ok := r.codecs[expr.Repr()] if !ok { @@ -71,6 +89,8 @@ func (r *Registry) Marshal(expr Expr) (string, error) { return m.Encode(expr) } +// Unmarshal deserializes an expression. Returns an error if the representation +// or a codec for it is not registered. func (r *Registry) Unmarshal(s string, outType string) (Expr, error) { m, ok := r.codecs[outType] if !ok { @@ -94,6 +114,9 @@ func reverse[T any](list []T) []T { return reversed } +// ConversionPath attempts to find a set of valid conversions that (if applied) +// convert one representation to another. Returns an error if no path can be +// found. func (r *Registry) ConversionPath(from, to string) ([]Conversion, error) { backtrack := map[string]Conversion{} iteration := []string{from} diff --git a/pkg/convert/saccharine_to_lambda.go b/pkg/convert/saccharine_to_lambda.go index 73aeb0f..d8caa97 100644 --- a/pkg/convert/saccharine_to_lambda.go +++ b/pkg/convert/saccharine_to_lambda.go @@ -1,3 +1,5 @@ +// Package convert defined some standard conversions between various types of +// representations. package convert import ( @@ -124,10 +126,13 @@ func decodeExression(l lambda.Expression) saccharine.Expression { } } +// Lambda2Saccharine converts a pure lambda calculus expression into its +// Saccharine counterpart. func Lambda2Saccharine(l lambda.Expression) (saccharine.Expression, error) { return decodeExression(l), nil } +// Saccharine2Lambda desugars a saccharine expression into pure lambda calculus. func Saccharine2Lambda(s saccharine.Expression) (lambda.Expression, error) { return encodeExpression(s), nil } diff --git a/pkg/engine/engine.go b/pkg/engine/engine.go index 571b09e..9cbc307 100644 --- a/pkg/engine/engine.go +++ b/pkg/engine/engine.go @@ -2,11 +2,17 @@ // expression. package engine -// A Process handles the reduction of a +// A Process handles the reduction of a single expression. type Process[T any] interface { + // Get the current state of the process. + // Returns an error if the current state cannot be represented. Get() (T, error) + + // Step performs reduction(s) on the representation. If the number of steps + // defined is less than zero, it will perform as many reductions as + // possible. Returns whether a reduction was performed. Step(int) bool } -// An Engine is an object that handles +// An Engine is an function that generates reduction processes. type Engine[T any] = func(T) (Process[T], error)