New

From Esolang
Jump to navigation Jump to search

New is an esoteric programming language created by User:Squidmanescape based on a scrapped language created by User:Infinitehexagon with the same name.

It has an infinite amount of accumulators that are treated like Brainfuck's cells but unbounded.

Instructions

Command Description
I Increment the accumulator by 1.
~ Decrement the accumulator by 1.
O Output the accumulator as a Unicode character corresponding to the number modulo 1114112
! Add the value in the next accumulator to the current one.
* Move the pointer right.
% Move the pointer left.
( if the value in the accumulator is 0, go forwards past the corresponding )
) if the value in the accumulator is not 0, go backwards to the corresponding (

Turing-Completeness

It is Turing-complete because 6 of its commands directly correspond to the 6 Turing-complete Brainfuck commands.

Brainfuck     New
   +           I
   -           ~
   <           %
   >           *
   [           (
   ]           )

Implementation

def run_new(rawcode: str, textfile=False) -> None:
    pointer = 0  # for instructions
    location = 0  # for tape
    tape = [0]

    if textfile:
        with open(rawcode, 'r') as s:
            code = [char for char in ''.join(s.readlines()) if char in set('I~O!*%()')]
    else:
        code = [char for char in rawcode if char in set('I~O!*%()')]

    corresponding_bracket = {}  # dictionary where the values are the corresponding bracket positions of the keys
    bracket_stack = []  # acts as a stack for the last bracket

    for num, char in enumerate(code):
        if char == '(':
            bracket_stack.append(num)
        elif char == ')':
            if len(bracket_stack) <= 0:
                raise ValueError('unmatched ]')
            corresponding_bracket[num] = bracket_stack[-1]
            corresponding_bracket[bracket_stack[-1]] = num
            bracket_stack.pop()
    if len(bracket_stack) != 0:
        raise ValueError('unmatched [')

    while pointer < len(code):
        if code[pointer] == 'I':
            tape[location] += 1
        elif code[pointer] == '~':
            tape[location] -= 1
        elif code[pointer] == 'O':
            print(chr(tape[location] % 1114112), end='')
        elif code[pointer] == '!':
            if location == len(tape) - 1:
                raise KeyError("There is no next cell for ! to add from.")
            tape[location] += tape[location+1]
        elif code[pointer] == '*':
            location += 1
            if location == len(tape):
                tape.append(0)
        elif code[pointer] == '%':
            if location == 0:
                tape = [0] + tape
            else:
                location -= 1
        elif code[pointer] == '(':
            if tape[location] == 0:
                pointer = corresponding_bracket[pointer]
        elif code[pointer] == ')':
            if tape[location] != 0:
                pointer = corresponding_bracket[pointer]
        pointer += 1