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