small changes
This commit is contained in:
@@ -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
|
||||
}
|
||||
|
||||
@@ -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)
|
||||
|
||||
61
profile.go
Normal file
61
profile.go
Normal file
@@ -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("<profiler>", code)
|
||||
if len(errs) > 0 {
|
||||
panic("parser errors")
|
||||
}
|
||||
|
||||
c := compiler.New()
|
||||
c.SetFileInfo("<profiler>", code)
|
||||
check(c.Compile(tree))
|
||||
|
||||
check(pprof.StartCPUProfile(cpuf))
|
||||
defer pprof.StopCPUProfile()
|
||||
mvm := vm.New("<profiler>", c.Bytecode())
|
||||
mvm.Run()
|
||||
}
|
||||
Reference in New Issue
Block a user