double AM_PARAM::GetValue( const D_CODE* aDcode ) const
{
    double paramvalue = 0.0;
    double curr_value = 0.0;
    parm_item_type state = POPVALUE;
    for( unsigned ii = 0; ii < m_paramStack.size(); ii++ )
    {
        AM_PARAM_ITEM item = m_paramStack[ii];
        switch( item.GetType() )
        {
            case ADD:
            case SUB:
            case MUL:
            case DIV:   // just an operator for next parameter value: store it
                state = item.GetType();
                break;

            case PUSHPARM:
                // get the parameter from the aDcode
                if( aDcode && item.GetIndex() <= aDcode->GetParamCount() )
                    curr_value = aDcode->GetParam( item.GetIndex() );
                else    // Get parameter from local param definition
                {
                    const APERTURE_MACRO * am_parent = aDcode->GetMacro();
                    curr_value = am_parent->GetLocalParam( aDcode, item.GetIndex() );
                }
                // Fall through
            case PUSHVALUE: // a value is on the stack:
                if( item.GetType() == PUSHVALUE )
                    curr_value = item.GetValue();
                switch( state )
                {
                    case POPVALUE:
                        paramvalue = curr_value;
                        break;

                    case ADD:
                        paramvalue += curr_value;
                        break;

                    case SUB:
                        paramvalue -= curr_value;
                        break;

                    case MUL:
                        paramvalue *= curr_value;
                        break;

                    case DIV:
                        paramvalue /= curr_value;
                        break;

                    default:
                        wxLogDebug( wxT( "AM_PARAM::GetValue() : unexpected operator\n" ) );
                        break;
                }
                break;

            default:
                wxLogDebug( wxT( "AM_PARAM::GetValue(): unexpected type\n" ) );
                break;
        }
    }
    return paramvalue;
}
Example #2
0
double AM_PARAM::GetValue( const D_CODE* aDcode ) const
{
    // In macros, actual values are sometimes given by an expression like:
    // 0-$2/2-$4
    // Because arithmetic predence is used, the parameters (values (double) and operators)
    // are stored in a stack, with all numeric values converted to the actual values
    // when they are defered parameters
    // Each item is stored in a AM_PARAM_EVAL (a value or an operator)
    //
    // Then the stack with all values resolved is parsed and numeric values
    // calculated according to the precedence of operators
    double curr_value = 0.0;
    parm_item_type op_code;

    AM_PARAM_EVAL_STACK ops;

    for( unsigned ii = 0; ii < m_paramStack.size(); ii++ )
    {
        AM_PARAM_ITEM item = m_paramStack[ii];

        switch( item.GetType() )
        {
            case ADD:
            case SUB:
            case MUL:
            case DIV:       // just an operator for next parameter value
            case OPEN_PAR:
            case CLOSE_PAR: // Priority modifiers: store in stack
                op_code = item.GetType();
                ops.push_back( AM_PARAM_EVAL( op_code ) );
                break;

            case PUSHPARM:
                // a defered value: get the actual parameter from the aDcode
                if( aDcode )    // should be always true here
                {
                    if( item.GetIndex() <= aDcode->GetParamCount() )
                    {
                        curr_value = aDcode->GetParam( item.GetIndex() );
                    }
                    else    // Get parameter from local param definition
                    {
                        const APERTURE_MACRO * am_parent = aDcode->GetMacro();
                        curr_value = am_parent->GetLocalParam( aDcode, item.GetIndex() );
                    }
                }
                else
                {
                    wxLogDebug( wxT( "AM_PARAM::GetValue(): NULL param aDcode\n" ) );
                }

                ops.push_back( AM_PARAM_EVAL( curr_value ) );
                break;

            case PUSHVALUE: // a value is on the stack:
                curr_value = item.GetValue();
                ops.push_back( AM_PARAM_EVAL( curr_value ) );
                break;

            default:
                wxLogDebug( "AM_PARAM::GetValue(): dcode %d prm %d/%d: unexpected type %d",
                            aDcode ? aDcode->m_Num_Dcode : -1, ii, m_paramStack.size(), item.GetType() );
                break;
        }
    }

    double result = Evaluate( ops );

    return result;
}