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