Start line:  
End line:  

Snippet Preview

Snippet HTML Code

Stack Overflow Questions
   /*
    * Copyright The Sett Ltd, 2005 to 2014.
    *
    * Licensed under the Apache License, Version 2.0 (the "License");
    * you may not use this file except in compliance with the License.
    * You may obtain a copy of the License at
    *
    *     http://www.apache.org/licenses/LICENSE-2.0
    *
   * Unless required by applicable law or agreed to in writing, software
   * distributed under the License is distributed on an "AS IS" BASIS,
   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
   * See the License for the specific language governing permissions and
   * limitations under the License.
   */
  package com.thesett.aima.logic.fol.wam.compiler;
  
  import java.util.EnumSet;
  import java.util.HashMap;
  import java.util.List;
  import java.util.Map;
  
WAMInstruction provides a structured in-memory representation of the WAM instruction set, as well as utilities to emmit the instructions as byte code, disassemble them back into the structured representation, and pretty print them.

Instructions implement com.thesett.common.util.Sizeable reporting their length in bytes as their 'size of'.

CRC Card
Responsibilities Collaborations
Provide the translation of the WAM instruction set down to bytes.
Provide dissasembly of byte encoded instructions back into structured instructions.
Calculate the length of an instruction in bytes. com.thesett.common.util.Sizeable

Author(s):
Rupert Smith
  
  public class WAMInstruction implements Sizeable
  {
    
Instruction to write out a struc onto the heap.
  
      public static final byte PUT_STRUC = 0x01;

    
The instruction to set a register as a variable.
  
      public static final byte SET_VAR = 0x02;

    
The instruction to set a register to a heap location.
  
      public static final byte SET_VAL = 0x03;

    
The instruction to compare a register to a structure on the heap.
  
      public static final byte GET_STRUC = 0x04;

    
The instruction to unify a register with a variable.
  
      public static final byte UNIFY_VAR = 0x05;

    
The instruction to unify a register with a location on the heap.
  
      public static final byte UNIFY_VAL = 0x06;

    
The instruction to copy a heap location into an argument register.
  
      public static final byte PUT_VAR = 0x07;

    
The instruction to copy a register into an argument register.
  
      public static final byte PUT_VAL = 0x08;

    
The instruction to unify an argument register with a variable.
  
      public static final byte GET_VAR = 0x09;

    
The instruction to unify a register with a location on the heap.
  
      public static final byte GET_VAL = 0x0a;

    
The instruction to copy a constant into an argument register.
  
      public static final byte PUT_CONST = 0x12;

    
The instruction to compare or bind a reference from a register to a constant.
  
      public static final byte GET_CONST = 0x13;

    
The instruction to write a constant onto the heap.
  
      public static final byte SET_CONST = 0x14;

    
The instruction to unify the heap with a constant.
  
      public static final byte UNIFY_CONST = 0x15;

    
The instruction to copy a list pointer into an argument register.
  
      public static final byte PUT_LIST = 0x16;

    
The instruction to compare or bind a reference from a register to a list pointer.
  
     public static final byte GET_LIST = 0x17;

    
The instruction to write an anonymous variable onto the heap.
 
     public static final byte SET_VOID = 0x18;

    
The instruction to unify with anonymous variables on the heap.
 
     public static final byte UNIFY_VOID = 0x19;

    
The instruction to initialize an argument register, ensuring the stack variable it references is globalized.
 
     public static final byte PUT_UNSAFE_VAL = 0x1c;

    
The instruction to set a register, ensuring the stack variable it references is globalized.
 
     public static final byte SET_LOCAL_VAL = 0x1d;

    
The instruction to unify a register, ensuring any stack variable it references is globalized.
 
     public static final byte UNIFY_LOCAL_VAL = 0x1e;

    
The instruction to call a predicate.
 
     public static final byte CALL = 0x0b;

    
The instruction to tail call a predicate.
 
     public static final byte EXECUTE = 0x1a;

    
The instruction to return from a called predicate.
 
     public static final byte PROCEED = 0x0c;

    
The stack frame allocation instruction.
 
     public static final byte ALLOCATE = 0x1b;

    
The stack frame allocation instruction for queries.
 
     public static final byte ALLOCATE_N = 0x0d;

    
The stack frame de-allocation instruction.
 
     public static final byte DEALLOCATE = 0x0e;

    
The first clause try instruction.
 
     public static final byte TRY_ME_ELSE = 0x0f;

    
The middle clause retry instruction.
 
     public static final byte RETRY_ME_ELSE = 0x10;

    
The final clause trust or fail instruction.
 
     public static final byte TRUST_ME = 0x11;

    
The first clause indexing try instruction.
 
     public static final byte TRY = 0x1f;

    
The middle clause indexing retry instruction.
 
     public static final byte RETRY = 0x20;

    
The final clause indexing trust or fail instruction.
 
     public static final byte TRUST = 0x21;

    
The second level indexing instruction.
 
     public static final byte SWITCH_ON_TERM = 0x22;

    
The third level indexing instruction for constants.
 
     public static final byte SWITCH_ON_CONST = 0x23;

    
The third level indexing instruction for structures.
 
     public static final byte SWITCH_ON_STRUC = 0x24;

    
The simpler neck-cut instruction.
 
     public static final byte NECK_CUT = 0x25;

    
The get level instruction for cuts.
 
     public static final byte GET_LEVEL = 0x26;

    
The full deep cut instruction.
 
     public static final byte CUT = 0x27;

    
The continue instruction for inline choice points.
 
     public static final byte CONTINUE = 0x28;

    
The no-op instruction, useful for inserting labels into the code.
 
     public static final byte NO_OP = 0x29;

    
The internal call instruction for intrinsics.
 
     public static final byte CALL_INTERNAL = 0x2a;

    
The suspend operation.
 
     public static final byte SUSPEND = 0x7f;
 
     // === Defines the addressing modes.
 
    
Used to specify addresses relative to registers.
 
     public static final byte REG_ADDR = 0x01;

    
Used to specify addresses relative to the current stack frame.
 
     public static final byte STACK_ADDR = 0x02;
 
     // === Defines the heap cell marker types.
 
    
Indicates a reference data type.
 
     public static final byte REF = 0x00;

    
Indicates a structure data type.
 
     public static final byte STR = 0x01;

    
Indicates a constant atom data type.
 
     public static final byte CON = 0x02;

    
Indicates a list data type.
 
     public static final byte LIS = 0x03;

    
Defines the L0 virtual machine instruction set as constants.
 
     public enum WAMInstructionSet
     {
        
Instruction to write out a struc onto the heap.
 
         PutStruc("put_struc", 7, 0xb)
         {
            
 
             protected void disassembleArguments(WAMInstruction instructionint ipByteBuffer codeBuf,
                 VariableAndFunctorInterner interner)
             {
                 disassembleReg1Fn(codeBufipinstructioninterner);
             }

            
 
             public void emmitCode(WAMInstruction instructionByteBuffer codeBufWAMMachine machine)
             {
                 emmitCodeReg1Fn(codeBufinstructionmachine);
             }

            
 
             public String toString(WAMInstruction instruction)
             {
                 return toStringReg1Fn(instruction);
             }
         },

        
The instruction to set a register as a variable.
 
         SetVar("set_var", 3, 0x3),

        
The instruction to set a register to a heap location.
 
         SetVal("set_val", 3, 0x3),

        
The instruction to set a register, ensuring the stack variable it references is globalized.
 
         SetLocalVal("set_local_val", 3, 0x3),

        
The instruction to compare a register to a structure on the heap.
 
         GetStruc("get_struc", 7, 0xb)
         {
            
 
             protected void disassembleArguments(WAMInstruction instructionint ipByteBuffer codeBuf,
                 VariableAndFunctorInterner interner)
             {
                 disassembleReg1Fn(codeBufipinstructioninterner);
             }

            
 
             public void emmitCode(WAMInstruction instructionByteBuffer codeBufWAMMachine machine)
             {
                 emmitCodeReg1Fn(codeBufinstructionmachine);
             }

            
 
             public String toString(WAMInstruction instruction)
             {
                 return toStringReg1Fn(instruction);
             }
         },

        
The instruction to unify a register with a variable.
 
         UnifyVar("unify_var", 3, 0x3),

        
The instruction to unify a register with a location on the heap.
 
         UnifyVal("unify_val", 3, 0x3),

        
The instruction to unify a register, ensuring any stack variable it references is globalized.
 
         UnifyLocalVal("unify_local_val", 3, 0x3),

        
The instruction to copy a heap location into an argument register.
 
         PutVar("put_var", 4, 0x7)
         {
            
 
             protected void disassembleArguments(WAMInstruction instructionint ipByteBuffer codeBuf,
                 VariableAndFunctorInterner interner)
             {
                 disassembleReg1Reg2(codeBufipinstruction);
             }

            
 
             public void emmitCode(WAMInstruction instructionByteBuffer codeBufWAMMachine machine)
             {
                 emmitCodeReg1Reg2(codeBufinstruction);
             }

            
 
             public String toString(WAMInstruction instruction)
             {
                 return toStringReg1Reg2(instruction);
             }
         },

        
The instruction to copy a register into an argument register.
 
         PutVal("put_val", 4, 0x7)
         {
            
 
             protected void disassembleArguments(WAMInstruction instructionint ipByteBuffer codeBuf,
                 VariableAndFunctorInterner interner)
             {
                 disassembleReg1Reg2(codeBufipinstruction);
             }

            
 
             public void emmitCode(WAMInstruction instructionByteBuffer codeBufWAMMachine machine)
             {
                 emmitCodeReg1Reg2(codeBufinstruction);
             }

            
 
             public String toString(WAMInstruction instruction)
             {
                 return toStringReg1Reg2(instruction);
             }
         },

        
The instruction to initialize an argument register, ensuring the stack variable it references is globalized.
 
         PutUnsafeVal("put_unsafe_val", 4, 0x7)
         {
            
 
             public void emmitCode(WAMInstruction instructionByteBuffer codeBufWAMMachine machine)
             {
                 emmitCodeReg1Reg2(codeBufinstruction);
             }

            
 
             public String toString(WAMInstruction instruction)
             {
                 return toStringReg1Reg2(instruction);
             }
         },

        
The instruction to unify an argument register with a variable.
 
         GetVar("get_var", 4, 0x7)
         {
            
 
             protected void disassembleArguments(WAMInstruction instructionint ipByteBuffer codeBuf,
                 VariableAndFunctorInterner interner)
             {
                 disassembleReg1Reg2(codeBufipinstruction);
             }

            
 
             public void emmitCode(WAMInstruction instructionByteBuffer codeBufWAMMachine machine)
             {
                 emmitCodeReg1Reg2(codeBufinstruction);
             }

            
 
             public String toString(WAMInstruction instruction)
             {
                 return toStringReg1Reg2(instruction);
             }
         },

        
The instruction to unify a register with a location on the heap.
 
         GetVal("get_val", 4, 0x7)
         {
            
 
             protected void disassembleArguments(WAMInstruction instructionint ipByteBuffer codeBuf,
                 VariableAndFunctorInterner interner)
             {
                 disassembleReg1Reg2(codeBufipinstruction);
             }

            
 
             public void emmitCode(WAMInstruction instructionByteBuffer codeBufWAMMachine machine)
             {
                 emmitCodeReg1Reg2(codeBufinstruction);
             }

            
 
             public String toString(WAMInstruction instruction)
             {
                 return toStringReg1Reg2(instruction);
             }
         },

        
The instruction to copy a constant into an argument register.
 
         PutConstant("put_const", 7, 0xb)
         {
            
 
             protected void disassembleArguments(WAMInstruction instructionint ipByteBuffer codeBuf,
                 VariableAndFunctorInterner interner)
             {
                 disassembleReg1Fn(codeBufipinstructioninterner);
             }

            
 
             public void emmitCode(WAMInstruction instructionByteBuffer codeBufWAMMachine machine)
                 throws LinkageException
             {
                 emmitCodeReg1Fn(codeBufinstructionmachine);
             }

            
 
             public String toString(WAMInstruction instruction)
             {
                 return toStringReg1Fn(instruction);
             }
         },

        
The instruction to compare or bind a reference from a register to a constant.
 
         GetConstant("get_const", 7, 0xb)
         {
            
 
             protected void disassembleArguments(WAMInstruction instructionint ipByteBuffer codeBuf,
                 VariableAndFunctorInterner interner)
             {
                 disassembleReg1Fn(codeBufipinstructioninterner);
             }

            
 
             public void emmitCode(WAMInstruction instructionByteBuffer codeBufWAMMachine machine)
                 throws LinkageException
             {
                 emmitCodeReg1Fn(codeBufinstructionmachine);
             }

            
 
             public String toString(WAMInstruction instruction)
             {
                 return toStringReg1Fn(instruction);
             }
         },

        
The instruction to write a constant onto the heap.
 
         SetConstant("set_const", 5, 0x8)
         {
            
 
             protected void disassembleArguments(WAMInstruction instructionint ipByteBuffer codeBuf,
                 VariableAndFunctorInterner interner)
             {
                 disassembleFn(codeBufipinstructioninterner);
             }

            
 
             public void emmitCode(WAMInstruction instructionByteBuffer codeBufWAMMachine machine)
                 throws LinkageException
             {
                 emmitCodeFn(codeBufinstructionmachine);
             }

            
 
             public String toString(WAMInstruction instruction)
             {
                 return toStringFn(instruction);
             }
         },

        
The instruction to unify the heap with a constant.
 
         UnifyConstant("unify_const", 5, 0x8)
         {
            
 
             protected void disassembleArguments(WAMInstruction instructionint ipByteBuffer codeBuf,
                 VariableAndFunctorInterner interner)
             {
                 disassembleFn(codeBufipinstructioninterner);
             }

            
 
             public void emmitCode(WAMInstruction instructionByteBuffer codeBufWAMMachine machine)
                 throws LinkageException
             {
                 emmitCodeFn(codeBufinstructionmachine);
             }

            
 
             public String toString(WAMInstruction instruction)
             {
                 return toStringFn(instruction);
             }
         },

        
The instruction to copy a list pointer into an argument register.
 
         PutList("put_list", 3, 0x3),

        
The instruction to compare or bind a reference from a register to a list pointer.
 
         GetList("get_list", 3, 0x3),

        
The instruction to write an anonymous variable onto the heap.
 
         SetVoid("set_void", 2, 0x2)
         {
            
 
             protected void disassembleArguments(WAMInstruction instructionint ipByteBuffer codeBuf,
                 VariableAndFunctorInterner interner)
             {
                 disassembleReg1NoMode(codeBufipinstruction);
             }

            
 
             public void emmitCode(WAMInstruction instructionByteBuffer codeBufWAMMachine machine)
             {
                 emmitCodeReg1NoMode(codeBufinstruction);
             }

            
 
             public String toString(WAMInstruction instruction)
             {
                 return  + " " + instruction.reg1;
             }
         },

        
The instruction to unify with anonymous variables on the heap.
 
         UnifyVoid("unify_void", 2, 0x2)
         {
            
 
             protected void disassembleArguments(WAMInstruction instructionint ipByteBuffer codeBuf,
                 VariableAndFunctorInterner interner)
             {
                 disassembleReg1NoMode(codeBufipinstruction);
             }

            
 
             public void emmitCode(WAMInstruction instructionByteBuffer codeBufWAMMachine machine)
             {
                 emmitCodeReg1NoMode(codeBufinstruction);
             }

            
 
             public String toString(WAMInstruction instruction)
             {
                 return  + " " + instruction.reg1;
             }
         },

        
The instruction to call a predicate.
 
         Call("call", 7, 0xa)
         {
            
 
             protected void disassembleArguments(WAMInstruction instructionint ipByteBuffer codeBuf,
                 VariableAndFunctorInterner interner)
             {
                 int entryPoint = codeBuf.getInt(ip + 1);
                 int arity = codeBuf.get(ip + 5);
                 instruction.reg1 = codeBuf.get(ip + 6);
             }

            
 
             public void emmitCode(WAMInstruction instructionByteBuffer codeBufWAMMachine machine)
                 throws LinkageException
             {
                 int toCall = machine.internFunctorName(instruction.fn);
 
                 WAMCallPoint callPointToCall = machine.resolveCallPoint(toCall);
 
                 // Ensure that a valid call point was returned, otherwise a linkage error has occurred.
                 if (callPointToCall == null)
                 {
                     throw new LinkageException("Could not resolve call to " + instruction.fn + "."nullnull,
                         "Unable to resolve call to " + instruction.fn.getName() + "/" + instruction.fn.getArity() +
                         ".");
                 }
 
                 int entryPoint = callPointToCall.entryPoint;
 
                 codeBuf.put();
                 codeBuf.putInt(entryPoint);
                 codeBuf.put((byteinstruction.fn.getArity());
                 codeBuf.put(instruction.reg1);
             }

            
 
             public String toString(WAMInstruction instruction)
             {
                 return  + " " +
                     ((instruction.fn != null) ? (instruction.fn.getName() + "/" + instruction.fn.getArity()) : "") +
                     (", " + instruction.reg1);
             }
         },

        
The instruction to tail call a predicate.
 
         Execute("execute", 6, 0x8)
         {
            
 
             protected void disassembleArguments(WAMInstruction instructionint ipByteBuffer codeBuf,
                 VariableAndFunctorInterner interner)
             {
                 int entryPoint = codeBuf.getInt(ip + 1);
                 int arity = codeBuf.get(ip + 5);
             }

            
 
             public void emmitCode(WAMInstruction instructionByteBuffer codeBufWAMMachine machine)
                 throws LinkageException
             {
                 int toCall = machine.internFunctorName(instruction.fn);
 
                 WAMCallPoint callPointToCall = machine.resolveCallPoint(toCall);
 
                 // Ensure that a valid call point was returned, otherwise a linkage error has occurred.
                 if (callPointToCall == null)
                 {
                     throw new LinkageException("Could not resolve call to " + instruction.fn + "."nullnull,
                         "Unable to resolve call to " + instruction.fn.getName() + "/" + instruction.fn.getArity() +
                         ".");
                 }
 
                 int entryPoint = callPointToCall.entryPoint;
 
                 codeBuf.put();
                 codeBuf.putInt(entryPoint);
                 codeBuf.put((byteinstruction.fn.getArity());
             }

            
 
             public String toString(WAMInstruction instruction)
             {
                 return  + " " +
                     ((instruction.fn != null) ? (instruction.fn.getName() + "/" + instruction.fn.getArity()) : "");
             }
         },

        
The instruction to return from a called predicate.
 
         Proceed("proceed", 1, 0x0)
         {
            
 
             protected void disassembleArguments(WAMInstruction instructionint ipByteBuffer codeBuf,
                 VariableAndFunctorInterner interner)
             {
                 // Do nothing as this instruction takes no arguments.
             }

            
 
             public void emmitCode(WAMInstruction instructionByteBuffer codeBufWAMMachine machine)
             {
                 codeBuf.put();
             }

            
 
             public String toString(WAMInstruction instruction)
             {
                 return ;
             }
         },

        
The stack frame allocation instruction.
 
         Allocate("allocate", 1, 0x0)
         {
            
 
             protected void disassembleArguments(WAMInstruction instructionint ipByteBuffer codeBuf,
                 VariableAndFunctorInterner interner)
             {
                 // Do nothing as this instruction takes no arguments.
             }

            
 
             public void emmitCode(WAMInstruction instructionByteBuffer codeBufWAMMachine machine)
             {
                 codeBuf.put();
             }

            
 
             public String toString(WAMInstruction instruction)
             {
                 return ;
             }
         },

        
The stack frame allocation instruction for queries.
 
         AllocateN("allocate_n", 2, 0x2)
         {
            
 
             protected void disassembleArguments(WAMInstruction instructionint ipByteBuffer codeBuf,
                 VariableAndFunctorInterner interner)
             {
                 disassembleReg1NoMode(codeBufipinstruction);
             }

            
 
             public void emmitCode(WAMInstruction instructionByteBuffer codeBufWAMMachine machine)
             {
                 emmitCodeReg1NoMode(codeBufinstruction);
             }

            
 
             public String toString(WAMInstruction instruction)
             {
                 return  + " " + instruction.reg1;
             }
         },

        
The stack frame deallocation instruction.
 
         Deallocate("deallocate", 1, 0x0)
         {
            
 
             protected void disassembleArguments(WAMInstruction instructionint ipByteBuffer codeBuf,
                 VariableAndFunctorInterner interner)
             {
                 // Do nothing as this instruction takes no arguments.
             }

            
 
             public void emmitCode(WAMInstruction instructionByteBuffer codeBufWAMMachine machine)
             {
                 codeBuf.put();
             }

            
 
             public String toString(WAMInstruction instruction)
             {
                 return ;
             }
         },

        
The first clause try instruction.
 
         TryMeElse("try_me_else", 5, 0x10)
         {
            
 
             protected void disassembleArguments(WAMInstruction instructionint ipByteBuffer codeBuf,
                 VariableAndFunctorInterner interner)
             {
                 int label = codeBuf.getInt(ip + 1);
             }

            
 
             public void emmitCode(WAMInstruction instructionByteBuffer codeBufWAMMachine machine)
                 throws LinkageException
             {
                 int ip = codeBuf.position();
 
                 // Intern the alternative forward label, and write it out as zero initially, for later completion.
                 int toCall = machine.internFunctorName(instruction.target1);
                 machine.reserveReferenceToLabel(toCallip + 1);
 
                 codeBuf.put();
                 codeBuf.putInt(0);
             }

            
 
             public String toString(WAMInstruction instruction)
             {
                 WAMLabel label = instruction.target1;
 
                 return  + " " + ((label != null) ? label.toPrettyString() : "");
             }
         },

        
The middle clause retry instruction.
 
         RetryMeElse("retry_me_else", 5, 0x10)
         {
            
 
             protected void disassembleArguments(WAMInstruction instructionint ipByteBuffer codeBuf,
                 VariableAndFunctorInterner interner)
             {
                 int label = codeBuf.getInt(ip + 1);
             }

            
 
             public void emmitCode(WAMInstruction instructionByteBuffer codeBufWAMMachine machine)
                 throws LinkageException
             {
                 int ip = codeBuf.position();
 
                 // Resolve any forward reference to the label for this instruction.
                 int label = machine.internFunctorName(instruction.label);
                 machine.resolveLabelPoint(labelip);
 
                 // Intern the alternative forward label, and write it out as zero initially, for later completion.
                 int toCall = machine.internFunctorName(instruction.target1);
                 machine.reserveReferenceToLabel(toCallip + 1);
 
                 codeBuf.put();
                 codeBuf.putInt(0);
             }

            
 
             public String toString(WAMInstruction instruction)
             {
                 WAMLabel label = instruction.target1;
 
                 return  + " " + ((label != null) ? label.toPrettyString() : "");
             }
         },

        
The final clause trust or fail instruction.
 
         TrustMe("trust_me", 1, 0x0)
         {
            
 
             protected void disassembleArguments(WAMInstruction instructionint ipByteBuffer codeBuf,
                 VariableAndFunctorInterner interner)
             {
                 // Do nothing as this instruction takes no arguments.
             }

            
 
             public void emmitCode(WAMInstruction instructionByteBuffer codeBufWAMMachine machine)
             {
                 int ip = codeBuf.position();
 
                 // Resolve any forward reference to the label for this instruction.
                 int label = machine.internFunctorName(instruction.label);
                 machine.resolveLabelPoint(labelip);
 
                 codeBuf.put();
             }

            
 
             public String toString(WAMInstruction instruction)
             {
                 return ;
             }
         },

        
The first clause indexing try instruction.
 
         Try("try", 5, 0x10)
         {
            
 
             protected void disassembleArguments(WAMInstruction instructionint ipByteBuffer codeBuf,
                 VariableAndFunctorInterner interner)
             {
                 int label = codeBuf.getInt(ip + 1);
             }

            
 
             public void emmitCode(WAMInstruction instructionByteBuffer codeBufWAMMachine machine)
                 throws LinkageException
             {
                 int ip = codeBuf.position();
 
                 // Resolve any forward reference to the label for this instruction.
                 if (instruction.label != null)
                 {
                     int label = machine.internFunctorName(instruction.label);
                     machine.resolveLabelPoint(labelip);
                 }
 
                 // Intern the forward label, and write it out as zero initially, for later completion.
                 int toCall = machine.internFunctorName(instruction.target1);
                 machine.reserveReferenceToLabel(toCallip + 1);
 
                 codeBuf.put();
                 codeBuf.putInt(0);
             }

            
 
             public String toString(WAMInstruction instruction)
             {
                 WAMLabel label = instruction.target1;
 
                 return  + " " + ((label != null) ? label.toPrettyString() : "");
             }
         },

        
The middle clause indexing retry instruction.
 
         Retry("retry", 5, 0x10)
         {
            
 
             protected void disassembleArguments(WAMInstruction instructionint ipByteBuffer codeBuf,
                 VariableAndFunctorInterner interner)
             {
                 int label = codeBuf.getInt(ip + 1);
             }

            
 
             public void emmitCode(WAMInstruction instructionByteBuffer codeBufWAMMachine machine)
                 throws LinkageException
             {
                 int ip = codeBuf.position();
 
                 // Resolve any forward reference to the label for this instruction.
                 if (instruction.label != null)
                 {
                     int label = machine.internFunctorName(instruction.label);
                     machine.resolveLabelPoint(labelip);
                 }
 
                 // Intern the forward label, and write it out as zero initially, for later completion.
                 int toCall = machine.internFunctorName(instruction.target1);
                 machine.reserveReferenceToLabel(toCallip + 1);
 
                 codeBuf.put();
                 codeBuf.putInt(0);
             }

            
 
             public String toString(WAMInstruction instruction)
             {
                 WAMLabel label = instruction.target1;
 
                 return  + " " + ((label != null) ? label.toPrettyString() : "");
             }
         },

        
The final clause indexing trust or fail instruction.
 
         Trust("trust", 5, 0x10)
         {
            
 
             protected void disassembleArguments(WAMInstruction instructionint ipByteBuffer codeBuf,
                 VariableAndFunctorInterner interner)
             {
                 int label = codeBuf.getInt(ip + 1);
             }

            
 
             public void emmitCode(WAMInstruction instructionByteBuffer codeBufWAMMachine machine)
             {
                 int ip = codeBuf.position();
 
                 // Resolve any forward reference to the label for this instruction.
                 if (instruction.label != null)
                 {
                     int label = machine.internFunctorName(instruction.label);
                     machine.resolveLabelPoint(labelip);
                 }
 
                 // Intern the forward label, and write it out as zero initially, for later completion.
                 int toCall = machine.internFunctorName(instruction.target1);
                 machine.reserveReferenceToLabel(toCallip + 1);
 
                 codeBuf.put();
                 codeBuf.putInt(0);
             }

            
 
             public String toString(WAMInstruction instruction)
             {
                 return ;
             }
         },

        
The second level indexing instruction.
 
         SwitchOnTerm("switch_on_term", 17, 0x0)
         {
            
 
             public void emmitCode(WAMInstruction instructionByteBuffer codeBufWAMMachine machine)
                 throws LinkageException
             {
                 int ip = codeBuf.position();
 
                 // Resolve any forward reference to the label for this instruction.
                 int label = machine.internFunctorName(instruction.label);
                 machine.resolveLabelPoint(labelip);
 
                 // Intern the alternative forward labels, and write them out as zero initially, for later completion.
                 int jump = machine.internFunctorName(instruction.target1);
                 machine.reserveReferenceToLabel(jumpip + 1);
 
                 jump = machine.internFunctorName(instruction.target2);
                 machine.reserveReferenceToLabel(jumpip + 5);
 
                 jump = machine.internFunctorName(instruction.target3);
                 machine.reserveReferenceToLabel(jumpip + 9);
 
                 jump = machine.internFunctorName(instruction.target4);
                 machine.reserveReferenceToLabel(jumpip + 13);
 
                 codeBuf.put();
                 codeBuf.putInt(0);
             }

            
 
             public String toString(WAMInstruction instruction)
             {
                 return  + " " + labelToString(instruction.target1) + " / " + labelToString(instruction.target2) +
                     " / " + labelToString(instruction.target3) + " / " + labelToString(instruction.target4);
             }
         },

        
The third level indexing instruction for constants.
 
         SwitchOnConst("switch_on_const", 9, 0x0)
         {
            
 
             public void emmitCode(WAMInstruction instructionByteBuffer codeBufWAMMachine machine)
                 throws LinkageException
             {
                 int ip = codeBuf.position();
 
                 // Resolve any forward reference to the label for this instruction.
                 int label = machine.internFunctorName(instruction.label);
                 machine.resolveLabelPoint(labelip);
 
                 // Intern the alternative forward labels, and write them out as zero initially, for later completion.
                 int jump = machine.internFunctorName(instruction.target1);
                 machine.reserveReferenceToLabel(jumpip + 1);
 
                 jump = machine.internFunctorName(instruction.target2);
                 machine.reserveReferenceToLabel(jumpip + 5);
 
                 codeBuf.put();
                 codeBuf.putInt(0);
             }

            
 
             public String toString(WAMInstruction instruction)
             {
                 return  + " " + labelToString(instruction.target1) + " / " + labelToString(instruction.target2);
             }
         },

        
The third level indexing instruction for structures.
 
         SwitchOnStruc("switch_on_struc", 9, 0x0)
         {
            
 
             public void emmitCode(WAMInstruction instructionByteBuffer codeBufWAMMachine machine)
                 throws LinkageException
            {
                int ip = codeBuf.position();
                // Resolve any forward reference to the label for this instruction.
                int label = machine.internFunctorName(instruction.label);
                machine.resolveLabelPoint(labelip);
                // Intern the alternative forward labels, and write them out as zero initially, for later completion.
                int jump = machine.internFunctorName(instruction.target1);
                machine.reserveReferenceToLabel(jumpip + 1);
                jump = machine.internFunctorName(instruction.target2);
                machine.reserveReferenceToLabel(jumpip + 5);
                codeBuf.put();
                codeBuf.putInt(0);
            }

            
            public String toString(WAMInstruction instruction)
            {
                return  + " " + labelToString(instruction.target1) + " / " + labelToString(instruction.target2);
            }
        },

        
The simpler neck-cut instruction.
        NeckCut("neck_cut", 1, 0x0)
        {
            
            protected void disassembleArguments(WAMInstruction instructionint ipByteBuffer codeBuf,
                VariableAndFunctorInterner interner)
            {
                // Do nothing as this instruction takes no arguments.
            }

            
            public void emmitCode(WAMInstruction instructionByteBuffer codeBufWAMMachine machine)
            {
                codeBuf.put();
            }

            
            public String toString(WAMInstruction instruction)
            {
                return ;
            }
        },

        
The get level instruction for cuts.
        GetLevel("get_level", 2, 0x2)
        {
            
            protected void disassembleArguments(WAMInstruction instructionint ipByteBuffer codeBuf,
                VariableAndFunctorInterner interner)
            {
                disassembleReg1NoMode(codeBufipinstruction);
            }

            
            public void emmitCode(WAMInstruction instructionByteBuffer codeBufWAMMachine machine)
            {
                emmitCodeReg1NoMode(codeBufinstruction);
            }

            
            public String toString(WAMInstruction instruction)
            {
                return  + " " + instruction.reg1;
            }
        },

        
The full deep cut instruction.
        Cut("cut", 2, 0x2)
        {
            
            protected void disassembleArguments(WAMInstruction instructionint ipByteBuffer codeBuf,
                VariableAndFunctorInterner interner)
            {
                disassembleReg1NoMode(codeBufipinstruction);
            }

            
            public void emmitCode(WAMInstruction instructionByteBuffer codeBufWAMMachine machine)
            {
                emmitCodeReg1NoMode(codeBufinstruction);
            }

            
            public String toString(WAMInstruction instruction)
            {
                return  + " " + instruction.reg1;
            }
        },

        
The continue instruction for inline choice points.
        Continue("continue", 5, 0x10)
        {
            
            protected void disassembleArguments(WAMInstruction instructionint ipByteBuffer codeBuf,
                VariableAndFunctorInterner interner)
            {
                int label = codeBuf.getInt(ip + 1);
            }

            
            public void emmitCode(WAMInstruction instructionByteBuffer codeBufWAMMachine machine)
                throws LinkageException
            {
                int ip = codeBuf.position();
                // Intern the forward label, and write it out as zero initially, for later completion.
                int toCall = machine.internFunctorName(instruction.target1);
                machine.reserveReferenceToLabel(toCallip + 1);
                codeBuf.put();
                codeBuf.putInt(0);
            }

            
            public String toString(WAMInstruction instruction)
            {
                WAMLabel label = instruction.target1;
                return  + " " + ((label != null) ? label.toPrettyString() : "");
            }
        },

        
The no-op instruction, useful for inserting labels into the code.
        NoOp("no_op", 1, 0x0)
        {
            
            protected void disassembleArguments(WAMInstruction instructionint ipByteBuffer codeBuf,
                VariableAndFunctorInterner interner)
            {
                // Do nothing as this instruction takes no arguments.
            }

            
            public void emmitCode(WAMInstruction instructionByteBuffer codeBufWAMMachine machine)
            {
                int ip = codeBuf.position();
                // Resolve any forward reference to the label for this instruction.
                int label = machine.internFunctorName(instruction.label);
                machine.resolveLabelPoint(labelip);
                codeBuf.put();
            }

            
            public String toString(WAMInstruction instruction)
            {
                return ;
            }
        },

        
The instruction to call a predicate.
        CallInternal("call_internal", 7, 0xa)
        {
            
            protected void disassembleArguments(WAMInstruction instructionint ipByteBuffer codeBuf,
                VariableAndFunctorInterner interner)
            {
                int entryPoint = codeBuf.getInt(ip + 1);
                int arity = codeBuf.get(ip + 5);
                instruction.reg1 = codeBuf.get(ip + 6);