reMorse
reMorse is an esoteric programming language invented by Ryan Kusnery. It is a turning tarpit where the code looks like Morse code.
reMorse consist of four instructions. The dash(-) and dasher(- followed by a space) instructions select the next and previous operation respectively, from a circular list of seven operations. Dot(.) and dotty(. followed by a space) do the operation and the opposite of the operation which is being selected, respectively.
reMorse2, reMorse2.-, and reMorse4ever are the dialects of reMorse, among which only reMorse2.- is claimed as Turing-complete.
Contents |
[edit] Language overview
This overview will cover the reMorse2.- dialect, but the term "reMorse" will be used throughout.
The original language spec is somewhat unclear, and this explanation may contain mistakes and mis-interpretations.
[edit] Syntax
The reMorse2.- syntax is essentially binary, but uses the morse-code-like "." (dot) and "-" (dash) as its digits. Dots and dashes are paired, and thus the language has four instructions: "..", ".-", "-." and "--". All non-dot/non-dash characters are ignored, so whitespace and comments (without dots or dashes) may be embedded in the code. (The original reMorse syntax described in the preview is a tad more complex than the reMorse descendants in its parsing rules.) Instructions are executed in sequence unless a jump occurs.
[edit] Registers
reMorse has 256 1-byte registers ordered in a circular list. Each register is initialized with the 0-index value of its place in the list. Thus Register 0 is initialized with 00, Register 1 is initialized with 01, and so on. The "register pointer" keeps track of the "current register" and initially starts on Register 1 (NOT Register 0).
[edit] Stack
reMorse has an unbounded stack for 1-byte values. In practice, the stack is more like a list, because the "stack pointer" is not necessarily at the top of the stack. The stack pointer points between values, and so may or may not have a value below or above it. A push or pop only affects the values below the stack pointer. The "stack byte" (if there is one) is the byte on the stack just below the stack pointer.
[edit] Operations
There are 9 operation/counter-operation pairs that may be performed in reMorse(2.-). They are ordered in a circular list. There is also an "operation pointer" which points to the current "operation pair". The instructions "--" and "-." increment/decrement the operation pointer respectively. The instructions ".." and ".-" perform the current operation/counter-operation respectively. The operation pointer starts on operation pair 1.
The operations are as follows:
- Push the byte at the current register onto the stack. Leave the register unchanged.
- Output the stack byte to STDOUT as an ASCII char. Leave the stack unchanged.
- Move the stack pointer up 1 ("fake push"). This operation causes an error if the stack pointer is at the top of the stack.
- Bit sort the stack byte in place.
- AND the stack byte with the current register, and replace the stack byte with the result.
- Left ROT the current register in place.
- Add the stack byte and the current register, and replace the stack byte with the result. (Overflows are assumed to wrap around.)
- Increase register pointer by value in current register.
- Skip the next N instructions, where N is the current register. If N is 00, this operation has no effect. If N is greater than the number of remaining instructions, the program terminates.
The respective counter-operations are as follows:
- Pop the stack byte into the current register. This operation causes an error if the stack pointer is at the top of the stack.
- Push a byte from STDIN onto the stack.
- Move the stack pointer down 1 ("fake pop"). This operation causes an error if the stack pointer is at the bottom of the stack.
- Reverse bit sort the stack byte in place.
- NOT the stack byte in place.
- Right ROT the current register in place.
- Subtract the current register from the stack byte, and replace the stack byte with the result. (Underflows are assumed to wrap around.)
- Decrease register pointer by value in current register.
- Go back N instructions, where N is the current register. If N is 00, this operation has no effect. If N is greater than the number of previous instructions, an error occurs. If N is 01, an infinite loop is entered.
[edit] Remarks
After examining the operation set above, it should be obvious that, if the register pointer was initialized to start on Register 0, a program that never asked for input could never do anything!
[edit] External resources
- reMorse programming language specification (from the Wayback Machine; retrieved on 3 April 2008)