/**************************************************************
 *
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you under the Apache License, Version 2.0 (the
 * "License"); you may not use this file except in compliance
 * with the License.  You may obtain a copy of the License at
 *
 *   http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing,
 * software distributed under the License is distributed on an
 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 * KIND, either express or implied.  See the License for the
 * specific language governing permissions and limitations
 * under the License.
 *
 *************************************************************/



// MARKER(update_precomp.py): autogen include statement, do not remove
#include "precompiled_basic.hxx"

#include "sbcomp.hxx"
#include <basic/sbx.hxx>		// w.g. ...IMPL_REF(...sbxvariable)
#include "expr.hxx"

/***************************************************************************
|*
|*      SbiExpression
|*
***************************************************************************/

SbiExpression::SbiExpression( SbiParser* p, SbiExprType t,
	SbiExprMode eMode, const KeywordSymbolInfo* pKeywordSymbolInfo )
{
	pParser = p;
	bError = bByVal = bBased = bBracket = sal_False;
	nParenLevel = 0;
	eCurExpr = t;
	m_eMode = eMode;
	pNext = NULL;
	pExpr = (t != SbSTDEXPR ) ? Term( pKeywordSymbolInfo ) : Boolean();
	if( t != SbSYMBOL )
		pExpr->Optimize();
	if( t == SbLVALUE && !pExpr->IsLvalue() )
		p->Error( SbERR_LVALUE_EXPECTED );
	if( t == SbOPERAND && !IsVariable() )
		p->Error( SbERR_VAR_EXPECTED );
}

SbiExpression::SbiExpression( SbiParser* p, double n, SbxDataType t )
{
	pParser = p;
	eCurExpr = SbOPERAND;
	pNext = NULL;
	bError = bByVal = bBased = bBracket = sal_False;
	pExpr = new SbiExprNode( pParser, n, t );
	pExpr->Optimize();
}

SbiExpression::SbiExpression( SbiParser* p, const String& r )
{
	pParser = p;
	pNext = NULL;
	bError = bByVal = bBased = bBracket = sal_False;
	eCurExpr = SbOPERAND;
	pExpr = new SbiExprNode( pParser, r );
}

SbiExpression::SbiExpression( SbiParser* p, const SbiSymDef& r, SbiExprList* pPar )
{
	pParser = p;
	pNext = NULL;
	bError = bByVal = bBased = bBracket = sal_False;
	eCurExpr = SbOPERAND;
	pExpr = new SbiExprNode( pParser, r, SbxVARIANT, pPar );
}

SbiExpression::SbiExpression( SbiParser* p, SbiToken t )
{
	pParser = p;
	pNext = NULL;
	bError = bByVal = bBased = bBracket = sal_False;
	eCurExpr = SbOPERAND;
	pExpr = new SbiExprNode( pParser, NULL, t, NULL );
}

SbiExpression::~SbiExpression()
{
	delete pExpr;
}

// Einlesen eines kompletten Bezeichners
// Ein Bezeichner hat folgende Form:
// name[(Parameter)][.Name[(parameter)]]...
// Strukturelemente werden ueber das Element pNext verkoppelt,
// damit sie nicht im Baum stehen.

// Folgen Parameter ohne Klammer? Dies kann eine Zahl, ein String,
// ein Symbol oder auch ein Komma sein (wenn der 1. Parameter fehlt)

static sal_Bool DoParametersFollow( SbiParser* p, SbiExprType eCurExpr, SbiToken eTok )
{
	if( eTok == LPAREN )
		return sal_True;
	// Aber nur, wenn CALL-aehnlich!
	if( !p->WhiteSpace() || eCurExpr != SbSYMBOL )
		return sal_False;
	if (   eTok == NUMBER || eTok == MINUS || eTok == FIXSTRING
		|| eTok == SYMBOL || eTok == COMMA  || eTok == DOT || eTok == NOT || eTok == BYVAL )
	{
		return sal_True;
	}
	else // check for default params with reserved names ( e.g. names of tokens )
	{
		SbiTokenizer tokens( *(SbiTokenizer*)p );
		// Urk the Next() / Peek() symantics are... weird
		tokens.Next();
		if ( tokens.Peek() == ASSIGN )
			return sal_True;
	}
	return sal_False;
}

// Definition eines neuen Symbols

static SbiSymDef* AddSym
	( SbiToken eTok, SbiSymPool& rPool, SbiExprType eCurExpr,
	  const String& rName, SbxDataType eType, SbiParameters* pPar )
{
	SbiSymDef* pDef;
	// A= ist keine Prozedur
	sal_Bool bHasType = sal_Bool( eTok == EQ || eTok == DOT );
	if( ( !bHasType && eCurExpr == SbSYMBOL ) || pPar )
	{
		// Dies ist also eine Prozedur
		// da suche man doch den richtigen Pool raus, da Procs
		// immer in einem Public-Pool landen muessen
		SbiSymPool* pPool = &rPool;
		if( pPool->GetScope() != SbPUBLIC )
			pPool = &rPool.GetParser()->aPublics;
		SbiProcDef* pProc = pPool->AddProc( rName );

		// Sonderbehandlung fuer Colls wie Documents(1)
		if( eCurExpr == SbSTDEXPR )
			bHasType = sal_True;

		pDef = pProc;
		pDef->SetType( bHasType ? eType : SbxEMPTY );
		if( pPar )
		{
			// Dummy-Parameter generieren
			sal_uInt16 n = 1;
			for( short i = 0; i < pPar->GetSize(); i++ )
			{
				String aPar = String::CreateFromAscii( "PAR" );
				aPar += ++n;
				pProc->GetParams().AddSym( aPar );
			}
		}
	}
	else
	{
		// oder ein normales Symbol
		pDef = rPool.AddSym( rName );
		pDef->SetType( eType );
	}
	return pDef;
}

// Zur Zeit sind sogar Keywords zugelassen (wg. gleichnamiger Dflt-Properties)

SbiExprNode* SbiExpression::Term( const KeywordSymbolInfo* pKeywordSymbolInfo )
{
	if( pParser->Peek() == DOT )
	{
		// eine WITH-Variable
		SbiExprNode* pWithVar = pParser->GetWithVar();
		// #26608: Ans Ende der Node-Kette gehen, um richtiges Objekt zu uebergeben
		SbiSymDef* pDef = pWithVar ? pWithVar->GetRealVar() : NULL;
		SbiExprNode* pNd = NULL;
		if( !pDef )
		{
			pParser->Next();
		}
		else
		{
			pNd = ObjTerm( *pDef );
			if( pNd )
				pNd->SetWithParent( pWithVar );
		}
		if( !pNd )
		{
			pParser->Error( SbERR_UNEXPECTED, DOT );
			pNd = new SbiExprNode( pParser, 1.0, SbxDOUBLE );
		}
		return pNd;
	}

	SbiToken eTok = (pKeywordSymbolInfo == NULL) ? pParser->Next() : pKeywordSymbolInfo->m_eTok;
	// Anfang des Parsings merken
	pParser->LockColumn();
	String aSym( (pKeywordSymbolInfo == NULL) ? pParser->GetSym() : pKeywordSymbolInfo->m_aKeywordSymbol );
	SbxDataType eType = (pKeywordSymbolInfo == NULL) ? pParser->GetType() : pKeywordSymbolInfo->m_eSbxDataType;
	SbiParameters* pPar = NULL;
	SbiExprListVector* pvMoreParLcl = NULL;
	// Folgen Parameter?
	SbiToken eNextTok = pParser->Peek();
	// Ist es ein benannter Parameter?
	// Dann einfach eine Stringkonstante erzeugen. Diese wird
	// im SbiParameters-ctor erkannt und weiterverarbeitet
	if( eNextTok == ASSIGN )
	{
		pParser->UnlockColumn();
		return new SbiExprNode( pParser, aSym );
	}
	// ab hier sind keine Keywords zugelassen!
	if( pParser->IsKwd( eTok ) )
	{
		if( pParser->IsCompatible() && eTok == INPUT )
		{
			eTok = SYMBOL;
		}
		else
		{
			pParser->Error( SbERR_SYNTAX );
			bError = sal_True;
		}
	}

	if( DoParametersFollow( pParser, eCurExpr, eTok = eNextTok ) )
	{
		bool bStandaloneExpression = (m_eMode == EXPRMODE_STANDALONE);
		pPar = new SbiParameters( pParser, bStandaloneExpression );
		bError |= !pPar->IsValid();
		if( !bError )
			bBracket = pPar->IsBracket();
		eTok = pParser->Peek();

		// i75443 check for additional sets of parameters
		while( eTok == LPAREN )
		{
			if( pvMoreParLcl == NULL )
				pvMoreParLcl = new SbiExprListVector();
			SbiParameters* pAddPar = new SbiParameters( pParser );
			pvMoreParLcl->push_back( pAddPar );
			bError |= !pPar->IsValid();
			eTok = pParser->Peek();
		}
	}
	// Es koennte ein Objektteil sein, wenn . oder ! folgt
	// Bei . muss aber die Variable bereits definiert sein; wenn pDef
	// nach der Suche NULL ist, isses ein Objekt!
	sal_Bool bObj = sal_Bool( ( eTok == DOT || eTok == EXCLAM )
					&& !pParser->WhiteSpace() );
	if( bObj )
	{
		bBracket = sal_False;	// Now the bracket for the first term is obsolete
		if( eType == SbxVARIANT )
			eType = SbxOBJECT;
		else
		{
			// Name%. geht wirklich nicht!
			pParser->Error( SbERR_BAD_DECLARATION, aSym );
			bError = sal_True;
		}
	}
	// Suche:
	SbiSymDef* pDef = pParser->pPool->Find( aSym );
	if( !pDef )
	{
		// Teil der Runtime-Library?
		// AB 31.3.1996: In Parser-Methode ausgelagert
		// (wird auch in SbiParser::DefVar() in DIM.CXX benoetigt)
		pDef = pParser->CheckRTLForSym( aSym, eType );

		// #i109184: Check if symbol is or later will be defined inside module
		SbModule& rMod = pParser->aGen.GetModule();
		SbxArray* pModMethods = rMod.GetMethods();
		if( pModMethods->Find( aSym, SbxCLASS_DONTCARE ) )
			pDef = NULL;
	}
	if( !pDef )
	{
		// Falls ein Punkt angegeben war, isses Teil eines Objekts,
		// also muss der Returnwert ein Objekt sein
		if( bObj )
			eType = SbxOBJECT;
		pDef = AddSym( eTok, *pParser->pPool, eCurExpr, aSym, eType, pPar );
		// Looks like this is a local ( but undefined variable )
		// if it is in a static procedure then make this Symbol
		// static
		if ( !bObj && pParser->pProc && pParser->pProc->IsStatic() )
		    pDef->SetStatic();
	}
	else
	{

		// Symbol ist bereits definiert.
		// Ist es eine Konstante?
		SbiConstDef* pConst = pDef->GetConstDef();
		if( pConst )
		{
			if( pConst->GetType() == SbxSTRING )
				return new SbiExprNode( pParser, pConst->GetString() );
			else
				return new SbiExprNode( pParser, pConst->GetValue(), pConst->GetType() );
		}
		// Hat es Dimensionen,
		// und sind auch Parameter angegeben?
		// (Wobei 0 Parameter () entsprechen)
		if( pDef->GetDims() )
		{
			if( pPar && pPar->GetSize() && pPar->GetSize() != pDef->GetDims() )
				pParser->Error( SbERR_WRONG_DIMS );
		}
		if( pDef->IsDefinedAs() )
		{
			SbxDataType eDefType = pDef->GetType();
			// #119187 Only error if types conflict
			if( eType >= SbxINTEGER && eType <= SbxSTRING && eType != eDefType )
			{
				// Wie? Erst mit AS definieren und dann einen Suffix nehmen?
				pParser->Error( SbERR_BAD_DECLARATION, aSym );
				bError = sal_True;
			}
			else if ( eType == SbxVARIANT )
				// Falls nix angegeben, den Typ des Eintrags nehmen
				// aber nur, wenn die Var nicht mit AS XXX definiert ist
				// damit erwischen wir n% = 5 : print n
				eType = eDefType;
		}
		// Typcheck bei Variablen:
		// ist explizit im Scanner etwas anderes angegeben?
		// Bei Methoden ist dies OK!
		if( eType != SbxVARIANT &&			// Variant nimmt alles
			eType != pDef->GetType() &&
			!pDef->GetProcDef() )
		{
			// Es kann sein, dass pDef ein Objekt beschreibt, das bisher
			// nur als SbxVARIANT erkannt wurde, dann Typ von pDef aendern
			// AB, 16.12.95 (Vielleicht noch aehnliche Faelle moeglich ?!?)
			if( eType == SbxOBJECT && pDef->GetType() == SbxVARIANT )
			{
				pDef->SetType( SbxOBJECT );
			}
			else
			{
				pParser->Error( SbERR_BAD_DECLARATION, aSym );
				bError = sal_True;
			}
		}
	}
	SbiExprNode* pNd = new SbiExprNode( pParser, *pDef, eType );
	if( !pPar )
		pPar = new SbiParameters( pParser,sal_False,sal_False );
	pNd->aVar.pPar = pPar;
	pNd->aVar.pvMorePar = pvMoreParLcl;
	if( bObj )
	{
		// AB, 8.1.95: Objekt kann auch vom Typ SbxVARIANT sein
		if( pDef->GetType() == SbxVARIANT )
			pDef->SetType( SbxOBJECT );
		// Falls wir etwas mit Punkt einscannen, muss der
		// Typ SbxOBJECT sein
		if( pDef->GetType() != SbxOBJECT && pDef->GetType() != SbxVARIANT )
		{
			pParser->Error( SbERR_BAD_DECLARATION, aSym );
			bError = sal_True;
		}
		if( !bError )
			pNd->aVar.pNext = ObjTerm( *pDef );
	}
	// Merken der Spalte 1 wieder freigeben
	pParser->UnlockColumn();
	return pNd;
}

// Aufbau eines Objekt-Terms. Ein derartiger Term ist Teil
// eines Ausdrucks, der mit einer Objektvariablen beginnt.

SbiExprNode* SbiExpression::ObjTerm( SbiSymDef& rObj )
{
	pParser->Next();
	SbiToken eTok = pParser->Next();
	if( eTok != SYMBOL && !pParser->IsKwd( eTok ) && !pParser->IsExtra( eTok ) )
	{
		// #66745 Einige Operatoren koennen in diesem Kontext auch
		// als Identifier zugelassen werden, wichtig fuer StarOne
		if( eTok != MOD && eTok != NOT && eTok != AND && eTok != OR &&
			eTok != XOR && eTok != EQV && eTok != IMP && eTok != IS )
		{
			pParser->Error( SbERR_VAR_EXPECTED );
			bError = sal_True;
		}
	}
	/* #118410 Allow type for Class methods and RTL object, e.g. RTL.Chr$(97)
	else
	{
		if( pParser->GetType() != SbxVARIANT )
			pParser->Error( SbERR_SYNTAX ), bError = sal_True;
	}
	*/
	if( bError )
		return NULL;

	String aSym( pParser->GetSym() );
	SbxDataType eType = pParser->GetType();
	SbiParameters* pPar = NULL;
	SbiExprListVector* pvMoreParLcl = NULL;
	eTok = pParser->Peek();
	// Parameter?
	if( DoParametersFollow( pParser, eCurExpr, eTok ) )
	{
		bool bStandaloneExpression = false;
		pPar = new SbiParameters( pParser, bStandaloneExpression );
		bError |= !pPar->IsValid();
		eTok = pParser->Peek();

		// i109624 check for additional sets of parameters
		while( eTok == LPAREN )
		{
			if( pvMoreParLcl == NULL )
				pvMoreParLcl = new SbiExprListVector();
			SbiParameters* pAddPar = new SbiParameters( pParser );
			pvMoreParLcl->push_back( pAddPar );
			bError |= !pPar->IsValid();
			eTok = pParser->Peek();
		}

	}
	sal_Bool bObj = sal_Bool( ( eTok == DOT || eTok == EXCLAM ) && !pParser->WhiteSpace() );
	if( bObj )
	{
		if( eType == SbxVARIANT )
			eType = SbxOBJECT;
		else
		{
			// Name%. geht wirklich nicht!
			pParser->Error( SbERR_BAD_DECLARATION, aSym );
			bError = sal_True;
		}
	}

	// Der Symbol-Pool eines Objekts ist immer PUBLIC
	SbiSymPool& rPool = rObj.GetPool();
	rPool.SetScope( SbPUBLIC );
	SbiSymDef* pDef = rPool.Find( aSym );
	if( !pDef )
	{
		pDef = AddSym( eTok, rPool, eCurExpr, aSym, eType, pPar );
		pDef->SetType( eType );
	}

	SbiExprNode* pNd = new SbiExprNode( pParser, *pDef, eType );
	pNd->aVar.pPar = pPar;
	pNd->aVar.pvMorePar = pvMoreParLcl;
	if( bObj )
	{
		// Falls wir etwas mit Punkt einscannen, muss der
		// Typ SbxOBJECT sein

		// AB, 3.1.96
		// Es kann sein, dass pDef ein Objekt beschreibt, das bisher
		// nur als SbxVARIANT erkannt wurde, dann Typ von pDef aendern
		if( pDef->GetType() == SbxVARIANT )
			pDef->SetType( SbxOBJECT );

		if( pDef->GetType() != SbxOBJECT )
		{
			pParser->Error( SbERR_BAD_DECLARATION, aSym );
			bError = sal_True;
		}
		if( !bError )
		{
			pNd->aVar.pNext = ObjTerm( *pDef );
			pNd->eType = eType;
		}
	}
	return pNd;
}

// Als Operanden kommen in Betracht:
//      Konstante
//      skalare Variable
//      Strukturelemente
//      Array-Elemente
//      Funktionen
//      geklammerte Ausdruecke

SbiExprNode* SbiExpression::Operand( bool bUsedForTypeOf )
{
	SbiExprNode *pRes;
	SbiToken eTok;

	// Operand testen:
	switch( eTok = pParser->Peek() )
	{
		case SYMBOL:
			pRes = Term();
			// process something like "IF Not r Is Nothing Then .."
			if( !bUsedForTypeOf && pParser->IsVBASupportOn() && pParser->Peek() == IS )
			{
				eTok = pParser->Next();
				pRes = new SbiExprNode( pParser, pRes, eTok, Like() );
			}
			break;
		case DOT:	// .with
			pRes = Term(); break;
		case NUMBER:
			pParser->Next();
			pRes = new SbiExprNode( pParser, pParser->GetDbl(), pParser->GetType() );
			break;
		case FIXSTRING:
			pParser->Next();
			pRes = new SbiExprNode( pParser, pParser->GetSym() ); break;
		case LPAREN:
			pParser->Next();
			if( nParenLevel == 0 && m_eMode == EXPRMODE_LPAREN_PENDING && pParser->Peek() == RPAREN )
			{
				m_eMode = EXPRMODE_EMPTY_PAREN;
				pRes = new SbiExprNode();	// Dummy node
				pParser->Next();
				break;
			}
			nParenLevel++;
			pRes = Boolean();
			if( pParser->Peek() != RPAREN )
			{
				// If there was a LPARAM, it does not belong to the expression
				if( nParenLevel == 1 && m_eMode == EXPRMODE_LPAREN_PENDING )
					m_eMode = EXPRMODE_LPAREN_NOT_NEEDED;
				else
					pParser->Error( SbERR_BAD_BRACKETS );
			}
			else
			{
				pParser->Next();
				if( nParenLevel == 1 && m_eMode == EXPRMODE_LPAREN_PENDING )
				{
					SbiToken eTokAfterRParen = pParser->Peek();
					if( eTokAfterRParen == EQ || eTokAfterRParen == LPAREN || eTokAfterRParen == DOT )
						m_eMode = EXPRMODE_ARRAY_OR_OBJECT;
					else
						m_eMode = EXPRMODE_STANDARD;
				}
			}
			nParenLevel--;
			pRes->bComposite = sal_True;
			break;
		default:
			// Zur Zeit sind Keywords hier OK!
			if( pParser->IsKwd( eTok ) )
				pRes = Term();
			else
			{
				pParser->Next();
				pRes = new SbiExprNode( pParser, 1.0, SbxDOUBLE ); // bei Fehlern
				pParser->Error( SbERR_UNEXPECTED, eTok );
			}
	}
	return pRes;
}

SbiExprNode* SbiExpression::Unary()
{
	SbiExprNode* pNd;
	SbiToken eTok = pParser->Peek();
	switch( eTok )
	{
		case MINUS:
			eTok = NEG;
			pParser->Next();
			pNd = new SbiExprNode( pParser, Unary(), eTok, NULL );
			break;
		case NOT:
			if( pParser->IsVBASupportOn() )
			{
				pNd = Operand();
			}
			else
			{
				pParser->Next();
				pNd = new SbiExprNode( pParser, Unary(), eTok, NULL );
			}
			break;
		case PLUS:
			pParser->Next();
			pNd = Unary();
			break;
		case TYPEOF:
		{
			pParser->Next();
			bool bUsedForTypeOf = true;
			SbiExprNode* pObjNode = Operand( bUsedForTypeOf );
			pParser->TestToken( IS );
			String aDummy;
			SbiSymDef* pTypeDef = new SbiSymDef( aDummy );
			pParser->TypeDecl( *pTypeDef, sal_True );
			pNd = new SbiExprNode( pParser, pObjNode, pTypeDef->GetTypeId() );
			break;
		}
		case NEW:
		{
			pParser->Next();
			String aStr;
			SbiSymDef* pTypeDef = new SbiSymDef( aStr );
			pParser->TypeDecl( *pTypeDef, sal_True );
			pNd = new SbiExprNode( pParser, pTypeDef->GetTypeId() );
			break;
		}
		default:
			pNd = Operand();
	}
	return pNd;
}

SbiExprNode* SbiExpression::Exp()
{
	SbiExprNode* pNd = Unary();
	if( m_eMode != EXPRMODE_EMPTY_PAREN )
	{
		while( pParser->Peek() == EXPON ) {
			SbiToken eTok = pParser->Next();
			pNd = new SbiExprNode( pParser, pNd, eTok, Unary() );
		}
	}
	return pNd;
}

SbiExprNode* SbiExpression::MulDiv()
{
	SbiExprNode* pNd = Exp();
	if( m_eMode != EXPRMODE_EMPTY_PAREN )
	{
		for( ;; )
		{
			SbiToken eTok = pParser->Peek();
			if( eTok != MUL && eTok != DIV )
				break;
			eTok = pParser->Next();
			pNd = new SbiExprNode( pParser, pNd, eTok, Exp() );
		}
	}
	return pNd;
}

SbiExprNode* SbiExpression::IntDiv()
{
	SbiExprNode* pNd = MulDiv();
	if( m_eMode != EXPRMODE_EMPTY_PAREN )
	{
		while( pParser->Peek() == IDIV ) {
			SbiToken eTok = pParser->Next();
			pNd = new SbiExprNode( pParser, pNd, eTok, MulDiv() );
		}
	}
	return pNd;
}

SbiExprNode* SbiExpression::Mod()
{
	SbiExprNode* pNd = IntDiv();
	if( m_eMode != EXPRMODE_EMPTY_PAREN )
	{
		while( pParser->Peek() == MOD ) {
			SbiToken eTok = pParser->Next();
			pNd = new SbiExprNode( pParser, pNd, eTok, IntDiv() );
		}
	}
	return pNd;
}

SbiExprNode* SbiExpression::AddSub()
{
	SbiExprNode* pNd = Mod();
	if( m_eMode != EXPRMODE_EMPTY_PAREN )
	{
		for( ;; )
		{
			SbiToken eTok = pParser->Peek();
			if( eTok != PLUS && eTok != MINUS )
				break;
			eTok = pParser->Next();
			pNd = new SbiExprNode( pParser, pNd, eTok, Mod() );
		}
	}
	return pNd;
}

SbiExprNode* SbiExpression::Cat()
{
	SbiExprNode* pNd = AddSub();
	if( m_eMode != EXPRMODE_EMPTY_PAREN )
	{
		for( ;; )
		{
			SbiToken eTok = pParser->Peek();
			if( eTok != CAT )
				break;
			eTok = pParser->Next();
			pNd = new SbiExprNode( pParser, pNd, eTok, AddSub() );
		}
	}
	return pNd;
}

SbiExprNode* SbiExpression::Comp()
{
	SbiExprNode* pNd = Cat();
	if( m_eMode != EXPRMODE_EMPTY_PAREN )
	{
		short nCount = 0;
		for( ;; )
		{
			SbiToken eTok = pParser->Peek();
			if( m_eMode == EXPRMODE_ARRAY_OR_OBJECT )
				break;
			if( eTok != EQ && eTok != NE && eTok != LT
			 && eTok != GT && eTok != LE && eTok != GE )
				break;
			eTok = pParser->Next();
			pNd = new SbiExprNode( pParser, pNd, eTok, Cat() );
			nCount++;
		}
	}
	return pNd;
}

SbiExprNode* SbiExpression::VBA_Not()
{
	SbiExprNode* pNd = NULL;

	SbiToken eTok = pParser->Peek();
	if( eTok == NOT )
	{
		pParser->Next();
		pNd = new SbiExprNode( pParser, VBA_Not(), eTok, NULL );
	}
	else
	{
		pNd = Comp();
	}
	return pNd;
}

SbiExprNode* SbiExpression::Like()
{
	SbiExprNode* pNd = pParser->IsVBASupportOn() ? VBA_Not() : Comp();
	if( m_eMode != EXPRMODE_EMPTY_PAREN )
	{
		short nCount = 0;
		while( pParser->Peek() == LIKE ) {
			SbiToken eTok = pParser->Next();
			pNd = new SbiExprNode( pParser, pNd, eTok, Comp() ), nCount++;
		}
		// Mehrere Operatoren hintereinander gehen nicht
		if( nCount > 1 )
		{
			pParser->Error( SbERR_SYNTAX );
			bError = sal_True;
		}
	}
	return pNd;
}

SbiExprNode* SbiExpression::Boolean()
{
	SbiExprNode* pNd = Like();
	if( m_eMode != EXPRMODE_EMPTY_PAREN )
	{
		for( ;; )
		{
			SbiToken eTok = pParser->Peek();
			if( eTok != AND && eTok != OR && eTok != XOR
			 && eTok != EQV && eTok != IMP && eTok != IS )
				break;
			eTok = pParser->Next();
			pNd = new SbiExprNode( pParser, pNd, eTok, Like() );
		}
	}
	return pNd;
}

/***************************************************************************
|*
|*      SbiConstExpression
|*
***************************************************************************/

// Parsing einer Expression, die sich zu einer numerischen
// Konstanten verarbeiten laesst.

SbiConstExpression::SbiConstExpression( SbiParser* p ) : SbiExpression( p )
{
	if( pExpr->IsConstant() )
	{
		eType = pExpr->GetType();
		if( pExpr->IsNumber() )
		{
			nVal = pExpr->nVal;
		}
		else
		{
			nVal = 0;
			aVal = pExpr->aStrVal;
		}
	}
	else
	{
		// #40204 Spezialbehandlung fuer sal_Bool-Konstanten
		sal_Bool bIsBool = sal_False;
		if( pExpr->eNodeType == SbxVARVAL )
		{
			SbiSymDef* pVarDef = pExpr->GetVar();

			// Ist es eine sal_Bool-Konstante?
			sal_Bool bBoolVal = sal_False;
			if( pVarDef->GetName().EqualsIgnoreCaseAscii( "true" ) )
			//if( pVarDef->GetName().ICompare( "true" ) == COMPARE_EQUAL )
			{
				bIsBool = sal_True;
				bBoolVal = sal_True;
			}
			else if( pVarDef->GetName().EqualsIgnoreCaseAscii( "false" ) )
			//else if( pVarDef->GetName().ICompare( "false" ) == COMPARE_EQUAL )
			{
				bIsBool = sal_True;
				bBoolVal = sal_False;
			}

			// Wenn es ein sal_Bool ist, Node austauschen
			if( bIsBool )
			{
				delete pExpr;
				pExpr = new SbiExprNode( pParser, (bBoolVal ? SbxTRUE : SbxFALSE), SbxINTEGER );
				eType = pExpr->GetType();
				nVal = pExpr->nVal;
			}
		}

		if( !bIsBool )
		{
			pParser->Error( SbERR_SYNTAX );
			eType = SbxDOUBLE;
			nVal = 0;
		}
	}
}

short SbiConstExpression::GetShortValue()
{
	if( eType == SbxSTRING )
	{
		SbxVariableRef refConv = new SbxVariable;
		refConv->PutString( aVal );
		return refConv->GetInteger();
	}
	else
	{
		double n = nVal;
		if( n > 0 ) n += .5; else n -= .5;
		if( n > SbxMAXINT ) n = SbxMAXINT, pParser->Error( SbERR_OUT_OF_RANGE );
		else
		if( n < SbxMININT ) n = SbxMININT, pParser->Error( SbERR_OUT_OF_RANGE );
		return (short) n;
	}
}


/***************************************************************************
|*
|*      SbiExprList
|*
***************************************************************************/

SbiExprList::SbiExprList( SbiParser* p )
{
	pParser = p;
	pFirst = NULL;
	nExpr  =
	nDim   = 0;
	bError =
	bBracket = sal_False;
}

SbiExprList::~SbiExprList()
{
	SbiExpression* p = pFirst;
	while( p )
	{
		SbiExpression* q = p->pNext;
		delete p;
		p = q;
	}
}

// Parameter anfordern (ab 0)

SbiExpression* SbiExprList::Get( short n )
{
	SbiExpression* p = pFirst;
	while( n-- && p )
		p = p->pNext;
	return p;
}

void SbiExprList::addExpression( SbiExpression* pExpr )
{
	SbiExpression* p = pFirst;
	while( p && p->pNext )
		p = p->pNext;

	p->pNext = pExpr;
}


/***************************************************************************
|*
|*      SbiParameters
|*
***************************************************************************/

// Parsender Konstruktor:
// Die Parameterliste wird komplett geparst.
// "Prozedurname()" ist OK.
// Dann handelt es sich um eine Funktion ohne Parameter
// respektive um die Angabe eines Arrays als Prozedurparameter.

// #i79918/#i80532: bConst has never been set to true
// -> reused as bStandaloneExpression
//SbiParameters::SbiParameters( SbiParser* p, sal_Bool bConst, sal_Bool bPar) :
SbiParameters::SbiParameters( SbiParser* p, sal_Bool bStandaloneExpression, sal_Bool bPar) :
	SbiExprList( p )
{
	if( !bPar )
		return;

	SbiExpression *pExpr;
	SbiToken eTok = pParser->Peek();

	// evtl. Klammer auf weg:
	bool bAssumeExprLParenMode = false;
	bool bAssumeArrayMode = false;
	if( eTok == LPAREN )
	{
		if( bStandaloneExpression )
		{
			bAssumeExprLParenMode = true;
		}
		else
		{
			bBracket = sal_True;
			pParser->Next();
			eTok = pParser->Peek();
		}
	}

	// Ende-Test
	if( ( bBracket && eTok == RPAREN ) || pParser->IsEoln( eTok ) )
	{
		if( eTok == RPAREN )
			pParser->Next();
		return;
	}
	// Parametertabelle einlesen und in richtiger Folge ablegen!
	SbiExpression* pLast = NULL;
	String aName;
	while( !bError )
	{
		aName.Erase();
		// Fehlendes Argument
		if( eTok == COMMA )
		{
			pExpr = new SbiExpression( pParser, 0, SbxEMPTY );
			//if( bConst )
			//	pParser->Error( SbERR_SYNTAX ), bError = sal_True;
		}
		// Benannte Argumente: entweder .name= oder name:=
		else
		{
			bool bByVal = false;
			if( eTok == BYVAL )
			{
				bByVal = true;
				pParser->Next();
				eTok = pParser->Peek();
			}

			if( bAssumeExprLParenMode )
			{
				pExpr = new SbiExpression( pParser, SbSTDEXPR, EXPRMODE_LPAREN_PENDING );
				bAssumeExprLParenMode = sal_False;

				SbiExprMode eModeAfter = pExpr->m_eMode;
				if( eModeAfter == EXPRMODE_LPAREN_NOT_NEEDED )
				{
					bBracket = sal_True;
				}
				else if( eModeAfter == EXPRMODE_ARRAY_OR_OBJECT )
				{
					// Expression "looks" like an array assignment
					// a(...)[(...)] = ? or a(...).b(...)
					// RPAREN is already parsed
					bBracket = sal_True;
					bAssumeArrayMode = true;
					eTok = NIL;
				}
				else if( eModeAfter == EXPRMODE_EMPTY_PAREN )
				{
					bBracket = sal_True;
					delete pExpr;
					if( bByVal )
						pParser->Error( SbERR_LVALUE_EXPECTED );
					return;
				}
			}
			else
				pExpr = new SbiExpression( pParser );

			if( bByVal && pExpr->IsLvalue() )
				pExpr->SetByVal();

			//pExpr = bConst ? new SbiConstExpression( pParser )
			//				: new SbiExpression( pParser );
			if( !bAssumeArrayMode )
			{
				if( pParser->Peek() == ASSIGN )
				{
					// VBA mode: name:=
					// SbiExpression::Term() hat einen String daraus gemacht
					aName = pExpr->GetString();
					delete pExpr;
					pParser->Next();
					pExpr = new SbiExpression( pParser );
					//if( bConst )
					//	pParser->Error( SbERR_SYNTAX ), bError = sal_True;
				}
				pExpr->GetName() = aName;
			}
		}
		pExpr->pNext = NULL;
		if( !pLast )
			pFirst = pLast = pExpr;
		else
			pLast->pNext = pExpr, pLast = pExpr;
		nExpr++;
		bError |= !pExpr->IsValid();

		if( bAssumeArrayMode )
			break;

		// Naechstes Element?
		eTok = pParser->Peek();
		if( eTok != COMMA )
		{
			if( ( bBracket && eTok == RPAREN ) || pParser->IsEoln( eTok ) )
				break;
			pParser->Error( bBracket
							? SbERR_BAD_BRACKETS
							: SbERR_EXPECTED, COMMA );
			bError = sal_True;
		}
		else
		{
			pParser->Next();
			eTok = pParser->Peek();
			if( ( bBracket && eTok == RPAREN ) || pParser->IsEoln( eTok ) )
				break;
		}
	}
	// Schliessende Klammer
	if( eTok == RPAREN )
	{
		pParser->Next();
		pParser->Peek();
		if( !bBracket )
		{
			pParser->Error( SbERR_BAD_BRACKETS );
			bError = sal_True;
		}
	}
	nDim = nExpr;
}

/***************************************************************************
|*
|*      SbiDimList
|*
***************************************************************************/

// Parsender Konstruktor:
// Eine Liste von Array-Dimensionen wird geparst. Die Ausdruecke werden
// auf numerisch getestet. Das bCONST-Bit wird gesetzt, wenn alle Ausdruecke
// Integer-Konstanten sind.

SbiDimList::SbiDimList( SbiParser* p ) : SbiExprList( p )
{
	bConst = sal_True;

	if( pParser->Next() != LPAREN )
	{
		pParser->Error( SbERR_EXPECTED, LPAREN );
		bError = sal_True; return;
	}

	if( pParser->Peek() != RPAREN )
	{
		SbiExpression *pExpr1, *pExpr2, *pLast = NULL;
		SbiToken eTok;
		for( ;; )
		{
			pExpr1 = new SbiExpression( pParser );
			eTok = pParser->Next();
			if( eTok == TO )
			{
				pExpr2 = new SbiExpression( pParser );
				eTok = pParser->Next();
				bConst &= pExpr1->IsIntConstant() & pExpr2->IsIntConstant();
				bError |= !pExpr1->IsValid();
				bError |= !pExpr2->IsValid();
				pExpr1->pNext = pExpr2;
				if( !pLast )
					pFirst = pExpr1;
				else
					pLast->pNext = pExpr1;
				pLast = pExpr2;
				nExpr += 2;
			}
			else
			{
				// Nur eine Dim-Angabe
				pExpr1->SetBased();
				pExpr1->pNext = NULL;
				bConst &= pExpr1->IsIntConstant();
				bError |= !pExpr1->IsValid();
				if( !pLast )
					pFirst = pLast = pExpr1;
				else
					pLast->pNext = pExpr1, pLast = pExpr1;
				nExpr++;
			}
			nDim++;
			if( eTok == RPAREN ) break;
			if( eTok != COMMA )
			{
				pParser->Error( SbERR_BAD_BRACKETS );
				pParser->Next();
				break;
			}
		}
	}
	else pParser->Next();
}
