diff options
Diffstat (limited to 'src/mem/slicc/ast/OperatorExprAST.py')
-rw-r--r-- | src/mem/slicc/ast/OperatorExprAST.py | 112 |
1 files changed, 112 insertions, 0 deletions
diff --git a/src/mem/slicc/ast/OperatorExprAST.py b/src/mem/slicc/ast/OperatorExprAST.py new file mode 100644 index 000000000..df074b9f0 --- /dev/null +++ b/src/mem/slicc/ast/OperatorExprAST.py @@ -0,0 +1,112 @@ +# Copyright (c) 1999-2008 Mark D. Hill and David A. Wood +# Copyright (c) 2009 The Hewlett-Packard Development Company +# All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions are +# met: redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer; +# redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in the +# documentation and/or other materials provided with the distribution; +# neither the name of the copyright holders nor the names of its +# contributors may be used to endorse or promote products derived from +# this software without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +from slicc.ast.ExprAST import ExprAST +from slicc.symbols import Type + +class InfixOperatorExprAST(ExprAST): + def __init__(self, slicc, left, op, right): + super(InfixOperatorExprAST, self).__init__(slicc) + + self.left = left + self.op = op + self.right = right + + def __repr__(self): + return "[InfixExpr: %r %s %r]" % (self.left, self.op, self.right) + + def generate(self, code): + lcode = self.slicc.codeFormatter() + rcode = self.slicc.codeFormatter() + + ltype = self.left.generate(lcode) + rtype = self.right.generate(rcode) + + # Figure out what the input and output types should be + if self.op in ("==", "!=", ">=", "<=", ">", "<"): + output = "bool" + if (ltype != rtype): + self.error("Type mismatch: left and right operands of " + + "operator '%s' must be the same type. " + + "left: '%s', right: '%s'", + self.op, ltype, rtype) + else: + expected_types = [] + output = None + + if self.op in ("&&", "||"): + # boolean inputs and output + expected_types = [("bool", "bool", "bool")] + elif self.op in ("<<", ">>"): + expected_types = [("int", "int", "int"), + ("Cycles", "int", "Cycles")] + elif self.op in ("+", "-", "*", "/"): + expected_types = [("int", "int", "int"), + ("Cycles", "Cycles", "Cycles"), + ("Cycles", "int", "Cycles"), + ("Scalar", "int", "Scalar"), + ("int", "Cycles", "Cycles")] + else: + self.error("No operator matched with {0}!" .format(self.op)) + + for expected_type in expected_types: + left_input_type = self.symtab.find(expected_type[0], Type) + right_input_type = self.symtab.find(expected_type[1], Type) + + if (left_input_type == ltype) and (right_input_type == rtype): + output = expected_type[2] + + if output == None: + self.error("Type mismatch: operands ({0}, {1}) for operator " \ + "'{2}' failed to match with the expected types" . + format(ltype, rtype, self.op)) + + # All is well + fix = code.nofix() + code("($lcode ${{self.op}} $rcode)") + code.fix(fix) + return self.symtab.find(output, Type) + +class PrefixOperatorExprAST(ExprAST): + def __init__(self, slicc, op, operand): + super(PrefixOperatorExprAST, self).__init__(slicc) + + self.op = op + self.operand = operand + + def __repr__(self): + return "[PrefixExpr: %s %r]" % (self.op, self.operand) + + def generate(self, code): + opcode = self.slicc.codeFormatter() + optype = self.operand.generate(opcode) + + fix = code.nofix() + code("(${{self.op}} $opcode)") + code.fix(fix) + + return self.symtab.find("void", Type) |