xref: /AOO41X/main/basic/source/comp/exprnode.cxx (revision e1f63238eb022c8a12b30d46a012444ff20e0951)
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