## Summary - Added doc comments across the codebase: `pkg/lambda`, `pkg/saccharine`, `pkg/codec`, `pkg/engine`, `pkg/iterator`, `pkg/set`, `pkg/convert`, `internal/registry`, and `cmd/lambda`. - Made lambda and saccharine expression structs use public fields instead of getters, matching `go/ast` conventions. - Removed superfluous constructors for saccharine and lambda expression/statement types in favor of struct literals. - Consolidated saccharine token constructors into a single `NewToken` function. - Removed the unused `trace` package. ## Test plan - [x] `go build ./...` passes. - [x] `go test ./...` passes. - [ ] Verify `go doc` output renders correctly for documented packages. Reviewed-on: #45 Co-authored-by: M.V. Hutz <git@maximhutz.me> Co-committed-by: M.V. Hutz <git@maximhutz.me>
40 lines
1.1 KiB
Go
40 lines
1.1 KiB
Go
package normalorder
|
|
|
|
import "git.maximhutz.com/max/lambda/pkg/lambda"
|
|
|
|
// ReduceOnce attempts to apply a single reduction to a lambda expression.
|
|
// It returns (1) the final expression (reduced, or not), and (2) whether or not
|
|
// a reduction was applied.
|
|
//
|
|
// If a reduction is not applied, it returns the original expression.
|
|
func ReduceOnce(e lambda.Expression) (lambda.Expression, bool) {
|
|
switch e := e.(type) {
|
|
case lambda.Abstraction:
|
|
body, reduced := ReduceOnce(e.Body)
|
|
if reduced {
|
|
return lambda.Abstraction{Parameter: e.Parameter, Body: body}, true
|
|
}
|
|
return e, false
|
|
|
|
case lambda.Application:
|
|
if fn, fnOk := e.Abstraction.(lambda.Abstraction); fnOk {
|
|
return lambda.Substitute(fn.Body, fn.Parameter, e.Argument), true
|
|
}
|
|
|
|
abs, reduced := ReduceOnce(e.Abstraction)
|
|
if reduced {
|
|
return lambda.Application{Abstraction: abs, Argument: e.Argument}, true
|
|
}
|
|
|
|
arg, reduced := ReduceOnce(e.Argument)
|
|
if reduced {
|
|
return lambda.Application{Abstraction: e.Abstraction, Argument: arg}, true
|
|
}
|
|
|
|
return e, false
|
|
|
|
default:
|
|
return e, false
|
|
}
|
|
}
|