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