From f65d7bfb1c263485d88dc09dbad1f60d477a77c8 Mon Sep 17 00:00:00 2001 From: Chuck Smith Date: Fri, 29 Mar 2024 08:18:24 -0400 Subject: [PATCH] small changes --- internal/compiler/bytecode.go | 32 ++++++++++++++++++ monkey.go | 4 +++ profile.go | 61 +++++++++++++++++++++++++++++++++++ 3 files changed, 97 insertions(+) create mode 100644 profile.go diff --git a/internal/compiler/bytecode.go b/internal/compiler/bytecode.go index e282a9b..57bfdd0 100644 --- a/internal/compiler/bytecode.go +++ b/internal/compiler/bytecode.go @@ -8,13 +8,45 @@ import ( "math" "monkey/internal/code" "monkey/internal/object" + "strings" ) +func Indent(text, ident string) string { + if text[len(text)-1:] == "\n" { + result := "" + for _, j := range strings.Split(text[:len(text)-1], "\n") { + result += ident + j + "\n" + } + return result + } + result := "" + for _, j := range strings.Split(strings.TrimRight(text, "\n"), "\n") { + result += ident + j + "\n" + } + return result[:len(result)-1] +} + type Bytecode struct { Instructions code.Instructions Constants []object.Object } +func (b *Bytecode) String() string { + var s strings.Builder + + s.WriteString("Constants:\n") + for i, c := range b.Constants { + s.WriteString(fmt.Sprintf("%02d %s\n", i, c)) + if cf, ok := c.(*object.CompiledFunction); ok { + s.WriteString(fmt.Sprintf(" Instructions:\n%s\n", Indent(cf.Instructions.String(), " "))) + } + } + + s.WriteString(fmt.Sprintf("Instructions:\n%s\n", b.Instructions)) + + return s.String() +} + type encoder struct { bytes.Buffer } diff --git a/monkey.go b/monkey.go index c0e6585..53596e1 100644 --- a/monkey.go +++ b/monkey.go @@ -120,6 +120,10 @@ func CompileFiles(files []string, debug bool) error { continue } + if debug { + log.Printf("Bytecode:\n%s\n", c.Bytecode()) + } + cnt, err := c.Bytecode().Encode() if err != nil { fmt.Println(err) diff --git a/profile.go b/profile.go new file mode 100644 index 0000000..5d28548 --- /dev/null +++ b/profile.go @@ -0,0 +1,61 @@ +//go:build ignore + +package main + +import ( + "monkey/internal/compiler" + "monkey/internal/parser" + "monkey/internal/vm" + "os" + "runtime/pprof" +) + +const fib = ` +fib := fn(n) { + if (n < 2) { + return n + } + return fib(n-1) + fib(n-2) +} + +print(fib(35))` + +func check(err error) { + if err != nil { + panic(err) + } +} + +func code(path string) string { + b, err := os.ReadFile(path) + check(err) + + return string(b) +} + +func fileOrDefault() string { + if len(os.Args) > 1 { + return code(os.Args[1]) + } + return fib +} + +func main() { + cpuf, err := os.Create("cpu.prof") + check(err) + + code := fileOrDefault() + tree, errs := parser.Parse("", code) + if len(errs) > 0 { + panic("parser errors") + } + + c := compiler.New() + c.SetFileInfo("", code) + check(c.Compile(tree)) + + check(pprof.StartCPUProfile(cpuf)) + defer pprof.StopCPUProfile() + mvm := vm.New("", c.Bytecode()) + mvm.Run() +}