| 1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889 |
- // Author: simon
- // Author: ynwdlxm@163.com
- // Date: 2022/10/22 13:55
- // Desc: Stack VM implement
- package vm
- import (
- "fmt"
- "github/runnignwater/monkey/code"
- "github/runnignwater/monkey/compiler"
- "github/runnignwater/monkey/object"
- )
- const StackSize = 2048
- type VM struct {
- constants []object.Object
- instructions code.Instructions
- stack []object.Object
- sp int // Always points to the next value. Top of stack is stack[sp-1]
- }
- func New(byteCode *compiler.ByteCode) *VM {
- return &VM{
- instructions: byteCode.Instructions,
- constants: byteCode.Constants,
- stack: make([]object.Object, StackSize),
- sp: 0,
- }
- }
- func (vm *VM) StackTop() object.Object {
- if vm.sp == 0 {
- return nil
- }
- return vm.stack[vm.sp-1]
- }
- func (vm *VM) Run() error {
- for ip := 0; ip < len(vm.instructions); ip++ {
- op := code.Opcode(vm.instructions[ip])
- switch op {
- case code.OpConstant:
- constIndex := code.ReadUint16(vm.instructions[ip+1:])
- ip += 2
- // 执行
- err := vm.push(vm.constants[constIndex])
- if err != nil {
- return err
- }
- case code.OpAdd:
- right := vm.pop()
- left := vm.pop()
- leftValue := left.(*object.Integer).Value
- rightValue := right.(*object.Integer).Value
- result := leftValue + rightValue
- err := vm.push(&object.Integer{Value: result})
- if err != nil {
- return err
- }
- }
- }
- return nil
- }
- func (vm *VM) push(o object.Object) error {
- if vm.sp >= StackSize {
- return fmt.Errorf("stack overflow")
- }
- vm.stack[vm.sp] = o
- vm.sp++
- return nil
- }
- func (vm *VM) pop() object.Object {
- o := vm.stack[vm.sp-1]
- vm.sp--
- return o
- }
|