1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
3 * This file is part of the LibreOffice project.
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
9 * This file incorporates work covered by the following license notice:
11 * Licensed to the Apache Software Foundation (ASF) under one or more
12 * contributor license agreements. See the NOTICE file distributed
13 * with this work for additional information regarding copyright
14 * ownership. The ASF licenses this file to you under the Apache
15 * License, Version 2.0 (the "License"); you may not use this file
16 * except in compliance with the License. You may obtain a copy of
17 * the License at http://www.apache.org/licenses/LICENSE-2.0 .
22 #include <basic/sbx.hxx> // because of ...IMPL_REF(...sbxvariable)
25 /***************************************************************************
29 ***************************************************************************/
31 SbiExpression::SbiExpression( SbiParser
* p
, SbiExprType t
,
32 SbiExprMode eMode
, const KeywordSymbolInfo
* pKeywordSymbolInfo
)
35 bBased
= bError
= bByVal
= bBracket
= false;
40 pExpr
= (t
!= SbSTDEXPR
) ? Term( pKeywordSymbolInfo
) : Boolean();
45 if( t
== SbLVALUE
&& !pExpr
->IsLvalue() )
47 p
->Error( SbERR_LVALUE_EXPECTED
);
49 if( t
== SbOPERAND
&& !IsVariable() )
51 p
->Error( SbERR_VAR_EXPECTED
);
55 SbiExpression::SbiExpression( SbiParser
* p
, double n
, SbxDataType t
)
60 bBased
= bError
= bByVal
= bBracket
= false;
61 pExpr
= new SbiExprNode( pParser
, n
, t
);
65 SbiExpression::SbiExpression( SbiParser
* p
, const SbiSymDef
& r
, SbiExprList
* pPar
)
69 bBased
= bError
= bByVal
= bBracket
= false;
71 pExpr
= new SbiExprNode( pParser
, r
, SbxVARIANT
, pPar
);
74 SbiExpression::~SbiExpression()
79 // reading in a complete identifier
80 // an identifier has the following form:
81 // name[(Parameter)][.Name[(parameter)]]...
82 // structure elements are coupled via the element pNext,
83 // so that they're not in the tree.
85 // Are there parameters without brackets following? This may be a number,
86 // a string, a symbol or also a comma (if the 1st parameter is missing)
88 static sal_Bool
DoParametersFollow( SbiParser
* p
, SbiExprType eCurExpr
, SbiToken eTok
)
94 // but only if similar to CALL!
95 if( !p
->WhiteSpace() || eCurExpr
!= SbSYMBOL
)
99 if ( eTok
== NUMBER
|| eTok
== MINUS
|| eTok
== FIXSTRING
||
100 eTok
== SYMBOL
|| eTok
== COMMA
|| eTok
== DOT
|| eTok
== NOT
|| eTok
== BYVAL
)
104 else // check for default params with reserved names ( e.g. names of tokens )
106 SbiTokenizer
tokens( *(SbiTokenizer
*)p
);
107 // Urk the Next() / Peek() symantics are... weird
109 if ( tokens
.Peek() == ASSIGN
)
117 // definition of a new symbol
119 static SbiSymDef
* AddSym ( SbiToken eTok
, SbiSymPool
& rPool
, SbiExprType eCurExpr
,
120 const OUString
& rName
, SbxDataType eType
, SbiParameters
* pPar
)
123 // A= is not a procedure
124 sal_Bool bHasType
= sal_Bool( eTok
== EQ
|| eTok
== DOT
);
125 if( ( !bHasType
&& eCurExpr
== SbSYMBOL
) || pPar
)
127 // so this is a procedure
128 // the correct pool should be found out, as
129 // procs must always get into a public pool
130 SbiSymPool
* pPool
= &rPool
;
131 if( pPool
->GetScope() != SbPUBLIC
)
133 pPool
= &rPool
.GetParser()->aPublics
;
135 SbiProcDef
* pProc
= pPool
->AddProc( rName
);
137 // special treatment for Colls like Documents(1)
138 if( eCurExpr
== SbSTDEXPR
)
143 pDef
->SetType( bHasType
? eType
: SbxEMPTY
);
146 // generate dummy parameters
148 for( short i
= 0; i
< pPar
->GetSize(); i
++ )
151 OUStringBuffer
aPar("PAR");
153 pProc
->GetParams().AddSym( aPar
.makeStringAndClear() );
159 // or a normal symbol
160 pDef
= rPool
.AddSym( rName
);
161 pDef
->SetType( eType
);
166 // currently even keywords are allowed (because of Dflt properties of the same name)
168 SbiExprNode
* SbiExpression::Term( const KeywordSymbolInfo
* pKeywordSymbolInfo
)
170 if( pParser
->Peek() == DOT
)
172 SbiExprNode
* pWithVar
= pParser
->GetWithVar();
173 // #26608: get to the node-chain's end to pass the correct object
174 SbiSymDef
* pDef
= pWithVar
? pWithVar
->GetRealVar() : NULL
;
175 SbiExprNode
* pNd
= NULL
;
182 pNd
= ObjTerm( *pDef
);
185 pNd
->SetWithParent( pWithVar
);
190 pParser
->Error( SbERR_UNEXPECTED
, DOT
);
191 pNd
= new SbiExprNode( pParser
, 1.0, SbxDOUBLE
);
196 SbiToken eTok
= (pKeywordSymbolInfo
== NULL
) ? pParser
->Next() : pKeywordSymbolInfo
->m_eTok
;
197 // memorize the parsing's begin
198 pParser
->LockColumn();
199 OUString
aSym( (pKeywordSymbolInfo
== NULL
) ? pParser
->GetSym() : pKeywordSymbolInfo
->m_aKeywordSymbol
);
200 SbxDataType eType
= (pKeywordSymbolInfo
== NULL
) ? pParser
->GetType() : pKeywordSymbolInfo
->m_eSbxDataType
;
201 SbiParameters
* pPar
= NULL
;
202 SbiExprListVector
* pvMoreParLcl
= NULL
;
203 // are there parameters following?
204 SbiToken eNextTok
= pParser
->Peek();
205 // is it a known parameter?
206 // create a string constant then, which will be recognized
207 // in the SbiParameters-ctor and is continued to be handled
208 if( eNextTok
== ASSIGN
)
210 pParser
->UnlockColumn();
211 return new SbiExprNode( pParser
, aSym
);
213 // no keywords allowed from here on!
214 if( pParser
->IsKwd( eTok
) )
216 if( pParser
->IsCompatible() && eTok
== INPUT
)
222 pParser
->Error( SbERR_SYNTAX
);
227 if( DoParametersFollow( pParser
, eCurExpr
, eTok
= eNextTok
) )
229 bool bStandaloneExpression
= (m_eMode
== EXPRMODE_STANDALONE
);
230 pPar
= new SbiParameters( pParser
, bStandaloneExpression
);
231 bError
= bError
|| !pPar
->IsValid();
233 bBracket
= pPar
->IsBracket();
234 eTok
= pParser
->Peek();
236 // i75443 check for additional sets of parameters
237 while( eTok
== LPAREN
)
239 if( pvMoreParLcl
== NULL
)
241 pvMoreParLcl
= new SbiExprListVector();
243 SbiParameters
* pAddPar
= new SbiParameters( pParser
);
244 pvMoreParLcl
->push_back( pAddPar
);
245 bError
= bError
|| !pAddPar
->IsValid();
246 eTok
= pParser
->Peek();
249 // It might be an object part, if . or ! is following.
250 // In case of . the variable must already be defined;
251 // it's an object, if pDef is NULL after the search.
252 sal_Bool bObj
= sal_Bool( ( eTok
== DOT
|| eTok
== EXCLAM
)
253 && !pParser
->WhiteSpace() );
256 bBracket
= false; // Now the bracket for the first term is obsolete
257 if( eType
== SbxVARIANT
)
263 // Name%. really does not work!
264 pParser
->Error( SbERR_BAD_DECLARATION
, aSym
);
269 SbiSymDef
* pDef
= pParser
->pPool
->Find( aSym
);
272 // Part of the Runtime-Library?
273 // from 31.3.1996: swapped out to parser-method
274 // (is also needed in SbiParser::DefVar() in DIM.CXX)
275 pDef
= pParser
->CheckRTLForSym( aSym
, eType
);
277 // #i109184: Check if symbol is or later will be defined inside module
278 SbModule
& rMod
= pParser
->aGen
.GetModule();
279 SbxArray
* pModMethods
= rMod
.GetMethods();
280 if( pModMethods
->Find( aSym
, SbxCLASS_DONTCARE
) )
291 pDef
= AddSym( eTok
, *pParser
->pPool
, eCurExpr
, aSym
, eType
, pPar
);
292 // Looks like this is a local ( but undefined variable )
293 // if it is in a static procedure then make this Symbol
295 if ( !bObj
&& pParser
->pProc
&& pParser
->pProc
->IsStatic() )
303 SbiConstDef
* pConst
= pDef
->GetConstDef();
308 if( pConst
->GetType() == SbxSTRING
)
310 return new SbiExprNode( pParser
, pConst
->GetString() );
314 return new SbiExprNode( pParser
, pConst
->GetValue(), pConst
->GetType() );
318 // 0 parameters come up to ()
319 if( pDef
->GetDims() )
321 if( pPar
&& pPar
->GetSize() && pPar
->GetSize() != pDef
->GetDims() )
323 pParser
->Error( SbERR_WRONG_DIMS
);
326 if( pDef
->IsDefinedAs() )
328 SbxDataType eDefType
= pDef
->GetType();
329 // #119187 Only error if types conflict
330 if( eType
>= SbxINTEGER
&& eType
<= SbxSTRING
&& eType
!= eDefType
)
332 // How? Define with AS first and take a Suffix then?
333 pParser
->Error( SbERR_BAD_DECLARATION
, aSym
);
336 else if ( eType
== SbxVARIANT
)
338 // if there's nothing named, take the type of the entry,
339 // but only if the var hasn't been defined with AS XXX
340 // so that we catch n% = 5 : print n
344 // checking type of variables:
345 // is there named anything different in the scanner?
346 // That's OK for methods!
347 if( eType
!= SbxVARIANT
&& // Variant takes everything
348 eType
!= pDef
->GetType() &&
349 !pDef
->GetProcDef() )
351 // maybe pDef describes an object that so far has only been
352 // recognized as SbxVARIANT - then change type of pDef
353 // from 16.12.95 (similar cases possible perhaps?!?)
354 if( eType
== SbxOBJECT
&& pDef
->GetType() == SbxVARIANT
)
356 pDef
->SetType( SbxOBJECT
);
360 pParser
->Error( SbERR_BAD_DECLARATION
, aSym
);
365 SbiExprNode
* pNd
= new SbiExprNode( pParser
, *pDef
, eType
);
368 pPar
= new SbiParameters( pParser
,sal_False
,sal_False
);
370 pNd
->aVar
.pPar
= pPar
;
371 pNd
->aVar
.pvMorePar
= pvMoreParLcl
;
374 // from 8.1.95: Object may also be of the type SbxVARIANT
375 if( pDef
->GetType() == SbxVARIANT
)
376 pDef
->SetType( SbxOBJECT
);
377 // if we scan something with point,
378 // the type must be SbxOBJECT
379 if( pDef
->GetType() != SbxOBJECT
&& pDef
->GetType() != SbxVARIANT
)
381 // defer error until runtime if in vba mode
382 if ( !pParser
->IsVBASupportOn() )
384 pParser
->Error( SbERR_BAD_DECLARATION
, aSym
);
390 pNd
->aVar
.pNext
= ObjTerm( *pDef
);
394 pParser
->UnlockColumn();
398 // construction of an object term. A term of this kind is part
399 // of an expression that begins with an object variable.
401 SbiExprNode
* SbiExpression::ObjTerm( SbiSymDef
& rObj
)
404 SbiToken eTok
= pParser
->Next();
405 if( eTok
!= SYMBOL
&& !pParser
->IsKwd( eTok
) && !pParser
->IsExtra( eTok
) )
407 // #66745 Some operators can also be allowed
408 // as identifiers, important for StarOne
409 if( eTok
!= MOD
&& eTok
!= NOT
&& eTok
!= AND
&& eTok
!= OR
&&
410 eTok
!= XOR
&& eTok
!= EQV
&& eTok
!= IMP
&& eTok
!= IS
)
412 pParser
->Error( SbERR_VAR_EXPECTED
);
421 OUString
aSym( pParser
->GetSym() );
422 SbxDataType eType
= pParser
->GetType();
423 SbiParameters
* pPar
= NULL
;
424 SbiExprListVector
* pvMoreParLcl
= NULL
;
425 eTok
= pParser
->Peek();
427 if( DoParametersFollow( pParser
, eCurExpr
, eTok
) )
429 bool bStandaloneExpression
= false;
430 pPar
= new SbiParameters( pParser
, bStandaloneExpression
);
431 bError
= bError
|| !pPar
->IsValid();
432 eTok
= pParser
->Peek();
434 // i109624 check for additional sets of parameters
435 while( eTok
== LPAREN
)
437 if( pvMoreParLcl
== NULL
)
439 pvMoreParLcl
= new SbiExprListVector();
441 SbiParameters
* pAddPar
= new SbiParameters( pParser
);
442 pvMoreParLcl
->push_back( pAddPar
);
443 bError
= bError
|| !pPar
->IsValid();
444 eTok
= pParser
->Peek();
447 sal_Bool bObj
= sal_Bool( ( eTok
== DOT
|| eTok
== EXCLAM
) && !pParser
->WhiteSpace() );
450 if( eType
== SbxVARIANT
)
456 // Name%. does really not work!
457 pParser
->Error( SbERR_BAD_DECLARATION
, aSym
);
462 // an object's symbol pool is always PUBLIC
463 SbiSymPool
& rPool
= rObj
.GetPool();
464 rPool
.SetScope( SbPUBLIC
);
465 SbiSymDef
* pDef
= rPool
.Find( aSym
);
468 pDef
= AddSym( eTok
, rPool
, eCurExpr
, aSym
, eType
, pPar
);
469 pDef
->SetType( eType
);
472 SbiExprNode
* pNd
= new SbiExprNode( pParser
, *pDef
, eType
);
473 pNd
->aVar
.pPar
= pPar
;
474 pNd
->aVar
.pvMorePar
= pvMoreParLcl
;
477 if( pDef
->GetType() == SbxVARIANT
)
479 pDef
->SetType( SbxOBJECT
);
481 if( pDef
->GetType() != SbxOBJECT
)
483 pParser
->Error( SbERR_BAD_DECLARATION
, aSym
);
488 pNd
->aVar
.pNext
= ObjTerm( *pDef
);
495 // an operand can be:
498 // structure elements
501 // bracketed expressions
503 SbiExprNode
* SbiExpression::Operand( bool bUsedForTypeOf
)
509 switch( eTok
= pParser
->Peek() )
513 // process something like "IF Not r Is Nothing Then .."
514 if( !bUsedForTypeOf
&& pParser
->IsVBASupportOn() && pParser
->Peek() == IS
)
516 eTok
= pParser
->Next();
517 pRes
= new SbiExprNode( pParser
, pRes
, eTok
, Like() );
521 pRes
= Term(); break;
524 pRes
= new SbiExprNode( pParser
, pParser
->GetDbl(), pParser
->GetType() );
528 pRes
= new SbiExprNode( pParser
, pParser
->GetSym() ); break;
531 if( nParenLevel
== 0 && m_eMode
== EXPRMODE_LPAREN_PENDING
&& pParser
->Peek() == RPAREN
)
533 m_eMode
= EXPRMODE_EMPTY_PAREN
;
534 pRes
= new SbiExprNode(); // Dummy node
540 if( pParser
->Peek() != RPAREN
)
542 // If there was a LPARAM, it does not belong to the expression
543 if( nParenLevel
== 1 && m_eMode
== EXPRMODE_LPAREN_PENDING
)
545 m_eMode
= EXPRMODE_LPAREN_NOT_NEEDED
;
549 pParser
->Error( SbERR_BAD_BRACKETS
);
555 if( nParenLevel
== 1 && m_eMode
== EXPRMODE_LPAREN_PENDING
)
557 SbiToken eTokAfterRParen
= pParser
->Peek();
558 if( eTokAfterRParen
== EQ
|| eTokAfterRParen
== LPAREN
|| eTokAfterRParen
== DOT
)
560 m_eMode
= EXPRMODE_ARRAY_OR_OBJECT
;
564 m_eMode
= EXPRMODE_STANDARD
;
571 // keywords here are OK at the moment!
572 if( pParser
->IsKwd( eTok
) )
579 pRes
= new SbiExprNode( pParser
, 1.0, SbxDOUBLE
);
580 pParser
->Error( SbERR_UNEXPECTED
, eTok
);
587 SbiExprNode
* SbiExpression::Unary()
590 SbiToken eTok
= pParser
->Peek();
596 pNd
= new SbiExprNode( pParser
, Unary(), eTok
, NULL
);
599 if( pParser
->IsVBASupportOn() )
606 pNd
= new SbiExprNode( pParser
, Unary(), eTok
, NULL
);
616 bool bUsedForTypeOf
= true;
617 SbiExprNode
* pObjNode
= Operand( bUsedForTypeOf
);
618 pParser
->TestToken( IS
);
620 SbiSymDef
* pTypeDef
= new SbiSymDef( aDummy
);
621 pParser
->TypeDecl( *pTypeDef
, sal_True
);
622 pNd
= new SbiExprNode( pParser
, pObjNode
, pTypeDef
->GetTypeId() );
629 SbiSymDef
* pTypeDef
= new SbiSymDef( aStr
);
630 pParser
->TypeDecl( *pTypeDef
, sal_True
);
631 pNd
= new SbiExprNode( pParser
, pTypeDef
->GetTypeId() );
640 SbiExprNode
* SbiExpression::Exp()
642 SbiExprNode
* pNd
= Unary();
643 if( m_eMode
!= EXPRMODE_EMPTY_PAREN
)
645 while( pParser
->Peek() == EXPON
)
647 SbiToken eTok
= pParser
->Next();
648 pNd
= new SbiExprNode( pParser
, pNd
, eTok
, Unary() );
654 SbiExprNode
* SbiExpression::MulDiv()
656 SbiExprNode
* pNd
= Exp();
657 if( m_eMode
!= EXPRMODE_EMPTY_PAREN
)
661 SbiToken eTok
= pParser
->Peek();
662 if( eTok
!= MUL
&& eTok
!= DIV
)
666 eTok
= pParser
->Next();
667 pNd
= new SbiExprNode( pParser
, pNd
, eTok
, Exp() );
673 SbiExprNode
* SbiExpression::IntDiv()
675 SbiExprNode
* pNd
= MulDiv();
676 if( m_eMode
!= EXPRMODE_EMPTY_PAREN
)
678 while( pParser
->Peek() == IDIV
)
680 SbiToken eTok
= pParser
->Next();
681 pNd
= new SbiExprNode( pParser
, pNd
, eTok
, MulDiv() );
687 SbiExprNode
* SbiExpression::Mod()
689 SbiExprNode
* pNd
= IntDiv();
690 if( m_eMode
!= EXPRMODE_EMPTY_PAREN
)
692 while( pParser
->Peek() == MOD
)
694 SbiToken eTok
= pParser
->Next();
695 pNd
= new SbiExprNode( pParser
, pNd
, eTok
, IntDiv() );
701 SbiExprNode
* SbiExpression::AddSub()
703 SbiExprNode
* pNd
= Mod();
704 if( m_eMode
!= EXPRMODE_EMPTY_PAREN
)
708 SbiToken eTok
= pParser
->Peek();
709 if( eTok
!= PLUS
&& eTok
!= MINUS
)
713 eTok
= pParser
->Next();
714 pNd
= new SbiExprNode( pParser
, pNd
, eTok
, Mod() );
720 SbiExprNode
* SbiExpression::Cat()
722 SbiExprNode
* pNd
= AddSub();
723 if( m_eMode
!= EXPRMODE_EMPTY_PAREN
)
727 SbiToken eTok
= pParser
->Peek();
732 eTok
= pParser
->Next();
733 pNd
= new SbiExprNode( pParser
, pNd
, eTok
, AddSub() );
739 SbiExprNode
* SbiExpression::Comp()
741 SbiExprNode
* pNd
= Cat();
742 if( m_eMode
!= EXPRMODE_EMPTY_PAREN
)
747 SbiToken eTok
= pParser
->Peek();
748 if( m_eMode
== EXPRMODE_ARRAY_OR_OBJECT
)
752 if( eTok
!= EQ
&& eTok
!= NE
&& eTok
!= LT
&&
753 eTok
!= GT
&& eTok
!= LE
&& eTok
!= GE
)
757 eTok
= pParser
->Next();
758 pNd
= new SbiExprNode( pParser
, pNd
, eTok
, Cat() );
766 SbiExprNode
* SbiExpression::VBA_Not()
768 SbiExprNode
* pNd
= NULL
;
770 SbiToken eTok
= pParser
->Peek();
774 pNd
= new SbiExprNode( pParser
, VBA_Not(), eTok
, NULL
);
783 SbiExprNode
* SbiExpression::Like()
785 SbiExprNode
* pNd
= pParser
->IsVBASupportOn() ? VBA_Not() : Comp();
786 if( m_eMode
!= EXPRMODE_EMPTY_PAREN
)
789 while( pParser
->Peek() == LIKE
)
791 SbiToken eTok
= pParser
->Next();
792 pNd
= new SbiExprNode( pParser
, pNd
, eTok
, Comp() ), nCount
++;
794 // multiple operands in a row does not work
795 if( nCount
> 1 && !pParser
->IsVBASupportOn() )
797 pParser
->Error( SbERR_SYNTAX
);
804 SbiExprNode
* SbiExpression::Boolean()
806 SbiExprNode
* pNd
= Like();
807 if( m_eMode
!= EXPRMODE_EMPTY_PAREN
)
811 SbiToken eTok
= pParser
->Peek();
812 if( (eTok
!= AND
) && (eTok
!= OR
) &&
813 (eTok
!= XOR
) && (eTok
!= EQV
) &&
814 (eTok
!= IMP
) && (eTok
!= IS
) )
818 eTok
= pParser
->Next();
819 pNd
= new SbiExprNode( pParser
, pNd
, eTok
, Like() );
825 /***************************************************************************
827 |* SbiConstExpression
829 ***************************************************************************/
831 SbiConstExpression::SbiConstExpression( SbiParser
* p
) : SbiExpression( p
)
833 if( pExpr
->IsConstant() )
835 eType
= pExpr
->GetType();
836 if( pExpr
->IsNumber() )
843 aVal
= pExpr
->aStrVal
;
848 // #40204 special treatment for sal_Bool-constants
849 sal_Bool bIsBool
= sal_False
;
850 if( pExpr
->eNodeType
== SbxVARVAL
)
852 SbiSymDef
* pVarDef
= pExpr
->GetVar();
854 sal_Bool bBoolVal
= sal_False
;
855 if( pVarDef
->GetName().equalsIgnoreAsciiCase( "true" ) )
860 else if( pVarDef
->GetName().equalsIgnoreAsciiCase( "false" ) )
861 //else if( pVarDef->GetName().ICompare( "false" ) == COMPARE_EQUAL )
864 bBoolVal
= sal_False
;
870 pExpr
= new SbiExprNode( pParser
, (bBoolVal
? SbxTRUE
: SbxFALSE
), SbxINTEGER
);
871 eType
= pExpr
->GetType();
878 pParser
->Error( SbERR_SYNTAX
);
885 short SbiConstExpression::GetShortValue()
887 if( eType
== SbxSTRING
)
889 SbxVariableRef refConv
= new SbxVariable
;
890 refConv
->PutString( aVal
);
891 return refConv
->GetInteger();
907 pParser
->Error( SbERR_OUT_OF_RANGE
);
909 else if( n
< SbxMININT
)
912 pParser
->Error( SbERR_OUT_OF_RANGE
);
920 /***************************************************************************
924 ***************************************************************************/
926 SbiExprList::SbiExprList( SbiParser
* p
)
936 SbiExprList::~SbiExprList()
938 SbiExpression
* p
= pFirst
;
941 SbiExpression
* q
= p
->pNext
;
948 SbiExpression
* SbiExprList::Get( short n
)
950 SbiExpression
* p
= pFirst
;
958 void SbiExprList::addExpression( SbiExpression
* pExpr
)
966 SbiExpression
* p
= pFirst
;
975 /***************************************************************************
979 ***************************************************************************/
981 // parsing constructor:
982 // the parameter list is completely parsed
983 // "procedurename()" is OK
984 // it's a function without parameters then
985 // i. e. you give an array as procedure parameter
987 // #i79918/#i80532: bConst has never been set to true
988 // -> reused as bStandaloneExpression
989 //SbiParameters::SbiParameters( SbiParser* p, sal_Bool bConst, sal_Bool bPar) :
990 SbiParameters::SbiParameters( SbiParser
* p
, bool bStandaloneExpression
, bool bPar
) :
997 SbiExpression
*pExpr
;
998 SbiToken eTok
= pParser
->Peek();
1000 bool bAssumeExprLParenMode
= false;
1001 bool bAssumeArrayMode
= false;
1002 if( eTok
== LPAREN
)
1004 if( bStandaloneExpression
)
1006 bAssumeExprLParenMode
= true;
1012 eTok
= pParser
->Peek();
1017 if( ( bBracket
&& eTok
== RPAREN
) || pParser
->IsEoln( eTok
) )
1019 if( eTok
== RPAREN
)
1025 // read in parameter table and lay down in correct order!
1026 SbiExpression
* pLast
= NULL
;
1034 pExpr
= new SbiExpression( pParser
, 0, SbxEMPTY
);
1036 // named arguments: either .name= or name:=
1039 bool bByVal
= false;
1044 eTok
= pParser
->Peek();
1047 if( bAssumeExprLParenMode
)
1049 pExpr
= new SbiExpression( pParser
, SbSTDEXPR
, EXPRMODE_LPAREN_PENDING
);
1050 bAssumeExprLParenMode
= sal_False
;
1052 SbiExprMode eModeAfter
= pExpr
->m_eMode
;
1053 if( eModeAfter
== EXPRMODE_LPAREN_NOT_NEEDED
)
1057 else if( eModeAfter
== EXPRMODE_ARRAY_OR_OBJECT
)
1059 // Expression "looks" like an array assignment
1060 // a(...)[(...)] = ? or a(...).b(...)
1061 // RPAREN is already parsed
1063 bAssumeArrayMode
= true;
1066 else if( eModeAfter
== EXPRMODE_EMPTY_PAREN
)
1072 pParser
->Error( SbERR_LVALUE_EXPECTED
);
1079 pExpr
= new SbiExpression( pParser
);
1081 if( bByVal
&& pExpr
->IsLvalue() )
1085 if( !bAssumeArrayMode
)
1087 if( pParser
->Peek() == ASSIGN
)
1090 // SbiExpression::Term() has made as string out of it
1091 aName
= pExpr
->GetString();
1094 pExpr
= new SbiExpression( pParser
);
1096 pExpr
->GetName() = aName
;
1099 pExpr
->pNext
= NULL
;
1102 pFirst
= pLast
= pExpr
;
1106 pLast
->pNext
= pExpr
, pLast
= pExpr
;
1109 bError
= bError
|| !pExpr
->IsValid();
1111 if( bAssumeArrayMode
)
1116 eTok
= pParser
->Peek();
1119 if( ( bBracket
&& eTok
== RPAREN
) || pParser
->IsEoln( eTok
) )
1123 pParser
->Error( bBracket
? SbERR_BAD_BRACKETS
: SbERR_EXPECTED
, COMMA
);
1129 eTok
= pParser
->Peek();
1130 if( ( bBracket
&& eTok
== RPAREN
) || pParser
->IsEoln( eTok
) )
1137 if( eTok
== RPAREN
)
1143 pParser
->Error( SbERR_BAD_BRACKETS
);
1150 /***************************************************************************
1154 ***************************************************************************/
1156 // parsing constructor:
1157 // A list of array dimensions is parsed. The expressions are tested for being
1158 // numeric. The bCONST-Bit is reset when all expressions are Integer constants.
1160 SbiDimList::SbiDimList( SbiParser
* p
) : SbiExprList( p
)
1164 if( pParser
->Next() != LPAREN
)
1166 pParser
->Error( SbERR_EXPECTED
, LPAREN
);
1167 bError
= true; return;
1170 if( pParser
->Peek() != RPAREN
)
1172 SbiExpression
*pExpr1
, *pExpr2
, *pLast
= NULL
;
1176 pExpr1
= new SbiExpression( pParser
);
1177 eTok
= pParser
->Next();
1180 pExpr2
= new SbiExpression( pParser
);
1181 eTok
= pParser
->Next();
1182 bConst
= bConst
&& pExpr1
->IsIntConstant() && pExpr2
->IsIntConstant();
1183 bError
= bError
|| !pExpr1
->IsValid() || !pExpr2
->IsValid();
1184 pExpr1
->pNext
= pExpr2
;
1191 pLast
->pNext
= pExpr1
;
1199 pExpr1
->pNext
= NULL
;
1200 bConst
= bConst
&& pExpr1
->IsIntConstant();
1201 bError
= bError
|| !pExpr1
->IsValid();
1204 pFirst
= pLast
= pExpr1
;
1208 pLast
->pNext
= pExpr1
, pLast
= pExpr1
;
1213 if( eTok
== RPAREN
) break;
1216 pParser
->Error( SbERR_BAD_BRACKETS
);
1222 else pParser
->Next();
1225 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */