This is an implementation of Intermediate Challenge #125, “Halt! It’s simulation time!”
The crux of the problem comes down to a table of virtual machine instructions like this:
I came up with the virtual machine abstraction, a 5-tuple machine with values for code, instruction pointer, instruction count, register values and whether or not the machine is halted. Then I defined some functions like get_register/3, set_register/4, set_instruction_pointer/3 which take a machine and some other arguments (a register number, for instance) and then return a value or a new machine with the appropriate change having been made.