User:Orange/Super Stack!
Super Stack! is a work in progress stack based esoteric programming language by User:Orange. Anything including the name may be changed in the future.
Super Stack! has only one stack that is manipulated by keywords.
Instructions
123 push a number onto the stack. Math: add pop the top two numbers from the stack, add them, and push the result sub pop the top two numbers from the stack, subtract the first from the second, and push the result mul pop the top two numbers from the stack, multiply them, and push the result div pop the top two numbers from the stack, divide the first from the second, and push the result mod pop the top two numbers from the stack, preform modulus on the first and second, and push the result Logic: note:For logic, 0 is false, and anything else is true (negative or positive) when pushing results 1 is true and 0 is false and pop the top two numbers from the stack, and them, and push the result or pop the top two numbers from the stack, or them, and push the result xor pop the top two numbers from the stack, xor them, and push the result nand pop the top two numbers from the stack, nand them, and push the result not pop the top number from the stack, not it, and push the result I/O: output pop the top element and output it as a number input get a single number from input and push it outputascii pop the top element and output as an ascii character inputascii get a string of characters from input and push each ascii character on the stack backwards Example: input is 'Hello' it gets pushed on the stack like this: 72 H 101 e 108 l 108 l 111 o so when you pop the top element you get the first letter inputted. Stack Manipulation: pop pop the top number swap swap the top two elements cycle put the top element on the bottom of the stack rcycle put the bottom element on the top of the stack dup duplicate the top element rev reverse the entire stack Flow: if while loop. if the top element is true, loop. Does not pop top element. fi end loop quit end program Misc: debug output entire stack (does not pop)
Style
When entering a loop you should indent.
0 inputascii if dup output outputascii fi
if there is only one instruction in the loop, you can shorten it like so
0 inputascii if outputascii fi
There is no comment character or commend, but any word that isn't a keyword is ignored So when writing comments, start them with ` and use - instead of spaces
1 `push-one-onto-stack
Of course completely optional, this style helps distinguish comments from code and from accidentally using keywords.
Example Programs
Cat
1 if 0 inputascii if outputascii fi `output-stack pop 10 outputascii fi
Explanation:
1 is pushed and then a while loop is entered. the 1 makes the loop run forever.
0 is pushed so we can tell when input ends.
input is pushed onto stack
while the top element is not 0, pop and output element
pop the 0
push 10 and output it(new line)
the stack now only has the number 1 on it, so the program will loop again.
as you can see keywords can be separated by spaces or newlines.
Fibonacci
0 1 if dup output dup cycle add fi
push 0 and 1 on the stack to start the fib
if for an infinite loop
output the top of stack
dup top number the put it on the back of the stack
add the top two
loop. Top of the stack will always be more then 0
Guess the pass code
0 58 101 100 111 67 32 115 115 97 80 32 114 101 116 110 69 if outputascii fi pop inputascii `compare each letter 109 sub not if pop 97 sub not if pop 114 sub not if pop 115 sub not if pop 104 sub not if pop 0 100 101 116 110 97 114 71 32 115 115 101 99 99 65 if outputascii fi pop quit fi fi fi fi fi `wrong 0 71 78 79 82 87 if outputascii fi pop
a little game. guess what the password is.
FizzBuzz
The stupid fizzbuzz problem
-100 if dup 101 add dup output dup 3 mod not if pop 0 122 122 105 102 `fizz if outputascii fi pop 0 fi pop dup 5 mod not if pop 0 122 122 117 98 `buzz if outputascii fi pop 0 fi pop 10 outputascii `newline pop 1 add fi inputascii
Simple chat bot
(requires 2.0)
1 if pop 0 58 116 117 112 110 105 if outputascii fi pop inputascii 0 5 random if pop cycle if cycle fi 0 fi pop 0 58 116 117 112 116 117 111 if outputascii fi pop cycle if dup outputascii cycle fi 10 outputascii 1 fi
First the program gets a string inputted onto the stack. Strings are represented by a 0 and then a series of characters that lead up to the next string.
After the input, we randomly cycle from string to string.
Then, we output the string and loop the program.
Turing Complete Theory
Ah, the classic question. Super Stack! may be Turing complete by polymorphism with brainfuck.
Brainfuck programs can be converted into Super Stack programs as so:
BF Super Stack! instruction(s) > rcycle < cycle + 1 add - 1 sub . dup output , pop input [ if ] fi
Tape is simulated by cycling through the stack.
Memory must be allocated by pushing 0's onto the stack. You must be careful because if you don't have enough memory allocated, < and > will warp around the memory space and may mess up the converted brainfuck program.
The converter must be able to count the number of < and > to predict how much memory the program will use and add as many 0's as needed.
Here is a brainfuck program I have converted into super stack! as a proof of concept
Brainfuck program(Hello world):
>+++++++++[<++++++++>-]<.>+++++++[<++++>-]<+.+++++++..+++.>>>++++++++[<++++>-] <.>>>++++++++++[<+++++++++>-]<---.<<<<.+++.------.--------.>>+.
Then I hacked together a python program to convert it, something like
text = """ >+++++++++[<++++++++>-]<.>+++++++[<++++>-]<+.+++++++..+++.>>>++++++++[<++++>-] <.>>>++++++++++[<+++++++++>-]<---.<<<<.+++.------.--------.>>+. """ memspace = 0 brace = 0 for c in text: if c=='>': brace += 1 if memspace<brace: memspace+=1 if c=='<': brace -= 1 text = text.replace('>','rcycle ') text = text.replace('<','cycle ') text = text.replace('+','1 add ') text = text.replace('-','1 sub ') text = text.replace('.','dup outputascii ') text = text.replace(',','pop inputascii ') text = text.replace('[','if ') text = text.replace(']','fi ') print'0 '*memspace #memory allocation print text
The program runs and outputs Hello World!, as long as the converter allocates enough memory(the hello world program requires at least 5 cells to run). The converter is very basic, it allocates memory and does a find/replace for the instructions.
I'm guessing some brainfuck programs will easily break this, such as
+[>+]
because enough memory would not get allocated.
Despite this, a converter could be made to make programs that simulate a brainfuck environment with a wrap around cell space.
A solution to the allocation problem would be for the converter to add more memory on the fly in the program.(still thinking about how to accomplish this)
A brainfuck translation
This language definitely seems TC. Here's one way brainfuck can be translated to it. I don't have an interpreter so I haven't tested any of it, so there's a chance it doesn't work properly. But it just might. It may not be the shortest or clearest way, either... I'm not fully aware how indenting works in this language, so translating brainfuck to this might require these code blocks to receive some additional spaces in front them, depending on how many nested loops there are at the given moment.
In this model the brainfuck memory array is split into two. Each cell, while in memory, is by its value one higher than it really is -- this trick is used to separate the split arrays, to mark the right-most end of it. Essentially, if you have memory state (in brainfuck) like
b b aX d e f
where X marks the currently chosen cell, it would appear in the Super Stack! memory something like this
d e f 0 b b aX
The top of the stack is on the right -- the currently chosen value is the top-most, its left cells below it, and 0 separates it from the other side.
First. This line must be added to the beginning of every program:
0 1
It creates the array and makes the first cell (which is zero, as every previously unaccessed cell in brainfuck, represented by '1' here).
Then, if this system works, it should be the matter of using these (and adding the needed spaces):
+
1 add
-
1 sub
<
cycle
>
rcycle dub not if 0 cycle swap fi pop
, (requires one-character input strings to work properly, didn't bother thinking about it too much, it's not necessary anyway)
pop inputascii
.
dub outputascii
[
1 sub if 1 add
]
1 sub fi 1 add
--Keymaker 11:43, 4 August 2009 (UTC)
Nice :) Figured there was some way to do this.
I think for the string input problem you can do something like this to grab the first letter of the input.
pop 0 inputascii `push-string-onto-stack swap `swap-top-elements-to-save-first-letter if `if-not-0 pop swap `pop-top-then-swap-first-letter-again fi pop `pop-0-leaving-first-letter
As for syntax stuff, indentation is optional, as long as there is a space, new line, or tab between keywords.
0 1 2 3 2 2 add if output fi
is the same as
0 1 2 3 2 2 add if output fi
I just like indenting because it makes it more readable and easy to understand.
I've also uploaded v1 of the interpreter here.
Orange 16:10, 4 August 2009 (UTC)
Possible Future Features
The macro feature. This will allow you to define your own keywords like so:
macro printstring if outputascii fi pop endmacro
end then use them like:
0 100 108 114 111 87 32 111 108 108 101 72 printstring
using printstring will run the code defined in the macro. Macros can be used in other macros, so you can build up and reuse code.
I was also thinking of a way to more easily hardcore characters into programs, maybe with prefixing a single letter with " , but this might take away from the beauty of not using anything but letters and numbers.
Orange 02:02, 10 August 2009 (UTC)
With macros you could even make your own flow structures
macro onceif dup if pop endmacro macro endif 0 fi pop endmacro input onceif dup dup dup output output output endif
This would make a macro that would act like a regular non looping if statement. Orange 18:59, 11 August 2009 (UTC)