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: desc 03.11.06 0.0.A.
11 *
12 * Author: Alexander Krivonogov ( algen )
13 *
14 * Summary: Обработка описаний переменных, параметров, приведений типов
15 *
16 ******************************************************************************/
17
18
19 #include "func.h"
20 #include "macroexp.h"
21
22 /*-----------------------------------------------------------------------------
23 *
24 * ID: desc_nextidvar 03.11.06 0.0.A.
25 *
26 * Summary: Обработка следующей переменной, параметра, поля структуры
27 *
28 -----------------------------------------------------------------------------*/
29 plexem STDCALL desc_nextidvar( plexem curlex, ps_descid descid )
30 {
31 //uint flgnextlex;//Игнорировать переносы
32 uint type; //Тип текущей переменной
33 pmacrores mr; //Результат обработки макровыражения
34 uint msrtype; //Тип текущей размерности
35 uint stkparsc[ MAX_MSR * 2 ];//Стэк для заполнения размерностей TReserved
36 puint parsc; //Текущий указатель в стэке размерностей
37 plexem beglex; //Лексема с именем идентификатора
38 plexem skiplex; //Текущая лексема для пропуска
39
40 D( "Nextidvar start\n" );
41 //flgnextlex = 0;
42 //if ( descid->flgdesc & DESCID_PAR )
43 // flgnextlex = LEXNEXT_IGNLINE;
44 if ( curlex->type == LEXEM_OPER &&
45 curlex->oper.operid == OpComma )
46 {
47 if ( descid->idtype )
48 {
49 curlex = lexem_next( curlex, LEXNEXT_IGNLINE );
50 if (descid->flgdesc & DESCID_PARFUNC)
51 {
52 descid->idtype = 0;
53 }
54 }
55 }
56
57 if ( !( descid->flgdesc & DESCID_VAR ) &&
58 curlex->type == LEXEM_OPER && curlex->oper.operid == OpLine )
59 {
60 descid->idtype = 0;
61 curlex = lexem_next( curlex, LEXNEXT_SKIPLINE );
62 }
63 //Определяем тип идентификатора
64 if ( curlex->type != LEXEM_NAME )
65 { //Идентификаторов больше нет
66 descid->idtype = 0;
67 return curlex;
68 }
69 type = bc_type( curlex );
70 if ( descid->idtype && type )
71 { //Указан новый тип
72 descid->idtype = 0;
73 }
74
75 if ( !descid->idtype )
76 { //Получаем новый тип
77 if ( !type || curlex->flag & LEXF_CALL )
78 {
79 if ( descid->flgdesc & DESCID_PARFUNC &&
80 curlex->type == LEXEM_NAME )
81 msg( MExptype | MSG_LEXERR, curlex );//Ожидается имя типа
82 return curlex;
83 }
84 descid->idtype = type;
85 curlex = lexem_next( curlex, 0/*flgnextlex*/ );
86 }
87 //Получаем идентификатор
88
89 if ( curlex->type != LEXEM_NAME )
90 msg( MExpname | MSG_LEXERR, curlex );//Ожидается идентификатор
91
92 beglex = curlex;
93 descid->name = lexem_getname( curlex );
94 descid->lex = curlex;
95 descid->msr = 0;
96 descid->oftype = 0;
97 descid->lexres = 0;
98
99 //Обработка размерностей
100 if ( curlex->flag & LEXF_ARR )
101 {
102 if ( descid->flgdesc == DESCID_VAR && descid->idtype != TReserved )
103 { // Если не тип Reserved то начальная загрузка
104 parsc = stkparsc;
105 out_add2uint( CVarload, fd.varcount );
106 *(parsc++) = type;
107 *(parsc++) = 0;
108 }
109 curlex = lexem_next( curlex, 0/*flgnextlex*/ );
110
111 while ( 1 ) //цикл по размерностям
112 {
113 curlex = lexem_next( curlex, LEXNEXT_IGNLINE );
114 if ( !( descid->flgdesc & DESCID_PAR ))
115 { //может быть число, выражение
116 if ( descid->flgdesc == DESCID_VAR && descid->idtype != TReserved )
117 {
118 //Обработка выражения
119 curlex = f_expr( curlex, EXPR_ARR | EXPR_COMMA, &msrtype, 0 );
120 *(parsc++) = msrtype;
121 *(parsc++) = 0;
122 }
123 else
124 {
125 //Обработка макровыражения/числа
126 curlex = macroexpr( curlex, &mr );
127 if ( mr->vallexem.type = LEXEM_NUMBER &&
128 mr->vallexem.num.type == TUint )
129 {
130 descid->msrs[descid->msr] = mr->vallexem.num.vint;
131 }
132 else
133 msg( MExpuint | MSG_LEXERR, curlex );
134 }
135 }
136 descid->msr++;
137 if ( curlex->type == LEXEM_OPER )
138 {
139 if ( curlex->oper.operid == OpComma )
140 {
141 continue;
142 }
143 if ( curlex->oper.operid == OpRsqbrack )
144 {
145 break;
146 }
147 }
148 msg( MExpcomma | MSG_LEXERR, curlex );
149 }
150 }
151
152 curlex = lexem_next( curlex, 0/*flgnextlex*/ );
153
154 //Обработка of
155 if ( curlex->type == LEXEM_KEYWORD &&
156 curlex->key == KEY_OF )
157 {
158 if ( (( povmtype)PCMD( type ))->index.type )
159 msg( 0 | MSG_LEXERR, curlex );
160 curlex = lexem_next( curlex, LEXNEXT_IGNLINE );
161 descid->oftype = bc_type( curlex );
162 if ( !descid->oftype )
163 msg( MExptype | MSG_LEXERR, curlex );//Должен быть указан тип после of
164 curlex = lexem_next( curlex, 0 );
165 }
166
167 //Конечная обработка
168 switch ( descid->flgdesc )
169 {
170 case DESCID_GLOBAL:
171 case DESCID_TYPE:
172 if ( curlex->type == LEXEM_OPER &&
173 curlex->oper.operid == OpSet )
174 {
175 curlex = lexem_next( curlex, LEXNEXT_IGNLINE );
176 curlex = macroexpr( curlex, &mr );
177 descid->lexres = &mr->vallexem;
178 }
179 //curlex = lexem_next( curlex, LEXNEXT_SKIPLINE );
180 break;
181 case DESCID_VAR:
182 if ( descid->idtype != TReserved )
183 {
184 if ( descid->oftype )
185 {
186 out_adduints( 5, CVarload, fd.varcount, CCmdload, descid->oftype,
187 bc_find( curlex, "@oftype", 2, descid->idtype, TUint ) );
188 }
189 if ( descid->msr )
190 out_adduint(
191 bc_funcname( curlex, "@array", descid->msr+1, stkparsc )->vmo.id );
192
193 }
194 var_checkadd( descid );
195 if ( ( curlex->type == LEXEM_OPER &&
196 curlex->oper.operid == OpSet ) ||
197 ( curlex->type == LEXEM_KEYWORD &&
198 curlex->key == KEY_AS ))
199 {
200 //Удаление из обработки описания массива
201 for( skiplex = curlex + 1; skiplex < curlex; skiplex++ )
202 skiplex->type = LEXEM_SKIP;
203 curlex = f_expr( beglex, EXPR_COMMA, 0, 0 );
204 }
205 //Обработка выражения
206 break;
207 case DESCID_PARFUNC:
208 case DESCID_PARSUBFUNC:
209 var_checkadd( descid );
210 break;
211 }
212
213 /*if ( curlex->type == LEXEM_OPER &&
214 curlex->oper.operid == OpComma )
215 curlex = lexem_next( curlex, LEXNEXT_IGNLINE ); */
216 D( "Nextidvar stop\n" );
217 return curlex;
218 }
219
220
221 /*-----------------------------------------------------------------------------
222 *
223 * ID: desc_idtype 03.11.06 0.0.A.
224 *
225 * Summary: Обработка описания типа
226 *
227 -----------------------------------------------------------------------------*/
228 plexem STDCALL desc_idtype( plexem curlex, ps_desctype desctype)
229 {
230 D( "type start\n" );
231 desctype->idtype = bc_type( curlex );
232 desctype->msr = 0;
233 desctype->oftype = 0;
234
235 if ( desctype->idtype )
236 {
237 curlex = lexem_next( curlex, 0 );
238
239 if ( curlex->type == LEXEM_OPER &&
240 curlex->oper.operid == OpLsqbrack ) //Обработка размерностей []
241 { //Данный код нужен для совместимости со старой версией
242 while ( 1 ) //цикл по размерностям
243 {
244 curlex = lexem_next( curlex, LEXNEXT_IGNLINE );
245 desctype->msr++;
246 if ( curlex->type == LEXEM_OPER )
247 {
248 if ( curlex->oper.operid == OpComma )
249 {
250 continue;
251 }
252 if ( curlex->oper.operid == OpRsqbrack )
253 {
254 curlex = lexem_next( curlex, 0 );
255 break;
256 }
257 }
258 if ( desctype->msr > 2 )
259 msg( MExpcomma | MSG_LEXERR, curlex );
260 else
261 {
262 return curlex - 1;
263 }
264 }
265 }
266
267 if ( curlex->type == LEXEM_KEYWORD &&
268 curlex->key == KEY_OF )//Обработка типа элемента of
269 {
270 curlex = lexem_next( curlex, LEXNEXT_IGNLINE );
271 desctype->oftype = bc_type( curlex );
272 if ( !desctype->oftype )
273 msg( MExptype | MSG_LEXERR, curlex );
274 curlex = lexem_next( curlex, 0 );
275 }
276 }
277 D( "type stop\n" );
278 return curlex;
279 }
280