xref: /aoo41x/main/basic/source/comp/exprtree.cxx (revision e1f63238)
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
10*e1f63238SAndrew Rist  *
11*e1f63238SAndrew Rist  *   http://www.apache.org/licenses/LICENSE-2.0
12*e1f63238SAndrew Rist  *
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.
19*e1f63238SAndrew Rist  *
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 }
1159cdf0e10cSrcweir 
1160