debug
This commit is contained in:
32
main.go
32
main.go
@@ -3,15 +3,17 @@ package main
|
|||||||
import (
|
import (
|
||||||
"flag"
|
"flag"
|
||||||
"fmt"
|
"fmt"
|
||||||
"io/ioutil"
|
"io"
|
||||||
"log"
|
"log"
|
||||||
"monkey/compiler"
|
"monkey/compiler"
|
||||||
"monkey/lexer"
|
"monkey/lexer"
|
||||||
|
"monkey/object"
|
||||||
"monkey/parser"
|
"monkey/parser"
|
||||||
"monkey/repl"
|
"monkey/repl"
|
||||||
"os"
|
"os"
|
||||||
"os/user"
|
"os/user"
|
||||||
"path"
|
"path"
|
||||||
|
"strings"
|
||||||
)
|
)
|
||||||
|
|
||||||
var (
|
var (
|
||||||
@@ -37,6 +39,22 @@ func init() {
|
|||||||
flag.StringVar(&engine, "e", "vm", "engine to use (eval or vm)")
|
flag.StringVar(&engine, "e", "vm", "engine to use (eval or vm)")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Indent indents a block of text with an indent string
|
||||||
|
func Indent(text, indent string) string {
|
||||||
|
if text[len(text)-1:] == "\n" {
|
||||||
|
result := ""
|
||||||
|
for _, j := range strings.Split(text[:len(text)-1], "\n") {
|
||||||
|
result += indent + j + "\n"
|
||||||
|
}
|
||||||
|
return result
|
||||||
|
}
|
||||||
|
result := ""
|
||||||
|
for _, j := range strings.Split(strings.TrimRight(text, "\n"), "\n") {
|
||||||
|
result += indent + j + "\n"
|
||||||
|
}
|
||||||
|
return result[:len(result)-1]
|
||||||
|
}
|
||||||
|
|
||||||
func main() {
|
func main() {
|
||||||
flag.Parse()
|
flag.Parse()
|
||||||
|
|
||||||
@@ -59,7 +77,7 @@ func main() {
|
|||||||
f, err := os.Open(args[0])
|
f, err := os.Open(args[0])
|
||||||
defer f.Close()
|
defer f.Close()
|
||||||
|
|
||||||
b, err := ioutil.ReadAll(f)
|
b, err := io.ReadAll(f)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Fatal(err)
|
log.Fatal(err)
|
||||||
}
|
}
|
||||||
@@ -79,7 +97,15 @@ func main() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
code := c.Bytecode()
|
code := c.Bytecode()
|
||||||
fmt.Printf("%s\n", code.Instructions)
|
fmt.Printf("Main:\n%s\n", code.Instructions)
|
||||||
|
|
||||||
|
fmt.Print("Constants:\n")
|
||||||
|
for i, constant := range code.Constants {
|
||||||
|
fmt.Printf("%04d %s\n", i, constant.Inspect())
|
||||||
|
if fn, ok := constant.(*object.CompiledFunction); ok {
|
||||||
|
fmt.Printf("%s\n", Indent(fn.Instructions.String(), " "))
|
||||||
|
}
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
opts := &repl.Options{
|
opts := &repl.Options{
|
||||||
Debug: debug,
|
Debug: debug,
|
||||||
|
|||||||
@@ -126,6 +126,7 @@ func (r *REPL) Exec(f io.Reader) (state *VMState) {
|
|||||||
state.constants = code.Constants
|
state.constants = code.Constants
|
||||||
|
|
||||||
machine := vm.NewWithGlobalState(code, state.globals)
|
machine := vm.NewWithGlobalState(code, state.globals)
|
||||||
|
machine.Debug = r.opts.Debug
|
||||||
err = machine.Run()
|
err = machine.Run()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
fmt.Fprintf(os.Stderr, "Woops! Executing bytecode failed:\n %s\n", err)
|
fmt.Fprintf(os.Stderr, "Woops! Executing bytecode failed:\n %s\n", err)
|
||||||
@@ -206,6 +207,7 @@ func (r *REPL) StartExecLoop(in io.Reader, out io.Writer, state *VMState) {
|
|||||||
state.constants = code.Constants
|
state.constants = code.Constants
|
||||||
|
|
||||||
machine := vm.NewWithGlobalState(code, state.globals)
|
machine := vm.NewWithGlobalState(code, state.globals)
|
||||||
|
machine.Debug = r.opts.Debug
|
||||||
err = machine.Run()
|
err = machine.Run()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
fmt.Fprintf(os.Stderr, "Woops! Executing bytecode failed:\n %s\n", err)
|
fmt.Fprintf(os.Stderr, "Woops! Executing bytecode failed:\n %s\n", err)
|
||||||
|
|||||||
15
vm/vm.go
15
vm/vm.go
@@ -2,9 +2,11 @@ package vm
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"log"
|
||||||
"monkey/code"
|
"monkey/code"
|
||||||
"monkey/compiler"
|
"monkey/compiler"
|
||||||
"monkey/object"
|
"monkey/object"
|
||||||
|
"strings"
|
||||||
)
|
)
|
||||||
|
|
||||||
const StackSize = 2048
|
const StackSize = 2048
|
||||||
@@ -16,6 +18,8 @@ var True = &object.Boolean{Value: true}
|
|||||||
var False = &object.Boolean{Value: false}
|
var False = &object.Boolean{Value: false}
|
||||||
|
|
||||||
type VM struct {
|
type VM struct {
|
||||||
|
Debug bool
|
||||||
|
|
||||||
constants []object.Object
|
constants []object.Object
|
||||||
|
|
||||||
stack []object.Object
|
stack []object.Object
|
||||||
@@ -77,6 +81,17 @@ func (vm *VM) Run() error {
|
|||||||
var ins code.Instructions
|
var ins code.Instructions
|
||||||
var op code.Opcode
|
var op code.Opcode
|
||||||
|
|
||||||
|
if vm.Debug {
|
||||||
|
log.Printf(
|
||||||
|
"%-20s %-20s\n",
|
||||||
|
strings.Split(ins[ip:].String(), "\n")[0],
|
||||||
|
fmt.Sprintf(
|
||||||
|
"[ip=%02d fp=%02d, sp=%02d]",
|
||||||
|
ip, vm.sp, vm.framesIndex-1,
|
||||||
|
),
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
for vm.currentFrame().ip < len(vm.currentFrame().Instructions())-1 {
|
for vm.currentFrame().ip < len(vm.currentFrame().Instructions())-1 {
|
||||||
vm.currentFrame().ip++
|
vm.currentFrame().ip++
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user