# This program interpretes code for Random Access Machine - RAM # RAM is hypothetical computational machine, like Turing's machine, # used for educational purposes and proving concepts # may be useful for debugging homework (my case) # feel free to modify to suit your needs # usage: takes one parameter - filename of file with RAM machine code import re import sys class Parser: program = [] # instruction set, True - instruction HAS parameter instructionSet = [ ("READ", False), # acc = stdin ("WRITE", False), # acc -> stdout ("LOAD", True), # acc = mem[param] ("STORE", True), # mem[param] = acc ("ALOAD", True), # acc = mem[mem[param]] ("ASTORE", True), # mem[mem[param]] = acc ("ADD", True), # acc += mem[param] ("SUB", True), # acc -= mem[param] ("MUL", True), # acc *= mem[param] ("DIV", True), # acc = acc / mem[param] ("MOD", True), # acc = acc % mem[param] ("SET", True), # acc = param ("INC", True), # acc += param ("DEC", True), # acc -= param ("JUMP", True), # instruction pointer = param ("JGTZ", True), # instruction pointer = param if acc > 0 ("JZERO", True), # instruction pointer = param if acc == 0 ("JNEG", True), # instruction pointer = param if acc < 0 ("AJUMP", False), # instruction pointer = mem[param] ("NOP", False), # no operation ("HALT", False)] # end program def parseInput(self, filename): pattern = "^(\w+)((\s+(-?\d+?))?)\s*$" f = open(filename, "r") for line in f: line = line.split("#")[0] if(re.match(pattern, line)): parsedLine = re.search(pattern, line) instruction = parsedLine.group(1) parameter = parsedLine.group(4) hasParameter = False if parameter == None else True if((instruction, hasParameter) in self.instructionSet): if(hasParameter == True): self.program.append((instruction, parameter)) else: self.program.append((instruction, None)) else: print "Unknown instruction "+instruction sys.exit() else: print "Unknown instruction "+line sys.exit() if(self.program[-1][0] != "HALT"): self.program.append(("HALT", False)) return self.program class Interpreter: program = [] def __init__(self, inputProgram): self.program = inputProgram def runProgram(self): acc = 0 # accumulator ip = 0 # instruction pointer mem = dict() # memory instr = self.program[ip][0] param = self.program[ip][1] while(instr != "HALT"): ip += 1 if(instr == "READ"): acc = int(sys.stdin.readline()) elif(instr == "WRITE"): print acc elif(instr == "LOAD"): if(int(param) not in mem): mem[int(param)] = 0 acc = mem[int(param)] elif(instr == "STORE"): mem[int(param)] = acc elif(instr == "ALOAD"): if(mem[int(param)] not in mem): mem[mem[int(param)]] = 0 acc = mem[mem[int(param)]] elif(instr == "ASTORE"): mem[mem[int(param)]] = acc elif(instr == "ADD"): if(int(param) not in mem): mem[int(param)] = 0 acc = acc + mem[int(param)] elif(instr == "SUB"): if(int(param) not in mem): mem[int(param)] = 0 acc = acc - mem[int(param)] elif(instr == "MUL"): if(int(param) not in mem): mem[int(param)] = 0 acc = acc * mem[int(param)] elif(instr == "DIV"): if(int(param) not in mem): mem[int(param)] = 0 acc = acc / mem[int(param)] elif(instr == "MOD"): if(int(param) not in mem): mem[int(param)] = 0 acc = acc % mem[int(param)] elif(instr == "SET"): acc = int(param) elif(instr == "INC"): acc = acc + int(param) elif(instr == "DEC"): acc = acc - int(param) elif(instr == "JUMP"): ip = int(param) elif(instr == "JGTZ"): if(acc > 0): ip = int(param) elif(instr == "JZERO"): if(acc == 0): ip = int(param) elif(instr == "JNEG"): if(acc < 0): ip = int(param) elif(instr == "AJUMP"): ip = acc instr = program[ip][0] param = program[ip][1] if(len(sys.argv) >= 2): filename = sys.argv[1] else: print "No input file" sys.exit() parser = Parser() program = parser.parseInput(filename) interpreter = Interpreter(program) interpreter.runProgram()