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