docs: document remaining packages and simplify AST types #45

Merged
mvhutz merged 15 commits from docs/rest into main 2026-02-10 01:15:42 +00:00
3 changed files with 36 additions and 2 deletions
Showing only changes of commit b259ab0125 - Show all commits

View File

@@ -1,3 +1,5 @@
// Package registry defines a structure to hold all available representations,
// engines, and conversions between them.
package registry package registry
import ( import (
@@ -6,12 +8,15 @@ import (
"maps" "maps"
) )
// A Registry holds all representations, conversions, codecs, and engines
// available to the program.
type Registry struct { type Registry struct {
codecs map[string]Codec codecs map[string]Codec
converter *Converter converter *Converter
engines map[string]Engine engines map[string]Engine
} }
// New makes an empty registry.
func New() *Registry { func New() *Registry {
return &Registry{ return &Registry{
codecs: map[string]Codec{}, 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) { func (r Registry) GetEngine(name string) (Engine, error) {
e, ok := r.engines[name] e, ok := r.engines[name]
if !ok { if !ok {
@@ -29,10 +36,13 @@ func (r Registry) GetEngine(name string) (Engine, error) {
return e, nil return e, nil
} }
// ListEngines returns all available engines to the registry.
func (r Registry) ListEngines() iter.Seq[Engine] { func (r Registry) ListEngines() iter.Seq[Engine] {
return maps.Values(r.engines) 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) { func (r *Registry) GetDefaultEngine(id string) (Engine, error) {
for _, engine := range r.engines { for _, engine := range r.engines {
if engine.InType() == id { 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) // 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) { func (r *Registry) ConvertTo(expr Expr, outType string) (Expr, error) {
path, err := r.ConversionPath(expr.Repr(), outType) path, err := r.ConversionPath(expr.Repr(), outType)
if err != nil { if err != nil {
@@ -62,6 +78,8 @@ func (r *Registry) ConvertTo(expr Expr, outType string) (Expr, error) {
return result, err 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) { func (r *Registry) Marshal(expr Expr) (string, error) {
m, ok := r.codecs[expr.Repr()] m, ok := r.codecs[expr.Repr()]
if !ok { if !ok {
@@ -71,6 +89,8 @@ func (r *Registry) Marshal(expr Expr) (string, error) {
return m.Encode(expr) 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) { func (r *Registry) Unmarshal(s string, outType string) (Expr, error) {
m, ok := r.codecs[outType] m, ok := r.codecs[outType]
if !ok { if !ok {
@@ -94,6 +114,9 @@ func reverse[T any](list []T) []T {
return reversed 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) { func (r *Registry) ConversionPath(from, to string) ([]Conversion, error) {
backtrack := map[string]Conversion{} backtrack := map[string]Conversion{}
iteration := []string{from} iteration := []string{from}

View File

@@ -1,3 +1,5 @@
// Package convert defined some standard conversions between various types of
// representations.
package convert package convert
import ( 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) { func Lambda2Saccharine(l lambda.Expression) (saccharine.Expression, error) {
return decodeExression(l), nil return decodeExression(l), nil
} }
// Saccharine2Lambda desugars a saccharine expression into pure lambda calculus.
func Saccharine2Lambda(s saccharine.Expression) (lambda.Expression, error) { func Saccharine2Lambda(s saccharine.Expression) (lambda.Expression, error) {
return encodeExpression(s), nil return encodeExpression(s), nil
} }

View File

@@ -2,11 +2,17 @@
// expression. // expression.
package engine package engine
// A Process handles the reduction of a // A Process handles the reduction of a single expression.
type Process[T any] interface { 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) 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 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) type Engine[T any] = func(T) (Process[T], error)