(top, height)

From Esolang
Jump to navigation Jump to search

(top, height) is a two-dimensional language where the pointer's x-coordinate is based on the value at the top of the stack, while the y-coordinate is based on the height of the stack.

Instructions

The program starts with a stack only containing the value 0. This means the program always starts at (0,0).

Command Description
Version 0.1.0
0-9 Push the number onto the stack.
A-Z,a-z Push the ASCII value of the character onto stack.
+ Pop two values A and B, then push the result of A+B.
- Pop two values A and B, then push the result of A-B.
* Pop two values A and B, then push the result of A*B.
/

Pop two values A and B, and check if B equals the number 0.
If so, end the program.
Else, push the result of A/B.

%

Pop two values A and B, and check if B equals the number 0.
If so, end the program.
Else, push the remainder of A/B.

> Pop two values A and B, then push whichever one is greater.
< Pop two values A and B, then push whichever one is smaller.
: Duplicate top of stack.
\ Swap top stack values.
$ Pop top of stack and discard.
. Pop top of stack and output as integer.
, Pop top of stack, modulo 256, and output as ASCII character.
~

Get input from user.
If it is numeric, push the corresponding number onto the stack.
Else, push the ASCII value of the corresponding character.

Anything else End program.
Version 1.0
! Push the ASCII value of the character onto the stack.
^

Pop top two values A and B.
Save the value C with A values between it and the top of the stack.
If there are fewer than A values in the stack, C is the bottom-most value of the stack.
Insert B in the spot where C is.
Push C to the top of the stack.

Every time an action is performed, the pointer's x-coordinate is reset to the absolute value of the value on top of the stack, and the y-coordinate is reset to the height of the stack - 1.

Any operation which uses two values, such as + or -, will end the program if the x-coordinate is less than 0 (meaning the stack height is one).

The program will also end if the stack height is equal to 0.

Tips

  • The duplicate command acts like pushing a pointer one space down.

Code Examples

Truth Machine

~
2:
..\

Hello, World!

=Version 0.1.0

This prints Hello, World! The space is written by multiplying 8 and 4, while the comma is written by taking the ASCII value of X, dividing it by 2, and taking the absolute value of subtracting that from 1. Finally, the exclamation mark is made by subtracting 1 from the ASCII value of A, then subtracting that from the ASCII value of a.

H
 e lloX8W orldA                                                         1
 \++++++4+++++                  1                                1      ,              21           12      1  1  1
 \\ *                           ,,          ,                   a1                     ,2           ,,      ,  ,  ,
 \\                                                              -                      /        -

Complexity

I am very sure that Version 0.1.0, at least, is not Turing-complete. This is because the stack cannot have arbitrary elements, as only the elements near the front can be accessed and elements cannot be put anywhere else. Therefore, I assume this is a push-down automaton.

Because Version 1.0 can access arbitrary elements through the ^ command, I believe it is Turing-complete.

Please correct me if you feel this is wrong.

Implementations

There are going to be multiple versions of the language as I add new features. I did this so that people know what aspects of the language are included by any given interpreter.

Version 0.1.0

This is a Python 3 implementation of Version 0.1.0 of this language.

def run_top_height(code_string: str, text_file = False) -> None:
    stack = [0]
    code = []

    if text_file:
        with open(code_string, 'r') as file:
            # The newlines don't affect the outcome
            code = file.readlines()
    else:
        code = code_string.split('\n')

    while len(stack) > 0:

        # The pointer's next position is always x_coord, y_coord.
        x_coord = abs(stack[-1])
        y_coord = len(stack)-1

        if y_coord < len(code) and x_coord < len(code[y_coord]):
            instruction = code[y_coord][x_coord]

            # appends digits
            if instruction.isdigit():
                stack.append(int(instruction))

            # appends the ASCII values of letters
            elif instruction.isalpha():
                stack.append(ord(instruction))

            # move down one space
            elif ':' == instruction:
                stack.append(stack[-1])

            # arithmetic instructions
            elif instruction in {'+', '-', '*', '<', '>', '\\', '/', '%'}:
                if y_coord > 0:
                    a = stack.pop()
                    b = stack.pop()
                    if '+' == instruction:
                        stack.append(a+b)
                    elif '-' == instruction:
                        stack.append(a-b)
                    elif '*' == instruction:
                        stack.append(a*b)
                    elif '>' == instruction:
                        stack.append(max({a,b}))
                    elif '<' == instruction:
                        stack.append(min(a,b))
                    elif '\\' == instruction:
                        stack.append(a)
                        stack.append(b)
                    else:
                        if b == 0:
                            break
                        elif '/' == instruction:
                            stack.append(a//b)
                        else:
                            stack.append(a%b)
                else:
                    break

            # popping instructions
            elif instruction in {'$', '.', ','}:
                new = stack.pop()
                if '.' == instruction:
                    print(new,end='')
                elif ',' == instruction:
                    print(chr(abs(new)),end='')

            elif '~' == instruction:
                new = input()[0]
                if new.isdigit():
                    stack.append(int(new))
                else:
                    stack.append(ord(new))
            else:
                break
        else:
            break

Version 1.0

def run_top_height_1_0(code_string: str, text_file = True) -> None:
    stack = [0]
    code = []

    if text_file:
        with open(code_string, 'r') as file:
            # The newlines don't affect the outcome
            code = file.readlines()
    else:
        code = code_string.split('\n')

    while len(stack) > 0:

        # The pointer's next position is always x_coord, y_coord.
        x_coord = abs(stack[-1])
        y_coord = len(stack)-1

        if y_coord < len(code) and x_coord < len(code[y_coord]):
            instruction = code[y_coord][x_coord]

            # appends digits
            if instruction.isdigit():
                stack.append(int(instruction))

            # appends the ASCII values of letters
            elif instruction.isalpha() or '!' == instruction:
                stack.append(ord(instruction))

            # move down one space
            elif ':' == instruction:
                stack.append(stack[-1])

            # arithmetic instructions
            elif instruction in {'+', '-', '*', '<', '>', '\\', '/', '%', '^'}:
                if y_coord > 0:
                    a = stack.pop()
                    b = stack.pop()
                    if '+' == instruction:
                        stack.append(a+b)
                    elif '-' == instruction:
                        stack.append(a-b)
                    elif '*' == instruction:
                        stack.append(a*b)
                    elif '>' == instruction:
                        stack.append(max({a,b}))
                    elif '<' == instruction:
                        stack.append(min(a,b))
                    elif '\\' == instruction:
                        stack.append(a)
                        stack.append(b)
                    elif '^' == instruction:
                        c = stack[-1*(a+1)]
                        stack[-1*(a+1)] = b
                        stack.append(c)
                    else:
                        if b == 0:
                            break
                        elif '/' == instruction:
                            stack.append(a//b)
                        else:
                            stack.append(a%b)
                else:
                    break

            # popping instructions
            elif instruction in {'$', '.', ','}:
                new = stack.pop()
                if '.' == instruction:
                    print(new,end='')
                elif ',' == instruction:
                    print(chr(abs(new)),end='')

            elif '~' == instruction:
                new = input()[0]
                if new.isdigit():
                    stack.append(int(new))
                else:
                    stack.append(ord(new))
            else:
                break
        else:
            break