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\subfunc.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: subfunc 02.02.06 0.0.A.
 11 *
 12 * Author: Alexander Krivonogov ( algen )
 13 *
 14 * Summary: Обработка подфункции
 15 *
 16 ******************************************************************************/
 17 
 18 #include "func.h"
 19 
 20 /*-----------------------------------------------------------------------------
 21 *
 22 * ID: f_subfunc 02.02.06 0.0.A.
 23 *
 24 * Summary: The subfunc processing
 25 *
 26 -----------------------------------------------------------------------------*/
 27 plexem STDCALL f_subfunc( plexem curlex )
 28 {
 29    uint       fd_lastcurcount;//Предыдущее значение кол. переменных в верхнем блоке
 30    uint       fd_functype;  //Текущий тип функции
 31    uint       fd_funcoftype;  //Текущий подтип функции
 32    uint       fd_oldoffbvar;//Текущее смещение в стэке локальных переменных
 33    uint       offbvars;     //Смещение в стэке локальных переменных для подфункции
 34 
 35    pflabel    curlabel;     //Текущий элемент в таблице меток
 36    pflabel    endlabel;     //Конец таблицы меток
 37    uint       offblabels;   //Начало подфункции в стэке меток
 38 
 39    uint       addr;         //Адрес подфункции в байткоде
 40    uint       pars;         //Количество параметров у подфункции
 41    uint       offbvardef;   //Смещение в буфере описание переменных
 42 
 43    s_desctype desctype;     //Структура для получения типа подфункции
 44    s_descid   descvar;      //Структура для описания подфункции как локальной переменной
 45    pfvar      var;          //Указатель на локальную переменную-подфункцию
 46 
 47    uint       isreturn;     //Флаг выхода из функции
 48    plexem     lexname;      //Лексема с именем функции
 49    uint       off;          //Временная переменная для смещений
 50 
 51    if ( fd.bllevel > 1 )
 52       msg( MSublevel | MSG_LEXERR, curlex );
 53 
 54 //Инициализация
 55    desctype.idtype = 0;
 56    descvar.idtype = 0;
 57    _compile->pout = fd.bout = &fd.bsubout;
 58 
 59    offblabels  = fd.blabels.use;
 60    fd_functype = fd.functype;
 61    fd_funcoftype = fd.funcoftype;
 62 
 63    //if ( !fd.bsubout.use )
 64    if ( !fd.offsubgoto )
 65    {
 66       out_add2uint( CGoto, 0 );
 67       fd.offsubgoto = fd.bsubout.use - 4;
 68    }
 69    addr = fd.bsubout.use/sizeof( uint );
 70 
 71 //Тип возвращаемого значения если указан   
 72    if ( curlex->type == LEXEM_NAME )
 73       curlex = desc_idtype( curlex, &desctype );
 74    if ( desctype.idtype )
 75    {
 76       fd.functype = desctype.idtype;
 77       fd.funcoftype = desctype.oftype;
 78       //Инициализация возврата
 79       out_add2uint( CSubret, (( povmtype)PCMD( fd.functype ))->stsize );
 80    }
 81    else
 82    {
 83       fd.functype = 0;
 84       fd.funcoftype = 0;
 85    }
 86 //Имя функции
 87    curlex = lexem_next( curlex, LEXNEXT_SKIPLINE );
 88    if ( curlex->type != LEXEM_NAME )
 89       msg( MExpname | MSG_LEXERR, curlex );//Ошибка Должен быть идентификатор
 90    lexname = curlex;
 91    offbvars = fd.bvars.use;
 92    descvar.idtype = fd.functype;
 93    descvar.oftype = fd.funcoftype;
 94    descvar.name = lexem_getname( lexname );
 95    descvar.lex = lexname;
 96    descvar.flgdesc = DESCID_SUBFUNC;
 97    var_checkadd( &descvar );
 98 
 99 //Список параметров
100    curlex = lexem_next( curlex, LEXNEXT_IGNLINE );
101    fd_oldoffbvar = fd.oldoffbvar;
102    fd.oldoffbvar = fd.bvars.use;
103    pars = 0;
104    if ( curlex->type == LEXEM_OPER &&
105         curlex->oper.operid == OpLbrack )//Открывающая скобка
106    {
107       curlex = lexem_next( curlex, LEXNEXT_IGNLINE );
108 
109       fd_lastcurcount = fd.lastcurcount;
110       fd.lastcurcount = fd.curcount;
111       fd.curcount = 0;
112       offbvardef = fd.bvardef.use;
113 
114       curlex = var_def( curlex, DESCID_PARSUBFUNC );
115 
116       pars = fd.curcount;
117       if ( fd.curcount )
118       {
119          out_add2uint( CSubpar, fd.blcount - 1 );//Загрузка параметров
120          buf_appenduint( &fd.bhead, fd.curcount );
121          fd.curcount = 0;
122       }
123       else
124       {
125          fd.curcount = fd.lastcurcount;
126          fd.lastcurcount = fd_lastcurcount;
127       }
128 
129       if ( curlex->type != LEXEM_OPER ||
130            curlex->oper.operid != OpRbrack )//Закрывающая скобка
131          msg( MExpclosebr | MSG_LEXERR, curlex );// Ошибка Ожадается закрывающая скобка
132       curlex = lexem_next( curlex, LEXNEXT_IGNLINE );
133    }
134 
135 //Запись подфункции как локальной переменной
136    var = (pfvar)( fd.bvars.data + offbvars );
137    var->flg  = FVAR_SUBFUNC;
138    var->addr = addr;
139    var->pars = pars;
140    var->offbvardef = offbvardef;
141 
142 //Обработка тела функции
143    curlex = f_body( curlex );
144 
145 //Очистка параметров из стэка локальных переменных
146    off = (uint)fd.bvars.data + fd.oldoffbvar;
147    for ( (uint)var = (uint)fd.bvars.data + fd.bvars.use - sizeof( fvar );
148          (uint)var >= off; var-- )
149    {
150       if ( var->hidn )
151          var->hidn->val = var->oldoffbvar;
152    }
153    fd.bvars.use = fd.oldoffbvar;
154    fd.oldoffbvar = fd_oldoffbvar;
155 
156 //Установка переходов, корректировка меток
157    isreturn = 0;
158    curlabel = ( pflabel )( fd.blabels.data + offblabels );
159    endlabel = ( pflabel )( fd.blabels.data + fd.blabels.use );
160    while( curlabel < endlabel )
161    {
162       if ( curlabel->type & LABT_GT )
163       {
164          if ( ( curlabel->type & LABT_GTUNDEF ) == LABT_GTUNDEF )
165             msg( MUnklabel | MSG_LEXNAMEERR, curlabel->lex );
166 
167          *( puint )(fd.bsubout.data + curlabel->offbout ) =
168                ((( pflabel )(fd.blabels.data + curlabel->link ))->offbout)/sizeof(uint);
169          if ( !isreturn )
170          {
171             //Помечаем метку как отработавшую (на неё был переход)
172             (( pflabel )(fd.blabels.data + curlabel->link ))->type |= LABT_LABELWORK;
173          }
174       }
175       else
176       if ( curlabel->type & LABT_RETURN )
177          isreturn = 1;//Устанавливаем флаг
178       else
179       if ( curlabel->type & LABT_LABELWORK )
180          isreturn = 0;//Если была отработавшая метка, то сбрасываем флаг
181       curlabel++;
182    }
183    fd.blabels.use = offblabels;
184 
185 //Проверка выходов из функции
186    if ( fd.functype )
187    {
188       if ( !isreturn )
189          msg( MMustret | MSG_LEXNAMEERR, lexname );
190    }
191    else
192       if ( !isreturn )
193          out_adduint( CSubreturn );
194 //Восстановление данных
195    _compile->pout = fd.bout = &fd.bfuncout;
196    fd.functype = fd_functype;
197    fd.funcoftype = fd_funcoftype;
198 
199    return curlex;
200 }
Редактировать