DStack
DStack is a stack-based esoteric language created by User:-Dark-Phantom- on November, 2015. The language uses two stacks, a cursor and a register, the four begin with the value zero. It has only one data type: unsigned integers of at least 8 bits. The cursor marks the position in the code of the instruction to be executed. There is also a dictionary which maps numbers to string literals.
Syntax
The only valid characters are:
dstackDSTACK0123456789/@
The program is illegal if it contains an invalid character that is not inside a comment or string literal, is not a new line (\n), a space nor a tab (\t).
Note: the @
symbol can only be used at the beginning of the line (see section String Literals).
The code is read in pairs, but only moves the cursor one character at a time. For example, in the code
0kckt
The instructions are: 0k, kc, ck, kt.
Instructions
The first letter of the pair can be uppercase or lowercase. If the second letter is capitalized then swaps the use of stacks in the operation (or do a different operation if indicated).
Character pair | Instruction name | Description | Equivalent in C++ |
---|---|---|---|
ds dS |
Add/Multiply | ds : Add the top of the two stacks and stores the result in the register.
|
|
dt dT |
Subtract | Subtract the top of the second stack to the first and stores the result in the register. |
|
da dA |
Power | Raises the top of the first stack to the power of the second and stores the result in the register. |
|
dc dC |
Divide | Divide the top of the first stack by the second and stores the result in the register. If the top of the second stack is zero, the program terminates with an error. |
|
dk dK |
Remainder | Calculates the remainder of the division of the top of the first stack by the second and stores the result in the register. If the top of the second stack is zero, the program terminates with an error. |
|
sd sD |
Zero | Sets the register value to zero. |
|
st sT |
Equal/Unequal | st : If the top of both stacks are equal put a one in the register, else put a zero.
|
|
sa sA |
Between Inclusive/Between Exclusive | sa : If the register is between the two tops of stacks (inclusive) replace the register with one, else with zero.
|
|
sc sC |
Greater | If the top of the first stack is greater than the second put a one in the register, else put a zero. |
|
sk sK |
Equal or Greater | If the top of the first stack is equal or greater than the second put a one in the register, else put a zero. |
|
td tD |
Not | If the top of the first stack is zero put a one in the register, else put a zero. |
|
ts tS |
Or/And | ts : If the top of at least one stack is nonzero put a one in the register, else put a zero.
|
|
ta tA |
Xor | If only the top of a stack is zero put a one in the register, else put a zero. | |
tc tC |
Peek | Copies the top of the first stack in the register. |
|
tk tK |
Min/Max | tk : Compares the top of both stacks and put the lowest in the register.
|
|
ad aD |
Print String | If there is a string literal with the number indicated by the register, print the string. | |
as aS |
Print String Interpolated with Numbers | If there is a string literal with the number indicated by the register, prints the string replacing the characters # and $ by the top of the first and second stack in form of numbers, respectively. |
|
at aT |
Print String Interpolated with Characters | If there is a string literal with the number indicated by the register, prints the string replacing the characters # and $ by the top of the first and second stack in form of characters, respectively. |
|
ac aC |
Push String | If there is a string literal with the number indicated by the register, push each character of the string in the first stack. | |
ak aK |
Push Reversed String | If there is a string literal with the number indicated by the register, push each character of the string in the first stack, starting from the end. | |
cd cD |
Send | Removes the top of the first stack and push it in the second. If the first stack runs out of numbers, a zero is pushed. |
|
cs cS |
Pop | Removes the top of the first stack, if it runs out of numbers, a zero is pushed. |
|
ct cT |
Random | If the top of the second stack is equal or greater than the first, put a random number on the register from the range of the above (inclusive). |
|
ca cA |
Swap | Swap the tops of the stacks. | |
ck cK |
Print Character/Print Number | ck : Displays the ASCII character corresponding to the register number (if it is greater than 255 the remainder of dividing by 256 is used).
|
|
kd kD |
None | Does nothing (Nop). |
|
ks kS |
Save | Push in the first stack the value of cursor + 1. |
|
kt kT |
Jump | If the value in register is non-zero, move the cursor to the position indicated by the top of the first stack. After this command, the cursor does not automatically advance. |
|
ka kA |
Reset/Halt | ka : If the register is nonzero, restarts the program.
|
|
kc kC |
Read Character/Read Number | kc : Reads a character from the keyboard and put it on the register. If several characters are entered, they remain in the buffer and will be available for the next time. The newline character will also be read. EOF = 0.
|
|
dd dD
|
Push | Push the value of register in the first stack. |
|
?0 |
Digit | ? represents any valid character. 0 represents any digit.
Multiplies by 10 the register value and adds the digit. |
|
0x |
None | 0 represents any digit. x represents any valid letter.
Does nothing (Nop). |
|
Pre-Parse
Before the program is interpreted, string literals, comments, new lines, tabs and spaces are removed. The positions of the instructions and the cursor are calculated after this step.
String Literals
The string literals are declared starting the line with @
. Then you can put a number identifying the string and finally a new line character. All the lines that continue, will become part of the string, until it finds a @
, alone at the beginning of a line.
Note: If there is a string with the same number, then it is concatenated to the end without any separator.
Example:
@123 This string is identified by the number 123. It contains two lines and even the @ character. @
Comments
Comments begin with / and finish at the end of the line. They can contain any characters.
There may be comments from multiple lines using a string literal without identification number.
Execution
Each time an instruction is executed the cursor position is advanced (except for kt
and kT
). If the cursor is at the last character or ahead, the program terminates (Can get those positions advancing or jumping with the Jump instruction).
Examples
Hello, World!
@0 Hello, world! @ ad
Cat
0kckt
Truth-machine
04KKCKT
Factorial
01kkKCccsd25DDkTsCK999kktCSdttsd25dDkTtcsd1DDcdCSdSScsd47DDkTcStCK
Infinite Loop
skt
Collatz sequence
kCc0sd2ccCCSCstcKdkkdsd44tTkTcscSdcccsd65kktcscSd3DDSsd1DDssstcScScsd1DDKkdcSd10ckKdtkT1cK
99 bottles of beer
@0 # bottles of beer on the wall, # bottles of beer. Take one down and pass it around, $ bottles of beer on the wall. @ @1 1 bottle of beer on the wall, 1 bottle of beer. Take one down and pass it around, no more bottles of beer on the wall. No more bottles of beer on the wall, no more bottles of beer. Go to the store and buy some more, 99 bottles of beer on the wall. @ 01SSd99CCcscDtTasd9ttkt
Is prime (golfed)
025SSd01kKCccscS0kT0cK1kAsd34SSd1ccd0sd1ddsScsdk0cD0cS0kTcdsKkdtcK
Quine
@100 010SSd64cckdtC0CKdtCk0adtCkdtckdtCk0ad @ 010SSd64cckdtC0CKdtCk0adtCkdtckdtCk0ad
Computational class
DStack is turing complete, as it is possible to translate any brainfuck code to it, using the following table:
Brainfuck | DStack |
---|---|
>
|
0cD
|
<
|
0cd
|
+
|
0sd1ddsstcSScscs
|
-
|
0sd1ddTtcSScscs
|
.
|
0tCk
|
,
|
0cSkcC
|
[
|
0sd#ttAktcs (You have to replace the # with the location of the instruction cs in the matching ] )
|
]
|
0sd#ttC0ktcs (You have to replace the # with the location of the instruction cs in the matching [ )
|