summaryrefslogtreecommitdiffstats
path: root/src/front/ast.py
blob: 5b4def74925472c5048b572441bf17b0d20c0ce1 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
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

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 at line %d>" % (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 = -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)