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>
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
)
58 bBased
= bError
= bByVal
= bBracket
= false;
61 m_eMode
= EXPRMODE_STANDARD
;
63 pExpr
= new SbiExprNode( pParser
, n
, t
);
67 SbiExpression::SbiExpression( SbiParser
* p
, const SbiSymDef
& r
, SbiExprList
* pPar
)
70 bBased
= bError
= bByVal
= bBracket
= false;
73 m_eMode
= EXPRMODE_STANDARD
;
75 pExpr
= new SbiExprNode( pParser
, r
, SbxVARIANT
, pPar
);
78 SbiExpression::~SbiExpression()
83 // reading in a complete identifier
84 // an identifier has the following form:
85 // name[(Parameter)][.Name[(parameter)]]...
86 // structure elements are coupled via the element pNext,
87 // so that they're not in the tree.
89 // Are there parameters without brackets following? This may be a number,
90 // a string, a symbol or also a comma (if the 1st parameter is missing)
92 static bool DoParametersFollow( SbiParser
* p
, SbiExprType eCurExpr
, SbiToken eTok
)
98 // but only if similar to CALL!
99 if( !p
->WhiteSpace() || eCurExpr
!= SbSYMBOL
)
103 if ( eTok
== NUMBER
|| eTok
== MINUS
|| eTok
== FIXSTRING
||
104 eTok
== SYMBOL
|| eTok
== COMMA
|| eTok
== DOT
|| eTok
== NOT
|| eTok
== BYVAL
)
108 else // check for default params with reserved names ( e.g. names of tokens )
110 SbiTokenizer
tokens( *(SbiTokenizer
*)p
);
111 // Urk the Next() / Peek() symantics are... weird
113 if ( tokens
.Peek() == ASSIGN
)
121 // definition of a new symbol
123 static SbiSymDef
* AddSym ( SbiToken eTok
, SbiSymPool
& rPool
, SbiExprType eCurExpr
,
124 const OUString
& rName
, SbxDataType eType
, SbiParameters
* pPar
)
127 // A= is not a procedure
128 bool bHasType
= ( eTok
== EQ
|| eTok
== DOT
);
129 if( ( !bHasType
&& eCurExpr
== SbSYMBOL
) || pPar
)
131 // so this is a procedure
132 // the correct pool should be found out, as
133 // procs must always get into a public pool
134 SbiSymPool
* pPool
= &rPool
;
135 if( pPool
->GetScope() != SbPUBLIC
)
137 pPool
= &rPool
.GetParser()->aPublics
;
139 SbiProcDef
* pProc
= pPool
->AddProc( rName
);
141 // special treatment for Colls like Documents(1)
142 if( eCurExpr
== SbSTDEXPR
)
147 pDef
->SetType( bHasType
? eType
: SbxEMPTY
);
150 // generate dummy parameters
152 for( short i
= 0; i
< pPar
->GetSize(); i
++ )
155 OUStringBuffer
aPar("PAR");
157 pProc
->GetParams().AddSym( aPar
.makeStringAndClear() );
163 // or a normal symbol
164 pDef
= rPool
.AddSym( rName
);
165 pDef
->SetType( eType
);
170 // currently even keywords are allowed (because of Dflt properties of the same name)
172 SbiExprNode
* SbiExpression::Term( const KeywordSymbolInfo
* pKeywordSymbolInfo
)
174 if( pParser
->Peek() == DOT
)
176 SbiExprNode
* pWithVar
= pParser
->GetWithVar();
177 // #26608: get to the node-chain's end to pass the correct object
178 SbiSymDef
* pDef
= pWithVar
? pWithVar
->GetRealVar() : NULL
;
179 SbiExprNode
* pNd
= NULL
;
186 pNd
= ObjTerm( *pDef
);
189 pNd
->SetWithParent( pWithVar
);
194 pParser
->Error( SbERR_UNEXPECTED
, DOT
);
195 pNd
= new SbiExprNode( pParser
, 1.0, SbxDOUBLE
);
200 SbiToken eTok
= (pKeywordSymbolInfo
== NULL
) ? pParser
->Next() : pKeywordSymbolInfo
->m_eTok
;
201 // memorize the parsing's begin
202 pParser
->LockColumn();
203 OUString
aSym( (pKeywordSymbolInfo
== NULL
) ? pParser
->GetSym() : pKeywordSymbolInfo
->m_aKeywordSymbol
);
204 SbxDataType eType
= (pKeywordSymbolInfo
== NULL
) ? pParser
->GetType() : pKeywordSymbolInfo
->m_eSbxDataType
;
205 SbiParameters
* pPar
= NULL
;
206 SbiExprListVector
* pvMoreParLcl
= NULL
;
207 // are there parameters following?
208 SbiToken eNextTok
= pParser
->Peek();
209 // is it a known parameter?
210 // create a string constant then, which will be recognized
211 // in the SbiParameters-ctor and is continued to be handled
212 if( eNextTok
== ASSIGN
)
214 pParser
->UnlockColumn();
215 return new SbiExprNode( pParser
, aSym
);
217 // no keywords allowed from here on!
218 if( SbiTokenizer::IsKwd( eTok
) )
220 if( pParser
->IsCompatible() && eTok
== INPUT
)
226 pParser
->Error( SbERR_SYNTAX
);
231 if( DoParametersFollow( pParser
, eCurExpr
, eTok
= eNextTok
) )
233 bool bStandaloneExpression
= (m_eMode
== EXPRMODE_STANDALONE
);
234 pPar
= new SbiParameters( pParser
, bStandaloneExpression
);
235 bError
= bError
|| !pPar
->IsValid();
237 bBracket
= pPar
->IsBracket();
238 eTok
= pParser
->Peek();
240 // i75443 check for additional sets of parameters
241 while( eTok
== LPAREN
)
243 if( pvMoreParLcl
== NULL
)
245 pvMoreParLcl
= new SbiExprListVector();
247 SbiParameters
* pAddPar
= new SbiParameters( pParser
);
248 pvMoreParLcl
->push_back( pAddPar
);
249 bError
= bError
|| !pAddPar
->IsValid();
250 eTok
= pParser
->Peek();
253 // It might be an object part, if . or ! is following.
254 // In case of . the variable must already be defined;
255 // it's an object, if pDef is NULL after the search.
256 bool bObj
= ( ( eTok
== DOT
|| eTok
== EXCLAM
)
257 && !pParser
->WhiteSpace() );
260 bBracket
= false; // Now the bracket for the first term is obsolete
261 if( eType
== SbxVARIANT
)
267 // Name%. really does not work!
268 pParser
->Error( SbERR_BAD_DECLARATION
, aSym
);
273 SbiSymDef
* pDef
= pParser
->pPool
->Find( aSym
);
276 // Part of the Runtime-Library?
277 // from 31.3.1996: swapped out to parser-method
278 // (is also needed in SbiParser::DefVar() in DIM.CXX)
279 pDef
= pParser
->CheckRTLForSym( aSym
, eType
);
281 // #i109184: Check if symbol is or later will be defined inside module
282 SbModule
& rMod
= pParser
->aGen
.GetModule();
283 SbxArray
* pModMethods
= rMod
.GetMethods();
284 if( pModMethods
->Find( aSym
, SbxCLASS_DONTCARE
) )
295 pDef
= AddSym( eTok
, *pParser
->pPool
, eCurExpr
, aSym
, eType
, pPar
);
296 // Looks like this is a local ( but undefined variable )
297 // if it is in a static procedure then make this Symbol
299 if ( !bObj
&& pParser
->pProc
&& pParser
->pProc
->IsStatic() )
307 SbiConstDef
* pConst
= pDef
->GetConstDef();
312 if( pConst
->GetType() == SbxSTRING
)
314 return new SbiExprNode( pParser
, pConst
->GetString() );
318 return new SbiExprNode( pParser
, pConst
->GetValue(), pConst
->GetType() );
322 // 0 parameters come up to ()
323 if( pDef
->GetDims() )
325 if( pPar
&& pPar
->GetSize() && pPar
->GetSize() != pDef
->GetDims() )
327 pParser
->Error( SbERR_WRONG_DIMS
);
330 if( pDef
->IsDefinedAs() )
332 SbxDataType eDefType
= pDef
->GetType();
333 // #119187 Only error if types conflict
334 if( eType
>= SbxINTEGER
&& eType
<= SbxSTRING
&& eType
!= eDefType
)
336 // How? Define with AS first and take a Suffix then?
337 pParser
->Error( SbERR_BAD_DECLARATION
, aSym
);
340 else if ( eType
== SbxVARIANT
)
342 // if there's nothing named, take the type of the entry,
343 // but only if the var hasn't been defined with AS XXX
344 // so that we catch n% = 5 : print n
348 // checking type of variables:
349 // is there named anything different in the scanner?
350 // That's OK for methods!
351 if( eType
!= SbxVARIANT
&& // Variant takes everything
352 eType
!= pDef
->GetType() &&
353 !pDef
->GetProcDef() )
355 // maybe pDef describes an object that so far has only been
356 // recognized as SbxVARIANT - then change type of pDef
357 // from 16.12.95 (similar cases possible perhaps?!?)
358 if( eType
== SbxOBJECT
&& pDef
->GetType() == SbxVARIANT
)
360 pDef
->SetType( SbxOBJECT
);
364 pParser
->Error( SbERR_BAD_DECLARATION
, aSym
);
369 SbiExprNode
* pNd
= new SbiExprNode( pParser
, *pDef
, eType
);
372 pPar
= new SbiParameters( pParser
,false,false );
374 pNd
->aVar
.pPar
= pPar
;
375 pNd
->aVar
.pvMorePar
= pvMoreParLcl
;
378 // from 8.1.95: Object may also be of the type SbxVARIANT
379 if( pDef
->GetType() == SbxVARIANT
)
380 pDef
->SetType( SbxOBJECT
);
381 // if we scan something with point,
382 // the type must be SbxOBJECT
383 if( pDef
->GetType() != SbxOBJECT
&& pDef
->GetType() != SbxVARIANT
)
385 // defer error until runtime if in vba mode
386 if ( !pParser
->IsVBASupportOn() )
388 pParser
->Error( SbERR_BAD_DECLARATION
, aSym
);
394 pNd
->aVar
.pNext
= ObjTerm( *pDef
);
398 pParser
->UnlockColumn();
402 // construction of an object term. A term of this kind is part
403 // of an expression that begins with an object variable.
405 SbiExprNode
* SbiExpression::ObjTerm( SbiSymDef
& rObj
)
408 SbiToken eTok
= pParser
->Next();
409 if( eTok
!= SYMBOL
&& !SbiTokenizer::IsKwd( eTok
) && !SbiTokenizer::IsExtra( eTok
) )
411 // #66745 Some operators can also be allowed
412 // as identifiers, important for StarOne
413 if( eTok
!= MOD
&& eTok
!= NOT
&& eTok
!= AND
&& eTok
!= OR
&&
414 eTok
!= XOR
&& eTok
!= EQV
&& eTok
!= IMP
&& eTok
!= IS
)
416 pParser
->Error( SbERR_VAR_EXPECTED
);
425 OUString
aSym( pParser
->GetSym() );
426 SbxDataType eType
= pParser
->GetType();
427 SbiParameters
* pPar
= NULL
;
428 SbiExprListVector
* pvMoreParLcl
= NULL
;
429 eTok
= pParser
->Peek();
431 if( DoParametersFollow( pParser
, eCurExpr
, eTok
) )
433 bool bStandaloneExpression
= false;
434 pPar
= new SbiParameters( pParser
, bStandaloneExpression
);
435 bError
= bError
|| !pPar
->IsValid();
436 eTok
= pParser
->Peek();
438 // i109624 check for additional sets of parameters
439 while( eTok
== LPAREN
)
441 if( pvMoreParLcl
== NULL
)
443 pvMoreParLcl
= new SbiExprListVector();
445 SbiParameters
* pAddPar
= new SbiParameters( pParser
);
446 pvMoreParLcl
->push_back( pAddPar
);
447 bError
= bError
|| !pPar
->IsValid();
448 eTok
= pParser
->Peek();
451 bool bObj
= ( ( eTok
== DOT
|| eTok
== EXCLAM
) && !pParser
->WhiteSpace() );
454 if( eType
== SbxVARIANT
)
460 // Name%. does really not work!
461 pParser
->Error( SbERR_BAD_DECLARATION
, aSym
);
466 // an object's symbol pool is always PUBLIC
467 SbiSymPool
& rPool
= rObj
.GetPool();
468 rPool
.SetScope( SbPUBLIC
);
469 SbiSymDef
* pDef
= rPool
.Find( aSym
);
472 pDef
= AddSym( eTok
, rPool
, eCurExpr
, aSym
, eType
, pPar
);
473 pDef
->SetType( eType
);
476 SbiExprNode
* pNd
= new SbiExprNode( pParser
, *pDef
, eType
);
477 pNd
->aVar
.pPar
= pPar
;
478 pNd
->aVar
.pvMorePar
= pvMoreParLcl
;
481 if( pDef
->GetType() == SbxVARIANT
)
483 pDef
->SetType( SbxOBJECT
);
485 if( pDef
->GetType() != SbxOBJECT
)
487 pParser
->Error( SbERR_BAD_DECLARATION
, aSym
);
492 pNd
->aVar
.pNext
= ObjTerm( *pDef
);
499 // an operand can be:
502 // structure elements
505 // bracketed expressions
507 SbiExprNode
* SbiExpression::Operand( bool bUsedForTypeOf
)
513 switch( eTok
= pParser
->Peek() )
517 // process something like "IF Not r Is Nothing Then .."
518 if( !bUsedForTypeOf
&& pParser
->IsVBASupportOn() && pParser
->Peek() == IS
)
520 eTok
= pParser
->Next();
521 pRes
= new SbiExprNode( pParser
, pRes
, eTok
, Like() );
525 pRes
= Term(); break;
528 pRes
= new SbiExprNode( pParser
, pParser
->GetDbl(), pParser
->GetType() );
532 pRes
= new SbiExprNode( pParser
, pParser
->GetSym() ); break;
535 if( nParenLevel
== 0 && m_eMode
== EXPRMODE_LPAREN_PENDING
&& pParser
->Peek() == RPAREN
)
537 m_eMode
= EXPRMODE_EMPTY_PAREN
;
538 pRes
= new SbiExprNode(); // Dummy node
544 if( pParser
->Peek() != RPAREN
)
546 // If there was a LPARAM, it does not belong to the expression
547 if( nParenLevel
== 1 && m_eMode
== EXPRMODE_LPAREN_PENDING
)
549 m_eMode
= EXPRMODE_LPAREN_NOT_NEEDED
;
553 pParser
->Error( SbERR_BAD_BRACKETS
);
559 if( nParenLevel
== 1 && m_eMode
== EXPRMODE_LPAREN_PENDING
)
561 SbiToken eTokAfterRParen
= pParser
->Peek();
562 if( eTokAfterRParen
== EQ
|| eTokAfterRParen
== LPAREN
|| eTokAfterRParen
== DOT
)
564 m_eMode
= EXPRMODE_ARRAY_OR_OBJECT
;
568 m_eMode
= EXPRMODE_STANDARD
;
575 // keywords here are OK at the moment!
576 if( SbiTokenizer::IsKwd( eTok
) )
583 pRes
= new SbiExprNode( pParser
, 1.0, SbxDOUBLE
);
584 pParser
->Error( SbERR_UNEXPECTED
, eTok
);
591 SbiExprNode
* SbiExpression::Unary()
594 SbiToken eTok
= pParser
->Peek();
600 pNd
= new SbiExprNode( pParser
, Unary(), eTok
, NULL
);
603 if( pParser
->IsVBASupportOn() )
610 pNd
= new SbiExprNode( pParser
, Unary(), eTok
, NULL
);
620 bool bUsedForTypeOf
= true;
621 SbiExprNode
* pObjNode
= Operand( bUsedForTypeOf
);
622 pParser
->TestToken( IS
);
624 SbiSymDef
* pTypeDef
= new SbiSymDef( aDummy
);
625 pParser
->TypeDecl( *pTypeDef
, true );
626 pNd
= new SbiExprNode( pParser
, pObjNode
, pTypeDef
->GetTypeId() );
633 SbiSymDef
* pTypeDef
= new SbiSymDef( aStr
);
634 pParser
->TypeDecl( *pTypeDef
, true );
635 pNd
= new SbiExprNode( pParser
, pTypeDef
->GetTypeId() );
644 SbiExprNode
* SbiExpression::Exp()
646 SbiExprNode
* pNd
= Unary();
647 if( m_eMode
!= EXPRMODE_EMPTY_PAREN
)
649 while( pParser
->Peek() == EXPON
)
651 SbiToken eTok
= pParser
->Next();
652 pNd
= new SbiExprNode( pParser
, pNd
, eTok
, Unary() );
658 SbiExprNode
* SbiExpression::MulDiv()
660 SbiExprNode
* pNd
= Exp();
661 if( m_eMode
!= EXPRMODE_EMPTY_PAREN
)
665 SbiToken eTok
= pParser
->Peek();
666 if( eTok
!= MUL
&& eTok
!= DIV
)
670 eTok
= pParser
->Next();
671 pNd
= new SbiExprNode( pParser
, pNd
, eTok
, Exp() );
677 SbiExprNode
* SbiExpression::IntDiv()
679 SbiExprNode
* pNd
= MulDiv();
680 if( m_eMode
!= EXPRMODE_EMPTY_PAREN
)
682 while( pParser
->Peek() == IDIV
)
684 SbiToken eTok
= pParser
->Next();
685 pNd
= new SbiExprNode( pParser
, pNd
, eTok
, MulDiv() );
691 SbiExprNode
* SbiExpression::Mod()
693 SbiExprNode
* pNd
= IntDiv();
694 if( m_eMode
!= EXPRMODE_EMPTY_PAREN
)
696 while( pParser
->Peek() == MOD
)
698 SbiToken eTok
= pParser
->Next();
699 pNd
= new SbiExprNode( pParser
, pNd
, eTok
, IntDiv() );
705 SbiExprNode
* SbiExpression::AddSub()
707 SbiExprNode
* pNd
= Mod();
708 if( m_eMode
!= EXPRMODE_EMPTY_PAREN
)
712 SbiToken eTok
= pParser
->Peek();
713 if( eTok
!= PLUS
&& eTok
!= MINUS
)
717 eTok
= pParser
->Next();
718 pNd
= new SbiExprNode( pParser
, pNd
, eTok
, Mod() );
724 SbiExprNode
* SbiExpression::Cat()
726 SbiExprNode
* pNd
= AddSub();
727 if( m_eMode
!= EXPRMODE_EMPTY_PAREN
)
731 SbiToken eTok
= pParser
->Peek();
736 eTok
= pParser
->Next();
737 pNd
= new SbiExprNode( pParser
, pNd
, eTok
, AddSub() );
743 SbiExprNode
* SbiExpression::Comp()
745 SbiExprNode
* pNd
= Cat();
746 if( m_eMode
!= EXPRMODE_EMPTY_PAREN
)
751 SbiToken eTok
= pParser
->Peek();
752 if( m_eMode
== EXPRMODE_ARRAY_OR_OBJECT
)
756 if( eTok
!= EQ
&& eTok
!= NE
&& eTok
!= LT
&&
757 eTok
!= GT
&& eTok
!= LE
&& eTok
!= GE
)
761 eTok
= pParser
->Next();
762 pNd
= new SbiExprNode( pParser
, pNd
, eTok
, Cat() );
770 SbiExprNode
* SbiExpression::VBA_Not()
772 SbiExprNode
* pNd
= NULL
;
774 SbiToken eTok
= pParser
->Peek();
778 pNd
= new SbiExprNode( pParser
, VBA_Not(), eTok
, NULL
);
787 SbiExprNode
* SbiExpression::Like()
789 SbiExprNode
* pNd
= pParser
->IsVBASupportOn() ? VBA_Not() : Comp();
790 if( m_eMode
!= EXPRMODE_EMPTY_PAREN
)
793 while( pParser
->Peek() == LIKE
)
795 SbiToken eTok
= pParser
->Next();
796 pNd
= new SbiExprNode( pParser
, pNd
, eTok
, Comp() ), nCount
++;
798 // multiple operands in a row does not work
799 if( nCount
> 1 && !pParser
->IsVBASupportOn() )
801 pParser
->Error( SbERR_SYNTAX
);
808 SbiExprNode
* SbiExpression::Boolean()
810 SbiExprNode
* pNd
= Like();
811 if( m_eMode
!= EXPRMODE_EMPTY_PAREN
)
815 SbiToken eTok
= pParser
->Peek();
816 if( (eTok
!= AND
) && (eTok
!= OR
) &&
817 (eTok
!= XOR
) && (eTok
!= EQV
) &&
818 (eTok
!= IMP
) && (eTok
!= IS
) )
822 eTok
= pParser
->Next();
823 pNd
= new SbiExprNode( pParser
, pNd
, eTok
, Like() );
829 /***************************************************************************
831 |* SbiConstExpression
833 ***************************************************************************/
835 SbiConstExpression::SbiConstExpression( SbiParser
* p
) : SbiExpression( p
)
837 if( pExpr
->IsConstant() )
839 eType
= pExpr
->GetType();
840 if( pExpr
->IsNumber() )
847 aVal
= pExpr
->aStrVal
;
852 // #40204 special treatment for sal_Bool-constants
853 bool bIsBool
= false;
854 if( pExpr
->eNodeType
== SbxVARVAL
)
856 SbiSymDef
* pVarDef
= pExpr
->GetVar();
858 bool bBoolVal
= false;
859 if( pVarDef
->GetName().equalsIgnoreAsciiCase( "true" ) )
864 else if( pVarDef
->GetName().equalsIgnoreAsciiCase( "false" ) )
865 //else if( pVarDef->GetName().ICompare( "false" ) == COMPARE_EQUAL )
874 pExpr
= new SbiExprNode( pParser
, (bBoolVal
? SbxTRUE
: SbxFALSE
), SbxINTEGER
);
875 eType
= pExpr
->GetType();
882 pParser
->Error( SbERR_SYNTAX
);
889 short SbiConstExpression::GetShortValue()
891 if( eType
== SbxSTRING
)
893 SbxVariableRef refConv
= new SbxVariable
;
894 refConv
->PutString( aVal
);
895 return refConv
->GetInteger();
911 pParser
->Error( SbERR_OUT_OF_RANGE
);
913 else if( n
< SbxMININT
)
916 pParser
->Error( SbERR_OUT_OF_RANGE
);
924 /***************************************************************************
928 ***************************************************************************/
930 SbiExprList::SbiExprList( SbiParser
* p
)
940 SbiExprList::~SbiExprList()
942 SbiExpression
* p
= pFirst
;
945 SbiExpression
* q
= p
->pNext
;
952 SbiExpression
* SbiExprList::Get( short n
)
954 SbiExpression
* p
= pFirst
;
962 void SbiExprList::addExpression( SbiExpression
* pExpr
)
970 SbiExpression
* p
= pFirst
;
979 /***************************************************************************
983 ***************************************************************************/
985 // parsing constructor:
986 // the parameter list is completely parsed
987 // "procedurename()" is OK
988 // it's a function without parameters then
989 // i. e. you give an array as procedure parameter
991 // #i79918/#i80532: bConst has never been set to true
992 // -> reused as bStandaloneExpression
993 //SbiParameters::SbiParameters( SbiParser* p, sal_Bool bConst, sal_Bool bPar) :
994 SbiParameters::SbiParameters( SbiParser
* p
, bool bStandaloneExpression
, bool bPar
) :
1001 SbiExpression
*pExpr
;
1002 SbiToken eTok
= pParser
->Peek();
1004 bool bAssumeExprLParenMode
= false;
1005 bool bAssumeArrayMode
= false;
1006 if( eTok
== LPAREN
)
1008 if( bStandaloneExpression
)
1010 bAssumeExprLParenMode
= true;
1016 eTok
= pParser
->Peek();
1021 if( ( bBracket
&& eTok
== RPAREN
) || SbiTokenizer::IsEoln( eTok
) )
1023 if( eTok
== RPAREN
)
1029 // read in parameter table and lay down in correct order!
1030 SbiExpression
* pLast
= NULL
;
1038 pExpr
= new SbiExpression( pParser
, 0, SbxEMPTY
);
1040 // named arguments: either .name= or name:=
1043 bool bByVal
= false;
1048 eTok
= pParser
->Peek();
1051 if( bAssumeExprLParenMode
)
1053 pExpr
= new SbiExpression( pParser
, SbSTDEXPR
, EXPRMODE_LPAREN_PENDING
);
1054 bAssumeExprLParenMode
= false;
1056 SbiExprMode eModeAfter
= pExpr
->m_eMode
;
1057 if( eModeAfter
== EXPRMODE_LPAREN_NOT_NEEDED
)
1061 else if( eModeAfter
== EXPRMODE_ARRAY_OR_OBJECT
)
1063 // Expression "looks" like an array assignment
1064 // a(...)[(...)] = ? or a(...).b(...)
1065 // RPAREN is already parsed
1067 bAssumeArrayMode
= true;
1070 else if( eModeAfter
== EXPRMODE_EMPTY_PAREN
)
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
) || SbiTokenizer::IsEoln( eTok
) )
1123 pParser
->Error( bBracket
? SbERR_BAD_BRACKETS
: SbERR_EXPECTED
, COMMA
);
1129 eTok
= pParser
->Peek();
1130 if( ( bBracket
&& eTok
== RPAREN
) || SbiTokenizer::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: */