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.

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)