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