MethodCallExprAST.py revision 6657:ef5fae93a3b2
13101Sstever@eecs.umich.edu# Copyright (c) 1999-2008 Mark D. Hill and David A. Wood 23101Sstever@eecs.umich.edu# Copyright (c) 2009 The Hewlett-Packard Development Company 33101Sstever@eecs.umich.edu# All rights reserved. 43101Sstever@eecs.umich.edu# 53101Sstever@eecs.umich.edu# Redistribution and use in source and binary forms, with or without 63101Sstever@eecs.umich.edu# modification, are permitted provided that the following conditions are 73101Sstever@eecs.umich.edu# met: redistributions of source code must retain the above copyright 83101Sstever@eecs.umich.edu# notice, this list of conditions and the following disclaimer; 93101Sstever@eecs.umich.edu# redistributions in binary form must reproduce the above copyright 103101Sstever@eecs.umich.edu# notice, this list of conditions and the following disclaimer in the 113101Sstever@eecs.umich.edu# documentation and/or other materials provided with the distribution; 123101Sstever@eecs.umich.edu# neither the name of the copyright holders nor the names of its 133101Sstever@eecs.umich.edu# contributors may be used to endorse or promote products derived from 143101Sstever@eecs.umich.edu# this software without specific prior written permission. 153101Sstever@eecs.umich.edu# 163101Sstever@eecs.umich.edu# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 173101Sstever@eecs.umich.edu# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 183101Sstever@eecs.umich.edu# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 193101Sstever@eecs.umich.edu# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 203101Sstever@eecs.umich.edu# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 213101Sstever@eecs.umich.edu# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 223101Sstever@eecs.umich.edu# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 233101Sstever@eecs.umich.edu# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 243101Sstever@eecs.umich.edu# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 253101Sstever@eecs.umich.edu# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 263101Sstever@eecs.umich.edu# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 273101Sstever@eecs.umich.edu 283101Sstever@eecs.umich.edufrom m5.util import code_formatter 293101Sstever@eecs.umich.edu 303101Sstever@eecs.umich.edufrom slicc.ast.ExprAST import ExprAST 313101Sstever@eecs.umich.edu 323101Sstever@eecs.umich.educlass MethodCallExprAST(ExprAST): 333101Sstever@eecs.umich.edu def __init__(self, slicc, proc_name, expr_ast_vec): 343101Sstever@eecs.umich.edu super(MethodCallExprAST, self).__init__(slicc) 353101Sstever@eecs.umich.edu self.proc_name = proc_name 363101Sstever@eecs.umich.edu self.expr_ast_vec = expr_ast_vec 373101Sstever@eecs.umich.edu 383101Sstever@eecs.umich.edu def generate(self, code): 393101Sstever@eecs.umich.edu tmp = code_formatter() 403101Sstever@eecs.umich.edu paramTypes = [] 413101Sstever@eecs.umich.edu for expr_ast in self.expr_ast_vec: 423101Sstever@eecs.umich.edu return_type = expr_ast.generate(tmp) 433101Sstever@eecs.umich.edu paramTypes.append(return_type) 443101Sstever@eecs.umich.edu 453101Sstever@eecs.umich.edu obj_type, methodId, prefix = self.generate_prefix(paramTypes) 463101Sstever@eecs.umich.edu 473101Sstever@eecs.umich.edu # generate code 483101Sstever@eecs.umich.edu params = [] 493101Sstever@eecs.umich.edu for expr_ast in self.expr_ast_vec: 503101Sstever@eecs.umich.edu return_type,tcode = expr_ast.inline(True) 513101Sstever@eecs.umich.edu params.append(str(tcode)) 523101Sstever@eecs.umich.edu fix = code.nofix() 533101Sstever@eecs.umich.edu code("$prefix${{self.proc_name}}(${{', '.join(params)}}))") 543101Sstever@eecs.umich.edu code.fix(fix) 553101Sstever@eecs.umich.edu 563101Sstever@eecs.umich.edu # Verify that this is a method of the object 573101Sstever@eecs.umich.edu if methodId not in obj_type.methods: 583101Sstever@eecs.umich.edu error("Invalid method call: Type '%s' does not have a method '%s'", 593101Sstever@eecs.umich.edu obj_type, methodId) 603101Sstever@eecs.umich.edu 613101Sstever@eecs.umich.edu if len(self.expr_ast_vec) != \ 623101Sstever@eecs.umich.edu len(obj_type.methods[methodId].param_types): 633101Sstever@eecs.umich.edu # Right number of parameters 643101Sstever@eecs.umich.edu error("Wrong number of parameters for function name: '%s', " + \ 653101Sstever@eecs.umich.edu "expected: , actual: ", proc_name, 663101Sstever@eecs.umich.edu len(obj_type.methods[methodId].param_types), 673101Sstever@eecs.umich.edu len(self.expr_ast_vec)) 683101Sstever@eecs.umich.edu 693101Sstever@eecs.umich.edu for actual_type, expected_type in \ 703101Sstever@eecs.umich.edu zip(paramTypes, obj_type.methods[methodId].param_types): 713101Sstever@eecs.umich.edu if actual_type != expected_type: 723101Sstever@eecs.umich.edu error("Type mismatch: expected: %s actual: %s", 733101Sstever@eecs.umich.edu expected_type, actual_type) 743101Sstever@eecs.umich.edu 753101Sstever@eecs.umich.edu # Return the return type of the method 763101Sstever@eecs.umich.edu return obj_type.methods[methodId].return_type 773101Sstever@eecs.umich.edu 783101Sstever@eecs.umich.edu def findResources(self, resources): 793101Sstever@eecs.umich.edu pass 803101Sstever@eecs.umich.edu 813101Sstever@eecs.umich.educlass MemberMethodCallExprAST(MethodCallExprAST): 823101Sstever@eecs.umich.edu def __init__(self, slicc, obj_expr_ast, proc_name, expr_ast_vec): 833101Sstever@eecs.umich.edu s = super(MemberMethodCallExprAST, self) 843101Sstever@eecs.umich.edu s.__init__(slicc, proc_name, expr_ast_vec) 853101Sstever@eecs.umich.edu 863101Sstever@eecs.umich.edu self.obj_expr_ast = obj_expr_ast 873101Sstever@eecs.umich.edu 883101Sstever@eecs.umich.edu def __repr__(self): 893101Sstever@eecs.umich.edu return "[MethodCallExpr: %r%r %r]" % (self.proc_name, 903101Sstever@eecs.umich.edu self.obj_expr_ast, 913101Sstever@eecs.umich.edu self.expr_ast_vec) 923101Sstever@eecs.umich.edu def generate_prefix(self, paramTypes): 933101Sstever@eecs.umich.edu code = code_formatter() 943101Sstever@eecs.umich.edu 953101Sstever@eecs.umich.edu # member method call 963101Sstever@eecs.umich.edu obj_type = self.obj_expr_ast.generate(code) 973101Sstever@eecs.umich.edu methodId = obj_type.methodId(self.proc_name, paramTypes) 983101Sstever@eecs.umich.edu 993101Sstever@eecs.umich.edu prefix = "" 1003101Sstever@eecs.umich.edu return_type = obj_type.methods[methodId].return_type 1013101Sstever@eecs.umich.edu if return_type.isInterface: 1023101Sstever@eecs.umich.edu prefix = "static_cast<%s &>" % return_type.c_ident 1033101Sstever@eecs.umich.edu prefix = "%s((%s)." % (prefix, code) 1043101Sstever@eecs.umich.edu 1053101Sstever@eecs.umich.edu return obj_type, methodId, prefix 1063101Sstever@eecs.umich.edu 1073101Sstever@eecs.umich.edu 1083101Sstever@eecs.umich.educlass ClassMethodCallExprAST(MethodCallExprAST): 1093101Sstever@eecs.umich.edu def __init__(self, slicc, type_ast, proc_name, expr_ast_vec): 1103101Sstever@eecs.umich.edu s = super(ClassMethodCallExprAST, self) 1113101Sstever@eecs.umich.edu s.__init__(slicc, proc_name, expr_ast_vec) 1123101Sstever@eecs.umich.edu 1133101Sstever@eecs.umich.edu self.type_ast = type_ast 1143101Sstever@eecs.umich.edu 1153101Sstever@eecs.umich.edu def __repr__(self): 1163101Sstever@eecs.umich.edu return "[MethodCallExpr: %r %r]" % (self.proc_name, self.expr_ast_vec) 1173101Sstever@eecs.umich.edu 1183101Sstever@eecs.umich.edu def generate_prefix(self, paramTypes): 1193101Sstever@eecs.umich.edu 1203101Sstever@eecs.umich.edu # class method call 1213101Sstever@eecs.umich.edu prefix = "(%s::" % self.type_ast 1223101Sstever@eecs.umich.edu obj_type = self.type_ast.type 1233101Sstever@eecs.umich.edu methodId = obj_type.methodId(self.proc_name, paramTypes) 1243101Sstever@eecs.umich.edu 1253101Sstever@eecs.umich.edu return obj_type, methodId, prefix 1263101Sstever@eecs.umich.edu 1273101Sstever@eecs.umich.edu__all__ = [ "MemberMethodCallExprAST", "ClassMethodCallExprAST" ] 1283101Sstever@eecs.umich.edu