Beispiel #1
0
/**
 * Initialize loop state. Here we evaluate the in-expression and
 * make sure it is a container with at least one dimension. We will
 * use the first dimension of the container to get the values for
 * the loop variable. We also add the loop variable to the environment.
 */
void SyntaxForLoop::initializeLoop( Environment& env )
{
    
    assert ( nextIndex == 0 );  // Check that we are not running already

    // Evaluate expression and check that we get a vector
    const RevPtr<RevVariable>&      theVar      = inExpression->evaluateContent(env);
    const RevObject&             theValue    = theVar->getRevObject();

    // Check that it is a container (the first dimension of which we will use)
    stateSpace = dynamic_cast<Container*>( theValue.clone() );
    if ( stateSpace == NULL )
    {
       throw RbException( "The 'in' expression does not evaluate to a container" );
    }
    
    // Add the loop variable to the environment, if it is not already there
    if ( !env.existsVariable( varName ) )
        env.addVariable( varName, new RevVariable( NULL) );
    
    // Set the local smart pointer to the loop variable
    loopVariable = env.getVariable( varName );
    
    // Initialize nextValue
    nextIndex = 1;
}
Beispiel #2
0
/**
 * @brief Get semantic value
 * 
 * Here we evaluate the length specification (statically) and create the
 * requested variable.
 *
 */
RevPtr<RevVariable> SyntaxVariableDecl::evaluateContent( Environment& env, bool dynamic )
{
    
    // Check if variable exists
    if ( env.existsVariable( variableName ) )
        throw RbException( "Illegal attempt to redefine variable " + variableName );
    
    // Check if type exists
    if ( !Workspace::userWorkspace().existsType( elementTypeName ) )
        throw RbException( "Type '" + elementTypeName + "' does not exist" );

    // Evaluate length specification
    std::vector<size_t> lengths;
    for ( std::list<SyntaxElement*>::iterator it = lengthExpr->begin(); it != lengthExpr->end(); ++it )
    {
        if ( (*it) == NULL )
        {
            lengths.push_back( 1 );
        }
        else
        {
            RevPtr<RevVariable> temp    = (*it)->evaluateContent( env, dynamic );
            const RevObject& value   = temp->getRevObject();
            
            size_t theLength;
            if ( value.isType( Natural::getClassTypeSpec() ) )
                theLength = size_t( static_cast<const Natural&>( value ).getValue() );
            else if ( value.isConvertibleTo( Natural::getClassTypeSpec(), true ) )
            {
                RevObject* convObj = value.convertTo( Natural::getClassTypeSpec() );
                theLength = size_t( static_cast<Natural*>( convObj )->getValue() );
                delete convObj;
            }
            else
                throw RbException( "Length specification does not evaluate to an object of type 'Natural'" );
            
            if ( theLength == 0 )
                throw RbException( "Invalid length specification (0)" );
            
            lengths.push_back( theLength );
        }
    }
    
    // We ask the user workspace for the new objects
    RevObject* newObject;
    if ( lengths.size() == 0 )
        newObject = Workspace::userWorkspace().makeNewDefaultObject( elementTypeName );
    else
    {
        throw RbException("This needs replacements!!!");
//        newObject = Workspace::userWorkspace().makeNewEmptyContainer( elementTypeName, lengths.size() );
//        static_cast<Container*>( newObject )->resize( lengths );
    }

    // Add the new RevVariable
    env.addVariable( variableName, new RevVariable( newObject ) );
    
    return NULL;
}
Beispiel #3
0
/**
 * @brief Evaluate left-hand-side content
 *
 * This function is similar to evaluateContent(). However, we
 * do not throw an error if the variable does not exist in the
 * frame; instead, we create and return a new null variable.
 */
RevPtr<RevVariable> SyntaxVariable::evaluateLHSContent( Environment& env, const std::string& elemType )
{
    RevPtr<RevVariable> theVar;
    
    // Find or create the variable
    if ( env.existsVariable( identifier ) )
    {
        theVar = env.getVariable( identifier );
    }
    else    // add it
    {
        theVar = new RevVariable( NULL, identifier );
        env.addVariable( identifier, theVar );
    }
    
    // Return the variable for assignment
    return theVar;
}
Beispiel #4
0
/** Execute function */
RevPtr<RevVariable> Func_module::execute( void )
{
    
    /* Get the module */
    std::string moduleName = static_cast<const RlString &>( args[0].getVariable()->getRevObject() ).getValue();
    const Module& mod = ModuleSystem::getModuleSystem().getModule( moduleName );
    
    Environment *execEnv = env;
    
    if ( args[1].getVariable()->getRevObject() != RevNullObject::getInstance() )
    {
        std::string ns = static_cast<const RlString &>( args[1].getVariable()->getRevObject() ).getValue();
    
         execEnv = env->getChildEnvironment( ns );
    }
    
//    WorkspaceVector<RevObject> *moduleArgs = new WorkspaceVector<RevObject>();
    for (size_t i = 2; i < args.size(); ++i)
    {
//        moduleArgs->push_back( args[i].getVariable()->getRevObject() );
        if ( args[i].getLabel() != "" )
        {
            if ( !execEnv->existsVariable( args[i].getLabel() ) )
            {
                execEnv->addVariable(args[i].getLabel(), args[i].getVariable() );
            }
            
        }
        else
        {
            std::cout << "Empty ellipsis argument label.\n";
        }
    }
//    execEnv->addVariable("args", moduleArgs);
//    if ( !execEnv->existsVariable("namespace") )
//    {
//        execEnv->addVariable("namespace", new RlString(ns) );
//    }
    
    /* Initialize */
    const std::vector<std::string>& commandLines = mod.getCommandLines();
    std::string command = "";
    int lineNumber = 0;
    int result = 0;     // result from processing of last command
    RBOUT("Processing module \"" + moduleName + "\"");
    
    /* Command-processing loop */
    for ( std::vector<std::string>::const_iterator it = commandLines.begin(); it != commandLines.end(); ++it)
    {
        
        // Get a line
        const std::string& line = *it;
        lineNumber++;
        
        // If previous result was 1 (append to command), we do this
        if ( result == 1 )
            command += line;
        else
            command = line;
        
        // Process the line and record result
        result = Parser::getParser().processCommand( command, execEnv );
        if ( result == 2 ) {
            std::ostringstream msg;
            msg << "Problem processing line " << lineNumber << " in module \"" << moduleName << "\"";
            throw RbException( msg.str() );
        }
    }
    
    /* Return control */
    RBOUT("Processing of module \"" + moduleName + "\" completed");
    
    return NULL;
}
/**
 * @brief Evaluate left-hand-side content
 *
 * This function is similar to evaluateContent(). However, we
 * do not throw an error if the variable does not exist in the
 * frame; instead, we create and return a new null variable.
 */
RevPtr<Variable> SyntaxVariable::evaluateLHSContent( Environment& env, const std::string& elemType )
{
    // Get static index. No dynamic evaluation here
    std::vector<size_t> oneOffsetIndices = computeStaticIndex( env );
    
    RevPtr<Variable> theVar;
    
    if ( baseVariable == NULL )
    {
        if ( functionCall != NULL )
        {
            // Get the return variable of the function call
            theVar = functionCall->evaluateContent( env );
        }
        else if ( expression != NULL )
        {
            // Get the return variable of the expression
            theVar = expression->evaluateContent( env );
        }
        else
        {
            // Find or create the variable
            if ( env.existsVariableInFrame( identifier ) )
                theVar = env.getVariable( identifier );
            else    // add it
            {
                if ( oneOffsetIndices.size() == 0 )
                    theVar = new Variable( NULL, identifier );
                else
                    theVar = new Variable( Workspace::userWorkspace().makeNewEmptyContainer( elemType, oneOffsetIndices.size() ), identifier );
                env.addVariable( identifier, theVar );
            }
        }
    }
    else
    {
        // Note that the function call is always NULL if there is
        // a base variable, because any variables that are base to
        // the function call are handled by the function call. Note
        // also that generic expressions can only occur in base
        // variables, so we need not worry about any expression if
        // we are not a base variable.
        
        // Get the base variable. Note that we do not create the variable in this case.
        theVar = baseVariable->evaluateContent( env );

        // Find member variable based on its name
        theVar = theVar->getRevObject().getMember( identifier );
    }
    
    // Get element if indices are provided.
    while ( !oneOffsetIndices.empty() )
    {
        // Get the element...
        if ( theVar->getRevObject().isTypeSpec( Container::RevObject::getClassTypeSpec() ) )
        {
            // ... from a container
            
            // Get the container indices
            std::vector<size_t> containerOneOffsetIndices;
            for ( size_t i = 0; i < theVar->getRevObject().getDim(); ++i )
            {
                if ( !oneOffsetIndices.empty() )
                {
                    containerOneOffsetIndices.push_back( oneOffsetIndices[0] );
                    oneOffsetIndices.erase( oneOffsetIndices.begin() );
                }
                else
                    containerOneOffsetIndices.push_back( 0 );
            }
            
            // Get the element using the findOrCreateElement function
            theVar = theVar->getRevObject().findOrCreateElement( containerOneOffsetIndices );
        }
        else
        {
            // ... or from a subscript operator
            
            // Note that we do not name the element here; either the member object gives out
            // a variable it names itself, or it gives out a temporary variable copy, which
            // should not be named. A subscript operator cannot be used to assign to a non-
            // existing variable.
            
            // Create the single argument for the index operator
            std::vector<Argument> args;
            RevPtr<Variable> indexVar = new Variable( new Natural( oneOffsetIndices[0] ) );
            args.push_back( Argument( indexVar ) );
            
            // Get the variable using the subscript operator function
            // TODO: This needs to be made generic for user-defined member objects
            theVar = theVar->getRevObject().executeMethod( "[]", args );
            
            // Erase the index
            oneOffsetIndices.erase( oneOffsetIndices.begin() );
        }
    }

    // Return the variable for assignment
    return theVar;
}