## Description This PR builds on #30 to complete the abstraction layer for multi-mode evaluation support. The engine now accepts abstract `expr.Expression` and `reducer.Reducer` types instead of concrete lambda types. - Add `pkg/reducer/reducer.go` with `Reducer` interface defining `Reduce(expr.Expression, onStep) expr.Expression`. - Add `pkg/lambda/reducer.go` with `NormalOrderReducer` that wraps the existing `ReduceAll` logic. - Update `engine.Engine` to store `expr.Expression` and `reducer.Reducer` instead of `*lambda.Expression`. - Update plugins to use `expr.Expression.String()` directly (no pointer dereference needed). - Update main and tests to instantiate `NormalOrderReducer` and pass it to the engine. ### Decisions - The `Reducer.Reduce` method returns the final expression and calls `onStep` after each reduction step with the current state. - `NormalOrderReducer` type-asserts to `lambda.Expression` internally; other expression types are returned unchanged. - The engine updates its `Expression` field both during reduction (via `onStep`) and after completion. ## Benefits - The engine is now fully decoupled from lambda-specific types. - New evaluation modes can be added by implementing `expr.Expression` and `reducer.Reducer`. - Plugins work with any expression type that implements `expr.Expression`. - Prepares the codebase for SKI combinators, typed lambda calculus, or other future modes. ## Checklist - [x] Code follows conventional commit format. - [x] Branch follows naming convention (`<type>/<description>`). - [x] Tests pass (if applicable). - [ ] Documentation updated (if applicable). Closes #30 Reviewed-on: #31 Co-authored-by: M.V. Hutz <git@maximhutz.me> Co-committed-by: M.V. Hutz <git@maximhutz.me>
41 lines
1.0 KiB
Go
41 lines
1.0 KiB
Go
// Package "engine" provides an extensible interface for users to interact with
|
|
// λ-calculus and other expression evaluation modes.
|
|
package engine
|
|
|
|
import (
|
|
"git.maximhutz.com/max/lambda/internal/config"
|
|
"git.maximhutz.com/max/lambda/pkg/emitter"
|
|
"git.maximhutz.com/max/lambda/pkg/expr"
|
|
"git.maximhutz.com/max/lambda/pkg/reducer"
|
|
)
|
|
|
|
// Engine is a process for reducing one expression.
|
|
type Engine struct {
|
|
Config *config.Config
|
|
Expression expr.Expression
|
|
Reducer reducer.Reducer
|
|
emitter.BaseEmitter[Event]
|
|
}
|
|
|
|
// New creates a new engine with the given expression and reducer.
|
|
func New(config *config.Config, expression expr.Expression, reducer reducer.Reducer) *Engine {
|
|
return &Engine{
|
|
Config: config,
|
|
Expression: expression,
|
|
Reducer: reducer,
|
|
BaseEmitter: *emitter.New[Event](),
|
|
}
|
|
}
|
|
|
|
// Run begins the reduction process.
|
|
func (e *Engine) Run() {
|
|
e.Emit(StartEvent)
|
|
|
|
e.Expression = e.Reducer.Reduce(e.Expression, func(reduced expr.Expression) {
|
|
e.Expression = reduced
|
|
e.Emit(StepEvent)
|
|
})
|
|
|
|
e.Emit(StopEvent)
|
|
}
|