xref: /AOO42X/main/basic/source/comp/exprtree.cxx (revision b1c5455db1639c48e26c568e4fa7ee78ca5d60ee)
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 "sbcomp.hxx"
28cdf0e10cSrcweir #include <basic/sbx.hxx>        // w.g. ...IMPL_REF(...sbxvariable)
29cdf0e10cSrcweir #include "expr.hxx"
30cdf0e10cSrcweir 
31cdf0e10cSrcweir /***************************************************************************
32cdf0e10cSrcweir |*
33cdf0e10cSrcweir |*      SbiExpression
34cdf0e10cSrcweir |*
35cdf0e10cSrcweir ***************************************************************************/
36cdf0e10cSrcweir 
SbiExpression(SbiParser * p,SbiExprType t,SbiExprMode eMode,const KeywordSymbolInfo * pKeywordSymbolInfo)37cdf0e10cSrcweir SbiExpression::SbiExpression( SbiParser* p, SbiExprType t,
38cdf0e10cSrcweir     SbiExprMode eMode, const KeywordSymbolInfo* pKeywordSymbolInfo )
39cdf0e10cSrcweir {
40cdf0e10cSrcweir     pParser = p;
41cdf0e10cSrcweir     bError = bByVal = bBased = bBracket = sal_False;
42cdf0e10cSrcweir     nParenLevel = 0;
43cdf0e10cSrcweir     eCurExpr = t;
44cdf0e10cSrcweir     m_eMode = eMode;
45cdf0e10cSrcweir     pNext = NULL;
46cdf0e10cSrcweir     pExpr = (t != SbSTDEXPR ) ? Term( pKeywordSymbolInfo ) : Boolean();
47cdf0e10cSrcweir     if( t != SbSYMBOL )
48cdf0e10cSrcweir         pExpr->Optimize();
49cdf0e10cSrcweir     if( t == SbLVALUE && !pExpr->IsLvalue() )
50cdf0e10cSrcweir         p->Error( SbERR_LVALUE_EXPECTED );
51cdf0e10cSrcweir     if( t == SbOPERAND && !IsVariable() )
52cdf0e10cSrcweir         p->Error( SbERR_VAR_EXPECTED );
53cdf0e10cSrcweir }
54cdf0e10cSrcweir 
SbiExpression(SbiParser * p,double n,SbxDataType t)55cdf0e10cSrcweir SbiExpression::SbiExpression( SbiParser* p, double n, SbxDataType t )
56cdf0e10cSrcweir {
57cdf0e10cSrcweir     pParser = p;
58cdf0e10cSrcweir     eCurExpr = SbOPERAND;
59cdf0e10cSrcweir     pNext = NULL;
60cdf0e10cSrcweir     bError = bByVal = bBased = bBracket = sal_False;
61cdf0e10cSrcweir     pExpr = new SbiExprNode( pParser, n, t );
62cdf0e10cSrcweir     pExpr->Optimize();
63cdf0e10cSrcweir }
64cdf0e10cSrcweir 
SbiExpression(SbiParser * p,const String & r)65cdf0e10cSrcweir SbiExpression::SbiExpression( SbiParser* p, const String& r )
66cdf0e10cSrcweir {
67cdf0e10cSrcweir     pParser = p;
68cdf0e10cSrcweir     pNext = NULL;
69cdf0e10cSrcweir     bError = bByVal = bBased = bBracket = sal_False;
70cdf0e10cSrcweir     eCurExpr = SbOPERAND;
71cdf0e10cSrcweir     pExpr = new SbiExprNode( pParser, r );
72cdf0e10cSrcweir }
73cdf0e10cSrcweir 
SbiExpression(SbiParser * p,const SbiSymDef & r,SbiExprList * pPar)74cdf0e10cSrcweir SbiExpression::SbiExpression( SbiParser* p, const SbiSymDef& r, SbiExprList* pPar )
75cdf0e10cSrcweir {
76cdf0e10cSrcweir     pParser = p;
77cdf0e10cSrcweir     pNext = NULL;
78cdf0e10cSrcweir     bError = bByVal = bBased = bBracket = sal_False;
79cdf0e10cSrcweir     eCurExpr = SbOPERAND;
80cdf0e10cSrcweir     pExpr = new SbiExprNode( pParser, r, SbxVARIANT, pPar );
81cdf0e10cSrcweir }
82cdf0e10cSrcweir 
SbiExpression(SbiParser * p,SbiToken t)83cdf0e10cSrcweir SbiExpression::SbiExpression( SbiParser* p, SbiToken t )
84cdf0e10cSrcweir {
85cdf0e10cSrcweir     pParser = p;
86cdf0e10cSrcweir     pNext = NULL;
87cdf0e10cSrcweir     bError = bByVal = bBased = bBracket = sal_False;
88cdf0e10cSrcweir     eCurExpr = SbOPERAND;
89cdf0e10cSrcweir     pExpr = new SbiExprNode( pParser, NULL, t, NULL );
90cdf0e10cSrcweir }
91cdf0e10cSrcweir 
~SbiExpression()92cdf0e10cSrcweir SbiExpression::~SbiExpression()
93cdf0e10cSrcweir {
94cdf0e10cSrcweir     delete pExpr;
95cdf0e10cSrcweir }
96cdf0e10cSrcweir 
97cdf0e10cSrcweir // Einlesen eines kompletten Bezeichners
98cdf0e10cSrcweir // Ein Bezeichner hat folgende Form:
99cdf0e10cSrcweir // name[(Parameter)][.Name[(parameter)]]...
100cdf0e10cSrcweir // Strukturelemente werden ueber das Element pNext verkoppelt,
101cdf0e10cSrcweir // damit sie nicht im Baum stehen.
102cdf0e10cSrcweir 
103cdf0e10cSrcweir // Folgen Parameter ohne Klammer? Dies kann eine Zahl, ein String,
104cdf0e10cSrcweir // ein Symbol oder auch ein Komma sein (wenn der 1. Parameter fehlt)
105cdf0e10cSrcweir 
DoParametersFollow(SbiParser * p,SbiExprType eCurExpr,SbiToken eTok)106cdf0e10cSrcweir static sal_Bool DoParametersFollow( SbiParser* p, SbiExprType eCurExpr, SbiToken eTok )
107cdf0e10cSrcweir {
108cdf0e10cSrcweir     if( eTok == LPAREN )
109cdf0e10cSrcweir         return sal_True;
110cdf0e10cSrcweir     // Aber nur, wenn CALL-aehnlich!
111cdf0e10cSrcweir     if( !p->WhiteSpace() || eCurExpr != SbSYMBOL )
112cdf0e10cSrcweir         return sal_False;
113cdf0e10cSrcweir     if (   eTok == NUMBER || eTok == MINUS || eTok == FIXSTRING
114cdf0e10cSrcweir         || eTok == SYMBOL || eTok == COMMA  || eTok == DOT || eTok == NOT || eTok == BYVAL )
115cdf0e10cSrcweir     {
116cdf0e10cSrcweir         return sal_True;
117cdf0e10cSrcweir     }
118cdf0e10cSrcweir     else // check for default params with reserved names ( e.g. names of tokens )
119cdf0e10cSrcweir     {
120cdf0e10cSrcweir         SbiTokenizer tokens( *(SbiTokenizer*)p );
121cdf0e10cSrcweir         // Urk the Next() / Peek() symantics are... weird
122cdf0e10cSrcweir         tokens.Next();
123cdf0e10cSrcweir         if ( tokens.Peek() == ASSIGN )
124cdf0e10cSrcweir             return sal_True;
125cdf0e10cSrcweir     }
126cdf0e10cSrcweir     return sal_False;
127cdf0e10cSrcweir }
128cdf0e10cSrcweir 
129cdf0e10cSrcweir // Definition eines neuen Symbols
130cdf0e10cSrcweir 
AddSym(SbiToken eTok,SbiSymPool & rPool,SbiExprType eCurExpr,const String & rName,SbxDataType eType,SbiParameters * pPar)131cdf0e10cSrcweir static SbiSymDef* AddSym
132cdf0e10cSrcweir     ( SbiToken eTok, SbiSymPool& rPool, SbiExprType eCurExpr,
133cdf0e10cSrcweir       const String& rName, SbxDataType eType, SbiParameters* pPar )
134cdf0e10cSrcweir {
135cdf0e10cSrcweir     SbiSymDef* pDef;
136cdf0e10cSrcweir     // A= ist keine Prozedur
137cdf0e10cSrcweir     sal_Bool bHasType = sal_Bool( eTok == EQ || eTok == DOT );
138cdf0e10cSrcweir     if( ( !bHasType && eCurExpr == SbSYMBOL ) || pPar )
139cdf0e10cSrcweir     {
140cdf0e10cSrcweir         // Dies ist also eine Prozedur
141cdf0e10cSrcweir         // da suche man doch den richtigen Pool raus, da Procs
142cdf0e10cSrcweir         // immer in einem Public-Pool landen muessen
143cdf0e10cSrcweir         SbiSymPool* pPool = &rPool;
144cdf0e10cSrcweir         if( pPool->GetScope() != SbPUBLIC )
145cdf0e10cSrcweir             pPool = &rPool.GetParser()->aPublics;
146cdf0e10cSrcweir         SbiProcDef* pProc = pPool->AddProc( rName );
147cdf0e10cSrcweir 
148cdf0e10cSrcweir         // Sonderbehandlung fuer Colls wie Documents(1)
149cdf0e10cSrcweir         if( eCurExpr == SbSTDEXPR )
150cdf0e10cSrcweir             bHasType = sal_True;
151cdf0e10cSrcweir 
152cdf0e10cSrcweir         pDef = pProc;
153cdf0e10cSrcweir         pDef->SetType( bHasType ? eType : SbxEMPTY );
154cdf0e10cSrcweir         if( pPar )
155cdf0e10cSrcweir         {
156cdf0e10cSrcweir             // Dummy-Parameter generieren
157cdf0e10cSrcweir             sal_uInt16 n = 1;
158cdf0e10cSrcweir             for( short i = 0; i < pPar->GetSize(); i++ )
159cdf0e10cSrcweir             {
160cdf0e10cSrcweir                 String aPar = String::CreateFromAscii( "PAR" );
161cdf0e10cSrcweir                 aPar += ++n;
162cdf0e10cSrcweir                 pProc->GetParams().AddSym( aPar );
163cdf0e10cSrcweir             }
164cdf0e10cSrcweir         }
165cdf0e10cSrcweir     }
166cdf0e10cSrcweir     else
167cdf0e10cSrcweir     {
168cdf0e10cSrcweir         // oder ein normales Symbol
169cdf0e10cSrcweir         pDef = rPool.AddSym( rName );
170cdf0e10cSrcweir         pDef->SetType( eType );
171cdf0e10cSrcweir     }
172cdf0e10cSrcweir     return pDef;
173cdf0e10cSrcweir }
174cdf0e10cSrcweir 
175cdf0e10cSrcweir // Zur Zeit sind sogar Keywords zugelassen (wg. gleichnamiger Dflt-Properties)
176cdf0e10cSrcweir 
Term(const KeywordSymbolInfo * pKeywordSymbolInfo)177cdf0e10cSrcweir SbiExprNode* SbiExpression::Term( const KeywordSymbolInfo* pKeywordSymbolInfo )
178cdf0e10cSrcweir {
179cdf0e10cSrcweir     if( pParser->Peek() == DOT )
180cdf0e10cSrcweir     {
181cdf0e10cSrcweir         // eine WITH-Variable
182cdf0e10cSrcweir         SbiExprNode* pWithVar = pParser->GetWithVar();
183cdf0e10cSrcweir         // #26608: Ans Ende der Node-Kette gehen, um richtiges Objekt zu uebergeben
184cdf0e10cSrcweir         SbiSymDef* pDef = pWithVar ? pWithVar->GetRealVar() : NULL;
185cdf0e10cSrcweir         SbiExprNode* pNd = NULL;
186cdf0e10cSrcweir         if( !pDef )
187cdf0e10cSrcweir         {
188cdf0e10cSrcweir             pParser->Next();
189cdf0e10cSrcweir         }
190cdf0e10cSrcweir         else
191cdf0e10cSrcweir         {
192cdf0e10cSrcweir             pNd = ObjTerm( *pDef );
193cdf0e10cSrcweir             if( pNd )
194cdf0e10cSrcweir                 pNd->SetWithParent( pWithVar );
195cdf0e10cSrcweir         }
196cdf0e10cSrcweir         if( !pNd )
197cdf0e10cSrcweir         {
198cdf0e10cSrcweir             pParser->Error( SbERR_UNEXPECTED, DOT );
199cdf0e10cSrcweir             pNd = new SbiExprNode( pParser, 1.0, SbxDOUBLE );
200cdf0e10cSrcweir         }
201cdf0e10cSrcweir         return pNd;
202cdf0e10cSrcweir     }
203cdf0e10cSrcweir 
204cdf0e10cSrcweir     SbiToken eTok = (pKeywordSymbolInfo == NULL) ? pParser->Next() : pKeywordSymbolInfo->m_eTok;
205cdf0e10cSrcweir     // Anfang des Parsings merken
206cdf0e10cSrcweir     pParser->LockColumn();
207cdf0e10cSrcweir     String aSym( (pKeywordSymbolInfo == NULL) ? pParser->GetSym() : pKeywordSymbolInfo->m_aKeywordSymbol );
208cdf0e10cSrcweir     SbxDataType eType = (pKeywordSymbolInfo == NULL) ? pParser->GetType() : pKeywordSymbolInfo->m_eSbxDataType;
209cdf0e10cSrcweir     SbiParameters* pPar = NULL;
210cdf0e10cSrcweir     SbiExprListVector* pvMoreParLcl = NULL;
211cdf0e10cSrcweir     // Folgen Parameter?
212cdf0e10cSrcweir     SbiToken eNextTok = pParser->Peek();
213cdf0e10cSrcweir     // Ist es ein benannter Parameter?
214cdf0e10cSrcweir     // Dann einfach eine Stringkonstante erzeugen. Diese wird
215cdf0e10cSrcweir     // im SbiParameters-ctor erkannt und weiterverarbeitet
216cdf0e10cSrcweir     if( eNextTok == ASSIGN )
217cdf0e10cSrcweir     {
218cdf0e10cSrcweir         pParser->UnlockColumn();
219cdf0e10cSrcweir         return new SbiExprNode( pParser, aSym );
220cdf0e10cSrcweir     }
221cdf0e10cSrcweir     // ab hier sind keine Keywords zugelassen!
222cdf0e10cSrcweir     if( pParser->IsKwd( eTok ) )
223cdf0e10cSrcweir     {
224cdf0e10cSrcweir         if( pParser->IsCompatible() && eTok == INPUT )
225cdf0e10cSrcweir         {
226cdf0e10cSrcweir             eTok = SYMBOL;
227cdf0e10cSrcweir         }
228cdf0e10cSrcweir         else
229cdf0e10cSrcweir         {
230cdf0e10cSrcweir             pParser->Error( SbERR_SYNTAX );
231cdf0e10cSrcweir             bError = sal_True;
232cdf0e10cSrcweir         }
233cdf0e10cSrcweir     }
234cdf0e10cSrcweir 
235cdf0e10cSrcweir     if( DoParametersFollow( pParser, eCurExpr, eTok = eNextTok ) )
236cdf0e10cSrcweir     {
237cdf0e10cSrcweir         bool bStandaloneExpression = (m_eMode == EXPRMODE_STANDALONE);
238cdf0e10cSrcweir         pPar = new SbiParameters( pParser, bStandaloneExpression );
239cdf0e10cSrcweir         bError |= !pPar->IsValid();
240cdf0e10cSrcweir         if( !bError )
241cdf0e10cSrcweir             bBracket = pPar->IsBracket();
242cdf0e10cSrcweir         eTok = pParser->Peek();
243cdf0e10cSrcweir 
244cdf0e10cSrcweir         // i75443 check for additional sets of parameters
245cdf0e10cSrcweir         while( eTok == LPAREN )
246cdf0e10cSrcweir         {
247cdf0e10cSrcweir             if( pvMoreParLcl == NULL )
248cdf0e10cSrcweir                 pvMoreParLcl = new SbiExprListVector();
249cdf0e10cSrcweir             SbiParameters* pAddPar = new SbiParameters( pParser );
250cdf0e10cSrcweir             pvMoreParLcl->push_back( pAddPar );
251cdf0e10cSrcweir             bError |= !pPar->IsValid();
252cdf0e10cSrcweir             eTok = pParser->Peek();
253cdf0e10cSrcweir         }
254cdf0e10cSrcweir     }
255cdf0e10cSrcweir     // Es koennte ein Objektteil sein, wenn . oder ! folgt
256cdf0e10cSrcweir     // Bei . muss aber die Variable bereits definiert sein; wenn pDef
257cdf0e10cSrcweir     // nach der Suche NULL ist, isses ein Objekt!
258cdf0e10cSrcweir     sal_Bool bObj = sal_Bool( ( eTok == DOT || eTok == EXCLAM )
259cdf0e10cSrcweir                     && !pParser->WhiteSpace() );
260cdf0e10cSrcweir     if( bObj )
261cdf0e10cSrcweir     {
262cdf0e10cSrcweir         bBracket = sal_False;   // Now the bracket for the first term is obsolete
263cdf0e10cSrcweir         if( eType == SbxVARIANT )
264cdf0e10cSrcweir             eType = SbxOBJECT;
265cdf0e10cSrcweir         else
266cdf0e10cSrcweir         {
267cdf0e10cSrcweir             // Name%. geht wirklich nicht!
268cdf0e10cSrcweir             pParser->Error( SbERR_BAD_DECLARATION, aSym );
269cdf0e10cSrcweir             bError = sal_True;
270cdf0e10cSrcweir         }
271cdf0e10cSrcweir     }
272cdf0e10cSrcweir     // Suche:
273cdf0e10cSrcweir     SbiSymDef* pDef = pParser->pPool->Find( aSym );
274cdf0e10cSrcweir     if( !pDef )
275cdf0e10cSrcweir     {
276cdf0e10cSrcweir         // Teil der Runtime-Library?
277cdf0e10cSrcweir         // AB 31.3.1996: In Parser-Methode ausgelagert
278cdf0e10cSrcweir         // (wird auch in SbiParser::DefVar() in DIM.CXX benoetigt)
279cdf0e10cSrcweir         pDef = pParser->CheckRTLForSym( aSym, eType );
280cdf0e10cSrcweir 
281cdf0e10cSrcweir         // #i109184: Check if symbol is or later will be defined inside module
282cdf0e10cSrcweir         SbModule& rMod = pParser->aGen.GetModule();
283cdf0e10cSrcweir         SbxArray* pModMethods = rMod.GetMethods();
284cdf0e10cSrcweir         if( pModMethods->Find( aSym, SbxCLASS_DONTCARE ) )
285cdf0e10cSrcweir             pDef = NULL;
286cdf0e10cSrcweir     }
287cdf0e10cSrcweir     if( !pDef )
288cdf0e10cSrcweir     {
289cdf0e10cSrcweir         // Falls ein Punkt angegeben war, isses Teil eines Objekts,
290cdf0e10cSrcweir         // also muss der Returnwert ein Objekt sein
291cdf0e10cSrcweir         if( bObj )
292cdf0e10cSrcweir             eType = SbxOBJECT;
293cdf0e10cSrcweir         pDef = AddSym( eTok, *pParser->pPool, eCurExpr, aSym, eType, pPar );
294cdf0e10cSrcweir         // Looks like this is a local ( but undefined variable )
295cdf0e10cSrcweir         // if it is in a static procedure then make this Symbol
296cdf0e10cSrcweir         // static
297cdf0e10cSrcweir         if ( !bObj && pParser->pProc && pParser->pProc->IsStatic() )
298cdf0e10cSrcweir             pDef->SetStatic();
299cdf0e10cSrcweir     }
300cdf0e10cSrcweir     else
301cdf0e10cSrcweir     {
302cdf0e10cSrcweir 
303cdf0e10cSrcweir         // Symbol ist bereits definiert.
304cdf0e10cSrcweir         // Ist es eine Konstante?
305cdf0e10cSrcweir         SbiConstDef* pConst = pDef->GetConstDef();
306cdf0e10cSrcweir         if( pConst )
307cdf0e10cSrcweir         {
308cdf0e10cSrcweir             if( pConst->GetType() == SbxSTRING )
309cdf0e10cSrcweir                 return new SbiExprNode( pParser, pConst->GetString() );
310cdf0e10cSrcweir             else
311cdf0e10cSrcweir                 return new SbiExprNode( pParser, pConst->GetValue(), pConst->GetType() );
312cdf0e10cSrcweir         }
313cdf0e10cSrcweir         // Hat es Dimensionen,
314cdf0e10cSrcweir         // und sind auch Parameter angegeben?
315cdf0e10cSrcweir         // (Wobei 0 Parameter () entsprechen)
316cdf0e10cSrcweir         if( pDef->GetDims() )
317cdf0e10cSrcweir         {
318cdf0e10cSrcweir             if( pPar && pPar->GetSize() && pPar->GetSize() != pDef->GetDims() )
319cdf0e10cSrcweir                 pParser->Error( SbERR_WRONG_DIMS );
320cdf0e10cSrcweir         }
321cdf0e10cSrcweir         if( pDef->IsDefinedAs() )
322cdf0e10cSrcweir         {
323cdf0e10cSrcweir             SbxDataType eDefType = pDef->GetType();
324cdf0e10cSrcweir             // #119187 Only error if types conflict
325cdf0e10cSrcweir             if( eType >= SbxINTEGER && eType <= SbxSTRING && eType != eDefType )
326cdf0e10cSrcweir             {
327cdf0e10cSrcweir                 // Wie? Erst mit AS definieren und dann einen Suffix nehmen?
328cdf0e10cSrcweir                 pParser->Error( SbERR_BAD_DECLARATION, aSym );
329cdf0e10cSrcweir                 bError = sal_True;
330cdf0e10cSrcweir             }
331cdf0e10cSrcweir             else if ( eType == SbxVARIANT )
332cdf0e10cSrcweir                 // Falls nix angegeben, den Typ des Eintrags nehmen
333cdf0e10cSrcweir                 // aber nur, wenn die Var nicht mit AS XXX definiert ist
334cdf0e10cSrcweir                 // damit erwischen wir n% = 5 : print n
335cdf0e10cSrcweir                 eType = eDefType;
336cdf0e10cSrcweir         }
337cdf0e10cSrcweir         // Typcheck bei Variablen:
338cdf0e10cSrcweir         // ist explizit im Scanner etwas anderes angegeben?
339cdf0e10cSrcweir         // Bei Methoden ist dies OK!
340cdf0e10cSrcweir         if( eType != SbxVARIANT &&          // Variant nimmt alles
341cdf0e10cSrcweir             eType != pDef->GetType() &&
342cdf0e10cSrcweir             !pDef->GetProcDef() )
343cdf0e10cSrcweir         {
344cdf0e10cSrcweir             // Es kann sein, dass pDef ein Objekt beschreibt, das bisher
345cdf0e10cSrcweir             // nur als SbxVARIANT erkannt wurde, dann Typ von pDef aendern
346cdf0e10cSrcweir             // AB, 16.12.95 (Vielleicht noch aehnliche Faelle moeglich ?!?)
347cdf0e10cSrcweir             if( eType == SbxOBJECT && pDef->GetType() == SbxVARIANT )
348cdf0e10cSrcweir             {
349cdf0e10cSrcweir                 pDef->SetType( SbxOBJECT );
350cdf0e10cSrcweir             }
351cdf0e10cSrcweir             else
352cdf0e10cSrcweir             {
353cdf0e10cSrcweir                 pParser->Error( SbERR_BAD_DECLARATION, aSym );
354cdf0e10cSrcweir                 bError = sal_True;
355cdf0e10cSrcweir             }
356cdf0e10cSrcweir         }
357cdf0e10cSrcweir     }
358cdf0e10cSrcweir     SbiExprNode* pNd = new SbiExprNode( pParser, *pDef, eType );
359cdf0e10cSrcweir     if( !pPar )
360cdf0e10cSrcweir         pPar = new SbiParameters( pParser,sal_False,sal_False );
361cdf0e10cSrcweir     pNd->aVar.pPar = pPar;
362cdf0e10cSrcweir     pNd->aVar.pvMorePar = pvMoreParLcl;
363cdf0e10cSrcweir     if( bObj )
364cdf0e10cSrcweir     {
365cdf0e10cSrcweir         // AB, 8.1.95: Objekt kann auch vom Typ SbxVARIANT sein
366cdf0e10cSrcweir         if( pDef->GetType() == SbxVARIANT )
367cdf0e10cSrcweir             pDef->SetType( SbxOBJECT );
368cdf0e10cSrcweir         // Falls wir etwas mit Punkt einscannen, muss der
369cdf0e10cSrcweir         // Typ SbxOBJECT sein
370cdf0e10cSrcweir         if( pDef->GetType() != SbxOBJECT && pDef->GetType() != SbxVARIANT )
371cdf0e10cSrcweir         {
372cdf0e10cSrcweir             pParser->Error( SbERR_BAD_DECLARATION, aSym );
373cdf0e10cSrcweir             bError = sal_True;
374cdf0e10cSrcweir         }
375cdf0e10cSrcweir         if( !bError )
376cdf0e10cSrcweir             pNd->aVar.pNext = ObjTerm( *pDef );
377cdf0e10cSrcweir     }
378cdf0e10cSrcweir     // Merken der Spalte 1 wieder freigeben
379cdf0e10cSrcweir     pParser->UnlockColumn();
380cdf0e10cSrcweir     return pNd;
381cdf0e10cSrcweir }
382cdf0e10cSrcweir 
383cdf0e10cSrcweir // Aufbau eines Objekt-Terms. Ein derartiger Term ist Teil
384cdf0e10cSrcweir // eines Ausdrucks, der mit einer Objektvariablen beginnt.
385cdf0e10cSrcweir 
ObjTerm(SbiSymDef & rObj)386cdf0e10cSrcweir SbiExprNode* SbiExpression::ObjTerm( SbiSymDef& rObj )
387cdf0e10cSrcweir {
388cdf0e10cSrcweir     pParser->Next();
389cdf0e10cSrcweir     SbiToken eTok = pParser->Next();
390cdf0e10cSrcweir     if( eTok != SYMBOL && !pParser->IsKwd( eTok ) && !pParser->IsExtra( eTok ) )
391cdf0e10cSrcweir     {
392cdf0e10cSrcweir         // #66745 Einige Operatoren koennen in diesem Kontext auch
393cdf0e10cSrcweir         // als Identifier zugelassen werden, wichtig fuer StarOne
394cdf0e10cSrcweir         if( eTok != MOD && eTok != NOT && eTok != AND && eTok != OR &&
395cdf0e10cSrcweir             eTok != XOR && eTok != EQV && eTok != IMP && eTok != IS )
396cdf0e10cSrcweir         {
397cdf0e10cSrcweir             pParser->Error( SbERR_VAR_EXPECTED );
398cdf0e10cSrcweir             bError = sal_True;
399cdf0e10cSrcweir         }
400cdf0e10cSrcweir     }
401cdf0e10cSrcweir     /* #118410 Allow type for Class methods and RTL object, e.g. RTL.Chr$(97)
402cdf0e10cSrcweir     else
403cdf0e10cSrcweir     {
404cdf0e10cSrcweir         if( pParser->GetType() != SbxVARIANT )
405cdf0e10cSrcweir             pParser->Error( SbERR_SYNTAX ), bError = sal_True;
406cdf0e10cSrcweir     }
407cdf0e10cSrcweir     */
408cdf0e10cSrcweir     if( bError )
409cdf0e10cSrcweir         return NULL;
410cdf0e10cSrcweir 
411cdf0e10cSrcweir     String aSym( pParser->GetSym() );
412cdf0e10cSrcweir     SbxDataType eType = pParser->GetType();
413cdf0e10cSrcweir     SbiParameters* pPar = NULL;
414cdf0e10cSrcweir     SbiExprListVector* pvMoreParLcl = NULL;
415cdf0e10cSrcweir     eTok = pParser->Peek();
416cdf0e10cSrcweir     // Parameter?
417cdf0e10cSrcweir     if( DoParametersFollow( pParser, eCurExpr, eTok ) )
418cdf0e10cSrcweir     {
419cdf0e10cSrcweir         bool bStandaloneExpression = false;
420cdf0e10cSrcweir         pPar = new SbiParameters( pParser, bStandaloneExpression );
421cdf0e10cSrcweir         bError |= !pPar->IsValid();
422cdf0e10cSrcweir         eTok = pParser->Peek();
423cdf0e10cSrcweir 
424cdf0e10cSrcweir         // i109624 check for additional sets of parameters
425cdf0e10cSrcweir         while( eTok == LPAREN )
426cdf0e10cSrcweir         {
427cdf0e10cSrcweir             if( pvMoreParLcl == NULL )
428cdf0e10cSrcweir                 pvMoreParLcl = new SbiExprListVector();
429cdf0e10cSrcweir             SbiParameters* pAddPar = new SbiParameters( pParser );
430cdf0e10cSrcweir             pvMoreParLcl->push_back( pAddPar );
431cdf0e10cSrcweir             bError |= !pPar->IsValid();
432cdf0e10cSrcweir             eTok = pParser->Peek();
433cdf0e10cSrcweir         }
434cdf0e10cSrcweir 
435cdf0e10cSrcweir     }
436cdf0e10cSrcweir     sal_Bool bObj = sal_Bool( ( eTok == DOT || eTok == EXCLAM ) && !pParser->WhiteSpace() );
437cdf0e10cSrcweir     if( bObj )
438cdf0e10cSrcweir     {
439cdf0e10cSrcweir         if( eType == SbxVARIANT )
440cdf0e10cSrcweir             eType = SbxOBJECT;
441cdf0e10cSrcweir         else
442cdf0e10cSrcweir         {
443cdf0e10cSrcweir             // Name%. geht wirklich nicht!
444cdf0e10cSrcweir             pParser->Error( SbERR_BAD_DECLARATION, aSym );
445cdf0e10cSrcweir             bError = sal_True;
446cdf0e10cSrcweir         }
447cdf0e10cSrcweir     }
448cdf0e10cSrcweir 
449cdf0e10cSrcweir     // Der Symbol-Pool eines Objekts ist immer PUBLIC
450cdf0e10cSrcweir     SbiSymPool& rPool = rObj.GetPool();
451cdf0e10cSrcweir     rPool.SetScope( SbPUBLIC );
452cdf0e10cSrcweir     SbiSymDef* pDef = rPool.Find( aSym );
453cdf0e10cSrcweir     if( !pDef )
454cdf0e10cSrcweir     {
455cdf0e10cSrcweir         pDef = AddSym( eTok, rPool, eCurExpr, aSym, eType, pPar );
456cdf0e10cSrcweir         pDef->SetType( eType );
457cdf0e10cSrcweir     }
458cdf0e10cSrcweir 
459cdf0e10cSrcweir     SbiExprNode* pNd = new SbiExprNode( pParser, *pDef, eType );
460cdf0e10cSrcweir     pNd->aVar.pPar = pPar;
461cdf0e10cSrcweir     pNd->aVar.pvMorePar = pvMoreParLcl;
462cdf0e10cSrcweir     if( bObj )
463cdf0e10cSrcweir     {
464cdf0e10cSrcweir         // Falls wir etwas mit Punkt einscannen, muss der
465cdf0e10cSrcweir         // Typ SbxOBJECT sein
466cdf0e10cSrcweir 
467cdf0e10cSrcweir         // AB, 3.1.96
468cdf0e10cSrcweir         // Es kann sein, dass pDef ein Objekt beschreibt, das bisher
469cdf0e10cSrcweir         // nur als SbxVARIANT erkannt wurde, dann Typ von pDef aendern
470cdf0e10cSrcweir         if( pDef->GetType() == SbxVARIANT )
471cdf0e10cSrcweir             pDef->SetType( SbxOBJECT );
472cdf0e10cSrcweir 
473cdf0e10cSrcweir         if( pDef->GetType() != SbxOBJECT )
474cdf0e10cSrcweir         {
475cdf0e10cSrcweir             pParser->Error( SbERR_BAD_DECLARATION, aSym );
476cdf0e10cSrcweir             bError = sal_True;
477cdf0e10cSrcweir         }
478cdf0e10cSrcweir         if( !bError )
479cdf0e10cSrcweir         {
480cdf0e10cSrcweir             pNd->aVar.pNext = ObjTerm( *pDef );
481cdf0e10cSrcweir             pNd->eType = eType;
482cdf0e10cSrcweir         }
483cdf0e10cSrcweir     }
484cdf0e10cSrcweir     return pNd;
485cdf0e10cSrcweir }
486cdf0e10cSrcweir 
487cdf0e10cSrcweir // Als Operanden kommen in Betracht:
488cdf0e10cSrcweir //      Konstante
489cdf0e10cSrcweir //      skalare Variable
490cdf0e10cSrcweir //      Strukturelemente
491cdf0e10cSrcweir //      Array-Elemente
492cdf0e10cSrcweir //      Funktionen
493cdf0e10cSrcweir //      geklammerte Ausdruecke
494cdf0e10cSrcweir 
Operand(bool bUsedForTypeOf)495cdf0e10cSrcweir SbiExprNode* SbiExpression::Operand( bool bUsedForTypeOf )
496cdf0e10cSrcweir {
497cdf0e10cSrcweir     SbiExprNode *pRes;
498cdf0e10cSrcweir     SbiToken eTok;
499cdf0e10cSrcweir 
500cdf0e10cSrcweir     // Operand testen:
501cdf0e10cSrcweir     switch( eTok = pParser->Peek() )
502cdf0e10cSrcweir     {
503cdf0e10cSrcweir         case SYMBOL:
504cdf0e10cSrcweir             pRes = Term();
505cdf0e10cSrcweir             // process something like "IF Not r Is Nothing Then .."
506cdf0e10cSrcweir             if( !bUsedForTypeOf && pParser->IsVBASupportOn() && pParser->Peek() == IS )
507cdf0e10cSrcweir             {
508cdf0e10cSrcweir                 eTok = pParser->Next();
509cdf0e10cSrcweir                 pRes = new SbiExprNode( pParser, pRes, eTok, Like() );
510cdf0e10cSrcweir             }
511cdf0e10cSrcweir             break;
512cdf0e10cSrcweir         case DOT:   // .with
513cdf0e10cSrcweir             pRes = Term(); break;
514cdf0e10cSrcweir         case NUMBER:
515cdf0e10cSrcweir             pParser->Next();
516cdf0e10cSrcweir             pRes = new SbiExprNode( pParser, pParser->GetDbl(), pParser->GetType() );
517cdf0e10cSrcweir             break;
518cdf0e10cSrcweir         case FIXSTRING:
519cdf0e10cSrcweir             pParser->Next();
520cdf0e10cSrcweir             pRes = new SbiExprNode( pParser, pParser->GetSym() ); break;
521cdf0e10cSrcweir         case LPAREN:
522cdf0e10cSrcweir             pParser->Next();
523cdf0e10cSrcweir             if( nParenLevel == 0 && m_eMode == EXPRMODE_LPAREN_PENDING && pParser->Peek() == RPAREN )
524cdf0e10cSrcweir             {
525cdf0e10cSrcweir                 m_eMode = EXPRMODE_EMPTY_PAREN;
526cdf0e10cSrcweir                 pRes = new SbiExprNode();   // Dummy node
527cdf0e10cSrcweir                 pParser->Next();
528cdf0e10cSrcweir                 break;
529cdf0e10cSrcweir             }
530cdf0e10cSrcweir             nParenLevel++;
531cdf0e10cSrcweir             pRes = Boolean();
532cdf0e10cSrcweir             if( pParser->Peek() != RPAREN )
533cdf0e10cSrcweir             {
534cdf0e10cSrcweir                 // If there was a LPARAM, it does not belong to the expression
535cdf0e10cSrcweir                 if( nParenLevel == 1 && m_eMode == EXPRMODE_LPAREN_PENDING )
536cdf0e10cSrcweir                     m_eMode = EXPRMODE_LPAREN_NOT_NEEDED;
537cdf0e10cSrcweir                 else
538cdf0e10cSrcweir                     pParser->Error( SbERR_BAD_BRACKETS );
539cdf0e10cSrcweir             }
540cdf0e10cSrcweir             else
541cdf0e10cSrcweir             {
542cdf0e10cSrcweir                 pParser->Next();
543cdf0e10cSrcweir                 if( nParenLevel == 1 && m_eMode == EXPRMODE_LPAREN_PENDING )
544cdf0e10cSrcweir                 {
545cdf0e10cSrcweir                     SbiToken eTokAfterRParen = pParser->Peek();
546cdf0e10cSrcweir                     if( eTokAfterRParen == EQ || eTokAfterRParen == LPAREN || eTokAfterRParen == DOT )
547cdf0e10cSrcweir                         m_eMode = EXPRMODE_ARRAY_OR_OBJECT;
548cdf0e10cSrcweir                     else
549cdf0e10cSrcweir                         m_eMode = EXPRMODE_STANDARD;
550cdf0e10cSrcweir                 }
551cdf0e10cSrcweir             }
552cdf0e10cSrcweir             nParenLevel--;
553cdf0e10cSrcweir             pRes->bComposite = sal_True;
554cdf0e10cSrcweir             break;
555cdf0e10cSrcweir         default:
556cdf0e10cSrcweir             // Zur Zeit sind Keywords hier OK!
557cdf0e10cSrcweir             if( pParser->IsKwd( eTok ) )
558cdf0e10cSrcweir                 pRes = Term();
559cdf0e10cSrcweir             else
560cdf0e10cSrcweir             {
561cdf0e10cSrcweir                 pParser->Next();
562cdf0e10cSrcweir                 pRes = new SbiExprNode( pParser, 1.0, SbxDOUBLE ); // bei Fehlern
563cdf0e10cSrcweir                 pParser->Error( SbERR_UNEXPECTED, eTok );
564cdf0e10cSrcweir             }
565cdf0e10cSrcweir     }
566cdf0e10cSrcweir     return pRes;
567cdf0e10cSrcweir }
568cdf0e10cSrcweir 
Unary()569cdf0e10cSrcweir SbiExprNode* SbiExpression::Unary()
570cdf0e10cSrcweir {
571cdf0e10cSrcweir     SbiExprNode* pNd;
572cdf0e10cSrcweir     SbiToken eTok = pParser->Peek();
573cdf0e10cSrcweir     switch( eTok )
574cdf0e10cSrcweir     {
575cdf0e10cSrcweir         case MINUS:
576cdf0e10cSrcweir             eTok = NEG;
577cdf0e10cSrcweir             pParser->Next();
578cdf0e10cSrcweir             pNd = new SbiExprNode( pParser, Unary(), eTok, NULL );
579cdf0e10cSrcweir             break;
580cdf0e10cSrcweir         case NOT:
581cdf0e10cSrcweir             if( pParser->IsVBASupportOn() )
582cdf0e10cSrcweir             {
583cdf0e10cSrcweir                 pNd = Operand();
584cdf0e10cSrcweir             }
585cdf0e10cSrcweir             else
586cdf0e10cSrcweir             {
587cdf0e10cSrcweir                 pParser->Next();
588cdf0e10cSrcweir                 pNd = new SbiExprNode( pParser, Unary(), eTok, NULL );
589cdf0e10cSrcweir             }
590cdf0e10cSrcweir             break;
591cdf0e10cSrcweir         case PLUS:
592cdf0e10cSrcweir             pParser->Next();
593cdf0e10cSrcweir             pNd = Unary();
594cdf0e10cSrcweir             break;
595cdf0e10cSrcweir         case TYPEOF:
596cdf0e10cSrcweir         {
597cdf0e10cSrcweir             pParser->Next();
598cdf0e10cSrcweir             bool bUsedForTypeOf = true;
599cdf0e10cSrcweir             SbiExprNode* pObjNode = Operand( bUsedForTypeOf );
600cdf0e10cSrcweir             pParser->TestToken( IS );
601cdf0e10cSrcweir             String aDummy;
602cdf0e10cSrcweir             SbiSymDef* pTypeDef = new SbiSymDef( aDummy );
603cdf0e10cSrcweir             pParser->TypeDecl( *pTypeDef, sal_True );
604cdf0e10cSrcweir             pNd = new SbiExprNode( pParser, pObjNode, pTypeDef->GetTypeId() );
605cdf0e10cSrcweir             break;
606cdf0e10cSrcweir         }
607cdf0e10cSrcweir         case NEW:
608cdf0e10cSrcweir         {
609cdf0e10cSrcweir             pParser->Next();
610cdf0e10cSrcweir             String aStr;
611cdf0e10cSrcweir             SbiSymDef* pTypeDef = new SbiSymDef( aStr );
612cdf0e10cSrcweir             pParser->TypeDecl( *pTypeDef, sal_True );
613cdf0e10cSrcweir             pNd = new SbiExprNode( pParser, pTypeDef->GetTypeId() );
614cdf0e10cSrcweir             break;
615cdf0e10cSrcweir         }
616cdf0e10cSrcweir         default:
617cdf0e10cSrcweir             pNd = Operand();
618cdf0e10cSrcweir     }
619cdf0e10cSrcweir     return pNd;
620cdf0e10cSrcweir }
621cdf0e10cSrcweir 
Exp()622cdf0e10cSrcweir SbiExprNode* SbiExpression::Exp()
623cdf0e10cSrcweir {
624cdf0e10cSrcweir     SbiExprNode* pNd = Unary();
625cdf0e10cSrcweir     if( m_eMode != EXPRMODE_EMPTY_PAREN )
626cdf0e10cSrcweir     {
627cdf0e10cSrcweir         while( pParser->Peek() == EXPON ) {
628cdf0e10cSrcweir             SbiToken eTok = pParser->Next();
629cdf0e10cSrcweir             pNd = new SbiExprNode( pParser, pNd, eTok, Unary() );
630cdf0e10cSrcweir         }
631cdf0e10cSrcweir     }
632cdf0e10cSrcweir     return pNd;
633cdf0e10cSrcweir }
634cdf0e10cSrcweir 
MulDiv()635cdf0e10cSrcweir SbiExprNode* SbiExpression::MulDiv()
636cdf0e10cSrcweir {
637cdf0e10cSrcweir     SbiExprNode* pNd = Exp();
638cdf0e10cSrcweir     if( m_eMode != EXPRMODE_EMPTY_PAREN )
639cdf0e10cSrcweir     {
640cdf0e10cSrcweir         for( ;; )
641cdf0e10cSrcweir         {
642cdf0e10cSrcweir             SbiToken eTok = pParser->Peek();
643cdf0e10cSrcweir             if( eTok != MUL && eTok != DIV )
644cdf0e10cSrcweir                 break;
645cdf0e10cSrcweir             eTok = pParser->Next();
646cdf0e10cSrcweir             pNd = new SbiExprNode( pParser, pNd, eTok, Exp() );
647cdf0e10cSrcweir         }
648cdf0e10cSrcweir     }
649cdf0e10cSrcweir     return pNd;
650cdf0e10cSrcweir }
651cdf0e10cSrcweir 
IntDiv()652cdf0e10cSrcweir SbiExprNode* SbiExpression::IntDiv()
653cdf0e10cSrcweir {
654cdf0e10cSrcweir     SbiExprNode* pNd = MulDiv();
655cdf0e10cSrcweir     if( m_eMode != EXPRMODE_EMPTY_PAREN )
656cdf0e10cSrcweir     {
657cdf0e10cSrcweir         while( pParser->Peek() == IDIV ) {
658cdf0e10cSrcweir             SbiToken eTok = pParser->Next();
659cdf0e10cSrcweir             pNd = new SbiExprNode( pParser, pNd, eTok, MulDiv() );
660cdf0e10cSrcweir         }
661cdf0e10cSrcweir     }
662cdf0e10cSrcweir     return pNd;
663cdf0e10cSrcweir }
664cdf0e10cSrcweir 
Mod()665cdf0e10cSrcweir SbiExprNode* SbiExpression::Mod()
666cdf0e10cSrcweir {
667cdf0e10cSrcweir     SbiExprNode* pNd = IntDiv();
668cdf0e10cSrcweir     if( m_eMode != EXPRMODE_EMPTY_PAREN )
669cdf0e10cSrcweir     {
670cdf0e10cSrcweir         while( pParser->Peek() == MOD ) {
671cdf0e10cSrcweir             SbiToken eTok = pParser->Next();
672cdf0e10cSrcweir             pNd = new SbiExprNode( pParser, pNd, eTok, IntDiv() );
673cdf0e10cSrcweir         }
674cdf0e10cSrcweir     }
675cdf0e10cSrcweir     return pNd;
676cdf0e10cSrcweir }
677cdf0e10cSrcweir 
AddSub()678cdf0e10cSrcweir SbiExprNode* SbiExpression::AddSub()
679cdf0e10cSrcweir {
680cdf0e10cSrcweir     SbiExprNode* pNd = Mod();
681cdf0e10cSrcweir     if( m_eMode != EXPRMODE_EMPTY_PAREN )
682cdf0e10cSrcweir     {
683cdf0e10cSrcweir         for( ;; )
684cdf0e10cSrcweir         {
685cdf0e10cSrcweir             SbiToken eTok = pParser->Peek();
686cdf0e10cSrcweir             if( eTok != PLUS && eTok != MINUS )
687cdf0e10cSrcweir                 break;
688cdf0e10cSrcweir             eTok = pParser->Next();
689cdf0e10cSrcweir             pNd = new SbiExprNode( pParser, pNd, eTok, Mod() );
690cdf0e10cSrcweir         }
691cdf0e10cSrcweir     }
692cdf0e10cSrcweir     return pNd;
693cdf0e10cSrcweir }
694cdf0e10cSrcweir 
Cat()695cdf0e10cSrcweir SbiExprNode* SbiExpression::Cat()
696cdf0e10cSrcweir {
697cdf0e10cSrcweir     SbiExprNode* pNd = AddSub();
698cdf0e10cSrcweir     if( m_eMode != EXPRMODE_EMPTY_PAREN )
699cdf0e10cSrcweir     {
700cdf0e10cSrcweir         for( ;; )
701cdf0e10cSrcweir         {
702cdf0e10cSrcweir             SbiToken eTok = pParser->Peek();
703cdf0e10cSrcweir             if( eTok != CAT )
704cdf0e10cSrcweir                 break;
705cdf0e10cSrcweir             eTok = pParser->Next();
706cdf0e10cSrcweir             pNd = new SbiExprNode( pParser, pNd, eTok, AddSub() );
707cdf0e10cSrcweir         }
708cdf0e10cSrcweir     }
709cdf0e10cSrcweir     return pNd;
710cdf0e10cSrcweir }
711cdf0e10cSrcweir 
Comp()712cdf0e10cSrcweir SbiExprNode* SbiExpression::Comp()
713cdf0e10cSrcweir {
714cdf0e10cSrcweir     SbiExprNode* pNd = Cat();
715cdf0e10cSrcweir     if( m_eMode != EXPRMODE_EMPTY_PAREN )
716cdf0e10cSrcweir     {
717cdf0e10cSrcweir         short nCount = 0;
718cdf0e10cSrcweir         for( ;; )
719cdf0e10cSrcweir         {
720cdf0e10cSrcweir             SbiToken eTok = pParser->Peek();
721cdf0e10cSrcweir             if( m_eMode == EXPRMODE_ARRAY_OR_OBJECT )
722cdf0e10cSrcweir                 break;
723cdf0e10cSrcweir             if( eTok != EQ && eTok != NE && eTok != LT
724cdf0e10cSrcweir              && eTok != GT && eTok != LE && eTok != GE )
725cdf0e10cSrcweir                 break;
726cdf0e10cSrcweir             eTok = pParser->Next();
727cdf0e10cSrcweir             pNd = new SbiExprNode( pParser, pNd, eTok, Cat() );
728cdf0e10cSrcweir             nCount++;
729cdf0e10cSrcweir         }
730cdf0e10cSrcweir     }
731cdf0e10cSrcweir     return pNd;
732cdf0e10cSrcweir }
733cdf0e10cSrcweir 
VBA_Not()734cdf0e10cSrcweir SbiExprNode* SbiExpression::VBA_Not()
735cdf0e10cSrcweir {
736cdf0e10cSrcweir     SbiExprNode* pNd = NULL;
737cdf0e10cSrcweir 
738cdf0e10cSrcweir     SbiToken eTok = pParser->Peek();
739cdf0e10cSrcweir     if( eTok == NOT )
740cdf0e10cSrcweir     {
741cdf0e10cSrcweir         pParser->Next();
742cdf0e10cSrcweir         pNd = new SbiExprNode( pParser, VBA_Not(), eTok, NULL );
743cdf0e10cSrcweir     }
744cdf0e10cSrcweir     else
745cdf0e10cSrcweir     {
746cdf0e10cSrcweir         pNd = Comp();
747cdf0e10cSrcweir     }
748cdf0e10cSrcweir     return pNd;
749cdf0e10cSrcweir }
750cdf0e10cSrcweir 
Like()751cdf0e10cSrcweir SbiExprNode* SbiExpression::Like()
752cdf0e10cSrcweir {
753cdf0e10cSrcweir     SbiExprNode* pNd = pParser->IsVBASupportOn() ? VBA_Not() : Comp();
754cdf0e10cSrcweir     if( m_eMode != EXPRMODE_EMPTY_PAREN )
755cdf0e10cSrcweir     {
756cdf0e10cSrcweir         short nCount = 0;
757cdf0e10cSrcweir         while( pParser->Peek() == LIKE ) {
758cdf0e10cSrcweir             SbiToken eTok = pParser->Next();
759cdf0e10cSrcweir             pNd = new SbiExprNode( pParser, pNd, eTok, Comp() ), nCount++;
760cdf0e10cSrcweir         }
761cdf0e10cSrcweir         // Mehrere Operatoren hintereinander gehen nicht
762cdf0e10cSrcweir         if( nCount > 1 )
763cdf0e10cSrcweir         {
764cdf0e10cSrcweir             pParser->Error( SbERR_SYNTAX );
765cdf0e10cSrcweir             bError = sal_True;
766cdf0e10cSrcweir         }
767cdf0e10cSrcweir     }
768cdf0e10cSrcweir     return pNd;
769cdf0e10cSrcweir }
770cdf0e10cSrcweir 
Boolean()771cdf0e10cSrcweir SbiExprNode* SbiExpression::Boolean()
772cdf0e10cSrcweir {
773cdf0e10cSrcweir     SbiExprNode* pNd = Like();
774cdf0e10cSrcweir     if( m_eMode != EXPRMODE_EMPTY_PAREN )
775cdf0e10cSrcweir     {
776cdf0e10cSrcweir         for( ;; )
777cdf0e10cSrcweir         {
778cdf0e10cSrcweir             SbiToken eTok = pParser->Peek();
779cdf0e10cSrcweir             if( eTok != AND && eTok != OR && eTok != XOR
780cdf0e10cSrcweir              && eTok != EQV && eTok != IMP && eTok != IS )
781cdf0e10cSrcweir                 break;
782cdf0e10cSrcweir             eTok = pParser->Next();
783cdf0e10cSrcweir             pNd = new SbiExprNode( pParser, pNd, eTok, Like() );
784cdf0e10cSrcweir         }
785cdf0e10cSrcweir     }
786cdf0e10cSrcweir     return pNd;
787cdf0e10cSrcweir }
788cdf0e10cSrcweir 
789cdf0e10cSrcweir /***************************************************************************
790cdf0e10cSrcweir |*
791cdf0e10cSrcweir |*      SbiConstExpression
792cdf0e10cSrcweir |*
793cdf0e10cSrcweir ***************************************************************************/
794cdf0e10cSrcweir 
795cdf0e10cSrcweir // Parsing einer Expression, die sich zu einer numerischen
796cdf0e10cSrcweir // Konstanten verarbeiten laesst.
797cdf0e10cSrcweir 
SbiConstExpression(SbiParser * p)798cdf0e10cSrcweir SbiConstExpression::SbiConstExpression( SbiParser* p ) : SbiExpression( p )
799cdf0e10cSrcweir {
800cdf0e10cSrcweir     if( pExpr->IsConstant() )
801cdf0e10cSrcweir     {
802cdf0e10cSrcweir         eType = pExpr->GetType();
803cdf0e10cSrcweir         if( pExpr->IsNumber() )
804cdf0e10cSrcweir         {
805cdf0e10cSrcweir             nVal = pExpr->nVal;
806cdf0e10cSrcweir         }
807cdf0e10cSrcweir         else
808cdf0e10cSrcweir         {
809cdf0e10cSrcweir             nVal = 0;
810cdf0e10cSrcweir             aVal = pExpr->aStrVal;
811cdf0e10cSrcweir         }
812cdf0e10cSrcweir     }
813cdf0e10cSrcweir     else
814cdf0e10cSrcweir     {
815cdf0e10cSrcweir         // #40204 Spezialbehandlung fuer sal_Bool-Konstanten
816cdf0e10cSrcweir         sal_Bool bIsBool = sal_False;
817cdf0e10cSrcweir         if( pExpr->eNodeType == SbxVARVAL )
818cdf0e10cSrcweir         {
819cdf0e10cSrcweir             SbiSymDef* pVarDef = pExpr->GetVar();
820cdf0e10cSrcweir 
821cdf0e10cSrcweir             // Ist es eine sal_Bool-Konstante?
822cdf0e10cSrcweir             sal_Bool bBoolVal = sal_False;
823cdf0e10cSrcweir             if( pVarDef->GetName().EqualsIgnoreCaseAscii( "true" ) )
824cdf0e10cSrcweir             //if( pVarDef->GetName().ICompare( "true" ) == COMPARE_EQUAL )
825cdf0e10cSrcweir             {
826cdf0e10cSrcweir                 bIsBool = sal_True;
827cdf0e10cSrcweir                 bBoolVal = sal_True;
828cdf0e10cSrcweir             }
829cdf0e10cSrcweir             else if( pVarDef->GetName().EqualsIgnoreCaseAscii( "false" ) )
830cdf0e10cSrcweir             //else if( pVarDef->GetName().ICompare( "false" ) == COMPARE_EQUAL )
831cdf0e10cSrcweir             {
832cdf0e10cSrcweir                 bIsBool = sal_True;
833cdf0e10cSrcweir                 bBoolVal = sal_False;
834cdf0e10cSrcweir             }
835cdf0e10cSrcweir 
836cdf0e10cSrcweir             // Wenn es ein sal_Bool ist, Node austauschen
837cdf0e10cSrcweir             if( bIsBool )
838cdf0e10cSrcweir             {
839cdf0e10cSrcweir                 delete pExpr;
840cdf0e10cSrcweir                 pExpr = new SbiExprNode( pParser, (bBoolVal ? SbxTRUE : SbxFALSE), SbxINTEGER );
841cdf0e10cSrcweir                 eType = pExpr->GetType();
842cdf0e10cSrcweir                 nVal = pExpr->nVal;
843cdf0e10cSrcweir             }
844cdf0e10cSrcweir         }
845cdf0e10cSrcweir 
846cdf0e10cSrcweir         if( !bIsBool )
847cdf0e10cSrcweir         {
848cdf0e10cSrcweir             pParser->Error( SbERR_SYNTAX );
849cdf0e10cSrcweir             eType = SbxDOUBLE;
850cdf0e10cSrcweir             nVal = 0;
851cdf0e10cSrcweir         }
852cdf0e10cSrcweir     }
853cdf0e10cSrcweir }
854cdf0e10cSrcweir 
GetShortValue()855cdf0e10cSrcweir short SbiConstExpression::GetShortValue()
856cdf0e10cSrcweir {
857cdf0e10cSrcweir     if( eType == SbxSTRING )
858cdf0e10cSrcweir     {
859cdf0e10cSrcweir         SbxVariableRef refConv = new SbxVariable;
860cdf0e10cSrcweir         refConv->PutString( aVal );
861cdf0e10cSrcweir         return refConv->GetInteger();
862cdf0e10cSrcweir     }
863cdf0e10cSrcweir     else
864cdf0e10cSrcweir     {
865cdf0e10cSrcweir         double n = nVal;
866cdf0e10cSrcweir         if( n > 0 ) n += .5; else n -= .5;
867cdf0e10cSrcweir         if( n > SbxMAXINT ) n = SbxMAXINT, pParser->Error( SbERR_OUT_OF_RANGE );
868cdf0e10cSrcweir         else
869cdf0e10cSrcweir         if( n < SbxMININT ) n = SbxMININT, pParser->Error( SbERR_OUT_OF_RANGE );
870cdf0e10cSrcweir         return (short) n;
871cdf0e10cSrcweir     }
872cdf0e10cSrcweir }
873cdf0e10cSrcweir 
874cdf0e10cSrcweir 
875cdf0e10cSrcweir /***************************************************************************
876cdf0e10cSrcweir |*
877cdf0e10cSrcweir |*      SbiExprList
878cdf0e10cSrcweir |*
879cdf0e10cSrcweir ***************************************************************************/
880cdf0e10cSrcweir 
SbiExprList(SbiParser * p)881cdf0e10cSrcweir SbiExprList::SbiExprList( SbiParser* p )
882cdf0e10cSrcweir {
883cdf0e10cSrcweir     pParser = p;
884cdf0e10cSrcweir     pFirst = NULL;
885cdf0e10cSrcweir     nExpr  =
886cdf0e10cSrcweir     nDim   = 0;
887cdf0e10cSrcweir     bError =
888cdf0e10cSrcweir     bBracket = sal_False;
889cdf0e10cSrcweir }
890cdf0e10cSrcweir 
~SbiExprList()891cdf0e10cSrcweir SbiExprList::~SbiExprList()
892cdf0e10cSrcweir {
893cdf0e10cSrcweir     SbiExpression* p = pFirst;
894cdf0e10cSrcweir     while( p )
895cdf0e10cSrcweir     {
896cdf0e10cSrcweir         SbiExpression* q = p->pNext;
897cdf0e10cSrcweir         delete p;
898cdf0e10cSrcweir         p = q;
899cdf0e10cSrcweir     }
900cdf0e10cSrcweir }
901cdf0e10cSrcweir 
902cdf0e10cSrcweir // Parameter anfordern (ab 0)
903cdf0e10cSrcweir 
Get(short n)904cdf0e10cSrcweir SbiExpression* SbiExprList::Get( short n )
905cdf0e10cSrcweir {
906cdf0e10cSrcweir     SbiExpression* p = pFirst;
907cdf0e10cSrcweir     while( n-- && p )
908cdf0e10cSrcweir         p = p->pNext;
909cdf0e10cSrcweir     return p;
910cdf0e10cSrcweir }
911cdf0e10cSrcweir 
addExpression(SbiExpression * pExpr)912cdf0e10cSrcweir void SbiExprList::addExpression( SbiExpression* pExpr )
913cdf0e10cSrcweir {
914cdf0e10cSrcweir     SbiExpression* p = pFirst;
915cdf0e10cSrcweir     while( p && p->pNext )
916cdf0e10cSrcweir         p = p->pNext;
917cdf0e10cSrcweir 
918cdf0e10cSrcweir     p->pNext = pExpr;
919cdf0e10cSrcweir }
920cdf0e10cSrcweir 
921cdf0e10cSrcweir 
922cdf0e10cSrcweir /***************************************************************************
923cdf0e10cSrcweir |*
924cdf0e10cSrcweir |*      SbiParameters
925cdf0e10cSrcweir |*
926cdf0e10cSrcweir ***************************************************************************/
927cdf0e10cSrcweir 
928cdf0e10cSrcweir // Parsender Konstruktor:
929cdf0e10cSrcweir // Die Parameterliste wird komplett geparst.
930cdf0e10cSrcweir // "Prozedurname()" ist OK.
931cdf0e10cSrcweir // Dann handelt es sich um eine Funktion ohne Parameter
932cdf0e10cSrcweir // respektive um die Angabe eines Arrays als Prozedurparameter.
933cdf0e10cSrcweir 
934cdf0e10cSrcweir // #i79918/#i80532: bConst has never been set to true
935cdf0e10cSrcweir // -> reused as bStandaloneExpression
936cdf0e10cSrcweir //SbiParameters::SbiParameters( SbiParser* p, sal_Bool bConst, sal_Bool bPar) :
SbiParameters(SbiParser * p,sal_Bool bStandaloneExpression,sal_Bool bPar)937cdf0e10cSrcweir SbiParameters::SbiParameters( SbiParser* p, sal_Bool bStandaloneExpression, sal_Bool bPar) :
938cdf0e10cSrcweir     SbiExprList( p )
939cdf0e10cSrcweir {
940cdf0e10cSrcweir     if( !bPar )
941cdf0e10cSrcweir         return;
942cdf0e10cSrcweir 
943cdf0e10cSrcweir     SbiExpression *pExpr;
944cdf0e10cSrcweir     SbiToken eTok = pParser->Peek();
945cdf0e10cSrcweir 
946cdf0e10cSrcweir     // evtl. Klammer auf weg:
947cdf0e10cSrcweir     bool bAssumeExprLParenMode = false;
948cdf0e10cSrcweir     bool bAssumeArrayMode = false;
949cdf0e10cSrcweir     if( eTok == LPAREN )
950cdf0e10cSrcweir     {
951cdf0e10cSrcweir         if( bStandaloneExpression )
952cdf0e10cSrcweir         {
953cdf0e10cSrcweir             bAssumeExprLParenMode = true;
954cdf0e10cSrcweir         }
955cdf0e10cSrcweir         else
956cdf0e10cSrcweir         {
957cdf0e10cSrcweir             bBracket = sal_True;
958cdf0e10cSrcweir             pParser->Next();
959cdf0e10cSrcweir             eTok = pParser->Peek();
960cdf0e10cSrcweir         }
961cdf0e10cSrcweir     }
962cdf0e10cSrcweir 
963cdf0e10cSrcweir     // Ende-Test
964cdf0e10cSrcweir     if( ( bBracket && eTok == RPAREN ) || pParser->IsEoln( eTok ) )
965cdf0e10cSrcweir     {
966cdf0e10cSrcweir         if( eTok == RPAREN )
967cdf0e10cSrcweir             pParser->Next();
968cdf0e10cSrcweir         return;
969cdf0e10cSrcweir     }
970cdf0e10cSrcweir     // Parametertabelle einlesen und in richtiger Folge ablegen!
971cdf0e10cSrcweir     SbiExpression* pLast = NULL;
972cdf0e10cSrcweir     String aName;
973cdf0e10cSrcweir     while( !bError )
974cdf0e10cSrcweir     {
975cdf0e10cSrcweir         aName.Erase();
976cdf0e10cSrcweir         // Fehlendes Argument
977cdf0e10cSrcweir         if( eTok == COMMA )
978cdf0e10cSrcweir         {
979cdf0e10cSrcweir             pExpr = new SbiExpression( pParser, 0, SbxEMPTY );
980cdf0e10cSrcweir             //if( bConst )
981cdf0e10cSrcweir             //  pParser->Error( SbERR_SYNTAX ), bError = sal_True;
982cdf0e10cSrcweir         }
983cdf0e10cSrcweir         // Benannte Argumente: entweder .name= oder name:=
984cdf0e10cSrcweir         else
985cdf0e10cSrcweir         {
986cdf0e10cSrcweir             bool bByVal = false;
987cdf0e10cSrcweir             if( eTok == BYVAL )
988cdf0e10cSrcweir             {
989cdf0e10cSrcweir                 bByVal = true;
990cdf0e10cSrcweir                 pParser->Next();
991cdf0e10cSrcweir                 eTok = pParser->Peek();
992cdf0e10cSrcweir             }
993cdf0e10cSrcweir 
994cdf0e10cSrcweir             if( bAssumeExprLParenMode )
995cdf0e10cSrcweir             {
996cdf0e10cSrcweir                 pExpr = new SbiExpression( pParser, SbSTDEXPR, EXPRMODE_LPAREN_PENDING );
997cdf0e10cSrcweir                 bAssumeExprLParenMode = sal_False;
998cdf0e10cSrcweir 
999cdf0e10cSrcweir                 SbiExprMode eModeAfter = pExpr->m_eMode;
1000cdf0e10cSrcweir                 if( eModeAfter == EXPRMODE_LPAREN_NOT_NEEDED )
1001cdf0e10cSrcweir                 {
1002cdf0e10cSrcweir                     bBracket = sal_True;
1003cdf0e10cSrcweir                 }
1004cdf0e10cSrcweir                 else if( eModeAfter == EXPRMODE_ARRAY_OR_OBJECT )
1005cdf0e10cSrcweir                 {
1006cdf0e10cSrcweir                     // Expression "looks" like an array assignment
1007cdf0e10cSrcweir                     // a(...)[(...)] = ? or a(...).b(...)
1008cdf0e10cSrcweir                     // RPAREN is already parsed
1009cdf0e10cSrcweir                     bBracket = sal_True;
1010cdf0e10cSrcweir                     bAssumeArrayMode = true;
1011cdf0e10cSrcweir                     eTok = NIL;
1012cdf0e10cSrcweir                 }
1013cdf0e10cSrcweir                 else if( eModeAfter == EXPRMODE_EMPTY_PAREN )
1014cdf0e10cSrcweir                 {
1015cdf0e10cSrcweir                     bBracket = sal_True;
1016cdf0e10cSrcweir                     delete pExpr;
1017cdf0e10cSrcweir                     if( bByVal )
1018cdf0e10cSrcweir                         pParser->Error( SbERR_LVALUE_EXPECTED );
1019cdf0e10cSrcweir                     return;
1020cdf0e10cSrcweir                 }
1021cdf0e10cSrcweir             }
1022cdf0e10cSrcweir             else
1023cdf0e10cSrcweir                 pExpr = new SbiExpression( pParser );
1024cdf0e10cSrcweir 
1025cdf0e10cSrcweir             if( bByVal && pExpr->IsLvalue() )
1026cdf0e10cSrcweir                 pExpr->SetByVal();
1027cdf0e10cSrcweir 
1028cdf0e10cSrcweir             //pExpr = bConst ? new SbiConstExpression( pParser )
1029cdf0e10cSrcweir             //              : new SbiExpression( pParser );
1030cdf0e10cSrcweir             if( !bAssumeArrayMode )
1031cdf0e10cSrcweir             {
1032cdf0e10cSrcweir                 if( pParser->Peek() == ASSIGN )
1033cdf0e10cSrcweir                 {
1034cdf0e10cSrcweir                     // VBA mode: name:=
1035cdf0e10cSrcweir                     // SbiExpression::Term() hat einen String daraus gemacht
1036cdf0e10cSrcweir                     aName = pExpr->GetString();
1037cdf0e10cSrcweir                     delete pExpr;
1038cdf0e10cSrcweir                     pParser->Next();
1039cdf0e10cSrcweir                     pExpr = new SbiExpression( pParser );
1040cdf0e10cSrcweir                     //if( bConst )
1041cdf0e10cSrcweir                     //  pParser->Error( SbERR_SYNTAX ), bError = sal_True;
1042cdf0e10cSrcweir                 }
1043cdf0e10cSrcweir                 pExpr->GetName() = aName;
1044cdf0e10cSrcweir             }
1045cdf0e10cSrcweir         }
1046cdf0e10cSrcweir         pExpr->pNext = NULL;
1047cdf0e10cSrcweir         if( !pLast )
1048cdf0e10cSrcweir             pFirst = pLast = pExpr;
1049cdf0e10cSrcweir         else
1050cdf0e10cSrcweir             pLast->pNext = pExpr, pLast = pExpr;
1051cdf0e10cSrcweir         nExpr++;
1052cdf0e10cSrcweir         bError |= !pExpr->IsValid();
1053cdf0e10cSrcweir 
1054cdf0e10cSrcweir         if( bAssumeArrayMode )
1055cdf0e10cSrcweir             break;
1056cdf0e10cSrcweir 
1057cdf0e10cSrcweir         // Naechstes Element?
1058cdf0e10cSrcweir         eTok = pParser->Peek();
1059cdf0e10cSrcweir         if( eTok != COMMA )
1060cdf0e10cSrcweir         {
1061cdf0e10cSrcweir             if( ( bBracket && eTok == RPAREN ) || pParser->IsEoln( eTok ) )
1062cdf0e10cSrcweir                 break;
1063cdf0e10cSrcweir             pParser->Error( bBracket
1064cdf0e10cSrcweir                             ? SbERR_BAD_BRACKETS
1065cdf0e10cSrcweir                             : SbERR_EXPECTED, COMMA );
1066cdf0e10cSrcweir             bError = sal_True;
1067cdf0e10cSrcweir         }
1068cdf0e10cSrcweir         else
1069cdf0e10cSrcweir         {
1070cdf0e10cSrcweir             pParser->Next();
1071cdf0e10cSrcweir             eTok = pParser->Peek();
1072cdf0e10cSrcweir             if( ( bBracket && eTok == RPAREN ) || pParser->IsEoln( eTok ) )
1073cdf0e10cSrcweir                 break;
1074cdf0e10cSrcweir         }
1075cdf0e10cSrcweir     }
1076cdf0e10cSrcweir     // Schliessende Klammer
1077cdf0e10cSrcweir     if( eTok == RPAREN )
1078cdf0e10cSrcweir     {
1079cdf0e10cSrcweir         pParser->Next();
1080cdf0e10cSrcweir         pParser->Peek();
1081cdf0e10cSrcweir         if( !bBracket )
1082cdf0e10cSrcweir         {
1083cdf0e10cSrcweir             pParser->Error( SbERR_BAD_BRACKETS );
1084cdf0e10cSrcweir             bError = sal_True;
1085cdf0e10cSrcweir         }
1086cdf0e10cSrcweir     }
1087cdf0e10cSrcweir     nDim = nExpr;
1088cdf0e10cSrcweir }
1089cdf0e10cSrcweir 
1090cdf0e10cSrcweir /***************************************************************************
1091cdf0e10cSrcweir |*
1092cdf0e10cSrcweir |*      SbiDimList
1093cdf0e10cSrcweir |*
1094cdf0e10cSrcweir ***************************************************************************/
1095cdf0e10cSrcweir 
1096cdf0e10cSrcweir // Parsender Konstruktor:
1097cdf0e10cSrcweir // Eine Liste von Array-Dimensionen wird geparst. Die Ausdruecke werden
1098cdf0e10cSrcweir // auf numerisch getestet. Das bCONST-Bit wird gesetzt, wenn alle Ausdruecke
1099cdf0e10cSrcweir // Integer-Konstanten sind.
1100cdf0e10cSrcweir 
SbiDimList(SbiParser * p)1101cdf0e10cSrcweir SbiDimList::SbiDimList( SbiParser* p ) : SbiExprList( p )
1102cdf0e10cSrcweir {
1103cdf0e10cSrcweir     bConst = sal_True;
1104cdf0e10cSrcweir 
1105cdf0e10cSrcweir     if( pParser->Next() != LPAREN )
1106cdf0e10cSrcweir     {
1107cdf0e10cSrcweir         pParser->Error( SbERR_EXPECTED, LPAREN );
1108cdf0e10cSrcweir         bError = sal_True; return;
1109cdf0e10cSrcweir     }
1110cdf0e10cSrcweir 
1111cdf0e10cSrcweir     if( pParser->Peek() != RPAREN )
1112cdf0e10cSrcweir     {
1113cdf0e10cSrcweir         SbiExpression *pExpr1, *pExpr2, *pLast = NULL;
1114cdf0e10cSrcweir         SbiToken eTok;
1115cdf0e10cSrcweir         for( ;; )
1116cdf0e10cSrcweir         {
1117cdf0e10cSrcweir             pExpr1 = new SbiExpression( pParser );
1118cdf0e10cSrcweir             eTok = pParser->Next();
1119cdf0e10cSrcweir             if( eTok == TO )
1120cdf0e10cSrcweir             {
1121cdf0e10cSrcweir                 pExpr2 = new SbiExpression( pParser );
1122cdf0e10cSrcweir                 eTok = pParser->Next();
1123cdf0e10cSrcweir                 bConst &= pExpr1->IsIntConstant() & pExpr2->IsIntConstant();
1124cdf0e10cSrcweir                 bError |= !pExpr1->IsValid();
1125cdf0e10cSrcweir                 bError |= !pExpr2->IsValid();
1126cdf0e10cSrcweir                 pExpr1->pNext = pExpr2;
1127cdf0e10cSrcweir                 if( !pLast )
1128cdf0e10cSrcweir                     pFirst = pExpr1;
1129cdf0e10cSrcweir                 else
1130cdf0e10cSrcweir                     pLast->pNext = pExpr1;
1131cdf0e10cSrcweir                 pLast = pExpr2;
1132cdf0e10cSrcweir                 nExpr += 2;
1133cdf0e10cSrcweir             }
1134cdf0e10cSrcweir             else
1135cdf0e10cSrcweir             {
1136cdf0e10cSrcweir                 // Nur eine Dim-Angabe
1137cdf0e10cSrcweir                 pExpr1->SetBased();
1138cdf0e10cSrcweir                 pExpr1->pNext = NULL;
1139cdf0e10cSrcweir                 bConst &= pExpr1->IsIntConstant();
1140cdf0e10cSrcweir                 bError |= !pExpr1->IsValid();
1141cdf0e10cSrcweir                 if( !pLast )
1142cdf0e10cSrcweir                     pFirst = pLast = pExpr1;
1143cdf0e10cSrcweir                 else
1144cdf0e10cSrcweir                     pLast->pNext = pExpr1, pLast = pExpr1;
1145cdf0e10cSrcweir                 nExpr++;
1146cdf0e10cSrcweir             }
1147cdf0e10cSrcweir             nDim++;
1148cdf0e10cSrcweir             if( eTok == RPAREN ) break;
1149cdf0e10cSrcweir             if( eTok != COMMA )
1150cdf0e10cSrcweir             {
1151cdf0e10cSrcweir                 pParser->Error( SbERR_BAD_BRACKETS );
1152cdf0e10cSrcweir                 pParser->Next();
1153cdf0e10cSrcweir                 break;
1154cdf0e10cSrcweir             }
1155cdf0e10cSrcweir         }
1156cdf0e10cSrcweir     }
1157cdf0e10cSrcweir     else pParser->Next();
1158cdf0e10cSrcweir }
1159