Example #1
0
/**
 * Interpret a function call.
 *
 * @param environment The environment to make the interpretation of a call 
 *                    over. This could be another function environment.
 *                    We use it to parse arguments in and to obtain the 
 *                    global environment.
 * @param function_element The function we want to evaluate the call of.
 * @param parms The container of parameters into the call.
 *
 *
 * @return The interpreted element.
 */
Element Function_::InterpretCall( Environment& environment
                                , Element const& function_element
                                , std::vector<Element> const& parms )
{
    GlobalEnvironment globals(environment.Globals());

    bool hasFunction = false;
    Function function = CastToFunction(function_element, hasFunction);
    Element result;

    if (hasFunction)
    {
        bool tailRecursion = true;
        std::vector<Element> parameters(parms);

        while(tailRecursion)
        {
            tailRecursion = false;

            Environment function_environment = Environment::Create(globals);
            globals.PushCallStack(function, function_environment);

            bool success = Funcall_::CreateEnvironment( function.Arguments()
                                                      , parameters
                                                      , function_environment ); 
            if (success)
            {
                Element body(function.Body());
                result = body.Interpret(function_environment);

                // Making a recursive call using tail recursion.
                if (Types::TAILRECURSE == result.Type())
                {
                    TailRecurse tailRecurse = CastToTailRecurse(result, success);
                    parameters = tailRecurse.Parameters();
          
                    // Go again! :D
                    tailRecursion = true; 
                }
            }

            globals.PopCallStack();
        }
    }

    return result;
}