fix: parameters converted in opposite order
This commit is contained in:
2
Makefile
2
Makefile
@@ -5,4 +5,4 @@ it:
|
||||
@ chmod +x ${BINARY_NAME}
|
||||
|
||||
ex: it
|
||||
@ ./lambda.exe -v - < ./samples/simple.txt
|
||||
@ ./lambda.exe - < ./samples/simple.txt
|
||||
@@ -7,6 +7,8 @@ import (
|
||||
|
||||
"git.maximhutz.com/max/lambda/internal/cli"
|
||||
"git.maximhutz.com/max/lambda/internal/config"
|
||||
"git.maximhutz.com/max/lambda/pkg/convert"
|
||||
"git.maximhutz.com/max/lambda/pkg/lambda"
|
||||
"git.maximhutz.com/max/lambda/pkg/saccharine"
|
||||
)
|
||||
|
||||
@@ -16,8 +18,8 @@ func main() {
|
||||
cli.HandleError(err)
|
||||
|
||||
logger := options.GetLogger()
|
||||
logger.Info("Using program arguments.", "args", os.Args)
|
||||
logger.Info("Parsed CLI options.", "options", options)
|
||||
logger.Info("using program arguments", "args", os.Args)
|
||||
logger.Info("parsed CLI options", "options", options)
|
||||
|
||||
input, err := options.Source.Pull()
|
||||
cli.HandleError(err)
|
||||
@@ -25,29 +27,32 @@ func main() {
|
||||
// Parse tokens.
|
||||
tokens, err := saccharine.GetTokens([]rune(input))
|
||||
cli.HandleError(err)
|
||||
logger.Info("Parsed tokens.", "tokens", tokens)
|
||||
logger.Info("parsed tokens", "tokens", tokens)
|
||||
|
||||
// Turn tokens into syntax tree.
|
||||
expression, err := saccharine.Parse(tokens)
|
||||
cli.HandleError(err)
|
||||
logger.Info("Parsed syntax tree.", "tree", expression)
|
||||
logger.Info("parsed syntax tree", "tree", saccharine.Stringify(expression))
|
||||
|
||||
compiled := convert.SaccharineToLambda(expression)
|
||||
logger.Info("compiled lambda expression", "tree", lambda.Stringify(compiled))
|
||||
|
||||
// Reduce expression.
|
||||
start := time.Now()
|
||||
|
||||
if options.Explanation {
|
||||
fmt.Println(saccharine.Stringify(expression))
|
||||
fmt.Println(lambda.Stringify(compiled))
|
||||
}
|
||||
|
||||
// for lambda.ReduceOnce(&expression) {
|
||||
// logger.Info("Reduction.", "tree", saccharine.Stringify(expression))
|
||||
// if options.Explanation {
|
||||
// fmt.Println(" =", saccharine.Stringify(expression))
|
||||
// }
|
||||
// }
|
||||
for lambda.ReduceOnce(&compiled) {
|
||||
logger.Info("reduction", "tree", lambda.Stringify(compiled))
|
||||
if options.Explanation {
|
||||
fmt.Println(" =", lambda.Stringify(compiled))
|
||||
}
|
||||
}
|
||||
|
||||
elapsed := time.Since(start).Milliseconds()
|
||||
|
||||
fmt.Println(saccharine.Stringify(expression))
|
||||
fmt.Println(lambda.Stringify(compiled))
|
||||
fmt.Fprintln(os.Stderr, "Time Spent:", elapsed, "ms")
|
||||
}
|
||||
|
||||
52
pkg/convert/saccharine_to_lambda.go
Normal file
52
pkg/convert/saccharine_to_lambda.go
Normal file
@@ -0,0 +1,52 @@
|
||||
package convert
|
||||
|
||||
import (
|
||||
"git.maximhutz.com/max/lambda/pkg/lambda"
|
||||
"git.maximhutz.com/max/lambda/pkg/saccharine/ast"
|
||||
)
|
||||
|
||||
type compileVisitor struct{}
|
||||
|
||||
func (v compileVisitor) VisitAtom(n *ast.Atom) lambda.Expression {
|
||||
return lambda.NewVariable(n.Name)
|
||||
}
|
||||
|
||||
func (v compileVisitor) VisitAbstraction(n *ast.Abstraction) lambda.Expression {
|
||||
result := ast.Visit(v, n.Body)
|
||||
|
||||
parameters := n.Parameters
|
||||
|
||||
// If the function has no parameters, it is a thunk. Lambda calculus still
|
||||
// requires _some_ parameter exists, so generate one.
|
||||
if len(parameters) == 0 {
|
||||
freeVars := lambda.GetFreeVariables(result)
|
||||
freshName := lambda.GenerateFreshName(freeVars)
|
||||
parameters = append(parameters, freshName)
|
||||
}
|
||||
|
||||
for i := len(parameters) - 1; i >= 0; i-- {
|
||||
result = lambda.NewAbstraction(parameters[i], result)
|
||||
}
|
||||
|
||||
return result
|
||||
}
|
||||
|
||||
func (v compileVisitor) VisitApplication(n *ast.Application) lambda.Expression {
|
||||
result := ast.Visit(v, n.Abstraction)
|
||||
|
||||
arguments := []lambda.Expression{}
|
||||
for _, argument := range n.Arguments {
|
||||
convertedArgument := ast.Visit(v, argument)
|
||||
arguments = append(arguments, convertedArgument)
|
||||
}
|
||||
|
||||
for _, argument := range arguments {
|
||||
result = lambda.NewApplication(result, argument)
|
||||
}
|
||||
|
||||
return result
|
||||
}
|
||||
|
||||
func SaccharineToLambda(n ast.Expression) lambda.Expression {
|
||||
return ast.Visit(&compileVisitor{}, n)
|
||||
}
|
||||
@@ -3,7 +3,7 @@
|
||||
(\add.
|
||||
(\mult.
|
||||
(\exp.
|
||||
(exp (inc (inc (inc (inc (inc 0))))) (inc (inc (inc (inc (inc 0))))))
|
||||
(exp (inc (inc (inc (inc 0)))) (inc (inc (inc (inc (inc 0))))))
|
||||
\n m.(m n)
|
||||
)
|
||||
\m n f.(m (n f))
|
||||
|
||||
Reference in New Issue
Block a user