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