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