diff --git a/cmd/lambda/lambda.go b/cmd/lambda/lambda.go index eade9ff..050c727 100644 --- a/cmd/lambda/lambda.go +++ b/cmd/lambda/lambda.go @@ -8,7 +8,6 @@ import ( "git.maximhutz.com/max/lambda/internal/engine" "git.maximhutz.com/max/lambda/internal/plugins" "git.maximhutz.com/max/lambda/pkg/convert" - "git.maximhutz.com/max/lambda/pkg/lambda" "git.maximhutz.com/max/lambda/pkg/saccharine" ) @@ -32,7 +31,7 @@ func main() { // Compile expression to lambda calculus. compiled := convert.SaccharineToLambda(ast) - logger.Info("compiled λ expression", "tree", lambda.Stringify(compiled)) + logger.Info("compiled λ expression", "tree", compiled.String()) // Create reduction engine. process := engine.New(options, &compiled) @@ -62,7 +61,7 @@ func main() { process.Run() // Return the final reduced result. - result := lambda.Stringify(compiled) + result := (*process.Expression).String() err = options.Destination.Write(result) cli.HandleError(err) } diff --git a/internal/engine/engine.go b/internal/engine/engine.go index a617d72..830eeac 100644 --- a/internal/engine/engine.go +++ b/internal/engine/engine.go @@ -1,5 +1,5 @@ -// Package "engine" provides an extensible interface for users to interfact with -// λ-calculus. +// Package "engine" provides an extensible interface for users to interact with +// λ-calculus and other expression evaluation modes. package engine import ( @@ -8,7 +8,7 @@ import ( "git.maximhutz.com/max/lambda/pkg/lambda" ) -// A process for reducing one λ-expression. +// A process for reducing one expression. type Engine struct { Config *config.Config Expression *lambda.Expression @@ -25,7 +25,7 @@ func New(config *config.Config, expression *lambda.Expression) *Engine { } // Begin the reduction process. -func (e Engine) Run() { +func (e *Engine) Run() { e.Emit(StartEvent) lambda.ReduceAll(e.Expression, func() { diff --git a/internal/plugins/debug.go b/internal/plugins/debug.go index 15fe54b..8f0ec8e 100644 --- a/internal/plugins/debug.go +++ b/internal/plugins/debug.go @@ -4,7 +4,6 @@ import ( "log/slog" "git.maximhutz.com/max/lambda/internal/engine" - "git.maximhutz.com/max/lambda/pkg/lambda" ) type Logs struct { @@ -20,6 +19,5 @@ func NewLogs(logger *slog.Logger, process *engine.Engine) *Logs { } func (t *Logs) Step() { - stringified := lambda.Stringify(*t.process.Expression) - t.logger.Info("reduction", "tree", stringified) + t.logger.Info("reduction", "tree", (*t.process.Expression).String()) } diff --git a/internal/plugins/explanation.go b/internal/plugins/explanation.go index 141e8fc..4fcadce 100644 --- a/internal/plugins/explanation.go +++ b/internal/plugins/explanation.go @@ -1,4 +1,4 @@ -// Package "explanation" provides a observer to gather the reasoning during the +// Package "explanation" provides an observer to gather the reasoning during the // reduction, and present a thorough explanation to the user for each step. package plugins @@ -6,10 +6,9 @@ import ( "fmt" "git.maximhutz.com/max/lambda/internal/engine" - "git.maximhutz.com/max/lambda/pkg/lambda" ) -// Track the reductions made by a reduction proess. +// Track the reductions made by a reduction process. type Explanation struct { process *engine.Engine } @@ -24,9 +23,9 @@ func NewExplanation(process *engine.Engine) *Explanation { } func (t *Explanation) Start() { - fmt.Println(lambda.Stringify(*t.process.Expression)) + fmt.Println((*t.process.Expression).String()) } func (t *Explanation) Step() { - fmt.Println(" =", lambda.Stringify(*t.process.Expression)) + fmt.Println(" =", (*t.process.Expression).String()) } diff --git a/pkg/expr/expr.go b/pkg/expr/expr.go new file mode 100644 index 0000000..4fd8b78 --- /dev/null +++ b/pkg/expr/expr.go @@ -0,0 +1,11 @@ +// Package expr provides the abstract Expression interface for all evaluatable +// expression types in the lambda interpreter. +package expr + +// Expression is the base interface for all evaluatable expression types. +// Different evaluation modes (lambda calculus, SKI combinators, typed lambda +// calculus, etc.) implement this interface with their own concrete types. +type Expression interface { + // String returns a human-readable representation of the expression. + String() string +} diff --git a/pkg/lambda/expression.go b/pkg/lambda/expression.go index f34b3b4..91e1502 100644 --- a/pkg/lambda/expression.go +++ b/pkg/lambda/expression.go @@ -1,6 +1,11 @@ package lambda +import "git.maximhutz.com/max/lambda/pkg/expr" + +// Expression is the interface for all lambda calculus expression types. +// It embeds the general expr.Expression interface for cross-mode compatibility. type Expression interface { + expr.Expression Accept(Visitor) } @@ -23,6 +28,10 @@ func (a *Abstraction) Accept(v Visitor) { v.VisitAbstraction(a) } +func (a *Abstraction) String() string { + return Stringify(a) +} + func NewAbstraction(parameter string, body Expression) *Abstraction { return &Abstraction{parameter: parameter, body: body} } @@ -46,6 +55,10 @@ func (a *Application) Accept(v Visitor) { v.VisitApplication(a) } +func (a *Application) String() string { + return Stringify(a) +} + func NewApplication(abstraction Expression, argument Expression) *Application { return &Application{abstraction: abstraction, argument: argument} } @@ -64,6 +77,10 @@ func (v *Variable) Accept(visitor Visitor) { visitor.VisitVariable(v) } +func (v *Variable) String() string { + return Stringify(v) +} + func NewVariable(name string) *Variable { return &Variable{value: name} }