From 3bf28deef216b5e795a782165eb7878ca36e80a8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andreas=20N=C3=BC=C3=9Flein?= Date: Tue, 26 May 2009 00:07:37 +0200 Subject: tac and ast updates - added eval to ast-elems every ast-element now has a .eval-method that creates the ThreeAddressCode for said element. Also: tac-elements are stored linear in a list (, duh) --- src/back/tac.py | 72 +++++++++++++++++++----------- src/front/ast.py | 134 ++++++++++++++++++++++++++++++++++++++++++++++++------- 2 files changed, 162 insertions(+), 44 deletions(-) (limited to 'src') diff --git a/src/back/tac.py b/src/back/tac.py index 2b288f8..a875a7d 100644 --- a/src/back/tac.py +++ b/src/back/tac.py @@ -8,43 +8,61 @@ class Op(object): return self.name def __repr__(self): - return "" % self + return """""" % self +# arg1 arg2 +Op.ADD = Op("ADD") # x + y -> x y +Op.SUB = Op("SUB") # x - y -> x y +Op.MUL = Op("MUL") # x * y -> x y +Op.DIV = Op("DIV") # x / y -> x y +Op.MOD = Op("MOD") # x % y -> x y +Op.AND = Op("AND") # x AND y -> x y +Op.OR = Op("OR") # x OR y -> x y -Op.ADD = Op("ADD") # x = y + z -> y z x -Op.SUB = Op("SUB") # x = y - z -> y z x -Op.MUL = Op("MUL") # x = y * z -> y z x -Op.DIV = Op("DIV") # x = y / z -> y z x -Op.MOD = Op("MOD") # x = y % z -> y z x -Op.AND = Op("AND") # x = y AND z -> y z x -Op.OR = Op("OR") # x = y OR z -> y z x +Op.NOT = Op("NOT") # !x -> x +Op.MINUS = Op("MINUS") # -x -> x -Op.NOT = Op("NOT") # x = !y -> y None x -Op.MINUS = Op("MINUS") # x = - y -> y None x +Op.ASSIGN = Op("ASSIGN") # x = y -> x y -Op.ASSIGN = Op("ASSIGN") # x = y -> y None x +Op.JMP = Op("JMP") # "goto" x -> x +Op.BEQ = Op("EQ") # "if x == y" -> x y +Op.BNE = Op("NE") # "if x != y" -> x y +Op.BLE = Op("LE") # ... +Op.BGE = Op("GE") +Op.BLT = Op("LT") +Op.BGT = Op("GT") -Op.JMP = Op("JMP") # "goto" x -> x -Op.BEQ = Op("BEQ") # "if y == z" goto x -> y z x -Op.BNE = Op("BNE") # "if y != z" goto x -> y z x -Op.BLE = Op("BLE") # ... -Op.BGE = Op("BGE") -Op.BLT = Op("BLT") -Op.BGT = Op("BGT") +Op.PARAM = Op("PARAM") # param x -> x +Op.CALL = Op("CALL") # fun x (y-args..) -> x y +Op.RETURN = Op("RETURN") # return x -> x -Op.PARAM = Op("PARAM") # param x -> x -Op.CALL = Op("CALL") # fun y (z-args..) -> y z -Op.RETURN = Op("RETURN") # return x -> x +# maybe in the future +#Op.ARRAYGET = Op("ARRAYGET") # x = y[i] -> i +#Op.ARRAYSET = Op("ARRAYSET") # x[i] = y -> y i -Op.ARRAYGET = Op("ARRAYGET") # x = y[i] -> y i x -Op.ARRAYSET = Op("ARRAYSET") # x[i] = y -> y i x +class TacElem: -class ThreeAddressCode: - - def __init__(self,op,arg1=None,arg2=None,result=None): + def __init__(self,op,arg1=None,arg2=None): self.op = op self.arg1 = arg1 self.arg2 = arg2 - self.result = result + + def __repr__(self): + return "" % (self.op,self.arg1,self.arg2) + +class TacArray: + def __init__(self): + self.liste = [] + + def append(self,arg): + self.liste.append(arg) + return len(self.liste)-1 + + def createList(self): + i = 0 + output = "" + for item in self.liste: + print "%08d | %s\t%s\t%s" % (i,item.op,item.arg1,item.arg2) + diff --git a/src/front/ast.py b/src/front/ast.py index 26cda51..5b4def7 100644 --- a/src/front/ast.py +++ b/src/front/ast.py @@ -1,87 +1,187 @@ +from back.tac import * + class Node(object): pass class Program(Node): - def __init__(self, functions, lineno = None): + def __init__(self, functions, lineno = -1): self.functions = functions self.lineno = lineno + def eval(self,tacarray): + for function in self.functions: + function = function.eval(tacarray) + + return 0 + class Function(Node): - def __init__(self, name, params, statements, lineno = None): + def __init__(self, name, params, statements, lineno = -1): self.name = name self.params = params self.statements = statements self.lineno = lineno def __repr__(self): - return "" % (name, lineno) + return "" % (self.name, self.lineno) + + def eval(self,tacarray): + return tacarray.append(te) class Statement(Node): pass class IfStatement(Statement): - def __init__(self, expression, true_statements, false_statements, lineno = None): + def __init__(self, expression, true_statements, false_statements, lineno = -1): self.expression = expression self.true_statements = true_statements self.false_statements = false_statements self.lineno = lineno def __repr__(self): - return "" % lineno + return "" % self.lineno + + def eval(self,tacarray): + return tacarray.append(te) class WhileStatement(Statement): - def __init__(self, expression, statements, lineno = None): + def __init__(self, expression, statements, lineno = -1): self.expression = expression self.statements = statements self.lineno = lineno def __repr__(self): - return "" % lineno + return "" % self.lineno + + def eval(self,tacarray): + return tacarray.append(te) class ReturnStatement(Statement): - def __init__(self, expression, lineno = None): + def __init__(self, expression, lineno = -1): self.expression = expression self.lineno = lineno def __repr__(self): - return "" % lineno + return "" % self.lineno + + def eval(self,tacarray): + + if isinstance(expression,Node): + expression = expression.eval(tacarray) + + te = TacElem(Op.RETURN,expression) + return tacarray.append(te) class AssignStatement(Statement): - def __init__(self, ident, expression, lineno = None): + def __init__(self, ident, expression, lineno = -1): self.ident = ident self.expression = expression self.lineno = lineno def __repr__(self): - return "" % (ident, lineno) + return "" % (self.ident, self.lineno) + + def eval(self,tacarray): + if isinstance(expression,Node): + expression = expression.eval(tacarray) + yield self.expression + class FunctionCall(Statement): - def __init__(self, ident, arguments, lineno = None): + def __init__(self, ident, arguments = [], lineno = -1): self.ident = ident self.arguments = arguments self.lineno = lineno def __repr__(self): - return "" % (ident, lineno) + return "" % (self.ident, self.lineno) + + def eval(self,tacarray): + """ Function call will be seperated in all the Op.PARAMs first, and the + Op.CALL afterwards""" + + # XXX can there be arguments with multiple expressions bla((x+y-3),z)? + # -> have to look into that, when it comes to param-number + # for every parameter create a TacElem + #for argument in self.arguments: + # if isinstance(argument,Node): + # argument = argument.eval(tacarray) + # TacElem(Op.PARAM,argument) + + # in the end create the CALL-TacElem with the number of parameters + te = TacElem(Op.CALL,self.ident,len(self.arguments)) + return tacarray.append(te) + class Expression(Node): pass class UnaryExpression(Expression): - def __init__(self, op, right, lineno = None): + """ Unary expressions are !x or -x ...""" + def __init__(self, op, right, lineno = -1): self.op = op self.right = right self.lineno = lineno def __repr__(self): - return "" % (op, right, lineno) + return "" % (self.op, self.right, self.lineno) + + def eval(self,tacarray): + right = self.right + op = None + + if (self.op == "not"): + op = Op.NOT + if (self.op == "minus"): + op = Op.MINUS + + if op == None: + return None + + if isinstance(right,Node): + right = right.eval(tacarray) + + te = TacElem(op,right) + return tacarray.append(te) + class BinaryExpression(Expression): - def __init__(self, left, op, right, lineno = None): + """ Biary expression are x+y, x-y, ... """ + def __init__(self, left, op, right, lineno = -1): self.left = left self.op = op self.right = right self.lineno = lineno def __repr__(self): - return "" % (op, left, right, lineno) + return "" % (self.op, self.left, self.right, self.lineno) + + + def eval(self,tacarray): + op = None + if (self.op == "+"): + op = Op.ADD + if (self.op == "-"): + op = Op.SUB + if (self.op == "*"): + op= Op.MUL + if (self.op == "/"): + op= Op.DIV + if (self.op == "%"): + op= Op.MOD + if (self.op == "and"): + op= Op.AND + if (self.op == "or"): + op= Op.OR + + if op == None: + return None + + if isinstance(left,Node): + left = left.eval(tacarray) + + if isinstance(right,Node): + right = right.eval(tacarray) + + te = TacElem(op,left,right) + return tacarray.append(te) + -- cgit v1.2.3