(())
(()), 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