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: while 09.02.07 0.0.A.
11 *
12 * Author: Alexander Krivonogov ( algen )
13 *
14 * Summary: The while and do-while statements
15 *
16 ******************************************************************************/
17
18 #include "func.h"
19
20 /*-----------------------------------------------------------------------------
21 *
22 * ID: c_while 09.02.07 0.0.A.
23 *
24 * Summary: The while processing
25 *
26 -----------------------------------------------------------------------------*/
27 plexem STDCALL c_while( plexem curlex )
28 {
29 uint labbeg; //Метка начало
30 uint labend; //Метка конец
31 uint offlcbreak; //Смещение в таблице меток
32 uint offlccontinue; //Смещение в таблице меток
33
34 fd.blcycle++;
35 D( "While start\n" );
36 //Добавляем метку на начало
37 labbeg = j_label( LABT_LABELVIRT, -1 );
38
39 //Обработка логического выражения
40 curlex = f_expr( curlex, EXPR_BOOL, 0, 0 );
41
42 //Сохраняем последние метки цикла
43 offlcbreak = fd.offlcbreak;
44 offlccontinue = fd.offlccontinue;
45
46 //Добавляем переход на конец
47 fd.offlcbreak = j_jump( CIfze, LABT_GTVIRT, -1);
48 fd.offlccontinue = -1;
49
50 //Обработка тела
51 curlex = f_body( curlex );
52
53 //Добавляем переход на начало
54 j_jump( CGoto, LABT_GTVIRT, labbeg );
55
56 //Добавляем метку на конец
57 labend = j_label( LABT_LABELVIRT, -1 );
58
59 //Цикл установки переходов на конец
60 j_correct( fd.offlcbreak, labend );
61
62 //Цикл установки переходов на начало
63 j_correct( fd.offlccontinue, labbeg );
64
65 //Восстановление меток цикла
66 fd.offlcbreak = offlcbreak;
67 fd.offlccontinue = offlccontinue;
68 fd.blcycle--;
69 D( "While stop\n" );
70 return curlex;
71 }
72
73 /*-----------------------------------------------------------------------------
74 *
75 * ID: c_dowhile 09.02.07 0.0.A.
76 *
77 * Summary: <do_while> processing
78 *
79 -----------------------------------------------------------------------------*/
80 plexem STDCALL c_dowhile( plexem curlex )
81 {
82 uint labbeg; //Метка начало
83 uint labend; //Метка конец
84 uint labcont; //Метка продолжить
85 uint fd_offlcbreak; //Смещение в таблице меток
86 uint fd_offlccontinue; //Смещение в таблице меток
87
88 D( "DoWhile start\n" );
89 fd.blcycle++;
90 //Добавляем метку на начало
91 labbeg = j_label( LABT_LABELVIRT, -1 );
92
93 //Сохраняем последние метки цикла
94 fd_offlcbreak = fd.offlcbreak;
95 fd_offlccontinue = fd.offlccontinue;
96
97 //Добавляем переход на конец
98 fd.offlcbreak = -1;
99 fd.offlccontinue = -1;
100
101 //Обработка тела
102 curlex = f_body( curlex );
103
104 //Проверка ключевого слова while
105 curlex = lexem_next( curlex, LEXNEXT_IGNLINE );
106 if ( curlex->type != LEXEM_KEYWORD || curlex->key != KEY_WHILE )
107 msg( MExpwhile | MSG_LEXERR, curlex );
108 curlex = lexem_next( curlex, 0 );
109 //Добавляем метку на продолжить
110 labcont = j_label( LABT_LABELVIRT, -1 );
111
112 //Обработка логического выражения
113 curlex = f_expr( curlex, EXPR_BOOL, 0, 0);
114 //Добавляем переход на начало
115 j_jump( CIfnze, LABT_GTVIRT, labbeg );
116
117 //Добавляем метку на конец
118 labend = j_label( LABT_LABELVIRT, -1 );
119
120 //Цикл установки переходов на конец
121 j_correct( fd.offlcbreak, labend );
122
123 //Цикл установки переходов на продолжить
124 j_correct( fd.offlccontinue, labcont );
125
126 //Восстановление меток цикла
127 fd.offlcbreak = fd_offlcbreak;
128 fd.offlccontinue = fd_offlccontinue;
129 fd.blcycle--;
130 D( "DoWhile stop\n" );
131 return curlex;
132 }