summaryrefslogtreecommitdiffstats
path: root/src/front/ast.py
diff options
context:
space:
mode:
Diffstat (limited to 'src/front/ast.py')
-rw-r--r--src/front/ast.py121
1 files changed, 78 insertions, 43 deletions
diff --git a/src/front/ast.py b/src/front/ast.py
index f221440..99ccbee 100644
--- a/src/front/ast.py
+++ b/src/front/ast.py
@@ -1,4 +1,5 @@
from back.tac import *
+from back.generator import Register
import sys
class Node(object):
@@ -9,12 +10,14 @@ class Node(object):
return Node.labels
def emitlabel(self, i):
- sys.stdout.write("L" + str(i) + ":")
- sys.stdout.flush()
+ TACList().add(Label("L%d" % i))
- def emit(self, s):
- sys.stdout.write("\t" + s + "\n")
- sys.stdout.flush()
+ def emitfunction(self, name):
+ TACList().add(FunctionLabel(name))
+
+ def emit(self, op, arg1=None, arg2=None):
+ self.debug("emit(): op = %s, arg = %s, arg2 = %s" % (op, arg1, arg2))
+ TACList().add(TAC(op, arg1, arg2))
def debug(self, msg):
#sys.stdout.write("DEBUG: " + msg + "\n")
@@ -43,13 +46,13 @@ class Function(Node):
def generate(self):
self.debug("Function.generate(): name = %s, params = %s, statement = %s" % (self.name, self.params, self.statement))
- print "%s:" % self.name
+ self.emitfunction(self.name)
begin = self.newlabel()
after = self.newlabel()
self.emitlabel(begin)
self.statement.generate(begin, after)
self.emitlabel(after)
- print
+ self.emit(Op.RETURN, 0)
def __repr__(self):
return "<Function: %s(%s) at line %d: %s>" % (self.name, str(self.params), self.lineno, str(self.statement))
@@ -93,15 +96,15 @@ class IfStatement(Statement):
if self.false_statement:
true_label = self.newlabel()
false_label = self.newlabel()
- self.emit("iffalse %s goto L%d" % (x, false_label))
+ self.emit(Op.BEQ, x, "L%d" % false_label)
self.emitlabel(true_label)
self.true_statement.generate(true_label, after)
- self.emit("goto L%d" % after)
+ self.emit(Op.JMP, "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.emit(Op.BEQ, x, "L%d" % after)
self.emitlabel(true_label)
self.true_statement.generate(true_label, after)
@@ -116,19 +119,15 @@ class WhileStatement(Statement):
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))
+ self.emit(Op.BEQ, self.expression.reduce(), "L%d" % after)
label = self.newlabel()
self.emitlabel(label)
self.statement.generate(label, before)
- self.emit("goto L%d" % before)
+ self.emit(Op.JMP, "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
@@ -136,7 +135,7 @@ class ReturnStatement(Statement):
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())
+ self.emit(Op.RETURN, self.expression.reduce())
def __repr__(self):
return "<ReturnStatement at line %d>" % self.lineno
@@ -149,7 +148,7 @@ class AssignStatement(Statement):
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()))
+ self.emit(Op.STORE, self.ident, self.expression.reduce())
def __repr__(self):
return "<AssignStatement for %s at line %d>" % (self.ident, self.lineno)
@@ -162,13 +161,17 @@ class FunctionCall(Statement):
def generate(self):
self.debug("FunctionCall.generate(): ident = %s, arguments = %s" % (self.ident, self.arguments))
- self.emit("call %s" % self.ident)
+ for argument in self.arguments:
+ self.emit(Op.PARAM, argument.reduce())
+ self.emit(Op.CALL, self.ident, len(self.arguments))
def reduce(self):
self.debug("FunctionCall.reduce(): %s" % self)
- t = Temporary()
- self.emit("%s = call %s%s" % (t, self.ident, self.arguments))
- return t
+ for argument in self.arguments:
+ self.emit(Op.PARAM, argument.reduce())
+ r = Register().new()
+ self.emit(Op.CALL, self.ident, r)
+ return r
def __repr__(self):
return "<FunctionCall for %s at line %d>" % (self.ident, self.lineno)
@@ -178,12 +181,6 @@ class Expression(Node):
self.op = op
self.lineno = -1
- def generate(self):
- return self
-
- def reduce(self):
- return self
-
def __str__(self):
return str(self.op)
@@ -194,13 +191,6 @@ 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
@@ -210,9 +200,15 @@ class UnaryExpression(Operation):
super(UnaryExpression, self).__init__(op, lineno)
self.right = right
- def generate(self):
+ def reduce(self):
self.debug("UnaryExpression.generate(): op = %s, right = %s" % (self.op, self.right))
- return UnaryExpression(self.op, self.right.reduce())
+ op = {
+ "!": Op.NOT,
+ "-": Op.MINUS,
+ }[self.op]
+ r = self.right.reduce()
+ self.emit(op, r)
+ return r
def __str__(self):
return "%s %s" % (str(self.op), str(self.right))
@@ -227,9 +223,36 @@ class BinaryExpression(Operation):
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 reduce(self):
+ self.debug("BinaryExpression.reduce(): left = %s, op = %s, right = %s" % (self.left, self.op, self.right))
+ arith_op = {
+ "+": Op.ADD,
+ "-": Op.SUB,
+ "*": Op.MUL,
+ "/": Op.DIV,
+ "%": Op.MOD,
+ }
+
+ logic_op = {
+ "==": Op.EQ,
+ "!=": Op.NE,
+ "<": Op.LT,
+ "<=": Op.LE,
+ ">=": Op.GE,
+ ">": Op.GT,
+ }
+
+ try:
+ op = arith_op[self.op]
+ r = self.left.reduce()
+ self.emit(op, r, self.right.reduce())
+ except KeyError:
+ op = logic_op[self.op]
+ r = Register().new()
+ self.emit(Op.CMP, self.left.reduce(), self.right.reduce())
+ self.emit(op, r)
+
+ return r
def __str__(self):
return "%s %s %s" % (str(self.left), str(self.op), str(self.right))
@@ -241,6 +264,12 @@ class Variable(Expression):
def __init__(self, name, lineno = -1):
super(Variable, self).__init__(name, lineno)
+ def reduce(self):
+ self.debug("Variable.reduce(): name = %s" % self.op)
+ r = Register().new()
+ self.emit(Op.LOAD, self.op, r)
+ return r
+
def __repr__(self):
return "<Variable: %s at line %d>" %(self.op, self.lineno)
@@ -250,9 +279,15 @@ class Constant(Expression):
def jumping(self, true_label, false_label):
if self.op and true_label != 0:
- self.emit("goto L%d" % true_label)
+ self.emit(Op.JMP, "L%d" % true_label)
elif not self.op and false_label != 0:
- self.emit("goto L%d" % false_label)
+ self.emit(Op.JMP, "L%d" % false_label)
+
+ def reduce(self):
+ self.debug("Constant.reduce(): value = %s" % self.op)
+ r = Register().new()
+ self.emit(Op.MOV, r, self.op)
+ return r
def __repr__(self):
return "<Constant: %d at line %d>" %(self.op, self.lineno)
@@ -265,4 +300,4 @@ class Temporary(Expression):
Temporary.count += 1
def __str__(self):
- return "t%d" % self.number
+ return "r%d" % self.number