refactor how repl works
This commit is contained in:
@@ -2,7 +2,6 @@ package vm
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"io/ioutil"
|
||||
"log"
|
||||
"monkey/internal/builtins"
|
||||
"monkey/internal/code"
|
||||
@@ -11,6 +10,8 @@ import (
|
||||
"monkey/internal/object"
|
||||
"monkey/internal/parser"
|
||||
"monkey/internal/utils"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"strings"
|
||||
"unicode"
|
||||
)
|
||||
@@ -30,20 +31,20 @@ func ExecModule(name string, state *VMState) (object.Object, error) {
|
||||
return nil, fmt.Errorf("ImportError: no module named '%s'", name)
|
||||
}
|
||||
|
||||
b, err := ioutil.ReadFile(filename)
|
||||
b, err := os.ReadFile(filename)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("IOError: error reading module '%s': %s", name, err)
|
||||
}
|
||||
|
||||
l := lexer.New(string(b))
|
||||
p := parser.New(l)
|
||||
p := parser.New(fmt.Sprintf("<module %s>", name), l)
|
||||
|
||||
module := p.ParseProgram()
|
||||
if len(p.Errors()) != 0 {
|
||||
return nil, fmt.Errorf("ParseError: %s", p.Errors())
|
||||
}
|
||||
|
||||
c := compiler.NewWithState(state.Symbols, state.Constants)
|
||||
c := compiler.NewWithState(state.Symbols, &state.Constants)
|
||||
err = c.Compile(module)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("CompileError: %s", err)
|
||||
@@ -52,7 +53,7 @@ func ExecModule(name string, state *VMState) (object.Object, error) {
|
||||
code := c.Bytecode()
|
||||
state.Constants = code.Constants
|
||||
|
||||
machine := NewWithState(code, state)
|
||||
machine := NewWithState(fmt.Sprintf("<module %s>", name), code, state)
|
||||
err = machine.Run()
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("RuntimeError: error loading module '%s'", err)
|
||||
@@ -102,6 +103,9 @@ type VM struct {
|
||||
|
||||
state *VMState
|
||||
|
||||
dir string
|
||||
file string
|
||||
|
||||
stack []object.Object
|
||||
sp int // Always points to the next value. Top of stack is stack[sp-1]
|
||||
|
||||
@@ -111,7 +115,7 @@ type VM struct {
|
||||
}
|
||||
|
||||
// New constructs a new monkey-lang bytecode virtual machine
|
||||
func New(bytecode *compiler.Bytecode) *VM {
|
||||
func New(fn string, bytecode *compiler.Bytecode) *VM {
|
||||
mainFn := &object.CompiledFunction{Instructions: bytecode.Instructions}
|
||||
mainClosure := &object.Closure{Fn: mainFn}
|
||||
mainFrame := NewFrame(mainClosure, 0)
|
||||
@@ -122,7 +126,7 @@ func New(bytecode *compiler.Bytecode) *VM {
|
||||
state := NewVMState()
|
||||
state.Constants = bytecode.Constants
|
||||
|
||||
return &VM{
|
||||
vm := &VM{
|
||||
state: state,
|
||||
|
||||
stack: make([]object.Object, StackSize),
|
||||
@@ -132,9 +136,13 @@ func New(bytecode *compiler.Bytecode) *VM {
|
||||
frame: mainFrame,
|
||||
fp: 1,
|
||||
}
|
||||
|
||||
vm.dir, vm.file = filepath.Split(fn)
|
||||
|
||||
return vm
|
||||
}
|
||||
|
||||
func NewWithState(bytecode *compiler.Bytecode, state *VMState) *VM {
|
||||
func NewWithState(fn string, bytecode *compiler.Bytecode, state *VMState) *VM {
|
||||
mainFn := &object.CompiledFunction{Instructions: bytecode.Instructions}
|
||||
mainClosure := &object.Closure{Fn: mainFn}
|
||||
mainFrame := NewFrame(mainClosure, 0)
|
||||
@@ -142,7 +150,7 @@ func NewWithState(bytecode *compiler.Bytecode, state *VMState) *VM {
|
||||
frames := make([]*Frame, MaxFrames)
|
||||
frames[0] = mainFrame
|
||||
|
||||
return &VM{
|
||||
vm := &VM{
|
||||
state: state,
|
||||
|
||||
frames: frames,
|
||||
@@ -152,6 +160,10 @@ func NewWithState(bytecode *compiler.Bytecode, state *VMState) *VM {
|
||||
stack: make([]object.Object, StackSize),
|
||||
sp: 0,
|
||||
}
|
||||
|
||||
vm.dir, vm.file = filepath.Split(fn)
|
||||
|
||||
return vm
|
||||
}
|
||||
|
||||
func (vm *VM) pushFrame(f *Frame) {
|
||||
@@ -429,7 +441,7 @@ func (vm *VM) Run() error {
|
||||
|
||||
case code.OpGetBuiltin:
|
||||
builtinIndex := code.ReadUint8(ins[ip+1:])
|
||||
vm.frame.ip += 1
|
||||
vm.frame.ip++
|
||||
|
||||
builtin := builtins.BuiltinsIndex[builtinIndex]
|
||||
|
||||
|
||||
Reference in New Issue
Block a user