xref: /trunk/main/basic/source/comp/exprnode.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 <math.h>
28 
29 #include <rtl/math.hxx>
30 #include "sbcomp.hxx"
31 #include "expr.hxx"
32 
33 //////////////////////////////////////////////////////////////////////////
34 
SbiExprNode(void)35 SbiExprNode::SbiExprNode( void )
36 {
37 	pLeft = NULL;
38 	pRight = NULL;
39 	eNodeType = SbxDUMMY;
40 }
41 
SbiExprNode(SbiParser * p,SbiExprNode * l,SbiToken t,SbiExprNode * r)42 SbiExprNode::SbiExprNode( SbiParser* p, SbiExprNode* l, SbiToken t, SbiExprNode* r )
43 {
44 	BaseInit( p );
45 
46 	pLeft     = l;
47 	pRight    = r;
48 	eTok      = t;
49 	nVal	  = 0;
50 	eType     = SbxVARIANT;		// Nodes sind immer Variant
51 	eNodeType = SbxNODE;
52 	bComposite= sal_True;
53 }
54 
SbiExprNode(SbiParser * p,double n,SbxDataType t)55 SbiExprNode::SbiExprNode( SbiParser* p, double n, SbxDataType t )
56 {
57 	BaseInit( p );
58 
59 	eType     = t;
60 	eNodeType = SbxNUMVAL;
61 	nVal      = n;
62 }
63 
SbiExprNode(SbiParser * p,const String & rVal)64 SbiExprNode::SbiExprNode( SbiParser* p, const String& rVal )
65 {
66 	BaseInit( p );
67 
68 	eType     = SbxSTRING;
69 	eNodeType = SbxSTRVAL;
70 	aStrVal   = rVal;
71 }
72 
SbiExprNode(SbiParser * p,const SbiSymDef & r,SbxDataType t,SbiExprList * l)73 SbiExprNode::SbiExprNode( SbiParser* p, const SbiSymDef& r, SbxDataType t, SbiExprList* l )
74 {
75 	BaseInit( p );
76 
77 	eType     = ( t == SbxVARIANT ) ? r.GetType() : t;
78 	eNodeType = SbxVARVAL;
79 	aVar.pDef = (SbiSymDef*) &r;
80 	aVar.pPar = l;
81 	aVar.pvMorePar = NULL;
82 	aVar.pNext= NULL;
83 
84 	// Funktionsergebnisse sind nie starr
85 	bComposite= sal_Bool( aVar.pDef->GetProcDef() != NULL );
86 }
87 
88 // #120061 TypeOf
SbiExprNode(SbiParser * p,SbiExprNode * l,sal_uInt16 nId)89 SbiExprNode::SbiExprNode( SbiParser* p, SbiExprNode* l, sal_uInt16 nId )
90 {
91 	BaseInit( p );
92 
93 	pLeft      = l;
94 	eType      = SbxBOOL;
95 	eNodeType  = SbxTYPEOF;
96 	nTypeStrId = nId;
97 }
98 
99 // new <type>
SbiExprNode(SbiParser * p,sal_uInt16 nId)100 SbiExprNode::SbiExprNode( SbiParser* p, sal_uInt16 nId )
101 {
102 	BaseInit( p );
103 
104 	eType     = SbxOBJECT;
105 	eNodeType = SbxNEW;
106 	nTypeStrId = nId;
107 }
108 
109 // AB: 17.12.95, Hilfsfunktion fuer Ctor fuer einheitliche Initialisierung
BaseInit(SbiParser * p)110 void SbiExprNode::BaseInit( SbiParser* p )
111 {
112 	pGen = &p->aGen;
113 	eTok = NIL;
114 	pLeft 		= NULL;
115 	pRight		= NULL;
116 	pWithParent = NULL;
117 	bComposite	= sal_False;
118 	bError	    = sal_False;
119 }
120 
~SbiExprNode()121 SbiExprNode::~SbiExprNode()
122 {
123 	delete pLeft;
124 	delete pRight;
125 	if( IsVariable() )
126 	{
127 		delete aVar.pPar;
128 		delete aVar.pNext;
129 		SbiExprListVector* pvMorePar = aVar.pvMorePar;
130 		if( pvMorePar )
131 		{
132 			SbiExprListVector::iterator it;
133 			for( it = pvMorePar->begin() ; it != pvMorePar->end() ; ++it )
134 				delete *it;
135 			delete pvMorePar;
136 		}
137 	}
138 }
139 
GetVar()140 SbiSymDef* SbiExprNode::GetVar()
141 {
142 	if( eNodeType == SbxVARVAL )
143 		return aVar.pDef;
144 	else
145 		return NULL;
146 }
147 
GetRealVar()148 SbiSymDef* SbiExprNode::GetRealVar()
149 {
150 	SbiExprNode* p = GetRealNode();
151 	if( p )
152 		return p->GetVar();
153 	else
154 		return NULL;
155 }
156 
157 // AB: 18.12.95
GetRealNode()158 SbiExprNode* SbiExprNode::GetRealNode()
159 {
160 	if( eNodeType == SbxVARVAL )
161 	{
162 		SbiExprNode* p = this;
163 		while( p->aVar.pNext )
164 			p = p->aVar.pNext;
165 		return p;
166 	}
167 	else
168 		return NULL;
169 }
170 
171 // Diese Methode setzt den Typ um, falls er in den Integer-Bereich hineinpasst
172 
IsIntConst()173 sal_Bool SbiExprNode::IsIntConst()
174 {
175 	if( eNodeType == SbxNUMVAL )
176 	{
177 		if( eType >= SbxINTEGER && eType <= SbxDOUBLE )
178 		{
179 			double n;
180 			if( nVal >= SbxMININT && nVal <= SbxMAXINT && modf( nVal, &n ) == 0 )
181 			{
182 				nVal = (double) (short) nVal;
183 				eType = SbxINTEGER;
184 				return sal_True;
185 			}
186 		}
187 	}
188 	return sal_False;
189 }
190 
IsNumber()191 sal_Bool SbiExprNode::IsNumber()
192 {
193 	return sal_Bool( eNodeType == SbxNUMVAL );
194 }
195 
IsString()196 sal_Bool SbiExprNode::IsString()
197 {
198 	return sal_Bool( eNodeType == SbxSTRVAL );
199 }
200 
IsVariable()201 sal_Bool SbiExprNode::IsVariable()
202 {
203 	return sal_Bool( eNodeType == SbxVARVAL );
204 }
205 
IsLvalue()206 sal_Bool SbiExprNode::IsLvalue()
207 {
208 	return IsVariable();
209 }
210 
211 // Ermitteln der Tiefe eines Baumes
212 
GetDepth()213 short SbiExprNode::GetDepth()
214 {
215 	if( IsOperand() ) return 0;
216 	else
217 	{
218 		short d1 = pLeft->GetDepth();
219 		short d2 = pRight->GetDepth();
220 		return( (d1 < d2 ) ? d2 : d1 ) + 1;
221 	}
222 }
223 
224 
225 // Abgleich eines Baumes:
226 // 1. Constant Folding
227 // 2. Typabgleich
228 // 3. Umwandlung der Operanden in Strings
229 // 4. Hochziehen der Composite- und Error-Bits
230 
Optimize()231 void SbiExprNode::Optimize()
232 {
233 	FoldConstants();
234 	CollectBits();
235 }
236 
237 // Hochziehen der Composite- und Fehlerbits
238 
CollectBits()239 void SbiExprNode::CollectBits()
240 {
241 	if( pLeft )
242 	{
243 		pLeft->CollectBits();
244 		bError |= pLeft->bError;
245 		bComposite |= pLeft->bComposite;
246 	}
247 	if( pRight )
248 	{
249 		pRight->CollectBits();
250 		bError |= pRight->bError;
251 		bComposite |= pRight->bComposite;
252 	}
253 }
254 
255 // Kann ein Zweig umgeformt werden, wird sal_True zurueckgeliefert. In diesem
256 // Fall ist das Ergebnis im linken Zweig.
257 
FoldConstants()258 void SbiExprNode::FoldConstants()
259 {
260 	if( IsOperand() || eTok == LIKE ) return;
261 	if( pLeft )
262 		pLeft->FoldConstants();
263 	if( pRight )
264 	{
265 		pRight->FoldConstants();
266 		if( pLeft->IsConstant() && pRight->IsConstant()
267 			&& pLeft->eNodeType == pRight->eNodeType )
268 		{
269 			CollectBits();
270 			if( eTok == CAT )
271 				// CAT verbindet auch zwei Zahlen miteinander!
272 				eType = SbxSTRING;
273 			if( pLeft->eType == SbxSTRING )
274 				// Kein Type Mismatch!
275 				eType = SbxSTRING;
276 			if( eType == SbxSTRING )
277 			{
278 				String rl( pLeft->GetString() );
279 				String rr( pRight->GetString() );
280 				delete pLeft; pLeft = NULL;
281 				delete pRight; pRight = NULL;
282 				bComposite = sal_False;
283 				if( eTok == PLUS || eTok == CAT )
284 				{
285 					eTok = CAT;
286 					// Verkettung:
287 					aStrVal = rl;
288 					aStrVal += rr;
289 					eType = SbxSTRING;
290 					eNodeType = SbxSTRVAL;
291 				}
292 				else
293 				{
294 					eType = SbxDOUBLE;
295 					eNodeType = SbxNUMVAL;
296 					StringCompare eRes = rr.CompareTo( rl );
297 					switch( eTok )
298 					{
299 						case EQ:
300 							nVal = ( eRes == COMPARE_EQUAL ) ? SbxTRUE : SbxFALSE;
301 							break;
302 						case NE:
303 							nVal = ( eRes != COMPARE_EQUAL ) ? SbxTRUE : SbxFALSE;
304 							break;
305 						case LT:
306 							nVal = ( eRes == COMPARE_LESS ) ? SbxTRUE : SbxFALSE;
307 							break;
308 						case GT:
309 							nVal = ( eRes == COMPARE_GREATER ) ? SbxTRUE : SbxFALSE;
310 							break;
311 						case LE:
312 							nVal = ( eRes != COMPARE_GREATER ) ? SbxTRUE : SbxFALSE;
313 							break;
314 						case GE:
315 							nVal = ( eRes != COMPARE_LESS ) ? SbxTRUE : SbxFALSE;
316 							break;
317 						default:
318 							pGen->GetParser()->Error( SbERR_CONVERSION );
319 							bError = sal_True;
320 					}
321 				}
322 			}
323 			else
324 			{
325 				double nl = pLeft->nVal;
326 				double nr = pRight->nVal;
327 				long ll = 0, lr = 0;
328 				long llMod = 0, lrMod = 0;
329 				if( ( eTok >= AND && eTok <= IMP )
330 				   || eTok == IDIV || eTok == MOD )
331 				{
332 					// Integer-Operationen
333 					sal_Bool err = sal_False;
334 					if( nl > SbxMAXLNG ) err = sal_True, nl = SbxMAXLNG;
335 					else
336 					if( nl < SbxMINLNG ) err = sal_True, nl = SbxMINLNG;
337 					if( nr > SbxMAXLNG ) err = sal_True, nr = SbxMAXLNG;
338 					else
339 					if( nr < SbxMINLNG ) err = sal_True, nr = SbxMINLNG;
340 					ll = (long) nl; lr = (long) nr;
341                     llMod = (long) (nl < 0 ? nl - 0.5 : nl + 0.5);
342                     lrMod = (long) (nr < 0 ? nr - 0.5 : nr + 0.5);
343 					if( err )
344 					{
345 						pGen->GetParser()->Error( SbERR_MATH_OVERFLOW );
346 						bError = sal_True;
347 					}
348 				}
349 				sal_Bool bBothInt = sal_Bool( pLeft->eType < SbxSINGLE
350 								   && pRight->eType < SbxSINGLE );
351 				delete pLeft; pLeft = NULL;
352 				delete pRight; pRight = NULL;
353 				nVal = 0;
354 				eType = SbxDOUBLE;
355 				eNodeType = SbxNUMVAL;
356 				bComposite = sal_False;
357 				sal_Bool bCheckType = sal_False;
358 				switch( eTok )
359 				{
360 					case EXPON:
361 						nVal = pow( nl, nr ); break;
362 					case MUL:
363 						bCheckType = sal_True;
364 						nVal = nl * nr; break;
365 					case DIV:
366 						if( !nr )
367 						{
368 							pGen->GetParser()->Error( SbERR_ZERODIV ); nVal = HUGE_VAL;
369 							bError = sal_True;
370 						} else nVal = nl / nr;
371 						break;
372 					case PLUS:
373 						bCheckType = sal_True;
374 						nVal = nl + nr; break;
375 					case MINUS:
376 						bCheckType = sal_True;
377 						nVal = nl - nr; break;
378 					case EQ:
379 						nVal = ( nl == nr ) ? SbxTRUE : SbxFALSE;
380 						eType = SbxINTEGER; break;
381 					case NE:
382 						nVal = ( nl != nr ) ? SbxTRUE : SbxFALSE;
383 						eType = SbxINTEGER; break;
384 					case LT:
385 						nVal = ( nl <  nr ) ? SbxTRUE : SbxFALSE;
386 						eType = SbxINTEGER; break;
387 					case GT:
388 						nVal = ( nl >  nr ) ? SbxTRUE : SbxFALSE;
389 						eType = SbxINTEGER; break;
390 					case LE:
391 						nVal = ( nl <= nr ) ? SbxTRUE : SbxFALSE;
392 						eType = SbxINTEGER; break;
393 					case GE:
394 						nVal = ( nl >= nr ) ? SbxTRUE : SbxFALSE;
395 						eType = SbxINTEGER; break;
396 					case IDIV:
397 						if( !lr )
398 						{
399 							pGen->GetParser()->Error( SbERR_ZERODIV ); nVal = HUGE_VAL;
400 							bError = sal_True;
401 						} else nVal = ll / lr;
402 						eType = SbxLONG; break;
403 					case MOD:
404 						if( !lr )
405 						{
406 							pGen->GetParser()->Error( SbERR_ZERODIV ); nVal = HUGE_VAL;
407 							bError = sal_True;
408 						} else nVal = llMod % lrMod;
409 						eType = SbxLONG; break;
410 					case AND:
411 						nVal = (double) ( ll & lr ); eType = SbxLONG; break;
412 					case OR:
413 						nVal = (double) ( ll | lr ); eType = SbxLONG; break;
414 					case XOR:
415 						nVal = (double) ( ll ^ lr ); eType = SbxLONG; break;
416 					case EQV:
417 						nVal = (double) ( ~ll ^ lr ); eType = SbxLONG; break;
418 					case IMP:
419 						nVal = (double) ( ~ll | lr ); eType = SbxLONG; break;
420 					default: break;
421 				}
422 
423                 if( !::rtl::math::isFinite( nVal ) )
424 					pGen->GetParser()->Error( SbERR_MATH_OVERFLOW );
425 
426 				// Den Datentyp wiederherstellen, um Rundungsfehler
427 				// zu killen
428 				if( bCheckType && bBothInt
429 				 && nVal >= SbxMINLNG && nVal <= SbxMAXLNG )
430 				{
431 					// NK-Stellen weg
432 					long n = (long) nVal;
433 					nVal = n;
434 					eType = ( n >= SbxMININT && n <= SbxMAXINT )
435 						  ? SbxINTEGER : SbxLONG;
436 				}
437 			}
438 		}
439 	}
440 	else if( pLeft && pLeft->IsNumber() )
441 	{
442 		nVal = pLeft->nVal;
443 		delete pLeft;
444 		pLeft = NULL;
445 		eType = SbxDOUBLE;
446 		eNodeType = SbxNUMVAL;
447 		bComposite = sal_False;
448 		switch( eTok )
449 		{
450 			case NEG:
451 				nVal = -nVal; break;
452 			case NOT: {
453 				// Integer-Operation!
454 				sal_Bool err = sal_False;
455 				if( nVal > SbxMAXLNG ) err = sal_True, nVal = SbxMAXLNG;
456 				else
457 				if( nVal < SbxMINLNG ) err = sal_True, nVal = SbxMINLNG;
458 				if( err )
459 				{
460 					pGen->GetParser()->Error( SbERR_MATH_OVERFLOW );
461 					bError = sal_True;
462 				}
463 				nVal = (double) ~((long) nVal);
464 				eType = SbxLONG;
465 				} break;
466 			default: break;
467 		}
468 	}
469 	if( eNodeType == SbxNUMVAL )
470 	{
471 		// Evtl auf INTEGER falten (wg. besserem Opcode)?
472 		if( eType == SbxSINGLE || eType == SbxDOUBLE )
473 		{
474 			double x;
475 			if( nVal >= SbxMINLNG && nVal <= SbxMAXLNG
476 			&& !modf( nVal, &x ) )
477 				eType = SbxLONG;
478 		}
479 		if( eType == SbxLONG && nVal >= SbxMININT && nVal <= SbxMAXINT )
480 			eType = SbxINTEGER;
481 	}
482 }
483 
484 
485