# Copyright (c) 1999-2008 Mark D. Hill and David A. Wood
# Copyright (c) 2009 The Hewlett-Packard Development Company
# All rights reserved.
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions are
# met: redistributions of source code must retain the above copyright
# notice, this list of conditions and the following disclaimer;
# redistributions in binary form must reproduce the above copyright
# notice, this list of conditions and the following disclaimer in the
# documentation and/or other materials provided with the distribution;
# neither the name of the copyright holders nor the names of its
# contributors may be used to endorse or promote products derived from
# this software without specific prior written permission.
#
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

from slicc.ast.ExprAST import ExprAST
from slicc.symbols import Func, Type

class FuncCallExprAST(ExprAST):
    def __init__(self, slicc, proc_name, exprs):
        super(FuncCallExprAST, self).__init__(slicc)
        self.proc_name = proc_name
        self.exprs = exprs

    def __repr__(self):
        return "[FuncCallExpr: %s %s]" % (self.proc_name, self.exprs)

    def generate(self, code):
        machine = self.state_machine

        if self.proc_name == "DPRINTF":
            # Code for inserting the location of the DPRINTF()
            # statement in the .sm file in the statement it self.
            # 'self.exprs[0].location' represents the location.
            # 'format' represents the second argument of the
            # original DPRINTF() call. It is left unmodified.
            # str_list is used for concatenating the argument
            # list following the format specifier. A DPRINTF()
            # call may or may not contain any arguments following
            # the format specifier. These two cases need to be
            # handled differently. Hence the check whether or not
            # the str_list is empty.

            format = "%s" % (self.exprs[1].inline())
            format_length = len(format)
            str_list = []

            for i in range(2, len(self.exprs)):
                str_list.append("%s" % self.exprs[i].inline())

            if len(str_list) == 0:
                code('DPRINTF(RubySlicc, "$0: $1")',
                     self.exprs[0].location, format[2:format_length-2])
            else:
                code('DPRINTF(RubySlicc, "$0: $1", $2)',
                     self.exprs[0].location, format[2:format_length-2],
                     ', '.join(str_list))

            return self.symtab.find("void", Type)

        # hack for adding comments to profileTransition
        if self.proc_name == "APPEND_TRANSITION_COMMENT":
            # FIXME - check for number of parameters
            code("APPEND_TRANSITION_COMMENT($0)", self.exprs[0].inline())
            return self.symtab.find("void", Type)

        # Look up the function in the symbol table
        func = self.symtab.find(self.proc_name, Func)

        # Check the types and get the code for the parameters
        if func is None:
            self.error("Unrecognized function name: '%s'", self.proc_name)

        if len(self.exprs) != len(func.param_types):
            self.error("Wrong number of arguments passed to function : '%s'" +\
                       " Expected %d, got %d", self.proc_name,
                       len(func.param_types), len(self.exprs))

        cvec = []
        type_vec = []
        for expr,expected_type in zip(self.exprs, func.param_types):
            # Check the types of the parameter
            actual_type,param_code = expr.inline(True)
            if str(actual_type) != 'OOD' and \
            str(actual_type) != str(expected_type):
                expr.error("Type mismatch: expected: %s actual: %s" % \
                           (expected_type, actual_type))
            cvec.append(param_code)
            type_vec.append(expected_type)

        # OK, the semantics of "trigger" here is that, ports in the
        # machine have different priorities. We always check the first
        # port for doable transitions. If nothing/stalled, we pick one
        # from the next port.
        #
        # One thing we have to be careful as the SLICC protocol
        # writter is : If a port have two or more transitions can be
        # picked from in one cycle, they must be independent.
        # Otherwise, if transition A and B mean to be executed in
        # sequential, and A get stalled, transition B can be issued
        # erroneously. In practice, in most case, there is only one
        # transition should be executed in one cycle for a given
        # port. So as most of current protocols.

        if self.proc_name == "trigger":
            code('''
{
''')
            if machine.TBEType != None and machine.EntryType != None:
                code('''
    TransitionResult result = doTransition(${{cvec[0]}}, ${{cvec[2]}}, ${{cvec[3]}}, ${{cvec[1]}});
''')
            elif machine.TBEType != None:
                code('''
    TransitionResult result = doTransition(${{cvec[0]}}, ${{cvec[2]}}, ${{cvec[1]}});
''')
            elif machine.EntryType != None:
                code('''
    TransitionResult result = doTransition(${{cvec[0]}}, ${{cvec[2]}}, ${{cvec[1]}});
''')
            else:
                code('''
    TransitionResult result = doTransition(${{cvec[0]}}, ${{cvec[1]}});
''')

            code('''
    if (result == TransitionResult_Valid) {
        counter++;
        continue; // Check the first port again
    }

    if (result == TransitionResult_ResourceStall) {
        scheduleEvent(Cycles(1));

        // Cannot do anything with this transition, go check next doable transition (mostly likely of next port)
    }
}
''')
        elif self.proc_name == "error":
            code("$0", self.exprs[0].embedError(cvec[0]))
        elif self.proc_name == "assert":
            error = self.exprs[0].embedError('"assert failure"')
            code('''
#ifndef NDEBUG
if (!(${{cvec[0]}})) {
    $error
}
#endif
''')

        elif self.proc_name == "set_cache_entry":
            code("set_cache_entry(m_cache_entry_ptr, %s);" %(cvec[0]));
        elif self.proc_name == "unset_cache_entry":
            code("unset_cache_entry(m_cache_entry_ptr);");
        elif self.proc_name == "set_tbe":
            code("set_tbe(m_tbe_ptr, %s);" %(cvec[0]));
        elif self.proc_name == "unset_tbe":
            code("unset_tbe(m_tbe_ptr);");

        else:
            # Normal function
            if "external" not in func and not func.isInternalMachineFunc:
                self.error("Invalid function")

            params = ""
            first_param = True

            for (param_code, type) in zip(cvec, type_vec):
                if first_param:
                    params = str(param_code)
                    first_param  = False
                else:
                    params += ', '
                    params += str(param_code);

            fix = code.nofix()
            code('(${{func.c_ident}}($params))')
            code.fix(fix)

        return func.return_type
