#! /usr/bin/env python import sys out = sys.stdout.write IO = '\t\n' STACK = ' ' ARITHMETIC = '\t ' HEAP = '\t\t' FLOW = '\n' def number(num): if num < 0: s = ['\t'] else: s = [' '] s += [' ' if x == '0' else '\t' for x in bin(num)[2:]] return ''.join(s+['\n']) def compi(line): if line.startswith('--'): return if '-v' in sys.argv: out(line.replace(' ', ''.replace('\t', ''))) if line == 'READ CHAR': # Read character and place it to location given by the top of the stack out(IO + '\t ') elif line == 'READ NUMBER': # Read a number and place it in the location given by the top of the stack out(IO + '\t\t') elif line == 'OUTPUT CHAR': # Output the character at the top of the stack out(IO + ' ') elif line == 'OUTPUT NUMBER': # Output the number at the top of the stack out(IO + ' \t') elif line.startswith('PUSH '): num = int(line[5:]) out(STACK + ' ' + number(num)) elif line == 'DUPLICATE': out(STACK + '\n ') elif line == 'SWAP': out(STACK + '\n\t') elif line == 'DISCARD': out(STACK + '\n\n') elif line == 'ADD': out(ARITHMETIC + ' ') elif line == 'SUB': out(ARITHMETIC + ' \t') elif line == 'MUL': out(ARITHMETIC + ' \n') elif line == 'IDIV': out(ARITHMETIC + '\t ') elif line == 'MOD': out(ARITHMETIC + '\t\t') elif line == 'STORE': out (HEAP + ' ') elif line == 'RETRIEVE': out(HEAP + '\t') elif line.startswith('MARK '): out(FLOW + ' ' + number(int(line[5:]))) elif line.startswith('CALL '): out(FLOW + ' \t' + number(int(line[5:]))) elif line.startswith('JMP '): out(FLOW + ' \n' + number(int(line[4:]))) elif line.startswith('JZ '): out(FLOW + '\t ' + number(int(line[3:]))) elif line.startswith('JN '): out(FLOW + '\t\t' + number(int(line[3:]))) elif line == 'RETURN': out(FLOW + '\t\n') elif line == 'END': out(FLOW + '\n\n') if __name__ == '__main__': if len(sys.argv) < 2: print 'Usage: %s [-v]' % sys.argv[0] raise SystemExit with open(sys.argv[1], 'r') as f: for line in f: compi(line.strip())