/**************************************************************
 * 
 * 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 "expr.hxx"

// Umsetztabelle fuer Token-Operatoren und Opcodes

typedef struct {
		SbiToken  eTok; 				// Token
		SbiOpcode eOp;  				// Opcode
} OpTable;

static OpTable aOpTable [] = {
	{ EXPON,_EXP },
	{ MUL,	_MUL },
	{ DIV,	_DIV },
	{ IDIV,	_IDIV },
	{ MOD,	_MOD },
	{ PLUS,	_PLUS },
	{ MINUS,_MINUS },
	{ EQ,	_EQ },
	{ NE,	_NE },
	{ LE,	_LE },
	{ GE,	_GE },
	{ LT,	_LT },
	{ GT,	_GT },
	{ AND,	_AND },
	{ OR,	_OR },
	{ XOR,	_XOR },
	{ EQV,	_EQV },
	{ IMP,	_IMP },
	{ NOT,	_NOT },
	{ NEG,	_NEG },
	{ CAT,	_CAT },
	{ LIKE, _LIKE },
	{ IS,   _IS },
	{ NIL,  _NOP }};

// Ausgabe eines Elements
void SbiExprNode::Gen( RecursiveMode eRecMode )
{
	if( IsConstant() )
	{
		switch( GetType() )
		{
			case SbxEMPTY:	 pGen->Gen( _EMPTY ); break;
			case SbxINTEGER: pGen->Gen( _CONST,  (short) nVal ); break;
			case SbxSTRING:  
			{
				sal_uInt16 nStringId = pGen->GetParser()->aGblStrings.Add( aStrVal, sal_True );
				pGen->Gen( _SCONST, nStringId ); break;
			}
			default:
			{
				sal_uInt16 nStringId = pGen->GetParser()->aGblStrings.Add( nVal, eType );
				pGen->Gen( _NUMBER, nStringId );
			}
		}
	}
	else if( IsOperand() )
	{
		SbiExprNode* pWithParent_ = NULL;
		SbiOpcode eOp;
		if( aVar.pDef->GetScope() == SbPARAM )
        {
            eOp = _PARAM;
            if( 0 == aVar.pDef->GetPos() )
			{
				bool bTreatFunctionAsParam = true;
				if( eRecMode == FORCE_CALL )
				{
					bTreatFunctionAsParam = false;
				}
				else if( eRecMode == UNDEFINED )
				{
					if( aVar.pPar && aVar.pPar->IsBracket() )
				 		bTreatFunctionAsParam = false;
				}
				if( !bTreatFunctionAsParam )
					eOp = aVar.pDef->IsGlobal() ? _FIND_G : _FIND;
			}
        }
		// AB: 17.12.1995, Spezialbehandlung fuer WITH
		else if( (pWithParent_ = GetWithParent()) != NULL )
		{
			eOp = _ELEM;			// .-Ausdruck in WITH
		}
		else
		{
            eOp = ( aVar.pDef->GetScope() == SbRTL ) ? _RTL : 
                (aVar.pDef->IsGlobal() ? _FIND_G : _FIND);
		}

		if( eOp == _FIND )
		{
	
			SbiProcDef* pProc = aVar.pDef->GetProcDef();
			if ( pGen->GetParser()->bClassModule )
				eOp = _FIND_CM;
			else if ( aVar.pDef->IsStatic() || (pProc && pProc->IsStatic()) )
			{
				eOp = _FIND_STATIC;
			}
		}
		for( SbiExprNode* p = this; p; p = p->aVar.pNext )
		{
			if( p == this && pWithParent_ != NULL )
				pWithParent_->Gen();
			p->GenElement( eOp );
			eOp = _ELEM;
		}
	}
	else if( IsTypeOf() )
	{
		pLeft->Gen();
		pGen->Gen( _TESTCLASS, nTypeStrId );
	}
	else if( IsNew() )
	{
		pGen->Gen( _CREATE, 0, nTypeStrId );
	}
	else
	{
		pLeft->Gen();
		if( pRight )
			pRight->Gen();
		for( OpTable* p = aOpTable; p->eTok != NIL; p++ )
		{
			if( p->eTok == eTok )
			{
				pGen->Gen( p->eOp ); break;
			}
		}
	}
}

// Ausgabe eines Operanden-Elements

void SbiExprNode::GenElement( SbiOpcode eOp )
{
#ifdef DBG_UTIL
	if( (eOp < _RTL || eOp > _CALLC) && eOp != _FIND_G && eOp != _FIND_CM )
		pGen->GetParser()->Error( SbERR_INTERNAL_ERROR, "Opcode" );
#endif
	SbiSymDef* pDef = aVar.pDef;
	// Das ID ist entweder die Position oder das String-ID
	// Falls das Bit 0x8000 gesetzt ist, hat die Variable
	// eine Parameterliste.
	sal_uInt16 nId = ( eOp == _PARAM ) ? pDef->GetPos() : pDef->GetId();
	// Parameterliste aufbauen
	if( aVar.pPar && aVar.pPar->GetSize() )
	{
		nId |= 0x8000;
		aVar.pPar->Gen();
	}
		
	pGen->Gen( eOp, nId, sal::static_int_cast< sal_uInt16 >( GetType() ) );

	if( aVar.pvMorePar )
	{
		SbiExprListVector* pvMorePar = aVar.pvMorePar;
		SbiExprListVector::iterator it;
		for( it = pvMorePar->begin() ; it != pvMorePar->end() ; ++it )
		{
			SbiExprList* pExprList = *it;
			pExprList->Gen();
			pGen->Gen( _ARRAYACCESS );
		}
	}
}

// Erzeugen einer Argv-Tabelle
// Das erste Element bleibt immer frei fuer Returnwerte etc.
// Siehe auch SbiProcDef::SbiProcDef() in symtbl.cxx

void SbiExprList::Gen()
{
	if( pFirst )
	{
		pParser->aGen.Gen( _ARGC );
		// AB 10.1.96: Typ-Anpassung bei DECLARE
		sal_uInt16 nCount = 1 /*, nParAnz = 0*/;
//		SbiSymPool* pPool = NULL;
		for( SbiExpression* pExpr = pFirst; pExpr; pExpr = pExpr->pNext,nCount++ )
		{
			pExpr->Gen();
			if( pExpr->GetName().Len() )
			{
				// named arg
				sal_uInt16 nSid = pParser->aGblStrings.Add( pExpr->GetName() );
				pParser->aGen.Gen( _ARGN, nSid );

				/* TODO: Check after Declare concept change
				// AB 10.1.96: Typanpassung bei named -> passenden Parameter suchen
				if( pProc )
				{
					// Vorerst: Error ausloesen
					pParser->Error( SbERR_NO_NAMED_ARGS );

					// Spaeter, wenn Named Args bei DECLARE moeglich
					//for( sal_uInt16 i = 1 ; i < nParAnz ; i++ )
					//{
					//	SbiSymDef* pDef = pPool->Get( i );
					//	const String& rName = pDef->GetName();
					//	if( rName.Len() )
					//	{
					//		if( pExpr->GetName().ICompare( rName )
					//			== COMPARE_EQUAL )
					//		{
					//			pParser->aGen.Gen( _ARGTYP, pDef->GetType() );
					//			break;
					//		}
					//	}
					//}
				}
				*/
			}
			else
			{
				pParser->aGen.Gen( _ARGV );
			}
		}
	}
}

void SbiExpression::Gen( RecursiveMode eRecMode )
{
	// AB: 17.12.1995, Spezialbehandlung fuer WITH
	// Wenn pExpr == .-Ausdruck in With, zunaechst Gen fuer Basis-Objekt
	pExpr->Gen( eRecMode );
	if( bByVal )
		pParser->aGen.Gen( _BYVAL );
	if( bBased )
	{
		sal_uInt16 uBase = pParser->nBase;
		if( pParser->IsCompatible() )
			uBase |= 0x8000;		// #109275 Flag compatiblity
		pParser->aGen.Gen( _BASED, uBase );
		pParser->aGen.Gen( _ARGV );
	}
}

