OperatorExprAST.py revision 9499
1# Copyright (c) 1999-2008 Mark D. Hill and David A. Wood 2# Copyright (c) 2009 The Hewlett-Packard Development Company 3# All rights reserved. 4# 5# Redistribution and use in source and binary forms, with or without 6# modification, are permitted provided that the following conditions are 7# met: redistributions of source code must retain the above copyright 8# notice, this list of conditions and the following disclaimer; 9# redistributions in binary form must reproduce the above copyright 10# notice, this list of conditions and the following disclaimer in the 11# documentation and/or other materials provided with the distribution; 12# neither the name of the copyright holders nor the names of its 13# contributors may be used to endorse or promote products derived from 14# this software without specific prior written permission. 15# 16# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 17# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 18# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 19# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 20# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 21# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 22# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 23# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 24# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 25# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 26# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 27 28from slicc.ast.ExprAST import ExprAST 29from slicc.symbols import Type 30 31class InfixOperatorExprAST(ExprAST): 32 def __init__(self, slicc, left, op, right): 33 super(InfixOperatorExprAST, self).__init__(slicc) 34 35 self.left = left 36 self.op = op 37 self.right = right 38 39 def __repr__(self): 40 return "[InfixExpr: %r %s %r]" % (self.left, self.op, self.right) 41 42 def generate(self, code): 43 lcode = self.slicc.codeFormatter() 44 rcode = self.slicc.codeFormatter() 45 46 ltype = self.left.generate(lcode) 47 rtype = self.right.generate(rcode) 48 49 # Figure out what the input and output types should be 50 if self.op in ("==", "!=", ">=", "<=", ">", "<"): 51 output = "bool" 52 if (ltype != rtype): 53 self.error("Type mismatch: left and right operands of " + 54 "operator '%s' must be the same type. " + 55 "left: '%s', right: '%s'", 56 self.op, ltype, rtype) 57 else: 58 expected_types = [] 59 output = None 60 61 if self.op in ("&&", "||"): 62 # boolean inputs and output 63 expected_types = [("bool", "bool", "bool")] 64 elif self.op in ("<<", ">>"): 65 expected_types = [("int", "int", "int"), 66 ("Cycles", "int", "Cycles")] 67 elif self.op in ("+", "-", "*", "/"): 68 expected_types = [("int", "int", "int"), 69 ("Time", "Time", "Time"), 70 ("Cycles", "Cycles", "Cycles"), 71 ("Cycles", "int", "Cycles"), 72 ("int", "Cycles", "Cycles")] 73 else: 74 self.error("No operator matched with {0}!" .format(self.op)) 75 76 for expected_type in expected_types: 77 left_input_type = self.symtab.find(expected_type[0], Type) 78 right_input_type = self.symtab.find(expected_type[1], Type) 79 80 if (left_input_type == ltype) and (right_input_type == rtype): 81 output = expected_type[2] 82 83 if output == None: 84 self.error("Type mismatch: operands ({0}, {1}) for operator " \ 85 "'{2}' failed to match with the expected types" . 86 format(ltype, rtype, self.op)) 87 88 # All is well 89 fix = code.nofix() 90 code("($lcode ${{self.op}} $rcode)") 91 code.fix(fix) 92 return self.symtab.find(output, Type) 93