1 /******************************************************************************
2 *
3 * Copyright (C) 2006, The Gentee Group. All rights reserved.
4 * This file is part of the Gentee open source project - http://www.gentee.com.
5 *
6 * THIS FILE IS PROVIDED UNDER THE TERMS OF THE GENTEE LICENSE ("AGREEMENT").
7 * ANY USE, REPRODUCTION OR DISTRIBUTION OF THIS FILE CONSTITUTES RECIPIENTS
8 * ACCEPTANCE OF THE AGREEMENT.
9 *
10 * ID: if 08.02.07 0.0.A.
11 *
12 * Author: Alexander Krivonogov ( algen )
13 *
14 * Summary: Конструкция if-elif-else
15 *
16 ******************************************************************************/
17
18 #include "func.h"
19
20 /*-----------------------------------------------------------------------------
21 *
22 * ID: c_if 08.02.07 0.0.A.
23 *
24 * Summary: The if-elif-else processing
25 *
26 -----------------------------------------------------------------------------*/
27 plexem STDCALL c_if( plexem curlex )
28 {
29 uint jmpnext; //Смещение в стэке меток - переход к следующему elif, else
30 uint jmpend; //Смещение в стэке меток - переход к концу
31 uint labend; //Смещение в стэке меток - метка конца
32
33 D( "If start" );
34 jmpend = -1;
35
36 while ( 1 )
37 {
38 //Обработка логического выражения
39 curlex = f_expr( curlex, EXPR_BOOL, 0, 0 );
40 //Добавляем переход на следующий
41 jmpnext = j_jump( CIfze, LABT_GTVIRT, -1 );
42 //Обработка тела
43 curlex = f_body( curlex );
44
45 curlex = lexem_next( curlex, LEXNEXT_IGNLINE );
46 if ( curlex->type == LEXEM_KEYWORD &&
47 ( curlex->key == KEY_ELIF ||
48 curlex->key == KEY_ELSE ))
49 {
50 //Добавляем переход на конец
51 jmpend = j_jump( CGoto, LABT_GTVIRT, jmpend );
52
53 //Добавляем метку на следующий, устанавливаем связь с последним переходом
54 ((pflabel)( fd.blabels.data + jmpnext ))->link = j_label( LABT_LABELVIRT, -1);
55 jmpnext = -1;
56 if ( curlex->key == KEY_ELIF )
57 {
58 D( "Elif start\n" );
59 curlex = lexem_next( curlex, 0 );
60 continue;
61 }
62 D( "Else start\n" );
63 curlex = f_body( lexem_next( curlex, LEXNEXT_IGNLINE ) );
64 curlex = lexem_next( curlex, LEXNEXT_IGNLINE );
65 break;
66 }
67 break;
68 }
69 //Добавляем метку на последний
70 labend = j_label( LABT_LABELVIRT, -1 );
71
72 //Корректируем все переходы на конец
73 j_correct( jmpend, labend );
74
75 //Корректировка, если нет else
76 if ( jmpnext != -1 )
77 ((pflabel)( fd.blabels.data + jmpnext ))->link = labend;
78
79 D( "If stop\n" );
80 return curlex;
81 }
82
83