Language Specification
l33t is an esoteric language based loosely on BrainF***, and influenced by Beatnik. The basic data unit is the unsigned byte (big-endian), which can represent ASCII values, numbers in the range 0-255, and, well, pretty much anything else you can put your sick little minds to.
Source is entered in l33t sP34k, and each word is evaluated as follows: Word are considered to be separated by spaces or carriage returns. The value of a word is obtained by adding the numerical digits within it together, e.g. l33t = 3 + 3 = 6.All other characters are valid but ignored. Words with no numeric characters (or in which the only numeric characters are “0”s) are evaluated to 0. It is possible to program in l33t just using numbers, i.e. not forming letters in l33t 5p34k. However, programmers who do this are “teh sUxX0r”, and the interpreter is well within its rights to format your hard drive for attempting this. Needless to say, l33t is case-insensitive, but extra kudos is awarded for random capitalisation ;o)
The Opcodes
VALUE | OPCODE | DESCRIPTION |
0 |
NOP |
No Operation, except to increment the instruction pointer. |
WRT | Writes the ASCII values of the byte under the memory pointer to the current connection (see CON). Increments the instruction pointer. |
|
RD | Reads a character from the current connection (see CON) and writes it to the byte currently under the memory pointer. Increments the instruction pointer. |
|
IF | Moves the instruction pointer forward to the command following the matching EIF, if the byte under the memory pointer is equal to zero. If the byte under the memory pointer does not equal zero, IF simply increments the instruction pointer. | |
EIF | Moves the instruction pointer backwards to the command following the matching IF, if the byte under the memory pointer is not equal to zero. If the byte under the memory pointer does equal zero, EIF simply increments the instruction pointer. |
|
FWD | Move memory pointer forward by (next word+1) bytes. Adds 2 to the instruction pointer. |
|
BAK | Move memory pointer backward by (next word+1) bytes. Adds 2 to the instruction pointer. |
|
INC | Increment value of the byte under memory pointer by (next word+1). Adds 2 to the instruction pointer. |
|
DEC | Decrement value of the byte under memory pointer by (next word+1). Adds 2 to the instruction pointer. |
|
9 |
CON |
Reads the 6 bytes starting with the memory pointer (the first 4 bytes specifying an IP in the format 127.0.0.1, and the last 2 bytes combining to make a 16-bit port number * ), and opens a connection if possible. If a connection can't be opened, l33t will return the error message: "h0s7 5uXz0r5! c4N'7 c0Nn3<7 l0l0l0l0l l4m3R !!!". and reset the current connection to the last successful one (stdin/stdout if there were no previous successful connections). If all 6 bytes read 0, l33t reverts back to the local machine's stdin and stdout (this is the default setting upon starting a l33t program). Increments the instruction pointer. Regardless of whether the connection was successful or not, the memory pointer will be left in the same place as it was. Only FWD and BAK move the memory pointer. * The port number can be calculated by something along the lines of: portNumber = (byte5 << 8) + byte |
10 |
END | Closes all open connections and ends the program. The value 10 won't end the program if it is used as data for OpCodes FWD, BAK, INC or DEC. |
... And Now The Bad News...
A few points to be aware of:
- Any OpCodes evaluating to > 10 will produce an error message but carry on. Although this is legal syntax, it will print the standard l33t error code "j00 4r3 teh 5ux0r", and make your program somewhat embarrassing to run in public... No error will be produced if values > 10 are used as data for OpCodes FWD, BAK, INC & DEC.
- l33t will interpret ANY usages of 3 and 4 as brackets, even if they were intended as data! So although “pH34r m3!” will increment the current byte by 3 as expected, a subsequent call to EIF (if the current byte under the memory pointer is nonzero) will jump back to that “m3!”. If the memory pointer fails to find a matching "bracket" in the direction it is looking, the results are undefined: chances are the program will crash, and insult your stupidity.
- IF/EIF pairs can be nested, so for example if the byte under the memory pointer is 0 and the program encounters a sequence like IF... IF... EIF... EIF the program will jump to the second EIF , not the first.
- Memory byte values are unsigned, so they wrap: 255 + 1 = 0, and 0 - 1 = 255. Interpreters are advised, but not required to be able to handle the case where words in the l33t source evaluate to >255 and wrap accordingly. However, as this situation is very unlikely, results are undefined.
- The 64K memory limit is arbitrary, but a handy size for portability and minimalism. l33t interpreters may utilise different memory sizes, but 64K is considered to be the standard. In all cases, the memory and instruction pointers should be data types large enough to cope with accessing all locations within the memory block (i.e. a 16-bit unsigned integer in the case of a 64K memory block).