from back.tac import *
import sys
class Node(object):
labels = 0
def newlabel(self):
Node.labels += 1
return Node.labels
def emitlabel(self, i):
sys.stdout.write("L" + str(i) + ":")
sys.stdout.flush()
def emit(self, s):
sys.stdout.write("\t" + s + "\n")
sys.stdout.flush()
def debug(self, msg):
#sys.stdout.write("DEBUG: " + msg + "\n")
#sys.stdout.flush()
return
class Program(Node):
def __init__(self, functions, lineno = -1):
self.functions = functions
self.lineno = lineno
def generate(self):
self.debug("Program.generate(): functions = %s" % self.functions)
for function in self.functions:
function.generate()
def __repr__(self):
return "<Program: %s>" % self.functions
class Function(Node):
def __init__(self, name, params, statement, lineno = -1):
self.name = name
self.params = params
self.statement = statement
self.lineno = lineno
def generate(self):
self.debug("Function.generate(): name = %s, params = %s, statement = %s" % (self.name, self.params, self.statement))
print "%s:" % self.name
begin = self.newlabel()
after = self.newlabel()
self.emitlabel(begin)
self.statement.generate(begin, after)
self.emitlabel(after)
print
def __repr__(self):
return "<Function: %s(%s) at line %d: %s>" % (self.name, str(self.params), self.lineno, str(self.statement))
class Statement(Node):
pass
class Sequence(Statement):
def __init__(self, s1, s2, lineno = -1):
self.s1 = s1
self.s2 = s2
self.lineno = lineno
def generate(self, before, after):
self.debug("Sequence.generate(before = %d, after = %d): s1 = %s, s2 = %s" % (before, after, self.s1, self.s2))
if not self.s1:
self.s2.generate(before, after)
elif not self.s2:
self.s1.generate(before, after)
else:
label = self.newlabel()
self.s1.generate(before, label)
self.emitlabel(label)
self.s2.generate(label, after)
def __repr__(self):
return "<Sequence at line %d: %s, %s>" % (self.lineno, self.s1, self.s2)
class IfStatement(Statement):
def __init__(self, expression, true_statement, false_statement, lineno = -1):
self.expression = expression
self.true_statement = true_statement
self.false_statement = false_statement
self.lineno = lineno
def generate(self, before, after):
self.debug("IfStatement.generate(before = %d, after = %d): expression = %s, true = %s, false = %s" % (before, after, self.expression, self.true_statement, self.false_statement))
x = self.expression.reduce()
if self.false_statement:
true_label = self.newlabel()
false_label = self.newlabel()
self.emit("iffalse %s goto L%d" % (x, false_label))
self.emitlabel(true_label)
self.true_statement.generate(true_label, after)
self.emit("goto L%d" % after)
self.emitlabel(false_label)
self.false_statement.generate(false_label, after)
else:
true_label = self.newlabel()
self.emit("iffalse %s goto L%d" % (x, after))
self.emitlabel(true_label)
self.true_statement.generate(true_label, after)
def __repr__(self):
return "<IfStatement at line %d>" % self.lineno
class WhileStatement(Statement):
def __init__(self, expression, statement, lineno = -1):
self.expression = expression
self.statement = statement
self.lineno = lineno
def generate(self, before, after):
self.debug("WhileStatement.generate(before = %d, after = %d): expression = %s, statement = %s" % (before, after, self.expression, self.statement))
x = self.expression.reduce()
self.emit("iffalse %s goto L%d" % (x, after))
label = self.newlabel()
self.emitlabel(label)
self.statement.generate(label, before)
self.emit("goto L%d" % before)
def __repr__(self):
return "<WhileStatement at line %d>" % self.lineno
def eval(self,tacarray):
return tacarray.append(te)
class ReturnStatement(Statement):
def __init__(self, expression, lineno = -1):
self.expression = expression
self.lineno = lineno
def generate(self, before, after):
self.debug("ReturnStatement.generate(before = %d, after = %d): expression = %s" % (before, after, self.expression))
self.emit("return %s" % self.expression.reduce())
def __repr__(self):
return "<ReturnStatement at line %d>" % self.lineno
class AssignStatement(Statement):
def __init__(self, ident, expression, lineno = -1):
self.ident = ident
self.expression = expression
self.lineno = lineno
def generate(self, before, after):
self.debug("AssignStatement.generate(before = %d, after = %d): ident = %s, expression = %s" % (before, after, self.ident, self.expression))
self.emit("%s = %s" % (self.ident, self.expression.reduce()))
def __repr__(self):
return "<AssignStatement for %s at line %d>" % (self.ident, self.lineno)
class FunctionCall(Statement):
def __init__(self, ident, arguments = [], lineno = -1):
self.ident = ident
self.arguments = arguments
self.lineno = lineno
def generate(self):
self.debug("FunctionCall.generate(): ident = %s, arguments = %s" % (self.ident, self.arguments))
self.emit("call %s" % self.ident)
def reduce(self):
self.debug("FunctionCall.reduce(): %s" % self)
t = Temporary()
self.emit("%s = call %s%s" % (t, self.ident, self.arguments))
return t
def __repr__(self):
return "<FunctionCall for %s at line %d>" % (self.ident, self.lineno)
class Expression(Node):
def __init__(self, op, lineno = -1):
self.op = op
self.lineno = -1
def generate(self):
return self
def reduce(self):
return self
def __str__(self):
return str(self.op)
def __repr__(self):
return "<Expression at line %d>" % self.lineno
class Operation(Expression):
def __init__(self, op, lineno = -1):
super(Operation, self).__init__(op, lineno)
def reduce(self):
self.debug("Operation.reduce(): %s" % self)
x = self.generate()
t = Temporary()
self.emit("%s = %s" % (t, x))
return t
def __repr__(self):
return "<Operation at line %d>" % self.lineno
class UnaryExpression(Operation):
""" Unary expressions are !x or -x ..."""
def __init__(self, op, right, lineno = -1):
super(UnaryExpression, self).__init__(op, lineno)
self.right = right
def generate(self):
self.debug("UnaryExpression.generate(): op = %s, right = %s" % (self.op, self.right))
return UnaryExpression(self.op, self.right.reduce())
def __str__(self):
return "%s %s" % (str(self.op), str(self.right))
def __repr__(self):
return "<UnaryExpression: %s(%s) at line %d>" % (self.op, self.right, self.lineno)
class BinaryExpression(Operation):
""" Biary expression are x+y, x-y, ... """
def __init__(self, left, op, right, lineno = -1):
super(BinaryExpression, self).__init__(op, lineno)
self.left = left
self.right = right
def generate(self):
self.debug("BinaryExpression.generate(): left = %s, op = %s, right = %s" % (self.left, self.op, self.right))
return BinaryExpression(self.left.reduce(), self.op, self.right.reduce())
def __str__(self):
return "%s %s %s" % (str(self.left), str(self.op), str(self.right))
def __repr__(self):
return "<BinaryExpression: %s(%s, %s) at line %d>" % (self.op, self.left, self.right, self.lineno)
class Variable(Expression):
def __init__(self, name, lineno = -1):
super(Variable, self).__init__(name, lineno)
def __repr__(self):
return "<Variable: %s at line %d>" %(self.op, self.lineno)
class Constant(Expression):
def __init__(self, value, lineno = -1):
super(Constant, self).__init__(value, lineno)
def jumping(self, true_label, false_label):
if self.op and true_label != 0:
self.emit("goto L%d" % true_label)
elif not self.op and false_label != 0:
self.emit("goto L%d" % false_label)
def __repr__(self):
return "<Constant: %d at line %d>" %(self.op, self.lineno)
class Temporary(Expression):
count = 0
def __init__(self):
self.number = Temporary.count
Temporary.count += 1
def __str__(self):
return "t%d" % self.number