Cheers

Cheers is an esoteric programming language aimed at beverage-oriented programming.

Partially inspired by INTERCAL and Chef.

Statements
A Cheers program consists of a list of statements. The following statements are recognized:
 * beverage preparation,
 * pour and spill statements,
 * cheers and sip statement,
 * ask for statement,
 * throw up statement,
 * binge ... end loop,
 * mumble statement.

The language is case-insensitive and statements can be delimited with any of ,. ; ? ! \n</tt>. For example, the following two are equivalent: binge pour 200 ml of water cheers end Binge! Pour 200 ml of water, cheers! End.

The language syntax uses  </tt>s,  </tt>s and  </tt>s. Names are sequences of case-insensitive ASCII letters and dashes (-</tt>). Volumes are floating-point literals followed by ml</tt> unit. Percentages are floating-point literals in the range 0-96, followed by a %</tt> sign.

prepare</tt>
The prepare</tt> statement declares and initializes a new beverage object. There are several alternative uses of this keyword:


 * prepare drink </tt> — creates a new drink with a given name and sets its strength to  </tt>, e.g. prepare drink wine 12%</tt>.
 * prepare soft drink </tt> — alias for prepare drink 0%</tt>.
 * prepare syrup</tt> — creates a new syrup with a given name; all syrups have 0% strength and reside in a separate namespace (so e.g. wine</tt> refers to a drink and <tt>wine syrup</tt> refers to a syrup.
 * <tt>prepare water</tt> — prepares some water; because water is a global object and is accessible from the beginning, <tt>prepare water</tt> is a documented NOP.
 * <tt>prepare drink as end</tt> — creates a new drink with a content described by the compound statement; the compound statement must contain at least one <tt>pour</tt> statement.

An example of a preparation with a compound statement: prepare drink U-Boot as   prepare drink Vodka 40% pour 40 ml of Vodka prepare drink Beer 5% pour slowly 200 ml of Beer end

<tt>pour</tt> and <tt>spill</tt>
The <tt>pour</tt> and <tt>spill</tt> are statements used for operations on an implicit container, so-called “working glass”.

Pouring adds a quantity to the working glass:
 * <tt>pour fast of </tt> — adds a quantity of a beverage to the working glass and, if it is not empty, mixes it with its contents; the strength of the new beverage is a weighted average of the strengths of the components (e.g. 90 ml of a 10% drink and 10 ml of water combine to 100 ml of a 9% drink).
 * <tt>pour slowly of </tt> — similar to the one above, except the contents are not mixed, but “layered” (think of it as of adding new elements to the container).
 * <tt>pour of </tt> — computes to <tt>pour slowly ...</tt> for syrups and <tt>pour fast ...</tt> for other beverages.

Spilling removes a quantity from the working glass:
 * <tt>spill </tt> — removes a quantity of beverage from the working glass; if the quantity is greater that the contents, the glass becomes empty; if the contents are layered, first a quantity of the last element is removed, then the second-to-last, and so on, until the given amount of spill is reached.

The working glass has a maximum capacity of 500 ml, any operation that would result in an overflow causes an implicit spill of the superfluous quantity, for example: pour 100 ml of juice pour fast 200 ml of water pour slowly 100 ml of juice pour slowly 200 ml of water will result of 100 ml of water being spilled. (The final state of the working glass will be: 300 ml of juice-water, 100 ml of juice and 100 ml of water.

<tt>pour fast 0 ml of water</tt> can be used as an idiom for mixing contents of the working glass.

If inside of a <tt>prepare</tt> compound statement, the contents of the working glass are then returned as the prepared drink.

<tt>cheers</tt> and <tt>sip</tt>
The <tt>cheers</tt> and <tt>sip</tt> statements are used for consuming the contents of the working glass.


 * <tt>cheers</tt> — consumes all the contents of the working glass; the global intoxication counter is incremented by combined strength × volume (e.g. consuming 40 ml of 40% vodka will increment the counter by 16) and the glass becomes empty.
 * <tt>sip </tt> — works similarly to <tt>spill</tt>, except the contents are not spilled, but consumed as with <tt>cheers</tt>.

Please note that layered contents don't get mixed while drinking, but are consumed last element first.

<tt>ask for</tt>
The <tt>ask for</tt> statement is used for text input.


 * <tt>ask for a drink</tt> — reads a sequence of n identical characters c from the standard input, creates a beverage of n% strength and pours ord(c) ml into the working glass (e.g. a sequence <tt>bbb</tt> adds 98 ml of a 3% beverage).

<tt>throw up</tt>
The <tt>throw up</tt> statement is used for text output.


 * <tt>throw up</tt> — outputs all the already consumed beverages, the last one consumed first, by transforming the strength into the length and the volume into the code of a character (e.g. 100 ml of 5% beverage is transformed into <tt>ddddd</tt>, i.e. five characters of code 100).

This statement has a side effect of zeroing the intoxication counter.

No corresponding <tt>catch</tt> is supported.

<tt>binge</tt>
The <tt>binge</tt> statement is used for constructing loops.


 * <tt>binge <compound-statement> end</tt> — constructs a loop and computes the inner statements while the intoxication counter is less than 200.

For example:

binge prepare drink beer 5% pour 200 ml of beer cheers end Above, the loop will be executed 20 times (the counter starting at 0 and incremented by 5% × 200 = 10).

<tt>mumble</tt>
The <tt>mumble</tt> statement is used for writing comments. All the input till the end of the statement (any of <tt>, . ; ? ! \n</tt>) is discarded.

Infinite loop
The following program will never terminate: binge pour water cheers end

Echo
The following program reads the input and repeats it to the output: binge ask for a drink cheers throw up end

Reverse
The following program reads the input and outputs it in reverse: binge ask for a drink cheers end throw up ; mumble --  note the difference

Hello world
The following program outputs "Hello world!". prepare drink Hennchata 1% prepare drink El-Presidente 1% prepare drink Double-Lorraine 2% prepare drink Old-Spanish 1% prepare drink White-Lady 1% prepare drink Whiskey-Sour 1% prepare drink Rossini 1% prepare drink Lorraine 1% prepare drink Daiquiri 1% prepare drink Wow 1%

pour 33 ml of Wow cheers pour 100 ml of Daiquiri cheers pour 108 ml of Lorraine cheers pour 114 ml of Rossini cheers pour 111 ml of Old-Spanish cheers pour 119 ml of Whiskey-Sour cheers

pour 32 ml of White-Lady cheers pour 111 ml of Old-Spanish cheers pour 108 ml of Double-Lorraine cheers pour 101 ml of El-Presidente cheers pour 72 ml of Hennchata cheers

throw up