Graphopytha
Jump to navigation
Jump to search
This is my python interpreter made (note: not used in Graphomata) for Graphomata's programming language, and I made it in python
Interpreter
import random tutorial_on_how_to_use_it = """ the workers are reperesented by their index in the workers list the nodes are reperesented by their index in the nodes list, although not used in the program to have a starting input, set the nodes to something, then index the workers and set one of the workers to an index of the nodes, for example worker 0 at node 0 to have an output, i currently dont know, maybe you just try replacing numbers in the indexes to different numbers to see if they ever turn into the output i literally dont know yet commands are formatted like [commandname, worker1, worker2, direction1, direction2], also worker2 and direction2 are optional for commands not using them, if they dont use it put None instead, also here are the command names if you are too lazy to read the run function, node, link, unlink, walk, test, and join, which take 1, 2, 2, 1, 2, and 2 workers respectfully, and take 1, 1, 1, 1, 2, and 1 directions respectfully, for example, test is ["test", worker1, worker2, direction1, direction2], but join is ["join", worker1, worker2- , direction1, None], so yeah """ def make_n_workers(n): global workers workers = [-1 for _ in range(n)] def walk(n): if n == -1: raise IndexError("home worker cant move") if workers[n] > -1: outgoings = nodes[workers[n]] if len(outgoings)>0: workers[n] = random.choice(outgoings) else: workers[n] = -1 else: raise IndexError("worker "+str(n)+" is at home, so it can't move") def node(n): global index if n == -1: raise IndexError("home worker cant make a node") nodes.append([]) ids.append(index) index += 1 workers[n] = len(nodes)-1 def link(x, y): placea = workers[x] placeb = workers[y] if placea>-1 and placeb>-1 and x != -1 and y != -1: if placea != placeb: if placeb not in nodes[placea]: nodes[placea].append(placeb) else: raise IndexError("that link already exists") else: raise IndexError("worker "+str(x)+" and worker "+str(y)+" are at the same place, you cant link two things at the same place") else: raise IndexError("you cant connect to or from a worker at home") def unlink(x, y): placea = workers[x] placeb = workers[y] if placea>-1 and placeb>-1 and x != -1 and y != -1: if placea != placeb: if placeb in nodes[placea]: nodes[placea].remove(placeb) else: raise IndexError("that link doesnt exists") else: raise IndexError("worker "+str(x)+" and worker "+str(y)+" are at the same place, you cant unlink two things at the same place") else: raise IndexError("you cant disconnect to or from a worker at home") def test(a, b): return (-1 if a==-1 else workers[a]) == (-1 if b==-1 else workers[b]) def join(a, b): if a == -1: raise IndexError("home worker cant move") workers[a] = (-1 if b==-1 else workers[b]) def delete_node(i): del nodes[i] del ids[i] for j in range(len(nodes)): nodes[j] = [k-1 if k > i else k for k in nodes[j]] for w in range(len(workers)): if workers[w] > i: workers[w] -= 1 def reduce(): i = 0 while i < len(nodes) : if i in workers: i+=1; continue if i in [target for source in nodes if source for target in source]: i+=1; continue if nodes[i] and len(nodes[i])>0: i+=1; continue delete_node(i) def notoutofbounds(pos, wid, hei): return pos[0]>-1 and wid>pos[0] and pos[1]>-1 and hei>pos[1] def run(coms): height = len(coms) width = len(coms[3]) direction = coms[2] position = [coms[0],coms[1]] bre = False print("Starting with nodes as:", nodes, "And workers as:", workers, "And index of made as:", ids) while notoutofbounds(position, width, height): command = coms[position[1]+3][position[0]] if command[0] == "node": node(command[1]) direction = command[3] elif command[0] == "walk": walk(command[1]) direction = command[3] elif command[0] == "link": link(command[1], command[2]) direction = command[3] elif command[0] == "unlink": unlink(command[1], command[2]) direction = command[3] elif command[0] == "join": join(command[1], command[2]) direction = command[3] elif command[0] == "test": if test(command[1], command[2]): direction = command[3] else: direction = command[4] if direction == "r": position[0] += 1 elif direction == "l": position[0] -= 1 elif direction == "u": position[1] -= 1 elif direction == "d": position[1] += 1 elif direction == None: bre = True reduce() print("After doing:", command, "The nodes are:", nodes, "And the workers are:", workers, "And index of made is:", ids) if bre: break print("Ending with nodes as:", nodes, "And workers as:", workers, "And index of made as:", ids) nodes = [] #index is node index, value is list of node indeces ids = list(range(len(nodes))) #for when a node was made for clarity on stuff index = len(nodes) workers = [] #index is worker, value at index is what node the worker is, -1 is home, 0th is first one make_n_workers(10) # ten workers (you can change it) commands = [0, 0, 'r', [['node', 0, None, 'r', None], ['node', 1, None, 'd', None]], [['node', 3, None, 'u', None], ['node', 2, None, 'l', None]]] run(commands)
Parser (bonus)
#this is the parser (pars.py) #it should parse text like this: #0, 0, r #node 0 r, node 1 l #or: #test 0 1 r l #so those will be the first examples to try using the function def readexception(i, code, end, errorchr, error="Unexpected char: "): output = "" while i < len(code) and code[i] not in end: if code[i] in errorchr: raise SyntaxError(error) output += code[i] i += 1 return (i, output) def readexceptstop(i, code, end, specifics=None): if specifics == None: specifics = ["nothing"] output = "" while i < len(code) and code[i] not in end: output += code[i] i += 1 if output in specifics: break return (i, output) def read(i, code, end): output = "" while i < len(code) and code[i] not in end: output += code[i] i += 1 return (i, output) def skip(i, code, things): while i < len(code) and code[i] in things: #skip extra comma and space i += 1 return i def parse(code): #we should go in a loop output = [] i = len(code.split(" ")[0])+1 #skip first line so we can loop #first, we need start inputs: topline = code.split(" ")[0].split(", ") output.append(int(topline[0])) output.append(int(topline[1])) output.append(topline[2]) output.append([]) #then lets go get the rest while i < len(code): #look for a command name first i, name = readexceptstop(i, code, " ") if name != "nothing": i = skip(i, code, " ") else: i = skip(i, code, ", ") #ok now we got our name, now we need to figure out how many args, (workers, dirs) argdict = { "node": (1, 1), "walk": (1, 1), "nothing": (0, 0), "link": (2, 1), "unlink": (2, 1), "test": (2, 2), "join": (2, 1) } if name not in argdict: raise NameError(f"{name} is not a thing, use something else") args = argdict[name] #get the args for name #now we need to loop for first the workers, but first, is args even a tuple workers = [None, None] dirs = [None, None] for j in range(args[0]): #yay time to parse numbers de = " " #alway i, workers[j] = readexception(i, code, de, ",", f"Thats not enough for {name}'s inputs, {j+1} instead of {args[0]+args[1]}") i = skip(i, code, " ") for j in range(args[1]): #yay time to parse strings if j == args[1]-1: #last de = (", ", ", ") i, dirs[j] = read(i, code, de[0]) else: #not last de = (" ", " ") i, dirs[j] = readexception(i, code, de[0], ",", f"Thats not enough for {name}'s inputs, {j+args[0]+1} instead of {args[0]+args[1]}") i = skip(i, code, de[1]) #then we just need to switch halt into None workers = [(int(wk) if wk != None else None) for wk in workers] dirs = [(di if di != "halt" else None) for di in dirs] output[-1].append([name, workers[0], workers[1], dirs[0], dirs[1]]) #ok now finally we just need to look for a new thing if i < len(code) and code[i] == " ": output.append([]) i+=1 return output print(parse("""0, 0, r node 0 r, node 1 d node 3 u, node 2 l"""))