Hack VM is a tiny programming language (though its author calls it “virtual machine for hackers”, it still deserves to be called a language, since it is simple enough to write code by hand).

Hack VM was created by Adam Miller, and has only one implementation (two, if we count JavaScript and Python ones by the same author as different ones). It is unknown whether other esoteric languages influenced the creation of this one, though it seems quite likely.

The main (and only) purpose of this language is to use it in hacker.org challenges: some of the tasks require writing a program which produces a certain result. This makes this language one of the few really used esoteric languages.

A program in Hack VM is a string of single-character commands. Virtual machine starts with the first instruction, executes it, moves on to the next instruction, and so on. The index of the current instruction is called the program counter. The execution is terminated either when end of program is reached, ‘!’ instruction is met or some run-time exception is thrown.

Hack VM is a stack-based language: the virtual machine consists of an operand stack, a memory buffer, and a call stack. Each item on the operand stack or in memory is a cell that can hold a 32-bits signed integer. The call stack is used to push the value of the program counter when jumping to a routine from which we want to return. The memory buffer holds 16384 cells, indexed in 0-based way. By default, the execution starts with empty call stack, empty operand stack and all the cells in the memory buffer set to 0. It is possible to initialize the memory buffer with user-defined values, which can be used to simulate user input.

The commands of the language are the following (here S<n> denotes n-th element off the top of the stack: S0 is the topmost element):

' ' : Do nothing (used for readability purposes)

: Do nothing (used for readability purposes) 'p' : Print S0 as an integer

: Print S0 as an integer 'P' : Print S0 as an ASCII character (only the least significant 7 bits of the value are used)

: Print S0 as an ASCII character (only the least significant 7 bits of the value are used) '0'..'9' : Push the value 0..9 on the stack

: Push the value 0..9 on the stack '+', '-', '*', '/' : Push S1+S0, S1-S0, S1*S0, S1/S0

: Push S1+S0, S1-S0, S1*S0, S1/S0 ':' : Push -1 if S1<S0, 0 if S1=S0, or 1 S1>S0

: Push -1 if S1<S0, 0 if S1=S0, or 1 S1>S0 'g' : Add S0 to the program counter

: Add S0 to the program counter '?' : Add S0 to the program counter if S1 is 0

: Add S0 to the program counter if S1 is 0 'c' : Push the program counter on the call stack and set the program counter to S0

: Push the program counter on the call stack and set the program counter to S0 '$' : Set the program counter to the value popped from the call stack

: Set the program counter to the value popped from the call stack '<' : Push the value of memory cell S0

: Push the value of memory cell S0 '>' : Store S1 into memory cell S0

: Store S1 into memory cell S0 '^' : Push a copy of S<S0+1> (ex: 0^ duplicates S0)

: Push a copy of S<S0+1> (ex: 0^ duplicates S0) 'v' : Remove S<S0+1> from the stack and push it on top (ex: 1v swaps S0 and S1)

: Remove S<S0+1> from the stack and push it on top (ex: 1v swaps S0 and S1) 'd' : Drop S0

: Drop S0 '!' : Terminate the program

Note that elements of the stack which are used are removed from it in most commands: thus, ‘+’ command removes its arguments, as well as ‘P’.