summaryrefslogblamecommitdiffstats
path: root/src/front/ast.py
blob: d6d4a3f54c7b18baf83d625178eb8d417b46d802 (plain) (tree)
1
2
3
4
5
6
7
8
9
10

                      



                    
                                               


                                  





                                              


                                               
                     
                                                              





                                    
                                                                                                                     


                                  




                             
                                                                                   





                                                



                                                       

                                
                                                            




                                    



                                                          

                                 
                                                



                                    








                                                           

                                 
                                                       




                                    






                                                                                

                              
                                                           




                                  

















                                                                                




                                  

                                               




                            



















                                                                                          

                                   

                                                     





                            































                                                                                                          















                                                                     
from back.tac import *

class Node(object):
    pass

class Program(Node):
    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

    def __repr__(self):
        return "<Program: %s>" % self.functions

class Function(Node):
    def __init__(self, name, params, statements, lineno = -1):
        self.name = name
        self.params = params
        self.statements = statements
        self.lineno = lineno

    def __repr__(self):
        return "<Function: %s(%s) at line %d: %s>" % (self.name, str(self.params), self.lineno, str(self.statements))

    def eval(self,tacarray):
        return tacarray.append(te)

class Statement(Node):
    pass

class IfStatement(Statement):
    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 "<IfStatement at line %d>" % self.lineno

    def eval(self,tacarray):
        return tacarray.append(te)

class WhileStatement(Statement):
    def __init__(self, expression, statements, lineno = -1):
        self.expression = expression
        self.statements = statements
        self.lineno = lineno

    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 __repr__(self):
        return "<ReturnStatement at line %d>" % 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 = -1):
        self.ident = ident
        self.expression = expression
        self.lineno = lineno

    def __repr__(self):
        return "<AssignStatement for %s at line %d>" % (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 = -1):
        self.ident = ident
        self.arguments = arguments
        self.lineno = lineno

    def __repr__(self):
        return "<FunctionCall for %s at line %d>" % (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):
    """ 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 "<UnaryExpression: %s(%s) at line %d>" % (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):
    """ 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 "<BinaryExpression: %s(%s, %s) at line %d>" % (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)


class Variable(Expression):
    def __init__(self, name, lineno = -1):
        self.name = name
        self.lineno = lineno

    def __repr__(self):
        return "<Variable: %s at line %d>" %(self.name, self.lineno)

class Constant(Expression):
    def __init__(self, value, lineno = -1):
        self.value = value
        self.lineno = lineno

    def __repr__(self):
        return "<Variable: %d at line %d>" %(self.value, self.lineno)