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.py67
1 files changed, 42 insertions, 25 deletions
diff --git a/src/front/ast.py b/src/front/ast.py
index b05f7fb..875bdf0 100644
--- a/src/front/ast.py
+++ b/src/front/ast.py
@@ -12,9 +12,6 @@ class Node(object):
def emitlabel(self, i):
TACList().add(Label("L%d" % i))
- 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))
@@ -31,6 +28,7 @@ class Program(Node):
def generate(self):
self.debug("Program.generate(): %s" % repr(self))
+ self.emit(Op.JMP, "main")
for function in self.functions:
function.generate()
@@ -44,15 +42,23 @@ class Function(Node):
self.statement = statement
self.lineno = lineno
+ def emit_prologue(self, name):
+ TACList().add(FunctionPrologue(name))
+
+ def emit_epilogue(self, name):
+ TACList().add(FunctionEpilogue(name))
+
def generate(self):
self.debug("Function.generate(): %s" % repr(self))
- self.emitfunction(self.name)
+ self.emit_prologue(self.name)
+ Register().set_function(self.name)
begin = self.newlabel()
after = self.newlabel()
self.emitlabel(begin)
- self.statement.generate(begin, after)
+ self.statement.generate(begin, after, after)
+ self.emit(Op.RETURN, 0, after)
self.emitlabel(after)
- self.emit(Op.RETURN, 0)
+ self.emit_epilogue(self.name)
def __repr__(self):
return "<Function: %s(%s) at line %d: %s>" % (self.name, str(self.params), self.lineno, str(self.statement))
@@ -69,17 +75,17 @@ class Sequence(Statement):
self.s2 = s2
self.lineno = lineno
- def generate(self, before, after):
+ def generate(self, before, after, last):
self.debug("Sequence.generate(before = %d, after = %d): %s" % (before, after, repr(self)))
if not self.s1:
- self.s2.generate(before, after)
+ self.s2.generate(before, after, last)
elif not self.s2:
- self.s1.generate(before, after)
+ self.s1.generate(before, after, last)
else:
label = self.newlabel()
- self.s1.generate(before, label)
+ self.s1.generate(before, label, last)
self.emitlabel(label)
- self.s2.generate(label, after)
+ self.s2.generate(label, after, last)
def __repr__(self):
return "<Sequence at line %d: %s, %s>" % (self.lineno, self.s1, self.s2)
@@ -91,7 +97,7 @@ class IfStatement(Statement):
self.false_statement = false_statement
self.lineno = lineno
- def generate(self, before, after):
+ def generate(self, before, after, last):
self.debug("IfStatement.generate(before = %d, after = %d): %s" % (before, after, repr(self)))
x = self.expression.reduce()
@@ -101,15 +107,15 @@ class IfStatement(Statement):
false_label = self.newlabel()
self.emit(Op.BEZ, x, "L%d" % false_label)
self.emitlabel(true_label)
- self.true_statement.generate(true_label, after)
+ self.true_statement.generate(true_label, after, last)
self.emit(Op.JMP, "L%d" % after)
self.emitlabel(false_label)
- self.false_statement.generate(false_label, after)
+ self.false_statement.generate(false_label, after, last)
else:
true_label = self.newlabel()
self.emit(Op.BEZ, x, "L%d" % after)
self.emitlabel(true_label)
- self.true_statement.generate(true_label, after)
+ self.true_statement.generate(true_label, after, last)
def __repr__(self):
return "<IfStatement at line %d>" % self.lineno
@@ -120,12 +126,12 @@ class WhileStatement(Statement):
self.statement = statement
self.lineno = lineno
- def generate(self, before, after):
+ def generate(self, before, after, last):
self.debug("WhileStatement.generate(before = %d, after = %d): %s" % (before, after, repr(self)))
self.emit(Op.BEZ, self.expression.reduce(), "L%d" % after)
label = self.newlabel()
self.emitlabel(label)
- self.statement.generate(label, before)
+ self.statement.generate(label, before, last)
self.emit(Op.JMP, "L%d" % before)
def __repr__(self):
@@ -136,9 +142,9 @@ class ReturnStatement(Statement):
self.expression = expression
self.lineno = lineno
- def generate(self, before, after):
+ def generate(self, before, after, last):
self.debug("ReturnStatement.generate(before = %d, after = %d): %s" % (before, after, repr(self)))
- self.emit(Op.RETURN, self.expression.reduce())
+ self.emit(Op.RETURN, self.expression.reduce(), last)
def __repr__(self):
return "<ReturnStatement at line %d>" % self.lineno
@@ -149,7 +155,7 @@ class AssignStatement(Statement):
self.expression = expression
self.lineno = lineno
- def generate(self, before, after):
+ def generate(self, before, after, last):
self.debug("AssignStatement.generate(before = %d, after = %d): %s" % (before, after, repr(self)))
self.emit(Op.STORE, self.ident, self.expression.reduce())
@@ -162,22 +168,33 @@ class FunctionCall(Statement, Expression):
self.arguments = arguments
self.lineno = lineno
+ def push_params(self):
+ self.arguments.reverse()
+ for argument in self.arguments:
+ self.emit(Op.PUSH, argument.reduce())
+ self.arguments.reverse()
+
+ def pop_params(self):
+ for argument in self.arguments:
+ self.emit(Op.POP, 0)
+
+ # XXX: wrong signature?
def generate(self):
self.debug("FunctionCall.generate(): %s" % (repr(self)))
- for argument in self.arguments:
- self.emit(Op.PARAM, argument.reduce())
+ self.push_params()
self.emit(Op.CALL, self.ident, 0)
+ self.pop_params()
def reduce(self):
self.debug("FunctionCall.reduce(): %s" % repr(self))
- for argument in self.arguments:
- self.emit(Op.PARAM, argument.reduce())
+ self.push_params()
r = Register().new()
self.emit(Op.CALL, self.ident, r)
+ self.pop_params()
return r
def __repr__(self):
- return "<FunctionCall for %s at line %d>" % (self.ident, self.lineno)
+ return "<FunctionCall for %s(%s) at line %d>" % (self.ident, self.arguments, self.lineno)
class Operation(Expression):
def __init__(self, op, lineno = -1):