diff --git a/pkg/expr/expr.go b/pkg/expr/expr.go index 4fd8b78..a041966 100644 --- a/pkg/expr/expr.go +++ b/pkg/expr/expr.go @@ -2,10 +2,14 @@ // expression types in the lambda interpreter. package expr +import ( + "fmt" +) + // 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 + // The expression should have a human-readable representation. + fmt.Stringer } diff --git a/pkg/lambda/expression.go b/pkg/lambda/expression.go index 91e1502..7cb838a 100644 --- a/pkg/lambda/expression.go +++ b/pkg/lambda/expression.go @@ -1,12 +1,13 @@ package lambda -import "git.maximhutz.com/max/lambda/pkg/expr" +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) } /** ------------------------------------------------------------------------- */ @@ -16,6 +17,8 @@ type Abstraction struct { body Expression } +var _ Expression = (*Abstraction)(nil) + func (a *Abstraction) Parameter() string { return a.parameter } @@ -24,16 +27,12 @@ func (a *Abstraction) Body() Expression { return a.body } -func (a *Abstraction) Accept(v Visitor) { - v.VisitAbstraction(a) -} - func (a *Abstraction) String() string { - return Stringify(a) + return "\\" + a.parameter + "." + a.body.String() } func NewAbstraction(parameter string, body Expression) *Abstraction { - return &Abstraction{parameter: parameter, body: body} + return &Abstraction{parameter, body} } /** ------------------------------------------------------------------------- */ @@ -43,6 +42,8 @@ type Application struct { argument Expression } +var _ Expression = (*Application)(nil) + func (a *Application) Abstraction() Expression { return a.abstraction } @@ -51,16 +52,12 @@ func (a *Application) Argument() Expression { return a.argument } -func (a *Application) Accept(v Visitor) { - v.VisitApplication(a) -} - func (a *Application) String() string { - return Stringify(a) + return "(" + a.abstraction.String() + " " + a.argument.String() + ")" } func NewApplication(abstraction Expression, argument Expression) *Application { - return &Application{abstraction: abstraction, argument: argument} + return &Application{abstraction, argument} } /** ------------------------------------------------------------------------- */ @@ -69,26 +66,16 @@ type Variable struct { value string } +var _ Expression = (*Variable)(nil) + func (v *Variable) Value() string { return v.value } -func (v *Variable) Accept(visitor Visitor) { - visitor.VisitVariable(v) -} - func (v *Variable) String() string { - return Stringify(v) + return v.value } func NewVariable(name string) *Variable { - return &Variable{value: name} -} - -/** ------------------------------------------------------------------------- */ - -type Visitor interface { - VisitAbstraction(*Abstraction) - VisitApplication(*Application) - VisitVariable(*Variable) + return &Variable{name} } diff --git a/pkg/lambda/stringify.go b/pkg/lambda/stringify.go deleted file mode 100644 index 1d838b2..0000000 --- a/pkg/lambda/stringify.go +++ /dev/null @@ -1,32 +0,0 @@ -package lambda - -import "strings" - -type stringifyVisitor struct { - builder strings.Builder -} - -func (v *stringifyVisitor) VisitVariable(a *Variable) { - v.builder.WriteString(a.value) -} - -func (v *stringifyVisitor) VisitAbstraction(f *Abstraction) { - v.builder.WriteRune('\\') - v.builder.WriteString(f.parameter) - v.builder.WriteRune('.') - f.body.Accept(v) -} - -func (v *stringifyVisitor) VisitApplication(c *Application) { - v.builder.WriteRune('(') - c.abstraction.Accept(v) - v.builder.WriteRune(' ') - c.argument.Accept(v) - v.builder.WriteRune(')') -} - -func Stringify(e Expression) string { - b := &stringifyVisitor{builder: strings.Builder{}} - e.Accept(b) - return b.builder.String() -}