ButWhy

From Esolang
Jump to navigation Jump to search

ButWhy is an esoteric language created by User:Rehydratedmango, designed to cause programmers to repeat the language's name as many times as possible while using it. Commands in ButWhy are represented in binary, encoded in base-64. Each base-64 character is placed on a grid, and the program starts reading characters from the top left. The / and \ characters divert program execution like mirrors. Once 4 bits of information have been read, the corresponding command is executed. The ? character will skip over the following character if the stack has a 0 on top. An example of program flow:

####\
    #
/###/
#
\####

The program follows the S shape, reading each character (represented by the #s).

Commands

Command (binary) Description
0000 Push a 1 bit onto the stack, unless it is a Monday and the program doesn't feel like it.
0001 Pop the top bit off of the stack and ethically recycle it.
0010 Nor the top two bits on the stack.
0011 Duplicate the top bit on the stack and provide therapy to the bits with identity crises.
0100 Remove the bottom bit from the stack and push it on top. Print "Jenga" if the stack falls over.
0101 If the top bit on the stack is a 1, pop it and rewind the program to the previous 0101 command, continue from there.
0110 Rip bits off of the stack like an angry toddler until there is a 0 bit on top.
0111 Push the program off a cliff, shattering the source code into bits.
1000 Rudely mug the user for an input in binary, which is pushed onto the stack one bit at a time starting from the righthand side.
1001 Pop the top 8 bits off the stack and output them as an ASCII character.
1010 Pop the top bit off the stack and output it, unless it is the 17th bit on the stack, because they had a falling out with the program.
1011 Tell a joke. That's... that's it.

Computational class

User:PkmnQ has proven that the subset of just the commands 0000 (push 1), 0001 (pop), 0010 (nor), 0011 (dup), 0100 (rotate/cycle), 0110 (teardown) is Turing complete, providing this compiler:

productions = (False, True, True), (True, False), (True, False, True)
initial = (True,)

c = "dup nor dup dup dup nor dup dup nor teardown nor nor", "dup dup dup nor teardown pop"
first_production = True
for production in productions:
    if first_production:
        first_bit = True
        for bit in initial:
            print("1 cycle" if first_bit else c[0])
            print(c[bit])
            first_bit = False
        print("dup dup nor teardown pop pop")
    else:
        print("cycle pop")
    print("cycle")
    for bit in production:
        print(c[0])
        print(c[bit])
    print("pop")
    first_production = False

The main part of the construction is dup nor dup dup dup nor dup dup nor teardown nor nor and dup dup dup nor teardown pop, which each conditionally (i.e. only if the top element of the stack is 1) insert a bit below the top element of the stack. abc... in the cyclic tag datastring corresponds to 0a0b0c... on the stack.

Programs generated by this compiler must be assembled into the bitwise form, then organized into a full-program loop. This could be done by chopping the resulting bitcode in half, reversing the latter half, and putting it in the following form:

/first half \
\flah dnoces/

Interpreter

No