Example #1
0
/**
 * Interpret a builtin call. Yes, this can be slow because each time we invoke
 * this we must query the mapping in the builtins table to see if it can be 
 * executed (builtin implementation). HOWEVER, this also allows us to swap out
 * builtin implementations on the fly.
 *
 * @return The interpreted element.
 */
Element Builtin_::InterpretCall( Environment& environment
                               , Element const& builtin_element
                               , std::vector<Element> const& parms )
{
    std::shared_ptr<Builtin_> builtin(std::dynamic_pointer_cast<Builtin_>(builtin_element.ElementHandle()));
    BuiltinsTable& table = *(builtin->table);
    BuiltinImplementation* impl = table.Get(builtin->Name());

    Element result;

    if (0 != builtin && 0 != impl)
    {
        std::vector<Element> output_parameters; 
        GlobalEnvironment globals(environment.Globals());
        Environment output_environment = Environment::Create(globals);
        bool success = Funcall_::CreateEnvironment( environment
                                                  , parms
                                                  , output_parameters);


        if (success && (0 != impl))
        {
            result = impl->Interpret( output_environment
                                    , output_parameters 
                                    , builtin->AdditionalParameter() );
        }
    }

    return result;
}
Example #2
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;
}