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

Ads

Perfect Automation tool
All-In-One: Script editor, Launcher, Scheduler, Keyboard & Mouse Recorder. Try now!

CreateInstall
Freeware and commercial installers.

Cell Phone Batteries
Batteries Plus offers batteries for laptop, camcorder, cell phone, camera.

Gentee needs your help!
How to advertise with us
 
laptop battery

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       var = (( pfvar )( fd.bvars.data + offvar ));
160    }
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 
173       var->type = itemtype;
174       var->oftype = 0;
175       var->flg |= FVAR_UINTAS;
176    }
177 
178    //Добавляем вызов first
179    out_adduints( 8, CVarptrload,
180                   indexnum,
181                   CVarload,
182                   objnum,
183                   CVarload,
184                   fordata,
185                   bcfirst,
186                   /*bcset*/CSetI );
187 
188    //Добавляем метку на начало
189    labbeg = j_label( LABT_LABELVIRT, -1 );
190 
191    out_debugtrace( curlex );
192 
193    //Вызов метода Eof
194    //Обработка логического выражения
195    out_adduints( 5, CVarload,
196                   objnum,
197                   CVarload,
198                   fordata,
199                   bceof );
200 
201    //Сохраняем последние метки цикла
202    fd_offlcbreak = fd.offlcbreak;
203    fd_offlccontinue = fd.offlccontinue;
204 
205    //Добавляем переход на конец
206    fd.offlcbreak = j_jump( CIfnze, LABT_GTVIRT, -1);
207    fd.offlccontinue = -1;
208 
209    if ( bcadvget )
210    {
211       //Коррекция для базовых типов
212       out_adduints( 7, CVarptrload,
213                      indexnum,
214                      CVarptrload,
215                      indexnum,
216                      CGetI,
217                      bcadvget,
218                      bcadvset );
219       /*out_adduints( 6, CVarptrload,
220                      indexnum,
221                      CVarload,
222                      indexnum,
223                      bcadvget,
224                      bcset );*/
225    }
226 
227    //Обработка тела
228    curlex = f_body( curlex );
229 
230    //Метка на continue
231    labcont = j_label( LABT_LABELVIRT, -1 );
232 
233    //Вызов метода Next
234    out_adduints( 8, CVarptrload,
235                   indexnum,
236                   CVarload,
237                   objnum,
238                   CVarload,
239                   fordata,
240                   bcnext,                  
241                   /*bcset*/CSetI );
242 
243    //Добавляем переход на начало
244    j_jump( CGoto, LABT_GTVIRT, labbeg );
245 
246    //Добавляем метку на конец
247    labend = j_label( LABT_LABELVIRT, -1 );
248 
249    //Цикл установки переходов на конец
250    j_correct( fd.offlcbreak, labend );
251 
252    //Цикл установки переходов на начало
253    j_correct( fd.offlccontinue, labcont );
254 
255    //Восстановление меток цикла
256    fd.offlcbreak = fd_offlcbreak;
257    fd.offlccontinue = fd_offlccontinue;
258    fd.blcycle--;
259 
260 D( "Foreach stop\n" );
261    return curlex;
262 }
Edit