62 #include "wx/canvas/eval.h"
65 #define SAVE_ERR(n) {ERROR2=n; ERPOS=m_expression-ERANC-1; ERTOK = m_token;}
72 #define ERR(n) { SAVE_ERR(n); throw EvalErr();}
74 #define ERR(n) { SAVE_ERR(n); longjmp(m_jb,1);}
83 #define M_PI 3.14159265358979323846
86 #define M_E 2.71828182845904523536
96 double deg(
double x );
97 double rad(
double x );
110 wxStringCharType* ERANC;
113 #endif // wxUSE_UNICODE
117 WX_DEFINE_LIST( a2dFunctionList );
118 WX_DEFINE_LIST( a2dVariableList );
133 return( x * 180.0 / M_PI );
139 return( x * M_PI / 180.0 );
144 m_tokenstr.Alloc( VARLEN );
146 m_token = m_tokenstr.wx_str();
148 m_token = ( wxChar* ) m_tokenstr.c_str();
159 m_const.Append(
new a2dEvalVar( wxT(
"pi" ), M_PI ) );
160 m_const.Append(
new a2dEvalVar( wxT(
"e" ), M_E ) );
170 #define MATH_FUNC(f) m_functions.Append(new a2dEvalFunction(wxT(#f), f))
201 bool a2dEval::GetSymbol(
const wxString& envname, TYPENUMBER* envValue )
204 if( !wxGetEnv( envname, &senvValue ) )
207 if ( senvValue.ToDouble( envValue ) )
214 a2dVariableList::compatibility_iterator node = m_vars.GetFirst();
217 delete node->GetData();
218 m_vars.DeleteNode( node );
219 node = m_vars.GetFirst();
222 node = m_const.GetFirst();
225 delete node->GetData();
226 m_const.DeleteNode( node );
227 node = m_const.GetFirst();
230 a2dFunctionList::compatibility_iterator node2 = m_functions.GetFirst();
233 delete node2->GetData();
234 m_functions.DeleteNode( node2 );
235 node2 = m_functions.GetFirst();
249 void a2dEval::ClearAllVars()
251 a2dVariableList::compatibility_iterator node = m_vars.GetFirst();
254 delete node->GetData();
255 m_vars.DeleteNode( node );
256 node = m_vars.GetFirst();
273 bool a2dEval::ClearVar(
const wxString& name )
275 a2dVariableList::compatibility_iterator node = m_vars.GetFirst();
279 if( ( !obj->m_name.IsEmpty () ) && obj->m_name == name )
281 a2dVariableList::compatibility_iterator h = node;
283 node = node->GetNext();
285 m_vars.DeleteNode( h );
289 node = node->GetNext();
310 bool a2dEval::GetValue(
const wxString& name, TYPENUMBER* value )
313 if( name[0] == wxT(
'_' ) )
314 return( GetSymbol( name.Mid( 1 ), value ) );
318 a2dVariableList::compatibility_iterator node = m_vars.GetFirst();
322 if ( obj->m_name == name )
324 *value = obj->m_value;
327 node = node->GetNext();
332 node = m_const.GetFirst();
336 if( obj->m_name == name )
338 *value = obj->m_value;
341 node = node->GetNext();
359 bool a2dEval::SetValue(
const wxString& name, TYPENUMBER value )
362 m_vars.Append(
new a2dEvalVar( name, value ) );
376 void a2dEval::Parse()
382 #endif // wxUSE_UNICODE
386 t = (wxStringCharType*) m_token;
389 #endif // wxUSE_UNICODE
390 while( iswhite( *m_expression ) )
392 if( isdelim( *m_expression ) )
395 *t++ = *m_expression++;
397 else if( isnumer( *m_expression ) )
400 while( isnumer( *m_expression ) )
401 *t++ = *m_expression++;
403 else if( isalphaeval( *m_expression ) )
406 while( isalphaeval( *m_expression ) )
407 *t++ = *m_expression++;
410 else if( *m_expression )
412 *t++ = *m_expression++;
417 while( iswhite( *m_expression ) )
432 int a2dEval::Level1( TYPENUMBER* r )
437 if( *m_expression == wxT(
'=' ) )
448 if( ! SetValue( t, *r ) )
465 void a2dEval::Level2( TYPENUMBER* r )
471 while( ( o = *m_token ) == wxT(
'+' ) || o == wxT(
'-' ) )
475 if( o == wxT(
'+' ) )
477 else if( o == wxT(
'-' ) )
491 void a2dEval::Level3( TYPENUMBER* r )
497 while( ( o = *m_token ) == wxT(
'*' ) || o == wxT(
'/' ) || o == wxT(
'%' ) )
501 if( o == wxT(
'*' ) )
503 else if( o == wxT(
'/' ) )
509 else if( o == wxT(
'%' ) )
527 void a2dEval::Level4( TYPENUMBER* r )
532 if( *m_token == wxT(
'^' ) )
549 void a2dEval::Level5( TYPENUMBER* r )
553 if( *m_token == wxT(
'+' ) || *m_token == wxT(
'-' ) )
559 if( o == wxT(
'-' ) )
572 void a2dEval::Level6( TYPENUMBER* r )
577 if( *m_token == wxT(
'(' ) )
580 if( *m_token == wxT(
')' ) )
583 if( *m_token != wxT(
')' ) )
591 wxString numstr = m_token;
592 numstr.ToDouble( r );
595 else if( m_type == VAR )
597 if( *m_expression == wxT(
'(' ) )
599 a2dFunctionList::compatibility_iterator node = m_functions.GetFirst();
604 if( m_token == obj->m_name )
611 if( *m_token == wxT(
')' ) || *m_token == wxT(
',' ) )
617 while( n < 4 && *m_token == wxT(
',' ) );
619 if( n != obj->m_args )
621 m_tokenstr = obj->m_name;
624 *r = obj->m_func( a[0], a[1], a[2] );
627 if( obj->m_name.IsEmpty () )
630 node = node->GetNext();
633 else if( ! GetValue( m_token, r ) )
656 int a2dEval::Evaluate( TYPENUMBER* result,
int* a )
668 m_expression = m_eval.wx_str();
669 ERANC = (wxStringCharType*) m_expression;
671 m_expression = ( wxChar* ) m_eval.c_str();
672 ERANC = ( wxChar* ) m_eval.c_str();
673 #endif // wxUSE_UNICODE
680 *a = Level1( result );
684 catch(
const EvalErr& )
702 const wxChar* ErrMsgs[] =
704 wxT(
"Syntax error" ),
705 wxT(
"Unbalanced parenthesis" ),
706 wxT(
"Division by zero" ),
707 wxT(
"Unknown variable" ),
708 wxT(
"Maximum variables exceeded" ),
709 wxT(
"Unrecognised funtion" ),
710 wxT(
"Wrong number of arguments to funtion" ),
711 wxT(
"Missing an argument" ),
712 wxT(
"Empty expression" )
holds a function in an evaluation string for a2dEval
holds a variable in an evaluation string for a2dEval