www.pudn.com > Tierazon-v29.zip > Unique.cpp


////////////////////////////// 
// Unique Parser by Gerry Myers 
// Unique.cpp  4/29/97 
// 
 
#include "stdafx.h" 
#include "Tierazon.h" 
 
#include "TierazonDoc.h" 
#include "TierazonView.h" 
#include  
#include "unique.h" 
 
//--------------------------------------------------------------------------- 
//#include  
//#pragma hdrstop 
 
//#include "Unit1.h" 
//--------------------------------------------------------------------------- 
//#pragma resource "*.dfm" 
//TForm1 *Form1; 
 
// 
// A simple class that could be used for exception 
// handling chores. 
// 
 
class MyEHClass { 
  public: 
    MyEHClass(int error, char* msg) 
    { 
      ErrorCode = error; 
      Msg = msg; 
    } 
    int Error() 
    { 
      return ErrorCode; 
    } 
    CString Message() 
    { 
      return Msg; 
    } 
    int Message(char* buff, int buffsize) 
		{ 
      if (Msg.GetLength() < buffsize) { 
        strcpy(buff, Msg); 
        //strcpy(buff, Msg.c_str()); 
        return Msg.GetLength(); 
      } 
      else { 
        strcpy(buff, ""); 
        return 0; 
      } 
    } 
private: 
  int ErrorCode; 
  CString Msg; 
}; 
 
//--------------------------------------------------------------------------- 
//double __fastcall TForm1::ParseExpression( const char* str, int& index ) 
CTierazonView::MExpression* CTierazonView::ParseExpression( const char* str, int& index ) 
{ 
	try 
	{ 
		// 
		// Parse out the first operand of this expression. 
		// 
		MExpression* Operand1 = ParseOperand( str, index ); 
 
		// 
		// Determine the operation.  The next character should be an operator. 
		// Prime the pump. 
		// 
		while ( str[ index ] == ' ' ) index++;		// eat whitespace 
		char Operation = str[ index ]; 
 
		// Repeat this block as long as there is more expression left.  If this 
		// is a "two operand" expression, this loop will only execute once. 
		// However, if this is a three, four, or more operand expression, this 
		// loop will execute once for each operand (except for the first operand). 
		// The current progress is always held as operand 1. 
		while ( ( Operation != '\0' ) && ( Operation != ')' ) ) 
		{ 
			// 
			// Parse out the second operand in this expression. 
			// 
			MExpression* Operand2 = ParseOperand( str, ++index ); 
 
			// 
			// Perform the operation with the two operands. 
			// 
			switch ( Operation ) 
			{ 
				case '+': 
					Operand1 = new MAddExpr( Operand1, Operand2 ); 
					break; 
				 
        case '-': 
					Operand1 = new MSubtractExpr( Operand1, Operand2 ); 
					break; 
				 
        case '*': 
					Operand1 = new MMultiplyExpr( Operand1, Operand2 ); 
					break; 
				 
        case '/': 
					Operand1 = new MDivideExpr( Operand1, Operand2 ); 
					break; 
 
        case '^': 
					Operand1 = new MExponentExpr( Operand1, Operand2 ); 
					break; 
 
				default: 
          throw MyEHClass( 0, "Bad Expression" ); 
			} 
 
			while ( str[ index ] == ' ' ) index++;		// eat whitespace 
			Operation = str[ index ]; 
		} 
 
		// Return the accumulated result. 
		return Operand1; 
	} 
	catch ( MyEHClass& ) 
	{ 
		throw;	// re-throw it for the next level up. 
	} 
  return new MLeafExpr(cmplx(0, 0)); 
} 
 
//--------------------------------------------------------------------------- 
//double __fastcall TForm1::ParseOperand( const char* str, int& index ) 
CTierazonView::MExpression* CTierazonView::ParseOperand( const char* str, int& index ) 
{ 
	try 
	{ 
		// Get rid of any leading blanks. 
		while ( str[ index ] == ' ' ) index++; 
 
		switch ( str[ index ] ) 
		{ 
			// Is this a sub-expression? 
			case '(': 
			{ 
				index++; 
				MExpression* d = ParseExpression( str, index ); 
 
				// Get rid of any leading blanks. 
				while ( str[ index ] == ' ' ) index++; 
 
				// The current character (left over from the above sub-expression) 
				// should be ')'.  If not, the entire expression is bad. 
				if ( str[ index++ ] != ')' ) throw MyEHClass( 0, "Bad Expression" ); 
 
				// Store the first operand. 
				return d; 
			} 
 
			// Is this the Z data member? 
			case 'z': 
			case 'Z': 
				index++;						// advance to the next character 
				return new MZExpr( this ); 
 
			// Is this the U data member? 
			case 'u': 
			case 'U': 
				index++;						// advance to the next character 
				return new MLeafExpr( uu ); 
 
			// Is this the V data member? 
			case 'v': 
			case 'V': 
				index++;						// advance to the next character 
				return new MLeafExpr( vv ); 
 
			// Is this the W data member? 
			case 'w': 
			case 'W': 
				index++;						// advance to the next character 
				return new MLeafExpr( ww ); 
 
			// Is this the C data member? 
			case 'c': 
			case 'C': 
				// Is it the cos() function? 
				if ( strncmp( &( str[ index ] ), "cos(", 4 ) == 0 ) 
				{ 
					index += 3; 
					return new MCosExpr( ParseOperand( str, index ) ); 
				} 
        else  
        { 
          index++;						// advance to the next character 
				return new MCExpr( this ); 
        } 
 
			// Is this a number? 
			case '0': 
			case '1': 
			case '2': 
			case '3': 
			case '4': 
			case '5': 
			case '6': 
			case '7': 
			case '8': 
			case '9': 
			case '.': 
			{ 
				double d = atof( &( str[ index ] ) ); 
 
				// Move to the end of this number. 
				while ( ( ( str[ index ] >= '0' ) && ( str[ index ] <= '9' ) ) || 
									( str[ index ] == '.' ) ) 
					index++; 
				return new MLeafExpr( cmplx( d, 0 ) ); 
			} 
 
			// Is this the unary minus?  If so, break down any sub-expression that 
			// may be sitting behind it. 
			case '-': 
				return new MUnaryMinusExpr( ParseExpression( str, ++index ) ); 
 
			// If none of the above options used, something is wrong with the 
			// expression. 
			default: 
				// Is it the sin() function? 
				// All values used inside the sin(), cos(), and tan() are in radians 
				// where 2 pi radians = 360 degrees. 
				if ( strncmp( &( str[ index ] ), "sin(", 4 ) == 0 ) 
				{ 
					index += 3; 
					//return sin( ParseOperand( str, index ) ); 
					return new MSinExpr( ParseOperand( str, index ) ); 
				} 
 
				// Is it the sinh() function? 
				else if ( strncmp( &( str[ index ] ), "sinh(", 5 ) == 0 ) 
				{ 
					index += 4; 
					return new MSinhExpr( ParseOperand( str, index ) ); 
         
        } 
 
				// Is it the asin() function? 
				else if ( strncmp( &( str[ index ] ), "asin(", 5 ) == 0 ) 
				{ 
					index += 4; 
					return new MASinExpr( ParseOperand( str, index ) ); 
				} 
 
				// Is it the acos() function? 
				else if ( strncmp( &( str[ index ] ), "acos(", 5 ) == 0 ) 
				{ 
					index += 4; 
					return new MACosExpr( ParseOperand( str, index ) ); 
				} 
 
				// Is it the tan() function? 
				else if ( strncmp( &( str[ index ] ), "tan(", 4 ) == 0 ) 
				{ 
					index += 3; 
					return new MTanExpr( ParseOperand( str, index ) ); 
				} 
 
				// Is it the atan() function? 
				else if ( strncmp( &( str[ index ] ), "atan(", 5 ) == 0 ) 
				{ 
					index += 4; 
					return new MATanExpr( ParseOperand( str, index ) ); 
				} 
 
				// Is it the log() function? 
				else if ( strncmp( &( str[ index ] ), "log(", 4 ) == 0 ) 
				{ 
					index += 3; 
					return new MLogExpr( ParseOperand( str, index ) ); 
				} 
 
				// Is it the lost() function? 
				else if ( strncmp( &( str[ index ] ), "lost(", 5 ) == 0 ) 
				{ 
					index += 4; 
					return new MUnknownExpr( ParseOperand( str, index ) ); 
				} 
 
				// Is it the real() function? 
				else if ( strncmp( &( str[ index ] ), "real(", 5 ) == 0 ) 
				{ 
					index += 4; 
					return new MRealExpr( ParseOperand( str, index ) ); 
				} 
 
				// Is it the imag() function? 
				else if ( strncmp( &( str[ index ] ), "imag(", 5 ) == 0 ) 
				{ 
					index += 4; 
					return new MImagExpr( ParseOperand( str, index ) ); 
				} 
 
				// If execution gets to here, something is wrong with the expression. 
				else 
				{ 
					//char cstr[100]; 
					//CString sz = str[index]; 
					//wsprintf(cstr,"Bad expression, index=%d, str=%s",index, sz); 
					//AfxMessageBox(cstr); 
					 
					throw MyEHClass( 0, "Bad Expression" ); 
					//throw MyEHClass( 0, cstr ); 
 
				} 
 
				// new end 
		} 
	} 
	catch ( MyEHClass& ) 
	{ 
		throw;	// re-throw it for the next level up. 
	} 
  return new MLeafExpr(cmplx(0, 0)); 
} 
 
///////////////////////////////////////////////////////////////////////////// 
// CUnique dialog 
 
CUnique::CUnique(CWnd* pParent /*=NULL*/) 
	: CDialog(CUnique::IDD, pParent) 
{ 
	//{{AFX_DATA_INIT(CUnique) 
	m_u_imag = 0.0; 
	m_u_real = 0.0; 
	m_v_real = 0.0; 
	m_w_real = 0.0; 
	m_Formulae = _T(""); 
	m_v_imag = 0.0; 
	m_w_imag = 0.0; 
	m_Radio = -1; 
	//}}AFX_DATA_INIT 
} 
 
 
void CUnique::DoDataExchange(CDataExchange* pDX) 
{ 
	CDialog::DoDataExchange(pDX); 
	//{{AFX_DATA_MAP(CUnique) 
	DDX_Text(pDX, IDC_U_IMAG, m_u_imag); 
	DDX_Text(pDX, IDC_U_REAL, m_u_real); 
	DDX_Text(pDX, IDC_V_REAL, m_v_real); 
	DDX_Text(pDX, IDC_W_REAL, m_w_real); 
	DDX_Text(pDX, IDC_FORMULAE, m_Formulae); 
	DDX_Text(pDX, IDC_V_IMAG, m_v_imag); 
	DDX_Text(pDX, IDC_W_IMAG, m_w_imag); 
	DDX_Radio(pDX, IDC_RADIO_M, m_Radio); 
	//}}AFX_DATA_MAP 
} 
 
 
BEGIN_MESSAGE_MAP(CUnique, CDialog) 
	//{{AFX_MSG_MAP(CUnique) 
	//}}AFX_MSG_MAP 
END_MESSAGE_MAP() 
 
 
///////////////////////////////////////////////////////////////////////////// 
// CUnique message handlers 
 
void CTierazonView::OnDrawUnique() 
{ 
  CUnique cu; 
 
	cu.m_Radio = nFormulaType; 
 
  cu.m_u_real = u_real; 
  cu.m_u_imag = u_imag; 
 
  cu.m_v_real = v_real; 
  cu.m_v_imag = v_imag; 
 
  cu.m_w_real = w_real; 
  cu.m_w_imag = w_imag; 
 
  cu.m_Formulae = strFormulae; 
 
  if (cu.DoModal() == IDOK) 
  { 
		nFormulaType = cu.m_Radio; 
 
    u_real = cu.m_u_real; 
    u_imag = cu.m_u_imag; 
 
    v_real = cu.m_v_real; 
    v_imag = cu.m_v_imag; 
 
    w_real = cu.m_w_real; 
    w_imag = cu.m_w_imag; 
 
    uu.set_real(cu.m_u_real); 
    uu.set_imag(cu.m_u_imag); 
 
    vv.set_real(cu.m_v_real); 
    vv.set_imag(cu.m_v_imag); 
 
    ww.set_real(cu.m_w_real); 
    ww.set_imag(cu.m_w_imag); 
     
    strFormulae = cu.m_Formulae; 
 
    int i_try = 0; 
    try 
	  { 
      //char cstr[120]; 
      //temp = ParseExpression( strFormulae, i_try ); 
       
      uu.set_real(u_real); 
      uu.set_imag(u_imag); 
 
      vv.set_real(v_real); 
      vv.set_imag(v_imag); 
 
      ww.set_real(w_real); 
      ww.set_imag(w_imag); 
 
      ParsedExpr = ParseExpression( strFormulae, i_try ); 
 
      if (nFormulaType == 0) 
				OnDraw101();  // M-Set 
			else 
				OnDraw118();  // N-Set 
    } 
	  catch ( MyEHClass& ) 
	  { 
		  //Application->MessageBox( "Something wrong in the expression!", 
			  //"Invalid Expression", MB_OK | MB_ICONEXCLAMATION ); 
      AfxMessageBox("Invalid Expression"); 
	  } 
  } 
} 
 
void CUnique::OnOK()  
{ 
  /* 
  try 
	{ 
		// If there is nothing in the string, do nothing. 
		if ( ExpressionEdit->Text.Length() <= 0 ) return; 
 
		u = atof( URealEdit->Text.c_str() ); 
		v = atof( VRealEdit->Text.c_str() ); 
		w = atof( WRealEdit->Text.c_str() ); 
		int i = 0; 
		z_real = ParseExpression( ExpressionEdit->Text.c_str(), i ); 
		DebugLabel->Caption = AnsiString( z ); 
	} 
	catch ( MyEHClass& ) 
	{ 
		Application->MessageBox( "Something wrong in the expression!", 
			"Invalid Expression", MB_OK | MB_ICONEXCLAMATION ); 
 
		DebugLabel->Caption = "Invalid Expression."; 
	} 
  */ 
   
	CDialog::OnOK(); 
} 
 
void CTierazonView::OnDraw101()  
{ 
	jul 		 = 0; 
	jul_save = 1; 
 
	dMagnification = 1; 
	CRMID = 0; 
	CIMID = 0; 
 
	ActiveTitle = "101) M-Set Method"; 
	nDistortion = 101; 
	GoDoFractal(); 
} 
 
void CTierazonView::OnUpdateDraw101(CCmdUI* pCmdUI)  
{ 
	if (nDistortion == 101) pCmdUI->SetCheck(TRUE);	 
	else  pCmdUI->SetCheck(FALSE); 
} 
 
void CTierazonView::OnDraw118()  
{ 
	jul 		 = 0; 
	jul_save = 1; 
 
	dMagnification = 1; 
	CRMID = 0; 
	CIMID = 0; 
 
	ActiveTitle = "118) N-Set method"; 
	nDistortion = 118; 
	GoDoFractal();	 
} 
 
void CTierazonView::OnUpdateDraw118(CCmdUI* pCmdUI)  
{ 
	if (nDistortion == 118) pCmdUI->SetCheck(TRUE);	 
	else  pCmdUI->SetCheck(FALSE); 
}