This commit is contained in:
Chuck Smith
2024-03-16 20:02:57 -04:00
parent 83ad72a7fc
commit d454572870
3 changed files with 46 additions and 3 deletions

32
main.go
View File

@@ -3,15 +3,17 @@ package main
import (
"flag"
"fmt"
"io/ioutil"
"io"
"log"
"monkey/compiler"
"monkey/lexer"
"monkey/object"
"monkey/parser"
"monkey/repl"
"os"
"os/user"
"path"
"strings"
)
var (
@@ -37,6 +39,22 @@ func init() {
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() {
flag.Parse()
@@ -59,7 +77,7 @@ func main() {
f, err := os.Open(args[0])
defer f.Close()
b, err := ioutil.ReadAll(f)
b, err := io.ReadAll(f)
if err != nil {
log.Fatal(err)
}
@@ -79,7 +97,15 @@ func main() {
}
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 {
opts := &repl.Options{
Debug: debug,

View File

@@ -126,6 +126,7 @@ func (r *REPL) Exec(f io.Reader) (state *VMState) {
state.constants = code.Constants
machine := vm.NewWithGlobalState(code, state.globals)
machine.Debug = r.opts.Debug
err = machine.Run()
if err != nil {
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
machine := vm.NewWithGlobalState(code, state.globals)
machine.Debug = r.opts.Debug
err = machine.Run()
if err != nil {
fmt.Fprintf(os.Stderr, "Woops! Executing bytecode failed:\n %s\n", err)

View File

@@ -2,9 +2,11 @@ package vm
import (
"fmt"
"log"
"monkey/code"
"monkey/compiler"
"monkey/object"
"strings"
)
const StackSize = 2048
@@ -16,6 +18,8 @@ var True = &object.Boolean{Value: true}
var False = &object.Boolean{Value: false}
type VM struct {
Debug bool
constants []object.Object
stack []object.Object
@@ -77,6 +81,17 @@ func (vm *VM) Run() error {
var ins code.Instructions
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 {
vm.currentFrame().ip++