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: vars 07.11.06 0.0.A.
11 *
12 * Author: Alexander Krivonogov ( algen )
13 *
14 * Summary: Функции для работы с локальными переменными
15 *
16 ******************************************************************************/
17
18 #include "func.h"
19 #include "bcodes.h"
20
21 /*-----------------------------------------------------------------------------
22 *
23 * ID: create_varmode 07.11.06 0.0.A.
24 *
25 * Summary: Добавление описания переменной, параметра в байткод функции
26 *
27 -----------------------------------------------------------------------------*/
28 STDCALL create_varmode( pbuf out, ps_desctype desctype, ps_descid descid )
29 {
30 byte flags = 0; //Значение для поля flags
31 uint off_flags; //Смещение поля с flags
32 uint i;
33
34 off_flags = out->use + sizeof( uint );
35 if ( desctype )
36 {
37 buf_appenduint( out, desctype->idtype );
38 buf_appendch( out, 0 );
39 if ( desctype->oftype )
40 {
41 buf_appenduint( out, desctype->oftype );
42 flags |= VAR_OFTYPE;
43 }
44 }
45 else
46 {
47 buf_appenduint( out, descid->idtype );
48 buf_appendch( out, 0 );
49 if ( descid->flgdesc & DESCID_PAR )
50 flags |= VAR_PARAM;
51 if ( descid->flgdesc & DESCID_PAR || descid->idtype == TReserved )
52 {
53 if ( descid->oftype )
54 {
55 buf_appenduint( out, descid->oftype );
56 flags |= VAR_OFTYPE;
57 }
58 if ( descid->msr )
59 {
60 buf_appendch( out, (byte)(descid->msr) );
61 flags |= VAR_DIM;
62 for ( i = 0; i < descid->msr; i++ )
63 {
64 buf_appenduint( out, descid->msrs[i] );
65 }
66 }
67 }
68 if ( _compile->flag & CMPL_DEBUG && descid->name )
69 {
70 flags |= VAR_NAME;
71 buf_append( out, descid->name , mem_len( descid->name ) + 1 );
72 }
73 }
74 *(byte *)( out->data + off_flags ) = flags;
75 }
76
77
78 /*-----------------------------------------------------------------------------
79 *
80 * ID: var_add 07.11.06 0.0.A.
81 *
82 * Summary: Добавление локальной переменной в таблицу
83 *
84 -----------------------------------------------------------------------------*/
85 uint STDCALL var_add( phashiuint hidn, ps_descid descvar )
86 {
87 pfvar cvar;
88
89 buf_expand( &fd.bvars, sizeof( fvar ));
90 cvar = (pfvar)(fd.bvars.data + fd.bvars.use);
91 fd.bvars.use += sizeof( fvar );
92
93 cvar->hidn = hidn;
94 cvar->type = descvar->idtype;
95 cvar->oftype = descvar->oftype;
96 cvar->msr = descvar->msr;
97 cvar->num = fd.varcount;
98 cvar->flg = 0;
99 cvar->oldoffbvar = 0;
100
101 if ( ( descvar->flgdesc & DESCID_VAR || ( descvar->flgdesc == DESCID_PARSUBFUNC )) &&
102 !fd.curcount )
103 { //Формируем загрузку нового блока
104 if ( descvar->flgdesc == DESCID_VAR )
105 {
106 buf_appenduint( &fd.bblinit, CVarsInit );
107 buf_appenduint( &fd.bblinit, fd.blcount );
108 }
109 fd.blcount++;
110 if ( fd.lastcurcount )
111 { //Закрытие блока данных
112 buf_appenduint( &fd.bhead, fd.lastcurcount );
113 fd.lastcurcount = 0;
114 }
115 }
116
117 if ( descvar->flgdesc != DESCID_SUBFUNC )
118 {
119 //Добавляем в заголовок функции
120 create_varmode( descvar->flgdesc == DESCID_PARFUNC ? &fd.bhead : &fd.bvardef, 0, descvar );
121 fd.curcount++;
122 return fd.varcount++;
123 }
124 return 0;
125 }
126
127 /*-----------------------------------------------------------------------------
128 *
129 * ID: var_addtmp 07.11.06 0.0.A.
130 *
131 * Summary: Добавить локальную переменную не имеющую имени
132 *
133 -----------------------------------------------------------------------------*/
134 uint STDCALL var_addtmp( uint type, uint oftype )
135 {
136 s_descid descvar;
137 descvar.oftype = oftype;
138 descvar.idtype = type;
139 descvar.flgdesc = DESCID_VAR;
140 descvar.name = 0;
141 return var_add( 0, &descvar );
142 }
143
144 /*-----------------------------------------------------------------------------
145 *
146 * ID: var_checkadd 07.11.06 0.0.A.
147 *
148 * Summary: Проверка локальной переменной на наличие и добавление в таблицу
149 *
150 -----------------------------------------------------------------------------*/
151 uint STDCALL var_checkadd( ps_descid descvar )
152 {
153 uint oldoffbvar; // Предыдущее смещение локальной переменной
154 uint offbvar; // Смещение локальной переменной в таблице
155 uint num; // Номер локальной переменной
156 pfvar var; // Указатель на структуру локальной переменной
157 phashiuint phitem;//Элемент хэштаблицы с локальной переменной
158 //Поиск в таблице имён если нет добавляем
159 phitem = (phashiuint)hash_create( &fd.nvars, descvar->name);
160
161 //Получение номера переменной если есть
162 oldoffbvar = phitem->val;
163
164 //Если переменная есть и она в текущем блоке, то ошибка
165 if ( oldoffbvar && oldoffbvar >= fd.oldoffbvar )
166 msg( MDblname | MSG_LEXNAMEERR, descvar->lex );//Ошибка Идентификатор с таким именем уже есть
167
168 //Запись в таблицу смещения новой переменной
169 phitem->val = offbvar = fd.bvars.use;
170
171 //Вызов функции добавления
172 num = var_add( phitem, descvar );
173
174 //Запись дополнительной информации
175 var = ( pfvar )( fd.bvars.data + offbvar );
176 if ( oldoffbvar )
177 {
178 var->oldoffbvar = oldoffbvar;
179 }
180 return num;
181 }
182
183 /*-----------------------------------------------------------------------------
184 *
185 * ID: var_def 07.11.06 0.0.A.
186 *
187 * Summary: Обработка описаний локальных переменных, параметров функции
188 *
189 -----------------------------------------------------------------------------*/
190 plexem STDCALL var_def( plexem curlex, uint flgdesc )
191 {
192 s_descid descvar;
193
194 descvar.flgdesc = flgdesc;
195 descvar.idtype = 0;
196 while ( 1 )
197 {
198 curlex = desc_nextidvar( curlex, &descvar );
199 if ( !descvar.idtype ) break;
200 }
201 return curlex;
202 }
Редактировать