xref: /aoo42x/main/basic/source/comp/exprgen.cxx (revision 07a3d7f1)
1e1f63238SAndrew Rist /**************************************************************
2cdf0e10cSrcweir  *
3e1f63238SAndrew Rist  * Licensed to the Apache Software Foundation (ASF) under one
4e1f63238SAndrew Rist  * or more contributor license agreements.  See the NOTICE file
5e1f63238SAndrew Rist  * distributed with this work for additional information
6e1f63238SAndrew Rist  * regarding copyright ownership.  The ASF licenses this file
7e1f63238SAndrew Rist  * to you under the Apache License, Version 2.0 (the
8e1f63238SAndrew Rist  * "License"); you may not use this file except in compliance
9e1f63238SAndrew Rist  * with the License.  You may obtain a copy of the License at
10e1f63238SAndrew Rist  *
11e1f63238SAndrew Rist  *   http://www.apache.org/licenses/LICENSE-2.0
12e1f63238SAndrew Rist  *
13e1f63238SAndrew Rist  * Unless required by applicable law or agreed to in writing,
14e1f63238SAndrew Rist  * software distributed under the License is distributed on an
15e1f63238SAndrew Rist  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16e1f63238SAndrew Rist  * KIND, either express or implied.  See the License for the
17e1f63238SAndrew Rist  * specific language governing permissions and limitations
18e1f63238SAndrew Rist  * under the License.
19e1f63238SAndrew Rist  *
20e1f63238SAndrew Rist  *************************************************************/
21e1f63238SAndrew Rist 
22e1f63238SAndrew Rist 
23cdf0e10cSrcweir 
24cdf0e10cSrcweir // MARKER(update_precomp.py): autogen include statement, do not remove
25cdf0e10cSrcweir #include "precompiled_basic.hxx"
26cdf0e10cSrcweir 
27cdf0e10cSrcweir #include "sbcomp.hxx"
28cdf0e10cSrcweir #include "expr.hxx"
29cdf0e10cSrcweir 
30cdf0e10cSrcweir // Umsetztabelle fuer Token-Operatoren und Opcodes
31cdf0e10cSrcweir 
32cdf0e10cSrcweir typedef struct {
33cdf0e10cSrcweir 		SbiToken  eTok; 				// Token
34cdf0e10cSrcweir 		SbiOpcode eOp;  				// Opcode
35cdf0e10cSrcweir } OpTable;
36cdf0e10cSrcweir 
37cdf0e10cSrcweir static OpTable aOpTable [] = {
38cdf0e10cSrcweir 	{ EXPON,_EXP },
39cdf0e10cSrcweir 	{ MUL,	_MUL },
40cdf0e10cSrcweir 	{ DIV,	_DIV },
41cdf0e10cSrcweir 	{ IDIV,	_IDIV },
42cdf0e10cSrcweir 	{ MOD,	_MOD },
43cdf0e10cSrcweir 	{ PLUS,	_PLUS },
44cdf0e10cSrcweir 	{ MINUS,_MINUS },
45cdf0e10cSrcweir 	{ EQ,	_EQ },
46cdf0e10cSrcweir 	{ NE,	_NE },
47cdf0e10cSrcweir 	{ LE,	_LE },
48cdf0e10cSrcweir 	{ GE,	_GE },
49cdf0e10cSrcweir 	{ LT,	_LT },
50cdf0e10cSrcweir 	{ GT,	_GT },
51cdf0e10cSrcweir 	{ AND,	_AND },
52cdf0e10cSrcweir 	{ OR,	_OR },
53cdf0e10cSrcweir 	{ XOR,	_XOR },
54cdf0e10cSrcweir 	{ EQV,	_EQV },
55cdf0e10cSrcweir 	{ IMP,	_IMP },
56cdf0e10cSrcweir 	{ NOT,	_NOT },
57cdf0e10cSrcweir 	{ NEG,	_NEG },
58cdf0e10cSrcweir 	{ CAT,	_CAT },
59cdf0e10cSrcweir 	{ LIKE, _LIKE },
60cdf0e10cSrcweir 	{ IS,   _IS },
61cdf0e10cSrcweir 	{ NIL,  _NOP }};
62cdf0e10cSrcweir 
63cdf0e10cSrcweir // Ausgabe eines Elements
Gen(RecursiveMode eRecMode)64cdf0e10cSrcweir void SbiExprNode::Gen( RecursiveMode eRecMode )
65cdf0e10cSrcweir {
66cdf0e10cSrcweir 	if( IsConstant() )
67cdf0e10cSrcweir 	{
68cdf0e10cSrcweir 		switch( GetType() )
69cdf0e10cSrcweir 		{
70cdf0e10cSrcweir 			case SbxEMPTY:	 pGen->Gen( _EMPTY ); break;
71cdf0e10cSrcweir 			case SbxINTEGER: pGen->Gen( _CONST,  (short) nVal ); break;
72cdf0e10cSrcweir 			case SbxSTRING:
73cdf0e10cSrcweir 			{
74cdf0e10cSrcweir 				sal_uInt16 nStringId = pGen->GetParser()->aGblStrings.Add( aStrVal, sal_True );
75cdf0e10cSrcweir 				pGen->Gen( _SCONST, nStringId ); break;
76cdf0e10cSrcweir 			}
77cdf0e10cSrcweir 			default:
78cdf0e10cSrcweir 			{
79cdf0e10cSrcweir 				sal_uInt16 nStringId = pGen->GetParser()->aGblStrings.Add( nVal, eType );
80cdf0e10cSrcweir 				pGen->Gen( _NUMBER, nStringId );
81cdf0e10cSrcweir 			}
82cdf0e10cSrcweir 		}
83cdf0e10cSrcweir 	}
84cdf0e10cSrcweir 	else if( IsOperand() )
85cdf0e10cSrcweir 	{
86cdf0e10cSrcweir 		SbiExprNode* pWithParent_ = NULL;
87cdf0e10cSrcweir 		SbiOpcode eOp;
88cdf0e10cSrcweir 		if( aVar.pDef->GetScope() == SbPARAM )
89cdf0e10cSrcweir         {
90cdf0e10cSrcweir             eOp = _PARAM;
91cdf0e10cSrcweir             if( 0 == aVar.pDef->GetPos() )
92cdf0e10cSrcweir 			{
93cdf0e10cSrcweir 				bool bTreatFunctionAsParam = true;
94cdf0e10cSrcweir 				if( eRecMode == FORCE_CALL )
95cdf0e10cSrcweir 				{
96cdf0e10cSrcweir 					bTreatFunctionAsParam = false;
97cdf0e10cSrcweir 				}
98cdf0e10cSrcweir 				else if( eRecMode == UNDEFINED )
99cdf0e10cSrcweir 				{
100cdf0e10cSrcweir 					if( aVar.pPar && aVar.pPar->IsBracket() )
101cdf0e10cSrcweir 				 		bTreatFunctionAsParam = false;
102cdf0e10cSrcweir 				}
103cdf0e10cSrcweir 				if( !bTreatFunctionAsParam )
104cdf0e10cSrcweir 					eOp = aVar.pDef->IsGlobal() ? _FIND_G : _FIND;
105cdf0e10cSrcweir 			}
106cdf0e10cSrcweir         }
107cdf0e10cSrcweir 		// AB: 17.12.1995, Spezialbehandlung fuer WITH
108cdf0e10cSrcweir 		else if( (pWithParent_ = GetWithParent()) != NULL )
109cdf0e10cSrcweir 		{
110cdf0e10cSrcweir 			eOp = _ELEM;			// .-Ausdruck in WITH
111cdf0e10cSrcweir 		}
112cdf0e10cSrcweir 		else
113cdf0e10cSrcweir 		{
114cdf0e10cSrcweir             eOp = ( aVar.pDef->GetScope() == SbRTL ) ? _RTL :
115cdf0e10cSrcweir                 (aVar.pDef->IsGlobal() ? _FIND_G : _FIND);
116cdf0e10cSrcweir 		}
117cdf0e10cSrcweir 
118cdf0e10cSrcweir 		if( eOp == _FIND )
119cdf0e10cSrcweir 		{
120cdf0e10cSrcweir 
121cdf0e10cSrcweir 			SbiProcDef* pProc = aVar.pDef->GetProcDef();
122cdf0e10cSrcweir 			if ( pGen->GetParser()->bClassModule )
123cdf0e10cSrcweir 				eOp = _FIND_CM;
124cdf0e10cSrcweir 			else if ( aVar.pDef->IsStatic() || (pProc && pProc->IsStatic()) )
125cdf0e10cSrcweir 			{
126cdf0e10cSrcweir 				eOp = _FIND_STATIC;
127cdf0e10cSrcweir 			}
128cdf0e10cSrcweir 		}
129cdf0e10cSrcweir 		for( SbiExprNode* p = this; p; p = p->aVar.pNext )
130cdf0e10cSrcweir 		{
131cdf0e10cSrcweir 			if( p == this && pWithParent_ != NULL )
132cdf0e10cSrcweir 				pWithParent_->Gen();
133cdf0e10cSrcweir 			p->GenElement( eOp );
134cdf0e10cSrcweir 			eOp = _ELEM;
135cdf0e10cSrcweir 		}
136cdf0e10cSrcweir 	}
137cdf0e10cSrcweir 	else if( IsTypeOf() )
138cdf0e10cSrcweir 	{
139cdf0e10cSrcweir 		pLeft->Gen();
140cdf0e10cSrcweir 		pGen->Gen( _TESTCLASS, nTypeStrId );
141cdf0e10cSrcweir 	}
142cdf0e10cSrcweir 	else if( IsNew() )
143cdf0e10cSrcweir 	{
144cdf0e10cSrcweir 		pGen->Gen( _CREATE, 0, nTypeStrId );
145cdf0e10cSrcweir 	}
146cdf0e10cSrcweir 	else
147cdf0e10cSrcweir 	{
148cdf0e10cSrcweir 		pLeft->Gen();
149cdf0e10cSrcweir 		if( pRight )
150cdf0e10cSrcweir 			pRight->Gen();
151cdf0e10cSrcweir 		for( OpTable* p = aOpTable; p->eTok != NIL; p++ )
152cdf0e10cSrcweir 		{
153cdf0e10cSrcweir 			if( p->eTok == eTok )
154cdf0e10cSrcweir 			{
155cdf0e10cSrcweir 				pGen->Gen( p->eOp ); break;
156cdf0e10cSrcweir 			}
157cdf0e10cSrcweir 		}
158cdf0e10cSrcweir 	}
159cdf0e10cSrcweir }
160cdf0e10cSrcweir 
161cdf0e10cSrcweir // Ausgabe eines Operanden-Elements
162cdf0e10cSrcweir 
GenElement(SbiOpcode eOp)163cdf0e10cSrcweir void SbiExprNode::GenElement( SbiOpcode eOp )
164cdf0e10cSrcweir {
165cdf0e10cSrcweir #ifdef DBG_UTIL
166cdf0e10cSrcweir 	if( (eOp < _RTL || eOp > _CALLC) && eOp != _FIND_G && eOp != _FIND_CM )
167cdf0e10cSrcweir 		pGen->GetParser()->Error( SbERR_INTERNAL_ERROR, "Opcode" );
168cdf0e10cSrcweir #endif
169cdf0e10cSrcweir 	SbiSymDef* pDef = aVar.pDef;
170cdf0e10cSrcweir 	// Das ID ist entweder die Position oder das String-ID
171cdf0e10cSrcweir 	// Falls das Bit 0x8000 gesetzt ist, hat die Variable
172cdf0e10cSrcweir 	// eine Parameterliste.
173cdf0e10cSrcweir 	sal_uInt16 nId = ( eOp == _PARAM ) ? pDef->GetPos() : pDef->GetId();
174cdf0e10cSrcweir 	// Parameterliste aufbauen
175cdf0e10cSrcweir 	if( aVar.pPar && aVar.pPar->GetSize() )
176cdf0e10cSrcweir 	{
177cdf0e10cSrcweir 		nId |= 0x8000;
178cdf0e10cSrcweir 		aVar.pPar->Gen();
179cdf0e10cSrcweir 	}
180cdf0e10cSrcweir 
181cdf0e10cSrcweir 	pGen->Gen( eOp, nId, sal::static_int_cast< sal_uInt16 >( GetType() ) );
182cdf0e10cSrcweir 
183cdf0e10cSrcweir 	if( aVar.pvMorePar )
184cdf0e10cSrcweir 	{
185cdf0e10cSrcweir 		SbiExprListVector* pvMorePar = aVar.pvMorePar;
186cdf0e10cSrcweir 		SbiExprListVector::iterator it;
187cdf0e10cSrcweir 		for( it = pvMorePar->begin() ; it != pvMorePar->end() ; ++it )
188cdf0e10cSrcweir 		{
189cdf0e10cSrcweir 			SbiExprList* pExprList = *it;
190cdf0e10cSrcweir 			pExprList->Gen();
191cdf0e10cSrcweir 			pGen->Gen( _ARRAYACCESS );
192cdf0e10cSrcweir 		}
193cdf0e10cSrcweir 	}
194cdf0e10cSrcweir }
195cdf0e10cSrcweir 
196cdf0e10cSrcweir // Erzeugen einer Argv-Tabelle
197cdf0e10cSrcweir // Das erste Element bleibt immer frei fuer Returnwerte etc.
198cdf0e10cSrcweir // Siehe auch SbiProcDef::SbiProcDef() in symtbl.cxx
199cdf0e10cSrcweir 
Gen()200cdf0e10cSrcweir void SbiExprList::Gen()
201cdf0e10cSrcweir {
202cdf0e10cSrcweir 	if( pFirst )
203cdf0e10cSrcweir 	{
204cdf0e10cSrcweir 		pParser->aGen.Gen( _ARGC );
205cdf0e10cSrcweir 		// AB 10.1.96: Typ-Anpassung bei DECLARE
206cdf0e10cSrcweir 		sal_uInt16 nCount = 1 /*, nParAnz = 0*/;
207cdf0e10cSrcweir //		SbiSymPool* pPool = NULL;
208cdf0e10cSrcweir 		for( SbiExpression* pExpr = pFirst; pExpr; pExpr = pExpr->pNext,nCount++ )
209cdf0e10cSrcweir 		{
210cdf0e10cSrcweir 			pExpr->Gen();
211cdf0e10cSrcweir 			if( pExpr->GetName().Len() )
212cdf0e10cSrcweir 			{
213cdf0e10cSrcweir 				// named arg
214cdf0e10cSrcweir 				sal_uInt16 nSid = pParser->aGblStrings.Add( pExpr->GetName() );
215cdf0e10cSrcweir 				pParser->aGen.Gen( _ARGN, nSid );
216cdf0e10cSrcweir 
217cdf0e10cSrcweir 				/* TODO: Check after Declare concept change
218cdf0e10cSrcweir 				// AB 10.1.96: Typanpassung bei named -> passenden Parameter suchen
219cdf0e10cSrcweir 				if( pProc )
220cdf0e10cSrcweir 				{
221cdf0e10cSrcweir 					// Vorerst: Error ausloesen
222cdf0e10cSrcweir 					pParser->Error( SbERR_NO_NAMED_ARGS );
223cdf0e10cSrcweir 
224cdf0e10cSrcweir 					// Spaeter, wenn Named Args bei DECLARE moeglich
225cdf0e10cSrcweir 					//for( sal_uInt16 i = 1 ; i < nParAnz ; i++ )
226cdf0e10cSrcweir 					//{
227cdf0e10cSrcweir 					//	SbiSymDef* pDef = pPool->Get( i );
228cdf0e10cSrcweir 					//	const String& rName = pDef->GetName();
229cdf0e10cSrcweir 					//	if( rName.Len() )
230cdf0e10cSrcweir 					//	{
231cdf0e10cSrcweir 					//		if( pExpr->GetName().ICompare( rName )
232cdf0e10cSrcweir 					//			== COMPARE_EQUAL )
233cdf0e10cSrcweir 					//		{
234cdf0e10cSrcweir 					//			pParser->aGen.Gen( _ARGTYP, pDef->GetType() );
235cdf0e10cSrcweir 					//			break;
236cdf0e10cSrcweir 					//		}
237cdf0e10cSrcweir 					//	}
238cdf0e10cSrcweir 					//}
239cdf0e10cSrcweir 				}
240cdf0e10cSrcweir 				*/
241cdf0e10cSrcweir 			}
242cdf0e10cSrcweir 			else
243cdf0e10cSrcweir 			{
244cdf0e10cSrcweir 				pParser->aGen.Gen( _ARGV );
245cdf0e10cSrcweir 			}
246cdf0e10cSrcweir 		}
247cdf0e10cSrcweir 	}
248cdf0e10cSrcweir }
249cdf0e10cSrcweir 
Gen(RecursiveMode eRecMode)250cdf0e10cSrcweir void SbiExpression::Gen( RecursiveMode eRecMode )
251cdf0e10cSrcweir {
252cdf0e10cSrcweir 	// AB: 17.12.1995, Spezialbehandlung fuer WITH
253cdf0e10cSrcweir 	// Wenn pExpr == .-Ausdruck in With, zunaechst Gen fuer Basis-Objekt
254cdf0e10cSrcweir 	pExpr->Gen( eRecMode );
255cdf0e10cSrcweir 	if( bByVal )
256cdf0e10cSrcweir 		pParser->aGen.Gen( _BYVAL );
257cdf0e10cSrcweir 	if( bBased )
258cdf0e10cSrcweir 	{
259cdf0e10cSrcweir 		sal_uInt16 uBase = pParser->nBase;
260cdf0e10cSrcweir 		if( pParser->IsCompatible() )
261*07a3d7f1SPedro Giffuni 			uBase |= 0x8000;		// #109275 Flag compatibility
262cdf0e10cSrcweir 		pParser->aGen.Gen( _BASED, uBase );
263cdf0e10cSrcweir 		pParser->aGen.Gen( _ARGV );
264cdf0e10cSrcweir 	}
265cdf0e10cSrcweir }
266cdf0e10cSrcweir 
267