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

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.

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                               left_int = 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                            flg_resuint = 1;
347                            break;
348 
349                         //Операции сравнения чисел
350                         case OpGreateq:
351                            flg_not = 1;
352                         case OpLess:
353                            if ( left_numtype )
354                            {
355                               left_int = left_int < right_int;
356                               left_intl = left_long < right_long;
357                               left_intf = left_float < right_float;
358                               left_intd = left_double < right_double;
359                               flg_resuint = 1;
360                               break;
361                            }
362                            goto nosup;
363                         case OpLesseq:
364                            flg_not = 1;
365                         case OpGreater:
366                            if ( left_numtype )
367                            {
368                               left_int = left_int > right_int;
369                               left_intl = left_long > right_long;
370                               left_intf = left_float > right_float;
371                               left_intd = left_double > right_double;
372                               flg_resuint = 1;
373                               break;
374                            }
375                         default: goto nosup;
376                      }
377                   }
378                   else //Унарные операции
379                   {
380                      switch ( stackop_id )
381                      {
382                         //Арифметические унарные операции
383                         case OpPlus:
384                            if ( !left_numtype )
385                               goto nosup;
386                            break;
387                         case OpMinus:
388                            if ( left_numtype )
389                            {
390                               left_int = -left_int;
391                               left_long = -left_long;
392                               left_float = -left_float;
393                               left_double = -left_double;
394                               break;
395                            }
396                            goto nosup;
397 
398                         //Двоичная унарная операция
399                         case OpBinnot:
400                            switch ( left_numtype )
401                            {
402                               case TInt:
403                                  left_int = !left_int;
404                                  break;
405                               case TLong:
406                                  left_long = !left_long;
407                                  break;
408                               default:
409                                  goto nosup;
410                            }
411                            break;
412 
413                         //Логическая унарная операция
414                         case OpLognot:
415                            left_int = !left_bvalue;
416                            flg_resuint = 1;
417                            break;
418 
419                         default:
420                            goto nosup;
421                      }
422                   }
423 
424 //Конец вычисления операции
425 
426                   switch ( left_numtype )
427                   { //Корректировка значений для чисел
428                      case TInt:
429                         left_bvalue = (tokleft->vallexem.num.vint = left_int) ? 1 : 0;
430                         break;
431                      case TLong:
432                         left_bvalue = (tokleft->vallexem.num.vlong = left_long) ? 1 : 0;
433                         left_int = left_intl;
434                         break;
435                      case TFloat:
436                         left_bvalue = (tokleft->vallexem.num.vfloat =
437                                        left_float) ? 1 : 0;
438                         left_int = left_intf;
439                         break;
440                      case TDouble:
441                         left_bvalue = (tokleft->vallexem.num.vdouble =
442                                        left_double) ? 1 : 0;
443                         left_int = left_intd;
444                         break;
445                   }
446                   if ( flg_resuint )
447                   {   //Результат операции TUint
448                      tokleft->vallexem.type = LEXEM_NUMBER;
449                      tokleft->vallexem.num.type = TUint;
450                      tokleft->vallexem.num.vint = left_bvalue =
451                                        flg_not ? !left_int : left_int;
452                   }
453 
454                   tokleft->bvalue = left_bvalue;
455                }
456                else
457                {
458                   if ( stackop_id == OpComma )
459                   {
460                      (stackc-1)->left->colpars++;
461                   }
462                   else
463                   if ( ( curop_id == OpRcrbrack && stackop_id == OpCollect )  )
464                   {
465                      if ( stackc->left != tokc - 1 )
466                      {
467                         stackc->left->colpars++;
468                      }
469                      else
470                      {
471                         laststate = state;
472                      }
473                   }
474                   else
475                   {                  
476                      if ( ( stackop_flgs & OPF_OPEN ) && ( stackop != curop - 1 ) )
477                         msg( MNotopenbr | MSG_LEXERR , stackc->operlexem );
478                   }
479                }
480 
481             }
482             if ( flgexp && stackop_after <= curop_before )
483             {  //Выход из цикла
484                break;
485             }
486             continue;
487 nosup:
488             msg( MUnsmoper | MSG_LEXNAMEERR, stackc->operlexem );
489          }
490 // Конец цикла выталкивания из стека операций
491 
492 // Добавление в стэк последней операций
493          if ( curop_id == OpCollect )
494          {
495             tokc->bvalue = 1;
496             tokc->vallexem = *curlex;
497             tokc->vallexem.type = LEXEM_COLLECT;
498             tokc->colpars = 0;
499             tokc++;
500          }         
501          stackc->operid = curop_id;
502          stackc->operlexem = curlex;
503          stackc->left = tokc-1;
504          stackc++;
505       }
506 // Конец обработки системной лексемы
507       else
508       {
509 // Обработка операндов
510          tokc->vallexem = *curlex;
511          state = L_OPERAND;
512          switch ( curlex->type )
513          {
514             case LEXEM_NUMBER://Число
515                switch ( curlex->num.type )
516                {
517                   case TUint:
518                   case TInt:
519                      tokc->bvalue = tokc->vallexem.num.vint ? 1 : 0;
520                      break;
521                   case TUlong:
522                   case TLong:
523                      tokc->bvalue = tokc->vallexem.num.vlong ? 1 : 0;
524                      break;
525                   case TFloat:
526                      tokc->bvalue = tokc->vallexem.num.vfloat ? 1 : 0;
527                      break;
528                   case TDouble:
529                      tokc->bvalue = tokc->vallexem.num.vdouble ? 1 : 0;
530                      break;
531                }
532                break;
533 
534             case LEXEM_STRING://Строка
535                tokc->bvalue = str_len( lexem_getstr( &tokc->vallexem )) ? 1 : 0;
536                break;
537 
538             case LEXEM_BINARY://Двоичные данные
539                tokc->bvalue = buf_len( lexem_getstr( &tokc->vallexem ))   ? 1 : 0;
540                break;
541 
542             case LEXEM_NAME://Идентификатор
543                tokc->bvalue = -1;
544                break;
545 
546             case LEXEM_KEYWORD:
547                msg( MNokeyword | MSG_LEXERR, curlex );
548 
549             default:
550                msg( MUnsmoper | MSG_LEXNAMEERR, curlex );
551          }
552          tokc++;
553       }      
554 // Проверка синтаксиса выражения
555       if ( flgexp )
556       {
557          switch ( laststate )
558          {
559             case L_OPERAND:
560             case L_POST_CLOSE:
561                if ( state & L_OPERAND ||
562                     state & L_UNARY_OPEN )
563                {                  
564                   msg( MUnexpoper | MSG_LEXERR, curlex );
565                }
566                break;
567             default:
568                if ( state & L_BINARY ||
569                     state & L_POST_CLOSE )
570                {
571                   msg( MMustoper | MSG_LEXERR, curlex );
572                }
573          }
574          laststate = state;
575       }
576       else
577       {
578          if ( ( laststate == L_UNARY_OPEN && tokc != tokb ) ||
579               laststate == L_BINARY )
580             msg( MMustoper | MSG_LEXERR, curlex );
581          break;
582       }
583 
584 next:
585       curlex = lexem_next( curlex, 0 );
586       if ( curlex > maxlex )
587          msg( MExpmuch | MSG_LEXERR, curlex );
588    }
589 
590    //Возврат значения
591    if ( tokb->vallexem.type == LEXEM_COLLECT )
592    {
593       bcol = buf_init( ( pbuf )arr_append( &_compile->binary ));
594       tokb->vallexem.binid = arr_count( &_compile->binary ) - 1;
595       buf_appenduint( bcol, tokb->colpars );
596 
597       for ( tokleft = tokb + 1; tokleft < tokc; tokleft++ )
598       {
599 
600          switch ( tokleft->vallexem.type )
601          {
602             case LEXEM_NUMBER:
603                buf_appendch( bcol, (ubyte)tokleft->vallexem.num.type );
604                switch ( tokleft->vallexem.num.type )
605                {
606                   case TByte:
607                   case TUbyte:
608                      buf_appendch( bcol, (ubyte)tokleft->vallexem.num.vint );
609                      break;
610                   case TShort:
611                   case TUshort:
612                      buf_appendushort( bcol, (ushort)tokleft->vallexem.num.vint );
613                      break;
614                   case TUlong:
615                   case TLong:
616                   case TDouble:
617                      buf_appendulong( bcol, tokleft->vallexem.num.vlong );
618                      break;
619                   default:
620                      buf_appenduint( bcol, tokleft->vallexem.num.vint );
621                }
622                break;
623 
624             case LEXEM_STRING:
625                buf_appendch( bcol, TStr );
626                strt = lexem_getstr( &tokleft->vallexem );
627                buf_append( bcol, strt->data, strt->use );
628                break;
629 
630             case LEXEM_BINARY:
631                buf_appendch( bcol, TBuf );
632                buft = lexem_getstr( &tokleft->vallexem );
633                buf_appenduint( bcol, buft->use );
634                buf_append( bcol, buft->data, buft->use );
635                break;
636 
637             case LEXEM_COLLECT:
638                buf_appendch( bcol, TCollection );               
639                buf_appenduint( bcol, tokleft->colpars );
640                break;
641 
642             default:
643                msg( MSyntax | MSG_LEXNAMEERR, &tokleft->vallexem );
644          }
645       }
646    }
647    else
648    if ( tokc != tokb+1 )
649    {
650       msg( MSyntax | MSG_LEXNAMEERR, curlex );
651    }
652 
653    *mr = tokb;
654 
655 D("Macroexp stop\n" );
656    return curlex;
657 }
658 
659 
660 
661