Emoticon v1.7

manual | emoticon interpreter | obfuscation | contributions | version history
The Esoteric Programming Languages Ring
<< Prev Ring Hub Next >>

Introduction

Emoticon is a programming langauge based on emoticons, or smileys, such as those that excessivly littered many bad emails and chat posts before the introduction of emojis. In Emoticon these smileys become program instructions, while anything surrounding them becomes 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!

A web based Emoticon Interpreter, written in PHP, is available on this site.

Emoticon basics

Emoticon involves three basic concepts, Data items, the Emoticon, and the List:

An Emoticon program is made up of Emoticons seperated by Data Items. 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 (which is the rightmost character) controls what sort of command is being given, the Nose (which is the character immediatly to the left of the mouth) supplies the operator for the command (if any) while the Face (every character excluding the mouth, and the nose if the Emoticon has more than two characters) defines what list the command operates on, or is unused. Note that the characters in an Emoticon are case sensitive, so that 'D' is a valid mouth and 'd' is not.

For example, in the Emoticon above the breakdown is as follows.

Mouth]
Nose+
Face==|8

We will discuss the meaning of this command a little later on.

Lists

ABC123

A list is the only data type in Emoticon. A list is an ordered series of individual elements, each of which is an Emoticon or a Data item. 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 any word in the code that is not recognised as an Emoticon. Note that words that end in valid Emoticon Mouth characters (such as ] or D) will be treated as Emoticons and could lead to errors. 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.

  1. The source code is split into its constituent words and they are put (in order) into the list 'Z:', with the word 'START' preprended to them.
  2. The program counter ('X:') is set to 1

The interpreter then loops through the code, executing each instruction in 'Z:' as follows.

  1. 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 instuction 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
  2. The instruction counter is incremented by 1
  3. 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:
STARThelloworld
A:
:
G:
S:
 
E:
:
helloworld

Of course its 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

OSet current List to this list
CPut 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
VInsert current list into this list at right of ':' for right of ':'-1 elements
DReplace conents of this list with contents of current list
@Rotate this list right a number of times eqal to the left value of current list
PPrint left of this list
QPrint left of this list and then delete it
*Add input to this list
7Explode left of this list and put on left of this list
LExplode 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
3Break - If the left of ':' is 'TRUE' move the program counter 'X:' to the next '|' or ')'. If the left of ':' is 'FALSE' do nothing.
EBreak - 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.
JJump to the marker corresponding to its face
^_^Enter obfuscated mode
^__^Leave obfuscated mode
_(._.)_Toggle literal mode
(°_°)_Marker for whatever face it is holding in its hand
O_oBreak the output stream to a new line

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

Lets step through this code to see what happens.

helloThe data item 'hello' is placed on the right of the current list ':'
worldThe data item 'world' is placed on the right of the current list ':'
:-QThe left of the list ':' ('hello') is printed out and then removed
S:-PThe left of the list 'S:' (' ') is printed out
:-QThe 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! :-(
   :-Q
   8-O
   :=\
   :-E
:-)

IF-THEN-ELSE

Here is one being used as an IF - ELSE

8-O 1 [8-O 10
:-(
   8=\
   :-E
   :-O not equal
:-|
   :-O equal
:-)
:~# :-P

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.

1X:-OSet current list to X: (the counter)
2[8-[Copy counter (2) to [8
3...Do some stuff
4[8-OSet current list to [8
5X:-DCopy 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. Alternatively, use the Jump emoticon.

Emoticon Reference

Utility Emoticons

O - SET CURRENT      :-O (SUPRISED 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

abc

':-C' puts '3' on the left of the current list.

X - REVERSE (1.5)      :-X (PURSED LIPS)

This emoticon reverses the order of elements in the list specified in its face.

@ - 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: =
ab
c: =
abc
8-OSet current list to 8
28 =
2
8-@: =
bca

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. ':-]' copys 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' copys 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 number of list elements replaced in the target list, it then takes (and removes) another number off the left of ':', this will be the insertion point.

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.

: =
11
8 =
aXc
B: =
b

Executing 'B:-O 8-V' will result in

: =
X
8 =
abc
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

helloworld

Then the emoticon ':-7' will leave it as

helloworld

# 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 there are no elements in the list specified to provide the number, or the value is not a number, then the entire list will be imploded.

If the nose is '~' then the elements are put together with spaces between them, otherwise they are not.

e.g. If ':' is

helloworld

And '8' is 5. Then ':-#' will leave ':' as

helloworld

While ':~#' will leave it as

h e l l oworld

Output Emoticons

These Emoticons output values from lists to Output Channels. Output channels are not lists, they are defined by the Interpreter and could be on screen areas, files, pipes and the like. Output Channels are implementation dependant. The Channel to which output should be printed is indicated by the nose of the Emoticon. By default screen print values should go to the channel -

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.

Input Emoticons

* - INPUT      :-* (PURSED MOUTH)

Pause execution to request user input. The user input is treated as data and read into this list as if it had been inline at the same location as the input emoticon. If the nose is '~', then the current list is treated as a prompt for the input.

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 controled by the nose character. The valid operations are

+addition
-subtraction
xmultiplication
/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 ':'

45010

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

5410

} - 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 ':'

45010

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 ':'.

Flow 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!!)

Causes execution to continue from the instruction following the next enclosing ). (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.

J - JUMP      ==:-J (TONGUE IN CHEEK)

Jumps program execution to the marker corresponding to its face. e.g. '==:-J' jumps to the marker '(°_°)_==:'.

Compilation Control Emoticons

^_^ - OBFUSCATION ON

Enables pure obfuscation mode (see obfuscation guide).

^__^ - OBFUSCATION OFF

Disables pure obfuscation mode (see obfuscation guide).

_(._.)_ - TOGGLE LITERAL MODE

Toggles literal mode. In literal mode all tokens are treated as Data items, even if they resemble Emoticons.

(°_°)_ - MARKER

Indiciates a marker equal to what it holds in its hand. e.g. '(°_°)_==:' indicates a marker of '==:', which you could jump to with '==:-J'.

Output Control Emoticons

O_o - LINE BREAK

Outputs a line break in an output stream.

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:-P :-)

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 it's 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

Loops

Loops a set number of times, printing the current loop counter.

** first set up some useful values **
    |8-O   5               ** this is the counter for the loop          **
    =|8-O  1               ** this is the decrement value               **
    ()=O   0               ** this is the comparison value for stopping **

** now do the actual looping **
    :-(
       |8-P                ** print the current inner loop value        **
       =|8-O               ** select the decrement value                **
       |8-[                ** copy the decrement value to the counter   **
       |8-}                ** decrement the counter                     **
       |8-O                ** select the counter                        **
       ()=\                ** is the counter equal to the stop value?   **
       :-E                 ** if so break the loop                      **
       :-O - :-Q           ** print a divider                           **
    :-)