*** immediate values, bits 4..7
  if value = 15
    add next byte & 0x&F to value
      while next byte & 0x80
     
*** opcodes, bits 0..3
0 - message invocation
    argument count - bits 4..7
    pop selector or block and arguments from stack
    save return instruction pointer in stack frame
    if selector or block is a selector
      dispatch selector on arguments to find block
    establish frame for block and execute it
    push result on stack

1 - load variable 
    variable index - bits 4..7
    push variable on stack

2 - store variable
    variable index - bits 4..7
    store top of stack in variable

3 - load free variable
    lexical offset - bits 4..7
    free variable index - next byte
    push free variable at -offset on stack
 
4 - store free variable
    lexical offset - bits 4..7
    free variable index - next byte
    store top of stack in free variable at -offset

5 - load literal
    literal index - bits 4..7
    push literal on stack

6 - load selector
    selector index - bits 4..7
    push selector on stack
    
7 - pop
    pop count - bits 4..7
    pop count values from the stack
    
8 - push array
    array size - bits 4..7
    pop size arguments from stack 
    allocate array of size and fill array with arguments
    push array on stack

9 - new block 
    literal block index - bits 4..7
    push literal block on stack
    setup literal block's lexical window

A - branch keyed
    literal table index - bits 4..7
    pop top of stack
    find displacement associated with top of stack in literal table
    add displacement to code pointer

    table is an array of the form { key. displacement. ... }

B - message invocation with optionals
    argument count - bits 4..7
    pop selector or block, optional keyword array, and arguments from stack
    save return instruction pointer in stack frame
    if selector or block is a selector
      dispatch selector on arguments to find block
    establish frame for block and execute it
    push result on stack

C - non-local return
    lexical offset - bits 4..7
    pop value off stack
    return from the block at the lexical offset
    push value back on stack

D - push integer
    integer - bits 4..7
    push integer on stack

E - resend message
    lexical offset - bits 4..7
    resend message invocation at the lexical offset and push result on stack

F - extension
    extended opcode - bits 4..7
    0 - jump
        displacement (16 bit, signed) follows byte code
        add displacement to instruction pointer
    1 - branch if true
        displacement (16 bit, signed) follows byte code
        pop top of stack
        if top of stack was true
          add displacement to instruction pointer
    2 - branch if false
        displacement (16 bit, signed) follows byte code
        pop top of stack
        if top of stack was false
          add displacement to instruction pointer
    3 - push environment
        push environment on stack
    4 - push nil
        push nil on stack
    5 - ==
        pop top of stack
        pop top of stack
        push true or false on stack indicating if stack tops were ==
    6 - push true
        push true on stack
    7 - push false
        push false on stack
    8 - resume
        return from the currently executing method without passing along
        any result

*** stack format
  stack is an object array
  stack grows upwards
  lexical context
    0: method or block
    1: frame pointer or nil
    2: variable 0
    2+N-1: variable N-1
  frame
    -N: return instruction pointer (fixed integer)
    -N+1: variable 0
    -1: variable N-1
    0: previous frame pointer (fixed integer)
    1: currently executing block or method
    2: lexical context or nil
    ...
  input variables precede local variables in stack frame
  establishment
    overwrite selector with return instruction pointer on stack
    allocate space for variables on stack
    put current stack pointer in frame pointer
    push previous frame pointer on stack
    push block or method on stack
    if block needs free variables allocated
      allocate lexical context and push on stack
    otherwise
      push nil on stack
  de-establishment
    if lexical context is not nil
      set frame pointer in lexical context to nil
    temporarily save top of stack as result value
    set stack pointer to frame pointer
    set frame pointer to previous frame pointer
    pop return instruction pointer from stack into instruction pointer
    push result value on stack

*** block format
    0: input variable count (fixed integer)
    1: local variable count (fixed integer)
    2: free variable count (fixed integer)
    3: top level environment (namespace)
    4: lexical window (array of free variable arrays or nil)
    5: literal array (array of literals or nil)
    6: selector array (array of symbols or nil)
    7: code array (byte array of instructions)
    8: syntax tree (syntax node or nil)

*** method format (inherits fields from block format)
    0: selector (symbol)
    

