KiCad PCB EDA Suite
evaluate.cpp File Reference
#include <class_am_param.h>

Go to the source code of this file.

Functions

double Evaluate (AM_PARAM_EVAL_STACK &aExp)
 Evaluate an basic arithmetic expression (infix notation) with precedence The expression is a sequence of numbers (double) and arith operators: operators are + - x / ( and ) the expression is stored in a std::vector each item is a AM_PARAM_EVAL (each item is an operator or a double) More...
 

Function Documentation

double Evaluate ( AM_PARAM_EVAL_STACK aExp)

Evaluate an basic arithmetic expression (infix notation) with precedence The expression is a sequence of numbers (double) and arith operators: operators are + - x / ( and ) the expression is stored in a std::vector each item is a AM_PARAM_EVAL (each item is an operator or a double)

Parameters
aExp= the arithmetic expression to evaluate
Returns
the value

Definition at line 102 of file evaluate.cpp.

References ADD, CLOSE_PAR, DIV, AM_PARAM_EVAL::GetOperator(), AM_PARAM_EVAL::GetPriority(), AM_PARAM_EVAL::GetValue(), AM_PARAM_EVAL::IsOperator(), MUL, OPEN_PAR, POPVALUE, and SUB.

Referenced by AM_PARAM::GetValue().

103 {
104  class OP_CODE // A small class to store a operator and its priority
105  {
106  public:
107  parm_item_type m_Optype;
108  int m_Priority;
109 
110  OP_CODE( AM_PARAM_EVAL& aAmPrmEval )
111  : m_Optype( aAmPrmEval.GetOperator() ),
112  m_Priority( aAmPrmEval.GetPriority() )
113  {}
114 
115  OP_CODE( parm_item_type aOptype )
116  : m_Optype( aOptype ), m_Priority( 0 )
117  {}
118  };
119 
120  double result = 0.0;
121 
122  std::vector<double> values; // the current list of values
123  std::vector<OP_CODE> optype; // the list of arith operators
124 
125  double curr_value = 0.0;
126  int extra_priority = 0;
127 
128  for( unsigned ii = 0; ii < aExp.size(); ii++ )
129  {
130  AM_PARAM_EVAL& prm = aExp[ii];
131 
132  if( prm.IsOperator() )
133  {
134  if( prm.GetOperator() == OPEN_PAR )
135  {
136  extra_priority += AM_PARAM_EVAL::GetPriority( OPEN_PAR );
137  }
138  else if( prm.GetOperator() == CLOSE_PAR )
139  {
140  extra_priority -= AM_PARAM_EVAL::GetPriority( CLOSE_PAR );
141  }
142  else
143  {
144  optype.push_back( OP_CODE( prm ) );
145  optype.back().m_Priority += extra_priority;
146  }
147  }
148  else // we have a value:
149  {
150  values.push_back( prm.GetValue() );
151 
152  if( optype.size() < 2 )
153  continue;
154 
155  OP_CODE& previous_optype = optype[optype.size() - 2];
156 
157  if( optype.back().m_Priority > previous_optype.m_Priority )
158  {
159  double op1 = 0.0;
160 
161  double op2 = values.back();
162  values.pop_back();
163 
164  if( values.size() )
165  {
166  op1 = values.back();
167  values.pop_back();
168  }
169 
170  switch( optype.back().m_Optype )
171  {
172  case ADD:
173  values.push_back( op1+op2 );
174  break;
175 
176  case SUB:
177  values.push_back( op1-op2 );
178  break;
179 
180  case MUL:
181  values.push_back( op1*op2 );
182  break;
183 
184  case DIV:
185  values.push_back( op1/op2 );
186  break;
187 
188  default:
189  break;
190  }
191 
192  optype.pop_back();
193  }
194  }
195  }
196 
197  // Now all operators have the same priority, or those having the higher priority
198  // are before others, calculate the final result by combining initial values and/or
199  // replaced values.
200  if( values.size() > optype.size() )
201  // If there are n values, the number of operator is n-1 or n if the first
202  // item of the expression to evaluate is + or - (like -$1/2)
203  // If the number of operator is n-1 the first value is just copied to result
204  optype.insert( optype.begin(), OP_CODE( POPVALUE ) );
205 
206  wxASSERT( values.size() == optype.size() );
207 
208  for( unsigned idx = 0; idx < values.size(); idx++ )
209  {
210  curr_value = values[idx];
211 
212  switch( optype[idx].m_Optype )
213  {
214  case POPVALUE:
215  result = curr_value;
216  break;
217 
218  case ADD:
219  result += curr_value;
220  break;
221 
222  case SUB:
223  result -= curr_value;
224  break;
225 
226  case MUL:
227  result *= curr_value;
228  break;
229 
230  case DIV:
231  result /= curr_value;
232  break;
233 
234  default:
235  break;
236  }
237  }
238 
239  return result;
240 }
parm_item_type GetOperator() const
int GetPriority() const
This helper class hold a value or an arithmetic operator to calculate the final value of a aperture m...
bool IsOperator() const
parm_item_type
double GetValue() const