We are currently working on new rules for what content should and shouldn't be allowed on this website, and are looking for feedback! See Esolang:2026 topicality proposal to view and give feedback on the current draft.
TMMLPTEALPAITAFNFAL
TMMLPTEALPAITAFNFAL (The Multi-Million Language Project To End All Language Projects And Isn't That A Fine Name For A Language) is an esoteric programming language devised by Gerson Kurz. Actually, it is not only one language; it is a new language for each day. Based on a unique-day-index (relative to January 1, 1900) a new allowed set of commands and arbitrary limits for variable names take place. However the syntax of the language does not change and looks mostly like some BASIC dialect. For example, on August 16, 2004, the following rules applied:
VALID TMMLPTEALPAITAFNFAL INSTRUCTIONS FOR TODAY:
- GOTO
- STOP
- RETURN
- ADD
- SUB
- MUL
- DIV
- IF-THEN-UNLESS
- COPY
- WRITE
- READ
- DECLARATION
- WHILE-DO-PROVIDED
- UNLESS-DO
- REPEAT-UNLESS
- DO-UNTIL
- DO-UNLESS
- NAND
RESTRICTIONS ON IDENTIFIERS FOR TODAY:
IDENTIFIER CHARACTERS MUST BE IN ASCII RANGE 32 .. 75 (' ' .. 'K')
Data storage
There are an infinite number of cells (limited to 3927 in the official implementation). The cells can be given names with the DECLARE instruction; however, the names must adhere to the RESTRICTIONS ON IDENTIFIERS. Alternatively, you can simply use a cell index (e.g. CELL 0). The cells each have the storage of a long.
Appending INDIRECT allows for one level of indirection -- that is, setting or getting the value of the cell with the resulting index. For example, if CELL 0 contains 6, then CELL 0 INDIRECT results in the contents of CELL 6.
Reading an uninitialized cell results in 0.
Instructions
Note that not all instructions are available on all days. Conditions are always available and take the form <LEFT_VALUE> <COMPARISON> <RIGHT_VALUE> where <COMPARISON> is one of "=", "<", ">", "<=", ">=", and "<>" (for not-equal). Instructions can also start with a line number directive of the form LINE <LINE_NUMBER>:.
| Instruction | Explanation | Availability | Equivalent C code |
|---|---|---|---|
| GOTO <VALUE> | Jumps to the line of code directly after the one with given line number. | Exactly one of this and GOSUB will be allowed. | N/a |
| GOSUB <VALUE> | Calls the subroutine starting directly after the line of code with the given line number. | Exactly one of this and GOTO will be allowed. | N/a |
| STOP | Ends the program. | Always allowed. | exit(0);
|
| RETURN | Returns from the current subroutine. If there is none, acts like STOP. | Always allowed. | return;
|
| ADD <VALUE> TO <TARGET> | Adds the given values together. | Always allowed. | TARGET += VALUE;
|
| SUB <VALUE> FROM <TARGET> | Subtracts the given values. | Always allowed. | TARGET -= VALUE;
|
| MUL <VALUE> WITH <TARGET> | Multiplies the given values together. | Always allowed. | TARGET *= VALUE;
|
| DIV <VALUE> BY <TARGET> | Integer-divides the given values. Results in the error "HEY, DIVISION BY ZERO IS A VERY BAD IDEA" if the divisor is 0. | Exactly one of this and MOD will be allowed. | TARGET /= VALUE;
|
| MOD <VALUE> BY <TARGET> | Takes the modulus of the given values. Results in the error "HEY, MODULO ZERO IS A VERY BAD IDEA" if the divisor is 0. | Exactly one of this and DIV will be allowed. | TARGET %= VALUE;
|
| IF <COND> THEN <STMT> | Runs the statement if the given condition is true. | At least one of this and the other control structures is allowed. | if (COND) {STMT;}
|
| IF <COND> THEN <THEN_STMT> ELSE <ELSE_STMT> | Runs the first statement if the given condition is true; otherwise runs the second statement. | At least one of this and the other control structures is allowed. | if (COND) {THEN_STMT;} else {ELSE_STMT;}
|
| IF <IF_COND> THEN <STMT> UNLESS <UNLESS_COND> | Runs the statement if the first condition is true and the second condition is false. | At least one of this and the other control structures is allowed. | if (IF_COND && !UNLESS_COND) {STMT;}
|
| IF <IF_COND> THEN <STMT> PROVIDED <PROVIDED_COND> | Runs the statement if the first condition and the second condition are both true. | At least one of this and the other control structures is allowed. | if (IF_COND && PROVIDED_COND) {STMT;}
|
| COPY <VALUE> TO <TARGET> | Copies the value to the given cell. | Always allowed. | TARGET = VALUE;
|
| WRITE CHAR <VALUE> | Outputs the corresponding ASCII character. | Always allowed. | printf("%c", VALUE);
|
| WRITE INTEGER <VALUE> | Outputs the value as a number, as well as a space character immediately after. | Always allowed. | printf("%ld ", VALUE);
|
| READ CHAR <TARGET> | Reads a character and puts its ASCII value into the given variable. | Always allowed. | scanf("%c", &TARGET);
|
| READ INTEGER <TARGET> | Reads an integer into the given variable. If the input does not match an integer, this will read 0. | Always allowed. | scanf("%ld", &TARGET);
|
| DECLARE <NUMERIC> AS <NAME> | Declares a name for a cell. | Always allowed. | N/a |
| WHILE <COND> DO <STMT> | Runs the statement while the condition is true. | At least one of this and the other control structures is allowed. | while (COND) {STMT;}
|
| WHILE <WHILE_COND> DO <STMT> UNLESS <UNLESS_COND> | Runs the statement while the first condition is true and the second condition is false. | At least one of this and the other control structures is allowed. | while (WHILE_COND && !UNLESS_COND) {STMT;}
|
| WHILE <WHILE_COND> DO <STMT> PROVIDED <PROVIDED_COND> | Runs the statement while the first condition and the second condition are both true. | At least one of this and the other control structures is allowed. | while (WHILE_COND && PROVIDED_COND) {STMT;}
|
| UNLESS <COND> DO <STMT> | Acts the same as UNTIL-DO. | At least one of this and the other control structures is allowed. | See UNTIL-DO |
| REPEAT <STMT> UNTIL <COND> | Acts the same as DO-UNTIL. | At least one of this and the other control structures is allowed. | See DO-UNTIL |
| REPEAT <STMT> UNLESS <COND> | Acts the same as UNTIL-DO. | At least one of this and the other control structures is allowed. | See UNTIL-DO |
| DO <STMT> WHILE <COND> | Acts like a do-while loop while the condition is true. | At least one of this and the other control structures is allowed. | do {STMT;} while (COND);
|
| DO <STMT> UNTIL <COND> | Acts like a do-while loop while the condition is false. | At least one of this and the other control structures is allowed. | do {STMT;} while (!COND);
|
| DO <STMT> UNLESS <COND> | Acts the same as UNTIL-DO. | At least one of this and the other control structures is allowed. | See UNTIL-DO |
| UNTIL <COND> DO <STMT> | Runs the statement while the condition is false. | At least one of this and the other control structures is allowed. | while (!COND) {STMT;}
|
| NAND <VALUE> WITH <TARGET> | Sets the output to 0 if either input is -1, otherwise to 1. | Always allowed. | TARGET = (~TARGET) && (~VALUE);
|
Errors
- The arithmetic instructions must have the destination value on the right. If it's not a cell, results in an error "ERROR, ARITHMETIC INSTRUCTION MUST HAVE MEMORY TARGET, STUPID!"
- READ must have a cell value as the destination. If it doesn't, results in an error "ERROR, READ INSTRUCTION MUST HAVE MEMORY TARGET, STUPID!"
- NAND must have the destination value on the right. If it's not a cell, results in an error "ERROR, NAND INSTRUCTION MUST HAVE MEMORY TARGET, STUPID!"
Syntax
Taken from the official page, with some formatting changes and corrections.
STATEMENT: [LINE_NUMBER] CONTROL_LOGIC | MATH_STATEMENT | IO_STATEMENTS | DECLARATION
DECLARATION: "DECLARE" NUMERIC "AS" NAME
NAME: NC (NC | DECINT)*
NC: <non-numeric printable ASCII char>
CONTROL_LOGIC: BRANCH_STATEMENT | IF_FAMILY | WHILE_FAMILY
IF_FAMILY: IF_THEN | IF_THEN_ELSE | IF_THEN_UNLESS | IF_THEN_PROVIDED
WHILE_FAMILY: WHILE_DO | WHILE_DO_UNLESS | WHILE_DO_PROVIDED | UNLESS_DO | REPEAT_UNTIL | REPEAT_UNLESS | DO_WHILE | DO_UNTIL | DO_UNLESS | UNTIL_DO
IF_THEN: "IF" BOOLEAN_EXPRESSION "THEN" STATEMENT
IF_THEN_ELSE: "IF" BOOLEAN_EXPRESSION "THEN" STATEMENT "ELSE" STATEMENT
IF_THEN_UNLESS: "IF" BOOLEAN_EXPRESSION "THEN" STATEMENT "UNLESS" BOOLEAN_EXPRESSION
IF_THEN_PROVIDED: "IF" BOOLEAN_EXPRESSION "THEN" STATEMENT "PROVIDED" BOOLEAN_EXPRESSION
WHILE_DO: "WHILE" BOOLEAN_EXPRESSION "DO" STATEMENT
WHILE_DO_UNLESS: "WHILE" BOOLEAN_EXPRESSION "DO" STATEMENT "UNLESS" BOOLEAN_EXPRESSION
WHILE_DO_PROVIDED: "WHILE" BOOLEAN_EXPRESSION "DO" STATEMENT "PROVIDED" BOOLEAN_EXPRESSION
UNLESS_DO: "UNLESS" BOOLEAN_EXPRESSION "DO" STATEMENT
UNTIL_DO: "UNTIL" BOOLEAN_EXPRESSION "DO" STATEMENT
REPEAT_UNTIL: "REPEAT" STATEMENT "UNTIL" BOOLEAN_EXPRESSION
REPEAT_UNLESS: "REPEAT" STATEMENT "UNLESS" BOOLEAN_EXPRESSION
DO_WHILE: "DO" STATEMENT "WHILE" BOOLEAN_EXPRESSION
DO_UNTIL: "DO" STATEMENT "UNTIL" BOOLEAN_EXPRESSION
DO_UNLESS: "DO" STATEMENT "UNLESS" BOOLEAN_EXPRESSION
IO_STATEMENTS: READ | WRITE
WRITE: "WRITE" ("CHAR" | "INTEGER") NUMERIC
READ: "READ" ("CHAR" | "INTEGER") NUMERIC
BOOLEAN_EXPRESSION: NUMERIC [(">" | "<" | "=" | "<>" | ">=" | "<=") NUMERIC]
MATH_STATEMENT: ADD | SUB | MUL | MOD | DIV | COPY | NAND
ADD: "ADD" NUMERIC "TO" NUMERIC
COPY: "COPY" NUMERIC "TO" NUMERIC
SUB: "SUB" NUMERIC "FROM" NUMERIC
MUL: "MUL" NUMERIC "WITH" NUMERIC
NAND: "NAND" NUMERIC "WITH" NUMERIC
MOD: "MOD" NUMERIC "BY" NUMERIC
DIV: "DIV" NUMERIC "BY" NUMERIC
NUMERIC: NAME | INTEGER | "CELL" INTEGER ["INDIRECT"]
BRANCH_STATEMENT: GOTO | GOSUB | STOP | RETURN
STOP: "STOP"
RETURN: "RETURN"
GOSUB: "GOSUB" NUMERIC
GOTO: "GOTO" NUMERIC
LINE_NUMBER: "LINE" INTEGER ":"
INTEGER: DECINT (DECINT)*
DECINT: "0" .. "9"
Workarounds
Any variable name restrictions can be avoided by only using cell numbers. Working around instructions is more difficult, but it can be done. Here, the ' suffix is used to indicate the inversion of a condition (which can be done by swapping < for >=, > for <=, and = for <>).
MOD using DIV
COPY <X> TO <TEMP> DIV <Y> BY <TEMP> MUL <Y> WITH <TEMP> SUB <TEMP> FROM <X>
The IF family
IF-THEN-ELSE can emulate IF-THEN by setting its "else" statement to a no-op such as ADD 0 TO CELL 0. Similarly, IF-THEN-UNLESS and IF-THEN-PROVIDED can emulate IF-THEN by setting their auxiliary conditions to 0 = 1 and 0 = 0, respectively. It thus suffices to show that IF-THEN can emulate the others. For IF-THEN-UNLESS and IF-THEN-PROVIDED:
IF <IF_COND> THEN IF <UNLESS_COND'> THEN <STMT> IF <IF_COND> THEN IF <PROVIDED_COND> THEN <STMT>
As for IF-THEN-ELSE, a temporary location is needed in the event that either statement influences the condition:
COPY 0 TO CELL <TEMP> IF <COND> THEN COPY 1 TO CELL <TEMP> IF <TEMP> = 1 THEN <THEN_STMT> IF <TEMP> = 0 THEN <ELSE_STMT>
The WHILE family
WHILE-DO-UNLESS and WHILE-DO-PROVIDED are trivial to translate to WHILE-DO. UNTIL-DO, UNLESS-DO, REPEAT-UNLESS, and DO-UNLESS are equivalent to WHILE-DO with an inverted condition. For DO-WHILE:
<STMT> WHILE <COND> DO <STMT>
For DO-UNTIL and REPEAT-UNTIL, simply invert the condition of DO-WHILE. Thus, anything within the WHILE family can simulate WHILE-DO.