コード例 #1
0
/** Get semantic value: insert symbol and return the rhs value of the assignment */
void SyntaxStochasticAssignment::assign(RevPtr<RevVariable> &lhs, RevPtr<RevVariable> &rhs)
{
#ifdef DEBUG_PARSER
    printf( "Evaluating tilde assignment\n" );
#endif
    
    // Get distribution, which should be the return value of the rhs function
    const RevObject& exprValue = rhs->getRevObject();
    if ( !exprValue.isType( Distribution::getClassTypeSpec() ) ) 
    {
        throw RbException( "Expression on the right-hand-side of '~' did not return a distribution object." );
    }
    const Distribution &dist = dynamic_cast<const Distribution &>( exprValue );
        
    // Create new stochastic variable
    RevObject* rv = dist.createRandomVariable();
    
    // Fill the slot with the new stochastic variable
    lhs->replaceRevObject( rv );
    
    // make sure all the implicitly created variables got a correct name
    RevBayesCore::DagNode* theNode = lhs->getRevObject().getDagNode();
    theNode->setParentNamePrefix( theNode->getName() );
    
#ifdef DEBUG_PARSER
    env.printValue(std::cerr);
#endif
}
コード例 #2
0
/**
 * Evaluate the content of this syntax element. This will perform a
 * subtraction assignment operation.
 */
void SyntaxSubtractionAssignment::assign(RevPtr<RevVariable> &lhs, RevPtr<RevVariable> &rhs)
{
#ifdef DEBUG_PARSER
    printf( "Evaluating subtraction assignment\n" );
#endif
    
    // Get variable from lhs. We use standard evaluation because the variable is
    // implicitly on both sides (lhs and rhs) of this type of statement
    if ( lhs == NULL )
    {
        throw RbException( "Invalid NULL variable returned by lhs expression in subtraction assignment" );
    }
    
    // Make sure that the variable is constant
    if ( !lhs->getRevObject().isConstant() )
    {
        throw RbException( "Invalid subtraction assignment to dynamic variable" );
    }
    
    // Record whether it is a workspace (control) variable
    bool isWorkspaceVar = lhs->isWorkspaceVariable();
    
    // Get a reference to the lhs value object
    const RevObject& lhs_value = lhs->getRevObject();
    
    // Evaluate the rhs expression
    if ( rhs == NULL )
    {
        throw RbException( "Invalid NULL variable returned by rhs expression in subtraction assignment" );
    }
    
    // Get a reference to the rhs value object
    const RevObject& rhs_value = rhs->getRevObject();
    
    // Generate result of the multiplication
    RevObject *newValue = lhs_value.subtract( rhs_value );
    
    // Fill the slot with the new RevVariable
    lhs->replaceRevObject( newValue );
    
    // Reset it as workspace (control) variable, if it was a workspace (control) variable before the assignment.
    // When we fill the slot, the workspace (control) variable property is reset to false by default.
    if ( isWorkspaceVar )
    {
        lhs->setWorkspaceVariableState( true );
    }
    
#ifdef DEBUG_PARSER
    env.printValue(std::cerr);
#endif
}
コード例 #3
0
/**
 * Fit a variable into an argument according to the argument rule. If necessary and
 * appropriate, we do type conversion or type promotion.
 *
 *
 *
 * @todo To conform to the old code we change the required type of the incoming
 *       variable wrapper here. We need to change this so that we do not change
 *       the wrapper here, but make sure that if the argument variable is inserted
 *       in a member variable or container element slot, that the slot variable
 *       wrapper, which should be unique (not the same as the incoming variable
 *       wrapper), has the right required type.
 */
Argument ArgumentRule::fitArgument( Argument& arg, bool once ) const
{

    RevPtr<RevVariable> theVar = arg.getVariable();
    if ( evalType == BY_VALUE || theVar->isWorkspaceVariable() || theVar->getRevObject().isConstant() )
    {
        once = true;
    }
    
    
    for ( std::vector<TypeSpec>::const_iterator it = argTypeSpecs.begin(); it != argTypeSpecs.end(); ++it )
    {
        if ( evalType == BY_VALUE )
        {
            if ( theVar->getRevObject().isType( *it ) )
            {
                RevPtr<RevVariable> valueVar = RevPtr<RevVariable>( new RevVariable(theVar->getRevObject().clone(),arg.getLabel()) );
                return Argument( valueVar, getArgumentLabel(), false );
            }
            else if ( theVar->getRevObject().isConvertibleTo( *it, once ) != -1)
            {
                // Fit by type conversion. For now, we also modify the type of the incoming variable wrapper.
                RevObject* convertedObject = theVar->getRevObject().convertTo( *it );

                RevPtr<RevVariable> valueVar = RevPtr<RevVariable>( new RevVariable(convertedObject,arg.getLabel()) );
                return Argument( valueVar, getArgumentLabel(), false );
                
            }
        } // if (by-value)
        else
        {
            if ( theVar->getRevObject().isType( *it ) )
            {
                // For now, change the required type of the incoming variable wrapper
                theVar->setRequiredTypeSpec( *it );
            
                if ( !isEllipsis() )
                {
                    return Argument( theVar, getArgumentLabel(), evalType == BY_CONSTANT_REFERENCE );
                }
                else
                {
                    return Argument( theVar, arg.getLabel(), true );
                }
            
            }
            else if ( theVar->getRevObject().isConvertibleTo( *it, once ) != -1  && (*it).isDerivedOf( theVar->getRequiredTypeSpec() ))
            {
                // Fit by type conversion. For now, we also modify the type of the incoming variable wrapper.
                RevObject* convertedObject = theVar->getRevObject().convertTo( *it );
                theVar->replaceRevObject( convertedObject );
                theVar->setRequiredTypeSpec( *it );
                if ( !isEllipsis() )
                {
                    return Argument( theVar, getArgumentLabel(), false );
                }
                else
                {
                    return Argument( theVar, arg.getLabel(), false );
                }
            }
            else
            {
                // Fit by type conversion function
            
                const TypeSpec& typeFrom = theVar->getRevObject().getTypeSpec();
                const TypeSpec& typeTo   = *it;
            
                // create the function name
                std::string functionName = "_" + typeFrom.getType() + "2" + typeTo.getType();
                
                // Package arguments
                std::vector<Argument> args;
                Argument theArg = Argument( theVar, "arg" );
                args.push_back( theVar );
                
                Environment& env = Workspace::globalWorkspace();
            
                try
                {
                    Function* func = env.getFunction(functionName, args, once).clone();

                    // Allow the function to process the arguments
                    func->processArguments( args, once );
            
                    // Set the execution environment of the function
                    func->setExecutionEnviroment( &env );
                
                    // Evaluate the function
                    RevPtr<RevVariable> conversionVar = func->execute();
                
                    // free the memory
                    delete func;
                
                    conversionVar->setHiddenVariableState( true );
                    conversionVar->setRequiredTypeSpec( *it );
                
                    return Argument( conversionVar, getArgumentLabel(), evalType == BY_CONSTANT_REFERENCE );
                
                }
                catch (RbException e)
                {
                // we do nothing here
                }
                
            } // else (type conversion function)

            
        } // else (not by-value)

    }
    
    std::cerr << "Once = " << (once ? "TRUE" : "FALSE") << std::endl;
    
    throw RbException( "Argument type mismatch fitting a " + theVar->getRevObject().getType() + " argument to formal " +
                        getArgumentTypeSpec()[0].getType() + " " + getArgumentLabel() );
}