(())

From Esolang
Jump to navigation Jump to search

(()), also known as Empty Nest, is a string re-writing scheme designed by User:DocHerrings to use only properly nested parenthesis, and to be completely impossible to read. The syntax is very simple. Every program consists of a list of productions, with the last item being the data. The interpreter iterates through the productions, testing them in order for a match within the program (all matches are greedy). If a match is found, the match substring is replaced with the productions replacement substring. If the production was non-terminating, then execution starts from the beginning of the productions and data. Otherwise, execution ends and the data is returned. A production of only one object matches the empty string.

A (()) program is made up of the following parts:

((productions) (data))
productions -> (non-terminating) | ((terminating))
non-terminating | terminating -> (match)(replace)

Examples

Binary Increment

Let 0 = (())
Let 1 = (()())
Let A = ((()))
Let B = ((()()))

To increment the binary number 1001, the following productions are used:

A1 -> 1A
A0 -> 0A
A -> B
1B -> B0
0B -| 1
B -| 1
-> A

Written in (()) form:

((((()))(()()))((()())((()))))
((((()))(()))((())((()))))
((((())))(((()()))))
(((()())((()())))(((()()))(())))
((((())((()())))((()()))))
(((((()())))((()()))))
((((()))))

The entire program, without line breaks:

((((((()))(()()))((()())((()))))((((()))(()))((())((()))))((((())))(((()()))))(((()())((()())))(((()()))(())))((((())((()())))((()()))))(((((()())))((()()))))((((())))))((()())(())(())(()())))

Interpreter

Here's an interpreter for (()), written in Python 3:

class Tree:
    def __init__(self,treelist):
        self.branches=treelist
    
    def __eq__(self,other):
        return other==None or self.branches==other.branches 
    
    def __str__(self):
        return "("+" ".join([(s.__str__() if type(s)!=type(None) else "n") for s in self.branches])+")"
   
    def __getitem__(self,key):
        if type(key)==int:
            return self.branches[key]
        elif len(key)==1:
            return self.branches[key[0]]
        return self.branches[key[0]][key[1:]]
   
    def __len__(self):
        return len(self.branches)
   
def str2(tree):
    string=""
    indent=0
    for paren in str(tree):
        if paren=="(":
            string+="\n"+"\t"*indent+paren
            indent+=1
        elif paren==")":
            indent-=1
            string+="\n"+"\t"*indent+paren
        else:
            string+="\n"+"\t"*indent+paren
    return string
def split(string):
    index=0
    i=0
    if string=="":
        return []
    elif string[0]==" ":
        return split(string[1:])
    for paren in string:
        i+=1;
        if paren=="(":
            index+=1
        elif paren==")":
            index-=1
        if index==0:
            return [string[:i]]+split(string[i:])
def tree(string):
    if string=="n":
        return None
    if len(split(string))!=1:
        return [tree(s) for s in split(string)]
    return Tree([tree(s) for s in split(string[1:-1])])
def subfinder(mylist, pattern):
    matches = []
    for i in range(len(mylist)):
        if mylist[i] == pattern[0] and mylist[i:i+len(pattern)] == pattern:
            return i
def emptyNestInterpreter(string):
    t=tree(string)

    productions=[[(s2[1:-1] if len(split(s[1:-1]))>1 else (split(s2[1:-1]) if len(split(s2[1:-1]))>1 else s2[1:-1])) for s2 in split(s[1:-1])] for s in split(str(t[0])[1:-1])]

    #print(productions)

    data=split(str(t[1])[1:-1])

    #print(data)

    end=False
    while not end:
        for production in productions:
            if type(production[0])==list:
                prod=[production[0][0][1:-1],production[0][1][1:-1]]
                end=True
            elif len(production)==1:
                prod=production
                data=prod+data
                break
            else:
                prod=production
            i=subfinder(data,split(prod[0]))
            try:
                data=data[:i]+split(prod[1])+data[i+len(split(prod[0])):]
                break
            except TypeError:
                pass
            end=False
        #print(data)
    return data