
/***************************************************************************
**
**    $Header:   D:/EP196/SRC/LOG/SYMSVR/SYMSYN.CPP   1.0   15 Aug 1997 14:04:16   ZJRD  $
**
**    $Log:   D:/EP196/SRC/LOG/SYMSVR/SYMSYN.CPP  $
** 
**    Rev 1.0   15 Aug 1997 14:04:16   ZJRD
** Initial revision.
** 
****************************************************************************/

/****************************************************************************
**
**  Name:  SYMSYN.CPP
**
**  Description:
**      member function of class CSymSyntax
**
**  Status:  CODED
**
**    Rev 1.0   19 March 1996 11:30:00pm   Gates Hua
** Initial revision.
**
**  Copyright (C) 1996 Microtek International.  All rights reserved.
**
*****************************************************************************/

                       /****************************
                        *                          *
                        *       INCLUDE FILES      *
                        *                          *
                        ****************************/

#include "stdafx.h"
#include <memory.h>
#include <string.h> 
#include "symoptpr.h"

#ifdef _LINK_WITH_ABI_
#include "abibase.h"  
#else
typedef int STATUS;
typedef unsigned char FLAG;
typedef struct {
    FLAG addrType;
    unsigned long  addr;
} ADDR;

/* All ABI routines Return codes */
typedef enum {
        ICE_OK              = 0x0,
        ICE_FAIL_STEP,                  //target cannot step
        ICE_FAIL_MEM_WRITE,             //memory write failure
        ICE_FAIL_MAP_INCLUDE,           //map status not included
        ICE_FAIL_MAP_BOUNDARY,          //map address boundary error
        ICE_NOT_FOUND       = 0x5,
        ICE_FOUND,
        ICE_TIME_OUT        = 0x7,
        ICE_PARA_ERROR      = 0x8,
        ICE_EP_RUNNING      = 0x10,
        ICE_TRACE_RUNNING   = 0x11,
        ICE_TRACE_READ_OVER = 0x12,
        ICE_COMMAND_INVALID = 0x13,

        ICE_FLASH_SW_ERROR  = 0x40,
        ICE_FLASH_EC_ERROR  = 0x41,
        ICE_FLASH_PRG_ERROR = 0x42,
        ICE_FLASH_REC_ERROR = 0x43,
		ICE_NO_RESPONSE		= 0xff
} RET_CODE;

#endif

#include "symblsvr.h"
#include "symsyn.h"
#include "symoptpr.h"
#include "symcalc.h"

                       /****************************
                        *                          *
                        *     LOCAL DEFINITIONS    *
                        *                          *
                        ****************************/

                       /****************************
                        *                          *
                        *    EXTERNAL VARIABLES    *
                        *                          *
                        ****************************/

extern int CheckIsValidVar(char *str,SYM_DESCRIPTOR &desc,
	TYPE_INDEX &typeIndex,BOOLEAN &isGlobal,ADDRESS_TYPE& addr);

                       /****************************
                        *                          *
                        *     LOCAL PROTOTYPES     *
                        *                          *
                        ****************************/

                       /****************************
                        *                          *
                        *      EXECUTABLE CODE     *
                        *                          *
                        ****************************/

/***************************************************************************
*                                                                          *
*  DeleteOperandStack  --  delete operand stack                            *
*  parameter :                                                             *
*       None                                                               *
*  return value :                                                          *
*       None                                                               *
*                                                                          *
***************************************************************************/
void CSymSyntax::DeleteOperandStack(void)
{
//    SYM_TOKEN_NODE *pTemp;
    CSymCalc *pTemp;
    void * pVoid;
	
	pTemp = 0;
	if ( GOOD != m_stkOperand.IsEmpty() ) {
		while( GOOD != m_stkOperand.IsEmpty() ) {
			m_stkOperand.Pop( pVoid );
//			pTemp = (SYM_TOKEN_NODE *)pVoid;
			pTemp = (CSymCalc *)pVoid;
			if ( pTemp ) delete pTemp;
			pTemp = 0;
		}
	}
}

/***************************************************************************
*                                                                          *
*  DeleteOperatorStack  --  delete operator stack                          *
*  parameter :                                                             *
*       None                                                               *
*  return value :                                                          *
*       None                                                               *
*                                                                          *
***************************************************************************/
void CSymSyntax::DeleteOperatorStack(void)
{
//    SYM_TOKEN_NODE *pTemp;
    int *pTemp;
    void * pVoid;
	
	pTemp = 0;
	if ( GOOD != m_stkOperator.IsEmpty() ) {
		while( GOOD != m_stkOperator.IsEmpty() ) {
			m_stkOperator.Pop( pVoid );
//			pTemp = (SYM_TOKEN_NODE *)pVoid;
			pTemp = (int *)pVoid;
			if ( pTemp ) delete pTemp;
			pTemp = 0;
		}
	}
}                        

/***************************************************************************
*                                                                          *
*  DeleteSyntaxStack  --  delete syntax stack                              *
*  parameter :                                                             *
*       None                                                               *
*  return value :                                                          *
*       None                                                               *
*                                                                          *
***************************************************************************/
void CSymSyntax::DeleteSyntaxStack(void)
{
    int *pTemp;
    void * pVoid;
	
	pTemp = 0;
	if ( GOOD != m_stkSyntax.IsEmpty() ) {
		while( GOOD != m_stkSyntax.IsEmpty() ) {
			m_stkSyntax.Pop( pVoid );
			pTemp = (int *)pVoid;
			if ( pTemp ) delete pTemp;
			pTemp = 0;
		}
	}
}                        

/***************************************************************************
*                                                                          *
*  DeleteArrayNum  --  delete array number stack                           *
*  parameter :                                                             *
*       None                                                               *
*  return value :                                                          *
*       None                                                               *
*                                                                          *
***************************************************************************/
void CSymSyntax::DeleteArrayNum(void)
{
    unsigned long *pTemp;
    void * pVoid;
	
	pTemp = 0;
	if ( GOOD != m_stkSyntax.IsEmpty() ) {
		while( GOOD != m_stkSyntax.IsEmpty() ) {
			m_stkSyntax.Pop( pVoid );
			pTemp = (unsigned long *)pVoid;
			if ( pTemp ) delete pTemp;
			pTemp = 0;
		}
	}
}                        

/***************************************************************************
*                                                                          *
*  Init  --  Initialize c expression's string                              *
*  parameter :                                                             *
*       str  --  c expression's string                                     *
*                                                                          *
*  return value :                                                          *
*       GOOD  --  success                                                  *
*       FAILURE  --  failure                                               *
*                                                                          *
***************************************************************************/
int CSymSyntax::Init(const char *str, int flag)	
{
	m_nErrNo = 0;
	InitStrCmd( str , flag);
	if ( m_nErrNo != 0 ) return FAILURE;
	return GOOD;
}

/***************************************************************************
*                                                                          *
*  IsVariable --  Check is only one symbol token                           *
*  parameter :                                                             *
*       None                                                               *
*                                                                          *
*  return value :                                                          *
*       GOOD  --  success                                                  *
*       FAILURE  --  failure                                               *
*                                                                          *
***************************************************************************/
int CSymSyntax::IsVariable(void)	
{
	if ( 1 == GetTokenNum() ) {
		if ( m_pLastToken ) {
			if ( SYMTOKEN_SYMBOL == m_pLastToken->symType ) {
				if ( 0 == m_pLastToken->nComplexType ) {
					if ( -1 != m_pLastToken->nTkNum ) return FAILURE;
				}
				return GOOD;
			}
		}
	}
	return FAILURE;
}

/***************************************************************************
*                                                                          *
*  CheckSyntax  --  analyse c expreesion's tokens and check syntax         *
*  parameter :                                                             *
*       None                                                               *
*  return value :                                                          *
*       GOOD  --  success                                                  *
*       FAILURE  --  failure                                               *
*                                                                          *
***************************************************************************/
int CSymSyntax::CheckSyntax(void)
{
    SYM_TOKEN_NODE *pTemp;
    SYMTOKENTYPE newTokenType;
    int *pInt = 0;                               
    void *pVoid;
    
	DeleteTokenList();
	
	while( 1 ) {
	    pTemp = new SYM_TOKEN_NODE;
	    if ( pTemp == 0 ) {
			m_bValidSyntax = FALSE;
			m_bValidResult = FALSE;
			m_nErrNo = 1;
			return FAILURE;
		}		    	
		if ( GOOD != GetNextToken( pTemp ) ) {
			m_bValidSyntax = FALSE;
			m_bValidResult = FALSE;
			delete pTemp;
			return FAILURE;
		}			                  
		
//		DisplayOneToken( pTemp );

		newTokenType = pTemp->symType;                
		if ( SYMTOKEN_UNKNOWN == newTokenType ) {
			m_nErrNo = 7;
			m_bValidSyntax = FALSE;
			m_bValidResult = FALSE;
			delete pTemp;
			return FAILURE;
		}			  
		switch ( m_lastTokenType ) {
		case SYMTOKEN_NULL:
			if ( SYMTOKEN_OPERATOR2 == newTokenType ||
				SYMTOKEN_OPERATOR == newTokenType ||
				SYMTOKEN_NULL == newTokenType ||
		   	    SYMTOKEN_RIGHTPARENTHESES == newTokenType ||
		   	    SYMTOKEN_LEFTBRANKETS == newTokenType ||
		   	    SYMTOKEN_RIGHTBRANKETS == newTokenType ) {
				m_bValidSyntax = FALSE;
				m_bValidResult = FALSE;
				m_nErrNo = 8;
				return FAILURE;
			}			  
			break;
		case SYMTOKEN_NUM:			
		case SYMTOKEN_FLOAT:
		   	if ( SYMTOKEN_LEFTBRANKETS == newTokenType ||
				SYMTOKEN_OPERATOR == newTokenType ) {
				m_bValidSyntax = FALSE;
				m_bValidResult = FALSE;
				m_nErrNo = 8;
				return FAILURE;
			}
		case SYMTOKEN_SYMBOL:
			if ( SYMTOKEN_NUM == newTokenType ||
				SYMTOKEN_FLOAT == newTokenType ||
		    	SYMTOKEN_SYMBOL == newTokenType || 
		   	    SYMTOKEN_LEFTPARENTHESES == newTokenType ||
		   	    SYMTOKEN_OPERATOR1 == newTokenType ) {
				m_bValidSyntax = FALSE;
				m_bValidResult = FALSE;
				m_nErrNo = 8;
				return FAILURE;
			}
			break;
		case SYMTOKEN_OPERATOR1:
			if ( SYMTOKEN_OPERATOR2 == newTokenType ||
				SYMTOKEN_NULL == newTokenType ||
				SYMTOKEN_OPERATOR == newTokenType ||
		   	    SYMTOKEN_RIGHTPARENTHESES == newTokenType ||
		   	    SYMTOKEN_LEFTBRANKETS == newTokenType ||
		   	    SYMTOKEN_RIGHTBRANKETS == newTokenType ) {
				m_bValidSyntax = FALSE;
				m_bValidResult = FALSE;
				m_nErrNo = 8;
				return FAILURE;
			}			  
			else if ( SYMTOKEN_OPERATOR1 == newTokenType ) {
				if ( pTemp->typeOpt != 5 ) {
					m_bValidSyntax = FALSE;
					m_bValidResult = FALSE;
					m_nErrNo = 8;
					return FAILURE;
				}
            }
			break;
		case SYMTOKEN_OPERATOR2:
			if ( SYMTOKEN_OPERATOR2 == newTokenType ||
				SYMTOKEN_NULL == newTokenType ||
				SYMTOKEN_OPERATOR == newTokenType ||
		   	    SYMTOKEN_RIGHTPARENTHESES == newTokenType ||
		   	    SYMTOKEN_LEFTBRANKETS == newTokenType ||
		   	    SYMTOKEN_RIGHTBRANKETS == newTokenType ) {
				m_bValidSyntax = FALSE;
				m_bValidResult = FALSE;
				m_nErrNo = 8;
				return FAILURE;
			}			  
			break;
		case SYMTOKEN_LEFTPARENTHESES :
		case SYMTOKEN_LEFTBRANKETS :
			pInt = new int;
			if ( pInt == 0 ) {
				m_bValidSyntax = FALSE;
				m_bValidResult = FALSE;
				m_nErrNo = 1;
				return FAILURE;
			}			  
			if ( SYMTOKEN_LEFTPARENTHESES == m_lastTokenType ) {
				*pInt = 0;
			}
			else *pInt = 1;

			if ( SYMTOKEN_OPERATOR2 == newTokenType ||
				SYMTOKEN_NULL == newTokenType ||
				SYMTOKEN_OPERATOR == newTokenType ||
		   	    SYMTOKEN_RIGHTPARENTHESES == newTokenType ||
		   	    SYMTOKEN_LEFTBRANKETS == newTokenType ||
		   	    SYMTOKEN_RIGHTBRANKETS == newTokenType ) {
				m_bValidSyntax = FALSE;
				m_bValidResult = FALSE;
				m_nErrNo = 8;
				delete pInt;
				return FAILURE;
			}			  

			if ( GOOD != m_stkSyntax.Push( pInt ) ) {
				m_bValidSyntax = FALSE;
				m_bValidResult = FALSE;
				m_nErrNo = 9;
				if ( pInt ) delete pInt;
				return FAILURE;
			}
			break;
		case SYMTOKEN_RIGHTPARENTHESES :
		case SYMTOKEN_RIGHTBRANKETS :
			if ( GOOD == m_stkSyntax.IsEmpty() ) {
				m_bValidSyntax = FALSE;
				m_bValidResult = FALSE;
				m_nErrNo = 8;
				return FAILURE;
			}                           
//			if ( GOOD != m_stkSyntax.Pop( (void *&)pInt ) ) {
			if ( GOOD != m_stkSyntax.Pop( pVoid ) ) {
				m_bValidSyntax = FALSE;
				m_bValidResult = FALSE;
				m_nErrNo = 9;
//				if ( pInt ) delete pInt;
				return FAILURE;
			}                             
			pInt = (int *)pVoid;
			if ((SYMTOKEN_RIGHTPARENTHESES == m_lastTokenType && 0 == *pInt)||
				(SYMTOKEN_RIGHTBRANKETS == m_lastTokenType && 1 == *pInt)) {
				if ( SYMTOKEN_NUM == newTokenType ||
					SYMTOKEN_FLOAT == newTokenType ||
			    	SYMTOKEN_SYMBOL == newTokenType || 
			   	    SYMTOKEN_LEFTPARENTHESES == newTokenType ||
			   	    SYMTOKEN_OPERATOR1 == newTokenType ) {
					m_bValidSyntax = FALSE;
					m_bValidResult = FALSE;
					m_nErrNo = 8;
					delete pInt;
					return FAILURE;
				}
				delete pInt;
			}	
			else {
				m_bValidSyntax = FALSE;
				m_bValidResult = FALSE;
				m_nErrNo = 8;   
				delete pInt;
				return FAILURE;
			}               
			break;
		case SYMTOKEN_OPERATOR :
			if ( SYMTOKEN_NUM == newTokenType ||
				SYMTOKEN_FLOAT == newTokenType ||
				SYMTOKEN_OPERATOR == newTokenType ||      
				SYMTOKEN_LEFTBRANKETS == newTokenType ||
		    	SYMTOKEN_SYMBOL == newTokenType || 
		   	    SYMTOKEN_LEFTPARENTHESES == newTokenType ||
		   	    SYMTOKEN_OPERATOR1 == newTokenType ) {
				m_bValidSyntax = FALSE;
				m_bValidResult = FALSE;
				m_nErrNo = 8;
				return FAILURE;
			}
			break;	
		default :							
			m_bValidSyntax = FALSE;
			m_bValidResult = FALSE;
			m_nErrNo = 8;
			return FAILURE;
		}

		if ( SYMTOKEN_NULL == pTemp->symType ) {
			delete pTemp;
			break;
		}

		if ( GOOD != AddOneTokenToList(pTemp) ) {
			m_bValidSyntax = FALSE;
			m_bValidResult = FALSE;
			delete pTemp;
			return FAILURE;
		}			  
	}			
	if ( GOOD != m_stkSyntax.IsEmpty() ) {
		m_bValidSyntax = FALSE;
		m_bValidResult = FALSE;
		m_nErrNo = 8;
		return FAILURE;
	}

	if ( GetTokenNum() == 0 ) {
		m_bValidSyntax = FALSE;
		m_bValidResult = FALSE;
		m_nErrNo = 2;
		return FAILURE;
	}
	
    return GOOD;
}                         

/***************************************************************************
*                                                                          *
*  CalculateValue  --  calculate c expression's value                      *
*  parameter :                                                             *
*       None                                                               *
*  return value :                                                          *
*       GOOD  --  success                                                  *
*       FAILURE  --  failure                                               *
*                                                                          *
***************************************************************************/
int CSymSyntax::CalculateValue(void)
{                             
	int nTokenNum , nNum;
	int i,j;
//	int nFlag;
	int nCurOpt , nOpt;
	void *pVoid;
	int *pInt;
	SYM_TOKEN_NODE *pNode;  
	CSymCalc *pCalc , *pNow;                                     
	unsigned long ul;
	                
	pCalc = 0;
	pNow = 0;
	pNode = 0;
	pInt = 0;
	pVoid = 0;
	nCurOpt = 0;
//	nFlag = 0;
	if ( (nTokenNum = GetTokenNum()) == 0 ) {
		m_bValidResult = FALSE;
		m_nErrNo = 2;
		return FAILURE;
	}
	for( i = 0; i <= nTokenNum ;i++ ) {
		if ( i < nTokenNum ) {
			if ( GOOD != GetOneTokenFromList(i+1, pNode) ) {
		        m_nErrNo = 10;
				m_bValidResult = FALSE;
				if ( pNow ) delete pNow; 
		        return FAILURE;
			}                           
			if ( SYMTOKEN_NULL == pNode->symType || 
				SYMTOKEN_UNKNOWN == pNode->symType ) {
		        m_nErrNo = 10;
				m_bValidResult = FALSE;
				if ( pNow ) delete pNow; 
		        return FAILURE;
			}
			if ( SYMTOKEN_SYMBOL == pNode->symType || 
				SYMTOKEN_NUM == pNode->symType ||
				SYMTOKEN_FLOAT == pNode->symType ) {
				pCalc = new CSymCalc(pNode);
				if ( pCalc == 0 ) {
			        m_nErrNo = 1;
					m_bValidResult = FALSE;
					if ( pNow ) delete pNow; 
			        return FAILURE;
				}
				if ( pNow ) {
					if ( m_stkOperand.Push( pNow ) != GOOD ) {
				        m_nErrNo = 10;
						m_bValidResult = FALSE;
						if ( pNow ) delete pNow; 
				        return FAILURE;
					}
				}
				pNow = pCalc;               
				continue;
			}             
			nOpt = pNode->typeOpt;
		}
		else {
			nOpt = 0;
		}
		
		nNum = SymCheckOptPre(nCurOpt,nOpt);
		if ( nNum == 0 ) {			
	        m_nErrNo = 10;
			m_bValidResult = FALSE;
			if ( pNow ) delete pNow; 
	        return FAILURE;
		}
		else if ( nNum > 0 ) {
			while( 1 ) {
				if ( nCurOpt == 0 || pNow == 0 ) {
			        m_nErrNo = 9;
					m_bValidResult = FALSE;
					if ( pNow ) delete pNow; 
			        return FAILURE;
				}
//				nFlag = 0;
				switch ( nCurOpt ) {
				case 1 :
					nNum = pNow->CheckOneOperate(nCurOpt);
					if ( nNum ) break;
					nNum = pNow->Plus();
					break;
				case 2 :
					nNum = pNow->CheckOneOperate(nCurOpt);
					if ( nNum ) break;
					nNum = pNow->Minus();
					break;
				case 3 :
					nNum = pNow->CheckOneOperate(nCurOpt);
					if ( nNum ) break;
					nNum = pNow->BitNot();
					break;
				case 4 :
					nNum = pNow->CheckOneOperate(nCurOpt);
					if ( nNum ) break;
					nNum = pNow->LogNot();
					break;
				case 5 :
					nNum = pNow->CheckOneOperate(nCurOpt);
					if ( nNum ) break;
					nNum = pNow->PointValue();
					break;
				case 7 :                                       
					nNum = 0;
					if ( m_stkOperator.Pop( pVoid ) != GOOD ) {
				        m_nErrNo = 10;
						m_bValidResult = FALSE;
						if ( pNow ) delete pNow; 
				        return FAILURE;
					}               
					pInt = (int *)pVoid;
					if ( *pInt != 6 ) {
						nNum = 10;
					}
					delete pInt;
//					nFlag = 1;
					break;
				case 9 :                                       
					nNum = 0;
					if ( m_stkOperator.Pop( pVoid ) != GOOD ) {
				        m_nErrNo = 10;
						m_bValidResult = FALSE;
						if ( pNow ) delete pNow; 
				        return FAILURE;
					}               
					pInt = (int *)pVoid;
					j = *pInt;
					delete pInt;
					if ( 8 == j ) {
						if ( m_stkOperand.Pop( pVoid ) != GOOD ) {
					        m_nErrNo = 10;
							m_bValidResult = FALSE;
							if ( pNow ) delete pNow; 
					        return FAILURE;
						}               
						pCalc = pNow;
						pNow = (CSymCalc *)pVoid;
						nNum = pNow->CheckArrayOperate(pCalc,j,ul);
						if ( 0 == nNum ) {
							if ( 0 == j ) {
//								nNum = pNow->CArray(pCalc);
								nNum = pNow->CArray(ul);
							}
							else {
								if ( nOpt == 8 ) {
									unsigned long *pl ;
									
									pl = new unsigned long;
									if ( 0 == pl ) {	
								        m_nErrNo = 1;
										m_bValidResult = FALSE;
										delete pCalc;
										if ( pNow ) delete pNow; 
								        return FAILURE;
									}               
									*pl = ul;
//									if ( m_stkOperator.Push( pl ) != GOOD ) {
									if ( m_stkArrayNum.Push( pl ) != GOOD ) {
								        m_nErrNo = 9;
										m_bValidResult = FALSE;
										if ( pNow ) delete pNow; 
								        return FAILURE;
									}
									pNow->AddOneDim();
								}
								else {    
								// calculate
									unsigned long *pl , *pl1;
									j = pNow->GetDimNum();
									pl = new unsigned long[j+1];
									if ( 0 == pl ) {	
								        m_nErrNo = 1;
										m_bValidResult = FALSE;
										delete pCalc;
										if ( pNow ) delete pNow; 
								        return FAILURE;
									}               
									for( int ii=j-1;ii>=0;ii-- ) {
//									for( int ii=0;ii<j;ii++ ) {
//										if ( GOOD != m_stkOperator.Pop( pVoid ) ) {
										if ( GOOD != m_stkArrayNum.Pop( pVoid ) ) {
									        m_nErrNo = 10;
											m_bValidResult = FALSE;
											delete pCalc;
											delete []pl;
											if ( pNow ) delete pNow; 
									        return FAILURE;
										}               
									    pl1 = (unsigned long *)pVoid;
									    pl[ii] = *pl1;
									}                         
									pl[j] = ul;
//									pl[0] = ul;
									nNum = pNow->Omf51Array(pl , j+1);
									delete []pl;
								}
							}            
						}
					}
					else {
						nNum = 10;
					}
					delete pCalc;
					break;
				case 10 :
					if ( m_stkOperand.Pop( pVoid ) != GOOD ) {
				        m_nErrNo = 10;
						m_bValidResult = FALSE;
						if ( pNow ) delete pNow; 
				        return FAILURE;
					}               
//					pCalc = (CSymCalc *)pVoid;
//					nNum = pNow->CheckTwoOperate(pCalc,nCurOpt);
					pCalc = pNow;
					pNow = (CSymCalc *)pVoid;

					nNum = pNow->CheckOneOperate(5);
					if ( nNum ) {
						delete pCalc;
						break;
					}
					nNum = pNow->PointValue();
					if ( nNum ) {
						delete pCalc;
						break;
					}

					nNum = pNow->CheckStructOpt(pCalc,nCurOpt);
					if ( nNum ) {
						delete pCalc;
						break;
					}
					nNum = pNow->Struct(pCalc,nCurOpt,this);
					delete pCalc;
					break;
				case 11 :
					if ( m_stkOperand.Pop( pVoid ) != GOOD ) {
				        m_nErrNo = 10;
						m_bValidResult = FALSE;
						if ( pNow ) delete pNow; 
				        return FAILURE;
					}               
//					pCalc = (CSymCalc *)pVoid;
//					nNum = pNow->CheckTwoOperate(pCalc,nCurOpt);
					pCalc = pNow;
					pNow = (CSymCalc *)pVoid;
					nNum = pNow->CheckStructOpt(pCalc,nCurOpt);
					if ( nNum ) {
						delete pCalc;
						break;
					}
					nNum = pNow->Struct(pCalc,nCurOpt,this);
					delete pCalc;
					break;
				case 12 :
					if ( m_stkOperand.Pop( pVoid ) != GOOD ) {
				        m_nErrNo = 10;
						m_bValidResult = FALSE;
						if ( pNow ) delete pNow; 
				        return FAILURE;
					}               
//					pCalc = (CSymCalc *)pVoid;
//					nNum = pNow->CheckTwoOperate(pCalc,nCurOpt);
					pCalc = pNow;
					pNow = (CSymCalc *)pVoid;
					nNum = pNow->CheckTwoOperate(pCalc,nCurOpt);
					if ( nNum ) {
						delete pCalc;
						break;
					}
					nNum = (*pNow) * (*pCalc);
					delete pCalc;
					break;
				case 13 :
					if ( m_stkOperand.Pop( pVoid ) != GOOD ) {
				        m_nErrNo = 10;
						m_bValidResult = FALSE;
						if ( pNow ) delete pNow; 
				        return FAILURE;
					}               
//					pCalc = (CSymCalc *)pVoid;
//					nNum = pNow->CheckTwoOperate(pCalc,nCurOpt);
					pCalc = pNow;
					pNow = (CSymCalc *)pVoid;
					nNum = pNow->CheckTwoOperate(pCalc,nCurOpt);
					if ( nNum ) {
						delete pCalc;
						break;
					}
					nNum = (*pNow) / (*pCalc);
					delete pCalc;
					break;
				case 14 :
					if ( m_stkOperand.Pop( pVoid ) != GOOD ) {
				        m_nErrNo = 10;
						m_bValidResult = FALSE;
						if ( pNow ) delete pNow; 
				        return FAILURE;
					}               
//					pCalc = (CSymCalc *)pVoid;
//					nNum = pNow->CheckTwoOperate(pCalc,nCurOpt);
					pCalc = pNow;
					pNow = (CSymCalc *)pVoid;
					nNum = pNow->CheckTwoOperate(pCalc,nCurOpt);
					if ( nNum ) {
						delete pCalc;
						break;
					}
					nNum = (*pNow) % (*pCalc);
					delete pCalc;
					break;
				case 15 :
					if ( m_stkOperand.Pop( pVoid ) != GOOD ) {
				        m_nErrNo = 10;
						m_bValidResult = FALSE;
						if ( pNow ) delete pNow; 
				        return FAILURE;
					}               
//					pCalc = (CSymCalc *)pVoid;
//					nNum = pNow->CheckTwoOperate(pCalc,nCurOpt);
					pCalc = pNow;
					pNow = (CSymCalc *)pVoid;
					nNum = pNow->CheckTwoOperate(pCalc,nCurOpt);
					if ( nNum ) {
						delete pCalc;
						break;
					}
					nNum = (*pNow) + (*pCalc);
					delete pCalc;
					break;
				case 16 :
					if ( m_stkOperand.Pop( pVoid ) != GOOD ) {
				        m_nErrNo = 10;
						m_bValidResult = FALSE;
						if ( pNow ) delete pNow; 
				        return FAILURE;
					}               
//					pCalc = (CSymCalc *)pVoid;
//					nNum = pNow->CheckTwoOperate(pCalc,nCurOpt);
					pCalc = pNow;
					pNow = (CSymCalc *)pVoid;
					nNum = pNow->CheckTwoOperate(pCalc,nCurOpt);
					if ( nNum ) {
						delete pCalc;
						break;
					}
					nNum = (*pNow) - (*pCalc);
					delete pCalc;
					break;
				case 17 :
					if ( m_stkOperand.Pop( pVoid ) != GOOD ) {
				        m_nErrNo = 10;
						m_bValidResult = FALSE;
						if ( pNow ) delete pNow; 
				        return FAILURE;
					}               
//					pCalc = (CSymCalc *)pVoid;
//					nNum = pNow->CheckTwoOperate(pCalc,nCurOpt);
					pCalc = pNow;
					pNow = (CSymCalc *)pVoid;
					nNum = pNow->CheckTwoOperate(pCalc,nCurOpt);
					if ( nNum ) {
						delete pCalc;
						break;
					}
					nNum = (*pNow) >> (*pCalc);
					delete pCalc;
					break;
				case 18 :
					if ( m_stkOperand.Pop( pVoid ) != GOOD ) {
				        m_nErrNo = 10;
						m_bValidResult = FALSE;
						if ( pNow ) delete pNow; 
				        return FAILURE;
					}               
//					pCalc = (CSymCalc *)pVoid;
//					nNum = pNow->CheckTwoOperate(pCalc,nCurOpt);
					pCalc = pNow;
					pNow = (CSymCalc *)pVoid;
					nNum = pNow->CheckTwoOperate(pCalc,nCurOpt);
					if ( nNum ) {
						delete pCalc;
						break;
					}
					nNum = (*pNow) << (*pCalc);
					delete pCalc;
					break;
				case 19 :
					if ( m_stkOperand.Pop( pVoid ) != GOOD ) {
				        m_nErrNo = 10;
						m_bValidResult = FALSE;
						if ( pNow ) delete pNow; 
				        return FAILURE;
					}               
//					pCalc = (CSymCalc *)pVoid;
//					nNum = pNow->CheckTwoOperate(pCalc,nCurOpt);
					pCalc = pNow;
					pNow = (CSymCalc *)pVoid;
					nNum = pNow->CheckTwoOperate(pCalc,nCurOpt);
					if ( nNum ) {
						delete pCalc;
						break;
					}
					nNum = (*pNow) < (*pCalc);
					delete pCalc;
					break;
				case 20 :
					if ( m_stkOperand.Pop( pVoid ) != GOOD ) {
				        m_nErrNo = 10;
						m_bValidResult = FALSE;
						if ( pNow ) delete pNow; 
				        return FAILURE;
					}               
//					pCalc = (CSymCalc *)pVoid;
//					nNum = pNow->CheckTwoOperate(pCalc,nCurOpt);
					pCalc = pNow;
					pNow = (CSymCalc *)pVoid;
					nNum = pNow->CheckTwoOperate(pCalc,nCurOpt);
					if ( nNum ) {
						delete pCalc;
						break;
					}
					nNum = (*pNow) > (*pCalc);
					delete pCalc;
					break;
				case 21 :
					if ( m_stkOperand.Pop( pVoid ) != GOOD ) {
				        m_nErrNo = 10;
						m_bValidResult = FALSE;
						if ( pNow ) delete pNow; 
				        return FAILURE;
					}               
//					pCalc = (CSymCalc *)pVoid;
//					nNum = pNow->CheckTwoOperate(pCalc,nCurOpt);
					pCalc = pNow;
					pNow = (CSymCalc *)pVoid;
					nNum = pNow->CheckTwoOperate(pCalc,nCurOpt);
					if ( nNum ) {
						delete pCalc;
						break;
					}
					nNum = (*pNow) <= (*pCalc);
					delete pCalc;
					break;
				case 22 :
					if ( m_stkOperand.Pop( pVoid ) != GOOD ) {
				        m_nErrNo = 10;
						m_bValidResult = FALSE;
						if ( pNow ) delete pNow; 
				        return FAILURE;
					}               
//					pCalc = (CSymCalc *)pVoid;
//					nNum = pNow->CheckTwoOperate(pCalc,nCurOpt);
					pCalc = pNow;
					pNow = (CSymCalc *)pVoid;
					nNum = pNow->CheckTwoOperate(pCalc,nCurOpt);
					if ( nNum ) {
						delete pCalc;
						break;
					}
					nNum = (*pNow) >= (*pCalc);
					delete pCalc;
					break;
				case 23 :
					if ( m_stkOperand.Pop( pVoid ) != GOOD ) {
				        m_nErrNo = 10;
						m_bValidResult = FALSE;
						if ( pNow ) delete pNow; 
				        return FAILURE;
					}               
//					pCalc = (CSymCalc *)pVoid;
//					nNum = pNow->CheckTwoOperate(pCalc,nCurOpt);
					pCalc = pNow;
					pNow = (CSymCalc *)pVoid;
					nNum = pNow->CheckTwoOperate(pCalc,nCurOpt);
					if ( nNum ) {
						delete pCalc;
						break;
					}
					nNum = (*pNow) == (*pCalc);
					delete pCalc;
					break;
				case 24 :
					if ( m_stkOperand.Pop( pVoid ) != GOOD ) {
				        m_nErrNo = 10;
						m_bValidResult = FALSE;
						if ( pNow ) delete pNow; 
				        return FAILURE;
					}               
//					pCalc = (CSymCalc *)pVoid;
//					nNum = pNow->CheckTwoOperate(pCalc,nCurOpt);
					pCalc = pNow;
					pNow = (CSymCalc *)pVoid;
					nNum = pNow->CheckTwoOperate(pCalc,nCurOpt);
					if ( nNum ) {
						delete pCalc;
						break;
					}
					nNum = (*pNow) != (*pCalc);
					delete pCalc;
					break;
				case 25 :
					if ( m_stkOperand.Pop( pVoid ) != GOOD ) {
				        m_nErrNo = 10;
						m_bValidResult = FALSE;
						if ( pNow ) delete pNow; 
				        return FAILURE;
					}               
//					pCalc = (CSymCalc *)pVoid;
//					nNum = pNow->CheckTwoOperate(pCalc,nCurOpt);
					pCalc = pNow;
					pNow = (CSymCalc *)pVoid;
					nNum = pNow->CheckTwoOperate(pCalc,nCurOpt);
					if ( nNum ) {
						delete pCalc;
						break;
					}
					nNum = (*pNow) & (*pCalc);
					delete pCalc;
					break;
				case 26 :
					if ( m_stkOperand.Pop( pVoid ) != GOOD ) {
				        m_nErrNo = 10;
						m_bValidResult = FALSE;
						if ( pNow ) delete pNow; 
				        return FAILURE;
					}               
//					pCalc = (CSymCalc *)pVoid;
//					nNum = pNow->CheckTwoOperate(pCalc,nCurOpt);
					pCalc = pNow;
					pNow = (CSymCalc *)pVoid;
					nNum = pNow->CheckTwoOperate(pCalc,nCurOpt);
					if ( nNum ) {
						delete pCalc;
						break;
					}
					nNum = (*pNow) ^ (*pCalc);
					delete pCalc;
					break;
				case 27 :
					if ( m_stkOperand.Pop( pVoid ) != GOOD ) {
				        m_nErrNo = 10;
						m_bValidResult = FALSE;
						if ( pNow ) delete pNow; 
				        return FAILURE;
					}               
//					pCalc = (CSymCalc *)pVoid;
//					nNum = pNow->CheckTwoOperate(pCalc,nCurOpt);
					pCalc = pNow;
					pNow = (CSymCalc *)pVoid;
					nNum = pNow->CheckTwoOperate(pCalc,nCurOpt);
					if ( nNum ) {
						delete pCalc;
						break;
					}
					nNum = (*pNow) | (*pCalc);
					delete pCalc;
					break;
				case 28 :
					if ( m_stkOperand.Pop( pVoid ) != GOOD ) {
				        m_nErrNo = 10;
						m_bValidResult = FALSE;
						if ( pNow ) delete pNow; 
				        return FAILURE;
					}               
//					pCalc = (CSymCalc *)pVoid;
//					nNum = pNow->CheckTwoOperate(pCalc,nCurOpt);
					pCalc = pNow;
					pNow = (CSymCalc *)pVoid;
					nNum = pNow->CheckTwoOperate(pCalc,nCurOpt);
					if ( nNum ) {
						delete pCalc;
						break;
					}
					nNum = (*pNow) && (*pCalc);
					delete pCalc;
					break;
				case 29 :
					if ( m_stkOperand.Pop( pVoid ) != GOOD ) {
				        m_nErrNo = 10;
						m_bValidResult = FALSE;
						if ( pNow ) delete pNow; 
				        return FAILURE;
					}               
//					pCalc = (CSymCalc *)pVoid;
//					nNum = pNow->CheckTwoOperate(pCalc,nCurOpt);
					pCalc = pNow;
					pNow = (CSymCalc *)pVoid;
					nNum = pNow->CheckTwoOperate(pCalc,nCurOpt);
					if ( nNum ) {
						delete pCalc;
						break;
					}
					nNum = (*pNow) || (*pCalc);
					delete pCalc;
					break;
				case 30 :
					if ( m_stkOperand.Pop( pVoid ) != GOOD ) {
				        m_nErrNo = 10;
						m_bValidResult = FALSE;
						if ( pNow ) delete pNow; 
				        return FAILURE;
					}               
					pCalc = pNow;
					pNow = (CSymCalc *)pVoid;
					nNum = pNow->CheckAssignOperate(pCalc,nCurOpt);
					if ( 0 == nNum ) {
//						CSymCalc pSave( pNow );
						nNum = pNow->Assignment(pCalc,this);
					}
//					delete pCalc;	
					delete pNow;
					pNow = pCalc;
					break;
				case 31 :
					if ( m_stkOperand.Pop( pVoid ) != GOOD ) {
				        m_nErrNo = 10;
						m_bValidResult = FALSE;
						if ( pNow ) delete pNow; 
				        return FAILURE;
					}               
					pCalc = pNow;
					pNow = (CSymCalc *)pVoid;
					nNum = pNow->CheckAssignOperate(pCalc,nCurOpt);
					if ( 0 == nNum ) {
						CSymCalc pSave( pNow );                 
						nNum = pNow->CheckTwoOperate(pCalc,15);
						if ( 0 == nNum ) {
							nNum = (*pNow)+(*pCalc);
							if ( 0 == nNum ) {
								nNum = (&pSave)->Assignment(pNow,this);
							}
						}
					}
					delete pCalc;	
					break;
				case 32 :
					if ( m_stkOperand.Pop( pVoid ) != GOOD ) {
				        m_nErrNo = 10;
						m_bValidResult = FALSE;
						if ( pNow ) delete pNow; 
				        return FAILURE;
					}               
					pCalc = pNow;
					pNow = (CSymCalc *)pVoid;
					nNum = pNow->CheckAssignOperate(pCalc,nCurOpt);
					if ( 0 == nNum ) {
						CSymCalc pSave( pNow );                 
						nNum = pNow->CheckTwoOperate(pCalc,16);
						if ( 0 == nNum ) {
							nNum = (*pNow)-(*pCalc);
							if ( 0 == nNum ) {
								nNum = (&pSave)->Assignment(pNow,this);
							}
						}
					}
					delete pCalc;	
					break;
				case 33 :
					if ( m_stkOperand.Pop( pVoid ) != GOOD ) {
				        m_nErrNo = 10;
						m_bValidResult = FALSE;
						if ( pNow ) delete pNow; 
				        return FAILURE;
					}               
					pCalc = pNow;
					pNow = (CSymCalc *)pVoid;
					nNum = pNow->CheckAssignOperate(pCalc,nCurOpt);
					if ( 0 == nNum ) {
						CSymCalc pSave( pNow );                 
						nNum = pNow->CheckTwoOperate(pCalc,12);
						if ( 0 == nNum ) {
							nNum = (*pNow)*(*pCalc);
							if ( 0 == nNum ) {
								nNum = (&pSave)->Assignment(pNow,this);
							}
						}
					}
					delete pCalc;	
					break;
				case 34 :
					if ( m_stkOperand.Pop( pVoid ) != GOOD ) {
				        m_nErrNo = 10;
						m_bValidResult = FALSE;
						if ( pNow ) delete pNow; 
				        return FAILURE;
					}               
					pCalc = pNow;
					pNow = (CSymCalc *)pVoid;
					nNum = pNow->CheckAssignOperate(pCalc,nCurOpt);
					if ( 0 == nNum ) {
						CSymCalc pSave( pNow );                 
						nNum = pNow->CheckTwoOperate(pCalc,13);
						if ( 0 == nNum ) {
							nNum = (*pNow)/(*pCalc);
							if ( 0 == nNum ) {
								nNum = (&pSave)->Assignment(pNow,this);
							}
						}
					}
					delete pCalc;	
					break;
				case 35 :
					if ( m_stkOperand.Pop( pVoid ) != GOOD ) {
				        m_nErrNo = 10;
						m_bValidResult = FALSE;
						if ( pNow ) delete pNow; 
				        return FAILURE;
					}               
					pCalc = pNow;
					pNow = (CSymCalc *)pVoid;
					nNum = pNow->CheckAssignOperate(pCalc,nCurOpt);
					if ( 0 == nNum ) {
						CSymCalc pSave( pNow );                 
						nNum = pNow->CheckTwoOperate(pCalc,14);
						if ( 0 == nNum ) {
							nNum = (*pNow)%(*pCalc);
							if ( 0 == nNum ) {
								nNum = (&pSave)->Assignment(pNow,this);
							}
						}
					}
					delete pCalc;	
					break;
				case 36 : // pre-increment
					nNum = pNow->CheckOperate(nCurOpt);
					if ( 0 == nNum ) {
						CSymCalc pSave( pNow );                 
						nNum = pNow->Increment();
						if ( 0 == nNum ) {
							nNum = (&pSave)->Assignment(pNow,this);
						}
					}
					break;
				case 37 : // pre-decrement
					nNum = pNow->CheckOperate(nCurOpt);
					if ( 0 == nNum ) {
						CSymCalc pSave( pNow );                 
						nNum = pNow->Decrement();
						if ( 0 == nNum ) {
							nNum = (&pSave)->Assignment(pNow,this);
						}
					}
					break;
				case 38 : // post-increment
					nNum = pNow->CheckOperate(nCurOpt);
					if ( 0 == nNum ) {
						CSymCalc pSave( pNow );                 
						nNum = pNow->Increment();
						if ( 0 == nNum ) {
							nNum = (&pSave)->Assignment(pNow,this);
						}
						if ( !nNum ) nNum = pNow->Decrement();
					}
					break;
				case 39 : // post-decrement
					nNum = pNow->CheckOperate(nCurOpt);
					if ( 0 == nNum ) {
						CSymCalc pSave( pNow );                 
						nNum = pNow->Decrement();
						if ( 0 == nNum ) {
							nNum = (&pSave)->Assignment(pNow,this);
						}
						if ( !nNum ) nNum = pNow->Increment();
					}
					break;
				default :
					nNum = 10;
					break;
				}
				if ( nNum ) {
					m_nErrNo = nNum;
					m_bValidResult = FALSE;
					if ( pNow ) delete pNow; 
			        return FAILURE;
				}
				if ( GOOD == m_stkOperator.IsEmpty() ) {
//					if ( nFlag ) nCurOpt = 0;
//					else nCurOpt = nOpt;
					nCurOpt = nOpt;
					break;
				}
				if ( m_stkOperator.Pop( pVoid ) != GOOD ) {
			        m_nErrNo = 10;
					m_bValidResult = FALSE;
					if ( pNow ) delete pNow; 
			        return FAILURE;
				}               
				pInt = (int *)pVoid;
//				if ( nFlag ) {
//					nCurOpt = *pInt;
//					delete pInt;
//					break;
//				}
				nNum = SymCheckOptPre(*pInt,nOpt);
				if ( nNum == 0 ) {
			        m_nErrNo = 10;
					m_bValidResult = FALSE;
					if ( pNow ) delete pNow; 
			        return FAILURE;
				}
				else if ( nNum > 0 ) {
					nCurOpt = *pInt;
					delete pInt;
				}
				else {
					if ( m_stkOperator.Push( pInt ) != GOOD ) {
				        m_nErrNo = 10;
						m_bValidResult = FALSE;
						if ( pNow ) delete pNow; 
				        return FAILURE;
					}               
					nCurOpt = nOpt;
					break;
				}
			}													
		}
		else {
			if ( nCurOpt ) {
				pInt = new int;
				if ( pInt == 0 ) {	
			        m_nErrNo = 1;
					m_bValidResult = FALSE;
					if ( pNow ) delete pNow; 
			        return FAILURE;
				}               
				*pInt = nCurOpt;      
				if ( m_stkOperator.Push( pInt ) != GOOD ) {
			        m_nErrNo = 9;
					m_bValidResult = FALSE;
					if ( pNow ) delete pNow; 
			        return FAILURE;
				}
			}
			nCurOpt = nOpt;
		}
	}
	if ( m_stkOperator.IsEmpty() != GOOD ||
		m_stkOperand.IsEmpty() != GOOD || pNow == 0 || nCurOpt != 0 ) {
        m_nErrNo = 10;
		m_bValidResult = FALSE;
		if ( pNow ) delete pNow; 
        return FAILURE;
	}
	
	if ( m_pValue ) delete m_pValue;
	m_pValue = pNow;                
	m_nErrNo = m_pValue->CheckValue();
	if ( m_nErrNo ) {
		m_bValidResult = FALSE;
        return FAILURE;
	}
//	m_pValue->Display();
	return GOOD;		
}

int CSymSyntax::GetExpAddr(ADDRESS_TYPE& addr) 
{
	if ( m_pValue == 0 ) return FAILURE;
	addr.addr = m_pValue->addr.addr;
	addr.segType = m_pValue->addr.segType;
	return GOOD;
}               

int CSymSyntax::GetTypeIndex(TYPE_INDEX& type)
{                
	int nResult;
	if ( m_pValue == 0 ) return FAILURE;
	if ( GOOD != IsComplexResult(nResult) ) return FAILURE;
	if ( nResult ) type = m_pValue->typeIndex;
	else type = m_pValue->typeValue;
	return GOOD;
}               

int CSymSyntax::IsComplexResult(int& nFlag)
{
	nFlag = 0;
	if ( m_pValue == 0 ) return FAILURE;
	if ( SYMTOKEN_SYMBOL == m_pValue->symType && 
		1 == m_pValue->nComplexType ) nFlag = 1;
	return GOOD;
}               
                               
int CSymSyntax::IsSymbol(int& nFlag)
{
	nFlag = 0;
	if ( m_pValue == 0 ) return FAILURE;
	if ( SYMTOKEN_SYMBOL == m_pValue->symType ) nFlag = 1;
	return GOOD;
}               
                               
int CSymSyntax::IsUserVariable()
{
	if ( m_pValue == 0 ) return FAILURE;
	if ( SYMTOKEN_SYMBOL != m_pValue->symType ) return FAILURE;
	if ( 0 != m_pValue->nComplexType ) return FAILURE;
	if ( -1 == m_pValue->m_nTkNum ) return FAILURE;
	return GOOD;
}               
                               
int CSymSyntax::ReflushExpress(void)
{
	int nTokenNum , i , nErr;             
	char *pName;
	SYM_TOKEN_NODE *pNode;  
	
	if ( (nTokenNum = GetTokenNum()) == 0 ) {
		m_bValidResult = FALSE;
		m_nErrNo = 2;
		return FAILURE;
	}
	for( i = 0; i < nTokenNum ;i++ ) {
		if ( GOOD != GetOneTokenFromList(i+1, pNode) ) {
			m_bValidResult = FALSE;
			m_nErrNo = 6;
			return FAILURE;
        }
		nErr = GetOneTokenName(i,pName);
		if ( 0 != nErr ) {
			m_bValidResult = FALSE;
			delete []pName;
			m_nErrNo = 6;
			return FAILURE;
        }
		nErr = UpdateSymbol(pNode,pName);
		if ( 0 != nErr ) {
			m_bValidResult = FALSE;
			delete []pName;
			m_nErrNo = 6;
			return FAILURE;
        }
        delete []pName;
	}    
//	if ( GOOD != CheckSyntax() ) {
//		return FAILURE;
//	}
	if ( GOOD != CalculateValue() ) {
		return FAILURE;
	}                                      
	return GOOD;
}	

/******************************** E O F ***********************************/
