(SIASL)² is an Esolang
It belongs to the Turing tarpit family of languages.
and takes inspiration from the most famous one Brainfuck.
The most simple way to descripe it would be as some sort of 2d Brainfuck.
see Generic 2D Brainfuck and 2DFuck
for reference.
the name SIASL stands for Siasl Is a Silly Language (very good name). The ()² part comes from the fact that
each (SIASL)² instruction is two SIASL instruction (SIASL is the language
I made before making this one and was a way for me to learn a few stuff before doing (SIASL)² ).
The main thing differentiating (SIASL)² from these languages is that a (SIASL)² instruction is a combination of two characters instead of one.
(check out parts III and IV for more details).
Crucially (SIASL)² instructions are commutative; which means that +♯
is the exact same thing as ♯+
which limits the amount of instructions that can be created in (SIASL)² but makes it (in my opinion)
easier to use.
similarly to brainfuck ; (SIASL)² does operation on cells containing numbers. However the structure containing these cells is a square matrix instead of an array. This allows movement in 4 directions instead of two ( < , > , v , ^ related operations). Each cell contains a signed integer. It's value can be modified by a lot of different operations. When reaching the end of a "line" in the matrixprintf and trying to go to the right the data pointer will be move to the next one. Similar behavior occurs when reaching the start and trying to go to the left or when reaching the first/last line of the matrix and going up or down.
(SIASL)² supports a lot of predefined instruction with different effects. It is
important to understand that (SIASL)² instruction are commutative. Thus
v♯
will always do the exact same thing as ♯v
It also supports multi-line comments. everything written in between {
and }
will be ignored
by the interpreter.
NB: The behavior of preset instruction cannot be changed.
instruction containing a ♯
are very similar to traditionnal Brainfuck instruction.
They are simple and straightforward operations. I call them the "default" family of instruction.
Command | Description |
---|---|
>♯ |
Move the pointer to the right |
<♯ |
Move the pointer to the left |
v♯ |
Move the pointer downwards |
^♯ |
Move the pointer upwards |
+♯ |
increments the cell under the pointer |
-♯ |
decrements the cell under the pointer |
.♯ |
prints the value stored at the current cell as a character |
,♯ |
reads a character from stdin and stores it's ASCII value in the current cell |
[♯ |
Jump past the matching ]♯ if the cell at the pointer is 0 |
]♯ |
Jump back to the matching [♯ if the cell at the pointer is nonzero |
*♯ |
multiply the cell under the pointer by the current mult/div value (default 2) |
/♯ |
sets the cell under the pointer to the result the integer division between it's value and the current mult/div value (default 2) |
(SIASL)² supports a number of instructions that are variations on the defaults
*♯
+♯
-♯
and /♯
instructions.
NB: /
related operations won't try to divide by zero. If they are
called in a context where they would have to calculate a division by zero they are
skipped.
Command | Description |
---|---|
>+ |
adds the value stored in the current cell to the one in the cell on the right and stores it in the current cell |
<+ |
adds the value stored in the current cell to the one in the cell on the left and stores it in the current cell |
v+ |
adds the value stored in the current cell to the one in the cell downwards and stores it in the current cell |
^+ |
adds the value stored in the current cell to the one in the cell upwards and stores it in the current cell |
>- |
substracts the value stored in the cell on the right from the one in the current cell and stores it in the current cell |
<- |
substracts the value stored in the cell on the left from the one in the current cell and stores it in the current cell |
v- |
substracts the value stored in the cell downwards from the one in the current cell and stores it in the current cell |
^- |
substracts the value stored in the cell upwards from the one in the current cell and stores it in the current cell |
>* |
multiplies the value stored in the current cell with the one stored in the cell on it's right and stores it in the current cell |
<* |
multiplies the value stored in the current cell with the one stored in the cell on it's left and stores it in the current cell |
v* |
multiplies the value stored in the current cell with the one stored in the cell downwards and stores it in the current cell |
^* |
multiplies the value stored in the current cell with the one stored in the cell upwards and stores it in the current cell |
>/ |
calculates the result of the integer division of the value stored in the current cell by the one stored in the cell on it's right and stores it in the current cell. |
</ |
calculates the result of the integer division of the value stored in the current cell by the one stored in the cell on it's left and stores it in the current cell. |
v/ |
calculates the result of the integer division of the value stored in the current cell by the one stored in the cell downwards and stores it in the current cell. |
^/ |
calculates the result of the integer division of the value stored in the current cell by the one stored in the cell upwards and stores it in the current cell. |
++ |
sums the value stored in the current cell with itself and stores it in the current cell (multiplies it by two) |
-- |
substracts the value stored in the current cell from itself and stores it in the current cell (sets it to zero) |
** |
multiplies the value stored in the current cell by itself and stores it in the current cell (sets it to it's square) |
// |
divides the value stored in the current cell with itself and stores it in the current cell (sets it to one) |
(SIASL)² supports a number of instructions that are variations on the defaults
[♯
and ♯]
instructions.
Command | Description |
---|---|
[+ |
at the beginning of each execution of the loop; increments the value of the current cell. |
+] |
at the end of each execution of the loop; increments the value of the current cell. |
[- |
at the beginning of each execution of the loop; decrements the value of the current cell. |
-] |
at the end of each execution of the loop; decrements the value of the current cell. |
[> |
at the beginning of each execution of the loop; moves the cell pointer to the right. |
>] |
at the end of each execution of the loop; moves the cell pointer to the right. |
[< |
at the beginning of each execution of the loop; moves the cell pointer to the left. |
<] |
at the end of each execution of the loop; moves the cell pointer to the left. |
[v |
at the beginning of each execution of the loop; moves the cell pointer downwards. |
v] |
at the end of each execution of the loop; moves the cell pointer downwards. |
[^ |
at the beginning of each execution of the loop; moves the cell pointer upwards. |
^] |
at the end of each execution of the loop; moves the cell pointer upwards. |
(SIASL)² supports a number of instructions that modify the effects of other instructions and/or the way the language behaves and can thus be seen as "meta instructions"
Command | Description |
---|---|
?> |
This instruction sets the flow of the execution of the
program from the right to the left.
The way this is implemented is that when given a program
the interpreter will execute the current instruction then the
"next" one until it reaches the end of the program.
ie: it will read the program from right to left and stop
at the end.
NB: this is the default behavior of (SIASL)² |
?< |
This instruction sets the flow of the execution of the
program from the left to the right.
The way this is implemented is that when given a program
the interpreter will execute the current instruction then the
"previous" one until it reaches the beginning of the program.
ie: it will read the program from left to right and stop
at the beginning. Also reverses the role of [* and *] so that open bracket
are seen as closing ones and vide-versa
NB: this can be used at the end of a program to execute it again "backwards" NB: in the interactive interpreter; the flow of execution is set to default after each line evaluated this is done to avoid problems with loops. |
?, |
this instruction read a character from stdin and sets the
value of the number used in the
*♯ and /♯
instructions to the ASCII value of the character read.
|
(♯ |
the (♯ combined with ♯) allows
to define behavior for unused symbols. The syntax to use them is :
(♯ [symbol] [symbols] ♯)
Once this expression has been evaluated [symbol] will be replaced by
[symbols] when evaluated
|
♯) |
the ♯) combined with ♯) allows
to define behavior for unused symbols. The syntax to use them is :
(♯ [symbol] [symbols] ♯)
Once this expression has been evaluated [symbol] will be replaced by
[symbols] when evaluated
|
(SIASL)² supports other instructions. They are regrouped in this category since they don't fit in any other one. These instructions are grouped into two families; the "print formatters" and the "movement" instructions.
Command | Description |
---|---|
.+ |
prints the value stored in the current cell as a signed decimal integer |
.- |
prints the value stored in the current cell as an hexadecimal integer |
.* |
prints the value stored in the current cell as an octal integer |
./ |
prints the value stored in the current cell as an unsigned integer |
.? |
prints the value stored in the current cell as a floating point number |
>> |
goes to the last cell of the current row |
<< |
goes to the first cell of the current row |
vv |
goes to the last cell of the matrix |
^^ |
goes to the first cell of the matrix |
(SIASL)² allows you to define behavior for every unused symbol/instruction
(a symbol/instruction being two (SIASL)² characters). Like regular instructions;
definable ones are commutative which means that
?+
is the same thing as +?
.
At the start of (SIASL)² none of the unused symbols has an effect.
To define them you can use (# and #).
The syntax for symbol definition is :
(# [unused symbol] [instructions that define new behavior of the unused symbol] #).
Once an expression of this form has been evaluated , [unused symbol] will be replaced
by the instructions after it when evaluating it.
I will not write all of them down but EVERY symbol that ISN'T documented is settable.
<?
instruction.
When flow of execution is reversed, redefinition statements are skipped.??
after this definition (♯?? ?? ♯)
it will cause a stack overflow.
The (SIASL)² interpreter supports normal bf-like symbols but also supports instructions passed as hexadecimal numbers. To use this lexic instead of the default one, use the -x option when starting the interpreter. However it's implementation is quite bad and it has worse performance than normal (SIASL)² lexic.
Symbol | Number |
---|---|
( |
0 |
♯ |
1 |
< |
2 |
> |
3 |
^ |
4 |
v |
5 |
+ |
6 |
- |
7 |
* |
8 |
/ |
9 |
, |
a and A |
. |
b and B |
[ |
c and C |
] |
d and D |
? |
e and E |
) |
f and F |