import sys import parser class Compiler: def __init__(self, stmts): self.instrs = [] self.labeli = 0 for st in stmts: self.preorder(st) for i in self.instrs: sys.stdout.write(i) print("EXIT") def fresh_label(self): self.labeli += 1 return "L%d" % self.labeli def preorder(self, node): return getattr(self, "t_" + node.__class__.__name__.lower())(node) def t_assign(self, node): self.preorder(node.exp) self.instrs.append("VAR_SET %s\n" % node.name) def t_var(self, node): self.instrs.append("VAR_LOOKUP %s\n" % node.name) def t_int(self, node): self.instrs.append("INT %s\n" % node.val) def t_bin_op(self, node): self.preorder(node.lhs) self.preorder(node.rhs) if node.op == "<": self.instrs.append("LESS_THAN\n") elif node.op == "+": self.instrs.append("ADD\n") elif node.op == "-": self.instrs.append("SUB\n") else: print(node.op) print("Unknown instruction '%s'" % node.op) def t_while(self, node): startl = self.fresh_label() endl = self.fresh_label() self.instrs.append("%s: " % startl) self.preorder(node.cond) self.instrs.append("JEQ %s\n" % endl) for stmt in node.body: self.preorder(stmt) self.instrs.append("JMP %s\n" % startl) self.instrs.append("%s: " % endl) def t_print(self, node): self.preorder(node.exp) self.instrs.append("PRINT\n") stmts = parser.parse(open(sys.argv[1]).read()) Compiler(stmts)