Mornington Crescent

From Esolang
Jump to navigation Jump to search

Mornington Crescent, named after Mornington Crescent tube station in London and invented by Timwi in 2013 as somewhat of a tribute to the game of Mornington Crescent, is an esoteric programming language in which the data pointer moves through the London Underground by traveling by tube from station to station, starting and ending at Mornington Crescent.

Syntax

Mornington Crescent programs consist of a series of transitions from the current tube station to another, using one of the tube lines available at the current station. For example:

Take Northern Line to Leicester Square
Take Piccadilly Line to King's Cross St. Pancras
Take Circle Line to Westminster

etc.

Only lines matching ^Take (.*) Line to (.*)$ are valid, and the capturing groups must match a valid tube line name and tube station name, respectively.

An optional extra newline at the end of the program is acceptable.

Environment

  • During execution, every tube station on the London Underground has a current value, which is either an arbitrary-size integer or a string. Unless otherwise noted below, every station’s value starts out as a string containing that station’s name, for example Waterloo starts out with the value "Waterloo".
  • There is an accumulator which is also either an arbitrary-size integer or a string. This starts out with the contents of STDIN as a string.
  • The data pointer points at a current station. Execution begins at Mornington Crescent.
  • There is also a “jumpstack”, a stack of program locations, which is initially empty.

Valid Mornington Crescent programs must end at Mornington Crescent tube station. If execution moves beyond the last instruction in the program and that instruction does not validly take the data pointer to Mornington Crescent, a runtime error occurs.

Execution

Each instruction is executed as follows:

  • If the specified line or tube station doesn’t exist, or the line doesn’t connect the current station with the destination, a runtime error occurs.
  • Otherwise:
    • the data pointer is moved to the destination station;
    • the accumulator and the destination station’s value are swapped.

For example, if the first instruction in the program is

Take Northern Line to Leicester Square

then Leicester Square’s value becomes the string read from STDIN and the accumulator’s value becomes "Leicester Square".

However, some of the stations have special behaviour as described below.

Station Short Special meaning
Upminster add The accumulator’s value is set to the sum of its current value and the station’s current value, if both are integers (otherwise, standard swap).
Chalfont & Latimer multiply The accumulator’s value is set to the product of its current value and the station’s current value, if both are integers (otherwise, standard swap).
Cannon Street integer division The accumulator’s value is set to the quotient (rounded towards 0) of the station’s current value divided by the accumulator’s current value (or the empty string if the accumulator is 0) if both are integers (otherwise, standard swap).
Preston Road remainder The accumulator’s value is set to the remainder of the station’s current value divided by the accumulator’s current value (or the empty string if the accumulator is 0) if both are integers (otherwise, standard swap).
Bounds Green max The accumulator’s value is set to the station’s current value only if it is larger, if both are integers (otherwise, standard swap).
Manor House bitwise NOR (OR+NOT) Just like the above arithmetic operators, but with bitwise operations. The shift operations only trigger if the shift amount is positive.
Holland Park bitwise AND
Turnham Green bitwise shift-right
Stepney Green bitwise shift-left
Russell Square square The accumulator’s value is set to the square of the station’s current value if it is an integer (otherwise, standard swap).
Notting Hill Gate bitwise NOT The accumulator’s value is set to the bitwise NOT of the station’s current value if it is an integer (otherwise, standard swap).
Parsons Green parse string to integer If the accumulator contains a string, attempts finding and parsing an integer in it. The accumulator is set to the first integer found (or 0 if none), and the station’s value is set to the rest of the string (or ""). (If the accumulator is an integer, standard swap occurs. Note that this condition is inconsistent with other instructions, which decide this based on their current value rather than the accumulator.)

Example: If the accumulator value is "a-2b4", the accumulator becomes -2 and the station "b4".

Seven Sisters 7 This station’s value is always 7. The accumulator’s value is set to 7 and its previous value discarded.
Charing Cross character ↔ codepoint If the station’s value is a non-empty string, the accumulator is set to the Unicode codepoint of the first character; if it’s the empty string, to 0; if it is an integer, the accumulator is set to the Unicode character with this codepoint.
Paddington string concatenation The accumulator is set to the concatenation of the station’s value followed by the accumulator’s previous value, if both are strings (otherwise, standard swap).
Gunnersbury left substring If one of the two values is a string s and the other an integer i, the accumulator is set to the string containing the first i characters of s. If i is negative or out of range, a runtime error occurs. If they are both strings or both integers, standard swap occurs.
Mile End right substring Like Gunnersbury, but the accumulator is set to the last i characters.
Upney upper-case Sets the accumulator to the upper-case of the station’s value if it is a string (otherwise, standard swap).
Hounslow Central lower-case Sets the accumulator to the lower-case of the station’s value if it is a string (otherwise, standard swap).
Turnpike Lane reverse string Sets the accumulator to the reverse of the station’s value if it is a string (otherwise, standard swap).
Bank When a value is stored in Bank, Hammersmith is also set to the same value.
Hammersmith Always retains its current value. The value of the accumulator is discarded and replaced.
Temple continuation This station does not have a current value. The accumulator remains unaltered. Landing on this station pushes the current instruction pointer onto the jumpstack.
Angel if This station does not have a current value. The accumulator remains unaltered. If the accumulator is the integer 0, nothing happens. Otherwise, execution continues at the instruction stored at the top of the jumpstack (without popping it) and the data pointer is teleported to Temple.
Marble Arch pop This station does not have a current value. The accumulator remains unaltered. Landing on this station pops the topmost value off the jumpstack. Nothing else happens.
Mornington Crescent output/exit The value of the accumulator is printed and the program is terminated.

Computational class

Likely Turing complete because strings and integers can be any size and the jumpstack allows arbitrarily nested flow control. Not proven, however.

Forward compatibility

As the validity and the semantics of a program depend on the structure of the London underground system, which is administered by London Underground Ltd, a subsidiary of Transport for London, who are likely unaware of the existence of this programming language, its future compatibility is uncertain. Programs may become invalid or subtly wrong as the transport company expands or retires some of the network, reroutes lines or renames stations. Features may be removed with no prior consultation with the programming community. For all we know, Mornington Crescent itself may at some point be closed, at which point this programming language will cease to exist.

Example

Hello, World!

This program was written by Martin Büttner and is only half the length of the language creator’s original version.

Take Northern Line to Hendon Central
Take Northern Line to Bank
Take Northern Line to Bank
Take District Line to Gunnersbury
Take District Line to Victoria
Take Victoria Line to Seven Sisters
Take Victoria Line to Victoria
Take Victoria Line to Victoria
Take District Line to Bank
Take District Line to Hammersmith
Take District Line to Cannon Street
Take District Line to Hammersmith
Take District Line to Cannon Street
Take District Line to Bank
Take District Line to Hammersmith
Take District Line to Upminster
Take District Line to Hammersmith
Take District Line to Upminster
Take District Line to Gunnersbury
Take District Line to Paddington
Take District Line to Acton Town
Take Piccadilly Line to Holloway Road
Take Piccadilly Line to Acton Town
Take Piccadilly Line to Acton Town
Take District Line to Gunnersbury
Take District Line to Hammersmith
Take District Line to Notting Hill Gate
Take District Line to Upminster
Take District Line to Notting Hill Gate
Take District Line to Upminster
Take District Line to Victoria
Take Victoria Line to Seven Sisters
Take Victoria Line to Victoria
Take Victoria Line to Victoria
Take District Line to Upminster
Take District Line to Gunnersbury
Take District Line to Mile End
Take District Line to Hammersmith
Take District Line to Notting Hill Gate
Take District Line to Upminster
Take District Line to Upminster
Take District Line to Mile End
Take District Line to Paddington
Take District Line to Paddington
Take District Line to Acton Town
Take Piccadilly Line to Heathrow Terminals 1, 2, 3
Take Piccadilly Line to Holborn
Take Central Line to Holborn
Take Central Line to Mile End
Take District Line to Upminster
Take District Line to Hammersmith
Take District Line to Upminster
Take District Line to Barking
Take District Line to Hammersmith
Take District Line to Upminster
Take District Line to Gunnersbury
Take District Line to Barking
Take District Line to Gunnersbury
Take District Line to Paddington
Take District Line to Paddington
Take Circle Line to Wood Lane
Take Circle Line to Victoria
Take Circle Line to Victoria
Take District Line to Gunnersbury
Take District Line to Hammersmith
Take District Line to Upminster
Take District Line to Gunnersbury
Take District Line to Paddington
Take District Line to Paddington
Take District Line to Mile End
Take Central Line to Fairlop
Take Central Line to Mile End
Take District Line to Barking
Take District Line to Upminster
Take District Line to Upminster
Take District Line to Hammersmith
Take District Line to Notting Hill Gate
Take District Line to Upminster
Take District Line to Mile End
Take District Line to Gunnersbury
Take District Line to Paddington
Take District Line to Paddington
Take District Line to Hammersmith
Take District Line to Mile End
Take District Line to Richmond
Take District Line to Mile End
Take District Line to Paddington
Take District Line to Paddington
Take District Line to Richmond
Take District Line to Bank
Take District Line to Hammersmith
Take District Line to Upminster
Take District Line to Stepney Green
Take District Line to Hammersmith
Take District Line to Stepney Green
Take District Line to Upney
Take District Line to Notting Hill Gate
Take District Line to Notting Hill Gate
Take District Line to Notting Hill Gate
Take District Line to Upminster
Take District Line to Upney
Take District Line to Upminster
Take District Line to Bank
Take Circle Line to Bank
Take Northern Line to Charing Cross
Take Bakerloo Line to Charing Cross
Take Bakerloo Line to Paddington
Take Circle Line to Bank
Take Circle Line to Bank
Take Northern Line to Mornington Crescent

Interpreters

Esoteric IDE

Interpreter and debugger for many esoteric languages (including Mornington Crescent), written by the author of Mornington Crescent. The sources can be found at GitHub.

Esoterpret

Multi-language interpreter written in Python, as of 2015-10-06 only supporting Mornington Crescent. Open Source and available at GitHub.