VM globals
This commit is contained in:
27
vm/vm.go
27
vm/vm.go
@@ -8,6 +8,7 @@ import (
|
||||
)
|
||||
|
||||
const StackSize = 2048
|
||||
const GlobalsSize = 65536
|
||||
|
||||
var Null = &object.Null{}
|
||||
var True = &object.Boolean{Value: true}
|
||||
@@ -19,6 +20,8 @@ type VM struct {
|
||||
|
||||
stack []object.Object
|
||||
sp int // Always points to the next value. Top of stack is stack[sp-1]
|
||||
|
||||
globals []object.Object
|
||||
}
|
||||
|
||||
func New(bytecode *compiler.Bytecode) *VM {
|
||||
@@ -28,9 +31,17 @@ func New(bytecode *compiler.Bytecode) *VM {
|
||||
|
||||
stack: make([]object.Object, StackSize),
|
||||
sp: 0,
|
||||
|
||||
globals: make([]object.Object, GlobalsSize),
|
||||
}
|
||||
}
|
||||
|
||||
func NewWithGlobalState(bytecode *compiler.Bytecode, s []object.Object) *VM {
|
||||
vm := New(bytecode)
|
||||
vm.globals = s
|
||||
return vm
|
||||
}
|
||||
|
||||
func (vm *VM) LastPoppedStackElem() object.Object {
|
||||
return vm.stack[vm.sp]
|
||||
}
|
||||
@@ -106,6 +117,22 @@ func (vm *VM) Run() error {
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
case code.OpSetGlobal:
|
||||
globalIndex := code.ReadUint16(vm.instructions[ip+1:])
|
||||
ip += 2
|
||||
|
||||
vm.globals[globalIndex] = vm.pop()
|
||||
|
||||
case code.OpGetGlobal:
|
||||
globalIndex := code.ReadUint16(vm.instructions[ip+1:])
|
||||
ip += 2
|
||||
|
||||
err := vm.push(vm.globals[globalIndex])
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -165,3 +165,13 @@ func TestConditionals(t *testing.T) {
|
||||
|
||||
runVmTests(t, tests)
|
||||
}
|
||||
|
||||
func TestGlobalLetStatements(t *testing.T) {
|
||||
tests := []vmTestCase{
|
||||
{"let one = 1; one", 1},
|
||||
{"let one = 1; let two = 2; one + two", 3},
|
||||
{"let one = 1; let two = one + one; one + two", 3},
|
||||
}
|
||||
|
||||
runVmTests(t, tests)
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user