Motorway
Motorway is an esoteric programming language based around the British motorway network, created by User:Ninesquared81. A Motorway program describes a route along British motorways, 12 of which correspond to commands which manipulate a data stack. Other motorways can be visited to connect these command motorways, and command motorways may be visited without invoking their effects by placing them in brackets.
Language
The syntax of Motorway is rather simple; motorway tokens are of the form M\d+|A\d+M|\((M\d+|A\d+M)\)
. Anything that does not match this regex is regarded as a comment and ignored. As seen in the regex, any motorway may placed inside brackets. This allows you to visit a command motorway without invoking its effect, which is useful for making a connection between two other motorways. Non-command motorways may also be placed in brackets, but the brackets are redundant and can be safely omitted.
Visiting a non-existent motorway (e.g. M7
) is a syntax error, as is visiting an isolated motorway (or isolated network of motorways such as the Leeds Inner Ring Road). Furthermore, each motorway visited must connect to the next. Two motorways are considered connected if they share a junction, regardless of the nature of said junction. For example, one can make the connection between the M1 and M69 at Leicester, even though doing so in real life involves leaving motorway restrictions to navigate a roundabout before entering the M69. The ability to “turn round” on a motorway is also implicitly accepted.
The data stack is initially empty. Trying to pop from an empty stack results in an error. Stack cells wrap on overflow.
The command motorways are:
Motorway | Command description | Connections |
---|---|---|
M1 |
Increment the top element of the stack | M6, M18, M25, M45, M62, M69, M621, A1M |
M4 |
Pop from the top of the stack and print the result to stdout |
M5, M25, M32, M48, M49, A48M |
M5 |
Pop from the top of the stack and discard the value | M4, M6, M42, M49, M50 |
M6 |
Push a new, zero-initialized, unsigned 8-bit cell to the top of the stack | M1, M5, M42, M54, M55, M56, M58, M61, M62, M65, M69, A38M, A74M, A601M |
M20 |
Read a single character from stdin and push it to the top of the stack |
M25, M26 |
M25 |
Pop from the top of the stack and jump to matching M26 if zero |
M1, M3, M4, M11, M20, M23, M26, M40 |
M26 |
Jump back to matching M25 (top will be popped again) |
M20, M25 |
M40 |
Duplicate the top element of the stack | M25, M42 |
M42 |
Swap the top two elements of the stack | M5, M6, M40 |
M48 |
Pop from the top of the stack and add the result to the next element | M4 |
M49 |
Pop from the top of the stack and subtract the result from the next element | M4, M5 |
M60 |
Rotate top three elements of stack like so: ... c, b, a → ... b, a, c |
M56, M61, M62, M66, M67, M602 |
Example programs
Hello world
Initialize stack to [2,4,8,16,32,64] (<-top): M6 M1 M45 M1 (M25) M40 M25 M40 (M42) M40 (M25) (M4) M48 (M4) (M25) M40 (M42) M40 (M25) (M4) M48 (M4) (M25) M40 (M25) (M4) M48 (M4) (M25) M26 Print "H": (M25) (M1) M62 M60 M56 (M6) (M5) (M4) M48 (M4) (M25) (M1) M62 M60 M56 (M6) (M42) M40 (M25) (M1) M62 M60 M56 (M6) (M42) M40 (M25) (M1) M62 M60 M56 (M6) (M5) M49 M4 Print "e": (M5) M42 (M5) (M4) M48 (M4) (M5) M6 M1 (M25) (M4) M49 (M5) M42 (M6) M56 M60 M62 (M1) (M25) M40 (M42) M40 (M25) (M4) M48 (M4) M48 (M4) (M5) M42 M40 (M25) (M1) M62 M60 M56 (M6) (M5) (M4) M48 (M4) (M5) M42 M40 (M25) M40 (M25) (M4) M48 (M4) (M5) (M6) M56 M60 M62 (M1) (M25) M40 (M42) (M6) M56 M60 M61 (M6) (M5) (M4) M48 (M4) (M25) M40 (M42) M6 M1 M45 M1 A1M M1 M621 M1 (M25) M40 (M25) (M4) M48 (M4) M49 (M5) (M6) M1 (M25) M4 Print "llo, W": (M25) M40 (M42) M40 (M25) M4 M32 M4 (M5) M6 M1 M18 M1 M45 M1 (M6) M42 M40 (M25) (M1) M62 M60 M56 (M6) (M5) (M4) M48 M4 (M5) M42 (M5) M4 (M5) M42 M40 (M25) M4 (M25) M1 M62 M60 M56 (M6) (M5) M4 Print "orld!\n": (M5) M42 (M6) M56 M60 M62 M1 (M6) M42 M40 (M25) (M1) M62 M60 M56 (M6) (M5) (M4) M48 (M4) (M25) M40 (M25) M4 (M25) M1 M45 M1 A1M M1 (M25) M4 (M25) M40 (M25) M4 (M5) M6 M1 M18 M1 M69 M1 M621 M1 (M25) M40 (M25) (M4) M48 (M4) (M25) M40 (M42) (M6) M56 M60 M67 M60 M56 (M6) (M5) M49 M4 (M5) M42 (M5) M4 (M25) M1 M45 M1 (M25) M4
Cat
read first character: M20 duplicate it: (M25) M40 if non-zero, loop: M25 in the loop, print: M4 (M25) read next character: M20 (M25) duplicate: M40 (M25) end loop: M26 clear up stack: (M25) (M4) M5
Truth-machine
read input: M20 duplicate input: (M25) M40 subtract 48 (to convert to a number): (M42) M6 M1 M45 M1 A1M M1 M621 M1 (M25) M40 (M25) (M4) M48 (M4) (M25) M40 (M25) (M4) M48 (M4) (M25) M40 (M42) M40 (M25) (M4) M48 (M4) M48 (M4) M49 loop forever if nonzero: (M5) (M42) M40 M25 (M40) M42 M40 (M25) M4 (M5) M42 M40 (M25) M26 otherwise, print once and exit: (M25) (M4) M5 M4
Shortest connections
Motorway programs often involve travelling between two motorways which are not directly connected. A JSON file showing the full network is included as an external resource, but the table below shows the shortest route (in terms of number of motorways visited) between each pair of command motorways. Alternative routes of the same length are shown if present.
M1 | M4 | M5 | M6 | M20 | M25 | M26 | M40 | M42 | M48 | M49 | M60 | |
---|---|---|---|---|---|---|---|---|---|---|---|---|
M1 | — | (M25) |
(M6) |
— | (M25) |
— | (M25) |
(M25) |
(M6) |
(M25) (M4) |
(M6) (M5) , (M25) (M4) |
M62
|
M4 | (M25) |
— | — | (M5) |
(M25) |
— | (M25) |
(M25) |
(M5) |
— | — | (M5) (M6) M56 , (M5) (M6) M61 , (M5) (M6) M62 , (M25) (M1) M62
|
M5 | (M6) |
— | — | — | (M4) (M25) |
(M4) |
(M4) (M25) |
(M42) |
— | (M4) |
— | (M6) M56 , (M6) M61 , (M6) M62
|
M6 | — | (M5) |
— | — | (M1) (M25) |
(M1) |
(M1) (M25) |
(M42) |
— | (M5) (M4) |
(M5) |
M56 , M61 , M62
|
M20 | (M25) |
(M25) |
(M25) (M4) |
(M25) (M1) |
— | — | — | (M25) |
(M25) (M40) |
(M25) (M4) |
(M25) (M4) |
(M25) (M1) M62
|
M25 | — | — | (M4) |
(M1) |
— | — | — | — | (M40) |
(M4) |
(M4) |
(M1) M62
|
M26 | (M25) |
(M25) |
(M25) (M4) |
(M25) (M1) |
— | — | — | (M25) |
(M25) (M40) |
(M25) (M4) |
(M25) (M4) |
(M25) (M1) M62
|
M40 | (M25) |
(M25) |
(M42) |
(M42) |
(M25) |
— | (M25) |
— | — | (M25) (M4) |
(M25) (M4) , (M5) (M42) |
(M25) (M1) M62 , (M42) (M6) M56 , (M42) (M6) M61 , (M42) (M6) M62
|
M42 | (M6) |
(M5) |
— | — | (M40) (M25) |
(M40) |
(M40) (M25) |
— | — | (M5) (M4) |
(M5) |
(M6) M56 , (M6) M61 , (M6) M62
|
M48 | (M4) (M25) , (M5) (M6) |
— | (M4) |
(M4) (M5) |
(M4) (M25) |
(M4) |
(M4) (M25) |
(M4) (M25) |
(M4) (M5) |
— | (M4) |
(M4) (M5) (M6) M56 , (M4) (M5) M61 , (M4) (M5) M62
|
M49 | (M4) (M25) , (M5) (M6) |
— | — | (M5) |
(M4) (M25) |
(M4) |
(M4) (M25) |
(M4) (M25) , (M5) (M42) |
(M5) |
(M4) |
— | (M5) (M6) M56 , (M5) (M6) M61 , (M5) (M6) M62
|
M60 | M62 |
M56 (M6) (M5) , M61 (M6) (M5) , M62 (M1) (M25) , M62 (M6) (M5) |
M56 (M6) , M61 (M6) , M62 (M6) |
M56 , M61 , M62 |
M62 (M1) (M25) |
M62 (M1) |
M62 (M1) (M25) |
M56 (M6) (M42) , M61 (M6) (M42) , M62 (M1) (M25) , M62 (M6) (M42) |
M56 (M6) , M61 (M6) , M62 (M6) |
M56 (M6) (M5) (M4) , M61 (M6) (M5) (M4) , M62 (M1) (M25) (M4) , M62 (M6) (M5) (M4) |
M56 (M6) (M5) , M61 (M6) (M5) , M62 (M6) (M5) |
— |
External resources
- Python interpreter
- JSON file showing connections for each motorway
- Roads.org.uk Motorway Database – more information on the British motorway network.