User:Orange/Super Stack!

From Esolang
Jump to navigation Jump to search

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.


123         push a number onto the stack.

  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

   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

  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

         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

  if        while loop.  if the top element is true, loop.  Does not pop top element.
  fi        end loop
  quit      end program

  debug     output entire stack (does not pop)


When entering a loop you should indent.


if there is only one instruction in the loop, you can shorten it like so

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


    if outputascii fi `output-stack
    10 outputascii

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.


0 1
    dup output
    dup cycle add

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

58 101 100 111 67 32
115 115 97 80 32
114 101 116 110 69
if outputascii fi pop


`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
	100 101 116 110 97 114 71 32
	115 115 101 99 99 65
	if outputascii fi pop
fi fi fi fi fi

71 78 79 82 87
if outputascii fi pop

a little game. guess what the password is.


The stupid fizzbuzz problem

    dup 101 add
    dup output
    dup 3 mod
    not if
        0 122 122 105 102 `fizz
        if outputascii fi pop
    fi pop
    dup 5 mod
    not if
        0 122 122 117 98 `buzz
        if outputascii fi pop
    fi pop
    10 outputascii `newline
    1 add


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:
    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




    0 cycle

, (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
    1 add


    1 sub
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
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


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

end then use them like:

0 100 108 114 111 87 32
111 108 108 101 72

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

    dup dup dup output output output

This would make a macro that would act like a regular non looping if statement. Orange 18:59, 11 August 2009 (UTC)