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
25cdf0e10cSrcweir #include "sbcomp.hxx"
26cdf0e10cSrcweir
27cdf0e10cSrcweir // Single-line IF und Multiline IF
28cdf0e10cSrcweir
If()29cdf0e10cSrcweir void SbiParser::If()
30cdf0e10cSrcweir {
31cdf0e10cSrcweir sal_uInt32 nEndLbl;
32cdf0e10cSrcweir SbiToken eTok = NIL;
33cdf0e10cSrcweir // Ende-Tokens ignorieren:
34cdf0e10cSrcweir SbiExpression aCond( this );
35cdf0e10cSrcweir aCond.Gen();
36cdf0e10cSrcweir TestToken( THEN );
37cdf0e10cSrcweir if( IsEoln( Next() ) )
38cdf0e10cSrcweir {
39cdf0e10cSrcweir // AB 13.5.1996: #27720# Am Ende jeden Blocks muss ein Jump zu ENDIF
40*c1e43d34Smseidel // eingef�gt werden, damit bei ELSEIF nicht erneut die Bedingung
41cdf0e10cSrcweir // ausgewertet wird. Die Tabelle nimmt alle Absprungstellen auf.
42cdf0e10cSrcweir #define JMP_TABLE_SIZE 100
43cdf0e10cSrcweir sal_uInt32 pnJmpToEndLbl[JMP_TABLE_SIZE]; // 100 ELSEIFs zulaessig
44cdf0e10cSrcweir sal_uInt16 iJmp = 0; // aktueller Tabellen-Index
45cdf0e10cSrcweir
46cdf0e10cSrcweir // multiline IF
47cdf0e10cSrcweir nEndLbl = aGen.Gen( _JUMPF, 0 );
48cdf0e10cSrcweir eTok = Peek();
49cdf0e10cSrcweir while( !( eTok == ELSEIF || eTok == ELSE || eTok == ENDIF ) &&
50cdf0e10cSrcweir !bAbort && Parse() )
51cdf0e10cSrcweir {
52cdf0e10cSrcweir eTok = Peek();
53cdf0e10cSrcweir if( IsEof() )
54cdf0e10cSrcweir {
55cdf0e10cSrcweir Error( SbERR_BAD_BLOCK, IF ); bAbort = sal_True; return;
56cdf0e10cSrcweir }
57cdf0e10cSrcweir }
58cdf0e10cSrcweir // ELSEIF?
59cdf0e10cSrcweir while( eTok == ELSEIF )
60cdf0e10cSrcweir {
61cdf0e10cSrcweir // #27720# Bei erfolgreichem IF/ELSEIF auf ENDIF springen
62cdf0e10cSrcweir if( iJmp >= JMP_TABLE_SIZE )
63cdf0e10cSrcweir {
64cdf0e10cSrcweir Error( SbERR_PROG_TOO_LARGE ); bAbort = sal_True; return;
65cdf0e10cSrcweir }
66cdf0e10cSrcweir pnJmpToEndLbl[iJmp++] = aGen.Gen( _JUMP, 0 );
67cdf0e10cSrcweir
68cdf0e10cSrcweir Next();
69cdf0e10cSrcweir aGen.BackChain( nEndLbl );
70cdf0e10cSrcweir
71cdf0e10cSrcweir aGen.Statement();
72cdf0e10cSrcweir SbiExpression* pCond = new SbiExpression( this );
73cdf0e10cSrcweir pCond->Gen();
74cdf0e10cSrcweir nEndLbl = aGen.Gen( _JUMPF, 0 );
75cdf0e10cSrcweir delete pCond;
76cdf0e10cSrcweir TestToken( THEN );
77cdf0e10cSrcweir eTok = Peek();
78cdf0e10cSrcweir while( !( eTok == ELSEIF || eTok == ELSE || eTok == ENDIF ) &&
79cdf0e10cSrcweir !bAbort && Parse() )
80cdf0e10cSrcweir {
81cdf0e10cSrcweir eTok = Peek();
82cdf0e10cSrcweir if( IsEof() )
83cdf0e10cSrcweir {
84cdf0e10cSrcweir Error( SbERR_BAD_BLOCK, ELSEIF ); bAbort = sal_True; return;
85cdf0e10cSrcweir }
86cdf0e10cSrcweir }
87cdf0e10cSrcweir }
88cdf0e10cSrcweir if( eTok == ELSE )
89cdf0e10cSrcweir {
90cdf0e10cSrcweir Next();
91cdf0e10cSrcweir sal_uInt32 nElseLbl = nEndLbl;
92cdf0e10cSrcweir nEndLbl = aGen.Gen( _JUMP, 0 );
93cdf0e10cSrcweir aGen.BackChain( nElseLbl );
94cdf0e10cSrcweir
95cdf0e10cSrcweir aGen.Statement();
96cdf0e10cSrcweir StmntBlock( ENDIF );
97cdf0e10cSrcweir }
98cdf0e10cSrcweir else if( eTok == ENDIF )
99cdf0e10cSrcweir Next();
100cdf0e10cSrcweir
101cdf0e10cSrcweir // #27720# Jmp-Tabelle abarbeiten
102cdf0e10cSrcweir while( iJmp > 0 )
103cdf0e10cSrcweir {
104cdf0e10cSrcweir iJmp--;
105cdf0e10cSrcweir aGen.BackChain( pnJmpToEndLbl[iJmp] );
106cdf0e10cSrcweir }
107cdf0e10cSrcweir }
108cdf0e10cSrcweir else
109cdf0e10cSrcweir {
110cdf0e10cSrcweir // single line IF
111cdf0e10cSrcweir bSingleLineIf = sal_True;
112cdf0e10cSrcweir nEndLbl = aGen.Gen( _JUMPF, 0 );
113cdf0e10cSrcweir Push( eCurTok );
114cdf0e10cSrcweir while( !bAbort )
115cdf0e10cSrcweir {
116cdf0e10cSrcweir if( !Parse() ) break;
117cdf0e10cSrcweir eTok = Peek();
118cdf0e10cSrcweir if( eTok == ELSE || eTok == EOLN || eTok == REM )
119cdf0e10cSrcweir break;
120cdf0e10cSrcweir }
121cdf0e10cSrcweir if( eTok == ELSE )
122cdf0e10cSrcweir {
123cdf0e10cSrcweir Next();
124cdf0e10cSrcweir sal_uInt32 nElseLbl = nEndLbl;
125cdf0e10cSrcweir nEndLbl = aGen.Gen( _JUMP, 0 );
126cdf0e10cSrcweir aGen.BackChain( nElseLbl );
127cdf0e10cSrcweir while( !bAbort )
128cdf0e10cSrcweir {
129cdf0e10cSrcweir if( !Parse() ) break;
130cdf0e10cSrcweir eTok = Peek();
13107396187SDamjan Jovanovic if( eTok == EOLN || eTok == REM )
132cdf0e10cSrcweir break;
133cdf0e10cSrcweir }
134cdf0e10cSrcweir }
135cdf0e10cSrcweir bSingleLineIf = sal_False;
136cdf0e10cSrcweir }
137cdf0e10cSrcweir aGen.BackChain( nEndLbl );
138cdf0e10cSrcweir }
139cdf0e10cSrcweir
140cdf0e10cSrcweir // ELSE/ELSEIF/ENDIF ohne IF
141cdf0e10cSrcweir
NoIf()142cdf0e10cSrcweir void SbiParser::NoIf()
143cdf0e10cSrcweir {
144cdf0e10cSrcweir Error( SbERR_NO_IF );
145cdf0e10cSrcweir StmntBlock( ENDIF );
146cdf0e10cSrcweir }
147cdf0e10cSrcweir
148cdf0e10cSrcweir // DO WHILE...LOOP
149cdf0e10cSrcweir // DO ... LOOP WHILE
150cdf0e10cSrcweir
DoLoop()151cdf0e10cSrcweir void SbiParser::DoLoop()
152cdf0e10cSrcweir {
153cdf0e10cSrcweir sal_uInt32 nStartLbl = aGen.GetPC();
154cdf0e10cSrcweir OpenBlock( DO );
155cdf0e10cSrcweir SbiToken eTok = Next();
156cdf0e10cSrcweir if( IsEoln( eTok ) )
157cdf0e10cSrcweir {
158cdf0e10cSrcweir // DO ... LOOP [WHILE|UNTIL expr]
159cdf0e10cSrcweir StmntBlock( LOOP );
160cdf0e10cSrcweir eTok = Next();
161cdf0e10cSrcweir if( eTok == UNTIL || eTok == WHILE )
162cdf0e10cSrcweir {
163cdf0e10cSrcweir SbiExpression aExpr( this );
164cdf0e10cSrcweir aExpr.Gen();
165cdf0e10cSrcweir aGen.Gen( eTok == UNTIL ? _JUMPF : _JUMPT, nStartLbl );
166cdf0e10cSrcweir } else
167cdf0e10cSrcweir if (eTok == EOLN || eTok == REM)
168cdf0e10cSrcweir aGen.Gen (_JUMP, nStartLbl);
169cdf0e10cSrcweir else
170cdf0e10cSrcweir Error( SbERR_EXPECTED, WHILE );
171cdf0e10cSrcweir }
172cdf0e10cSrcweir else
173cdf0e10cSrcweir {
174cdf0e10cSrcweir // DO [WHILE|UNTIL expr] ... LOOP
175cdf0e10cSrcweir if( eTok == UNTIL || eTok == WHILE )
176cdf0e10cSrcweir {
177cdf0e10cSrcweir SbiExpression aCond( this );
178cdf0e10cSrcweir aCond.Gen();
179cdf0e10cSrcweir }
180cdf0e10cSrcweir sal_uInt32 nEndLbl = aGen.Gen( eTok == UNTIL ? _JUMPT : _JUMPF, 0 );
181cdf0e10cSrcweir StmntBlock( LOOP );
182cdf0e10cSrcweir TestEoln();
183cdf0e10cSrcweir aGen.Gen( _JUMP, nStartLbl );
184cdf0e10cSrcweir aGen.BackChain( nEndLbl );
185cdf0e10cSrcweir }
186cdf0e10cSrcweir CloseBlock();
187cdf0e10cSrcweir }
188cdf0e10cSrcweir
189cdf0e10cSrcweir // WHILE ... WEND
190cdf0e10cSrcweir
While()191cdf0e10cSrcweir void SbiParser::While()
192cdf0e10cSrcweir {
193cdf0e10cSrcweir SbiExpression aCond( this );
194cdf0e10cSrcweir sal_uInt32 nStartLbl = aGen.GetPC();
195cdf0e10cSrcweir aCond.Gen();
196cdf0e10cSrcweir sal_uInt32 nEndLbl = aGen.Gen( _JUMPF, 0 );
197cdf0e10cSrcweir StmntBlock( WEND );
198cdf0e10cSrcweir aGen.Gen( _JUMP, nStartLbl );
199cdf0e10cSrcweir aGen.BackChain( nEndLbl );
200cdf0e10cSrcweir }
201cdf0e10cSrcweir
202cdf0e10cSrcweir // FOR var = expr TO expr STEP
203cdf0e10cSrcweir
For()204cdf0e10cSrcweir void SbiParser::For()
205cdf0e10cSrcweir {
206cdf0e10cSrcweir bool bForEach = ( Peek() == EACH );
207cdf0e10cSrcweir if( bForEach )
208cdf0e10cSrcweir Next();
209cdf0e10cSrcweir SbiExpression aLvalue( this, SbOPERAND );
210cdf0e10cSrcweir aLvalue.Gen(); // Variable auf dem Stack
211cdf0e10cSrcweir
212cdf0e10cSrcweir if( bForEach )
213cdf0e10cSrcweir {
214cdf0e10cSrcweir TestToken( _IN_ );
215cdf0e10cSrcweir SbiExpression aCollExpr( this, SbOPERAND );
216cdf0e10cSrcweir aCollExpr.Gen(); // Colletion var to for stack
217cdf0e10cSrcweir TestEoln();
218cdf0e10cSrcweir aGen.Gen( _INITFOREACH );
219cdf0e10cSrcweir }
220cdf0e10cSrcweir else
221cdf0e10cSrcweir {
222cdf0e10cSrcweir TestToken( EQ );
223cdf0e10cSrcweir SbiExpression aStartExpr( this );
224cdf0e10cSrcweir aStartExpr.Gen(); // Startausdruck auf dem Stack
225cdf0e10cSrcweir TestToken( TO );
226cdf0e10cSrcweir SbiExpression aStopExpr( this );
227cdf0e10cSrcweir aStopExpr.Gen(); // Endausdruck auf dem Stack
228cdf0e10cSrcweir if( Peek() == STEP )
229cdf0e10cSrcweir {
230cdf0e10cSrcweir Next();
231cdf0e10cSrcweir SbiExpression aStepExpr( this );
232cdf0e10cSrcweir aStepExpr.Gen();
233cdf0e10cSrcweir }
234cdf0e10cSrcweir else
235cdf0e10cSrcweir {
236cdf0e10cSrcweir SbiExpression aOne( this, 1, SbxINTEGER );
237cdf0e10cSrcweir aOne.Gen();
238cdf0e10cSrcweir }
239cdf0e10cSrcweir TestEoln();
240cdf0e10cSrcweir // Der Stack hat jetzt 4 Elemente: Variable, Start, Ende, Inkrement
241cdf0e10cSrcweir // Startwert binden
242cdf0e10cSrcweir aGen.Gen( _INITFOR );
243cdf0e10cSrcweir }
244cdf0e10cSrcweir
245cdf0e10cSrcweir sal_uInt32 nLoop = aGen.GetPC();
246*c1e43d34Smseidel // Test durchf�hren, evtl. Stack freigeben
247cdf0e10cSrcweir sal_uInt32 nEndTarget = aGen.Gen( _TESTFOR, 0 );
248cdf0e10cSrcweir OpenBlock( FOR );
249cdf0e10cSrcweir StmntBlock( NEXT );
250cdf0e10cSrcweir aGen.Gen( _NEXT );
251cdf0e10cSrcweir aGen.Gen( _JUMP, nLoop );
252cdf0e10cSrcweir // Kommen Variable nach NEXT?
253cdf0e10cSrcweir if( Peek() == SYMBOL )
254cdf0e10cSrcweir {
255cdf0e10cSrcweir SbiExpression aVar( this, SbOPERAND );
256cdf0e10cSrcweir if( aVar.GetRealVar() != aLvalue.GetRealVar() )
257cdf0e10cSrcweir Error( SbERR_EXPECTED, aLvalue.GetRealVar()->GetName() );
258cdf0e10cSrcweir }
259cdf0e10cSrcweir aGen.BackChain( nEndTarget );
260cdf0e10cSrcweir CloseBlock();
261cdf0e10cSrcweir }
262cdf0e10cSrcweir
263cdf0e10cSrcweir // WITH .. END WITH
264cdf0e10cSrcweir
With()265cdf0e10cSrcweir void SbiParser::With()
266cdf0e10cSrcweir {
267cdf0e10cSrcweir SbiExpression aVar( this, SbOPERAND );
268cdf0e10cSrcweir
269*c1e43d34Smseidel // Letzten Knoten in der Objekt-Kette �berpr�fen
270cdf0e10cSrcweir SbiExprNode *pNode = aVar.GetExprNode()->GetRealNode();
271cdf0e10cSrcweir SbiSymDef* pDef = pNode->GetVar();
272cdf0e10cSrcweir // Variant, AB 27.6.1997, #41090: bzw. empty -> mu� Object sein
273cdf0e10cSrcweir if( pDef->GetType() == SbxVARIANT || pDef->GetType() == SbxEMPTY )
274cdf0e10cSrcweir pDef->SetType( SbxOBJECT );
275cdf0e10cSrcweir else if( pDef->GetType() != SbxOBJECT )
276cdf0e10cSrcweir Error( SbERR_NEEDS_OBJECT );
277cdf0e10cSrcweir
278*c1e43d34Smseidel // Knoten auch auf SbxOBJECT setzen, damit sp�ter Gen() klappt
279cdf0e10cSrcweir pNode->SetType( SbxOBJECT );
280cdf0e10cSrcweir
281cdf0e10cSrcweir OpenBlock( NIL, aVar.GetExprNode() );
282cdf0e10cSrcweir StmntBlock( ENDWITH );
283cdf0e10cSrcweir CloseBlock();
284cdf0e10cSrcweir }
285cdf0e10cSrcweir
286cdf0e10cSrcweir // LOOP/NEXT/WEND ohne Konstrukt
287cdf0e10cSrcweir
BadBlock()288cdf0e10cSrcweir void SbiParser::BadBlock()
289cdf0e10cSrcweir {
290cdf0e10cSrcweir if( eEndTok )
291cdf0e10cSrcweir Error( SbERR_BAD_BLOCK, eEndTok );
292cdf0e10cSrcweir else
293cdf0e10cSrcweir Error( SbERR_BAD_BLOCK, "Loop/Next/Wend" );
294cdf0e10cSrcweir }
295cdf0e10cSrcweir
296cdf0e10cSrcweir // On expr Goto/Gosub n,n,n...
297cdf0e10cSrcweir
OnGoto()298cdf0e10cSrcweir void SbiParser::OnGoto()
299cdf0e10cSrcweir {
300cdf0e10cSrcweir SbiExpression aCond( this );
301cdf0e10cSrcweir aCond.Gen();
302cdf0e10cSrcweir sal_uInt32 nLabelsTarget = aGen.Gen( _ONJUMP, 0 );
303cdf0e10cSrcweir SbiToken eTok = Next();
304cdf0e10cSrcweir if( eTok != GOTO && eTok != GOSUB )
305cdf0e10cSrcweir {
306cdf0e10cSrcweir Error( SbERR_EXPECTED, "GoTo/GoSub" );
307cdf0e10cSrcweir eTok = GOTO;
308cdf0e10cSrcweir }
309cdf0e10cSrcweir // Label-Tabelle einlesen:
310cdf0e10cSrcweir sal_uInt32 nLbl = 0;
311cdf0e10cSrcweir do
312cdf0e10cSrcweir {
313cdf0e10cSrcweir SbiToken eTok2 = NIL;
314cdf0e10cSrcweir eTok2 = Next(); // Label holen
315cdf0e10cSrcweir if( MayBeLabel() )
316cdf0e10cSrcweir {
317cdf0e10cSrcweir sal_uInt32 nOff = pProc->GetLabels().Reference( aSym );
318cdf0e10cSrcweir aGen.Gen( _JUMP, nOff );
319cdf0e10cSrcweir nLbl++;
320cdf0e10cSrcweir }
321cdf0e10cSrcweir else Error( SbERR_LABEL_EXPECTED );
322cdf0e10cSrcweir }
323cdf0e10cSrcweir while( !bAbort && TestComma() );
324cdf0e10cSrcweir if( eTok == GOSUB )
325cdf0e10cSrcweir nLbl |= 0x8000;
326cdf0e10cSrcweir aGen.Patch( nLabelsTarget, nLbl );
327cdf0e10cSrcweir }
328cdf0e10cSrcweir
329cdf0e10cSrcweir // GOTO/GOSUB
330cdf0e10cSrcweir
Goto()331cdf0e10cSrcweir void SbiParser::Goto()
332cdf0e10cSrcweir {
333cdf0e10cSrcweir SbiOpcode eOp = eCurTok == GOTO ? _JUMP : _GOSUB;
334cdf0e10cSrcweir Next();
335cdf0e10cSrcweir if( MayBeLabel() )
336cdf0e10cSrcweir {
337cdf0e10cSrcweir sal_uInt32 nOff = pProc->GetLabels().Reference( aSym );
338cdf0e10cSrcweir aGen.Gen( eOp, nOff );
339cdf0e10cSrcweir }
340cdf0e10cSrcweir else Error( SbERR_LABEL_EXPECTED );
341cdf0e10cSrcweir }
342cdf0e10cSrcweir
343cdf0e10cSrcweir // RETURN [label]
344cdf0e10cSrcweir
Return()345cdf0e10cSrcweir void SbiParser::Return()
346cdf0e10cSrcweir {
347cdf0e10cSrcweir Next();
348cdf0e10cSrcweir if( MayBeLabel() )
349cdf0e10cSrcweir {
350cdf0e10cSrcweir sal_uInt32 nOff = pProc->GetLabels().Reference( aSym );
351cdf0e10cSrcweir aGen.Gen( _RETURN, nOff );
352cdf0e10cSrcweir }
353cdf0e10cSrcweir else aGen.Gen( _RETURN, 0 );
354cdf0e10cSrcweir }
355cdf0e10cSrcweir
356cdf0e10cSrcweir // SELECT CASE
357cdf0e10cSrcweir
Select()358cdf0e10cSrcweir void SbiParser::Select()
359cdf0e10cSrcweir {
360cdf0e10cSrcweir TestToken( CASE );
361cdf0e10cSrcweir SbiExpression aCase( this );
362cdf0e10cSrcweir SbiToken eTok = NIL;
363cdf0e10cSrcweir aCase.Gen();
364cdf0e10cSrcweir aGen.Gen( _CASE );
365cdf0e10cSrcweir TestEoln();
366cdf0e10cSrcweir sal_uInt32 nNextTarget = 0;
367cdf0e10cSrcweir sal_uInt32 nDoneTarget = 0;
368cdf0e10cSrcweir sal_Bool bElse = sal_False;
369cdf0e10cSrcweir // Die Cases einlesen:
370cdf0e10cSrcweir while( !bAbort )
371cdf0e10cSrcweir {
372cdf0e10cSrcweir eTok = Next();
373cdf0e10cSrcweir if( eTok == CASE )
374cdf0e10cSrcweir {
375cdf0e10cSrcweir if( nNextTarget )
376cdf0e10cSrcweir aGen.BackChain( nNextTarget ), nNextTarget = 0;
377cdf0e10cSrcweir aGen.Statement();
378cdf0e10cSrcweir // Jeden Case einlesen
379cdf0e10cSrcweir sal_Bool bDone = sal_False;
380cdf0e10cSrcweir sal_uInt32 nTrueTarget = 0;
381cdf0e10cSrcweir if( Peek() == ELSE )
382cdf0e10cSrcweir {
383cdf0e10cSrcweir // CASE ELSE
384cdf0e10cSrcweir Next();
385cdf0e10cSrcweir bElse = sal_True;
386cdf0e10cSrcweir }
387cdf0e10cSrcweir else while( !bDone )
388cdf0e10cSrcweir {
389cdf0e10cSrcweir if( bElse )
390cdf0e10cSrcweir Error( SbERR_SYNTAX );
391cdf0e10cSrcweir SbiToken eTok2 = Peek();
392cdf0e10cSrcweir if( eTok2 == IS || ( eTok2 >= EQ && eTok2 <= GE ) )
393cdf0e10cSrcweir { // CASE [IS] operator expr
394cdf0e10cSrcweir if( eTok2 == IS )
395cdf0e10cSrcweir Next();
396cdf0e10cSrcweir eTok2 = Peek();
397cdf0e10cSrcweir if( eTok2 < EQ || eTok2 > GE )
398cdf0e10cSrcweir Error( SbERR_SYNTAX );
399cdf0e10cSrcweir else Next();
400cdf0e10cSrcweir SbiExpression aCompare( this );
401cdf0e10cSrcweir aCompare.Gen();
402cdf0e10cSrcweir nTrueTarget = aGen.Gen(
403cdf0e10cSrcweir _CASEIS, nTrueTarget,
404cdf0e10cSrcweir sal::static_int_cast< sal_uInt16 >(
405cdf0e10cSrcweir SbxEQ + ( eTok2 - EQ ) ) );
406cdf0e10cSrcweir }
407cdf0e10cSrcweir else
408cdf0e10cSrcweir { // CASE expr | expr TO expr
409cdf0e10cSrcweir SbiExpression aCase1( this );
410cdf0e10cSrcweir aCase1.Gen();
411cdf0e10cSrcweir if( Peek() == TO )
412cdf0e10cSrcweir {
413cdf0e10cSrcweir // CASE a TO b
414cdf0e10cSrcweir Next();
415cdf0e10cSrcweir SbiExpression aCase2( this );
416cdf0e10cSrcweir aCase2.Gen();
417cdf0e10cSrcweir nTrueTarget = aGen.Gen( _CASETO, nTrueTarget );
418cdf0e10cSrcweir }
419cdf0e10cSrcweir else
420cdf0e10cSrcweir // CASE a
421cdf0e10cSrcweir nTrueTarget = aGen.Gen( _CASEIS, nTrueTarget, SbxEQ );
422cdf0e10cSrcweir
423cdf0e10cSrcweir }
424cdf0e10cSrcweir if( Peek() == COMMA ) Next();
425cdf0e10cSrcweir else TestEoln(), bDone = sal_True;
426cdf0e10cSrcweir }
427cdf0e10cSrcweir // Alle Cases abgearbeitet
428cdf0e10cSrcweir if( !bElse )
429cdf0e10cSrcweir {
430cdf0e10cSrcweir nNextTarget = aGen.Gen( _JUMP, nNextTarget );
431cdf0e10cSrcweir aGen.BackChain( nTrueTarget );
432cdf0e10cSrcweir }
433cdf0e10cSrcweir // den Statement-Rumpf bauen
434cdf0e10cSrcweir while( !bAbort )
435cdf0e10cSrcweir {
436cdf0e10cSrcweir eTok = Peek();
437cdf0e10cSrcweir if( eTok == CASE || eTok == ENDSELECT )
438cdf0e10cSrcweir break;
439cdf0e10cSrcweir if( !Parse() ) goto done;
440cdf0e10cSrcweir eTok = Peek();
441cdf0e10cSrcweir if( eTok == CASE || eTok == ENDSELECT )
442cdf0e10cSrcweir break;
443cdf0e10cSrcweir }
444cdf0e10cSrcweir if( !bElse )
445cdf0e10cSrcweir nDoneTarget = aGen.Gen( _JUMP, nDoneTarget );
446cdf0e10cSrcweir }
447cdf0e10cSrcweir else if( !IsEoln( eTok ) )
448cdf0e10cSrcweir break;
449cdf0e10cSrcweir }
450cdf0e10cSrcweir done:
451cdf0e10cSrcweir if( eTok != ENDSELECT )
452cdf0e10cSrcweir Error( SbERR_EXPECTED, ENDSELECT );
453cdf0e10cSrcweir if( nNextTarget )
454cdf0e10cSrcweir aGen.BackChain( nNextTarget );
455cdf0e10cSrcweir aGen.BackChain( nDoneTarget );
456cdf0e10cSrcweir aGen.Gen( _ENDCASE );
457cdf0e10cSrcweir }
458cdf0e10cSrcweir
459cdf0e10cSrcweir // ON Error/Variable
460cdf0e10cSrcweir
461cdf0e10cSrcweir #ifdef _MSC_VER
462cdf0e10cSrcweir #pragma optimize("",off)
463cdf0e10cSrcweir #endif
464cdf0e10cSrcweir
On()465cdf0e10cSrcweir void SbiParser::On()
466cdf0e10cSrcweir {
467cdf0e10cSrcweir SbiToken eTok = Peek();
468cdf0e10cSrcweir String aString = SbiTokenizer::Symbol(eTok);
469cdf0e10cSrcweir if (aString.EqualsIgnoreCaseAscii("ERROR"))
470cdf0e10cSrcweir //if (!aString.ICompare("ERROR"))
471cdf0e10cSrcweir eTok = _ERROR_; // Error kommt als SYMBOL
472cdf0e10cSrcweir if( eTok != _ERROR_ && eTok != LOCAL ) OnGoto();
473cdf0e10cSrcweir else
474cdf0e10cSrcweir {
475cdf0e10cSrcweir if( eTok == LOCAL ) Next();
476cdf0e10cSrcweir Next (); // Kein TestToken mehr, da es sonst einen Fehler gibt
477cdf0e10cSrcweir
478cdf0e10cSrcweir Next(); // Token nach Error holen
479cdf0e10cSrcweir if( eCurTok == GOTO )
480cdf0e10cSrcweir {
481cdf0e10cSrcweir // ON ERROR GOTO label|0
482cdf0e10cSrcweir Next();
483cdf0e10cSrcweir bool bError_ = false;
484cdf0e10cSrcweir if( MayBeLabel() )
485cdf0e10cSrcweir {
486cdf0e10cSrcweir if( eCurTok == NUMBER && !nVal )
487cdf0e10cSrcweir aGen.Gen( _STDERROR );
488cdf0e10cSrcweir else
489cdf0e10cSrcweir {
490cdf0e10cSrcweir sal_uInt32 nOff = pProc->GetLabels().Reference( aSym );
491cdf0e10cSrcweir aGen.Gen( _ERRHDL, nOff );
492cdf0e10cSrcweir }
493cdf0e10cSrcweir }
494cdf0e10cSrcweir else if( eCurTok == MINUS )
495cdf0e10cSrcweir {
496cdf0e10cSrcweir Next();
497cdf0e10cSrcweir if( eCurTok == NUMBER && nVal == 1 )
498cdf0e10cSrcweir aGen.Gen( _STDERROR );
499cdf0e10cSrcweir else
500cdf0e10cSrcweir bError_ = true;
501cdf0e10cSrcweir }
502cdf0e10cSrcweir if( bError_ )
503cdf0e10cSrcweir Error( SbERR_LABEL_EXPECTED );
504cdf0e10cSrcweir }
505cdf0e10cSrcweir else if( eCurTok == RESUME )
506cdf0e10cSrcweir {
507cdf0e10cSrcweir TestToken( NEXT );
508cdf0e10cSrcweir aGen.Gen( _NOERROR );
509cdf0e10cSrcweir }
510cdf0e10cSrcweir else Error( SbERR_EXPECTED, "GoTo/Resume" );
511cdf0e10cSrcweir }
512cdf0e10cSrcweir }
513cdf0e10cSrcweir
514cdf0e10cSrcweir #ifdef _MSC_VER
515cdf0e10cSrcweir #pragma optimize("",off)
516cdf0e10cSrcweir #endif
517cdf0e10cSrcweir
518cdf0e10cSrcweir // RESUME [0]|NEXT|label
519cdf0e10cSrcweir
Resume()520cdf0e10cSrcweir void SbiParser::Resume()
521cdf0e10cSrcweir {
522cdf0e10cSrcweir sal_uInt32 nLbl;
523cdf0e10cSrcweir
524cdf0e10cSrcweir switch( Next() )
525cdf0e10cSrcweir {
526cdf0e10cSrcweir case EOS:
527cdf0e10cSrcweir case EOLN:
528cdf0e10cSrcweir aGen.Gen( _RESUME, 0 );
529cdf0e10cSrcweir break;
530cdf0e10cSrcweir case NEXT:
531cdf0e10cSrcweir aGen.Gen( _RESUME, 1 );
532cdf0e10cSrcweir Next();
533cdf0e10cSrcweir break;
534cdf0e10cSrcweir case NUMBER:
535cdf0e10cSrcweir if( !nVal )
536cdf0e10cSrcweir {
537cdf0e10cSrcweir aGen.Gen( _RESUME, 0 );
538cdf0e10cSrcweir break;
53930acf5e8Spfg } // fall through
540cdf0e10cSrcweir case SYMBOL:
541cdf0e10cSrcweir if( MayBeLabel() )
542cdf0e10cSrcweir {
543cdf0e10cSrcweir nLbl = pProc->GetLabels().Reference( aSym );
544cdf0e10cSrcweir aGen.Gen( _RESUME, nLbl );
545cdf0e10cSrcweir Next();
546cdf0e10cSrcweir break;
54730acf5e8Spfg } // fall through
548cdf0e10cSrcweir default:
549cdf0e10cSrcweir Error( SbERR_LABEL_EXPECTED );
550cdf0e10cSrcweir }
551cdf0e10cSrcweir }
552cdf0e10cSrcweir
553*c1e43d34Smseidel /* vim: set noet sw=4 ts=4: */
554