fix: parameters converted in opposite order
This commit is contained in:
2
Makefile
2
Makefile
@@ -5,4 +5,4 @@ it:
|
|||||||
@ chmod +x ${BINARY_NAME}
|
@ chmod +x ${BINARY_NAME}
|
||||||
|
|
||||||
ex: it
|
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/cli"
|
||||||
"git.maximhutz.com/max/lambda/internal/config"
|
"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"
|
"git.maximhutz.com/max/lambda/pkg/saccharine"
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -16,8 +18,8 @@ func main() {
|
|||||||
cli.HandleError(err)
|
cli.HandleError(err)
|
||||||
|
|
||||||
logger := options.GetLogger()
|
logger := options.GetLogger()
|
||||||
logger.Info("Using program arguments.", "args", os.Args)
|
logger.Info("using program arguments", "args", os.Args)
|
||||||
logger.Info("Parsed CLI options.", "options", options)
|
logger.Info("parsed CLI options", "options", options)
|
||||||
|
|
||||||
input, err := options.Source.Pull()
|
input, err := options.Source.Pull()
|
||||||
cli.HandleError(err)
|
cli.HandleError(err)
|
||||||
@@ -25,29 +27,32 @@ func main() {
|
|||||||
// Parse tokens.
|
// Parse tokens.
|
||||||
tokens, err := saccharine.GetTokens([]rune(input))
|
tokens, err := saccharine.GetTokens([]rune(input))
|
||||||
cli.HandleError(err)
|
cli.HandleError(err)
|
||||||
logger.Info("Parsed tokens.", "tokens", tokens)
|
logger.Info("parsed tokens", "tokens", tokens)
|
||||||
|
|
||||||
// Turn tokens into syntax tree.
|
// Turn tokens into syntax tree.
|
||||||
expression, err := saccharine.Parse(tokens)
|
expression, err := saccharine.Parse(tokens)
|
||||||
cli.HandleError(err)
|
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.
|
// Reduce expression.
|
||||||
start := time.Now()
|
start := time.Now()
|
||||||
|
|
||||||
if options.Explanation {
|
if options.Explanation {
|
||||||
fmt.Println(saccharine.Stringify(expression))
|
fmt.Println(lambda.Stringify(compiled))
|
||||||
}
|
}
|
||||||
|
|
||||||
// for lambda.ReduceOnce(&expression) {
|
for lambda.ReduceOnce(&compiled) {
|
||||||
// logger.Info("Reduction.", "tree", saccharine.Stringify(expression))
|
logger.Info("reduction", "tree", lambda.Stringify(compiled))
|
||||||
// if options.Explanation {
|
if options.Explanation {
|
||||||
// fmt.Println(" =", saccharine.Stringify(expression))
|
fmt.Println(" =", lambda.Stringify(compiled))
|
||||||
// }
|
}
|
||||||
// }
|
}
|
||||||
|
|
||||||
elapsed := time.Since(start).Milliseconds()
|
elapsed := time.Since(start).Milliseconds()
|
||||||
|
|
||||||
fmt.Println(saccharine.Stringify(expression))
|
fmt.Println(lambda.Stringify(compiled))
|
||||||
fmt.Fprintln(os.Stderr, "Time Spent:", elapsed, "ms")
|
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.
|
(\add.
|
||||||
(\mult.
|
(\mult.
|
||||||
(\exp.
|
(\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)
|
\n m.(m n)
|
||||||
)
|
)
|
||||||
\m n f.(m (n f))
|
\m n f.(m (n f))
|
||||||
|
|||||||
Reference in New Issue
Block a user