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

   macroexp.c

   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\macroexp.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: expmacro 18.10.06 0.0.A.
 11 *
 12 * Author: Alexander Krivonogov ( algen )
 13 *
 14 * Summary: Обработка макро выражений
 15 *
 16 ******************************************************************************/
 17 
 18 #include "macroexp.h"
 19 
 20 /*-----------------------------------------------------------------------------
 21 *
 22 * ID: macroepr 18.10.06 0.0.A.
 23 *
 24 * Summary: The macro expression processing
 25 *
 26 -----------------------------------------------------------------------------*/
 27 /*Возможны операции
 28 с целыми числами        + - +ун -ун * / ! && || & | ~ > < >= <= == !=
 29 с дробными числами     + - +ун -ун * / ! && ||       > < >= <= == !=
 30 со строками и буфером                  ! && ||(Длина)          == != (значения)
 31 */
 32 plexem STDCALL macroexpr( plexem curlex, pmacrores * mr )
 33 {
 34    psoper      curop;    //Текущая операция
 35    psoper      stackop;  //Оператор из стэка
 36 
 37    uint        bropen;   //Количество открытых скобок ( и [
 38    uint        flgexp;   //Флаг определяющий конец разбора
 39    uint        state;    //Флаг типа текущей лексемы L_*
 40    uint        laststate; //Флаг типа предыдущей лексемы L_*
 41 
 42    pmacrooper  stackb;   //Указатель на начало стэка операций
 43    pmacrooper  stackc;   //Указатель на следующий элемент стэка операций
 44 
 45    pmacrores   tokb;     //Указатель на начало таблицы
 46    pmacrores   tokc;     //Указатель на следующий элемент таблицы
 47    pmacrores   tokleft;  //Указатель на левый операнд для IFDEF
 48    pmacrores   tokright; //Указатель на правый операнд для IFDEF
 49    plexem      maxlex;
 50 
 51    pbuf        bcol;     //Буфер с коллекцией
 52    pstr        strt;     //Указатель на строку
 53    pbuf        buft;     //Указатель на бинарные данные
 54 
 55    uint        curop_flgs;
 56    uint        curop_before;
 57    uint        curop_id;
 58    uint        stackop_flgs;
 59    uint        stackop_after;
 60    uint        stackop_id;
 61 
 62    uint   left_type, flg_resuint, flg_not;
 63    uint   left_numtype, right_numtype;
 64    uint   left_bvalue, right_bvalue;
 65    int    left_int, right_int;
 66    int    left_intl, left_intf, left_intd;
 67    long64 left_long, right_long;
 68    float  left_float, right_float;
 69    double left_double, right_double;
 70 
 71 // Инициализация
 72    stackb = _compile->stkmopers;//Стэк операций
 73    stackc = stackb;
 74    tokb = _compile->stkmops;//Стэк операндов
 75    tokc = tokb;
 76    flgexp = 1;
 77    bropen = 0;
 78    laststate = L_UNARY_OPEN;
 79    maxlex = curlex + min( STACK_OPERS / sizeof( macrooper ), STACK_OPS / sizeof( macrores ) );
 80 D("Macroexp start\n" );
 81 
 82 //Цикл формирования байткода
 83    while ( 1 )
 84    {
 85 // Обработка системной лексемы
 86       if ( curlex->type == LEXEM_OPER )
 87       {
 88          curop_id = curlex->oper.operid;
 89          curop = (psoper)&opers[curop_id]; 
 90          curop_flgs = curop->flgs;
 91 
 92 // Первичная обработка
 93          if ( curop_flgs & OPF_OPEN )//Открывающие скобки
 94          {          
 95             if ( curop_id == OpLcrbrack )
 96                flgexp = 0;//Если в конце выражения откр. фиг. скобка, то выходим из цикла
 97             else
 98             {
 99                state = L_UNARY_OPEN;
100                bropen++;
101             }
102          }
103          else
104          if ( curop_flgs & OPF_CLOSE )//Закрывающие скобки
105          {    
106             if ( bropen )
107             {
108                state = L_POST_CLOSE;
109                bropen--;
110             }
111             else
112             {
113                if ( curop_id == OpRcrbrack ||
114                     ( stackc != stackb ||
115                     tokc != tokb ))
116                   flgexp = 0;//Непарная скобка
117                else
118                   msg( MSyntax | MSG_LEXNAMEERR, curlex );
119             }
120          }
121          else
122          if ( curop_id == OpLine ) // ; - Точка с запятой - Перенос строки
123          {
124             if ( laststate & L_BINARY || bropen > 0 )
125                goto next;
126             flgexp = 0;
127          }
128          else
129          if ( curop_id == OpComma )//, - Запятая
130          {
131             if ( !bropen )
132             {
133                flgexp = 0;
134             }
135          }
136          else
137          if ( curop_flgs & OPF_UNDEF ) //Неопределённый оператор
138          {
139             if ( laststate & ( L_OPERAND | L_POST_CLOSE ))
140             {
141                curop = ( psoper )&opers[curop_id = ++curlex->oper.operid];
142                curop_flgs = curop->flgs;
143             }
144          }
145 
146 // Дополнительная обработка
147          if ( curop_flgs & OPF_BINARY )
148          {
149             state = L_BINARY;
150          }
151          else
152          if ( curop_flgs & OPF_UNARY )
153          {
154             state = L_UNARY_OPEN;
155          }
156          else
157          if ( curop_flgs & OPF_POST )
158          {
159             state = L_POST_CLOSE;
160          }
161          curop_before = curop->before;
162 // Цикл выталкивания из стека операций
163          while ( stackc != stackb )
164          {
165             stackop_id = (stackc-1)->operid;
166             stackop = (psoper)&opers[stackop_id];
167             stackop_after = stackop->after;
168             stackop_flgs = stackop->flgs;
169             flg_not = 0;
170             flg_resuint = 0;
171             if ( !flgexp || stackop_after >= curop_before )
172             {
173                stackc--;
174                if ( !( stackop_flgs & ( OPF_OPEN | OPF_CLOSE ) ||
175                     stackop_id == OpComma ) )
176                {
177                   if ( stackop_flgs & OPF_BINARY )
178                   {
179                      tokleft = tokc - 2;
180                      tokright = tokc - 1;
181                      tokc--;
182                   }
183                   else
184                   {
185                      tokleft = tokc - 1;
186                      tokright = 0;
187                   }
188                   if ( tokright && tokright < tokb + 1 )
189                      msg( MSyntax | MSG_LEXNAMEERR, curlex );
190 
191                   left_type = tokleft->vallexem.type;
192                   if ( left_type == LEXEM_NUMBER )
193                   {
194                      left_numtype = tokleft->vallexem.num.type;
195                      if ( left_numtype == TUint )
196                         left_numtype = TInt;
197                      else if ( left_numtype == TUlong )
198                         left_numtype = TLong;
199                      left_int = tokleft->vallexem.num.vint;
200                      left_long = tokleft->vallexem.num.vlong;
201                      left_float = tokleft->vallexem.num.vfloat;
202                      left_double = tokleft->vallexem.num.vdouble;
203                   }
204                   else left_numtype = 0;
205                   left_bvalue = tokleft->bvalue;
206                   if ( tokright )//Бинарная операция
207                   {
208                      right_bvalue = tokright->bvalue;
209                      if ( stackop_id != OpLogand && stackop_id != OpLogor )
210                      {
211                         if ( left_type != tokright->vallexem.type )
212                            goto nosup;                     
213                         if ( left_numtype )
214                         {
215                            right_numtype = tokright->vallexem.num.type;
216                            if ( right_numtype == TUint )
217                               right_numtype = TInt;
218                            else if ( right_numtype == TUlong )
219                               right_numtype = TLong;
220                            if ( left_numtype != right_numtype )
221                               goto nosup;
222                            right_int = tokright->vallexem.num.vint;
223                            right_long = tokright->vallexem.num.vlong;
224                            right_float = tokright->vallexem.num.vfloat;
225                            right_double = tokright->vallexem.num.vdouble;
226                         }
227                      }
228                      if ( left_bvalue == -1 || right_bvalue == -1 )
229                         goto nosup;
230                      switch ( stackop_id )
231                      {
232                         //Арифметические операции
233                         case OpAdd:
234                            if ( left_numtype )
235                            {
236                               left_int += right_int;
237                               left_long += right_long;
238                               left_float += right_float;
239                               left_double += right_double;
240                               break;
241                            }
242                            goto nosup;
243                         case OpSub:
244                            if ( left_numtype )
245                            {
246                               left_int -= right_int;
247                               left_long -= right_long;
248                               left_float -= right_float;
249                               left_double -= right_double;
250                               break;
251                            }
252                            goto nosup;
253                         case OpMul:
254                            if ( left_numtype )
255                            {
256                               left_int *= right_int;
257                               left_long *= right_long;
258                               left_float *= right_float;
259                               left_double *= right_double;
260                               break;
261                            }
262                            goto nosup;
263                         case OpDiv:
264                            if ( left_numtype )
265                            {
266                               left_int /= right_int;
267                               left_long /= right_long;
268                               left_float /= right_float;
269                               left_double /= right_double;
270                               break;
271                            }
272                            goto nosup;
273 
274                         //Двоичные операции
275                         case OpBinand:
276                            switch ( left_numtype )
277                            {
278                               case TInt:
279                                  left_int &= right_int;
280                                  break;
281                               case TLong:
282                                  left_long &= right_long;
283                                  break;
284                               default: goto nosup;
285                            }
286                            break;
287                         case OpBinor:
288                            switch ( left_numtype )
289                            {
290                               case TInt:
291                                  left_int |= right_int;
292                                  break;
293                               case TLong:
294                                  left_long |= right_long;
295                                  break;
296                               default: goto nosup;
297                            }
298                            break;
299                         case OpBinxor:
300                            switch ( left_numtype )
301                            {
302                               case TInt:
303                                  left_int ^= right_int;
304                                  break;
305                               case TLong:
306                                  left_long ^= right_long;
307                                  break;
308                               default:   goto nosup;
309                            }
310                            break;
311 
312                         //Логические операции
313                         case OpLogand:
314                            left_int = ( left_bvalue && right_bvalue ) ? 1 : 0;
315                            flg_resuint = 1;
316                            break;
317                         case OpLogor:
318                            left_int = ( left_bvalue || right_bvalue ) ? 1 : 0;
319                            flg_resuint = 1;
320                            break;
321 
322                         //Операции равенства
323                         case OpNoteq:
324                            flg_not = 1;
325                         case OpEq:
326                            if ( left_type == LEXEM_STRING || left_type == LEXEM_BINARY )
327                            {
328                               buf_isequal(
329                                  (pstr)lexem_getstr( &tokleft->vallexem ),
330                                  (pstr)lexem_getstr( &tokright->vallexem ));
331                            }
332                            /*else if ( left_type == LEXEM_BINARY )
333                            {
334                               buf_isequal(
335                                  (pbuf)lexem_getstr( &tokleft->vallexem ),
336                                  (pbuf)lexem_getstr( &tokright->vallexem ));
337                            }*/
338                            else if ( left_numtype )
339                            {
340                               left_int = left_int == right_int;
341                               left_intl = left_long == right_long;
342                               left_intf = left_float == right_float;
343                               left_intd = left_double == right_double;
344                            }
345                            else goto nosup;
346                            break;
347 
348                         //Операции сравнения чисел
349                         case OpGreateq:
350                            flg_not = 1;
351                         case OpLess:
352                            if ( left_numtype )
353                            {
354                               left_int = left_int < right_int;
355                               left_intl = left_long < right_long;
356                               left_intf = left_float < right_float;
357                               left_intd = left_double < right_double;
358                               flg_resuint = 1;
359                               break;
360                            }
361                            goto nosup;
362                         case OpLesseq:
363                            flg_not = 1;
364                         case OpGreater:
365                            if ( left_numtype )
366                            {
367                               left_int = left_int > right_int;
368                               left_intl = left_long > right_long;
369                               left_intf = left_float > right_float;
370                               left_intd = left_double > right_double;
371                               flg_resuint = 1;
372                               break;
373                            }
374                         default: goto nosup;
375                      }
376                   }
377                   else //Унарные операции
378                   {
379                      switch ( stackop_id )
380                      {
381                         //Арифметические унарные операции
382                         case OpPlus:
383                            if ( !left_numtype )
384                               goto nosup;
385                            break;
386                         case OpMinus:
387                            if ( left_numtype )
388                            {
389                               left_int = -left_int;
390                               left_long = -left_long;
391                               left_float = -left_float;
392                               left_double = -left_double;
393                               break;
394                            }
395                            goto nosup;
396 
397                         //Двоичная унарная операция
398                         case OpBinnot:
399                            switch ( left_numtype )
400                            {
401                               case TInt:
402                                  left_int = !left_int;
403                                  break;
404                               case TLong:
405                                  left_long = !left_long;
406                                  break;
407                               default:
408                                  goto nosup;
409                            }
410                            break;
411 
412                         //Логическая унарная операция
413                         case OpLognot:
414                            left_int = !left_bvalue;
415                            flg_resuint = 1;
416                            break;
417 
418                         default:
419                            goto nosup;
420                      }
421                   }
422 
423 //Конец вычисления операции
424 
425                   switch ( left_numtype )
426                   { //Корректировка значений для чисел
427                      case TInt:
428                         left_bvalue = (tokleft->vallexem.num.vint = left_int) ? 1 : 0;
429                         break;
430                      case TLong:
431                         left_bvalue = (tokleft->vallexem.num.vlong = left_long) ? 1 : 0;
432                         left_int = left_intl;
433                         break;
434                      case TFloat:
435                         left_bvalue = (tokleft->vallexem.num.vfloat =
436                                        left_float) ? 1 : 0;
437                         left_int = left_intf;
438                         break;
439                      case TDouble:
440                         left_bvalue = (tokleft->vallexem.num.vdouble =
441                                        left_double) ? 1 : 0;
442                         left_int = left_intd;
443                         break;
444                   }
445                   if ( flg_resuint )
446                   {   //Результат операции TUint
447                      tokleft->vallexem.type = LEXEM_NUMBER;
448                      tokleft->vallexem.num.type = TUint;
449                      tokleft->vallexem.num.vint = left_bvalue =
450                                        flg_not ? !left_int : left_int;
451                   }
452 
453                   tokleft->bvalue = left_bvalue;
454                }
455                else
456                {
457                   if ( stackop_id == OpComma )
458                   {
459                      (stackc-1)->left->colpars++;
460                   }
461                   else
462                   if ( ( curop_id == OpRcrbrack && stackop_id == OpCollect )  )
463                   {
464                      if ( stackc->left != tokc - 1 )
465                      {
466                         stackc->left->colpars++;
467                      }
468                      else
469                      {
470                         laststate = state;
471                      }
472                   }
473                   else
474                   {                  
475                      if ( ( stackop_flgs & OPF_OPEN ) && ( stackop != curop - 1 ) )
476                         msg( MNotopenbr | MSG_LEXERR , stackc->operlexem );
477                   }
478                }
479 
480             }
481             if ( flgexp && stackop_after <= curop_before )
482             {  //Выход из цикла
483                break;
484             }
485             continue;
486 nosup:
487             msg( MUnsmoper | MSG_LEXNAMEERR, stackc->operlexem );
488          }
489 // Конец цикла выталкивания из стека операций
490 
491 // Добавление в стэк последней операций
492          if ( curop_id == OpCollect )
493          {
494             tokc->bvalue = 1;
495             tokc->vallexem = *curlex;
496             tokc->vallexem.type = LEXEM_COLLECT;
497             tokc->colpars = 0;
498             tokc++;
499          }         
500          stackc->operid = curop_id;
501          stackc->operlexem = curlex;
502          stackc->left = tokc-1;
503          stackc++;
504       }
505 // Конец обработки системной лексемы
506       else
507       {
508 // Обработка операндов
509          tokc->vallexem = *curlex;
510          state = L_OPERAND;
511          switch ( curlex->type )
512          {
513             case LEXEM_NUMBER://Число
514                switch ( curlex->num.type )
515                {
516                   case TUint:
517                   case TInt:
518                      tokc->bvalue = tokc->vallexem.num.vint ? 1 : 0;
519                      break;
520                   case TUlong:
521                   case TLong:
522                      tokc->bvalue = tokc->vallexem.num.vlong ? 1 : 0;
523                      break;
524                   case TFloat:
525                      tokc->bvalue = tokc->vallexem.num.vfloat ? 1 : 0;
526                      break;
527                   case TDouble:
528                      tokc->bvalue = tokc->vallexem.num.vdouble ? 1 : 0;
529                      break;
530                }
531                break;
532 
533             case LEXEM_STRING://Строка
534                tokc->bvalue = str_len( lexem_getstr( &tokc->vallexem )) ? 1 : 0;
535                break;
536 
537             case LEXEM_BINARY://Двоичные данные
538                tokc->bvalue = buf_len( lexem_getstr( &tokc->vallexem ))   ? 1 : 0;
539                break;
540 
541             case LEXEM_NAME://Идентификатор
542                tokc->bvalue = -1;
543                break;
544 
545             case LEXEM_KEYWORD:
546                msg( MNokeyword | MSG_LEXERR, curlex );
547 
548             default:
549                msg( MUnsmoper | MSG_LEXNAMEERR, curlex );
550          }
551          tokc++;
552       }      
553 // Проверка синтаксиса выражения
554       if ( flgexp )
555       {
556          switch ( laststate )
557          {
558             case L_OPERAND:
559             case L_POST_CLOSE:
560                if ( state & L_OPERAND ||
561                     state & L_UNARY_OPEN )
562                {                  
563                   msg( MUnexpoper | MSG_LEXERR, curlex );
564                }
565                break;
566             default:
567                if ( state & L_BINARY ||
568                     state & L_POST_CLOSE )
569                {
570                   msg( MMustoper | MSG_LEXERR, curlex );
571                }
572          }
573          laststate = state;
574       }
575       else
576       {
577          if ( ( laststate == L_UNARY_OPEN && tokc != tokb ) ||
578               laststate == L_BINARY )
579             msg( MMustoper | MSG_LEXERR, curlex );
580          break;
581       }
582 
583 next:
584       curlex = lexem_next( curlex, 0 );
585       if ( curlex > maxlex )
586          msg( MExpmuch | MSG_LEXERR, curlex );
587    }
588 
589    //Возврат значения
590    if ( tokb->vallexem.type == LEXEM_COLLECT )
591    {
592       bcol = buf_init( ( pbuf )arr_append( &_compile->binary ));
593       tokb->vallexem.binid = arr_count( &_compile->binary ) - 1;
594       buf_appenduint( bcol, tokb->colpars );
595 
596       for ( tokleft = tokb + 1; tokleft < tokc; tokleft++ )
597       {
598 
599          switch ( tokleft->vallexem.type )
600          {
601             case LEXEM_NUMBER:
602                buf_appendch( bcol, (ubyte)tokleft->vallexem.num.type );
603                switch ( tokleft->vallexem.num.type )
604                {
605                   case TByte:
606                   case TUbyte:
607                      buf_appendch( bcol, (ubyte)tokleft->vallexem.num.vint );
608                      break;
609                   case TShort:
610                   case TUshort:
611                      buf_appendushort( bcol, (ushort)tokleft->vallexem.num.vint );
612                      break;
613                   case TUlong:
614                   case TLong:
615                   case TDouble:
616                      buf_appendulong( bcol, tokleft->vallexem.num.vlong );
617                      break;
618                   default:
619                      buf_appenduint( bcol, tokleft->vallexem.num.vint );
620                }
621                break;
622 
623             case LEXEM_STRING:
624                buf_appendch( bcol, TStr );
625                strt = lexem_getstr( &tokleft->vallexem );
626                buf_append( bcol, strt->data, strt->use );
627                break;
628 
629             case LEXEM_BINARY:
630                buf_appendch( bcol, TBuf );
631                buft = lexem_getstr( &tokleft->vallexem );
632                buf_appenduint( bcol, buft->use );
633                buf_append( bcol, buft->data, buft->use );
634                break;
635 
636             case LEXEM_COLLECT:
637                buf_appendch( bcol, TCollection );               
638                buf_appenduint( bcol, tokleft->colpars );
639                break;
640 
641             default:
642                msg( MSyntax | MSG_LEXNAMEERR, &tokleft->vallexem );
643          }
644       }
645    }
646    else
647    if ( tokc != tokb+1 )
648    {
649       msg( MSyntax | MSG_LEXNAMEERR, curlex );
650    }
651 
652    *mr = tokb;
653 
654 D("Macroexp stop\n" );
655    return curlex;
656 }
657 
658 
659 
Edit