We are currently working on new rules for what content should and shouldn't be allowed on this website, and are looking for feedback! See Esolang:2026 topicality proposal to view and give feedback on the current draft.

AuroraCode

From Esolang
Jump to navigation Jump to search

AuroraCode is an esoteric programming language developed by User:GozzieGoober. The language’s main use is math but it can be used for more complicated programs. There is also a fully functional interpreter for AuroraCode made in Python. AuroraCode also completely ignores spaces and letters so you can organize lines of code better.


How to use AuroraCode

The main purpose of AuroraCode is math related programs, however, more complicated things are possible. The strange syntax is only necessary for the ease of the interpreter knowing where things start and end. Every line will output the accumulator at the end.

Initializing

To start a line of code in AuroraCode, start with a “&” symbol, and after that, type whatever you want the accumulator to start as, then type a “!” The following code will set the accumulator to 1 and output 1.

&1!

Adding and Subtracting

Adding and subtracting are the most simple operations in AuroraCode, simply typing a “+” or “-” anywhere after the first “!” will increase or decrease the accumulator. The following code will increase by one and output 2.

&1!+

This next code will output 0.

&1!-

You can add as many of these as needed. This code will output 11.

&10!+++-+-----+++-+-++--++-

Variables

To create a variable, use “=name:val:” and replace name and val with the variable’s name and its value respectively. “?name:” will print the value of that variable. This code will create a variable with value 2 and print its value.

&0! =myVar:2: ?myVar:

Variables persist across lines and there is no limit to how many you can make.

Multiplying and Dividing

Multiplying and Dividing is the main use for variables. To multiply or divide the accumulator by a number, first create a variable of that number.

&2! =myVar:4:

Then, use “*name:” to multiply and “/name:” to divide. This next example will multiply the accumulator (2) by myVar (4) and output 8.

&2! =myVar:4: *myVar:

To do the same thing but divide, use a “/” instead of a “*”.

&4! =myVar:2: /myVar:

Loops

Variables can also be used for loops. There are two types of loops in AuroraCode, simple loops that repeat a set number of times and while loops which will repeat until the accumulator meets a requirement. A loop can either use a number or variable for it. A simple loop that will increase by one 5 times and output 7:

&2!$(+)5:

A while loop that will increase by one until it reaches 7 and output 7:

&2!%(+)/<7:

Comparing

To execute operations conditionally based on a comparison, use “[subject op value:true_ops|false_ops]”. The subject can be either a variable name or / to check the current accumulator value. The op can be >, <, or =. If the condition is met, true_ops will run; otherwise, false_ops will run. An example that checks if the accumulator is greater than 5 and subtracts 1 if true, or adds 1 if false:

&10! [/>5:-|+]

An example that checks if a variable myVar equals 3:

&0! =myVar:3: [myVar=3:+|-]

Miscellaneous

There are a few features of AuroraCode that don’t fall into the above categories. Typing “@” in a line of code will print the accumulator’s current value mid line. “#” will print the accumulator’s value as a1 z26 cipher. Typing vars without anything else will print all of the current variables and quit will stop the program entirely.

Examples

Decrementing Loop

This code starts at five, prints, and loops decreasing and printing its value, creating a countdown.

&5!@$(-@)5!

Infinite Loop

This code will continue looping as long as the accumulator is above 0. Since it starts as 1, it will go on indefinitely. This will trigger the interpreter’s protection from infinite loops to prevent it from crashing.

&1!%(+)/>0:

Multiplying Loop

This code will multiply by mult until its above target, then subtract by one, outputting 17.

&2!=mult:3:=target:15:*mult:*mult:[/>target:-|+]!

Comments

Since AuroraCode ignores spaces and letters in lines of code, you can organize the parts of your code with what are essentially comments. This code will run perfectly fine. However this can affect variables and syntax so make sure you be careful with this.

&1!     Creating variable    =myVar:2:     Printing variable    ?myVar:

Printing “hello”

Because of the “#” operation, you can print letters with the A1 Z26 cipher. The following code will print “hello” &8!#---#+++++++##+++#!

The Interpreter

variables = {}

def print_help():
    print("""
╔══════════════════════════════════════════════════════╗
║              Welcome to AuroraCode!                  ║
╠══════════════════════════════════════════════════════╣
║  An esoteric programming language made just for fun. ║
╠══════════════════════════════════════════════════════╣
║  SYNTAX:                                             ║
║   &<number>!<operations>!                            ║
║                                                      ║
║  OPERATIONS:                                         ║
║   +           increment by 1                         ║
║   -           decrement by 1                         ║
║   =name:val:  create variable                        ║
║   *name:      multiply accumulator by variable       ║
║   /name:      divide accumulator by variable         ║
║   ?name:      print a variable's value               ║
║   @           print current accumulator value        ║
║   $(ops)n:    repeat ops n times (n = num or var)    ║
║   #           print accumulator as letter (a=1 z=26) ║
║   %(ops)/>n:   while accumulator > n run ops         ║
║   [/>n:ops|ops]  if accumulator > n (also < and =)   ║
║   [var>n:ops|ops] if variable > n (also < and =)     ║
║                                                      ║
║  TIPS:                                               ║
║   - Variables persist across lines                   ║
║   - Type 'vars' to see all variables                 ║
║   - Type 'quit' to exit                              ║
╚══════════════════════════════════════════════════════╝
""")

def decode(code2, intOutput):
    i = 0

    def createVar(i):
        i += 1
        var = ''
        varValue = ''
        while i < len(code2) and code2[i] != ':':
            var += code2[i]
            i += 1
        i += 1
        while i < len(code2) and code2[i] != ':':
            varValue += code2[i]
            i += 1

        if not var:
            print("Error: Variable name cannot be empty")
            return i, intOutput
        if varValue.lstrip('-').isnumeric():
            resolved = int(varValue)
        elif varValue in variables:
            resolved = variables[varValue]
        else:
            print(f"Error: '{varValue}' is not a number or existing variable")
            return i, intOutput
        variables[var] = resolved
        print(f"  → Created variable '{var}' = {resolved}")
        return i, intOutput

    def multiply(i):
        i += 1
        var = ''
        while i < len(code2) and code2[i] != ':':
            var += code2[i]
            i += 1
        if var not in variables:
            print(f"Error: Variable '{var}' does not exist")
            return i, intOutput
        return i, intOutput * variables[var]

    def divide(i):
        i += 1
        var = ''
        while i < len(code2) and code2[i] != ':':
            var += code2[i]
            i += 1
        if var not in variables:
            print(f"Error: Variable '{var}' does not exist")
            return i, intOutput
        if variables[var] == 0:
            print("Error: Division by zero")
            return i, intOutput
        return i, int(intOutput / variables[var])

    def printVar(i):
        i += 1
        var = ''
        while i < len(code2) and code2[i] != ':':
            var += code2[i]
            i += 1
        if var not in variables:
            print(f"Error: Variable '{var}' does not exist")
        else:
            print(f"  → {var} = {variables[var]}")
        return i

    def doLoop(i, intOutput):

        i += 1
        if i >= len(code2) or code2[i] != '(':
            print("Error: Expected '(' after '$'")
            return i, intOutput
        i += 1

        inner = ''
        depth = 0
        while i < len(code2):
            if code2[i] == '(':
                depth += 1
                inner += code2[i]
            elif code2[i] == ')':
                if depth == 0:
                    break
                depth -= 1
                inner += code2[i]
            else:
                inner += code2[i]
            i += 1

        if i >= len(code2):
            print("Error: Missing ')' in loop")
            return i, intOutput
        i += 1

        countStr = ''
        while i < len(code2) and code2[i] != ':':
            countStr += code2[i]
            i += 1

        if countStr.lstrip('-').isnumeric():
            count = int(countStr)
        elif countStr in variables:
            count = variables[countStr]
        else:
            print(f"Error: Loop count '{countStr}' is not a number or existing variable")
            return i, intOutput

        if count < 0:
            print("Error: Loop count cannot be negative")
            return i, intOutput

        for _ in range(count):
            intOutput = decode(inner, intOutput)

        return i, intOutput

    def doIf(i, intOutput):

        i += 1

        subject = ''
        while i < len(code2) and code2[i] not in ('<', '>', '='):
            subject += code2[i]
            i += 1

        if i >= len(code2):
            print("Error: Missing operator in conditional")
            return i, intOutput

        op = code2[i]
        i += 1

        rhs_str = ''
        while i < len(code2) and code2[i] != ':':
            rhs_str += code2[i]
            i += 1
        i += 1

        if subject == '/':
            lhs = intOutput
        elif subject in variables:
            lhs = variables[subject]
        else:
            print(f"Error: '{subject}' is not a variable or '/'")
            return i, intOutput

        if rhs_str.lstrip('-').isnumeric():
            rhs = int(rhs_str)
        elif rhs_str in variables:
            rhs = variables[rhs_str]
        else:
            print(f"Error: '{rhs_str}' is not a number or variable")
            return i, intOutput

        if op == '>':
            condition = lhs > rhs
        elif op == '<':
            condition = lhs < rhs
        elif op == '=':
            condition = lhs == rhs
        else:
            condition = False

        true_ops = ''
        depth = 0
        while i < len(code2):
            if code2[i] == '[':
                depth += 1
            elif code2[i] == ']':
                depth -= 1
            if code2[i] == '|' and depth == 0:
                break
            true_ops += code2[i]
            i += 1
        i += 1

        false_ops = ''
        depth = 0
        while i < len(code2):
            if code2[i] == '[':
                depth += 1
            elif code2[i] == ']':
                if depth == 0:
                    break
                depth -= 1
            false_ops += code2[i]
            i += 1

        if condition:
            intOutput = decode(true_ops, intOutput)
        else:
            intOutput = decode(false_ops, intOutput)

        return i, intOutput


    def doWhile(i, intOutput):
        i += 1
        if i >= len(code2) or code2[i] != '(':
            print("Error: Expected '(' after '%'")
            return i, intOutput
        i += 1

        inner = ''
        depth = 0
        while i < len(code2):
            if code2[i] == '(':
                depth += 1
                inner += code2[i]
            elif code2[i] == ')':
                if depth == 0:
                    break
                depth -= 1
                inner += code2[i]
            else:
                inner += code2[i]
            i += 1

        if i >= len(code2):
            print("Error: Missing ')' in while loop")
            return i, intOutput
        i += 1

        subject = ''
        while i < len(code2) and code2[i] not in ('<', '>', '='):
            subject += code2[i]
            i += 1

        if i >= len(code2):
            print("Error: Missing operator in while condition")
            return i, intOutput

        op = code2[i]
        i += 1

        rhs_str = ''
        while i < len(code2) and code2[i] != ':':
            rhs_str += code2[i]
            i += 1

        def get_lhs():
            if subject == '/':
                return intOutput
            elif subject in variables:
                return variables[subject]
            else:
                print(f"Error: '{subject}' is not a variable or '/'")
                return None

        def get_rhs():
            if rhs_str.lstrip('-').isnumeric():
                return int(rhs_str)
            elif rhs_str in variables:
                return variables[rhs_str]
            else:
                print(f"Error: '{rhs_str}' is not a number or variable")
                return None

        def check():
            lhs = get_lhs()
            rhs = get_rhs()
            if lhs is None or rhs is None:
                return False
            if op == '>': return lhs > rhs
            if op == '<': return lhs < rhs
            if op == '=': return lhs == rhs
            return False

        iterations = 0
        while check():
            intOutput = decode(inner, intOutput)
            iterations += 1
            if iterations > 100000:
                print("Error: While loop exceeded 100000 iterations (possible infinite loop)")
                break

        return i, intOutput

    while i < len(code2):
        c = code2[i]
        if c == '+':
            intOutput += 1
        elif c == '-':
            intOutput -= 1
        elif c == '=':
            i, intOutput = createVar(i)
        elif c == '*':
            i, intOutput = multiply(i)
        elif c == '/':
            i, intOutput = divide(i)
        elif c == '?':
            i = printVar(i)
        elif c == '@':
            print(f"  → Accumulator: {intOutput}")
        elif c == '$':
            i, intOutput = doLoop(i, intOutput)
        elif c == '#':
            wrapped = ((intOutput - 1) % 26) + 1
            letter = chr(ord('a') + wrapped - 1)
            print(f"  → Letter: {letter}")
        elif c == '[':
            i, intOutput = doIf(i, intOutput)
        elif c == '%':
            i, intOutput = doWhile(i, intOutput)
        i += 1

    return intOutput

def run(code):
    i = 0

    if i >= len(code) or code[i] != '&':
        print("Syntax Error: Line must start with '&'")
        return
    i += 1

    start_str = ''
    while i < len(code) and code[i] != '!':
        if not code[i].isnumeric() and code[i] != '-':
            print(f"Syntax Error: Unexpected character '{code[i]}' in starting number")
            return
        start_str += code[i]
        i += 1
        if len(start_str) > 15:
            print("Error: Starting number too long")
            return

    if not start_str:
        print("Syntax Error: Missing starting number after '&'")
        return

    i += 1

    code2 = ''
    while i < len(code) and code[i] != '!':
        code2 += code[i]
        i += 1

    intOutput = int(start_str)
    intOutput = decode(code2, intOutput)
    print(f"  Final output: {intOutput}")

print_help()

while True:
    try:
        code = input("AuroraCode > ").strip()
    except (EOFError, KeyboardInterrupt):
        print("\nGoodbye!")
        break

    if code == 'quit':
        print("Goodbye!")
        break
    elif code == 'vars':
        if variables:
            print("  Variables:")
            for k, v in variables.items():
                print(f"    {k} = {v}")
        else:
            print("  No variables defined yet.")
    elif code == '':
        continue
    else:
        run(code)

The text UI at the start of the interpreter might not work on some devices.