package saccharine import ( "fmt" "strings" ) func stringifyAtom(n *Atom) string { return n.Name } func stringifyAbstraction(n *Abstraction) string { return "\\" + strings.Join(n.Parameters, " ") + "." + stringifyExpression(n.Body) } func stringifyApplication(n *Application) string { arguments := []string{stringifyExpression(n.Abstraction)} for _, argument := range n.Arguments { arguments = append(arguments, stringifyExpression(argument)) } return "(" + strings.Join(arguments, " ") + ")" } func stringifyLet(s *LetStatement) string { return s.Name + " " + strings.Join(s.Parameters, " ") + " := " + stringifyExpression(s.Body) } func stringifyDeclare(s *DeclareStatement) string { return stringifyExpression(s.Value) } func stringifyStatement(s Statement) string { switch s := s.(type) { case *DeclareStatement: return stringifyDeclare(s) case *LetStatement: return stringifyLet(s) default: panic(fmt.Errorf("unknown statement type: %v", s)) } } func stringifyClause(n *Clause) string { stmts := "" for _, statement := range n.Statements { stmts += stringifyStatement(statement) + "; " } return "{ " + stmts + stringifyExpression(n.Returns) + " }" } // Convert an expression back into valid source code. func stringifyExpression(n Expression) string { switch n := n.(type) { case *Atom: return stringifyAtom(n) case *Abstraction: return stringifyAbstraction(n) case *Application: return stringifyApplication(n) case *Clause: return stringifyClause(n) default: panic(fmt.Errorf("unknown expression type: %T", n)) } }