class Koota::VM
Implements a Koota
virtual machine.
Constants
- CALL_STACK_MAX
Public Class Methods
new(random: Random.new)
click to toggle source
# File lib/koota/vm.rb, line 20 def initialize(random: Random.new) @random = random end
Public Instance Methods
call(memory)
click to toggle source
# File lib/koota/vm.rb, line 24 def call(memory) output = ''.dup call_stack = [] offset = 0 while offset < memory.length op = memory[offset] offset += 1 case op when Opcodes::HALT then break when Opcodes::JUMP offset = Decode.short(memory, offset) when Opcodes::PUT decoded, advance = Decode.utf8(memory, offset) output << decoded offset += advance when Opcodes::PICK list_pointer = Decode.short(memory, offset) list_length = Decode.short(memory, list_pointer) # Jump to the chosen offset. # Multiply the rand by two because each offset has two bytes, and the # list length represents the length of each two-byte block. # Also, the offset starts at 1 to skip the list length. offset = Decode.short(memory, list_pointer + 2 * @random.rand(1..list_length)) when Opcodes::CALL break if call_stack.length >= CALL_STACK_MAX routine_pointer = Decode.short(memory, offset) call_stack.push(offset + 2) # opcode after the routine pointer offset = routine_pointer when Opcodes::RET offset = call_stack.pop break if offset.nil? when Opcodes::JRND offset = @random.rand(2) == 1 ? Decode.short(memory, offset) : offset + 2 else break end end output end