16657SN/A# Copyright (c) 1999-2008 Mark D. Hill and David A. Wood 26657SN/A# Copyright (c) 2009 The Hewlett-Packard Development Company 36657SN/A# All rights reserved. 46657SN/A# 56657SN/A# Redistribution and use in source and binary forms, with or without 66657SN/A# modification, are permitted provided that the following conditions are 76657SN/A# met: redistributions of source code must retain the above copyright 86657SN/A# notice, this list of conditions and the following disclaimer; 96657SN/A# redistributions in binary form must reproduce the above copyright 106657SN/A# notice, this list of conditions and the following disclaimer in the 116657SN/A# documentation and/or other materials provided with the distribution; 126657SN/A# neither the name of the copyright holders nor the names of its 136657SN/A# contributors may be used to endorse or promote products derived from 146657SN/A# this software without specific prior written permission. 156657SN/A# 166657SN/A# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 176657SN/A# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 186657SN/A# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 196657SN/A# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 206657SN/A# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 216657SN/A# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 226657SN/A# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 236657SN/A# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 246657SN/A# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 256657SN/A# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 266657SN/A# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 276657SN/A 286657SN/Afrom slicc.ast.ExprAST import ExprAST 296657SN/Afrom slicc.symbols import Type 306657SN/A 316657SN/Aclass InfixOperatorExprAST(ExprAST): 326657SN/A def __init__(self, slicc, left, op, right): 336657SN/A super(InfixOperatorExprAST, self).__init__(slicc) 346657SN/A 356657SN/A self.left = left 366657SN/A self.op = op 376657SN/A self.right = right 386657SN/A 396657SN/A def __repr__(self): 406657SN/A return "[InfixExpr: %r %s %r]" % (self.left, self.op, self.right) 416657SN/A 426657SN/A def generate(self, code): 436999SN/A lcode = self.slicc.codeFormatter() 446999SN/A rcode = self.slicc.codeFormatter() 456657SN/A 466657SN/A ltype = self.left.generate(lcode) 476657SN/A rtype = self.right.generate(rcode) 486657SN/A 496657SN/A # Figure out what the input and output types should be 509499SN/A if self.op in ("==", "!=", ">=", "<=", ">", "<"): 516657SN/A output = "bool" 526657SN/A if (ltype != rtype): 536657SN/A self.error("Type mismatch: left and right operands of " + 546657SN/A "operator '%s' must be the same type. " + 556657SN/A "left: '%s', right: '%s'", 566657SN/A self.op, ltype, rtype) 576657SN/A else: 589499SN/A expected_types = [] 599499SN/A output = None 609499SN/A 616657SN/A if self.op in ("&&", "||"): 626657SN/A # boolean inputs and output 639499SN/A expected_types = [("bool", "bool", "bool")] 649499SN/A elif self.op in ("<<", ">>"): 659499SN/A expected_types = [("int", "int", "int"), 669499SN/A ("Cycles", "int", "Cycles")] 679499SN/A elif self.op in ("+", "-", "*", "/"): 689499SN/A expected_types = [("int", "int", "int"), 699499SN/A ("Cycles", "Cycles", "Cycles"), 7011016Snilay@cs.wisc.edu ("Tick", "Tick", "Tick"), 719499SN/A ("Cycles", "int", "Cycles"), 729692Snilay@cs.wisc.edu ("Scalar", "int", "Scalar"), 7310521Snilay@cs.wisc.edu ("int", "bool", "int"), 7410521Snilay@cs.wisc.edu ("bool", "int", "int"), 759499SN/A ("int", "Cycles", "Cycles")] 766657SN/A else: 779499SN/A self.error("No operator matched with {0}!" .format(self.op)) 786657SN/A 799499SN/A for expected_type in expected_types: 809499SN/A left_input_type = self.symtab.find(expected_type[0], Type) 819499SN/A right_input_type = self.symtab.find(expected_type[1], Type) 826657SN/A 839499SN/A if (left_input_type == ltype) and (right_input_type == rtype): 849499SN/A output = expected_type[2] 856657SN/A 869499SN/A if output == None: 879499SN/A self.error("Type mismatch: operands ({0}, {1}) for operator " \ 889499SN/A "'{2}' failed to match with the expected types" . 899499SN/A format(ltype, rtype, self.op)) 906657SN/A 916657SN/A # All is well 926657SN/A fix = code.nofix() 936657SN/A code("($lcode ${{self.op}} $rcode)") 946657SN/A code.fix(fix) 956657SN/A return self.symtab.find(output, Type) 969692Snilay@cs.wisc.edu 979692Snilay@cs.wisc.educlass PrefixOperatorExprAST(ExprAST): 989692Snilay@cs.wisc.edu def __init__(self, slicc, op, operand): 999692Snilay@cs.wisc.edu super(PrefixOperatorExprAST, self).__init__(slicc) 1009692Snilay@cs.wisc.edu 1019692Snilay@cs.wisc.edu self.op = op 1029692Snilay@cs.wisc.edu self.operand = operand 1039692Snilay@cs.wisc.edu 1049692Snilay@cs.wisc.edu def __repr__(self): 1059692Snilay@cs.wisc.edu return "[PrefixExpr: %s %r]" % (self.op, self.operand) 1069692Snilay@cs.wisc.edu 1079692Snilay@cs.wisc.edu def generate(self, code): 1089692Snilay@cs.wisc.edu opcode = self.slicc.codeFormatter() 1099692Snilay@cs.wisc.edu optype = self.operand.generate(opcode) 1109692Snilay@cs.wisc.edu 11110965Sdavid.hashe@amd.com # Figure out what the input and output types should be 11210965Sdavid.hashe@amd.com opmap = {"!": "bool", "-": "int", "++": "Scalar"} 11310965Sdavid.hashe@amd.com if self.op in opmap: 11410965Sdavid.hashe@amd.com output = opmap[self.op] 11510965Sdavid.hashe@amd.com type_in_symtab = self.symtab.find(opmap[self.op], Type) 11610965Sdavid.hashe@amd.com if (optype != type_in_symtab): 11710965Sdavid.hashe@amd.com self.error("Type mismatch: right operand of " + 11810965Sdavid.hashe@amd.com "unary operator '%s' must be of type '%s'. ", 11910965Sdavid.hashe@amd.com self.op, type_in_symtab) 12010965Sdavid.hashe@amd.com else: 12110965Sdavid.hashe@amd.com self.error("Invalid prefix operator '%s'", 12210965Sdavid.hashe@amd.com self.op) 12310965Sdavid.hashe@amd.com 12410965Sdavid.hashe@amd.com # All is well 1259692Snilay@cs.wisc.edu fix = code.nofix() 1269692Snilay@cs.wisc.edu code("(${{self.op}} $opcode)") 1279692Snilay@cs.wisc.edu code.fix(fix) 1289692Snilay@cs.wisc.edu 12910965Sdavid.hashe@amd.com return self.symtab.find(output, Type) 130