Minsky Swap
Minsky Swap is an esolang based on Minsky machines and created by User:PythonshellDebugwindow.
Memory
Programs in Minsky Swap have access to two unbounded registers; however, only one of these registers can have "focus" at a time. The current register is pointed to by a register pointer.
Syntax and Semantics
Minsky Swap code is split onto two lines. The first line is the actual code to be executed and is known as the code line, and the second line contains a list of numbers and is known as the jump line. The code line is split into characters, each character being a command; the commands are listed below.
Command | Effect |
---|---|
+ |
Increment the register under the register pointer |
~ |
If the register under the register pointer is nonzero, decrement it; otherwise, jump to command M, where M is the Nth number in the jump line and this ~ is the Nth tilde in the code line
|
* |
Swap the register pointer between the first and second register |
Readable Minsky Swap Notation
Readable Minsky Swap Notation (RMSN) is a more readable notation for Minsky Swap. It is reminiscent of Portable Minsky Machine Notation. In RMSN, each command is on one line. inc();
increments the current register; decnz(N);
decrements the current register if it's nonzero, and jumps to line N (1-based) otherwise; and swap();
swaps the register pointer.
Computational class
Minsky's 2-register machine (sec 14.1 of Computation: Finite and Infinite Machines ) uses 2 registers, r, and s and has 4 commands in its most basic form:
- r+ :
inc();
for register 1: r - r-(n) :
decnz(N);
for r (jump happens iff register IS zero) - s+ :
inc();
for register 2: s - s-(n) :
decnz(N);
for s (jump happens iff register IS zero)
Any Minsky 2-register machine code can be translated unambiguously to Minsky Swap as follows:
2-reg MM | MS |
---|---|
r+ | +
|
r-(N) | ~(N)
|
s+ | *+*
|
s-(N) | *~(N)
|
Furthermore, for every target N of any jump, insert a double-swap / no-op: **
.
For any 2-reg MM source code, there will be a finite number of these. As a no-op, they do not affect the program behaviour.
Then adjust the N of every jump instruction to point to the first *
(swap) if it is a r- or to the second *
(swap) if it is a s-.
This way the intended r or s register is always correctly targeted for any possible path through the code, and the various decnz(N)
have a fixed register every time they are encountered.
This adding of no-ops to jump targets is probably unnecessary for Turing completeness. If anything, allowing the same block of code to target either register 1 or 2 depending on how it was jumped to gives the language more flexibility and reduces the amount of code needed to get a potential effect, but it makes it harder to reason about. Adding the no-ops and fixing the target registers so that register 1 is always current upon entering and exiting a composite-command makes the 2-reg Minsky machine translation clear.