Colourful Assembly Language, CASSEL, is a simplistic transpiled programming language making use of only HTML colour codes to write functional, Turing-Complete* code.
The compiler reads commands from colour codes in the pixels of a .PNG image and transpiles it into C++ code that you can compile and run yourself. The pixels are read from left to right, top to bottom. Any pixels that do not have an Alpha value of FF (= 255) will be ignored and treated like comments.
- Input and output
- Addition and subtraction
- Loops
- Data storage in memory
CASSEL features a three-way input system for using opcodes to perform a certain function. The values in the Green and Blue channels are always automatically converted to int before use.
| Channel | Argument |
|---|---|
| Red | Chosen opcode |
| Green | Variable address |
| Blue | Argument value |
| Opcode | Method |
|---|---|
| FF | Assignment |
| FA | Addition |
| F0 | Subtraction |
| CA | Input |
| C0 | Output |
| FE | Loop Begin |
| CE | Loop End |
Due to CASSEL's limitation by the max number, FF (= 255), that can be presented in a single channel, CASSEL features a fixed value as seen below.
| Hex Code | Behaviour |
|---|---|
| CC | Get value from next colour |
When the hex code CC is used in the Green or Blue channel, this tells CASSEL to look at the following colour code to get its information for that specific argument. This means the limit of FF (= 255) is removed and instead can hold up to FFFFFF (= 16,777,215).
Therefore, if you have reached the soft limit of 255, you can replace the channel value with CC and specify a greater-length number/address in the following colour code. If you use CC in both the Green channel and the Blue channel, you must specify two following colour codes containing values to be read into the Green and Blue channel respectively.
Example:
#FFCCCC
#000539
#0001A4
In the above example, the FF opcode is used in the Red channel to declare a variable. The CC in the Green channel specifies that the entire following colour code (0x539) will be used as a variable address. Because CC has been used in the Green channel already, CC in the Blue channel will now tell the compiler to use the second colour code specified (0x1A4) as a value to be set to the variable with the address specified in the Green channel.
This section will cover the usage and arguments of all 7 opcodes in the language.
Declares a variable with a given address and an assigned integer value within the current scope.
| Red | Green | Blue |
|---|---|---|
| FF | Variable Address | Value |
Variable Address - The name of the variable declared. Value - The value assigned to the variable.
Example: CASSEL (HTML Colour Code Translation)
#FF010C
C++ (Generated)
int v_1 = 12;Performs an addition operation on a variable with a given address using an assigned integer value.
| Red | Green | Blue |
|---|---|---|
| FA | Variable Address | Value Added |
Variable Address - The name of the variable being added to. Valued Added - The amount being added to the variable.
Example: CASSEL (HTML Colour Code Translation)
#FA0103
C++ (Generated)
v_1 += 3;Performs a subtraction operation on a variable with a given address using an assigned integer value.
| Red | Green | Blue |
|---|---|---|
| F0 | Variable Address | Value Subtracted |
Variable Address - The name of the variable being subtracted from. Valued Added - The amount being subtracted from the variable.
Example: CASSEL (HTML Colour Code Translation)
#F00F0A
C++ (Generated)
v_15 -= 10;Gets single-character input from the user with stdio, converts the character to an integer from UTF-8 and stores the value in a variable.
| Red | Green | Blue |
|---|---|---|
| CA | Variable Address | - |
Variable Address - The name of the variable in which the user's input is stored.
Example: CASSEL (HTML Colour Code Translation)
#FF0100
#CA0100
C++ (Generated)
int v_1 = 0;
char v_xxxx{};
std::cin.get(v_xxxx);
v_1 = int(v_xxxx);xxxx is a placeholder for a compiler-generated UUID
Prints out a single character from an integer stored in a variable with a given address. The integer is converted into a UTF-8 character before being outputted to the console.
| Red | Green | Blue |
|---|---|---|
| C0 | Variable Address | - |
Variable Address - The name of the variable in which the value that will be printed out is stored.
Example: CASSEL (HTML Colour Code Translation)
#FF0161
#C00100
C++ (Generated)
int v_1 = 97;
std::cout << char(v_1);Begins a loop over the code between this opcode and the closing opcode. Loops the number of times specified by the value in the variable with the given variable address.
| Red | Green | Blue |
|---|---|---|
| FE | Variable Address | - |
| CE | - | - |
Variable Address - The variable containing the amount of times to run the loop.
Example: CASSEL (HTML Colour Code Translation)
#FF0061
#FF0105
#FE0100
#C00200
#FA0001
#CE0000
C++ (Generated)
int v_0 = 97;
int v_1 = 5;
for (int v_xxxx = 0; v_xxxx < v_1; v_xxxx++)
{
std::cout << char(v_0);
v_0 += 1;
}xxxx is a placeholder for a compiler-generated UUID
The following is a simple Hello World program written (drawn) in CASSEL. This program does not feature string optimisation and is intended for demonstration purposes.
The following is a zoomed-in version of the image to be able to see it. The original is a 32x32 pixel image. The actual code is made up of the oddly coloured pixels in the ears. The rest of the pixels that are considered unimportant, have an Alpha value of FE (= 254). Enough to let the compiler know to ignore those pixels, and also to make the difference in opacity unnoticable to the viewer. The size of the image is unimportant when writing a normal program in CASSEL, the colours of individual pixels and their order is all that matters.
Original image:
The following is the CASSEL code represented as individual colour codes in regular text.
#FF0048
#C00000
#FF0165
#C00100
#FA0107
#FF0A02
#FE0A00
#C00100
#CE0000
#FF026F
#C00200
#FF032C
#C00300
#FF0420
#C00400
#FF0577
#C00500
#C00200
#FF0672
#C00600
#C00100
#FF0764
#C00700
#FF0821
#C00800
The following is the generated C++ code after the code in the image is transpiled.
#include<iostream>
int main()
{
int v_0 = 72;
std::cout << char(v_0);
int v_1 = 101;
std::cout << char(v_1);
v_1 += 7;
int v_10 = 2;
for (int v_xxxx = 0; v_xxxx < v_10; v_xxxx++)
{
std::cout << char(v_1);
}
int v_2 = 111;
std::cout << char(v_2);
int v_3 = 44;
std::cout << char(v_3);
int v_4 = 32;
std::cout << char(v_4);
int v_5 = 119;
std::cout << char(v_5);
std::cout << char(v_2);
int v_6 = 114;
std::cout << char(v_6);
std::cout << char(v_1);
int v_7 = 100;
std::cout << char(v_7);
int v_8 = 33;
std::cout << char(v_8);
return 0;
}xxxx is a placeholder for a compiler-generated UUID
Upon compiling and running the generated C++ code, the following output is received.
Hello, world!
This section will cover the preprocessing step in the compilation process. This information will help you write CASSEL code that generates cleaner and more efficient C++ code.
CASSEL has a string optimisation feature in which assignment opcodes followed by output opcodes that have consecutive matching variable addresses instead generate a string variable in C++. This is to avoid repeatedly creating int variables and printing out their char conversions.
For this to work, there must be at least 2 assignment opcodes followed by corresponding output opcodes. You can still have unrelated assignment or output opcodes before or after these string-optimised sections, they will be safely ignored as regular opcodes.
Example: In the following example, you can see that there are 3 assignments followed by 3 outputs, each variable address in the assignment opcodes corresponding to addresses in the output opcodes. Refer to the documentation for more information on how the assignment and output opcodes work.
CASSEL (HTML Colour Code Translation)
#FF0048
#FF0169
#FF0221
#C00000
#C00100
#C00200
C++ (Generated)
std::string v_xxxx = "Hi!";
std::cout << v_xxxx;xxxx is a placeholder for a compiler-generated UUID
*As the amount of variable addresses is finite, CASSEL is technically not Turing-Complete. However, there are over 16 million variable addresses available to be used. While not every problem could theoretically be solved with such a limitation, you could solve a good number. Also, this language is not meant to be taken seriously.

