docs: document remaining packages and simplify AST types #45
@@ -10,7 +10,7 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
func encodeAtom(n *saccharine.Atom) lambda.Expression {
|
func encodeAtom(n *saccharine.Atom) lambda.Expression {
|
||||||
return lambda.NewVariable(n.Name)
|
return lambda.Variable{Name: n.Name}
|
||||||
}
|
}
|
||||||
|
|
||||||
func encodeAbstraction(n *saccharine.Abstraction) lambda.Expression {
|
func encodeAbstraction(n *saccharine.Abstraction) lambda.Expression {
|
||||||
@@ -27,7 +27,7 @@ func encodeAbstraction(n *saccharine.Abstraction) lambda.Expression {
|
|||||||
}
|
}
|
||||||
|
|
||||||
for i := len(parameters) - 1; i >= 0; i-- {
|
for i := len(parameters) - 1; i >= 0; i-- {
|
||||||
result = lambda.NewAbstraction(parameters[i], result)
|
result = lambda.Abstraction{Parameter: parameters[i], Body: result}
|
||||||
}
|
}
|
||||||
|
|
||||||
return result
|
return result
|
||||||
@@ -43,7 +43,7 @@ func encodeApplication(n *saccharine.Application) lambda.Expression {
|
|||||||
}
|
}
|
||||||
|
|
||||||
for _, argument := range arguments {
|
for _, argument := range arguments {
|
||||||
result = lambda.NewApplication(result, argument)
|
result = lambda.Application{Abstraction: result, Argument: argument}
|
||||||
}
|
}
|
||||||
|
|
||||||
return result
|
return result
|
||||||
@@ -58,19 +58,19 @@ func reduceLet(s *saccharine.LetStatement, e lambda.Expression) lambda.Expressio
|
|||||||
value = encodeAbstraction(&saccharine.Abstraction{Parameters: s.Parameters, Body: s.Body})
|
value = encodeAbstraction(&saccharine.Abstraction{Parameters: s.Parameters, Body: s.Body})
|
||||||
}
|
}
|
||||||
|
|
||||||
return lambda.NewApplication(
|
return lambda.Application{
|
||||||
lambda.NewAbstraction(s.Name, e),
|
Abstraction: lambda.Abstraction{Parameter: s.Name, Body: e},
|
||||||
value,
|
Argument: value,
|
||||||
)
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func reduceDeclare(s *saccharine.DeclareStatement, e lambda.Expression) lambda.Expression {
|
func reduceDeclare(s *saccharine.DeclareStatement, e lambda.Expression) lambda.Expression {
|
||||||
freshVar := lambda.GenerateFreshName(e.GetFree())
|
freshVar := lambda.GenerateFreshName(e.GetFree())
|
||||||
|
|
||||||
return lambda.NewApplication(
|
return lambda.Application{
|
||||||
lambda.NewAbstraction(freshVar, e),
|
Abstraction: lambda.Abstraction{Parameter: freshVar, Body: e},
|
||||||
encodeExpression(s.Value),
|
Argument: encodeExpression(s.Value),
|
||||||
)
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func reduceStatement(s saccharine.Statement, e lambda.Expression) lambda.Expression {
|
func reduceStatement(s saccharine.Statement, e lambda.Expression) lambda.Expression {
|
||||||
@@ -112,15 +112,15 @@ func encodeExpression(s saccharine.Expression) lambda.Expression {
|
|||||||
func decodeExression(l lambda.Expression) saccharine.Expression {
|
func decodeExression(l lambda.Expression) saccharine.Expression {
|
||||||
switch l := l.(type) {
|
switch l := l.(type) {
|
||||||
case lambda.Variable:
|
case lambda.Variable:
|
||||||
return &saccharine.Atom{Name: l.Name()}
|
return &saccharine.Atom{Name: l.Name}
|
||||||
case lambda.Abstraction:
|
case lambda.Abstraction:
|
||||||
return &saccharine.Abstraction{
|
return &saccharine.Abstraction{
|
||||||
Parameters: []string{l.Parameter()},
|
Parameters: []string{l.Parameter},
|
||||||
Body: decodeExression(l.Body())}
|
Body: decodeExression(l.Body)}
|
||||||
case lambda.Application:
|
case lambda.Application:
|
||||||
return &saccharine.Application{
|
return &saccharine.Application{
|
||||||
Abstraction: decodeExression(l.Abstraction()),
|
Abstraction: decodeExression(l.Abstraction),
|
||||||
Arguments: []saccharine.Expression{decodeExression(l.Argument())}}
|
Arguments: []saccharine.Expression{decodeExression(l.Argument)}}
|
||||||
default:
|
default:
|
||||||
panic(fmt.Errorf("unknown expression type: %T", l))
|
panic(fmt.Errorf("unknown expression type: %T", l))
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -10,25 +10,25 @@ import "git.maximhutz.com/max/lambda/pkg/lambda"
|
|||||||
func ReduceOnce(e lambda.Expression) (lambda.Expression, bool) {
|
func ReduceOnce(e lambda.Expression) (lambda.Expression, bool) {
|
||||||
switch e := e.(type) {
|
switch e := e.(type) {
|
||||||
case lambda.Abstraction:
|
case lambda.Abstraction:
|
||||||
body, reduced := ReduceOnce(e.Body())
|
body, reduced := ReduceOnce(e.Body)
|
||||||
if reduced {
|
if reduced {
|
||||||
return lambda.NewAbstraction(e.Parameter(), body), true
|
return lambda.Abstraction{Parameter: e.Parameter, Body: body}, true
|
||||||
}
|
}
|
||||||
return e, false
|
return e, false
|
||||||
|
|
||||||
case lambda.Application:
|
case lambda.Application:
|
||||||
if fn, fnOk := e.Abstraction().(lambda.Abstraction); fnOk {
|
if fn, fnOk := e.Abstraction.(lambda.Abstraction); fnOk {
|
||||||
return fn.Body().Substitute(fn.Parameter(), e.Argument()), true
|
return fn.Body.Substitute(fn.Parameter, e.Argument), true
|
||||||
}
|
}
|
||||||
|
|
||||||
abs, reduced := ReduceOnce(e.Abstraction())
|
abs, reduced := ReduceOnce(e.Abstraction)
|
||||||
if reduced {
|
if reduced {
|
||||||
return lambda.NewApplication(abs, e.Argument()), true
|
return lambda.Application{Abstraction: abs, Argument: e.Argument}, true
|
||||||
}
|
}
|
||||||
|
|
||||||
arg, reduced := ReduceOnce(e.Argument())
|
arg, reduced := ReduceOnce(e.Argument)
|
||||||
if reduced {
|
if reduced {
|
||||||
return lambda.NewApplication(e.Abstraction(), arg), true
|
return lambda.Application{Abstraction: e.Abstraction, Argument: arg}, true
|
||||||
}
|
}
|
||||||
|
|
||||||
return e, false
|
return e, false
|
||||||
|
|||||||
@@ -3,17 +3,17 @@ package lambda
|
|||||||
import "git.maximhutz.com/max/lambda/pkg/set"
|
import "git.maximhutz.com/max/lambda/pkg/set"
|
||||||
|
|
||||||
func (e Variable) GetFree() set.Set[string] {
|
func (e Variable) GetFree() set.Set[string] {
|
||||||
return set.New(e.Name())
|
return set.New(e.Name)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (e Abstraction) GetFree() set.Set[string] {
|
func (e Abstraction) GetFree() set.Set[string] {
|
||||||
vars := e.Body().GetFree()
|
vars := e.Body.GetFree()
|
||||||
vars.Remove(e.Parameter())
|
vars.Remove(e.Parameter)
|
||||||
return vars
|
return vars
|
||||||
}
|
}
|
||||||
|
|
||||||
func (e Application) GetFree() set.Set[string] {
|
func (e Application) GetFree() set.Set[string] {
|
||||||
vars := e.Abstraction().GetFree()
|
vars := e.Abstraction.GetFree()
|
||||||
vars.Merge(e.Argument().GetFree())
|
vars.Merge(e.Argument.GetFree())
|
||||||
return vars
|
return vars
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,12 +1,12 @@
|
|||||||
package lambda
|
package lambda
|
||||||
|
|
||||||
func (e Variable) IsFree(n string) bool {
|
func (e Variable) IsFree(n string) bool {
|
||||||
return e.Name() == n
|
return e.Name == n
|
||||||
}
|
}
|
||||||
|
|
||||||
func (e Abstraction) IsFree(n string) bool {
|
func (e Abstraction) IsFree(n string) bool {
|
||||||
return e.Parameter() != n && e.Body().IsFree(n)
|
return e.Parameter != n && e.Body.IsFree(n)
|
||||||
}
|
}
|
||||||
func (e Application) IsFree(n string) bool {
|
func (e Application) IsFree(n string) bool {
|
||||||
return e.Abstraction().IsFree(n) || e.Argument().IsFree(n)
|
return e.Abstraction.IsFree(n) || e.Argument.IsFree(n)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -32,69 +32,25 @@ type Expression interface {
|
|||||||
/** ------------------------------------------------------------------------- */
|
/** ------------------------------------------------------------------------- */
|
||||||
|
|
||||||
type Abstraction struct {
|
type Abstraction struct {
|
||||||
parameter string
|
Parameter string
|
||||||
body Expression
|
Body Expression
|
||||||
}
|
}
|
||||||
|
|
||||||
var _ Expression = Abstraction{}
|
var _ Expression = Abstraction{}
|
||||||
|
|
||||||
func (a Abstraction) Parameter() string {
|
|
||||||
return a.parameter
|
|
||||||
}
|
|
||||||
|
|
||||||
func (a Abstraction) Body() Expression {
|
|
||||||
return a.body
|
|
||||||
}
|
|
||||||
|
|
||||||
func (a Abstraction) String() string {
|
|
||||||
return "\\" + a.parameter + "." + a.body.String()
|
|
||||||
}
|
|
||||||
|
|
||||||
func NewAbstraction(parameter string, body Expression) Abstraction {
|
|
||||||
return Abstraction{parameter, body}
|
|
||||||
}
|
|
||||||
|
|
||||||
/** ------------------------------------------------------------------------- */
|
/** ------------------------------------------------------------------------- */
|
||||||
|
|
||||||
type Application struct {
|
type Application struct {
|
||||||
abstraction Expression
|
Abstraction Expression
|
||||||
argument Expression
|
Argument Expression
|
||||||
}
|
}
|
||||||
|
|
||||||
var _ Expression = Application{}
|
var _ Expression = Application{}
|
||||||
|
|
||||||
func (a Application) Abstraction() Expression {
|
|
||||||
return a.abstraction
|
|
||||||
}
|
|
||||||
|
|
||||||
func (a Application) Argument() Expression {
|
|
||||||
return a.argument
|
|
||||||
}
|
|
||||||
|
|
||||||
func (a Application) String() string {
|
|
||||||
return "(" + a.abstraction.String() + " " + a.argument.String() + ")"
|
|
||||||
}
|
|
||||||
|
|
||||||
func NewApplication(abstraction Expression, argument Expression) Application {
|
|
||||||
return Application{abstraction, argument}
|
|
||||||
}
|
|
||||||
|
|
||||||
/** ------------------------------------------------------------------------- */
|
/** ------------------------------------------------------------------------- */
|
||||||
|
|
||||||
type Variable struct {
|
type Variable struct {
|
||||||
name string
|
Name string
|
||||||
}
|
}
|
||||||
|
|
||||||
var _ Expression = Variable{}
|
var _ Expression = Variable{}
|
||||||
|
|
||||||
func (v Variable) Name() string {
|
|
||||||
return v.name
|
|
||||||
}
|
|
||||||
|
|
||||||
func (v Variable) String() string {
|
|
||||||
return v.name
|
|
||||||
}
|
|
||||||
|
|
||||||
func NewVariable(name string) Variable {
|
|
||||||
return Variable{name}
|
|
||||||
}
|
|
||||||
|
|||||||
@@ -2,27 +2,27 @@ package lambda
|
|||||||
|
|
||||||
// Rename replaces all occurrences of the target variable name with the new name.
|
// Rename replaces all occurrences of the target variable name with the new name.
|
||||||
func (e Variable) Rename(target string, newName string) Expression {
|
func (e Variable) Rename(target string, newName string) Expression {
|
||||||
if e.Name() == target {
|
if e.Name == target {
|
||||||
return NewVariable(newName)
|
return Variable{Name: newName}
|
||||||
}
|
}
|
||||||
|
|
||||||
return e
|
return e
|
||||||
}
|
}
|
||||||
|
|
||||||
func (e Abstraction) Rename(target string, newName string) Expression {
|
func (e Abstraction) Rename(target string, newName string) Expression {
|
||||||
newParam := e.Parameter()
|
newParam := e.Parameter
|
||||||
if e.Parameter() == target {
|
if e.Parameter == target {
|
||||||
newParam = newName
|
newParam = newName
|
||||||
}
|
}
|
||||||
|
|
||||||
newBody := e.Body().Rename(target, newName)
|
newBody := e.Body.Rename(target, newName)
|
||||||
|
|
||||||
return NewAbstraction(newParam, newBody)
|
return Abstraction{Parameter: newParam, Body: newBody}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (e Application) Rename(target string, newName string) Expression {
|
func (e Application) Rename(target string, newName string) Expression {
|
||||||
newAbs := e.Abstraction().Rename(target, newName)
|
newAbs := e.Abstraction.Rename(target, newName)
|
||||||
newArg := e.Argument().Rename(target, newName)
|
newArg := e.Argument.Rename(target, newName)
|
||||||
|
|
||||||
return NewApplication(newAbs, newArg)
|
return Application{Abstraction: newAbs, Argument: newArg}
|
||||||
}
|
}
|
||||||
|
|||||||
13
pkg/lambda/stringify.go
Normal file
13
pkg/lambda/stringify.go
Normal file
@@ -0,0 +1,13 @@
|
|||||||
|
package lambda
|
||||||
|
|
||||||
|
func (a Abstraction) String() string {
|
||||||
|
return "\\" + a.Parameter + "." + a.Body.String()
|
||||||
|
}
|
||||||
|
|
||||||
|
func (a Application) String() string {
|
||||||
|
return "(" + a.Abstraction.String() + " " + a.Argument.String() + ")"
|
||||||
|
}
|
||||||
|
|
||||||
|
func (v Variable) String() string {
|
||||||
|
return v.Name
|
||||||
|
}
|
||||||
@@ -1,7 +1,7 @@
|
|||||||
package lambda
|
package lambda
|
||||||
|
|
||||||
func (e Variable) Substitute(target string, replacement Expression) Expression {
|
func (e Variable) Substitute(target string, replacement Expression) Expression {
|
||||||
if e.Name() == target {
|
if e.Name == target {
|
||||||
return replacement
|
return replacement
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -9,12 +9,12 @@ func (e Variable) Substitute(target string, replacement Expression) Expression {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (e Abstraction) Substitute(target string, replacement Expression) Expression {
|
func (e Abstraction) Substitute(target string, replacement Expression) Expression {
|
||||||
if e.Parameter() == target {
|
if e.Parameter == target {
|
||||||
return e
|
return e
|
||||||
}
|
}
|
||||||
|
|
||||||
body := e.Body()
|
body := e.Body
|
||||||
param := e.Parameter()
|
param := e.Parameter
|
||||||
if replacement.IsFree(param) {
|
if replacement.IsFree(param) {
|
||||||
freeVars := replacement.GetFree()
|
freeVars := replacement.GetFree()
|
||||||
freeVars.Merge(body.GetFree())
|
freeVars.Merge(body.GetFree())
|
||||||
@@ -24,12 +24,12 @@ func (e Abstraction) Substitute(target string, replacement Expression) Expressio
|
|||||||
}
|
}
|
||||||
|
|
||||||
newBody := body.Substitute(target, replacement)
|
newBody := body.Substitute(target, replacement)
|
||||||
return NewAbstraction(param, newBody)
|
return Abstraction{Parameter: param, Body: newBody}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (e Application) Substitute(target string, replacement Expression) Expression {
|
func (e Application) Substitute(target string, replacement Expression) Expression {
|
||||||
abs := e.Abstraction().Substitute(target, replacement)
|
abs := e.Abstraction.Substitute(target, replacement)
|
||||||
arg := e.Argument().Substitute(target, replacement)
|
arg := e.Argument.Substitute(target, replacement)
|
||||||
|
|
||||||
return NewApplication(abs, arg)
|
return Application{Abstraction: abs, Argument: arg}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user