Alyssa

python_bc_interpreter

Jan 28th, 2017
256
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Python 15.43 KB | None | 0 0
  1. import math
  2. import os
  3. import sys
  4. import time
  5.  
  6. class Program:
  7.     def __init__(self,world):
  8.         if str(type(world)) == "<class 'str'>":
  9.             from_string = True
  10.         else:
  11.             from_string = False
  12.         if not from_string:
  13.             self.world = world
  14.         else:
  15.             self.world = {}
  16.             y_layers = world.split("\n\n")
  17.             y_index = 0
  18.             for y_layer in y_layers:
  19.                 z_layers = y_layer.split("\n")
  20.                 z_index = 0
  21.                 for z_layer in z_layers:
  22.                     x_index = 0
  23.                     for char in z_layer:
  24.                         if not x_index in self.world:
  25.                             self.world[x_index] = {}
  26.                         if not y_index in self.world[x_index]:
  27.                             self.world[x_index][y_index] = {}
  28.                         self.world[x_index][y_index][z_index] = ord(char) - 32
  29.                         x_index += 1
  30.                     z_index += 1
  31.                 y_index += 1
  32.         self.cursor = {}
  33.         self.cursor["x"] = 0
  34.         self.cursor["y"] = 0
  35.         self.cursor["z"] = 0
  36.         self.cursor["dir"] = 1
  37.         self.search = False
  38.         self.search_score = 0
  39.         self.skip = False
  40.         self.pointer = 0
  41.         self.memp = 0
  42.         self.needle = 0
  43.         self.lifetime = 0
  44.         self.abandoned = 0
  45.         self.cells = {}
  46.         self.drive = {}
  47.         self.memory = {}
  48.         self.ops = [self.noop, self.increment_pointer, self.decrement_pointer, self.increment_cell, self.decrement_cell, self.output, self.input, self.jump_forward, self.jump_backward, self.dir_posx, self.dir_posz, self.dir_negx, self.dir_negz, self.dir_posy, self.dir_negy, self.end_program, self.add_surrounding, self.subtract_surrounding, self.multiply_surrounding, self.divide_surrounding, self.equal_left, self.swap, self.equal_left_less, self.equal_left_greater, self.mod_surrounding, self.equal_right, self.equal_right_less, self.equal_left_greater, self.if_zero, self.if_non_zero, self.if_equal_left, self.if_equal_right, self.if_less_left, self.if_less_right, self.if_more_left, self.if_more_right, self.playsound, self.big_output, self.set_zero, self.write_drive, self.receive_drive, self.increment_needle, self.decrement_needle, self.increment_memp, self.decrement_memp, self.receive_memory, self.write_memory, self.create_op, self.async_input, self.create_marker, self.delete_marker, self.goto_marker, self.set_needle, self.set_memp, self.set_pointer, self.set_cursor, self.get_op, self.relative_set_cursor, self.get_pointer, self.get_memp, self.get_needle]
  49.         self.markers = []
  50.     def get_world(self):
  51.         return self.world
  52.     def run(self,delay,limit=-1,timeout=500,verbose=False):
  53.         self.cursor = {}
  54.         self.cursor["x"] = 0
  55.         self.cursor["y"] = 0
  56.         self.cursor["z"] = 0
  57.         self.cursor["dir"] = 1
  58.         self.search = False
  59.         self.search_score = 0
  60.         self.skip = False
  61.         self.pointer = 0
  62.         self.memp = 0
  63.         self.needle = 0
  64.         self.lifetime = 0
  65.         self.abandoned = 0
  66.         self.cells = {}
  67.         self.memory = {}
  68.         self.running = True
  69.         while self.running == True:
  70.             if verbose == True:
  71.                 print("Cursor Dir: " + str(self.cursor["dir"]) + " X: " + str(self.cursor["x"]) + " Y:" + str(self.cursor["y"]) + " Z:" + str(self.cursor["z"]))
  72.                 print("Pointer Pos: " + str(self.pointer) + " Cells: " + str(self.cells))
  73.                 print("Mem Pointer Pos: " + str(self.memp) + " Memory: " + str(self.memory))
  74.                 print("Needle Pos: " + str(self.needle) + " Drive: " + str(self.drive))
  75.             self.lifetime += 1
  76.             if self.lifetime == limit:
  77.                 self.running = False
  78.             if self.abandoned >= timeout:
  79.                 self.running = False
  80.             time.sleep(delay)
  81.             try:
  82.                 if self.skip == False:
  83.                     op = self.world[self.cursor["x"]][self.cursor["y"]][self.cursor["z"]]
  84.                 else:
  85.                     self.skip = False
  86.                     op = 0
  87.             except KeyError:
  88.                 op = 0
  89.             try:
  90.                 if self.search == False:
  91.                     self.ops[op]()
  92.                     if verbose == True:
  93.                         print(self.ops[op].__name__)
  94.                 else:
  95.                     if op == 7:
  96.                         self.search_score += 1
  97.                     elif op == 8:
  98.                         self.search_score -= 1
  99.                     if search_score == 0:
  100.                         self.search = False
  101.             except IndexError:
  102.                 pass
  103.             if self.search_score >= 0:
  104.                 if self.cursor["dir"] == 1:
  105.                     self.cursor["x"] += 1
  106.                 elif self.cursor["dir"] == 2:
  107.                     self.cursor["z"] += 1
  108.                 elif self.cursor["dir"] == 3:
  109.                     self.cursor["x"] -= 1
  110.                 elif self.cursor["dir"] == 4:
  111.                     self.cursor["z"] -= 1
  112.                 elif self.cursor["dir"] == 5:
  113.                     self.cursor["y"] += 1
  114.                 elif self.cursor["dir"] == 6:
  115.                     self.cursor["y"] -= 1
  116.             else:
  117.                 if self.cursor["dir"] == 1:
  118.                     self.cursor["x"] -= 1
  119.                 elif self.cursor["dir"] == 2:
  120.                     self.cursor["z"] -= 1
  121.                 elif self.cursor["dir"] == 3:
  122.                     self.cursor["x"] += 1
  123.                 elif self.cursor["dir"] == 4:
  124.                     self.cursor["z"] += 1
  125.                 elif self.cursor["dir"] == 5:
  126.                     self.cursor["y"] -= 1
  127.                 elif self.cursor["dir"] == 6:
  128.                     self.cursor["y"] += 1
  129.     def get_cell(self, pos):
  130.         try:
  131.             return self.cells[pos]
  132.         except KeyError:
  133.             self.cells[pos] = 0
  134.             return self.cells[pos]
  135.     def get_drive(self, pos):
  136.         try:
  137.             return self.drive[pos]
  138.         except KeyError:
  139.             self.drive[pos] = 0
  140.             return self.drive[pos]
  141.     def get_memory(self, pos):
  142.         try:
  143.             return self.memory[pos]
  144.         except KeyError:
  145.             self.memory[pos] = 0
  146.             return self.memory[pos]
  147.     def noop(self):
  148.         #Does nothing, counts as an abandoned
  149.         self.abandoned += 1
  150.     def increment_pointer(self):
  151.         #Increment pointer position
  152.         self.pointer += 1
  153.     def decrement_pointer(self):
  154.         #Decrements pointer position
  155.         self.pointer -= 1
  156.     def increment_cell(self):
  157.         #Increments current cell
  158.         try:
  159.             self.cells[self.pointer] += 1
  160.         except KeyError:
  161.             self.cells[self.pointer] = 1
  162.     def decrement_cell(self):
  163.         #Decrements current cell
  164.         try:
  165.             self.cells[self.pointer] -= 1
  166.         except KeyError:
  167.             self.cells[self.pointer] = -1
  168.     def output(self):
  169.         #Output Ascii Character
  170.         try:
  171.             print(chr(self.cells[self.pointer]))
  172.         except KeyError:
  173.             print(chr(0))
  174.     def input(self):
  175.         #Get one character of input
  176.         self.cells[self.pointer] = wait_key()
  177.     def jump_forward(self):
  178.         #Jump to ] if cell is 0
  179.         try:
  180.             if self.cells[self.pointer] == 0:
  181.                 #Search for ]
  182.                 self.search = True
  183.                 self.search_score = 1
  184.         except KeyError:
  185.             self.cells[self.pointer] = 0
  186.             #Search for ]
  187.             self.search = True
  188.             self.search_score = 1
  189.     def jump_backward(self):
  190.         #Jump to [ if cell is not 0
  191.         try:
  192.             if self.cells[self.pointer] != 0:
  193.                 #Search for ]
  194.                 self.search = True
  195.                 self.search_score = -1
  196.         except KeyError:
  197.             pass
  198.     def dir_posx(self):
  199.         #Set direction to +X
  200.         self.cursor["dir"] = 1
  201.     def dir_posz(self):
  202.         #Set direction to +Z
  203.         self.cursor["dir"] = 2
  204.     def dir_negx(self):
  205.         #Set direction to -X
  206.         self.cursor["dir"] = 3
  207.     def dir_negz(self):
  208.         #Set direction to -Z
  209.         self.cursor["dir"] = 4
  210.     def dir_posy(self):
  211.         #Set direction to +Y
  212.         self.cursor["dir"] = 5
  213.     def dir_negy(self):
  214.         #Set direction to -Y
  215.         self.cursor["dir"] = 6
  216.     def end_program(self):
  217.         #Ends Program
  218.         self.running = False
  219.     def add_surrounding(self):
  220.         #Adds Surrounding Cells
  221.         cell_left = self.get_cell(self.pointer-1)
  222.         cell_right = self.get_cell(self.pointer+1)
  223.         self.cells[self.pointer] = cell_left + cell_right
  224.     def subtract_surrounding(self):
  225.         #Subtract Surrounding Cells
  226.         cell_left = self.get_cell(self.pointer-1)
  227.         cell_right = self.get_cell(self.pointer+1)
  228.         self.cells[self.pointer] = cell_left - cell_right
  229.     def multiply_surrounding(self):
  230.         #Multiply Surrounding Cells
  231.         cell_left = self.get_cell(self.pointer-1)
  232.         cell_right = self.get_cell(self.pointer+1)
  233.         self.cells[self.pointer] = cell_left * cell_right
  234.     def divide_surrounding(self):
  235.         #Divide & Floor Surrounding Cells
  236.         cell_left = self.get_cell(self.pointer-1)
  237.         cell_right = self.get_cell(self.pointer+1)
  238.         self.cells[self.pointer] = math.floor(cell_left / cell_right)
  239.     def equal_left(self):
  240.         #Set to Left Cell
  241.         try:
  242.             self.cells[self.pointer] = self.cells[self.pointer-1]
  243.         except KeyError:
  244.             self.cells[self.pointer-1] = 0
  245.             self.cells[self.pointer] = self.cells[self.pointer-1]
  246.     def swap(self):
  247.         #Swap left and right Cells
  248.         cell_left = self.get_cell(self.pointer-1)
  249.         cell_right = self.get_cell(self.pointer+1)
  250.         self.cells[self.pointer-1] = cell_right
  251.         self.cells[self.pointer+1] = cell_left
  252.     def equal_left_less(self):
  253.         #Set to Left Cell if less than Left Cell
  254.         try:
  255.             if self.cells[self.pointer-1] > self.cells[self.pointer]:
  256.                 self.cells[self.pointer] = self.cells[self.pointer-1]
  257.         except KeyError:
  258.             if not self.pointer-1 in self.cells:
  259.                 self.cells[self.pointer-1] = 0
  260.             if not self.pointer in self.cells:
  261.                 self.cells[self.pointer] = 0
  262.             if self.cells[self.pointer-1] > self.cells[self.pointer]:
  263.                 self.cells[self.pointer] = self.cells[self.pointer-1]
  264.     def equal_left_greater(self):
  265.         #Set to Left Cell if more than Left Cell
  266.         try:
  267.             if self.cells[self.pointer-1] < self.cells[self.pointer]:
  268.                 self.cells[self.pointer] = self.cells[self.pointer-1]
  269.         except KeyError:
  270.             if not self.pointer-1 in self.cells:
  271.                 self.cells[self.pointer-1] = 0
  272.             if not self.pointer in self.cells:
  273.                 self.cells[self.pointer] = 0
  274.             if self.cells[self.pointer-1] < self.cells[self.pointer]:
  275.                 self.cells[self.pointer] = self.cells[self.pointer-1]
  276.     def mod_surrounding(self):
  277.         #Do modulo on surrounding cells
  278.         cell_left = self.get_cell(self.pointer-1)
  279.         cell_right = self.get_cell(self.pointer+1)
  280.         self.cells[self.pointer] = cell_left % cell_right
  281.     def equal_right(self):
  282.         #Set cell to cell right
  283.         try:
  284.             self.cells[self.pointer] = self.cells[self.pointer+1]
  285.         except KeyError:
  286.             self.cells[self.pointer+1] = 0
  287.             self.cells[self.pointer] = self.cells[self.pointer+1]
  288.     def equal_right_less(self):
  289.         #Set to Right Cell if less than Right Cell
  290.         try:
  291.             if self.cells[self.pointer+1] > self.cells[self.pointer]:
  292.                 self.cells[self.pointer] = self.cells[self.pointer+1]
  293.         except KeyError:
  294.             if not self.pointer+1 in self.cells:
  295.                 self.cells[self.pointer+1] = 0
  296.             if not self.pointer in self.cells:
  297.                 self.cells[self.pointer] = 0
  298.             if self.cells[self.pointer+1] > self.cells[self.pointer]:
  299.                 self.cells[self.pointer] = self.cells[self.pointer+1]
  300.     def equal_right_greater(self):
  301.         #Set to Right Cell if more than Right Cell
  302.         try:
  303.             if self.cells[self.pointer+1] < self.cells[self.pointer]:
  304.                 self.cells[self.pointer] = self.cells[self.pointer+1]
  305.         except KeyError:
  306.             if not self.pointer+1 in self.cells:
  307.                 self.cells[self.pointer+1] = 0
  308.             if not self.pointer in self.cells:
  309.                 self.cells[self.pointer] = 0
  310.             if self.cells[self.pointer+1] < self.cells[self.pointer]:
  311.                 self.cells[self.pointer] = self.cells[self.pointer+1]
  312.     def if_zero(self):
  313.         #Skip if not zero
  314.         if self.get_cell(self.pointer) == 0:
  315.             pass
  316.         else:
  317.             self.skip = True
  318.     def if_non_zero(self):
  319.         #Skip if zero
  320.         if self.get_cell(self.pointer) != 0:
  321.             pass
  322.         else:
  323.             self.skip = True
  324.     def if_equal_left(self):
  325.         #Skip if cell equals left cell
  326.         if self.get_cell(self.pointer) == self.get_cell(self.pointer-1):
  327.             pass
  328.         else:
  329.             self.skip = True
  330.     def if_equal_right(self):
  331.         #Skip if cell equals right cell
  332.         if self.get_cell(self.pointer) == self.get_cell(self.pointer+1):
  333.             pass
  334.         else:
  335.             self.skip = True
  336.     def if_less_left(self):
  337.         #Skip if cell is less than left cell
  338.         if self.get_cell(self.pointer) < self.get_cell(self.pointer-1):
  339.             pass
  340.         else:
  341.             self.skip = True
  342.     def if_less_right(self):
  343.         #Skip if cell is less than right cell
  344.         if self.get_cell(self.pointer) < self.get_cell(self.pointer+1):
  345.             pass
  346.         else:
  347.             self.skip = True
  348.     def if_more_left(self):
  349.         #Skip if cell is more than left cell
  350.         if self.get_cell(self.pointer) > self.get_cell(self.pointer-1):
  351.             pass
  352.         else:
  353.             self.skip = True
  354.     def if_more_right(self):
  355.         #Skip if cell is more than right cell
  356.         if self.get_cell(self.pointer) > self.get_cell(self.pointer+1):
  357.             pass
  358.         else:
  359.             self.skip = True
  360.     def playsound(self):
  361.         #TODO: Play sound of pitch cell
  362.         pitch = self.get_cell(self.pointer)
  363.     def big_output(self):
  364.         #Output 80 characters
  365.         result = ""
  366.         for i in range(80):
  367.             cur = self.get_cell(self.pointer + i)
  368.             if cur >= 32 and cur <= 127:
  369.                 result += chr(cur)
  370.         print(result)
  371.     def set_zero(self):
  372.         #Set cell to 0
  373.         self.cells[self.pointer] = 0
  374.     def write_drive(self):
  375.         #Write cell to drive
  376.         self.drive[self.needle] = self.get_cell(self.pointer)
  377.     def receive_drive(self):
  378.         #Write drive to cell
  379.         self.cells[self.pointer] = self.get_drive(self.needle)
  380.     def increment_needle(self):
  381.         #Move needle +1
  382.         self.needle += 1
  383.     def decrement_needle(self):
  384.         #Move needle -1
  385.         self.needle -= 1
  386.     def increment_memp(self):
  387.         #Move memp +1
  388.         self.memp += 1
  389.     def decrement_memp(self):
  390.         #Move memp -1
  391.         self.memp -= 1
  392.     def receive_memory(self):
  393.         #Write memory to cell
  394.         self.cells[self.pointer] = self.get_memory(self.memp)
  395.     def write_memory(self):
  396.         #Write cell to memory
  397.         self.memory[self.memp] = self.get_cell(self.pointer)
  398.     def create_op(self):
  399.         #Creates an op
  400.         self.world[self.get_cell(self.pointer+1)+self.cursor["x"]][self.get_cell(self.pointer+2)+self.cursor["y"]][self.get_cell(self.pointer+3)+self.cursor["z"]] = self.get_cell(self.pointer)
  401.     def async_input(self):
  402.         #TODO: Async Input
  403.         pass
  404.     def create_marker(self):
  405.         #Create marker
  406.         self.markers.insert(0,{"x":self.cursor["x"],"y":self.cursor["y"],"z":self.cursor["z"],"dir":self.cursor["dir"]})
  407.     def delete_marker(self):
  408.         #Delete first marker
  409.         self.markers.pop(0)
  410.     def goto_marker(self):
  411.         #Goto first marker and kill it
  412.         self.cursor["x"] = self.markers[0]["x"]
  413.         self.cursor["y"] = self.markers[0]["y"]
  414.         self.cursor["z"] = self.markers[0]["z"]
  415.         self.cursor["dir"] = self.markers[0]["dir"]
  416.         self.markers.pop(0)
  417.     def set_needle(self):
  418.         #Set needle pos to cell
  419.         self.needle = self.get_cell(self.pointer)
  420.     def set_memp(self):
  421.         #Set memory pointer pos to cell
  422.         self.memp = self.get_cell(self.pointer)
  423.     def set_pointer(self):
  424.         #Set pointer pos to cell
  425.         self.pointer = self.get_cell(self.pointer)
  426.     def set_cursor(self):
  427.         #Set cursor pos
  428.         self.cursor["x"] = self.get_cell(self.pointer)
  429.         self.cursor["y"] = self.get_cell(self.pointer+1)
  430.         self.cursor["z"] = self.get_cell(self.pointer+2)
  431.     def get_op(self):
  432.         #Get op of pos
  433.         if self.get_cell(self.pointer) in self.world:
  434.             if self.get_cell(self.pointer+1) in self.world[self.get_cell(self.pointer)]:
  435.                 if self.get_cell(self.pointer+2) in self.world[self.get_cell(self.pointer)][self.get_cell(self.pointer+1)]:
  436.                     self.cells[self.pointer] = self.world[self.get_cell(self.pointer)][self.get_cell(self.pointer+1)][self.get_cell(self.pointer+2)]
  437.                 else:
  438.                     self.cells[self.pointer] = 0
  439.             else:
  440.                 self.cells[self.pointer] = 0
  441.         else:
  442.             self.cells[self.pointer] = 0
  443.     def relative_set_cursor(self):
  444.         #Relative set cursor pos
  445.         self.cursor["x"] += self.get_cell(self.pointer)
  446.         self.cursor["y"] += self.get_cell(self.pointer+1)
  447.         self.cursor["z"] += self.get_cell(self.pointer+2)
  448.     def get_pointer(self):
  449.         #Set cell to pointer pos
  450.         self.cells[self.pointer] = self.pointer
  451.     def get_memp(self):
  452.         #Set cell to memp pos
  453.         self.cells[self.pointer] = self.memp
  454.     def get_needle(self):
  455.         #Set cell to needle pos
  456.         self.cells[self.pointer] = self.needle
  457.     def wait_key():
  458.         ''' Wait for a key press on the console and return it. '''
  459.         #Curtesy of http://stackoverflow.com/a/34956791/6150373
  460.         result = None
  461.         if os.name == 'nt':
  462.             import msvcrt
  463.             result = msvcrt.getch()
  464.         else:
  465.             import termios
  466.             fd = sys.stdin.fileno()
  467.             oldterm = termios.tcgetattr(fd)
  468.             newattr = termios.tcgetattr(fd)
  469.             newattr[3] = newattr[3] & ~termios.ICANON & ~termios.ECHO
  470.             termios.tcsetattr(fd, termios.TCSANOW, newattr)
  471.             try:
  472.                 result = sys.stdin.read(1)
  473.             except IOError:
  474.                 pass
  475.             finally:
  476.                 termios.tcsetattr(fd, termios.TCSAFLUSH, oldterm)
  477.         return result
Advertisement
Add Comment
Please, Sign In to add comment