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