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.
dS: Multiply the top of the two stacks and stores the result in the register. 	
reg = A.top() + B.top();
reg = A.top() * B.top();	
dt dT 	Subtract 	Subtract the top of the second stack to the first and stores the result in the register. 	
reg = A.top() - B.top();	
da dA 	Power 	Raises the top of the first stack to the power of the second and stores the result in the register. 	
reg = pow(A.top(), B.top());	
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. 	
if (B.top() != 0)
: reg = A.top() / B.top();
else
: exit(0);	
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.	
if (B.top() != 0)
: reg = A.top() % B.top();
else
: exit(0);	
sd sD 	Zero 	Sets the register value to zero. 	
reg = 0; 	
st sT 	Equal/Unequal 	st: If the top of both stacks are equal put a one in the register, else put a zero.
sT: If the top of both stacks are different put a one in the register, else put a zero. 	
reg = A.top() == B.top();
reg = A.top() != B.top();	
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.
sA: If the register is between the two tops of stacks (exclusive) 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. 	
reg = A.top() > B.top();	
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. 	
reg = A.top() >= B.top();	
td tD 	Not 	If the top of the first stack is zero put a one in the register, else put a zero. 	
reg = !A.top(); 	
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.
tS: If the top of both stacks is nonzero put a one in the register, else put a zero. 	
reg = A.top() 	B.top();
reg = A.top() && B.top();
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. 	
reg = A.top(); 	
tk tK 	Min/Max 	tk: Compares the top of both stacks and put the lowest in the register.
tK: Compares the top of both stacks and put the largest in the register. 	
reg = min(A.top(), B.top());
reg = max(A.top(), B.top());	
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. 	
B.push(A.top());
A.pop();
if (A.empty())
: A.push(0);	
cs cS 	Pop 	Removes the top of the first stack, if it runs out of numbers, a zero is pushed. 	
A.pop();
if (A.empty())
: A.push(0);	
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). 	
if (B.top() >= A.top())
: reg = rand() % (B.top() - A.top() + 1) + A.top();	
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).
cK: Displays the number of the register. 	
cout << (char)(reg % 256);
cout << reg;	
kd kD 	None 	Does nothing (Nop). 	 	
ks kS 	Save 	Push in the first stack the value of cursor + 1. 	
A.push(cur + 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. 	
if (reg != 0)
: cur = A.top();	
ka kA 	Reset/Halt 	ka: If the register is nonzero, restarts the program.
kA: If the register is nonzero, halt 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.
kC: Read an integer from the keyboard and put it on the register. If it can not parse as a number then keep waiting for one.	
char ch;
cin.get(ch);
reg = ch;
// Without check for simplicity
cin >> reg;	
dd dD
ss sS
tt tT
cc cC
kk kK	Push 	Push the value of register in the first stack. 	
A.push(reg); 	
?0 	Digit 	? represents any valid character. 0 represents any digit.
Multiplies by 10 the register value and adds the digit. 	
reg = reg * 10 + 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 [)
== Implementation ==
C++ Implementation in GitHub
Online interpreter
Category:Languages
Category:Stack-based
Category:Turing complete
Category:Implemented
Category:2015