//go:build ignore package main import ( "flag" "fmt" "log" "monkey/internal/compiler" "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) } println(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, []string) { if flag.NArg() > 0 { log.Printf("Using %s as program input...", flag.Arg(0)) return readFile(flag.Arg(0)), flag.Args()[1:] } return defaultCode, flag.Args()[:] } 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, args := fileOrDefault() if strings.Count(code, "%d") > 0 { code = fmt.Sprintf(code, *n) } log.Printf("Code:\n%s\n", code) tree, errs := parser.Parse("", code) if len(errs) > 0 { for _, err := range errs { log.Println(err) } panic("parser errors") } c := compiler.New() c.SetFileInfo("", code) checkErr(c.Compile(tree)) checkErr(pprof.StartCPUProfile(cpuf)) defer pprof.StopCPUProfile() mvm := vm.New("", c.Bytecode(), vm.WithContext(context.New(context.WithArgs(args)))) 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") }