Emoticon
Emoticon, designed by David Donachie in 2004, is an esoteric programming language which uses smileys for program instructions.
Introduction
Emoticon is a programming language based on "emoticons", or combinations of characters meant to look like facial expressions to convey appropriate emotion (where words fail to serve). In Emoticon these smileys are program instructions, while anything surrounding them is considered to be data. With some cunning it should be possible to embed Emoticon code in any normal message, though any reader would probably end up being very confused at what mood you were trying to convey!
Emoticon basics
Emoticon involves three basic concepts - Data items, Emoticons and Lists. An Emoticon is the basic unit of Emoticon code, and the List is a single type of data which holds all of the information in an Emoticon program. Anything that is not an Emoticon is a Data item. When the program is run Lists are created to hold Data processed (or generated) by the program.
Emoticons
==|8+]
An Emoticon is a sequence of at least two characters, not containing any white space, making up a program instruction. An Emoticon is made up of three elements - the mouth, the nose, and the face. The Mouth, or the rightmost character, controls what sort of command is being given. The Nose, which is the character immediately to the left of the Mouth, supplies the operator for the command (if any) while the Face (remaining characters) either defines what list the command operates on or is unused. Note that the characters in an Emoticon are case sensitive, so 'D' is a valid Mouth and 'd' is not.
For example, in the above Emoticon, the makeup is as follows:
Mouth ] Nose + Face ==|8
The meaning of this particular command will be touched upon later.
Lists
A | B | C | 1 | 2 | 3
A list is the only data type in Emoticon. A list is an ordered series of individual elements (words or numbers). A List has two accessible elements, the Left ('A' in the example above) and the Right ('3' in the example above), which can be read, moved, or added to. Elements between these two are inaccessible but the list can easily be manipulated so that middle elements become the left or right of the list. New elements can be added to either end of the list, or, using the insert emoticon (version 1.4+), into the middle of it.
Data items
A Data Item is anything in the code that is not recognized as an Emoticon. Note that words that end in valid Emoticon Mouth characters (such as ] or D) will be treated as Emoticons and could potentially lead to errors within the program. When a Data Item is encountered in code it will be put on the right of the currently active list (see below).
The Emoticon Environment
The Emoticon Environment consists of a series of Lists. Some of these are defined by the Interpreter and will always exist, others are defined by the program code. Emoticon code can manipulate any of these Lists.
One List is always designated as the current List. The current List is very important, since most instructions manipulate it in some way. At the start of any Emoticon program the current List is always the default List ':'. During execution of the code this may change, but the List ':' will always exist and be designated as current at the start of the program.
The core lists
The following Lists will always exist:
X: The program counter Z: The program source A: The name of the current list G: The list of set markers S: A single space E: An empty list : The default list
Program Execution
When an Emoticon program is run the following things happen.
- The source code is split into its constituent words and they are put (in order) into the list 'Z:', with the word 'START' prepended to them.
- The program counter ('X:') is set to 1
The interpreter then loops through the code, executing each instruction in 'Z:' as follows.
- The instruction at the position indicated by the program counter ('X:') is examined, starting with instruction 1, the first after the 'START' element.
- If the instruction is a Data item it is placed on the right of the current List
- If the instruction is an Emoticon it is executed
- If the instruction is empty (past the end of the code) execution ends
- The instruction counter is incremented by 1
- The interpreter returns to the first step.
The behaviour when Data is encountered is very important, since it allows data to be read into lists. Take the following example. Given the code
hello world
The following will be the contents of each of the lists at the end of execution.
X: 3 Z: START hello world A: : G: <empty> S: <space> E: <empty> : hello world
Of course it’s not enough simply to have data, to actually do anything useful you need Emoticons as well, which we will discuss in the next section.
The Emoticons
All Emoticons are defined by the mouth character (except for the obfuscation control statements). The following are all of the valid Emoticon mouths in Emoticon version 1.2. Each Emoticon is described further in the Emoticon Reference.
O Set current List to this list C Put number of elements of this list on left of current list < Move left of current list to left of this list > Move right of current list to right of this list [ Copy left of current list to left of this list ] Copy right of current list to right of this list V Insert current list into this list at right of ':' for right of ':'-1 elements D Replace contents of this list with contents of current list @ Rotate this list right a number of times equal to the left value of current list P Print left of this list Q Print left of this list and then delete it 7 Explode left of this list and put on left of this list L Explode right of this list and put on right of this list # Implode a number of items from the left of this list equal to the left of current $ Implode a number of items from the right of this list equal to the right of current { Treat nose as a maths operation to perform on the leftmost two elements of this list, remove them both and put the result on the left of this list } Treat nose as a maths operation to perform on the rightmost two elements of this list, remove them both and put the result on the right of this list \ Treat nose as a comparison operation to perform on the leftmost two elements of this list and put 'TRUE' or 'FALSE' on the left of the default list ':' / Treat nose as a comparison operation to perform on the rightmost two elements of this list and put 'TRUE' or 'FALSE' on the left of the default list ':' ( Open a Block ) Close a Block and return to matching open | Divide a block in two 3 Break - If the left of ':' is 'TRUE' move the program counter 'X:' to the next '|' or ')'. If the left of ':' is 'FALSE' do nothing. E Break - If the left of ':' is 'TRUE' move the program counter 'X:' to the next '|' or ')' and remove the 'TRUE' from ':'. If the left of ':' is 'FALSE' remove it. ^_^ Enter obfuscated mode ^__^ Leave obfuscated mode
In the table above the current list is the one indicated by 'A:'. This list is the one indicated by the face of the Emoticon being executed. For example in the following Emoticon
)8->
this list is ')8' and the rightmost element of the current list will be moved to the right of ')8'.
Hello World
As a short example to make everything described above make sense here is the Hello World program in Emoticon.
hello world :-Q S:-P :-Q
Let’s step through this code to see what happens.
hello The data item 'hello' is placed on the right of the current list ':' world The data item 'world' is placed on the right of the current list ':' :-Q The left of the list ':' ('hello') is printed out and then removed S:-P The left of the list 'S:' (' ') is printed out :-Q The left of the list ':' ('world') is printed out and then removed
You can view this in action (and watch the lists change) using the interpreter.
Flow Control
Flow control in Emoticon is handled by dividing the code into blocks using the '(', ')', '|', '3' and 'E' emoticons.
When an open block '(' is encountered the current value of the program counter 'X:' is stored on the right of the list 'G:'. When a close block ')' is encountered the rightmost value of the list 'G:' is removed and the program counter is set to that value. This causes execution to return to the open block.
For example the following code will print 'help!' forever
help! :-( :-P :-)
Each time the code reaches the last Emoticon (the close block) it will return to the location set in 'G:', which is the location of the last open block.
The Break Emoticons allow you to exit from a block. When a break ('3' or 'E') is executed the left of ':' is examined. If it is 'TRUE' then the program counter is moved forward to the next '|' or ')' and restarts from there. This allows you to exit from a loop, or to use a block as an IF-ELSE construct.
Loops
Here is a break being used to exit a loop
help! :-( :-P 8-O :=\ :-E :-)
IF-THEN-ELSE
Here is one being used as an IF - ELSE
8-O 1 [8-O 1 :-( 8=\ :-E NOT EQUAL :-| EQUAL :-)
Naturally if the interpreter executes a '|' it will move onwards to the end of the corresponding block.
GOTO
You can easily replicate a GOTO instruction by storing the program counter in a List and later setting the program counter to that list using 'D'. Here is an example.
1 X:-O Set current list to X: (the counter) 2 [8-[ Copy counter (2) to [8 3 ... Do some stuff 4 [8-O Set current list to [8 5 X:-D Copy value in X: with that in [8
Because the program counter is always incremented at the end of each cycle the result will be to set the counter to the position of '[8' + 1, in this case 3. So at the end of this example the code will jump back to the '...' instruction.
Emoticon Reference
Utility Emoticons
O - SET CURRENT :-O (SURPRISED FACE)
This emoticon sets the current list to its face. e.g. ':-O' sets the current list to ':'
C - COUNT :-C (VERY SAD FACE)
This emoticon counts the list set in its face and puts that value on the left of the current list. e.g. If ':' is
a b c
':-C' puts '3' on the left of the current list.
@ - ROTATE :-@ (SCREAM!!!)
This emoticon rotates the list specified in its face, taking elements off the right and putting them on the left. It does this a number of times equal to the value on the left of the current list. e.g.
a : = a b : = a b c : = a b c 8-O Set current list to 8 2 8 = 2 8-@ : = b c a
Assignment Emoticons
< and > - MOVE :-> (MISCHEVIOUS SMILE)
These emoticons take the left ('<') or right ('>') of the current list and move it to the corresponding end of the list set in its face. e.g. ':->' moves the right value of the current list to the right end of ':'
[ and ] - COPY :-[ (NOT HAPPY) :-] (CAUTIOUSLY HAPPY)
These emoticons take the left ('[') or right (']') of the current list and copy it to the corresponding end of the list set in its face, leaving the original intact. e.g. ':-]' copies the right value of the current list to the right end of ':'
D - ASSIGN :-D (VERY HAPPY)
This replaces the entirety of the list indicated by its face with the entirety of the current list. e.g. ':-D' copies all of current list to ':' replacing what was there.
V - INSERT :-V (SINGING)
This emoticon inserts one list into another. It first takes (and removes) a number off the left of ':', this will be the insertion point, it then takes (and removes) another number off the left of ':', this will be the number of list elements replaced in the target list.
The entirety of the current list is then removed and inserted into this list, starting at the insertion point and replacing a number of elements equal to the replacement count. If this is 0 then the the current list is inserted into this list at the insertion point.
Finally if any elements were replaced then ':' is replaced with the removed elements.
e.g.
: = 1 1 8 = a X c B: = b
Executing 'B:-O 8-V' will result in
: = X 8 = a b c B: = b
7 and L - EXPLODE :-7 (WRY) :-L (NERVOUS)
This removes the left ('7') or right ('L') of the list indicated by its face, explodes it into its individual characters, and puts its back on the corresponding end of the list. e.g. If ':' is
hello world
Then the emoticon ':-7' will leave it as
h e l l o world
# and $ - IMPLODE :-# (OOOPS) :-$ (ILL)
This takes a number of elements off the left ('#') or right ('$') of the list indicated by its face, combines them into a single element, and puts it back on the corresponding end of the list. The number of elements taken is defined by the left ('#') or right ('$') of the current list.
If the nose is '~' then the elements are put together with spaces between them, otherwise they are not.
e.g. If ':' is
h e l l o world
And '8' is 5. Then ':-#' will leave ':' as
hello world
While ':~#' will leave it as
h e l l o world
Output Emoticons
P - PRINT :-P (TONGUE STUCK OUT)
This prints out the value on the left of the list indicated in its face. e.g. ':-P' prints out the value on the left end of ':'
Q - PRINT AND POP :-Q (SMOKING)
This prints out the value on the left of the list indicated in its face, and then removes that value. e.g. ':-Q' prints out the value on the left end of ':' and then deletes it.
Maths Emoticons
{ - MATHS LEFT :-{ (WORRIED)
This takes the leftmost two elements of the list indicated in its face, and then performs a maths operation on them. The operation is controlled by the nose character. The valid operations are
+ addition - subtraction x multiplication / division \ MOD (gives the remainder after division)
The order of the maths operation is to put the leftmost value on the left of the operator, and the next on the right.
e.g. if you have the following values on the list ':'
4 50 10
Then the Emoticon ':+{' would take 4 and 50 off the list ':', add them, and put the result back on the left of the list, leaving
54 10
} - MATHS RIGHT :-} (PLEASED)
Just like '}' except working on the right end of the list, and treating the values in the opposite direction. e.g. if you have the following values on the list ':'
4 50 10
Then the Emoticon ':-}' would take 10 and 50 off the list ':', subtract 50 from 10 them, and put the result back on the left of the list, leaving
4 -40
Comparison Emoticons
\ - COMPARE LEFT :=\ (CONFUSED AND WORRIED)
This takes the element on the left of the current list and compares it to the element on the left of the list indicated in the face and then puts 'TRUE' or 'FALSE' on the left of ':', depending on the result of the comparison. The valid operations are
= TRUE if the two values are equal > TRUE if the value on the left of current is greater than the left of this list < TRUE if the value on the left of current is less than the left of this list ~ TRUE if the two values are not equal
e.g. if the left of the current list is '3' and the left of the list '[8' is also '3' then the Emoticon '[8=\' will put 'TRUE' on the left of ':'
/ - COMPARE RIGHT :=/ (EVEN MORE CONFUSED)
The same as '\' except that it compares the right value of the current list with the right of this list and puts the result on the right of ':'.
Block Control Emoticons
( - OPEN BLOCK :-( (UNHAPPY)
This puts the current instruction number on the right of 'G:'. (See flow control).
) - CLOSE BLOCK :-) (HAPPY)
Returns execution to the location of the corresponding open block (the value on the right of 'G:') unless that value is 'IF', indicating that this is the last part of a conditional. (See flow control).
| - DIVIDE BLOCK :-| (UGH!!)
Puts 'IF' on the right of 'G:'. Usually this will only be executed if it is in an IF-THEN block and the second part is being executed. the 'IF' will stop the following ')' returning to the start of the block. (See flow control).
3 - BREAK :-3 (CURLY MOUSTACHE)
If the left value of ':' is 'TRUE' then moves the program counter ('X:') to the instruction following next '|' or ')' in this block. (See flow control).
E - BREAK AND POP :-E (HANDLEBAR MOUSTACHE)
The same as '3' except that the value on the left of ':' is also deleted.
Obfuscation Emoticons
^_^ - OBFUSCATION ON
Enables pure obfuscation mode (see obfuscation guide).
^__^ - OBFUSCATION OFF
Disables pure obfuscation mode (see obfuscation guide).
Examples
Hello World
Prints "hello world":
hello world :-Q S:-P :-Q
Quine
Prints its own source:
Z:-O 8-D 8-O ===||8-< :-( 8-Q [8=\ [8~E S:oP :-)
Reverse Input
Prints its input (the words on the first line), reversed.
hello world )]:-O :-C :~# :-7 :-O :-( [:]o< 8=\ 8-E :-) [:]oO :-( [:]oQ 8=\ 8-E :-)
Self-Modifying
Constructs a print-and-pop operator and inserts it into its own code. The central routine should be entirely portable.
** set up the operator we want to insert ** 8O : - Q $:-O 3 8-$ ** implode the characters we read ** ** preform the insert ** E:-O :D ** clear the : list ** :-O 0 ** load the length for the splice, 0 means just insert ** X:-O :-] ** use prog counter to get the location for the splice ** :-O 8 :+} ** increment splice location by offset to location (8) ** 8O Z:-V ** actually do the splice ** ** continue after insert ** :-O not_printed ** insertion point for new code ** S:-P printed :-Q
Double Loops
Loops twice, and inside each loop loops twice again, printing the current loop counters.
[8-O 2 =|8-O 1 ()=O 0 :-( <|8-O 2 [8-P :-( <|8-P <|8-O :-[ =|8-O :-[ :-{ :-O <|8=D ===|8-< <|8-O ()=\ :-E :-) ===|8-< [8-O :-[ =|8-O :-[ :-{ :-O [8=D ===|8-< [8-O ()=\ :-E :-)
See also
- x-D
- Cfluviurrh -- while Emoticon programs consist almost entirely of emotive notation, they are not required to experience any emotions during execution; in contrast, Cfluviurrh's syntax is devoid of emotive notation, but its programs are required to actually have feelings.