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)