EnglishРусский  

   ..

   alias.c

   alias.h

   bcodes.c

   bcodes.h

   body.c

   compile.c

   compile.h

   define.c

   define.h

   desc.c

   expr.c

   extern.c

   for.c

   foreach.c

   func.c

   func.h

   global.c

   global.h

   goto.c

   if.c

   ifdef.c

   ifdef.h

   import.c

   import.h

   include.c

   include.h

   jump.c

   lexem.c

   lexem.h

   macro.c

   macro.h

   operlist.txt

   out.c

   out.h

   subfunc.c

   switch.c

   type.c

   type.h

   vars.c

   while.c

   with.c

Реклама

Инсталлятор CreateInstall
Бесплатные и коммерческие инсталляторы

source\src\compiler\foreach.c
  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: foreach 09.02.07 0.0.A.
 11 *
 12 * Author: Alexander Krivonogov ( algen )
 13 *
 14 * Summary: The foreach statement
 15 *
 16 ******************************************************************************/
 17 
 18 #include "func.h"
 19 #include "bcodes.h"
 20 
 21 /*-----------------------------------------------------------------------------
 22 *
 23 * ID: c_foreach 08.02.07 0.0.A.
 24 *
 25 * Summary: The foreach processing
 26 *
 27 -----------------------------------------------------------------------------*/
 28 plexem STDCALL c_foreach( plexem curlex )
 29 {
 30    uint       labbeg;           //Метка начало
 31    uint       labend;           //Метка конец
 32    uint       labcont;          //Метка на continue
 33    uint       fd_offlcbreak;    //Смещение в таблице меток
 34    uint       fd_offlccontinue; //Смещение в таблице меток
 35    uint       indexnum;         //Номер/код переменной индекса
 36    uint       objnum;           //Номер дополнительной переменной хранящей объект
 37    uint       fordata;          //Номер переменной со структурой fordata
 38 
 39    plexem     indexlex;      //Лексема с описанной переменной
 40 
 41    uint       objtype;       //Тип объекта   
 42    uint       itemtype;      //Тип элемента
 43    uint       deftype;       //Описанный тип элемента
 44    uint       vartype;
 45 
 46    uint       bcfirst;       //Байт-код метода First
 47    uint       bceof;         //Байт-код метода Eof
 48    uint       bcnext;        //Байт-код метода Next
 49    //uint       bcset;         //Байт-код присваивания значения
 50    uint       bcadvget;      //Байт-код для дополнительного кода присваивания
 51    uint       bcadvset;      //Байт-код для дополнительного кода присваивания
 52 
 53    pfvar      var;          //Указатель на структуру локальной переменной
 54    pfvaras    varas;        //Указатель на структуру as
 55    phashiuint phitem;       //Элемент хэштаблицы с локальной переменной
 56    pubyte     varname;      //Имя локальной переменной
 57    uint       flgnewvar;    //Флаг добавлять новую локальную переменную с индекском
 58    s_descid   descvar;      //Структура для описания локальной переменной
 59    uint       offvar;       //Смещение структуры локальной переменной
 60 
 61    //pvmfunc    pfunc;    //Указатель на структуру операции
 62    //uint       parsc[4]; //Параметры для получения кода операции
 63 
 64 D( "Foreach start\n" );
 65    fd.blcycle++;
 66 
 67    //Обработка индекса цикла
 68    
 69    if ( curlex->type != LEXEM_NAME )
 70       msg( MExpname | MSG_LEXERR, curlex );
 71    vartype = bc_type( curlex );   
 72    if ( vartype )
 73    {
 74       curlex = lexem_next( curlex, LEXNEXT_IGNLINE );
 75    }
 76    if ( curlex->type != LEXEM_NAME )
 77       msg( MExpname | MSG_LEXERR, curlex );
 78    
 79    indexlex = curlex;
 80 
 81    //Существует ли локальная переменная
 82    phitem = (phashiuint)hash_find( &fd.nvars, lexem_getname( curlex ) );
 83    //flgnewvar = 1;
 84    if ( phitem && phitem->val &&
 85         !(( var = (pfvar)( fd.bvars.data + ( offvar = phitem->val )))->flg & FVAR_SUBFUNC))
 86    {  //Идентификатор есть в таблице локальных переменных
 87       flgnewvar = 0;
 88       indexnum = var->num;        
 89    }
 90    else
 91    {
 92       flgnewvar = 1;      
 93       varname = lexem_getname( curlex );
 94    }
 95    curlex = lexem_next( curlex, LEXNEXT_IGNLINE );
 96    if ( curlex->type != LEXEM_OPER || curlex->oper.operid != OpComma )
 97       msg( MExpcomma | MSG_LEXERR, curlex );
 98    curlex = lexem_next( curlex, LEXNEXT_IGNLINE );
 99 
100    //Обработка выражения-объекта
101    objnum = var_addtmp( TUint, 0 ); //Создание переменной для хранения адреса объекта
102    out_add2uint( CVarptrload, objnum );//Байт код для сохранения результата выражения
103    curlex = f_expr( curlex, EXPR_NONULL, &objtype, &itemtype );
104    if ( !itemtype )
105    {
106       /*if ( ! (itemtype = (( povmtype)PCMD( objtype ))->index.type ))
107          itemtype = TUint;*/
108       itemtype = (( povmtype)PCMD( objtype ))->index.type;
109       
110    }   
111    out_adduint( CSetI );//Байт код загрузки значения
112    //Получаем байт-коды методов
113    bcfirst = bc_find( indexlex, "@first", 2, objtype, TAny );
114    bceof   = bc_find( indexlex, "@eof", 2, objtype, TAny );
115    bcnext  = bc_find( indexlex, "@next", 2, objtype, TAny );
116 
117 
118    if ( (( pvmfunc)PCMD( bcfirst ))->ret->type != TUint )
119    {
120       itemtype = (( pvmfunc)PCMD( bcfirst ))->ret->type;
121       deftype = TUint;
122       /*if ( !(itemtype = (( pvmfunc)PCMD( bcfirst ))->ret->type ))
123       {
124          itemtype = TUint;
125       }*/
126    }
127    fordata = var_addtmp((( pvmfunc)PCMD( bcfirst ))->params[1].type , 0 );   
128 
129    //Уточнение типов
130    if ( (( pvmobj )PCMD( itemtype ))->flag & GHTY_STACK )
131    {//Базовый тип элемента, приводим указатель к значению
132     //Предполагается что first/next могут возвращать только указатели
133       //Заполнение полей фиктивной лексемы
134       /*parsc[0] = itemtype;
135       parsc[1] = 0;
136       parsc[2] = itemtype;
137       parsc[3] = 0;
138       pfunc = bc_funcname( curlex, "#=", 2, parsc );*/
139       //bcset = CSetI;            
140       bcadvget = artypes[ itemtype ];
141       bcadvset = (( povmtype )PCMD( itemtype ))->stsize == 1 ? CSetI : CSetL;
142       deftype = itemtype;
143    }
144    else
145    {  //Тип элемента структура      
146       //bcset = CSetI;
147       bcadvget = 0;
148       deftype = TUint;
149    }   
150    if ( flgnewvar )
151    {  //Создание новой локальной переменной-индекса
152       mem_zero( &descvar, sizeof( descvar ));
153       descvar.idtype = deftype;
154       descvar.name = varname;
155       descvar.lex = curlex;
156       descvar.flgdesc = DESCID_VAR;
157       offvar = fd.bvars.use;
158       indexnum = var_checkadd( &descvar );   
159    }
160    var = (( pfvar )( fd.bvars.data + offvar ));
161    if ( deftype != ( var->flg & FVAR_UINTAS ? TUint : var->type ) ||
162         ( vartype && vartype != itemtype ) )
163       msg( MDiftypes | MSG_LEXERR, indexlex );
164    if ( !((( pvmobj )PCMD( itemtype ))->flag & GHTY_STACK) ||
165         var->flg & FVAR_UINTAS )
166    {
167       varas = ( pfvaras )buf_appendtype( &fd.bvarsas, sizeof( fvaras ) );
168 
169       varas->offbvar = offvar;
170       varas->type = var->type;
171       varas->oftype = var->oftype; 
172       varas->flg = var->flg; 
173       
174       var->type = itemtype;
175       var->oftype = 0;
176       var->flg |= FVAR_UINTAS;      
177    }
178 
179    //Добавляем вызов first
180    out_adduints( 8, CVarptrload,
181                   indexnum,
182                   CVarload,
183                   objnum,
184                   CVarload,
185                   fordata,
186                   bcfirst,
187                   /*bcset*/CSetI );
188 
189    //Добавляем метку на начало
190    labbeg = j_label( LABT_LABELVIRT, -1 );
191 
192    out_debugtrace( curlex );
193 
194    //Вызов метода Eof
195    //Обработка логического выражения
196    out_adduints( 5, CVarload,
197                   objnum,
198                   CVarload,
199                   fordata,
200                   bceof );
201 
202    //Сохраняем последние метки цикла
203    fd_offlcbreak = fd.offlcbreak;
204    fd_offlccontinue = fd.offlccontinue;
205 
206    //Добавляем переход на конец
207    fd.offlcbreak = j_jump( CIfnze, LABT_GTVIRT, -1);
208    fd.offlccontinue = -1;
209 
210    if ( bcadvget )
211    {
212       //Коррекция для базовых типов
213       out_adduints( 7, CVarptrload,
214                      indexnum,
215                      CVarptrload,
216                      indexnum,
217                      CGetI,
218                      bcadvget,
219                      bcadvset );
220       /*out_adduints( 6, CVarptrload,
221                      indexnum,
222                      CVarload,
223                      indexnum,
224                      bcadvget,
225                      bcset );*/
226    }
227 
228    //Обработка тела
229    curlex = f_body( curlex );
230 
231    //Метка на continue
232    labcont = j_label( LABT_LABELVIRT, -1 );
233 
234    //Вызов метода Next
235    out_adduints( 8, CVarptrload,
236                   indexnum,
237                   CVarload,
238                   objnum,
239                   CVarload,
240                   fordata,
241                   bcnext,                  
242                   /*bcset*/CSetI );
243 
244    //Добавляем переход на начало
245    j_jump( CGoto, LABT_GTVIRT, labbeg );
246 
247    //Добавляем метку на конец
248    labend = j_label( LABT_LABELVIRT, -1 );
249 
250    //Цикл установки переходов на конец
251    j_correct( fd.offlcbreak, labend );
252 
253    //Цикл установки переходов на начало
254    j_correct( fd.offlccontinue, labcont );
255 
256    //Восстановление меток цикла
257    fd.offlcbreak = fd_offlcbreak;
258    fd.offlccontinue = fd_offlccontinue;
259    fd.blcycle--;
260 
261 D( "Foreach stop\n" );
262    return curlex;
263 }
Редактировать