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