xref: /trunk/main/basic/source/comp/parser.cxx (revision 0420d1a0e3c8970850b7ac50e40ab8b8310e3a44)
1e1f63238SAndrew Rist /**************************************************************
2cdf0e10cSrcweir  *
3e1f63238SAndrew Rist  * Licensed to the Apache Software Foundation (ASF) under one
4e1f63238SAndrew Rist  * or more contributor license agreements.  See the NOTICE file
5e1f63238SAndrew Rist  * distributed with this work for additional information
6e1f63238SAndrew Rist  * regarding copyright ownership.  The ASF licenses this file
7e1f63238SAndrew Rist  * to you under the Apache License, Version 2.0 (the
8e1f63238SAndrew Rist  * "License"); you may not use this file except in compliance
9e1f63238SAndrew Rist  * with the License.  You may obtain a copy of the License at
10cdf0e10cSrcweir  *
11e1f63238SAndrew Rist  *   http://www.apache.org/licenses/LICENSE-2.0
12cdf0e10cSrcweir  *
13e1f63238SAndrew Rist  * Unless required by applicable law or agreed to in writing,
14e1f63238SAndrew Rist  * software distributed under the License is distributed on an
15e1f63238SAndrew Rist  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16e1f63238SAndrew Rist  * KIND, either express or implied.  See the License for the
17e1f63238SAndrew Rist  * specific language governing permissions and limitations
18e1f63238SAndrew Rist  * under the License.
19cdf0e10cSrcweir  *
20e1f63238SAndrew Rist  *************************************************************/
21e1f63238SAndrew Rist 
22cdf0e10cSrcweir // MARKER(update_precomp.py): autogen include statement, do not remove
23cdf0e10cSrcweir #include "precompiled_basic.hxx"
24cdf0e10cSrcweir #include <basic/sbx.hxx>
25cdf0e10cSrcweir #include "sbcomp.hxx"
26cdf0e10cSrcweir #include <com/sun/star/script/ModuleType.hpp>
27cdf0e10cSrcweir 
28*0420d1a0Smseidel struct SbiParseStack {              // "Stack" für Statement-Blocks
29cdf0e10cSrcweir     SbiParseStack* pNext;           // Chain
30*0420d1a0Smseidel     SbiExprNode* pWithVar;          // Variable für WITH
31cdf0e10cSrcweir     SbiToken eExitTok;              // Exit-Token
32cdf0e10cSrcweir     sal_uInt32  nChain;                 // JUMP-Chain
33cdf0e10cSrcweir };
34cdf0e10cSrcweir 
35cdf0e10cSrcweir struct SbiStatement {
36cdf0e10cSrcweir     SbiToken eTok;
37cdf0e10cSrcweir     void( SbiParser::*Func )();     // Verarbeitungsroutine
38cdf0e10cSrcweir     sal_Bool  bMain;                    // sal_True: ausserhalb SUBs OK
39cdf0e10cSrcweir     sal_Bool  bSubr;                    // sal_True: in SUBs OK
40cdf0e10cSrcweir };
41cdf0e10cSrcweir 
42cdf0e10cSrcweir #define Y   sal_True
43cdf0e10cSrcweir #define N   sal_False
44cdf0e10cSrcweir 
45cdf0e10cSrcweir static SbiStatement StmntTable [] = {
46cdf0e10cSrcweir { CALL,     &SbiParser::Call,       N, Y, }, // CALL
47cdf0e10cSrcweir { CLOSE,    &SbiParser::Close,      N, Y, }, // CLOSE
48cdf0e10cSrcweir { _CONST_,  &SbiParser::Dim,        Y, Y, }, // CONST
49cdf0e10cSrcweir { DECLARE,  &SbiParser::Declare,    Y, N, }, // DECLARE
50cdf0e10cSrcweir { DEFBOOL,  &SbiParser::DefXXX,     Y, N, }, // DEFBOOL
51cdf0e10cSrcweir { DEFCUR,   &SbiParser::DefXXX,     Y, N, }, // DEFCUR
52cdf0e10cSrcweir { DEFDATE,  &SbiParser::DefXXX,     Y, N, }, // DEFDATE
53cdf0e10cSrcweir { DEFDBL,   &SbiParser::DefXXX,     Y, N, }, // DEFDBL
54cdf0e10cSrcweir { DEFERR,   &SbiParser::DefXXX,     Y, N, }, // DEFERR
55cdf0e10cSrcweir { DEFINT,   &SbiParser::DefXXX,     Y, N, }, // DEFINT
56cdf0e10cSrcweir { DEFLNG,   &SbiParser::DefXXX,     Y, N, }, // DEFLNG
57cdf0e10cSrcweir { DEFOBJ,   &SbiParser::DefXXX,     Y, N, }, // DEFOBJ
58cdf0e10cSrcweir { DEFSNG,   &SbiParser::DefXXX,     Y, N, }, // DEFSNG
59cdf0e10cSrcweir { DEFSTR,   &SbiParser::DefXXX,     Y, N, }, // DEFSTR
60cdf0e10cSrcweir { DEFVAR,   &SbiParser::DefXXX,     Y, N, }, // DEFVAR
61cdf0e10cSrcweir { DIM,      &SbiParser::Dim,        Y, Y, }, // DIM
62cdf0e10cSrcweir { DO,       &SbiParser::DoLoop,     N, Y, }, // DO
63cdf0e10cSrcweir { ELSE,     &SbiParser::NoIf,       N, Y, }, // ELSE
64cdf0e10cSrcweir { ELSEIF,   &SbiParser::NoIf,       N, Y, }, // ELSEIF
65cdf0e10cSrcweir { ENDIF,    &SbiParser::NoIf,       N, Y, }, // ENDIF
66cdf0e10cSrcweir { END,      &SbiParser::Stop,       N, Y, }, // END
67cdf0e10cSrcweir { ENUM,     &SbiParser::Enum,       Y, N, }, // TYPE
68cdf0e10cSrcweir { ERASE,    &SbiParser::Erase,      N, Y, }, // ERASE
69cdf0e10cSrcweir { _ERROR_,  &SbiParser::ErrorStmnt, N, Y, }, // ERROR
70cdf0e10cSrcweir { EXIT,     &SbiParser::Exit,       N, Y, }, // EXIT
71cdf0e10cSrcweir { FOR,      &SbiParser::For,        N, Y, }, // FOR
72cdf0e10cSrcweir { FUNCTION, &SbiParser::SubFunc,    Y, N, }, // FUNCTION
73cdf0e10cSrcweir { GOSUB,    &SbiParser::Goto,       N, Y, }, // GOSUB
74cdf0e10cSrcweir { GLOBAL,   &SbiParser::Dim,        Y, N, }, // GLOBAL
75cdf0e10cSrcweir { GOTO,     &SbiParser::Goto,       N, Y, }, // GOTO
76cdf0e10cSrcweir { IF,       &SbiParser::If,         N, Y, }, // IF
77cdf0e10cSrcweir { IMPLEMENTS, &SbiParser::Implements, Y, N, }, // IMPLEMENTS
78cdf0e10cSrcweir { INPUT,    &SbiParser::Input,      N, Y, }, // INPUT
79cdf0e10cSrcweir { LET,      &SbiParser::Assign,     N, Y, }, // LET
80cdf0e10cSrcweir { LINE,     &SbiParser::Line,       N, Y, }, // LINE, -> LINE INPUT (#i92642)
81cdf0e10cSrcweir { LINEINPUT,&SbiParser::LineInput,  N, Y, }, // LINE INPUT
82cdf0e10cSrcweir { LOOP,     &SbiParser::BadBlock,   N, Y, }, // LOOP
83cdf0e10cSrcweir { LSET,     &SbiParser::LSet,       N, Y, }, // LSET
84cdf0e10cSrcweir { NAME,     &SbiParser::Name,       N, Y, }, // NAME
85cdf0e10cSrcweir { NEXT,     &SbiParser::BadBlock,   N, Y, }, // NEXT
86cdf0e10cSrcweir { ON,       &SbiParser::On,         N, Y, }, // ON
87cdf0e10cSrcweir { OPEN,     &SbiParser::Open,       N, Y, }, // OPEN
88cdf0e10cSrcweir { OPTION,   &SbiParser::Option,     Y, N, }, // OPTION
89cdf0e10cSrcweir { PRINT,    &SbiParser::Print,      N, Y, }, // PRINT
90cdf0e10cSrcweir { PRIVATE,  &SbiParser::Dim,        Y, N, }, // PRIVATE
91cdf0e10cSrcweir { PROPERTY, &SbiParser::SubFunc,    Y, N, }, // FUNCTION
92cdf0e10cSrcweir { PUBLIC,   &SbiParser::Dim,        Y, N, }, // PUBLIC
93cdf0e10cSrcweir { REDIM,    &SbiParser::ReDim,      N, Y, }, // DIM
94cdf0e10cSrcweir { RESUME,   &SbiParser::Resume,     N, Y, }, // RESUME
95cdf0e10cSrcweir { RETURN,   &SbiParser::Return,     N, Y, }, // RETURN
96cdf0e10cSrcweir { RSET,     &SbiParser::RSet,       N, Y, }, // RSET
97cdf0e10cSrcweir { SELECT,   &SbiParser::Select,     N, Y, }, // SELECT
98cdf0e10cSrcweir { SET,      &SbiParser::Set,        N, Y, }, // SET
99cdf0e10cSrcweir { STATIC,   &SbiParser::Static,     Y, Y, }, // STATIC
100cdf0e10cSrcweir { STOP,     &SbiParser::Stop,       N, Y, }, // STOP
101cdf0e10cSrcweir { SUB,      &SbiParser::SubFunc,    Y, N, }, // SUB
102cdf0e10cSrcweir { TYPE,     &SbiParser::Type,       Y, N, }, // TYPE
103cdf0e10cSrcweir { UNTIL,    &SbiParser::BadBlock,   N, Y, }, // UNTIL
104cdf0e10cSrcweir { WHILE,    &SbiParser::While,      N, Y, }, // WHILE
105cdf0e10cSrcweir { WEND,     &SbiParser::BadBlock,   N, Y, }, // WEND
106cdf0e10cSrcweir { WITH,     &SbiParser::With,       N, Y, }, // WITH
107cdf0e10cSrcweir { WRITE,    &SbiParser::Write,      N, Y, }, // WRITE
108cdf0e10cSrcweir 
109cdf0e10cSrcweir { NIL, NULL, N, N }
110cdf0e10cSrcweir };
111cdf0e10cSrcweir 
112cdf0e10cSrcweir 
113cdf0e10cSrcweir #ifdef _MSC_VER
114cdf0e10cSrcweir // 'this' : used in base member initializer list
115cdf0e10cSrcweir #pragma warning( disable: 4355 )
116cdf0e10cSrcweir #endif
117cdf0e10cSrcweir 
SbiParser(StarBASIC * pb,SbModule * pm)118cdf0e10cSrcweir SbiParser::SbiParser( StarBASIC* pb, SbModule* pm )
119cdf0e10cSrcweir         : SbiTokenizer( pm->GetSource32(), pb ),
120cdf0e10cSrcweir           aGblStrings( this ),
121cdf0e10cSrcweir           aLclStrings( this ),
122cdf0e10cSrcweir           aGlobals( aGblStrings, SbGLOBAL ),
123cdf0e10cSrcweir           aPublics( aGblStrings, SbPUBLIC ),
124cdf0e10cSrcweir           aRtlSyms( aGblStrings, SbRTL ),
125cdf0e10cSrcweir           aGen( *pm, this, 1024 )
126cdf0e10cSrcweir {
127cdf0e10cSrcweir     pBasic   = pb;
128cdf0e10cSrcweir     eCurExpr = SbSYMBOL;
129cdf0e10cSrcweir     eEndTok  = NIL;
130cdf0e10cSrcweir     pProc    = NULL;
131cdf0e10cSrcweir     pStack   = NULL;
132cdf0e10cSrcweir     pWithVar = NULL;
133cdf0e10cSrcweir     nBase    = 0;
134cdf0e10cSrcweir     bText    =
135cdf0e10cSrcweir     bGblDefs =
136cdf0e10cSrcweir     bNewGblDefs =
137cdf0e10cSrcweir     bSingleLineIf =
138cdf0e10cSrcweir     bExplicit = sal_False;
139cdf0e10cSrcweir     bClassModule = ( pm->GetModuleType() == com::sun::star::script::ModuleType::CLASS );
140cdf0e10cSrcweir     OSL_TRACE("Parser - %s, bClassModule %d", rtl::OUStringToOString( pm->GetName(), RTL_TEXTENCODING_UTF8 ).getStr(), bClassModule );
141cdf0e10cSrcweir     pPool    = &aPublics;
142cdf0e10cSrcweir     for( short i = 0; i < 26; i++ )
143cdf0e10cSrcweir         eDefTypes[ i ] = SbxVARIANT; // Kein expliziter Defaulttyp
144cdf0e10cSrcweir 
145cdf0e10cSrcweir     aPublics.SetParent( &aGlobals );
146cdf0e10cSrcweir     aGlobals.SetParent( &aRtlSyms );
147cdf0e10cSrcweir 
148cdf0e10cSrcweir     // Die globale Chainkette faengt bei Adresse 0 an:
149cdf0e10cSrcweir     nGblChain = aGen.Gen( _JUMP, 0 );
150cdf0e10cSrcweir 
151cdf0e10cSrcweir     rTypeArray = new SbxArray; // Array fuer Benutzerdefinierte Typen
152cdf0e10cSrcweir     rEnumArray = new SbxArray; // Array for Enum types
153cdf0e10cSrcweir     bVBASupportOn = pm->IsVBACompat();
154cdf0e10cSrcweir     if ( bVBASupportOn )
155cdf0e10cSrcweir         EnableCompatibility();
156cdf0e10cSrcweir 
157cdf0e10cSrcweir }
158cdf0e10cSrcweir 
159cdf0e10cSrcweir 
160cdf0e10cSrcweir // Ist Teil der Runtime-Library?
CheckRTLForSym(const String & rSym,SbxDataType eType)161cdf0e10cSrcweir SbiSymDef* SbiParser::CheckRTLForSym( const String& rSym, SbxDataType eType )
162cdf0e10cSrcweir {
163cdf0e10cSrcweir     SbxVariable* pVar = GetBasic()->GetRtl()->Find( rSym, SbxCLASS_DONTCARE );
164cdf0e10cSrcweir     SbiSymDef* pDef = NULL;
165cdf0e10cSrcweir     if( pVar )
166cdf0e10cSrcweir     {
167cdf0e10cSrcweir         if( pVar->IsA( TYPE(SbxMethod) ) )
168cdf0e10cSrcweir         {
169cdf0e10cSrcweir             SbiProcDef* pProc_ = aRtlSyms.AddProc( rSym );
17022a7caf0STsutomu Uchino             SbxMethod* pMethod = (SbxMethod*) pVar;
17122a7caf0STsutomu Uchino             if ( pMethod && pMethod->IsRuntimeFunction() )
17222a7caf0STsutomu Uchino             {
17322a7caf0STsutomu Uchino                 pProc_->SetType( pMethod->GetRuntimeFunctionReturnType() );
17422a7caf0STsutomu Uchino             }
17522a7caf0STsutomu Uchino             else
17622a7caf0STsutomu Uchino             {
177cdf0e10cSrcweir                 pProc_->SetType( pVar->GetType() );
17822a7caf0STsutomu Uchino             }
179cdf0e10cSrcweir             pDef = pProc_;
180cdf0e10cSrcweir         }
181cdf0e10cSrcweir         else
182cdf0e10cSrcweir         {
183cdf0e10cSrcweir             pDef = aRtlSyms.AddSym( rSym );
184cdf0e10cSrcweir             pDef->SetType( eType );
185cdf0e10cSrcweir         }
186cdf0e10cSrcweir     }
187cdf0e10cSrcweir     return pDef;
188cdf0e10cSrcweir }
189cdf0e10cSrcweir 
190cdf0e10cSrcweir // Globale Chainkette schliessen
191cdf0e10cSrcweir 
HasGlobalCode()192cdf0e10cSrcweir sal_Bool SbiParser::HasGlobalCode()
193cdf0e10cSrcweir {
194cdf0e10cSrcweir     if( bGblDefs && nGblChain )
195cdf0e10cSrcweir     {
196cdf0e10cSrcweir         aGen.BackChain( nGblChain );
197cdf0e10cSrcweir         aGen.Gen( _LEAVE );
198cdf0e10cSrcweir         // aGen.Gen( _STOP );
199cdf0e10cSrcweir         nGblChain = 0;
200cdf0e10cSrcweir     }
201cdf0e10cSrcweir     return bGblDefs;
202cdf0e10cSrcweir }
203cdf0e10cSrcweir 
OpenBlock(SbiToken eTok,SbiExprNode * pVar)204cdf0e10cSrcweir void SbiParser::OpenBlock( SbiToken eTok, SbiExprNode* pVar )
205cdf0e10cSrcweir {
206cdf0e10cSrcweir     SbiParseStack* p = new SbiParseStack;
207cdf0e10cSrcweir     p->eExitTok = eTok;
208cdf0e10cSrcweir     p->nChain   = 0;
209cdf0e10cSrcweir     p->pWithVar = pWithVar;
210cdf0e10cSrcweir     p->pNext    = pStack;
211cdf0e10cSrcweir     pStack      = p;
212cdf0e10cSrcweir     pWithVar    = pVar;
213cdf0e10cSrcweir 
214cdf0e10cSrcweir     // #29955 for-Schleifen-Ebene pflegen
215cdf0e10cSrcweir     if( eTok == FOR )
216cdf0e10cSrcweir         aGen.IncForLevel();
217cdf0e10cSrcweir }
218cdf0e10cSrcweir 
CloseBlock()219cdf0e10cSrcweir void SbiParser::CloseBlock()
220cdf0e10cSrcweir {
221cdf0e10cSrcweir     if( pStack )
222cdf0e10cSrcweir     {
223cdf0e10cSrcweir         SbiParseStack* p = pStack;
224cdf0e10cSrcweir 
225cdf0e10cSrcweir         // #29955 for-Schleifen-Ebene pflegen
226cdf0e10cSrcweir         if( p->eExitTok == FOR )
227cdf0e10cSrcweir             aGen.DecForLevel();
228cdf0e10cSrcweir 
229cdf0e10cSrcweir         aGen.BackChain( p->nChain );
230cdf0e10cSrcweir         pStack = p->pNext;
231cdf0e10cSrcweir         pWithVar = p->pWithVar;
232cdf0e10cSrcweir         delete p;
233cdf0e10cSrcweir     }
234cdf0e10cSrcweir }
235cdf0e10cSrcweir 
236cdf0e10cSrcweir // EXIT ...
237cdf0e10cSrcweir 
Exit()238cdf0e10cSrcweir void SbiParser::Exit()
239cdf0e10cSrcweir {
240cdf0e10cSrcweir     SbiToken eTok = Next();
241cdf0e10cSrcweir     for( SbiParseStack* p = pStack; p; p = p->pNext )
242cdf0e10cSrcweir     {
243cdf0e10cSrcweir         SbiToken eExitTok = p->eExitTok;
244cdf0e10cSrcweir         if( eTok == eExitTok ||
245cdf0e10cSrcweir             (eTok == PROPERTY && (eExitTok == GET || eExitTok == LET) ) )   // #i109051
246cdf0e10cSrcweir         {
247cdf0e10cSrcweir             p->nChain = aGen.Gen( _JUMP, p->nChain );
248cdf0e10cSrcweir             return;
249cdf0e10cSrcweir         }
250cdf0e10cSrcweir     }
251cdf0e10cSrcweir     if( pStack )
252cdf0e10cSrcweir         Error( SbERR_EXPECTED, pStack->eExitTok );
253cdf0e10cSrcweir     else
254cdf0e10cSrcweir         Error( SbERR_BAD_EXIT );
255cdf0e10cSrcweir }
256cdf0e10cSrcweir 
TestSymbol(sal_Bool bKwdOk)257cdf0e10cSrcweir sal_Bool SbiParser::TestSymbol( sal_Bool bKwdOk )
258cdf0e10cSrcweir {
259cdf0e10cSrcweir     Peek();
260cdf0e10cSrcweir     if( eCurTok == SYMBOL || ( bKwdOk && IsKwd( eCurTok ) ) )
261cdf0e10cSrcweir     {
262cdf0e10cSrcweir         Next(); return sal_True;
263cdf0e10cSrcweir     }
264cdf0e10cSrcweir     Error( SbERR_SYMBOL_EXPECTED );
265cdf0e10cSrcweir     return sal_False;
266cdf0e10cSrcweir }
267cdf0e10cSrcweir 
268cdf0e10cSrcweir // Testen auf ein bestimmtes Token
269cdf0e10cSrcweir 
TestToken(SbiToken t)270cdf0e10cSrcweir sal_Bool SbiParser::TestToken( SbiToken t )
271cdf0e10cSrcweir {
272cdf0e10cSrcweir     if( Peek() == t )
273cdf0e10cSrcweir     {
274cdf0e10cSrcweir         Next(); return sal_True;
275cdf0e10cSrcweir     }
276cdf0e10cSrcweir     else
277cdf0e10cSrcweir     {
278cdf0e10cSrcweir         Error( SbERR_EXPECTED, t );
279cdf0e10cSrcweir         return sal_False;
280cdf0e10cSrcweir     }
281cdf0e10cSrcweir }
282cdf0e10cSrcweir 
283cdf0e10cSrcweir // Testen auf Komma oder EOLN
284cdf0e10cSrcweir 
TestComma()285cdf0e10cSrcweir sal_Bool SbiParser::TestComma()
286cdf0e10cSrcweir {
287cdf0e10cSrcweir     SbiToken eTok = Peek();
288cdf0e10cSrcweir     if( IsEoln( eTok ) )
289cdf0e10cSrcweir     {
290cdf0e10cSrcweir         Next();
291cdf0e10cSrcweir         return sal_False;
292cdf0e10cSrcweir     }
293cdf0e10cSrcweir     else if( eTok != COMMA )
294cdf0e10cSrcweir     {
295cdf0e10cSrcweir         Error( SbERR_EXPECTED, COMMA );
296cdf0e10cSrcweir         return sal_False;
297cdf0e10cSrcweir     }
298cdf0e10cSrcweir     Next();
299cdf0e10cSrcweir     return sal_True;
300cdf0e10cSrcweir }
301cdf0e10cSrcweir 
302cdf0e10cSrcweir // Testen, ob EOLN vorliegt
303cdf0e10cSrcweir 
TestEoln()304cdf0e10cSrcweir void SbiParser::TestEoln()
305cdf0e10cSrcweir {
306cdf0e10cSrcweir     if( !IsEoln( Next() ) )
307cdf0e10cSrcweir     {
308cdf0e10cSrcweir         Error( SbERR_EXPECTED, EOLN );
309cdf0e10cSrcweir         while( !IsEoln( Next() ) ) {}
310cdf0e10cSrcweir     }
311cdf0e10cSrcweir }
312cdf0e10cSrcweir 
313cdf0e10cSrcweir // Parsing eines Statement-Blocks
314*0420d1a0Smseidel // Das Parsing läuft bis zum Ende-Token.
315cdf0e10cSrcweir 
StmntBlock(SbiToken eEnd)316cdf0e10cSrcweir void SbiParser::StmntBlock( SbiToken eEnd )
317cdf0e10cSrcweir {
318cdf0e10cSrcweir     SbiToken xe = eEndTok;
319cdf0e10cSrcweir     eEndTok = eEnd;
320cdf0e10cSrcweir     while( !bAbort && Parse() ) {}
321cdf0e10cSrcweir     eEndTok = xe;
322cdf0e10cSrcweir     if( IsEof() )
323cdf0e10cSrcweir     {
324cdf0e10cSrcweir         Error( SbERR_BAD_BLOCK, eEnd );
325cdf0e10cSrcweir         bAbort = sal_True;
326cdf0e10cSrcweir     }
327cdf0e10cSrcweir }
328cdf0e10cSrcweir 
329cdf0e10cSrcweir // Die Hauptroutine. Durch wiederholten Aufrufs dieser Routine wird
330cdf0e10cSrcweir // die Quelle geparst. Returnwert sal_False bei Ende/Fehlern.
331cdf0e10cSrcweir 
Parse()332cdf0e10cSrcweir sal_Bool SbiParser::Parse()
333cdf0e10cSrcweir {
334cdf0e10cSrcweir     if( bAbort ) return sal_False;
335cdf0e10cSrcweir 
336cdf0e10cSrcweir     EnableErrors();
337cdf0e10cSrcweir 
338cdf0e10cSrcweir     bErrorIsSymbol = false;
339cdf0e10cSrcweir     Peek();
340cdf0e10cSrcweir     bErrorIsSymbol = true;
341cdf0e10cSrcweir     // Dateiende?
342cdf0e10cSrcweir     if( IsEof() )
343cdf0e10cSrcweir     {
344cdf0e10cSrcweir         // AB #33133: Falls keine Sub angelegt wurde, muss hier
345cdf0e10cSrcweir         // der globale Chain abgeschlossen werden!
346cdf0e10cSrcweir         // AB #40689: Durch die neue static-Behandlung kann noch
347cdf0e10cSrcweir         // ein nGblChain vorhanden sein, daher vorher abfragen
348cdf0e10cSrcweir         if( bNewGblDefs && nGblChain == 0 )
349cdf0e10cSrcweir             nGblChain = aGen.Gen( _JUMP, 0 );
350cdf0e10cSrcweir         return sal_False;
351cdf0e10cSrcweir     }
352cdf0e10cSrcweir 
353cdf0e10cSrcweir     // Leerstatement?
354cdf0e10cSrcweir     if( IsEoln( eCurTok ) )
355cdf0e10cSrcweir     {
356cdf0e10cSrcweir         Next(); return sal_True;
357cdf0e10cSrcweir     }
358cdf0e10cSrcweir 
359cdf0e10cSrcweir     if( !bSingleLineIf && MayBeLabel( sal_True ) )
360cdf0e10cSrcweir     {
361cdf0e10cSrcweir         // Ist ein Label
362cdf0e10cSrcweir         if( !pProc )
363cdf0e10cSrcweir             Error( SbERR_NOT_IN_MAIN, aSym );
364cdf0e10cSrcweir         else
365cdf0e10cSrcweir             pProc->GetLabels().Define( aSym );
366cdf0e10cSrcweir         Next(); Peek();
367cdf0e10cSrcweir         // Leerstatement?
368cdf0e10cSrcweir         if( IsEoln( eCurTok ) )
369cdf0e10cSrcweir         {
370cdf0e10cSrcweir             Next(); return sal_True;
371cdf0e10cSrcweir         }
372cdf0e10cSrcweir     }
373cdf0e10cSrcweir 
374cdf0e10cSrcweir     // Ende des Parsings?
375cdf0e10cSrcweir     if( eCurTok == eEndTok ||
376cdf0e10cSrcweir         ( bVBASupportOn &&      // #i109075
377cdf0e10cSrcweir           (eCurTok == ENDFUNC || eCurTok == ENDPROPERTY || eCurTok == ENDSUB) &&
378cdf0e10cSrcweir           (eEndTok == ENDFUNC || eEndTok == ENDPROPERTY || eEndTok == ENDSUB) ) )
379cdf0e10cSrcweir     {
380cdf0e10cSrcweir         Next();
381cdf0e10cSrcweir         if( eCurTok != NIL )
382cdf0e10cSrcweir             aGen.Statement();
383cdf0e10cSrcweir         return sal_False;
384cdf0e10cSrcweir     }
385cdf0e10cSrcweir 
386cdf0e10cSrcweir     // Kommentar?
387cdf0e10cSrcweir     if( eCurTok == REM )
388cdf0e10cSrcweir     {
389cdf0e10cSrcweir         Next(); return sal_True;
390cdf0e10cSrcweir     }
391cdf0e10cSrcweir 
392cdf0e10cSrcweir     // Kommt ein Symbol, ist es entweder eine Variable( LET )
393cdf0e10cSrcweir     // oder eine SUB-Prozedur( CALL ohne Klammern )
394*0420d1a0Smseidel     // DOT für Zuweisungen im WITH-Block: .A=5
395cdf0e10cSrcweir     if( eCurTok == SYMBOL || eCurTok == DOT )
396cdf0e10cSrcweir     {
397cdf0e10cSrcweir         if( !pProc )
398cdf0e10cSrcweir             Error( SbERR_EXPECTED, SUB );
399cdf0e10cSrcweir         else
400cdf0e10cSrcweir         {
401cdf0e10cSrcweir             // Damit Zeile & Spalte stimmen...
402cdf0e10cSrcweir             Next();
403cdf0e10cSrcweir             Push( eCurTok );
404cdf0e10cSrcweir             aGen.Statement();
405cdf0e10cSrcweir                 Symbol();
406cdf0e10cSrcweir         }
407cdf0e10cSrcweir     }
408cdf0e10cSrcweir     else
409cdf0e10cSrcweir     {
410cdf0e10cSrcweir         Next();
411cdf0e10cSrcweir 
412cdf0e10cSrcweir         // Hier folgen nun die Statement-Parser.
413cdf0e10cSrcweir 
414cdf0e10cSrcweir         SbiStatement* p;
415cdf0e10cSrcweir         for( p = StmntTable; p->eTok != NIL; p++ )
416cdf0e10cSrcweir             if( p->eTok == eCurTok )
417cdf0e10cSrcweir                 break;
418cdf0e10cSrcweir         if( p->eTok != NIL )
419cdf0e10cSrcweir         {
420cdf0e10cSrcweir             if( !pProc && !p->bMain )
421cdf0e10cSrcweir                 Error( SbERR_NOT_IN_MAIN, eCurTok );
422cdf0e10cSrcweir             else if( pProc && !p->bSubr )
423cdf0e10cSrcweir                 Error( SbERR_NOT_IN_SUBR, eCurTok );
424cdf0e10cSrcweir             else
425cdf0e10cSrcweir             {
426cdf0e10cSrcweir                 // globalen Chain pflegen
427cdf0e10cSrcweir                 // AB #41606/#40689: Durch die neue static-Behandlung kann noch
428cdf0e10cSrcweir                 // ein nGblChain vorhanden sein, daher vorher abfragen
429cdf0e10cSrcweir                 if( bNewGblDefs && nGblChain == 0 &&
430cdf0e10cSrcweir                     ( eCurTok == SUB || eCurTok == FUNCTION || eCurTok == PROPERTY ) )
431cdf0e10cSrcweir                 {
432cdf0e10cSrcweir                     nGblChain = aGen.Gen( _JUMP, 0 );
433cdf0e10cSrcweir                     bNewGblDefs = sal_False;
434cdf0e10cSrcweir                 }
435cdf0e10cSrcweir                 // Statement-Opcode bitte auch am Anfang einer Sub
436cdf0e10cSrcweir                 if( ( p->bSubr && (eCurTok != STATIC || Peek() == SUB || Peek() == FUNCTION ) ) ||
437cdf0e10cSrcweir                         eCurTok == SUB || eCurTok == FUNCTION )
438cdf0e10cSrcweir                     aGen.Statement();
439cdf0e10cSrcweir                 (this->*( p->Func ) )();
440cdf0e10cSrcweir                 SbxError nSbxErr = SbxBase::GetError();
441cdf0e10cSrcweir                 if( nSbxErr )
442cdf0e10cSrcweir                     SbxBase::ResetError(), Error( (SbError)nSbxErr );
443cdf0e10cSrcweir             }
444cdf0e10cSrcweir         }
445cdf0e10cSrcweir         else
446cdf0e10cSrcweir             Error( SbERR_UNEXPECTED, eCurTok );
447cdf0e10cSrcweir     }
448cdf0e10cSrcweir 
449cdf0e10cSrcweir     // Test auf Ende des Statements:
450cdf0e10cSrcweir     // Kann auch ein ELSE sein, da vor dem ELSE kein : stehen muss!
451cdf0e10cSrcweir 
452cdf0e10cSrcweir     if( !IsEos() )
453cdf0e10cSrcweir     {
454cdf0e10cSrcweir         Peek();
455cdf0e10cSrcweir         if( !IsEos() && eCurTok != ELSE )
456cdf0e10cSrcweir         {
457cdf0e10cSrcweir             // falls das Parsing abgebrochen wurde, bis zum ":" vorgehen:
458cdf0e10cSrcweir             Error( SbERR_UNEXPECTED, eCurTok );
459cdf0e10cSrcweir             while( !IsEos() ) Next();
460cdf0e10cSrcweir         }
461cdf0e10cSrcweir     }
462*0420d1a0Smseidel     // Der Parser bricht am Ende ab, das nächste Token ist noch nicht
463cdf0e10cSrcweir     // geholt!
464cdf0e10cSrcweir     return sal_True;
465cdf0e10cSrcweir }
466cdf0e10cSrcweir 
467cdf0e10cSrcweir // Innerste With-Variable liefern
GetWithVar()468cdf0e10cSrcweir SbiExprNode* SbiParser::GetWithVar()
469cdf0e10cSrcweir {
470cdf0e10cSrcweir     if( pWithVar )
471cdf0e10cSrcweir         return pWithVar;
472cdf0e10cSrcweir 
473cdf0e10cSrcweir     // Sonst im Stack suchen
474cdf0e10cSrcweir     SbiParseStack* p = pStack;
475cdf0e10cSrcweir     while( p )
476cdf0e10cSrcweir     {
477*0420d1a0Smseidel         // LoopVar kann zur Zeit nur für with sein
478cdf0e10cSrcweir         if( p->pWithVar )
479cdf0e10cSrcweir             return p->pWithVar;
480cdf0e10cSrcweir         p = p->pNext;
481cdf0e10cSrcweir     }
482cdf0e10cSrcweir     return NULL;
483cdf0e10cSrcweir }
484cdf0e10cSrcweir 
485cdf0e10cSrcweir 
486cdf0e10cSrcweir // Zuweisung oder Subroutine Call
487cdf0e10cSrcweir 
Symbol(const KeywordSymbolInfo * pKeywordSymbolInfo)488cdf0e10cSrcweir void SbiParser::Symbol( const KeywordSymbolInfo* pKeywordSymbolInfo )
489cdf0e10cSrcweir {
490cdf0e10cSrcweir     SbiExprMode eMode = bVBASupportOn ? EXPRMODE_STANDALONE : EXPRMODE_STANDARD;
491cdf0e10cSrcweir     SbiExpression aVar( this, SbSYMBOL, eMode, pKeywordSymbolInfo );
492cdf0e10cSrcweir 
493cdf0e10cSrcweir     bool bEQ = ( Peek() == EQ );
494cdf0e10cSrcweir     if( !bEQ && bVBASupportOn && aVar.IsBracket() )
495cdf0e10cSrcweir         Error( SbERR_EXPECTED, "=" );
496cdf0e10cSrcweir 
497cdf0e10cSrcweir     RecursiveMode eRecMode = ( bEQ ? PREVENT_CALL : FORCE_CALL );
498cdf0e10cSrcweir     bool bSpecialMidHandling = false;
499cdf0e10cSrcweir     SbiSymDef* pDef = aVar.GetRealVar();
500cdf0e10cSrcweir     if( bEQ && pDef && pDef->GetScope() == SbRTL )
501cdf0e10cSrcweir     {
502cdf0e10cSrcweir         String aRtlName = pDef->GetName();
503cdf0e10cSrcweir         if( aRtlName.EqualsIgnoreCaseAscii("Mid") )
504cdf0e10cSrcweir         {
505cdf0e10cSrcweir             SbiExprNode* pExprNode = aVar.GetExprNode();
506cdf0e10cSrcweir             // SbiNodeType eNodeType;
507cdf0e10cSrcweir             if( pExprNode && pExprNode->GetNodeType() == SbxVARVAL )
508cdf0e10cSrcweir             {
509cdf0e10cSrcweir                 SbiExprList* pPar = pExprNode->GetParameters();
510cdf0e10cSrcweir                 short nParCount = pPar ? pPar->GetSize() : 0;
511cdf0e10cSrcweir                 if( nParCount == 2 || nParCount == 3 )
512cdf0e10cSrcweir                 {
513cdf0e10cSrcweir                     if( nParCount == 2 )
514cdf0e10cSrcweir                         pPar->addExpression( new SbiExpression( this, -1, SbxLONG ) );
515cdf0e10cSrcweir 
516cdf0e10cSrcweir                     TestToken( EQ );
517cdf0e10cSrcweir                     pPar->addExpression( new SbiExpression( this ) );
518cdf0e10cSrcweir 
519cdf0e10cSrcweir                     bSpecialMidHandling = true;
520cdf0e10cSrcweir                 }
521cdf0e10cSrcweir             }
522cdf0e10cSrcweir         }
523cdf0e10cSrcweir     }
524cdf0e10cSrcweir     aVar.Gen( eRecMode );
525cdf0e10cSrcweir     if( !bSpecialMidHandling )
526cdf0e10cSrcweir     {
527cdf0e10cSrcweir         if( !bEQ )
528cdf0e10cSrcweir         {
529cdf0e10cSrcweir             aGen.Gen( _GET );
530cdf0e10cSrcweir         }
531cdf0e10cSrcweir         else
532cdf0e10cSrcweir         {
533*0420d1a0Smseidel             // Dann muss es eine Zuweisung sein. Was anderes gibt es nicht!
534cdf0e10cSrcweir             if( !aVar.IsLvalue() )
535cdf0e10cSrcweir                 Error( SbERR_LVALUE_EXPECTED );
536cdf0e10cSrcweir             TestToken( EQ );
537cdf0e10cSrcweir             SbiExpression aExpr( this );
538cdf0e10cSrcweir             aExpr.Gen();
539cdf0e10cSrcweir             SbiOpcode eOp = _PUT;
540cdf0e10cSrcweir             // SbiSymDef* pDef = aVar.GetRealVar();
541cdf0e10cSrcweir             if( pDef )
542cdf0e10cSrcweir             {
543cdf0e10cSrcweir                 if( pDef->GetConstDef() )
544cdf0e10cSrcweir                     Error( SbERR_DUPLICATE_DEF, pDef->GetName() );
545cdf0e10cSrcweir                 if( pDef->GetType() == SbxOBJECT )
546cdf0e10cSrcweir                 {
547cdf0e10cSrcweir                     eOp = _SET;
548cdf0e10cSrcweir                     if( pDef->GetTypeId() )
549cdf0e10cSrcweir                     {
550cdf0e10cSrcweir                         aGen.Gen( _SETCLASS, pDef->GetTypeId() );
551cdf0e10cSrcweir                         return;
552cdf0e10cSrcweir                     }
553cdf0e10cSrcweir                 }
554cdf0e10cSrcweir             }
555cdf0e10cSrcweir             aGen.Gen( eOp );
556cdf0e10cSrcweir         }
557cdf0e10cSrcweir     }
558cdf0e10cSrcweir }
559cdf0e10cSrcweir 
560cdf0e10cSrcweir // Zuweisungen
561cdf0e10cSrcweir 
Assign()562cdf0e10cSrcweir void SbiParser::Assign()
563cdf0e10cSrcweir {
564cdf0e10cSrcweir     SbiExpression aLvalue( this, SbLVALUE );
565cdf0e10cSrcweir     TestToken( EQ );
566cdf0e10cSrcweir     SbiExpression aExpr( this );
567cdf0e10cSrcweir     aLvalue.Gen();
568cdf0e10cSrcweir     aExpr.Gen();
569cdf0e10cSrcweir     sal_uInt16 nLen = 0;
570cdf0e10cSrcweir     SbiSymDef* pDef = aLvalue.GetRealVar();
571cdf0e10cSrcweir     {
572cdf0e10cSrcweir         if( pDef->GetConstDef() )
573cdf0e10cSrcweir             Error( SbERR_DUPLICATE_DEF, pDef->GetName() );
574cdf0e10cSrcweir         nLen = aLvalue.GetRealVar()->GetLen();
575cdf0e10cSrcweir     }
576cdf0e10cSrcweir     if( nLen )
577cdf0e10cSrcweir         aGen.Gen( _PAD, nLen );
578cdf0e10cSrcweir     aGen.Gen( _PUT );
579cdf0e10cSrcweir }
580cdf0e10cSrcweir 
581cdf0e10cSrcweir // Zuweisungen einer Objektvariablen
582cdf0e10cSrcweir 
Set()583cdf0e10cSrcweir void SbiParser::Set()
584cdf0e10cSrcweir {
585cdf0e10cSrcweir     SbiExpression aLvalue( this, SbLVALUE );
586cdf0e10cSrcweir     SbxDataType eType = aLvalue.GetType();
587cdf0e10cSrcweir     if( eType != SbxOBJECT && eType != SbxEMPTY && eType != SbxVARIANT )
588cdf0e10cSrcweir         Error( SbERR_INVALID_OBJECT );
589cdf0e10cSrcweir     TestToken( EQ );
590cdf0e10cSrcweir     SbiSymDef* pDef = aLvalue.GetRealVar();
591cdf0e10cSrcweir     if( pDef && pDef->GetConstDef() )
592cdf0e10cSrcweir         Error( SbERR_DUPLICATE_DEF, pDef->GetName() );
593cdf0e10cSrcweir 
594cdf0e10cSrcweir     SbiToken eTok = Peek();
595cdf0e10cSrcweir     if( eTok == NEW )
596cdf0e10cSrcweir     {
597cdf0e10cSrcweir         Next();
598cdf0e10cSrcweir         String aStr;
599cdf0e10cSrcweir         SbiSymDef* pTypeDef = new SbiSymDef( aStr );
600cdf0e10cSrcweir         TypeDecl( *pTypeDef, sal_True );
601cdf0e10cSrcweir 
602cdf0e10cSrcweir         aLvalue.Gen();
603cdf0e10cSrcweir         // aGen.Gen( _CLASS, pDef->GetTypeId() | 0x8000 );
604cdf0e10cSrcweir         aGen.Gen( _CREATE, pDef->GetId(), pTypeDef->GetTypeId() );
605cdf0e10cSrcweir         aGen.Gen( _SETCLASS, pDef->GetTypeId() );
606cdf0e10cSrcweir     }
607cdf0e10cSrcweir     else
608cdf0e10cSrcweir     {
609cdf0e10cSrcweir         SbiExpression aExpr( this );
610cdf0e10cSrcweir         aLvalue.Gen();
611cdf0e10cSrcweir         aExpr.Gen();
612*0420d1a0Smseidel         // It's a good idea to distinguish between
613*0420d1a0Smseidel         // set something = another &
614*0420d1a0Smseidel         // something = another
615*0420d1a0Smseidel         // ( it's necessary for vba objects where set is object
616cdf0e10cSrcweir         // specific and also doesn't involve processing default params )
617cdf0e10cSrcweir         if( pDef->GetTypeId() )
618cdf0e10cSrcweir         {
619cdf0e10cSrcweir             if ( bVBASupportOn )
620cdf0e10cSrcweir                 aGen.Gen( _VBASETCLASS, pDef->GetTypeId() );
621cdf0e10cSrcweir             else
622cdf0e10cSrcweir                 aGen.Gen( _SETCLASS, pDef->GetTypeId() );
623cdf0e10cSrcweir         }
624cdf0e10cSrcweir         else
625cdf0e10cSrcweir         {
626cdf0e10cSrcweir             if ( bVBASupportOn )
627cdf0e10cSrcweir                 aGen.Gen( _VBASET );
628cdf0e10cSrcweir             else
629cdf0e10cSrcweir                 aGen.Gen( _SET );
630cdf0e10cSrcweir         }
631cdf0e10cSrcweir     }
632cdf0e10cSrcweir     // aGen.Gen( _SET );
633cdf0e10cSrcweir }
634cdf0e10cSrcweir 
635cdf0e10cSrcweir // JSM 07.10.95
LSet()636cdf0e10cSrcweir void SbiParser::LSet()
637cdf0e10cSrcweir {
638cdf0e10cSrcweir     SbiExpression aLvalue( this, SbLVALUE );
639cdf0e10cSrcweir     if( aLvalue.GetType() != SbxSTRING )
640cdf0e10cSrcweir         Error( SbERR_INVALID_OBJECT );
641cdf0e10cSrcweir     TestToken( EQ );
642cdf0e10cSrcweir     SbiSymDef* pDef = aLvalue.GetRealVar();
643cdf0e10cSrcweir     if( pDef && pDef->GetConstDef() )
644cdf0e10cSrcweir         Error( SbERR_DUPLICATE_DEF, pDef->GetName() );
645cdf0e10cSrcweir     SbiExpression aExpr( this );
646cdf0e10cSrcweir     aLvalue.Gen();
647cdf0e10cSrcweir     aExpr.Gen();
648cdf0e10cSrcweir     aGen.Gen( _LSET );
649cdf0e10cSrcweir }
650cdf0e10cSrcweir 
651cdf0e10cSrcweir // JSM 07.10.95
RSet()652cdf0e10cSrcweir void SbiParser::RSet()
653cdf0e10cSrcweir {
654cdf0e10cSrcweir     SbiExpression aLvalue( this, SbLVALUE );
655cdf0e10cSrcweir     if( aLvalue.GetType() != SbxSTRING )
656cdf0e10cSrcweir         Error( SbERR_INVALID_OBJECT );
657cdf0e10cSrcweir     TestToken( EQ );
658cdf0e10cSrcweir     SbiSymDef* pDef = aLvalue.GetRealVar();
659cdf0e10cSrcweir     if( pDef && pDef->GetConstDef() )
660cdf0e10cSrcweir         Error( SbERR_DUPLICATE_DEF, pDef->GetName() );
661cdf0e10cSrcweir     SbiExpression aExpr( this );
662cdf0e10cSrcweir     aLvalue.Gen();
663cdf0e10cSrcweir     aExpr.Gen();
664cdf0e10cSrcweir     aGen.Gen( _RSET );
665cdf0e10cSrcweir }
666cdf0e10cSrcweir 
667cdf0e10cSrcweir // DEFINT, DEFLNG, DEFSNG, DEFDBL, DEFSTR und so weiter
668cdf0e10cSrcweir 
DefXXX()669cdf0e10cSrcweir void SbiParser::DefXXX()
670cdf0e10cSrcweir {
671cdf0e10cSrcweir     sal_Unicode ch1, ch2;
672cdf0e10cSrcweir     SbxDataType t = SbxDataType( eCurTok - DEFINT + SbxINTEGER );
673cdf0e10cSrcweir 
674cdf0e10cSrcweir     while( !bAbort )
675cdf0e10cSrcweir     {
676cdf0e10cSrcweir         if( Next() != SYMBOL ) break;
677cdf0e10cSrcweir         ch1 = aSym.ToUpperAscii().GetBuffer()[0];
678cdf0e10cSrcweir         ch2 = 0;
679cdf0e10cSrcweir         if( Peek() == MINUS )
680cdf0e10cSrcweir         {
681cdf0e10cSrcweir             Next();
682cdf0e10cSrcweir             if( Next() != SYMBOL ) Error( SbERR_SYMBOL_EXPECTED );
683cdf0e10cSrcweir             else
684cdf0e10cSrcweir             {
685cdf0e10cSrcweir                 ch2 = aSym.ToUpperAscii().GetBuffer()[0];
686cdf0e10cSrcweir                 //ch2 = aSym.Upper();
687cdf0e10cSrcweir                 if( ch2 < ch1 ) Error( SbERR_SYNTAX ), ch2 = 0;
688cdf0e10cSrcweir             }
689cdf0e10cSrcweir         }
690cdf0e10cSrcweir         if (!ch2) ch2 = ch1;
691cdf0e10cSrcweir         ch1 -= 'A'; ch2 -= 'A';
692cdf0e10cSrcweir         for (; ch1 <= ch2; ch1++) eDefTypes[ ch1 ] = t;
693cdf0e10cSrcweir         if( !TestComma() ) break;
694cdf0e10cSrcweir     }
695cdf0e10cSrcweir }
696cdf0e10cSrcweir 
697cdf0e10cSrcweir // STOP/SYSTEM
698cdf0e10cSrcweir 
Stop()699cdf0e10cSrcweir void SbiParser::Stop()
700cdf0e10cSrcweir {
701cdf0e10cSrcweir     aGen.Gen( _STOP );
702cdf0e10cSrcweir     Peek();     // #35694: Nur Peek(), damit EOL in Single-Line-If erkannt wird
703cdf0e10cSrcweir }
704cdf0e10cSrcweir 
705cdf0e10cSrcweir // IMPLEMENTS
706cdf0e10cSrcweir 
Implements()707cdf0e10cSrcweir void SbiParser::Implements()
708cdf0e10cSrcweir {
709cdf0e10cSrcweir     if( !bClassModule )
710cdf0e10cSrcweir     {
711cdf0e10cSrcweir         Error( SbERR_UNEXPECTED, IMPLEMENTS );
712cdf0e10cSrcweir         return;
713cdf0e10cSrcweir     }
714cdf0e10cSrcweir 
715cdf0e10cSrcweir     Peek();
716cdf0e10cSrcweir     if( eCurTok != SYMBOL )
717cdf0e10cSrcweir     {
718cdf0e10cSrcweir         Error( SbERR_SYMBOL_EXPECTED );
719cdf0e10cSrcweir         return;
720cdf0e10cSrcweir     }
721cdf0e10cSrcweir 
722cdf0e10cSrcweir     String aImplementedIface = aSym;
723cdf0e10cSrcweir     Next();
724cdf0e10cSrcweir     if( Peek() == DOT )
725cdf0e10cSrcweir     {
726cdf0e10cSrcweir         String aDotStr( '.' );
727cdf0e10cSrcweir         while( Peek() == DOT )
728cdf0e10cSrcweir         {
729cdf0e10cSrcweir             aImplementedIface += aDotStr;
730cdf0e10cSrcweir             Next();
731cdf0e10cSrcweir             SbiToken ePeekTok = Peek();
732cdf0e10cSrcweir             if( ePeekTok == SYMBOL || IsKwd( ePeekTok ) )
733cdf0e10cSrcweir             {
734cdf0e10cSrcweir                 Next();
735cdf0e10cSrcweir                 aImplementedIface += aSym;
736cdf0e10cSrcweir             }
737cdf0e10cSrcweir             else
738cdf0e10cSrcweir             {
739cdf0e10cSrcweir                 Next();
740cdf0e10cSrcweir                 Error( SbERR_SYMBOL_EXPECTED );
741cdf0e10cSrcweir                 break;
742cdf0e10cSrcweir             }
743cdf0e10cSrcweir         }
744cdf0e10cSrcweir     }
745cdf0e10cSrcweir     aIfaceVector.push_back( aImplementedIface );
746cdf0e10cSrcweir }
747cdf0e10cSrcweir 
EnableCompatibility()748cdf0e10cSrcweir void SbiParser::EnableCompatibility()
749cdf0e10cSrcweir {
750cdf0e10cSrcweir     if( !bCompatible )
751cdf0e10cSrcweir         AddConstants();
752cdf0e10cSrcweir     bCompatible = sal_True;
753cdf0e10cSrcweir }
754cdf0e10cSrcweir 
755cdf0e10cSrcweir // OPTION
756cdf0e10cSrcweir 
Option()757cdf0e10cSrcweir void SbiParser::Option()
758cdf0e10cSrcweir {
759cdf0e10cSrcweir     switch( Next() )
760cdf0e10cSrcweir     {
7613d762826SHerbert Dürr         case BASIC_EXPLICIT:
762cdf0e10cSrcweir             bExplicit = sal_True; break;
763cdf0e10cSrcweir         case BASE:
764cdf0e10cSrcweir             if( Next() == NUMBER )
765cdf0e10cSrcweir             {
766cdf0e10cSrcweir                 if( nVal == 0 || nVal == 1 )
767cdf0e10cSrcweir                 {
768cdf0e10cSrcweir                     nBase = (short) nVal;
769cdf0e10cSrcweir                     break;
770cdf0e10cSrcweir                 }
771cdf0e10cSrcweir             }
772cdf0e10cSrcweir             Error( SbERR_EXPECTED, "0/1" );
773cdf0e10cSrcweir             break;
774cdf0e10cSrcweir         case PRIVATE:
775cdf0e10cSrcweir         {
776cdf0e10cSrcweir             String aString = SbiTokenizer::Symbol(Next());
777cdf0e10cSrcweir             if( !aString.EqualsIgnoreCaseAscii("Module") )
778cdf0e10cSrcweir                 Error( SbERR_EXPECTED, "Module" );
779cdf0e10cSrcweir             break;
780cdf0e10cSrcweir         }
781cdf0e10cSrcweir         case COMPARE:
782cdf0e10cSrcweir         {
783cdf0e10cSrcweir             SbiToken eTok = Next();
784cdf0e10cSrcweir             if( eTok == BINARY )
785cdf0e10cSrcweir                 bText = sal_False;
786cdf0e10cSrcweir             else if( eTok == SYMBOL && GetSym().EqualsIgnoreCaseAscii("text") )
787cdf0e10cSrcweir                 bText = sal_True;
788cdf0e10cSrcweir             else
789cdf0e10cSrcweir                 Error( SbERR_EXPECTED, "Text/Binary" );
790cdf0e10cSrcweir             break;
791cdf0e10cSrcweir         }
792cdf0e10cSrcweir         case COMPATIBLE:
793cdf0e10cSrcweir             EnableCompatibility();
794cdf0e10cSrcweir             break;
795cdf0e10cSrcweir 
796cdf0e10cSrcweir         case CLASSMODULE:
797cdf0e10cSrcweir             bClassModule = sal_True;
798cdf0e10cSrcweir             aGen.GetModule().SetModuleType( com::sun::star::script::ModuleType::CLASS );
799cdf0e10cSrcweir             break;
800cdf0e10cSrcweir         case VBASUPPORT:
801cdf0e10cSrcweir             if( Next() == NUMBER )
802cdf0e10cSrcweir             {
803cdf0e10cSrcweir                 if ( nVal == 1 || nVal == 0 )
804cdf0e10cSrcweir                 {
805cdf0e10cSrcweir                     bVBASupportOn = ( nVal == 1 );
806cdf0e10cSrcweir                     if ( bVBASupportOn )
807cdf0e10cSrcweir                         EnableCompatibility();
808cdf0e10cSrcweir                     // if the module setting is different
809cdf0e10cSrcweir                     // reset it to what the Option tells us
810cdf0e10cSrcweir                     if ( bVBASupportOn != aGen.GetModule().IsVBACompat() )
811cdf0e10cSrcweir                         aGen.GetModule().SetVBACompat( bVBASupportOn );
812cdf0e10cSrcweir                     break;
813cdf0e10cSrcweir                 }
814cdf0e10cSrcweir             }
815cdf0e10cSrcweir             Error( SbERR_EXPECTED, "0/1" );
816cdf0e10cSrcweir             break;
817cdf0e10cSrcweir         default:
818cdf0e10cSrcweir             Error( SbERR_BAD_OPTION, eCurTok );
819cdf0e10cSrcweir     }
820cdf0e10cSrcweir }
821cdf0e10cSrcweir 
addStringConst(SbiSymPool & rPool,const char * pSym,const String & rStr)822cdf0e10cSrcweir void addStringConst( SbiSymPool& rPool, const char* pSym, const String& rStr )
823cdf0e10cSrcweir {
824cdf0e10cSrcweir     SbiConstDef* pConst = new SbiConstDef( String::CreateFromAscii( pSym ) );
825cdf0e10cSrcweir     pConst->SetType( SbxSTRING );
826cdf0e10cSrcweir     pConst->Set( rStr );
827cdf0e10cSrcweir     rPool.Add( pConst );
828cdf0e10cSrcweir }
829cdf0e10cSrcweir 
addStringConst(SbiSymPool & rPool,const char * pSym,const char * pStr)830cdf0e10cSrcweir inline void addStringConst( SbiSymPool& rPool, const char* pSym, const char* pStr )
831cdf0e10cSrcweir {
832cdf0e10cSrcweir     addStringConst( rPool, pSym, String::CreateFromAscii( pStr ) );
833cdf0e10cSrcweir }
834cdf0e10cSrcweir 
AddConstants(void)835cdf0e10cSrcweir void SbiParser::AddConstants( void )
836cdf0e10cSrcweir {
837cdf0e10cSrcweir     // #113063 Create constant RTL symbols
838cdf0e10cSrcweir     addStringConst( aPublics, "vbCr", "\x0D" );
839cdf0e10cSrcweir     addStringConst( aPublics, "vbCrLf", "\x0D\x0A" );
840cdf0e10cSrcweir     addStringConst( aPublics, "vbFormFeed", "\x0C" );
841cdf0e10cSrcweir     addStringConst( aPublics, "vbLf", "\x0A" );
842cdf0e10cSrcweir #if defined(UNX)
843cdf0e10cSrcweir     addStringConst( aPublics, "vbNewLine", "\x0A" );
844cdf0e10cSrcweir #else
845cdf0e10cSrcweir     addStringConst( aPublics, "vbNewLine", "\x0D\x0A" );
846cdf0e10cSrcweir #endif
847cdf0e10cSrcweir     addStringConst( aPublics, "vbNullString", "" );
848cdf0e10cSrcweir     addStringConst( aPublics, "vbTab", "\x09" );
849cdf0e10cSrcweir     addStringConst( aPublics, "vbVerticalTab", "\x0B" );
850cdf0e10cSrcweir 
851cdf0e10cSrcweir     // Force length 1 and make char 0 afterwards
852cdf0e10cSrcweir     String aNullCharStr( String::CreateFromAscii( " " ) );
853cdf0e10cSrcweir     aNullCharStr.SetChar( 0, 0 );
854cdf0e10cSrcweir     addStringConst( aPublics, "vbNullChar", aNullCharStr );
855cdf0e10cSrcweir }
856cdf0e10cSrcweir 
857cdf0e10cSrcweir // ERROR n
858cdf0e10cSrcweir 
ErrorStmnt()859cdf0e10cSrcweir void SbiParser::ErrorStmnt()
860cdf0e10cSrcweir {
861cdf0e10cSrcweir     SbiExpression aPar( this );
862cdf0e10cSrcweir     aPar.Gen();
863cdf0e10cSrcweir     aGen.Gen( _ERROR );
864cdf0e10cSrcweir }
865cdf0e10cSrcweir 
866*0420d1a0Smseidel /* vim: set noet sw=4 ts=4: */
867