diff --git a/.DS_Store b/.DS_Store new file mode 100644 index 0000000..ea3fae1 Binary files /dev/null and b/.DS_Store differ diff --git a/.gitignore b/.gitignore index 71c04ed..8e859cd 100644 --- a/.gitignore +++ b/.gitignore @@ -26,3 +26,5 @@ go.work.sum .env *.log + +profile/ \ No newline at end of file diff --git a/Makefile b/Makefile index 8e821b5..d7db258 100644 --- a/Makefile +++ b/Makefile @@ -13,5 +13,13 @@ thunk: it saccharine: it @ ./lambda.exe - < ./samples/saccharine.txt +prof: + @ go tool pprof -top profile/cpu.prof + +graph: + @ go tool pprof -raw -output=profile/cpu.raw profile/cpu.prof + @ go tool pprof -svg profile/cpu.prof > profile/cpu.svg + @ open profile/cpu.svg + saccharineX: it - @ ./lambda.exe -x - < ./samples/saccharine.txt > saccharine.out \ No newline at end of file + @ ./lambda.exe -x - < ./samples/saccharine.txt > saccharine.out diff --git a/cmd/.DS_Store b/cmd/.DS_Store new file mode 100644 index 0000000..85ac39e Binary files /dev/null and b/cmd/.DS_Store differ diff --git a/cmd/lambda/lambda.go b/cmd/lambda/lambda.go index bbc9242..b593434 100644 --- a/cmd/lambda/lambda.go +++ b/cmd/lambda/lambda.go @@ -3,6 +3,7 @@ package main import ( "fmt" "os" + "runtime/pprof" "time" "git.maximhutz.com/max/lambda/internal/cli" @@ -14,6 +15,14 @@ import ( // Run main application. func main() { + f, err := os.Create("profile/cpu.prof") + cli.HandleError(err) + defer f.Close() + + err = pprof.StartCPUProfile(f) + cli.HandleError(err) + defer pprof.StopCPUProfile() + options, err := config.FromArgs() cli.HandleError(err) diff --git a/internal/.DS_Store b/internal/.DS_Store new file mode 100644 index 0000000..40a0c4e Binary files /dev/null and b/internal/.DS_Store differ diff --git a/pkg/.DS_Store b/pkg/.DS_Store new file mode 100644 index 0000000..65e24b3 Binary files /dev/null and b/pkg/.DS_Store differ diff --git a/pkg/lambda/is_free_variable.go b/pkg/lambda/is_free_variable.go new file mode 100644 index 0000000..deb3492 --- /dev/null +++ b/pkg/lambda/is_free_variable.go @@ -0,0 +1,14 @@ +package lambda + +func IsFreeVariable(n string, e Expression) bool { + switch e := e.(type) { + case *Variable: + return e.Value == n + case *Abstraction: + return e.Parameter != n && IsFreeVariable(n, e.Body) + case *Application: + return IsFreeVariable(n, e.Abstraction) || IsFreeVariable(n, e.Argument) + default: + return false + } +} diff --git a/pkg/lambda/substitute.go b/pkg/lambda/substitute.go index ebc83c5..96d4ec2 100644 --- a/pkg/lambda/substitute.go +++ b/pkg/lambda/substitute.go @@ -11,12 +11,12 @@ func Substitute(e *Expression, target string, replacement Expression) { return } - replacementFreeVars := GetFreeVariables(replacement) - if !replacementFreeVars.Has(typed.Parameter) { + if !IsFreeVariable(typed.Parameter, replacement) { Substitute(&typed.Body, target, replacement) return } + replacementFreeVars := GetFreeVariables(replacement) used := GetFreeVariables(typed.Body) used.Merge(replacementFreeVars) freshVar := GenerateFreshName(used) diff --git a/pkg/saccharine/.DS_Store b/pkg/saccharine/.DS_Store new file mode 100644 index 0000000..6342c25 Binary files /dev/null and b/pkg/saccharine/.DS_Store differ