refactor: move event system to reducer, remove engine package (#32)

## Description

This PR completes the MVC-inspired refactoring by moving the event system from the engine into the reducer.
The engine package is now removed entirely, as the reducer handles both reduction logic and lifecycle events.

- Add `pkg/reducer/events.go` with `StartEvent`, `StepEvent`, and `StopEvent`.
- Extend `Reducer` interface to embed `Emitter[Event]` and add `Expression()` method.
- Update `NormalOrderReducer` to embed `BaseEmitter` and emit lifecycle events during reduction.
- Update all plugins to attach to `Reducer` instead of `Engine`.
- Remove `internal/engine` package entirely.
- Add `Off()` method to `BaseEmitter` to complete the `Emitter` interface.
- Fix `Emitter.On` signature to use generic type `E` instead of `string`.

### Decisions

- The `Reducer` interface now combines reduction logic with event emission, making it the single orchestration point.
- Plugins attach directly to the reducer, simplifying the architecture.
- The `Expression()` method on `Reducer` provides access to current state for plugins.

## Benefits

- Simpler architecture with one fewer abstraction layer.
- Plugins are now mode-agnostic - they work with any `Reducer` implementation.
- Cleaner separation: reducers handle reduction, plugins observe via events.
- Easier to add new evaluation modes - just implement `Reducer` with embedded emitter.

## Checklist

- [x] Code follows conventional commit format.
- [x] Branch follows naming convention (`<type>/<description>`).
- [x] Tests pass (if applicable).
- [ ] Documentation updated (if applicable).

Reviewed-on: #32
Co-authored-by: M.V. Hutz <git@maximhutz.me>
Co-committed-by: M.V. Hutz <git@maximhutz.me>
This commit was merged in pull request #32.
This commit is contained in:
2026-01-17 00:27:36 +00:00
committed by Maxim Hutz
parent f8e1223463
commit 1974ad582f
14 changed files with 143 additions and 154 deletions

View File

@@ -6,8 +6,6 @@ import (
"strings"
"testing"
"git.maximhutz.com/max/lambda/internal/config"
"git.maximhutz.com/max/lambda/internal/engine"
"git.maximhutz.com/max/lambda/pkg/convert"
"git.maximhutz.com/max/lambda/pkg/lambda"
"git.maximhutz.com/max/lambda/pkg/saccharine"
@@ -31,22 +29,11 @@ func runSample(samplePath string) (string, error) {
// Compile expression to lambda calculus.
compiled := convert.SaccharineToLambda(ast)
// Create minimal config for benchmarking.
cfg := &config.Config{
Source: config.StringSource{Data: ""},
Destination: config.StdoutDestination{},
Profile: "",
Explanation: false,
Statistics: false,
Verbose: false,
}
// Create and run the reducer.
reducer := lambda.NewNormalOrderReducer(&compiled)
reducer.Reduce()
// Create and run the engine with normal order reducer.
reducer := lambda.NewNormalOrderReducer()
process := engine.New(cfg, compiled, reducer)
process.Run()
return process.Expression.String() + "\n", nil
return reducer.Expression().String() + "\n", nil
}
// Test that all samples produce expected output.