MailBox
MailBox is a language based around e-mail filters. A program consists of a series of numbered mailboxes. Each box contains rules. Each rule is associated with a list of actions. When a message is received in a mailbox, the rules are evaluated and if they evaluate to true, the actions are applied.
The syntax for a mailbox is:
box NUMBER (rule) actions (rule) actions (rule) actions
etc (you can have as many rule/action pairs as you want, but there must be at least one even if it does nothing) NUMBER should be replaced with the mailbox number, which must be a non-negative integer.
Rules
(RULE denotes another rule. INT denotes an integer and STR denotes a "-delimited string)
( RULE ) | Brackets | |
true | always true | |
false | always false | |
RULE and RULE | logical and | |
RULE or RULE | logical or | |
not RULE | logical not | |
from INT | True if the message came from the specified mailbox number | |
forwarded | True if the message was forwarded at least once | |
contains STR | True if the message subject contains the string | |
contains count | True if the message subject contains a string representation of the number of items in this mailbox (the "count" of this mailbox) | (usefulness?) |
contains count INT | True if the message subject contains a string representation of the number of items in the specified mailbox | (usefulness?) |
from count | True if the message was received from the mailbox with the number equal to the count of this mailbox. | |
from count INT | True if the message was received from the mailbox with the number equal to the count of the specified mailbox. | |
empty | True if this mailbox is empty. Note that this will never be true when processing a message. | |
once | True if this rule has never previously evaluated to true |
Rules may evaluate to true even when no message is being received. (eg (true)
or (not contains "xyz")
) All rules that evaluate to true at the beginning of execution will be processed in the order they are in the source file. If a rule evaluates to true at any other time, it is undefined when the associated actions will be run.
Actions
send STR to INT | Send a message with the specified subject to the specified mailbox. |
send count STR to INT | Sends one message with the specified subject to the specified mailbox, for every message in this mailbox. (if this mailbox has 5 messages, for example, then 5 messages will be sent) |
send STR to count | Send a message with the specified subject to the mailbox with a number equal to the number of messages in this mailbox. |
send count INT STR to INT | Sends one message with the specified subject to the mailbox specified by the second number for every message in the mailbox specified by the first number |
empty | Delete all messages from this mailbox. |
send STR to count INT | Send a message with the specified subject to the mailbox with a number equal to the number of messages in the specified mailbox. |
forward to INT | If the rule was processed because a message was received, forward the message to the specified mailbox. |
forward to INT with STR | If the rule was processed because a message was received, forward the message to the specified mailbox after concatenating the given string to the subject. |
send count INT STR to count | Send one message with the specified subject to the mailbox with a number equal to the number of messages in the current mailbox, for every message in the specified mailbox. |
send count STR to count INT | Send one message with the specified subject to the mailbox with a number equal to the number of messages in the specified mailbox, for every message in the current mailbox. |
receive box number | Add the number of the current mailbox to the number of messages in the current mailbox. No rules are processed for these messages. |
output without STR | If the rule was processed because a message was received, output the message's subject followed by a newline after removing all occurrences of the given string. |
output | If the rule was processed because a message was received, output the message's subject followed by a newline. |
output count | Output the number of messages in the current mailbox, followed by a newline. |
output count INT | Output the number of messages in the specified mailbox, followed by a newline. |
delete | If the current mailbox has any messages, delete one of them. |
send input to INT | Input a string, and use it as the subject of a message which is sent to the specified mailbox. |
Order of evaluation
Any rules that evaluate to true at the beginning of execution (before any messages were sent) are evaluated in the order they are defined in the source file. Any rules that evaluate to true at any other point in time, except when processing a message, will be executed at an undefined time.
Messages are processed in the order they are sent. For each message, all rules from all mailboxes are evaluated in the order they are defined in the source file and their actions executed if applicable. The number of messages in a mailbox is incremented immediately before the first rule in the mailbox is evaluated.
Control constructs
Infinite loop:
box 0 (once) send "loop" to 1 (contains "output") output without "output" box 1 (contains "loop") send "outputHello, world!" to 0 forward to 1
Examples
Hello world:
box 0 (once) send "outputHello, world!" to 0 (contains "output") output without "output"
Fibonacci sequence:
box 0 // initialisation and code (once) send "empty" to 1 send "empty" to 2 send "add" to 1 send "add" to 2 send "again" to 0 (contains "again") send "empty" to 3 send "read" to 1 send "read" to 2 send "m2ove" to 3 box 1 // 2nd to last (contains "empty") empty (contains "read") delete send count "add" to 3 box 2 // last (contains "empty") empty (contains "read") delete send count "add" to 3 (contains "move") delete send count "add" to 1 empty box 3 // next (contains "move") delete send "empty" to 1 send "move" to 2 send "empty" to 2 send count "add" to 2 output count send "again" to 0 (contains "empty") empty (contains "m2ove") delete send "move" to 3 box 4 // output (contains "1" and not contains "s") output count 1 delete (contains "2" and not contains "s") output count 2 delete (contains "3" and not contains "s") output count 3 delete (contains "s") output without "s" delete
Cat:
box 0 (once) send input to 1 box 1 (from 0) output
Computational class
MailBox is Turing-complete, since it can simulate a counter machine with any number of registers:
Register r:
box r (contains "dec") delete delete
Appended to initial instruction:
(once) send "eval" to x
INC(r):
box x (not empty) empty send "inc" to r send "eval" to (x+1)
JZDEC(r, z):
box x (contains "eval") empty send count r "2" to x send "1" to x (contains "2" and contains count) delete (contains "1" and not contains count) empty send "dec" to r send "eval" to (x+1) (contains "1" and contains count) empty send "eval" to z
HALT:
box x