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

The project is closed! You can look at a new scripting language. It is available on GitHub.
Also, try our open source cross-platform automation software.

Ads

Installer and installation software
Commercial and Freeware installers.

  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: body 22.01.07 0.0.A.
 11 *
 12 * Author: Alexander Krivonogov ( algen )
 13 *
 14 * Summary: Block of function processing
 15 *
 16 ******************************************************************************/
 17 
 18 
 19 #include "func.h"
 20 #include "ifdef.h"
 21 #include "../vm/vmtype.h"
 22 
 23 /*-----------------------------------------------------------------------------
 24 *
 25 * ID: f_body 22.01.07 0.0.A.
 26 *
 27 * Summary: Block of function processing
 28 *
 29 -----------------------------------------------------------------------------*/
 30 plexem STDCALL f_body( plexem curlex )
 31 {
 32    plexem    nextlex;     //Лексема следующая после ключевого слова
 33    plexem    prevlex;
 34 
 35    uint      oldbvaruse;   //Пред. размер буфера для локальных переменных
 36    uint      oldbblinituse;//Пред. размер стэка ининициализации буферов
 37    uint      oldboutuse;   //Пред. размер байткода для вставки инициализации буферов
 38    uint      oldblabelsuse;//Пред. размер таблицы меток
 39    uint      oldbvarsasuse;//Перд. размер таблицы переменных As
 40    uint      lastcurcount; //Пред. значение fd.lastcurcount
 41    uint      oldvarcount;  //Пред. количество переменных
 42 
 43    pflabel   curlabel;   // Текущий элемент в таблице меток
 44 
 45    pfvar     pvar;       //Указатель на структуру переменной
 46    pfvaras   pvaras;     //Указатель на структуру as переменной
 47    uint      numins;     //На сколько сдвигать байткод при вставке команд иниц. блоков
 48    uint      rettype;    //Тип значения return
 49    uint      retoftype;  //Тип элеменента значения return
 50    uint      off;        //Временная переменная для смещений
 51 
 52 D( "Body start\n" );
 53 
 54 //Инициализация и сохранение данных по верхнему блоку
 55    oldbblinituse = fd.bblinit.use;
 56    oldboutuse     = fd.bout->use;
 57    oldbvarsasuse  = fd.bvarsas.use;
 58    if ( fd.curcount )
 59    {
 60       lastcurcount = fd.lastcurcount;
 61       fd.lastcurcount = fd.curcount;
 62    }
 63    else
 64    {
 65       lastcurcount = -1;
 66    }
 67    oldvarcount = fd.varcount;
 68    fd.curcount = 0;
 69    fd.bllevel++;
 70    oldbvaruse = fd.oldoffbvar;
 71    fd.oldoffbvar = fd.bvars.use;
 72    oldblabelsuse = fd.blabels.use;
 73 
 74    //Открывающая фигурная скобка
 75    curlex = lexem_next( curlex, LEXNEXT_SKIPLINE );
 76    curlex = lexem_next( curlex, LEXNEXT_IGNLINE | LEXNEXT_LCURLY );
 77 
 78    //Главный цикл чтения лексем
 79    while ( 1 )
 80    {      
 81       if ( curlex->type == LEXEM_KEYWORD )
 82       {
 83          nextlex = lexem_next( curlex, 0 );
 84          switch ( curlex->key )
 85          {
 86             case KEY_SUBFUNC:
 87                curlex = f_subfunc( nextlex );
 88                goto next;
 89             case KEY_IF:
 90                curlex = c_if( nextlex );
 91                continue;
 92             case KEY_WHILE:
 93                curlex = c_while( nextlex );
 94                goto next;
 95             case KEY_BREAK:
 96                out_debugtrace( curlex );
 97                curlex = nextlex;
 98                if ( fd.blcycle )
 99                   fd.offlcbreak = j_jump( CGoto, LABT_GTVIRT, fd.offlcbreak );
100                else
101                   msg( MLoopcmd | MSG_LEXERR, curlex );
102                break;
103             case KEY_CONTINUE:
104                out_debugtrace( curlex );
105                curlex = nextlex;
106                if ( fd.blcycle )
107                   fd.offlccontinue = j_jump( CGoto, LABT_GTVIRT, fd.offlccontinue );
108                else
109                   msg( MLoopcmd | MSG_LEXERR, curlex );
110                break;
111             case KEY_FOR:
112                curlex = c_for( nextlex );
113                goto next;
114             case KEY_FORNUM:
115                curlex = c_fornum( nextlex );
116                goto next;
117             case KEY_FOREACH:
118                curlex = c_foreach( nextlex );
119                goto next;
120             case KEY_DO:
121                curlex = c_dowhile( nextlex );
122                goto next;
123             case KEY_LABEL:
124                curlex = c_label( nextlex );
125                continue;
126             case KEY_GOTO:
127                curlex = c_goto( nextlex );
128                break;
129             case KEY_RETURN:
130                prevlex = curlex;
131                curlex = f_expr( nextlex, 0, &rettype, &retoftype );                              
132                if (  !type_compat( rettype, fd.functype, 0 ) ||
133                      ( fd.funcoftype && !type_compat( retoftype, fd.funcoftype, 1 )) )
134                   /*type_compfull( rettype ) !=
135                     type_compfull( fd.functype ) ||
136                     type_compfull( retoftype ) !=
137                     type_compfull( fd.funcoftype )*/
138                   msg( MRettype | MSG_LEXERR, curlex );
139 
140                if ( !rettype )
141                   out_debugtrace( prevlex );
142 
143                if ( fd.bout == &fd.bsubout )
144                   out_adduint( CSubreturn );
145                else
146                {
147                   if ( fd.flgfunc & GHBC_RESULT )
148                   {
149                      out_add2uint( CVarload, fd.idresult );
150                   }
151                   out_adduint( CReturn );
152                }
153                j_label( LABT_RETURN, -1 );
154                continue;
155 
156             case KEY_SWITCH:
157                curlex = c_switch( nextlex );
158                goto next;
159 
160             case KEY_WITH:
161                curlex = c_with( nextlex );
162                goto next;
163 
164             default:
165                curlex = f_expr( curlex, 0, 0, 0 );//Обработка выражения
166                continue;
167          }
168          if ( curlex->type == LEXEM_OPER && !(curlex->oper.operid == OpLine ||
169                curlex->oper.operid == OpRcrbrack) )
170             msg( MExpline | MSG_LEXERR, curlex );
171          continue;
172       }
173       else
174       {
175          if ( curlex->type == LEXEM_OPER )
176          {
177             if ( curlex->oper.operid == OpRcrbrack )//}
178             {
179                break;//Выйти из тела
180             }
181             if ( curlex->oper.operid == OpLcrbrack )//{
182             {
183                curlex = f_body( curlex );//Ещё одно тело
184                goto next;
185             }
186             else if ( curlex->oper.operid == OpLine )
187                goto next;
188          }
189          else
190          if ( curlex->type == LEXEM_NAME )
191          {  //Возможно определение локальных переменных
192             curlex = var_def( curlex, DESCID_VAR );
193          }
194          curlex = f_expr( curlex, 0, 0, 0 );//Обработка выражения
195          continue;
196       }
197 next:
198       curlex = lexem_next( curlex, LEXNEXT_IGNLINE );
199    }
200 
201    //Восстановление типов as
202    off = (uint)fd.bvarsas.data + oldbvarsasuse;   
203    for ( pvaras = ((pfvaras)(fd.bvarsas.data + fd.bvarsas.use)) - 1;
204          (uint)pvaras >= off;
205          pvaras-- )
206    {            
207       pvar = ( pfvar )(fd.bvars.data + pvaras->offbvar);
208       pvar->type = pvaras->type;      
209       pvar->oftype = pvaras->oftype;
210       pvar->flg = pvaras->flg;
211    }
212    fd.bvarsas.use = oldbvarsasuse;
213 
214    //Очистка локальных переменных
215    off = (uint)fd.bvars.data + fd.oldoffbvar;
216    for ( (uint)pvar = (uint)fd.bvars.data + fd.bvars.use - sizeof( fvar );
217          (uint)pvar >= off; pvar-- )
218    {
219       if ( pvar->hidn )
220       {
221          pvar->hidn->val = pvar->oldoffbvar;
222       }
223    }
224    //Удаляем лишние локальные переменные
225    fd.bvars.use = fd.oldoffbvar;
226    fd.oldoffbvar = oldbvaruse;
227    //Установка количества локальных переменных для последнего блока
228    if ( fd.curcount )
229    {
230       buf_appenduint( &fd.bhead, fd.curcount );
231    }
232    if ( oldvarcount != fd.varcount )
233    {
234       fd.curcount = 0;
235       fd.lastcurcount = 0;
236    }
237    else
238    {
239       if ( lastcurcount != -1 )
240       {
241          fd.curcount = fd.lastcurcount;
242          fd.lastcurcount = lastcurcount;
243       }
244    }
245 
246    //Вставка команд инициализации блоков
247    numins = fd.bblinit.use - oldbblinituse;
248    if ( numins )
249    {
250       buf_insert( fd.bout, oldboutuse, fd.bblinit.data + oldbblinituse, numins );
251       fd.bblinit.use = oldbblinituse;
252    }
253 
254 //Корректировка меток
255    curlabel = ( pflabel )( fd.blabels.data + oldblabelsuse );
256    oldblabelsuse = ( uint )( fd.blabels.data + fd.blabels.use );
257    while( ( uint )curlabel < oldblabelsuse )
258    {      
259       curlabel->offbout += numins;
260       
261       if ( !( curlabel->type & LABT_VIRT ) )
262       {
263          if ( curlabel->type & LABT_LABEL )
264          {            
265             curlabel->type = LABT_LABELUNDEF;
266          }
267          else
268          if ( ( curlabel->type & LABT_GTUNDEF ) == LABT_GTUNDEF )
269          {  //Определение неопределенных меток
270             off = curlabel->hitem->val;
271             if ( off != -1 )
272             {
273                if ( (( pflabel )(fd.blabels.data + off ))->type & LABT_LABEL )
274                {
275                   curlabel->type = LABT_GTDEF;
276                   curlabel->link = off;
277                }
278                else
279                   msg( MUnklabel | MSG_LEXNAMEERR, curlabel->lex );
280             }
281          }
282       }
283       curlabel++;
284    }
285    fd.bllevel--;
286 
287 D( "Body stop\n" );
288    return curlex;
289 }