Skip to content

Latest commit

 

History

History
107 lines (73 loc) · 3.79 KB

VM.md

File metadata and controls

107 lines (73 loc) · 3.79 KB

The Koota Virtual Machine

The Koota virtual machine runs Koota bytecode. It has the concept of memory, which is a randomly-accessible field of opcodes, and an output, which is where the generation result is.

At all times, the virtual machine is at a memory address or offset, which is an unsigned 16-bit number (aka C unsigned short). The offset points to a memory location; therefore, the maximum amount of memory possible is 64 KiB (65536 bytes), which should be enough for any reasonable pattern. In every occasion, this offset is encoded big-endian.

The virtual machine’s starting offset is always 0x0000.

There is also the concept of a call stack. Offsets are stored in that stack by call to be used when ret is executed. The maximum length of the call stack is 256.

Bytecode

Koota bytecode has the following opcodes:

Opcode Mnemonic Description
0x00 halt Halts the machine, stopping word generation.
0x01 jump Jumps to the given offset.
0x02 put Puts the given character in the output.
0x03 pick Randomly picks an offset in the given list and jumps to it.
0x04 call Calls subroutine.
0x05 ret Returns from subroutine.
0x06 jrnd Randomly jumps to the given offset.

With these few opcodes, any Koota pattern can be “bytecodified”. In the following section, they will be explained in more detail.

Opcode 0x00: halt

  • Arguments: none
  • Total length: 1 byte

When this opcode is run, the machine halts, with the generated word in the output.

Opcode 0x01: jump

  • Arguments: an offset (2 bytes)
  • Total length: 3 bytes

When this opcode is run, the virtual machine’s offset becomes the offset argument, and execution continues from there.

Opcode 0x02: put

  • Arguments: an UTF-8 character (1 to 4 bytes)
  • Total length: 2 to 5 bytes

When this opcode is run, the virtual machine places the given character at the end of its output.

Opcode 0x03: pick

  • Arguments: an offset (2 bytes)
  • Total length: 3 bytes

When this opcode is run, the given offset is taken as the start pointer of a list of offsets, with the first element representing the length of the list. Then, an offset in that list is randomly picked, and that offset is jumped to.

Opcode 0x04: call

  • Arguments: an offset (2 bytes)
  • Total length: 3 bytes

When this opcode is run, the current offset plus one (i.e. the offset that would be ran if the call wasn’t there) is pushed to the call stack, and the given offset is jumped to. If the call stack is full (256 entries), then the virtual machine must halt.

Opcode 0x05: ret

  • Arguments: none
  • Total length: 1 byte

When this opcode is run, the topmost offset in the call stack is jumped to and the call stack is popped. This effectively returns to the next opcode after the last call, completing the subroutine.

If the call stack is empty, the virtual machine should put the string <ret with empty stack> in the output then immediately halt.

Opcode 0x06: jrnd

  • Arguments: an offset (2 bytes)
  • Total length: 3 bytes

When this opcode is run, there is 50% chance of jumping to the given offset. If the jump does not happen, this is a no-op.

Unrecognised opcodes

If the virtual machine finds an unrecognised opcode, it must halt.

Out of bounds

If the virtual machine tries to access an offset out of bounds of its memory, it must halt.