Exemoji
| Paradigm(s) | imperative |
|---|---|
| Designed by | User:Glax |
| Appeared in | 2024 |
| Memory system | Cell-based |
| Dimensions | one-dimensional |
| Computational class | Turing complete |
| Reference implementation | exemoji.py |
| Influenced by | x86 |
| File extension(s) | .yip, .yap |
Exemoji is an 8bit computer architecture based on emoji.
Instructions are sequences of utf8-encoded emoji, making executables valid text files.
Playground
There is a web-based virtual machine that can execute and debug exemoji bytecode.
Registers
Exemoji supports 8 general-purpose 8bit registers:
| Register | Index | Special Use |
|---|---|---|
| π | 0 | Left handside operand for mathematical operations |
| π± | 1 | Right handside operand for mathematical operations |
| π² | 2 | Main result for mathematical operations |
| π¦ | 3 | Secondary result for mathematical operations |
| π― | 4 | |
| π¦ | 5 | |
| π¦ | 6 | |
| π» | 7 |
In addition to these, there are two 16 bit registers, the program counter (PC) and stack pointer (SP), which are affected by specific instructions.
Immediates
Immediate values can be directly encoded by bytes but this will sometimes result in invalid utf-8 sequences, as such there is an emoji alternative to encode immediate values
A nibble can be represented by one of the following emoji:
| Code | Hex | Dec |
|---|---|---|
| π | 0 | 0 |
| π | 1 | 1 |
| π | 2 | 2 |
| π« | 3 | 3 |
| π | 4 | 4 |
| π | 5 | 5 |
| π | 6 | 6 |
| π₯ | 7 | 7 |
| π | 8 | 8 |
| π | 9 | 9 |
| π | a | 10 |
| π | b | 11 |
| π | c | 12 |
| π₯₯ | d | 13 |
| π₯ | e | 14 |
| π | f | 15 |
To represent a full byte (octet), you need to prefix the immediate with π½ followed by two nibble emoji.
Instructions
| Opcode | Name | Operands | Description | ||
|---|---|---|---|---|---|
| πΈ | Swap | regβ | regβ | Swaps the value of regβ and regβ | |
| π | Assign | regβ | immβ | Assigns immβ to regβ | |
| π | Move | regβ | regβ | Assigns the value of regβ to regβ | |
| π«Έ | Push | regβ | Pushes regβ into the stack, incrementing the stack pointer | ||
| π₯ | Pop | regβ | Pops regβ from the stack, decrementing the stack pointer | ||
| πΎ | Load from SP | regβ | regβ | Loads into regβ the memory location regβ bytes before the stack pointer | |
| π§ | Load Long | regβ | regβ | regβ | Loads in regβ the absolute memory address obtained by combining regβ and regβ |
| π | Store Long | regβ | regβ | regβ | Stores regβ at the absolute memory address obtained by combining regβ and regβ |
| π¦ | Trigonometry | Polar coordinates of π as an angle (2pi = 256) and π± as length, offset by 127. π² will be x and π¦ will be y | |||
| π’ | Add | Adds π to π±, storing the result in π² and overflow in π¦ | |||
| π¦ | Subtract | Subtracts π± from π, storing the result in π², if the result is negative, π¦ will hold the absolute value of the negative result | |||
| π° | Multiply | Multiplies π to π±, storing the result in π² and overflow in π¦ | |||
| π | Divide | Divides π by π±, storing the result in π² and remainder in π¦ | |||
| π¦ | Or | Bitwise OR between π and π±, storing the result in π² | |||
| πͺ’ | Not | Bitwise NOT of π, storing the result in π² | |||
| π¦ | And | Bitwise AND between π and π±, storing the result in π² | |||
| π | Xor | Bitwise XOR between π and π±, storing the result in π² | |||
| π§ | Compare | Compares π and π±, storing the result in π²: 0 if equal, 1 if π± is greater ff if π is greater | |||
| π | Jump forward | emoβ | Jumps forwards, if emoβ is an immediate value by that many bytes, otherwise after the next occurrence of that emoji | ||
| π | Jump back | emoβ | Jumps backwards, if emoβ is an immediate value by that many bytes, otherwise after the previous occurrence of that emoji | ||
| π€ | Jump 0 fwd | emoβ | Jumps forwards when π² is 0, if emoβ is an immediate value by that many bytes, otherwise after the next occurrence of that emoji | ||
| π | Ignore | emoβ | Ignores emoβ | ||
| π¦Έ | Long Jump | immβ | immβ | Jumps to the absolute location obtained by combining immβ and immβ | |
| π« | Call | immβ | immβ | Pushes the program counter into the stack (most significant byte first) and jumps to the absolute location obtained by combining immβ and immβ | |
| π¬ | Pop PC | Pops the program counter from the stack (least significant byte first) | |||
| π« | Halt | Stops program execution | |||
| π€ | Inerrupt | immβ | Generates interrupt immβ | ||
Some instructions take 16 bit addresses represented as a pair of operands. These are combined by interpreting the first operand as the most significant byte.
Interrupts
Interrupts allow you to perform output operations
| Code | Effect |
|---|---|
| Text Output | |
| 00 | Prints π² as a character to the output |
| Graphics | |
| 10 | Enables / clears graphics output |
| 11 | Sets graphics stroke color to r π g π± b π² |
| 12 | Sets graphics stroke width to π |
| 13 | Applies stroke style to the current path |
| 14 | Sets graphics fill color to r π g π± b π² |
| 15 | Applies fill style to the current path |
| Graphics Path Commands | |
| 20 | Begins a new path |
| 21 | Closes the current path |
| 22 | Moves the path pen to x π y π± |
| 23 | Draws a line from pen position to x π y π± |
Examples
Hello World
This prints "Hello World" from a string stored explicitly in memory:
The following code also prints "Hello World" but the characters are evaulated with code instead of being stored in memory:
FizzBuzz
The classic FizzBuzz:
Graphics
This example uses the graphics interrupts to draw a house:
Output:
External Links
- Glax's site contains a description of the and a web-based interpreter and debugger.
- exemoji.py Python-based interpreter of the language
