Branch data Line data Source code
1 : : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 : : /*
3 : : * This file is part of the LibreOffice project.
4 : : *
5 : : * This Source Code Form is subject to the terms of the Mozilla Public
6 : : * License, v. 2.0. If a copy of the MPL was not distributed with this
7 : : * file, You can obtain one at http://mozilla.org/MPL/2.0/.
8 : : *
9 : : * This file incorporates work covered by the following license notice:
10 : : *
11 : : * Licensed to the Apache Software Foundation (ASF) under one or more
12 : : * contributor license agreements. See the NOTICE file distributed
13 : : * with this work for additional information regarding copyright
14 : : * ownership. The ASF licenses this file to you under the Apache
15 : : * License, Version 2.0 (the "License"); you may not use this file
16 : : * except in compliance with the License. You may obtain a copy of
17 : : * the License at http://www.apache.org/licenses/LICENSE-2.0 .
18 : : */
19 : :
20 : :
21 : : #include "sbcomp.hxx"
22 : :
23 : : // Single-line IF und Multiline IF
24 : :
25 : 249 : void SbiParser::If()
26 : : {
27 : : sal_uInt32 nEndLbl;
28 : 249 : SbiToken eTok = NIL;
29 : : // ignore end-tokens
30 [ + - ]: 249 : SbiExpression aCond( this );
31 [ + - ]: 249 : aCond.Gen();
32 [ + - ]: 249 : TestToken( THEN );
33 [ + - ][ + + ]: 249 : if( IsEoln( Next() ) )
34 : : {
35 : : // At the end of each block a jump to ENDIF must be inserted,
36 : : // so that the condition is not evaluated again at ELSEIF.
37 : : // The table collects all jump points.
38 : : #define JMP_TABLE_SIZE 100
39 : : sal_uInt32 pnJmpToEndLbl[JMP_TABLE_SIZE]; // 100 ELSEIFs allowed
40 : 247 : sal_uInt16 iJmp = 0; // current table index
41 : :
42 : : // multiline IF
43 [ + - ]: 247 : nEndLbl = aGen.Gen( _JUMPF, 0 );
44 [ + - ]: 247 : eTok = Peek();
45 [ + - ][ + + ]: 2275 : while( !( eTok == ELSEIF || eTok == ELSE || eTok == ENDIF ) &&
[ + + ][ + - ]
[ + - ][ + + ]
46 [ + - ]: 1014 : !bAbort && Parse() )
47 : : {
48 [ + - ]: 1014 : eTok = Peek();
49 [ - + ]: 1014 : if( IsEof() )
50 : : {
51 [ # # ]: 0 : Error( SbERR_BAD_BLOCK, IF ); bAbort = sal_True; return;
52 : : }
53 : : }
54 [ - + ]: 247 : while( eTok == ELSEIF )
55 : : {
56 : : // jump to ENDIF in case of a successful IF/ELSEIF
57 [ # # ]: 0 : if( iJmp >= JMP_TABLE_SIZE )
58 : : {
59 [ # # ]: 0 : Error( SbERR_PROG_TOO_LARGE ); bAbort = sal_True; return;
60 : : }
61 [ # # ]: 0 : pnJmpToEndLbl[iJmp++] = aGen.Gen( _JUMP, 0 );
62 : :
63 [ # # ]: 0 : Next();
64 [ # # ]: 0 : aGen.BackChain( nEndLbl );
65 : :
66 [ # # ]: 0 : aGen.Statement();
67 [ # # ][ # # ]: 0 : SbiExpression* pCond = new SbiExpression( this );
68 [ # # ]: 0 : pCond->Gen();
69 [ # # ]: 0 : nEndLbl = aGen.Gen( _JUMPF, 0 );
70 [ # # ][ # # ]: 0 : delete pCond;
71 [ # # ]: 0 : TestToken( THEN );
72 [ # # ]: 0 : eTok = Peek();
73 [ # # ][ # # ]: 0 : while( !( eTok == ELSEIF || eTok == ELSE || eTok == ENDIF ) &&
[ # # ][ # # ]
[ # # ][ # # ]
74 [ # # ]: 0 : !bAbort && Parse() )
75 : : {
76 [ # # ]: 0 : eTok = Peek();
77 [ # # ]: 0 : if( IsEof() )
78 : : {
79 [ # # ]: 0 : Error( SbERR_BAD_BLOCK, ELSEIF ); bAbort = sal_True; return;
80 : : }
81 : : }
82 : : }
83 [ + + ]: 247 : if( eTok == ELSE )
84 : : {
85 [ + - ]: 62 : Next();
86 : 62 : sal_uInt32 nElseLbl = nEndLbl;
87 [ + - ]: 62 : nEndLbl = aGen.Gen( _JUMP, 0 );
88 [ + - ]: 62 : aGen.BackChain( nElseLbl );
89 : :
90 [ + - ]: 62 : aGen.Statement();
91 [ + - ]: 62 : StmntBlock( ENDIF );
92 : : }
93 [ + - ]: 185 : else if( eTok == ENDIF )
94 [ + - ]: 185 : Next();
95 : :
96 : :
97 [ - + ]: 247 : while( iJmp > 0 )
98 : : {
99 : 0 : iJmp--;
100 [ # # ]: 0 : aGen.BackChain( pnJmpToEndLbl[iJmp] );
101 : : }
102 : : }
103 : : else
104 : : {
105 : : // single line IF
106 : 2 : bSingleLineIf = true;
107 [ + - ]: 2 : nEndLbl = aGen.Gen( _JUMPF, 0 );
108 [ + - ]: 2 : Push( eCurTok );
109 [ + - ]: 2 : while( !bAbort )
110 : : {
111 [ + - ][ - + ]: 2 : if( !Parse() ) break;
112 [ + - ]: 2 : eTok = Peek();
113 [ + - ][ - + ]: 2 : if( eTok == ELSE || eTok == EOLN || eTok == REM )
[ # # ]
114 : 2 : break;
115 : : }
116 [ - + ]: 2 : if( eTok == ELSE )
117 : : {
118 [ # # ]: 0 : Next();
119 : 0 : sal_uInt32 nElseLbl = nEndLbl;
120 [ # # ]: 0 : nEndLbl = aGen.Gen( _JUMP, 0 );
121 [ # # ]: 0 : aGen.BackChain( nElseLbl );
122 [ # # ]: 0 : while( !bAbort )
123 : : {
124 [ # # ][ # # ]: 0 : if( !Parse() ) break;
125 [ # # ]: 0 : eTok = Peek();
126 [ # # ]: 0 : if( eTok == EOLN )
127 : 0 : break;
128 : : }
129 : : }
130 : 2 : bSingleLineIf = false;
131 : : }
132 [ + - ][ + - ]: 249 : aGen.BackChain( nEndLbl );
[ + - ]
133 : : }
134 : :
135 : : // ELSE/ELSEIF/ENDIF without IF
136 : :
137 : 0 : void SbiParser::NoIf()
138 : : {
139 : 0 : Error( SbERR_NO_IF );
140 : 0 : StmntBlock( ENDIF );
141 : 0 : }
142 : :
143 : : // DO WHILE...LOOP
144 : : // DO ... LOOP WHILE
145 : :
146 : 0 : void SbiParser::DoLoop()
147 : : {
148 : 0 : sal_uInt32 nStartLbl = aGen.GetPC();
149 : 0 : OpenBlock( DO );
150 : 0 : SbiToken eTok = Next();
151 [ # # ]: 0 : if( IsEoln( eTok ) )
152 : : {
153 : : // DO ... LOOP [WHILE|UNTIL expr]
154 : 0 : StmntBlock( LOOP );
155 : 0 : eTok = Next();
156 [ # # ][ # # ]: 0 : if( eTok == UNTIL || eTok == WHILE )
157 : : {
158 [ # # ]: 0 : SbiExpression aExpr( this );
159 [ # # ]: 0 : aExpr.Gen();
160 [ # # ][ # # ]: 0 : aGen.Gen( eTok == UNTIL ? _JUMPF : _JUMPT, nStartLbl );
[ # # ]
161 : : } else
162 [ # # ][ # # ]: 0 : if (eTok == EOLN || eTok == REM)
163 : 0 : aGen.Gen (_JUMP, nStartLbl);
164 : : else
165 : 0 : Error( SbERR_EXPECTED, WHILE );
166 : : }
167 : : else
168 : : {
169 : : // DO [WHILE|UNTIL expr] ... LOOP
170 [ # # ][ # # ]: 0 : if( eTok == UNTIL || eTok == WHILE )
171 : : {
172 [ # # ]: 0 : SbiExpression aCond( this );
173 [ # # ][ # # ]: 0 : aCond.Gen();
174 : : }
175 [ # # ]: 0 : sal_uInt32 nEndLbl = aGen.Gen( eTok == UNTIL ? _JUMPT : _JUMPF, 0 );
176 : 0 : StmntBlock( LOOP );
177 : 0 : TestEoln();
178 : 0 : aGen.Gen( _JUMP, nStartLbl );
179 : 0 : aGen.BackChain( nEndLbl );
180 : : }
181 : 0 : CloseBlock();
182 : 0 : }
183 : :
184 : : // WHILE ... WEND
185 : :
186 : 0 : void SbiParser::While()
187 : : {
188 [ # # ]: 0 : SbiExpression aCond( this );
189 [ # # ]: 0 : sal_uInt32 nStartLbl = aGen.GetPC();
190 [ # # ]: 0 : aCond.Gen();
191 [ # # ]: 0 : sal_uInt32 nEndLbl = aGen.Gen( _JUMPF, 0 );
192 [ # # ]: 0 : StmntBlock( WEND );
193 [ # # ]: 0 : aGen.Gen( _JUMP, nStartLbl );
194 [ # # ][ # # ]: 0 : aGen.BackChain( nEndLbl );
195 : 0 : }
196 : :
197 : : // FOR var = expr TO expr STEP
198 : :
199 : 36 : void SbiParser::For()
200 : : {
201 [ + - ]: 36 : bool bForEach = ( Peek() == EACH );
202 [ - + ]: 36 : if( bForEach )
203 [ # # ]: 0 : Next();
204 [ + - ]: 36 : SbiExpression aLvalue( this, SbOPERAND );
205 [ + - ]: 36 : aLvalue.Gen(); // variable on the Stack
206 : :
207 [ - + ]: 36 : if( bForEach )
208 : : {
209 [ # # ]: 0 : TestToken( _IN_ );
210 [ # # ]: 0 : SbiExpression aCollExpr( this, SbOPERAND );
211 [ # # ]: 0 : aCollExpr.Gen(); // Colletion var to for stack
212 [ # # ]: 0 : TestEoln();
213 [ # # ][ # # ]: 0 : aGen.Gen( _INITFOREACH );
214 : : }
215 : : else
216 : : {
217 [ + - ]: 36 : TestToken( EQ );
218 [ + - ]: 36 : SbiExpression aStartExpr( this );
219 [ + - ]: 36 : aStartExpr.Gen();
220 [ + - ]: 36 : TestToken( TO );
221 [ + - ]: 36 : SbiExpression aStopExpr( this );
222 [ + - ]: 36 : aStopExpr.Gen();
223 [ + - ][ - + ]: 36 : if( Peek() == STEP )
224 : : {
225 [ # # ]: 0 : Next();
226 [ # # ]: 0 : SbiExpression aStepExpr( this );
227 [ # # ][ # # ]: 0 : aStepExpr.Gen();
228 : : }
229 : : else
230 : : {
231 [ + - ]: 36 : SbiExpression aOne( this, 1, SbxINTEGER );
232 [ + - ][ + - ]: 36 : aOne.Gen();
233 : : }
234 [ + - ]: 36 : TestEoln();
235 : : // The stack has all 4 elements now: variable, start, end, increment
236 : : // bind start value
237 [ + - ][ + - ]: 36 : aGen.Gen( _INITFOR );
[ + - ]
238 : : }
239 : :
240 [ + - ]: 36 : sal_uInt32 nLoop = aGen.GetPC();
241 : : // do tests, maybe free the stack
242 [ + - ]: 36 : sal_uInt32 nEndTarget = aGen.Gen( _TESTFOR, 0 );
243 [ + - ]: 36 : OpenBlock( FOR );
244 [ + - ]: 36 : StmntBlock( NEXT );
245 [ + - ]: 36 : aGen.Gen( _NEXT );
246 [ + - ]: 36 : aGen.Gen( _JUMP, nLoop );
247 : : // are there variables after NEXT?
248 [ + - ][ + + ]: 36 : if( Peek() == SYMBOL )
249 : : {
250 [ + - ]: 30 : SbiExpression aVar( this, SbOPERAND );
251 [ + - ][ + - ]: 30 : if( aVar.GetRealVar() != aLvalue.GetRealVar() )
[ - + ]
252 [ # # ][ # # ]: 30 : Error( SbERR_EXPECTED, aLvalue.GetRealVar()->GetName() );
[ # # ][ # # ]
[ + - ]
253 : : }
254 [ + - ]: 36 : aGen.BackChain( nEndTarget );
255 [ + - ][ + - ]: 36 : CloseBlock();
256 : 36 : }
257 : :
258 : : // WITH .. END WITH
259 : :
260 : 0 : void SbiParser::With()
261 : : {
262 [ # # ]: 0 : SbiExpression aVar( this, SbOPERAND );
263 : :
264 [ # # ]: 0 : SbiExprNode *pNode = aVar.GetExprNode()->GetRealNode();
265 [ # # ]: 0 : SbiSymDef* pDef = pNode->GetVar();
266 : : // Variant, from 27.6.1997, #41090: empty -> must be Object
267 [ # # ][ # # ]: 0 : if( pDef->GetType() == SbxVARIANT || pDef->GetType() == SbxEMPTY )
[ # # ]
268 [ # # ]: 0 : pDef->SetType( SbxOBJECT );
269 [ # # ]: 0 : else if( pDef->GetType() != SbxOBJECT )
270 [ # # ]: 0 : Error( SbERR_NEEDS_OBJECT );
271 : :
272 : :
273 : 0 : pNode->SetType( SbxOBJECT );
274 : :
275 [ # # ]: 0 : OpenBlock( NIL, aVar.GetExprNode() );
276 [ # # ]: 0 : StmntBlock( ENDWITH );
277 [ # # ][ # # ]: 0 : CloseBlock();
278 : 0 : }
279 : :
280 : : // LOOP/NEXT/WEND without construct
281 : :
282 : 0 : void SbiParser::BadBlock()
283 : : {
284 [ # # ]: 0 : if( eEndTok )
285 : 0 : Error( SbERR_BAD_BLOCK, eEndTok );
286 : : else
287 : 0 : Error( SbERR_BAD_BLOCK, "Loop/Next/Wend" );
288 : 0 : }
289 : :
290 : : // On expr Goto/Gosub n,n,n...
291 : :
292 : 0 : void SbiParser::OnGoto()
293 : : {
294 [ # # ]: 0 : SbiExpression aCond( this );
295 [ # # ]: 0 : aCond.Gen();
296 [ # # ]: 0 : sal_uInt32 nLabelsTarget = aGen.Gen( _ONJUMP, 0 );
297 [ # # ]: 0 : SbiToken eTok = Next();
298 [ # # ][ # # ]: 0 : if( eTok != GOTO && eTok != GOSUB )
299 : : {
300 [ # # ]: 0 : Error( SbERR_EXPECTED, "GoTo/GoSub" );
301 : 0 : eTok = GOTO;
302 : : }
303 : :
304 : 0 : sal_uInt32 nLbl = 0;
305 [ # # ][ # # ]: 0 : do
[ # # ]
306 : : {
307 [ # # ]: 0 : Next(); // get label
308 [ # # ][ # # ]: 0 : if( MayBeLabel() )
309 : : {
310 [ # # ][ # # ]: 0 : sal_uInt32 nOff = pProc->GetLabels().Reference( aSym );
[ # # ]
311 [ # # ]: 0 : aGen.Gen( _JUMP, nOff );
312 : 0 : nLbl++;
313 : : }
314 [ # # ]: 0 : else Error( SbERR_LABEL_EXPECTED );
315 : : }
316 [ # # ]: 0 : while( !bAbort && TestComma() );
317 [ # # ]: 0 : if( eTok == GOSUB )
318 : 0 : nLbl |= 0x8000;
319 [ # # ][ # # ]: 0 : aGen.Patch( nLabelsTarget, nLbl );
320 : 0 : }
321 : :
322 : : // GOTO/GOSUB
323 : :
324 : 2 : void SbiParser::Goto()
325 : : {
326 [ + - ]: 2 : SbiOpcode eOp = eCurTok == GOTO ? _JUMP : _GOSUB;
327 : 2 : Next();
328 [ + - ]: 2 : if( MayBeLabel() )
329 : : {
330 [ + - ]: 2 : sal_uInt32 nOff = pProc->GetLabels().Reference( aSym );
331 : 2 : aGen.Gen( eOp, nOff );
332 : : }
333 : 0 : else Error( SbERR_LABEL_EXPECTED );
334 : 2 : }
335 : :
336 : : // RETURN [label]
337 : :
338 : 0 : void SbiParser::Return()
339 : : {
340 : 0 : Next();
341 [ # # ]: 0 : if( MayBeLabel() )
342 : : {
343 [ # # ]: 0 : sal_uInt32 nOff = pProc->GetLabels().Reference( aSym );
344 : 0 : aGen.Gen( _RETURN, nOff );
345 : : }
346 : 0 : else aGen.Gen( _RETURN, 0 );
347 : 0 : }
348 : :
349 : : // SELECT CASE
350 : :
351 : 16 : void SbiParser::Select()
352 : : {
353 [ + - ]: 16 : TestToken( CASE );
354 [ + - ]: 16 : SbiExpression aCase( this );
355 : 16 : SbiToken eTok = NIL;
356 [ + - ]: 16 : aCase.Gen();
357 [ + - ]: 16 : aGen.Gen( _CASE );
358 [ + - ]: 16 : TestEoln();
359 : 16 : sal_uInt32 nNextTarget = 0;
360 : 16 : sal_uInt32 nDoneTarget = 0;
361 : 16 : sal_Bool bElse = sal_False;
362 : :
363 [ + - ]: 168 : while( !bAbort )
364 : : {
365 [ + - ]: 168 : eTok = Next();
366 [ + + ]: 168 : if( eTok == CASE )
367 : : {
368 [ + + ]: 152 : if( nNextTarget )
369 [ + - ]: 136 : aGen.BackChain( nNextTarget ), nNextTarget = 0;
370 [ + - ]: 152 : aGen.Statement();
371 : :
372 : 152 : sal_Bool bDone = sal_False;
373 : 152 : sal_uInt32 nTrueTarget = 0;
374 [ + - ][ + + ]: 152 : if( Peek() == ELSE )
375 : : {
376 : : // CASE ELSE
377 [ + - ]: 12 : Next();
378 : 12 : bElse = sal_True;
379 : : }
380 [ + + ]: 288 : else while( !bDone )
381 : : {
382 [ - + ]: 148 : if( bElse )
383 [ # # ]: 0 : Error( SbERR_SYNTAX );
384 [ + - ]: 148 : SbiToken eTok2 = Peek();
385 [ + - ][ + - ]: 148 : if( eTok2 == IS || ( eTok2 >= EQ && eTok2 <= GE ) )
[ - + ]
386 : : { // CASE [IS] operator expr
387 [ # # ]: 0 : if( eTok2 == IS )
388 [ # # ]: 0 : Next();
389 [ # # ]: 0 : eTok2 = Peek();
390 [ # # ][ # # ]: 0 : if( eTok2 < EQ || eTok2 > GE )
391 [ # # ]: 0 : Error( SbERR_SYNTAX );
392 [ # # ]: 0 : else Next();
393 [ # # ]: 0 : SbiExpression aCompare( this );
394 [ # # ]: 0 : aCompare.Gen();
395 : : nTrueTarget = aGen.Gen(
396 : : _CASEIS, nTrueTarget,
397 : : sal::static_int_cast< sal_uInt16 >(
398 [ # # ][ # # ]: 0 : SbxEQ + ( eTok2 - EQ ) ) );
399 : : }
400 : : else
401 : : { // CASE expr | expr TO expr
402 [ + - ]: 148 : SbiExpression aCase1( this );
403 [ + - ]: 148 : aCase1.Gen();
404 [ + - ][ - + ]: 148 : if( Peek() == TO )
405 : : {
406 : : // CASE a TO b
407 [ # # ]: 0 : Next();
408 [ # # ]: 0 : SbiExpression aCase2( this );
409 [ # # ]: 0 : aCase2.Gen();
410 [ # # ][ # # ]: 0 : nTrueTarget = aGen.Gen( _CASETO, nTrueTarget );
411 : : }
412 : : else
413 : : // CASE a
414 [ + - ][ + - ]: 148 : nTrueTarget = aGen.Gen( _CASEIS, nTrueTarget, SbxEQ );
415 : :
416 : : }
417 [ + - ][ + + ]: 148 : if( Peek() == COMMA ) Next();
[ + - ]
418 [ + - ]: 140 : else TestEoln(), bDone = sal_True;
419 : : }
420 : :
421 [ + + ]: 152 : if( !bElse )
422 : : {
423 [ + - ]: 140 : nNextTarget = aGen.Gen( _JUMP, nNextTarget );
424 [ + - ]: 140 : aGen.BackChain( nTrueTarget );
425 : : }
426 : : // build the statement body
427 [ + - ]: 326 : while( !bAbort )
428 : : {
429 [ + - ]: 326 : eTok = Peek();
430 [ + - ][ - + ]: 326 : if( eTok == CASE || eTok == ENDSELECT )
431 : 0 : break;
432 [ + - ][ - + ]: 326 : if( !Parse() ) goto done;
433 [ + - ]: 326 : eTok = Peek();
434 [ + + ][ + + ]: 326 : if( eTok == CASE || eTok == ENDSELECT )
435 : 152 : break;
436 : : }
437 [ + + ]: 152 : if( !bElse )
438 [ + - ]: 140 : nDoneTarget = aGen.Gen( _JUMP, nDoneTarget );
439 : : }
440 [ + - ]: 16 : else if( !IsEoln( eTok ) )
441 : 16 : break;
442 : : }
443 : : done:
444 [ - + ]: 16 : if( eTok != ENDSELECT )
445 [ # # ]: 0 : Error( SbERR_EXPECTED, ENDSELECT );
446 [ + + ]: 16 : if( nNextTarget )
447 [ + - ]: 4 : aGen.BackChain( nNextTarget );
448 [ + - ]: 16 : aGen.BackChain( nDoneTarget );
449 [ + - ][ + - ]: 16 : aGen.Gen( _ENDCASE );
450 : 16 : }
451 : :
452 : : // ON Error/Variable
453 : :
454 : : #ifdef _MSC_VER
455 : : #pragma optimize("",off)
456 : : #endif
457 : :
458 : 14 : void SbiParser::On()
459 : : {
460 [ + - ]: 14 : SbiToken eTok = Peek();
461 [ + - ][ + - ]: 14 : String aString = SbiTokenizer::Symbol(eTok);
462 [ + - ][ + + ]: 14 : if (aString.EqualsIgnoreCaseAscii("ERROR"))
463 : 2 : eTok = _ERROR_; // Error comes as SYMBOL
464 [ + + ][ - + ]: 14 : if( eTok != _ERROR_ && eTok != LOCAL ) OnGoto();
[ # # ]
465 : : else
466 : : {
467 [ + + ][ + - ]: 14 : if( eTok == LOCAL ) Next();
468 [ + - ]: 14 : Next (); // no more TestToken, as there'd be an error otherwise
469 : :
470 [ + - ]: 14 : Next(); // get token after error
471 [ + - ]: 14 : if( eCurTok == GOTO )
472 : : {
473 : : // ON ERROR GOTO label|0
474 [ + - ]: 14 : Next();
475 : 14 : bool bError_ = false;
476 [ + - ][ + - ]: 14 : if( MayBeLabel() )
477 : : {
478 [ - + ][ # # ]: 14 : if( eCurTok == NUMBER && !nVal )
479 [ # # ]: 0 : aGen.Gen( _STDERROR );
480 : : else
481 : : {
482 [ + - ][ + - ]: 14 : sal_uInt32 nOff = pProc->GetLabels().Reference( aSym );
[ + - ]
483 [ + - ]: 14 : aGen.Gen( _ERRHDL, nOff );
484 : : }
485 : : }
486 [ # # ]: 0 : else if( eCurTok == MINUS )
487 : : {
488 [ # # ]: 0 : Next();
489 [ # # ][ # # ]: 0 : if( eCurTok == NUMBER && nVal == 1 )
490 [ # # ]: 0 : aGen.Gen( _STDERROR );
491 : : else
492 : 0 : bError_ = true;
493 : : }
494 [ - + ]: 14 : if( bError_ )
495 [ # # ]: 0 : Error( SbERR_LABEL_EXPECTED );
496 : : }
497 [ # # ]: 0 : else if( eCurTok == RESUME )
498 : : {
499 [ # # ]: 0 : TestToken( NEXT );
500 [ # # ]: 0 : aGen.Gen( _NOERROR );
501 : : }
502 [ # # ]: 0 : else Error( SbERR_EXPECTED, "GoTo/Resume" );
503 [ + - ]: 14 : }
504 : 14 : }
505 : :
506 : : #ifdef _MSC_VER
507 : : #pragma optimize("",off)
508 : : #endif
509 : :
510 : : // RESUME [0]|NEXT|label
511 : :
512 : 0 : void SbiParser::Resume()
513 : : {
514 : : sal_uInt32 nLbl;
515 : :
516 [ # # # # : 0 : switch( Next() )
# ]
517 : : {
518 : : case EOS:
519 : : case EOLN:
520 : 0 : aGen.Gen( _RESUME, 0 );
521 : 0 : break;
522 : : case NEXT:
523 : 0 : aGen.Gen( _RESUME, 1 );
524 : 0 : Next();
525 : 0 : break;
526 : : case NUMBER:
527 [ # # ]: 0 : if( !nVal )
528 : : {
529 : 0 : aGen.Gen( _RESUME, 0 );
530 : 0 : break;
531 : : } // fall thru
532 : : case SYMBOL:
533 [ # # ]: 0 : if( MayBeLabel() )
534 : : {
535 [ # # ]: 0 : nLbl = pProc->GetLabels().Reference( aSym );
536 : 0 : aGen.Gen( _RESUME, nLbl );
537 : 0 : Next();
538 : 0 : break;
539 : : } // fall thru
540 : : default:
541 : 0 : Error( SbERR_LABEL_EXPECTED );
542 : : }
543 : 0 : }
544 : :
545 : : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|