88 lines
1.5 KiB
Go
88 lines
1.5 KiB
Go
//go:build ignore
|
|
|
|
package main
|
|
|
|
import (
|
|
"flag"
|
|
"fmt"
|
|
"log"
|
|
"monkey/internal/compiler"
|
|
"monkey/internal/object"
|
|
"monkey/internal/parser"
|
|
"monkey/internal/vm"
|
|
"os"
|
|
"runtime"
|
|
"runtime/pprof"
|
|
"strings"
|
|
)
|
|
|
|
const defaultCode = `
|
|
fib := fn(n) {
|
|
if (n < 2) {
|
|
return n
|
|
}
|
|
return fib(n-1) + fib(n-2)
|
|
}
|
|
|
|
print(fib(%d))`
|
|
|
|
func checkErr(err error) {
|
|
if err != nil {
|
|
panic(err)
|
|
}
|
|
}
|
|
|
|
func readFile(path string) string {
|
|
b, err := os.ReadFile(path)
|
|
checkErr(err)
|
|
|
|
return string(b)
|
|
}
|
|
|
|
func fileOrDefault() string {
|
|
if flag.NArg() > 0 {
|
|
log.Printf("Using %s as program input...", flag.Arg(0))
|
|
object.Args = flag.Args()[1:]
|
|
return readFile(flag.Arg(0))
|
|
}
|
|
return defaultCode
|
|
}
|
|
|
|
func main() {
|
|
n := flag.Int("n", 35, "Set n for fib(n) [Default: 35]")
|
|
flag.Parse()
|
|
|
|
cpuf, err := os.Create("cpu.prof")
|
|
checkErr(err)
|
|
|
|
heapf, err := os.Create("heap.prof")
|
|
checkErr(err)
|
|
|
|
log.Printf("Using %d as n", *n)
|
|
|
|
code := fileOrDefault()
|
|
if strings.Count(code, "%d") > 0 {
|
|
code = fmt.Sprintf(code, *n)
|
|
}
|
|
log.Printf("Code:\n%s\n", code)
|
|
tree, errs := parser.Parse("<profiler>", code)
|
|
if len(errs) > 0 {
|
|
for _, err := range errs {
|
|
log.Println(err)
|
|
}
|
|
panic("parser errors")
|
|
}
|
|
|
|
c := compiler.New()
|
|
c.SetFileInfo("<profiler>", code)
|
|
checkErr(c.Compile(tree))
|
|
checkErr(pprof.StartCPUProfile(cpuf))
|
|
defer pprof.StopCPUProfile()
|
|
mvm := vm.New("<profiler>", c.Bytecode())
|
|
checkErr(mvm.Run())
|
|
runtime.GC()
|
|
checkErr(pprof.WriteHeapProfile(heapf))
|
|
log.Println("CPU Profile written to cpu.prof")
|
|
log.Println("Heap Profile written to heap.prof")
|
|
}
|