/**************************************************************
 *
 * 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 für 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 für 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 für 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 auslösen
					pParser->Error( SbERR_NO_NAMED_ARGS );

					// Später, wenn Named Args bei DECLARE möglich
					//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 für WITH
	// Wenn pExpr == .-Ausdruck in With, zunächst Gen für 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 compatibility
		pParser->aGen.Gen( _BASED, uBase );
		pParser->aGen.Gen( _ARGV );
	}
}

/* vim: set noet sw=4 ts=4: */
