1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
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"
36 #include <rtl/math.hxx>
40 //////////////////////////////////////////////////////////////////////////
42 SbiExprNode::SbiExprNode( void )
49 SbiExprNode::SbiExprNode( SbiParser
* p
, SbiExprNode
* l
, SbiToken t
, SbiExprNode
* r
)
57 eType
= SbxVARIANT
; // Nodes sind immer Variant
62 SbiExprNode::SbiExprNode( SbiParser
* p
, double n
, SbxDataType t
)
67 eNodeType
= SbxNUMVAL
;
71 SbiExprNode::SbiExprNode( SbiParser
* p
, const String
& rVal
)
76 eNodeType
= SbxSTRVAL
;
80 SbiExprNode::SbiExprNode( SbiParser
* p
, const SbiSymDef
& r
, SbxDataType t
, SbiExprList
* l
)
84 eType
= ( t
== SbxVARIANT
) ? r
.GetType() : t
;
85 eNodeType
= SbxVARVAL
;
86 aVar
.pDef
= (SbiSymDef
*) &r
;
88 aVar
.pvMorePar
= NULL
;
91 // Funktionsergebnisse sind nie starr
92 bComposite
= BOOL( aVar
.pDef
->GetProcDef() != NULL
);
96 SbiExprNode::SbiExprNode( SbiParser
* p
, SbiExprNode
* l
, USHORT nId
)
102 eNodeType
= SbxTYPEOF
;
107 // AB: 17.12.95, Hilfsfunktion fuer Ctor fuer einheitliche Initialisierung
108 void SbiExprNode::BaseInit( SbiParser
* p
)
119 SbiExprNode::~SbiExprNode()
127 SbiExprListVector
* pvMorePar
= aVar
.pvMorePar
;
130 SbiExprListVector::iterator it
;
131 for( it
= pvMorePar
->begin() ; it
!= pvMorePar
->end() ; ++it
)
138 SbiSymDef
* SbiExprNode::GetVar()
140 if( eNodeType
== SbxVARVAL
)
146 SbiSymDef
* SbiExprNode::GetRealVar()
148 SbiExprNode
* p
= GetRealNode();
156 SbiExprNode
* SbiExprNode::GetRealNode()
158 if( eNodeType
== SbxVARVAL
)
160 SbiExprNode
* p
= this;
161 while( p
->aVar
.pNext
)
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
)
178 if( nVal
>= SbxMININT
&& nVal
<= SbxMAXINT
&& modf( nVal
, &n
) == 0 )
180 nVal
= (double) (short) nVal
;
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()
209 // Ermitteln der Tiefe eines Baumes
211 short SbiExprNode::GetDepth()
213 if( IsOperand() ) return 0;
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
226 // 3. Umwandlung der Operanden in Strings
227 // 4. Hochziehen der Composite- und Error-Bits
229 void SbiExprNode::Optimize()
235 // Hochziehen der Composite- und Fehlerbits
237 void SbiExprNode::CollectBits()
241 pLeft
->CollectBits();
242 bError
|= pLeft
->bError
;
243 bComposite
|= pLeft
->bComposite
;
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();
262 pRight
->FoldConstants();
263 if( pLeft
->IsConstant() && pRight
->IsConstant()
264 && pLeft
->eNodeType
== pRight
->eNodeType
)
268 // CAT verbindet auch zwei Zahlen miteinander!
270 if( pLeft
->eType
== SbxSTRING
)
271 // Kein Type Mismatch!
273 if( eType
== SbxSTRING
)
275 String
rl( pLeft
->GetString() );
276 String
rr( pRight
->GetString() );
277 delete pLeft
; pLeft
= NULL
;
278 delete pRight
; pRight
= NULL
;
280 if( eTok
== PLUS
|| eTok
== CAT
)
287 eNodeType
= SbxSTRVAL
;
292 eNodeType
= SbxNUMVAL
;
293 StringCompare eRes
= rr
.CompareTo( rl
);
297 nVal
= ( eRes
== COMPARE_EQUAL
) ? SbxTRUE
: SbxFALSE
;
300 nVal
= ( eRes
!= COMPARE_EQUAL
) ? SbxTRUE
: SbxFALSE
;
303 nVal
= ( eRes
== COMPARE_LESS
) ? SbxTRUE
: SbxFALSE
;
306 nVal
= ( eRes
== COMPARE_GREATER
) ? SbxTRUE
: SbxFALSE
;
309 nVal
= ( eRes
!= COMPARE_GREATER
) ? SbxTRUE
: SbxFALSE
;
312 nVal
= ( eRes
!= COMPARE_LESS
) ? SbxTRUE
: SbxFALSE
;
315 pGen
->GetParser()->Error( SbERR_CONVERSION
);
322 double nl
= pLeft
->nVal
;
323 double nr
= pRight
->nVal
;
325 long llMod
= 0, lrMod
= 0;
326 if( ( eTok
>= AND
&& eTok
<= IMP
)
327 || eTok
== IDIV
|| eTok
== MOD
)
329 // Integer-Operationen
331 if( nl
> SbxMAXLNG
) err
= TRUE
, nl
= SbxMAXLNG
;
333 if( nl
< SbxMINLNG
) err
= TRUE
, nl
= SbxMINLNG
;
334 if( nr
> SbxMAXLNG
) err
= TRUE
, nr
= SbxMAXLNG
;
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);
342 pGen
->GetParser()->Error( SbERR_MATH_OVERFLOW
);
346 BOOL bBothInt
= BOOL( pLeft
->eType
< SbxSINGLE
347 && pRight
->eType
< SbxSINGLE
);
348 delete pLeft
; pLeft
= NULL
;
349 delete pRight
; pRight
= NULL
;
352 eNodeType
= SbxNUMVAL
;
354 BOOL bCheckType
= FALSE
;
358 nVal
= pow( nl
, nr
); break;
361 nVal
= nl
* nr
; break;
365 pGen
->GetParser()->Error( SbERR_ZERODIV
); nVal
= HUGE_VAL
;
367 } else nVal
= nl
/ nr
;
371 nVal
= nl
+ nr
; break;
374 nVal
= nl
- nr
; break;
376 nVal
= ( nl
== nr
) ? SbxTRUE
: SbxFALSE
;
377 eType
= SbxINTEGER
; break;
379 nVal
= ( nl
!= nr
) ? SbxTRUE
: SbxFALSE
;
380 eType
= SbxINTEGER
; break;
382 nVal
= ( nl
< nr
) ? SbxTRUE
: SbxFALSE
;
383 eType
= SbxINTEGER
; break;
385 nVal
= ( nl
> nr
) ? SbxTRUE
: SbxFALSE
;
386 eType
= SbxINTEGER
; break;
388 nVal
= ( nl
<= nr
) ? SbxTRUE
: SbxFALSE
;
389 eType
= SbxINTEGER
; break;
391 nVal
= ( nl
>= nr
) ? SbxTRUE
: SbxFALSE
;
392 eType
= SbxINTEGER
; break;
396 pGen
->GetParser()->Error( SbERR_ZERODIV
); nVal
= HUGE_VAL
;
398 } else nVal
= ll
/ lr
;
399 eType
= SbxLONG
; break;
403 pGen
->GetParser()->Error( SbERR_ZERODIV
); nVal
= HUGE_VAL
;
405 } else nVal
= llMod
% lrMod
;
406 eType
= SbxLONG
; break;
408 nVal
= (double) ( ll
& lr
); eType
= SbxLONG
; break;
410 nVal
= (double) ( ll
| lr
); eType
= SbxLONG
; break;
412 nVal
= (double) ( ll
^ lr
); eType
= SbxLONG
; break;
414 nVal
= (double) ( ~ll
^ lr
); eType
= SbxLONG
; break;
416 nVal
= (double) ( ~ll
| lr
); eType
= SbxLONG
; break;
420 if( !::rtl::math::isFinite( nVal
) )
421 pGen
->GetParser()->Error( SbERR_MATH_OVERFLOW
);
423 // Den Datentyp wiederherstellen, um Rundungsfehler
425 if( bCheckType
&& bBothInt
426 && nVal
>= SbxMINLNG
&& nVal
<= SbxMAXLNG
)
429 long n
= (long) nVal
;
431 eType
= ( n
>= SbxMININT
&& n
<= SbxMAXINT
)
432 ? SbxINTEGER
: SbxLONG
;
437 else if( pLeft
->IsNumber() )
443 eNodeType
= SbxNUMVAL
;
450 // Integer-Operation!
452 if( nVal
> SbxMAXLNG
) err
= TRUE
, nVal
= SbxMAXLNG
;
454 if( nVal
< SbxMINLNG
) err
= TRUE
, nVal
= SbxMINLNG
;
457 pGen
->GetParser()->Error( SbERR_MATH_OVERFLOW
);
460 nVal
= (double) ~((long) nVal
);
466 if( eNodeType
== SbxNUMVAL
)
468 // Evtl auf INTEGER falten (wg. besserem Opcode)?
469 if( eType
== SbxSINGLE
|| eType
== SbxDOUBLE
)
472 if( nVal
>= SbxMINLNG
&& nVal
<= SbxMAXLNG
473 && !modf( nVal
, &x
) )
476 if( eType
== SbxLONG
&& nVal
>= SbxMININT
&& nVal
<= SbxMAXINT
)