Selmotic (short for Self-modifying time code) is an esoteric programming language created by User:Caenbe to explore the idea of a time virus, which is something that creates itself via time travel and interferes with your code. In the event time travel is ever invented, this language should serve as a warning not to use any language like itself. Besides being based on other time-travelling esolangs, Selmotic is mostly based on assembly and brainfuck.
The memory is an infinite row of unbounded integers. Each cell has an address, which is also an integer. The program is also read from this memory, starting at cell 0. A text file can contain a program by specifying the initial state of the memory. Each line has the form
address: value with both integers written in hexadecimal. Any address not specified is initialized to 0.
How pointers work in this language
Pointers contain two pieces of information: an address in the memory, and a time to access it. Both are integers. The time starts at 0 when the program executes its first command, and increments with every command. A negative time causes undefined behavior, because the memory hadn’t been initialized yet at that time.
If the same pointer is accessed multiple times, the accesses happen in chronological order of when the accessing code runs. A command read at time t is read between an access from time t-1 and an access from time t. If a pointer is accessed infinitely many times, this causes a supertask to happen, which can cause undefined behavior. Realistically, this won't happen because you can't run the program forever.
All commands and functions take pointers, and use prefix notation. The names given here are to aid programming, and aren’t used in the actual code.
|mov||Copy the integer pointed at by the second argument to the first argument.|
|inc||Increment the integer pointed at by the argument.|
|dec||Decrement the integer pointed at by the argument.|
|input||Take a number from input and store it at the pointer.|
|output||Output the pointed-at integer.|
|[||If the pointed-at integer is zero, jump to the matching ].|
|]||If the pointed-at integer is non-zero, jump to the matching [.|
Note: matching brackets can have different arguments.
|*||Current dereference: given a pointer, return a pointer with address=the pointed-at integer and time=the current time.|
|@||Absolute dereference: given 2 pointers, return a pointer with address=the first pointed-at integer and time=the second pointed-at integer.|
|^||Relative dereference: given 2 pointers, return a pointer with address=the first pointed-at integer and time=the current time + the second pointed-at integer.|
|(address)||A pointer to address at the current time, with address ranging from -4 to -1 inclusive.|
Reading commands from memory
To translate integers to commands, every command and function has a corresponding nibble:
Each integer is interpreted as one command, as follows:
- Write the integer in hexadecimal. If it is 0 or positive, 0s extend infinitely to the left. If it is negative, it is represented in 2’s complement, and Fs extend infinitely to the left.
- Find the right-most command nibble. Since 0 and F are both command nibbles, this is always possible.
- Treat everything to its right as its argument(s). A syntax error causes undefined behavior.
If you ignore time viruses, Selmotic is probably Turing-complete, due to similarities with brainfuck. It's unclear whether time travel allows a language to be super-Turing; see Talk:TwoDucks for further discussion on this.
However, all that is undermined by the possibility of a time virus. It would work like a regular computer virus by replicating itself, but it would be able to send itself to the past, thereby bringing itself into existence without anyone needing to create it. It could then interfere with the intended function of your code. It's not known what the probability of this happening is, or whether there's a way to make code resistant or immune to it. No specific examples of a time virus have been found.