From Esolang
Jump to navigation Jump to search

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.


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


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


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)
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,
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 (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