diff --git a/cmd/lambda/lambda.go b/cmd/lambda/lambda.go index 2276c3f..0652123 100644 --- a/cmd/lambda/lambda.go +++ b/cmd/lambda/lambda.go @@ -36,14 +36,15 @@ func main() { engine, err := r.GetDefaultEngine("lambda") cli.HandleError(err) - err = engine.Set(compiled) + process := engine.Load() + err = process.Set(compiled) cli.HandleError(err) // Run reduction. - for engine.Step(1) { + for process.Step(1) { } // Return the final reduced result. - result, err := engine.Get() + result, err := process.Get() cli.HandleError(err) output, err := r.Marshal(result) diff --git a/cmd/lambda/registry.go b/cmd/lambda/registry.go index 88fba6f..5603971 100644 --- a/cmd/lambda/registry.go +++ b/cmd/lambda/registry.go @@ -13,14 +13,14 @@ func GetRegistry() *registry.Registry { r := registry.New() // Codecs - r.AddConversions(cli.ConvertCodec(convert.Saccharine2Lambda{}, "saccharine", "lambda")...) + r.MustAddConversions(cli.ConvertCodec(convert.Saccharine2Lambda{}, "saccharine", "lambda")...) // Engines - r.AddEngine(cli.ConvertEngine(&normalorder.Engine{}, "normalorder", "lambda")) + r.MustAddEngine(cli.ConvertEngine(normalorder.Engine{}, "normalorder", "lambda")) // Marshalers - r.AddMarshaler(cli.ConvertMarshaler(lambda.Marshaler{}, "lambda")) - r.AddMarshaler(cli.ConvertMarshaler(saccharine.Marshaler{}, "saccharine")) + r.MustAddMarshaler(cli.ConvertMarshaler(lambda.Marshaler{}, "lambda")) + r.MustAddMarshaler(cli.ConvertMarshaler(saccharine.Marshaler{}, "saccharine")) return r } diff --git a/internal/cli/engine.go b/internal/cli/engine.go index f0141cd..15f1618 100644 --- a/internal/cli/engine.go +++ b/internal/cli/engine.go @@ -1,14 +1,9 @@ package cli -import ( - "fmt" - - "git.maximhutz.com/max/lambda/pkg/engine" -) +import "git.maximhutz.com/max/lambda/pkg/engine" type Engine interface { - engine.Engine[Repr] - + Load() Process Name() string InType() string } @@ -19,31 +14,14 @@ type convertedEngine[T any] struct { inType string } -func (b convertedEngine[T]) InType() string { return b.inType } +func (e convertedEngine[T]) InType() string { return e.inType } -func (b convertedEngine[T]) Name() string { return b.name } +func (e convertedEngine[T]) Name() string { return e.name } -func (b convertedEngine[T]) Get() (Repr, error) { - s, err := b.engine.Get() - if err != nil { - return nil, err - } - - return NewRepr(b.inType, s), nil +func (e convertedEngine[T]) Load() Process { + return convertedProcess[T]{e.engine.Load(), e.inType} } -func (b convertedEngine[T]) Set(r Repr) error { - if t, ok := r.Data().(T); ok { - return b.engine.Set(t) - } - - return fmt.Errorf("Incorrent format '%s' for engine '%s'.", r.Id(), b.inType) -} - -func (b convertedEngine[T]) Step(i int) bool { - return b.engine.Step(i) -} - -func ConvertEngine[T any](e engine.Engine[T], name string, inType string) Engine { - return convertedEngine[T]{e, name, inType} +func ConvertEngine[T any](e engine.Engine[T], name, inType string) Engine { + return &convertedEngine[T]{e, name, inType} } diff --git a/internal/cli/process.go b/internal/cli/process.go new file mode 100644 index 0000000..f3445f7 --- /dev/null +++ b/internal/cli/process.go @@ -0,0 +1,41 @@ +package cli + +import ( + "fmt" + + "git.maximhutz.com/max/lambda/pkg/engine" +) + +type Process interface { + engine.Process[Repr] + + InType() string +} + +type convertedProcess[T any] struct { + process engine.Process[T] + inType string +} + +func (e convertedProcess[T]) InType() string { return e.inType } + +func (b convertedProcess[T]) Get() (Repr, error) { + s, err := b.process.Get() + if err != nil { + return nil, err + } + + return NewRepr(b.inType, s), nil +} + +func (b convertedProcess[T]) Set(r Repr) error { + if t, ok := r.Data().(T); ok { + return b.process.Set(t) + } + + return fmt.Errorf("Incorrent format '%s' for engine '%s'.", r.Id(), b.inType) +} + +func (b convertedProcess[T]) Step(i int) bool { + return b.process.Step(i) +} diff --git a/internal/registry/registry.go b/internal/registry/registry.go index 624023a..e47d942 100644 --- a/internal/registry/registry.go +++ b/internal/registry/registry.go @@ -27,6 +27,11 @@ func (r *Registry) AddConversions(conversions ...cli.Conversion) error { return nil } +func (r *Registry) MustAddConversions(conversions ...cli.Conversion) { + if err := r.AddConversions(conversions...); err != nil { + panic(err) + } +} func (r *Registry) AddMarshaler(c cli.Marshaler) error { if _, ok := r.marshalers[c.InType()]; ok { @@ -37,6 +42,12 @@ func (r *Registry) AddMarshaler(c cli.Marshaler) error { return nil } +func (r *Registry) MustAddMarshaler(c cli.Marshaler) { + if err := r.AddMarshaler(c); err != nil { + panic(err) + } +} + func (r *Registry) AddEngine(e cli.Engine) error { if _, ok := r.engines[e.Name()]; ok { return fmt.Errorf("engine '%s' already registered", e.Name()) @@ -46,6 +57,12 @@ func (r *Registry) AddEngine(e cli.Engine) error { return nil } +func (r *Registry) MustAddEngine(e cli.Engine) { + if err := r.AddEngine(e); err != nil { + panic(err) + } +} + func (r *Registry) GetEngine(name string) (cli.Engine, error) { e, ok := r.engines[name] if !ok { diff --git a/pkg/engine/engine.go b/pkg/engine/engine.go index 22f716d..0fcebf3 100644 --- a/pkg/engine/engine.go +++ b/pkg/engine/engine.go @@ -1,6 +1,10 @@ package engine type Engine[T any] interface { + Load() Process[T] +} + +type Process[T any] interface { Get() (T, error) Set(T) error Step(int) bool diff --git a/pkg/engine/normalorder/engine.go b/pkg/engine/normalorder/engine.go index 2a09e51..fcdd362 100644 --- a/pkg/engine/normalorder/engine.go +++ b/pkg/engine/normalorder/engine.go @@ -5,20 +5,20 @@ import ( "git.maximhutz.com/max/lambda/pkg/lambda" ) -type Engine struct { +type Process struct { expr lambda.Expression } -func (e Engine) Get() (lambda.Expression, error) { +func (e Process) Get() (lambda.Expression, error) { return e.expr, nil } -func (e *Engine) Set(l lambda.Expression) error { +func (e *Process) Set(l lambda.Expression) error { e.expr = l return nil } -func (e *Engine) Step(i int) bool { +func (e *Process) Step(i int) bool { for range i { next, reduced := ReduceOnce(e.expr) if !reduced { @@ -31,4 +31,12 @@ func (e *Engine) Step(i int) bool { return true } +type Engine struct { +} + +func (e Engine) Load() engine.Process[lambda.Expression] { + return &Process{} +} + +var _ engine.Process[lambda.Expression] = (*Process)(nil) var _ engine.Engine[lambda.Expression] = (*Engine)(nil)