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
Бесплатные и коммерческие инсталляторы

  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: for 09.02.07 0.0.A.
 11 *
 12 * Author: Alexander Krivonogov ( algen )
 13 *
 14 * Summary: Конструкции for, fornum
 15 *
 16 ******************************************************************************/
 17 
 18 #include "func.h"
 19 #include "bcodes.h"
 20 
 21 /*-----------------------------------------------------------------------------
 22 *
 23 * ID: c_for 09.02.07 0.0.A.
 24 *
 25 * Summary: The for processing
 26 *
 27 -----------------------------------------------------------------------------*/
 28 plexem STDCALL c_for( plexem curlex )
 29 {
 30    uint       labbeg;          //Метка начало
 31    uint       labend;          //Метка конец
 32    uint       labcont;         //Метка на continue
 33    uint       fd_offlcbreak;   //Смещение в таблице меток
 34    uint       fd_offlccontinue;//Смещение в таблице меток
 35    plexem     incrlex;         //Лесема начала выражения инкремента
 36 
 37 D( "For start\n" );
 38    fd.blcycle++;
 39 
 40    //Обработка выражения инициализации
 41    curlex = f_expr( curlex, EXPR_COMMA, 0, 0 );
 42 
 43    if ( curlex->type != LEXEM_OPER || curlex->oper.operid != OpComma )
 44       msg( MExpcomma | MSG_LEXERR, curlex );
 45    curlex = lexem_next( curlex, 0 );
 46 
 47    //Добавляем метку на начало
 48    labbeg = j_label( LABT_LABELVIRT, -1 );
 49 
 50    //Обработка логического выражения
 51    curlex = f_expr( curlex, EXPR_BOOL | EXPR_COMMA, 0, 0 );
 52    if ( curlex->type != LEXEM_OPER || curlex->oper.operid != OpComma )
 53       msg( MExpcomma | MSG_LEXERR, curlex );
 54    curlex = lexem_next( curlex, 0 );
 55 
 56    //Сохраняем последние метки цикла
 57    fd_offlcbreak = fd.offlcbreak;
 58    fd_offlccontinue = fd.offlccontinue;
 59 
 60    //Добавляем переход на конец
 61    fd.offlcbreak = j_jump( CIfze, LABT_GTVIRT, -1);
 62    fd.offlccontinue = -1;
 63 
 64    //Пропуск инкремента
 65    incrlex = curlex;
 66    do
 67    {
 68       curlex = lexem_next( curlex, 0 );
 69    }
 70    while ( curlex->type != LEXEM_OPER || curlex->oper.operid != OpLcrbrack );
 71 
 72    //Обработка тела
 73    curlex = f_body( curlex );
 74 
 75    //Метка на continue
 76    labcont = j_label( LABT_LABELVIRT, -1 );
 77 
 78    //Обработка инкремента
 79    incrlex = f_expr( incrlex, 0, 0, 0 );
 80    incrlex = lexem_next( incrlex, LEXNEXT_SKIPLINE );
 81 
 82    if ( incrlex->type != LEXEM_OPER || incrlex->oper.operid != OpLcrbrack )
 83       msg( MLcurly | MSG_LEXERR, incrlex );
 84 
 85    //Добавляем переход на начало
 86    j_jump( CGoto, LABT_GTVIRT, labbeg );
 87 
 88    //Добавляем метку на конец
 89    labend = j_label( LABT_LABELVIRT, -1 );
 90 
 91    //Цикл установки переходов на конец
 92    j_correct( fd.offlcbreak, labend );
 93 
 94    //Цикл установки переходов на начало
 95    j_correct( fd.offlccontinue, labcont );
 96 
 97    //Восстановление меток цикла
 98    fd.offlcbreak = fd_offlcbreak;
 99    fd.offlccontinue = fd_offlccontinue;
100    fd.blcycle--;
101 
102 D( "For stop\n" );
103    return curlex;
104 }
105 
106 
107 /*-----------------------------------------------------------------------------
108 *
109 * ID: c_fornum 09.02.07 0.0.A.
110 *
111 * Summary: The fornum processing
112 *
113 -----------------------------------------------------------------------------*/
114 #define INDEX_LOCVAR 0x1  //Индекс-переменная локальная
115 #define INDEX_GLOBVAR 0x2 //Индекс-переменная глобальная
116 plexem STDCALL c_fornum( plexem curlex )
117 {
118    plexem     indexlex;      //Лексема с переменной индекска
119    uint       indexflg;      //Флаг переменной индекса локальная/глобальная переменная
120    uint       indexnum;      //Номер/код переменной индекса
121    uint       indextype;     //Тип индекса
122 
123    uint       labbeg;          //Метка начало
124    uint       labend;          //Метка конец
125    uint       labcont;         //Метка на continue
126 
127    uint       fd_offlcbreak;   //Смещение в таблице меток
128    uint       fd_offlccontinue;//Смещение в таблице меток
129 
130    uint       casenum;  //Номер дополнительной переменной хранящей верхнее условие
131    uint       globid;   //Идентификатор глобальной переменной
132    pfvar      var;      //Указатель на структуру локальной переменной
133    phashiuint phitem;   //Элемент хэштаблицы с локальной переменной
134    uint       parsc[4]; //Параметры для получения кода операции
135 
136 D( "Fornum start\n" );
137    fd.blcycle++;
138    indexlex = curlex;
139    indexflg = 0;
140 
141    //Получение переменной индеска
142    phitem = (phashiuint)hash_find( &fd.nvars, lexem_getname( curlex ) );
143    if ( phitem )
144    {  //Идентификатор есть в таблице локальных переменных
145       var = ( pfvar )(fd.bvars.data + phitem->val);
146       if ( !(var->flg ) )
147       {  // Локальная переменная
148          indexnum = var->num;
149          indexflg = INDEX_LOCVAR;
150          indextype = var->type;
151       }
152    }   
153    if ( !indexflg  )
154    {      
155       globid = bc_getid( curlex );      
156       if ( globid && (( pvmobj )PCMD( globid ))->type == OVM_GLOBAL )
157       {  //Глобальная переменная    
158          indexnum = globid;
159          indexflg = INDEX_GLOBVAR;
160          indextype = ((povmglobal)PCMD( globid ))->type->type;
161       }
162    }   
163    if ( !indexflg )
164       msg( MUnklex | MSG_LEXNAMEERR, curlex );//Неизвестный идентификатор
165    if ( indextype <= TInt || indextype >= TUshort )
166       msg( MVaruint | MSG_LEXERR, curlex );
167    parsc[0] = indextype;
168 
169    //Обработка выражения инициализации
170    curlex = lexem_next( curlex, 0 );
171    if ( curlex->type == LEXEM_OPER && curlex->oper.operid == OpSet )
172    {
173       curlex = f_expr( indexlex, EXPR_COMMA, 0, 0 );
174    }
175 
176 
177    curlex = lexem_next( curlex, LEXNEXT_SKIPLINE );
178    if ( curlex->type != LEXEM_OPER || curlex->oper.operid != OpComma )
179       msg( MExpcomma | MSG_LEXERR, curlex );//Ошибка Должна быть запятая
180    curlex = lexem_next( curlex, 0 );
181 
182    //Обработка выражения максимального значения
183    //Получение максимального значения и запись в локальную переменную
184    casenum = var_addtmp( indextype, 0 );
185    out_add2uint( CVarptrload, casenum );
186    curlex = f_expr( curlex, EXPR_NONULL, &parsc[2], &parsc[3] );
187 
188    parsc[1] = 0;   
189    out_adduint( bc_funcname( curlex, "#=", 2, parsc )->vmo.id );
190 
191    //Добавляем метку на начало
192    labbeg = j_label( LABT_LABELVIRT, -1 );
193 
194    out_debugtrace( curlex );
195    //Операция сравнения <
196    out_add2uint( indexflg & INDEX_LOCVAR ? CVarload : CPtrglobal,
197                indexnum );
198    if ( indexflg & INDEX_GLOBVAR )
199    {
200       out_adduint( CGetI );
201    }
202    out_adduints( 3, CVarload,
203                   casenum,
204                   bc_funcname( curlex, "#<", 2, parsc )->vmo.id );
205 
206    //Сохраняем последние метки цикла
207    fd_offlcbreak = fd.offlcbreak;
208    fd_offlccontinue = fd.offlccontinue;
209 
210    //Добавляем переход на конец
211    fd.offlcbreak = j_jump( CIfze, LABT_GTVIRT, -1);
212    fd.offlccontinue = -1;
213 
214    //Обработка тела
215    curlex = f_body( curlex );
216 
217    //Метка на continue
218    labcont = j_label( LABT_LABELVIRT, -1 );
219 
220    //Обработка инкремента ++
221    out_adduints( 3, indexflg & INDEX_LOCVAR ? CVarptrload : CPtrglobal,
222                   indexnum,
223                   bc_funcname( curlex, "#++", 1, parsc )->vmo.id );
224 
225    //Добавляем переход на начало
226    j_jump( CGoto, LABT_GTVIRT, labbeg );
227 
228    //Добавляем метку на конец
229    labend = j_label( LABT_LABELVIRT, -1 );
230 
231    //Цикл установки переходов на конец
232    j_correct( fd.offlcbreak, labend );
233 
234    //Цикл установки переходов на начало
235    j_correct( fd.offlccontinue, labcont );
236 
237    //Восстановление меток цикла
238    fd.offlcbreak = fd_offlcbreak;
239    fd.offlccontinue = fd_offlccontinue;
240    fd.blcycle--;
241 
242 D( "Fornum stop\n" );
243    return curlex;
244 }
245 
Редактировать