MethodCallExprAST.py revision 6657
16657Snate@binkert.org# Copyright (c) 1999-2008 Mark D. Hill and David A. Wood 26657Snate@binkert.org# Copyright (c) 2009 The Hewlett-Packard Development Company 36657Snate@binkert.org# All rights reserved. 46657Snate@binkert.org# 56657Snate@binkert.org# Redistribution and use in source and binary forms, with or without 66657Snate@binkert.org# modification, are permitted provided that the following conditions are 76657Snate@binkert.org# met: redistributions of source code must retain the above copyright 86657Snate@binkert.org# notice, this list of conditions and the following disclaimer; 96657Snate@binkert.org# redistributions in binary form must reproduce the above copyright 106657Snate@binkert.org# notice, this list of conditions and the following disclaimer in the 116657Snate@binkert.org# documentation and/or other materials provided with the distribution; 126657Snate@binkert.org# neither the name of the copyright holders nor the names of its 136657Snate@binkert.org# contributors may be used to endorse or promote products derived from 146657Snate@binkert.org# this software without specific prior written permission. 156657Snate@binkert.org# 166657Snate@binkert.org# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 176657Snate@binkert.org# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 186657Snate@binkert.org# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 196657Snate@binkert.org# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 206657Snate@binkert.org# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 216657Snate@binkert.org# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 226657Snate@binkert.org# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 236657Snate@binkert.org# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 246657Snate@binkert.org# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 256657Snate@binkert.org# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 266657Snate@binkert.org# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 276657Snate@binkert.org 286657Snate@binkert.orgfrom m5.util import code_formatter 296657Snate@binkert.org 306657Snate@binkert.orgfrom slicc.ast.ExprAST import ExprAST 316657Snate@binkert.org 326657Snate@binkert.orgclass MethodCallExprAST(ExprAST): 336657Snate@binkert.org def __init__(self, slicc, proc_name, expr_ast_vec): 346657Snate@binkert.org super(MethodCallExprAST, self).__init__(slicc) 356657Snate@binkert.org self.proc_name = proc_name 366657Snate@binkert.org self.expr_ast_vec = expr_ast_vec 376657Snate@binkert.org 386657Snate@binkert.org def generate(self, code): 396657Snate@binkert.org tmp = code_formatter() 406657Snate@binkert.org paramTypes = [] 416657Snate@binkert.org for expr_ast in self.expr_ast_vec: 426657Snate@binkert.org return_type = expr_ast.generate(tmp) 436657Snate@binkert.org paramTypes.append(return_type) 446657Snate@binkert.org 456657Snate@binkert.org obj_type, methodId, prefix = self.generate_prefix(paramTypes) 466657Snate@binkert.org 476657Snate@binkert.org # generate code 486657Snate@binkert.org params = [] 496657Snate@binkert.org for expr_ast in self.expr_ast_vec: 506657Snate@binkert.org return_type,tcode = expr_ast.inline(True) 516657Snate@binkert.org params.append(str(tcode)) 526657Snate@binkert.org fix = code.nofix() 536657Snate@binkert.org code("$prefix${{self.proc_name}}(${{', '.join(params)}}))") 546657Snate@binkert.org code.fix(fix) 556657Snate@binkert.org 566657Snate@binkert.org # Verify that this is a method of the object 576657Snate@binkert.org if methodId not in obj_type.methods: 586657Snate@binkert.org error("Invalid method call: Type '%s' does not have a method '%s'", 596657Snate@binkert.org obj_type, methodId) 606657Snate@binkert.org 616657Snate@binkert.org if len(self.expr_ast_vec) != \ 626657Snate@binkert.org len(obj_type.methods[methodId].param_types): 636657Snate@binkert.org # Right number of parameters 646657Snate@binkert.org error("Wrong number of parameters for function name: '%s', " + \ 656657Snate@binkert.org "expected: , actual: ", proc_name, 666657Snate@binkert.org len(obj_type.methods[methodId].param_types), 676657Snate@binkert.org len(self.expr_ast_vec)) 686657Snate@binkert.org 696657Snate@binkert.org for actual_type, expected_type in \ 706657Snate@binkert.org zip(paramTypes, obj_type.methods[methodId].param_types): 716657Snate@binkert.org if actual_type != expected_type: 726657Snate@binkert.org error("Type mismatch: expected: %s actual: %s", 736657Snate@binkert.org expected_type, actual_type) 746657Snate@binkert.org 756657Snate@binkert.org # Return the return type of the method 766657Snate@binkert.org return obj_type.methods[methodId].return_type 776657Snate@binkert.org 786657Snate@binkert.org def findResources(self, resources): 796657Snate@binkert.org pass 806657Snate@binkert.org 816657Snate@binkert.orgclass MemberMethodCallExprAST(MethodCallExprAST): 826657Snate@binkert.org def __init__(self, slicc, obj_expr_ast, proc_name, expr_ast_vec): 836657Snate@binkert.org s = super(MemberMethodCallExprAST, self) 846657Snate@binkert.org s.__init__(slicc, proc_name, expr_ast_vec) 856657Snate@binkert.org 866657Snate@binkert.org self.obj_expr_ast = obj_expr_ast 876657Snate@binkert.org 886657Snate@binkert.org def __repr__(self): 896657Snate@binkert.org return "[MethodCallExpr: %r%r %r]" % (self.proc_name, 906657Snate@binkert.org self.obj_expr_ast, 916657Snate@binkert.org self.expr_ast_vec) 926657Snate@binkert.org def generate_prefix(self, paramTypes): 936657Snate@binkert.org code = code_formatter() 946657Snate@binkert.org 956657Snate@binkert.org # member method call 966657Snate@binkert.org obj_type = self.obj_expr_ast.generate(code) 976657Snate@binkert.org methodId = obj_type.methodId(self.proc_name, paramTypes) 986657Snate@binkert.org 996657Snate@binkert.org prefix = "" 1006657Snate@binkert.org return_type = obj_type.methods[methodId].return_type 1016657Snate@binkert.org if return_type.isInterface: 1026657Snate@binkert.org prefix = "static_cast<%s &>" % return_type.c_ident 1036657Snate@binkert.org prefix = "%s((%s)." % (prefix, code) 1046657Snate@binkert.org 1056657Snate@binkert.org return obj_type, methodId, prefix 1066657Snate@binkert.org 1076657Snate@binkert.org 1086657Snate@binkert.orgclass ClassMethodCallExprAST(MethodCallExprAST): 1096657Snate@binkert.org def __init__(self, slicc, type_ast, proc_name, expr_ast_vec): 1106657Snate@binkert.org s = super(ClassMethodCallExprAST, self) 1116657Snate@binkert.org s.__init__(slicc, proc_name, expr_ast_vec) 1126657Snate@binkert.org 1136657Snate@binkert.org self.type_ast = type_ast 1146657Snate@binkert.org 1156657Snate@binkert.org def __repr__(self): 1166657Snate@binkert.org return "[MethodCallExpr: %r %r]" % (self.proc_name, self.expr_ast_vec) 1176657Snate@binkert.org 1186657Snate@binkert.org def generate_prefix(self, paramTypes): 1196657Snate@binkert.org 1206657Snate@binkert.org # class method call 1216657Snate@binkert.org prefix = "(%s::" % self.type_ast 1226657Snate@binkert.org obj_type = self.type_ast.type 1236657Snate@binkert.org methodId = obj_type.methodId(self.proc_name, paramTypes) 1246657Snate@binkert.org 1256657Snate@binkert.org return obj_type, methodId, prefix 1266657Snate@binkert.org 1276657Snate@binkert.org__all__ = [ "MemberMethodCallExprAST", "ClassMethodCallExprAST" ] 128