update dev300-m58
[ooovba.git] / basic / source / comp / exprnode.cxx
blob80fda09ff7084e3f7f14d09fda4f5c6e54b05874
1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * Copyright 2008 by Sun Microsystems, Inc.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * $RCSfile: exprnode.cxx,v $
10 * $Revision: 1.19.40.1 $
12 * This file is part of OpenOffice.org.
14 * OpenOffice.org is free software: you can redistribute it and/or modify
15 * it under the terms of the GNU Lesser General Public License version 3
16 * only, as published by the Free Software Foundation.
18 * OpenOffice.org is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU Lesser General Public License version 3 for more details
22 * (a copy is included in the LICENSE file that accompanied this code).
24 * You should have received a copy of the GNU Lesser General Public License
25 * version 3 along with OpenOffice.org. If not, see
26 * <http://www.openoffice.org/license.html>
27 * for a copy of the LGPLv3 License.
29 ************************************************************************/
31 // MARKER(update_precomp.py): autogen include statement, do not remove
32 #include "precompiled_basic.hxx"
34 #include <math.h>
36 #include <rtl/math.hxx>
37 #include "sbcomp.hxx"
38 #include "expr.hxx"
40 //////////////////////////////////////////////////////////////////////////
42 SbiExprNode::SbiExprNode( void )
44 pLeft = NULL;
45 pRight = NULL;
46 eNodeType = SbxDUMMY;
49 SbiExprNode::SbiExprNode( SbiParser* p, SbiExprNode* l, SbiToken t, SbiExprNode* r )
51 BaseInit( p );
53 pLeft = l;
54 pRight = r;
55 eTok = t;
56 nVal = 0;
57 eType = SbxVARIANT; // Nodes sind immer Variant
58 eNodeType = SbxNODE;
59 bComposite= TRUE;
62 SbiExprNode::SbiExprNode( SbiParser* p, double n, SbxDataType t )
64 BaseInit( p );
66 eType = t;
67 eNodeType = SbxNUMVAL;
68 nVal = n;
71 SbiExprNode::SbiExprNode( SbiParser* p, const String& rVal )
73 BaseInit( p );
75 eType = SbxSTRING;
76 eNodeType = SbxSTRVAL;
77 aStrVal = rVal;
80 SbiExprNode::SbiExprNode( SbiParser* p, const SbiSymDef& r, SbxDataType t, SbiExprList* l )
82 BaseInit( p );
84 eType = ( t == SbxVARIANT ) ? r.GetType() : t;
85 eNodeType = SbxVARVAL;
86 aVar.pDef = (SbiSymDef*) &r;
87 aVar.pPar = l;
88 aVar.pvMorePar = NULL;
89 aVar.pNext= NULL;
91 // Funktionsergebnisse sind nie starr
92 bComposite= BOOL( aVar.pDef->GetProcDef() != NULL );
95 // #120061 TypeOf
96 SbiExprNode::SbiExprNode( SbiParser* p, SbiExprNode* l, USHORT nId )
98 BaseInit( p );
100 pLeft = l;
101 eType = SbxBOOL;
102 eNodeType = SbxTYPEOF;
103 nTypeStrId = nId;
107 // AB: 17.12.95, Hilfsfunktion fuer Ctor fuer einheitliche Initialisierung
108 void SbiExprNode::BaseInit( SbiParser* p )
110 pGen = &p->aGen;
111 eTok = NIL;
112 pLeft = NULL;
113 pRight = NULL;
114 pWithParent = NULL;
115 bComposite = FALSE;
116 bError = FALSE;
119 SbiExprNode::~SbiExprNode()
121 delete pLeft;
122 delete pRight;
123 if( IsVariable() )
125 delete aVar.pPar;
126 delete aVar.pNext;
127 SbiExprListVector* pvMorePar = aVar.pvMorePar;
128 if( pvMorePar )
130 SbiExprListVector::iterator it;
131 for( it = pvMorePar->begin() ; it != pvMorePar->end() ; ++it )
132 delete *it;
133 delete pvMorePar;
138 SbiSymDef* SbiExprNode::GetVar()
140 if( eNodeType == SbxVARVAL )
141 return aVar.pDef;
142 else
143 return NULL;
146 SbiSymDef* SbiExprNode::GetRealVar()
148 SbiExprNode* p = GetRealNode();
149 if( p )
150 return p->GetVar();
151 else
152 return NULL;
155 // AB: 18.12.95
156 SbiExprNode* SbiExprNode::GetRealNode()
158 if( eNodeType == SbxVARVAL )
160 SbiExprNode* p = this;
161 while( p->aVar.pNext )
162 p = p->aVar.pNext;
163 return p;
165 else
166 return NULL;
169 // Diese Methode setzt den Typ um, falls er in den Integer-Bereich hineinpasst
171 BOOL SbiExprNode::IsIntConst()
173 if( eNodeType == SbxNUMVAL )
175 if( eType >= SbxINTEGER && eType <= SbxDOUBLE )
177 double n;
178 if( nVal >= SbxMININT && nVal <= SbxMAXINT && modf( nVal, &n ) == 0 )
180 nVal = (double) (short) nVal;
181 eType = SbxINTEGER;
182 return TRUE;
186 return FALSE;
189 BOOL SbiExprNode::IsNumber()
191 return BOOL( eNodeType == SbxNUMVAL );
194 BOOL SbiExprNode::IsString()
196 return BOOL( eNodeType == SbxSTRVAL );
199 BOOL SbiExprNode::IsVariable()
201 return BOOL( eNodeType == SbxVARVAL );
204 BOOL SbiExprNode::IsLvalue()
206 return IsVariable();
209 // Ermitteln der Tiefe eines Baumes
211 short SbiExprNode::GetDepth()
213 if( IsOperand() ) return 0;
214 else
216 short d1 = pLeft->GetDepth();
217 short d2 = pRight->GetDepth();
218 return( (d1 < d2 ) ? d2 : d1 ) + 1;
223 // Abgleich eines Baumes:
224 // 1. Constant Folding
225 // 2. Typabgleich
226 // 3. Umwandlung der Operanden in Strings
227 // 4. Hochziehen der Composite- und Error-Bits
229 void SbiExprNode::Optimize()
231 FoldConstants();
232 CollectBits();
235 // Hochziehen der Composite- und Fehlerbits
237 void SbiExprNode::CollectBits()
239 if( pLeft )
241 pLeft->CollectBits();
242 bError |= pLeft->bError;
243 bComposite |= pLeft->bComposite;
245 if( pRight )
247 pRight->CollectBits();
248 bError |= pRight->bError;
249 bComposite |= pRight->bComposite;
253 // Kann ein Zweig umgeformt werden, wird TRUE zurueckgeliefert. In diesem
254 // Fall ist das Ergebnis im linken Zweig.
256 void SbiExprNode::FoldConstants()
258 if( IsOperand() || eTok == LIKE ) return;
259 pLeft->FoldConstants();
260 if( pRight )
262 pRight->FoldConstants();
263 if( pLeft->IsConstant() && pRight->IsConstant()
264 && pLeft->eNodeType == pRight->eNodeType )
266 CollectBits();
267 if( eTok == CAT )
268 // CAT verbindet auch zwei Zahlen miteinander!
269 eType = SbxSTRING;
270 if( pLeft->eType == SbxSTRING )
271 // Kein Type Mismatch!
272 eType = SbxSTRING;
273 if( eType == SbxSTRING )
275 String rl( pLeft->GetString() );
276 String rr( pRight->GetString() );
277 delete pLeft; pLeft = NULL;
278 delete pRight; pRight = NULL;
279 bComposite = FALSE;
280 if( eTok == PLUS || eTok == CAT )
282 eTok = CAT;
283 // Verkettung:
284 aStrVal = rl;
285 aStrVal += rr;
286 eType = SbxSTRING;
287 eNodeType = SbxSTRVAL;
289 else
291 eType = SbxDOUBLE;
292 eNodeType = SbxNUMVAL;
293 StringCompare eRes = rr.CompareTo( rl );
294 switch( eTok )
296 case EQ:
297 nVal = ( eRes == COMPARE_EQUAL ) ? SbxTRUE : SbxFALSE;
298 break;
299 case NE:
300 nVal = ( eRes != COMPARE_EQUAL ) ? SbxTRUE : SbxFALSE;
301 break;
302 case LT:
303 nVal = ( eRes == COMPARE_LESS ) ? SbxTRUE : SbxFALSE;
304 break;
305 case GT:
306 nVal = ( eRes == COMPARE_GREATER ) ? SbxTRUE : SbxFALSE;
307 break;
308 case LE:
309 nVal = ( eRes != COMPARE_GREATER ) ? SbxTRUE : SbxFALSE;
310 break;
311 case GE:
312 nVal = ( eRes != COMPARE_LESS ) ? SbxTRUE : SbxFALSE;
313 break;
314 default:
315 pGen->GetParser()->Error( SbERR_CONVERSION );
316 bError = TRUE;
320 else
322 double nl = pLeft->nVal;
323 double nr = pRight->nVal;
324 long ll = 0, lr = 0;
325 long llMod = 0, lrMod = 0;
326 if( ( eTok >= AND && eTok <= IMP )
327 || eTok == IDIV || eTok == MOD )
329 // Integer-Operationen
330 BOOL err = FALSE;
331 if( nl > SbxMAXLNG ) err = TRUE, nl = SbxMAXLNG;
332 else
333 if( nl < SbxMINLNG ) err = TRUE, nl = SbxMINLNG;
334 if( nr > SbxMAXLNG ) err = TRUE, nr = SbxMAXLNG;
335 else
336 if( nr < SbxMINLNG ) err = TRUE, nr = SbxMINLNG;
337 ll = (long) nl; lr = (long) nr;
338 llMod = (long) (nl < 0 ? nl - 0.5 : nl + 0.5);
339 lrMod = (long) (nr < 0 ? nr - 0.5 : nr + 0.5);
340 if( err )
342 pGen->GetParser()->Error( SbERR_MATH_OVERFLOW );
343 bError = TRUE;
346 BOOL bBothInt = BOOL( pLeft->eType < SbxSINGLE
347 && pRight->eType < SbxSINGLE );
348 delete pLeft; pLeft = NULL;
349 delete pRight; pRight = NULL;
350 nVal = 0;
351 eType = SbxDOUBLE;
352 eNodeType = SbxNUMVAL;
353 bComposite = FALSE;
354 BOOL bCheckType = FALSE;
355 switch( eTok )
357 case EXPON:
358 nVal = pow( nl, nr ); break;
359 case MUL:
360 bCheckType = TRUE;
361 nVal = nl * nr; break;
362 case DIV:
363 if( !nr )
365 pGen->GetParser()->Error( SbERR_ZERODIV ); nVal = HUGE_VAL;
366 bError = TRUE;
367 } else nVal = nl / nr;
368 break;
369 case PLUS:
370 bCheckType = TRUE;
371 nVal = nl + nr; break;
372 case MINUS:
373 bCheckType = TRUE;
374 nVal = nl - nr; break;
375 case EQ:
376 nVal = ( nl == nr ) ? SbxTRUE : SbxFALSE;
377 eType = SbxINTEGER; break;
378 case NE:
379 nVal = ( nl != nr ) ? SbxTRUE : SbxFALSE;
380 eType = SbxINTEGER; break;
381 case LT:
382 nVal = ( nl < nr ) ? SbxTRUE : SbxFALSE;
383 eType = SbxINTEGER; break;
384 case GT:
385 nVal = ( nl > nr ) ? SbxTRUE : SbxFALSE;
386 eType = SbxINTEGER; break;
387 case LE:
388 nVal = ( nl <= nr ) ? SbxTRUE : SbxFALSE;
389 eType = SbxINTEGER; break;
390 case GE:
391 nVal = ( nl >= nr ) ? SbxTRUE : SbxFALSE;
392 eType = SbxINTEGER; break;
393 case IDIV:
394 if( !lr )
396 pGen->GetParser()->Error( SbERR_ZERODIV ); nVal = HUGE_VAL;
397 bError = TRUE;
398 } else nVal = ll / lr;
399 eType = SbxLONG; break;
400 case MOD:
401 if( !lr )
403 pGen->GetParser()->Error( SbERR_ZERODIV ); nVal = HUGE_VAL;
404 bError = TRUE;
405 } else nVal = llMod % lrMod;
406 eType = SbxLONG; break;
407 case AND:
408 nVal = (double) ( ll & lr ); eType = SbxLONG; break;
409 case OR:
410 nVal = (double) ( ll | lr ); eType = SbxLONG; break;
411 case XOR:
412 nVal = (double) ( ll ^ lr ); eType = SbxLONG; break;
413 case EQV:
414 nVal = (double) ( ~ll ^ lr ); eType = SbxLONG; break;
415 case IMP:
416 nVal = (double) ( ~ll | lr ); eType = SbxLONG; break;
417 default: break;
420 if( !::rtl::math::isFinite( nVal ) )
421 pGen->GetParser()->Error( SbERR_MATH_OVERFLOW );
423 // Den Datentyp wiederherstellen, um Rundungsfehler
424 // zu killen
425 if( bCheckType && bBothInt
426 && nVal >= SbxMINLNG && nVal <= SbxMAXLNG )
428 // NK-Stellen weg
429 long n = (long) nVal;
430 nVal = n;
431 eType = ( n >= SbxMININT && n <= SbxMAXINT )
432 ? SbxINTEGER : SbxLONG;
437 else if( pLeft->IsNumber() )
439 nVal = pLeft->nVal;
440 delete pLeft;
441 pLeft = NULL;
442 eType = SbxDOUBLE;
443 eNodeType = SbxNUMVAL;
444 bComposite = FALSE;
445 switch( eTok )
447 case NEG:
448 nVal = -nVal; break;
449 case NOT: {
450 // Integer-Operation!
451 BOOL err = FALSE;
452 if( nVal > SbxMAXLNG ) err = TRUE, nVal = SbxMAXLNG;
453 else
454 if( nVal < SbxMINLNG ) err = TRUE, nVal = SbxMINLNG;
455 if( err )
457 pGen->GetParser()->Error( SbERR_MATH_OVERFLOW );
458 bError = TRUE;
460 nVal = (double) ~((long) nVal);
461 eType = SbxLONG;
462 } break;
463 default: break;
466 if( eNodeType == SbxNUMVAL )
468 // Evtl auf INTEGER falten (wg. besserem Opcode)?
469 if( eType == SbxSINGLE || eType == SbxDOUBLE )
471 double x;
472 if( nVal >= SbxMINLNG && nVal <= SbxMAXLNG
473 && !modf( nVal, &x ) )
474 eType = SbxLONG;
476 if( eType == SbxLONG && nVal >= SbxMININT && nVal <= SbxMAXINT )
477 eType = SbxINTEGER;