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