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

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

   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: expr 22.01.07 0.0.A.
  11 *
  12 * Author: Alexander Krivonogov ( algen )
  13 *
  14 * Summary: Обработка выражений
  15 *
  16 ******************************************************************************/
  17 
  18 #include "func.h"
  19 #include "bcodes.h"
  20 #include "compinit.h"
  21 #include "../vm/vmtype.h"
  22 #include "alias.h"
  23 
  24 /*-----------------------------------------------------------------------------
  25 *
  26 * ID: exptoken 22.01.07 0.0.A.
  27 *
  28 * Summary: Структура токенов
  29 *
  30 -----------------------------------------------------------------------------*/
  31 
  32 typedef struct _exptoken
  33 {
  34    plexem           lex;   //Указатель на лексему
  35    struct _exptoken *left; //Указатель на левый операнд
  36    uint             flg;   //Флаг FTOK_*
  37    union {
  38       uint  offlocvar;     //Смещение локальной переменной
  39       uint  idglobvar;     //Идентификатор глобальной переменной
  40       uint  idglobfunc;    //Идентификатор глобальной функции      
  41       uint  idalias;       //Идентификатор псевдонима функции
  42       uint  parofsize;     //Тип параметр для ofsize
  43       uint  cmdbytecode;   //Команда для байткода
  44       uint  val;           //Идентификатор в соответствующей таблице, в зависимости от flg
  45       pstr  strbin;        //Указатель на строку или бинарные данные
  46    };
  47    union {
  48       uint  offout;        //Смещение в байт коде
  49       uint  pars;          //Количество параметров для функции
  50    };
  51    uint     type;          //Результирующий тип
  52    uint     ol;            //Смещение в таблице меток для хранения переходов в случае && или ||
  53    uint     oftype;
  54    uint     msr;   
  55 } exptoken, * pexptoken;
  56 
  57 /*-----------------------------------------------------------------------------
  58 *
  59 * ID: expoper 22.01.07 0.0.A.
  60 *
  61 * Summary: Структура операции
  62 *
  63 -----------------------------------------------------------------------------*/
  64 typedef struct
  65 {
  66    uint      operid; //Код операции
  67 
  68    plexem    lex;    //Указатель на лексему
  69    pexptoken left;   //Указатель на левый операнд
  70    uint      flg;    
  71    uint      val;    
  72    uint      pars;   //Количество параметров
  73 } expoper, * pexpoper;
  74 
  75 //Типы токенов
  76 #define FTOK_LOCVAR       0x01 //Локальная переменная
  77 #define FTOK_GLOBVAR      0x02 //Глобальная переменная
  78 #define FTOK_SUBFUNC      0x03 //Вызов локальной функции
  79 #define FTOK_GLOBFUNC     0x04 //Вызов глобальной функции
  80 #define FTOK_ADDRFUNC     0x05 //Вызов функции по её адресу
  81 #define FTOK_METHODFUNC   0x06 //Вызов метода
  82 #define FTOK_FIELD        0x07 //Поле структуры
  83 #define FTOK_NUMBER       0x08 //Число
  84 #define FTOK_OPER         0x09 //Оператор
  85 #define FTOK_PTRTYPE      0x0A //Приведение к типу
  86 #define FTOK_GLOBFUNCADDR 0x0B //Адрес глобальной функции
  87 #define FTOK_STRBIN       0x0C //Строка или двоичные данные
  88 #define FTOK_QUEST        0x0D //Операция ?(,,)
  89 #define FTOK_ARR          0x0E //Массив
  90 #define FTOK_SIZEOF       0x0F //Sizeof
  91 #define FTOK_TYPE         0x10 //0x200000 //Тип
  92 #define FTOK_BYTECODE     0x11 //0x400000 //Команда байткода
  93 #define FTOK_COLLECT      0x12 //0x500000 //Загрузка коллекции
  94 #define FTOK_COLLECTNEW   0x13 //0x600000 //Загрузка коллекции
  95 #define FTOK_LATE         0x14 //Отложеный вызов
  96 #define FTOK_ALIAS        0x15 //Псевдоним функции
  97 //Маски для типов токенов
  98 #define FTOK_NOFLAGS        0x0000FF//FF0000
  99 #define FTOK_FLAGS          0xFFFF00//00FFFF
 100 //Флаги токенов
 101 #define FTOK_LVALUE         0x000100 //Текущий операнд должен быть lvalue
 102 #define FTOK_FUNCPAR        0x000200 //Параметр функции
 103 #define FTOK_OPAND          0x000400 //Операнд операции &&
 104 #define FTOK_OPOR           0x000800 //Операнд операции ||
 105 #define FTOK_FUNC           0x001000 //Функция
 106 #define FTOK_QUESTFIRST     0x002000 //Первый операнд операции ?
 107 #define FTOK_QUESTSECOND    0x004000 //Второй операнд операции ?
 108 #define FTOK_QUESTTHIRD     0x008000 //Третий операнд операции ?
 109 #define FTOK_ADDFUNCPAR     0x010000 //Требуется добавить параметр функции (для метода)
 110 #define FTOK_LVALPROPERTY   0x020000 //Присваивание свойству
 111 #define FTOK_TEXT           0x040000 //Функция является текстовой
 112 #define FTOK_LVALLATE       0x080000 //Присваивание отложенному вызову
 113 #define FTOK_COLLECTIONLATE 0x100000 //Новая коллекция создается для позднего вызова
 114 #define FTOK_WITH           0x200000 //Опарация сокращенного вызова полей
 115 
 116 //Макроопределения для загрузок фиктивных операций-функций
 117 #define STACK_ADD( _ftok, _pars, _left, _lex ) \
 118 stackc->operid = OpFunc;\
 119 stackc->lex = _lex;\
 120 stackc->flg = _ftok | FTOK_FUNC | FTOK_FUNCPAR;\
 121 stackc->pars = _pars;\
 122 stackc->left = _left;\
 123 stackc++;\
 124 state = L_UNARY_OPEN | L_FUNC;
 125 
 126 #define STACK_ADDARR() \
 127 STACK_ADD( FTOK_ARR, 1, tokc-1, lastlex )
 128 
 129 #define STACK_ADDFUNC(_ftok)\
 130 STACK_ADD( _ftok, 0, tokc-1, curlex )
 131 
 132 #define STACK_ADDMETHOD(_ftok)\
 133 STACK_ADD( _ftok, 1, tokc-1, curlex )
 134 
 135 
 136 //Таблица команд для получения чисел
 137 uint artypes[ TUlong + 1 ] = 
 138          { 0, CGetI, CGetI, CGetB, CGetUB, CGetS, CGetUS, CGetI, CGetL, CGetL, CGetL };
 139 
 140 /*-----------------------------------------------------------------------------
 141 *
 142 * ID: f_exp 22.01.07 0.0.A.
 143 *
 144 * Summary: Обработка выражений
 145 *
 146 -----------------------------------------------------------------------------*/
 147 
 148 plexem STDCALL f_expr( plexem curlex, uint flg, puint rettype, puint retoftype )
 149 {
 150    plexem      lastlex;   //Предыдущая лексема
 151    plexem      lex;       //Обрабатываемая лексема
 152    plexem      firstlex;  //Первая лексема
 153 
 154    psoper      curop;     //Текущая операция
 155    psoper      stackop;   //Оператор из стэка
 156 
 157    pexpoper    stackb;    //Указатель на начало стэка операций
 158    pexpoper    stackc;    //Указатель на следующий элемент стэка операций
 159 
 160    pexptoken   tokb;    //Указатель на начало таблицы
 161    pexptoken   tokc;    //Указатель на следующий элемент таблицы
 162    pexptoken   toki;    //Указатель на текущий элемент таблицы
 163    pexptoken   toktmp;  //Временный указатель на операнд
 164    plexem      maxlex;
 165 
 166    uint        curop_flgs;
 167    uint        curop_before;
 168    uint        curop_id;
 169    uint        stackop_flgs;
 170    uint        stackop_after;
 171    uint        stackop_id;
 172 
 173    uint        state;     // Текущее состояние обработчика
 174    uint        laststate; // Предыдущее состояние обработчика
 175    uint        bropen;    // Количество открытых скобок
 176    uint        flgexp;    // Флаг продалжать обработку
 177 
 178    uint        off;       //Временная переменная для различных смещений
 179    uint        id;        //Временная переменная для хранения идентификаторов
 180    phashiuint  phitem;    //Элемент хэштаблицы с локальной переменной
 181 
 182    s_desctype  desctype;  //Описание типа
 183    pfvar       pvar;      //Указатель на структуру локальной переменной
 184    pfvaras     pvaras;    //Указатель на структуру as
 185    povmtype    ptype;     //Указатель на струкутру объекта
 186    pvartype    pglobvar;  //Указатель на структуру типа глобальной переменной
 187    pvmfunc     pfunc;     //Указатель на структуру байткода
 188    pfwith      pwith;     //Указатель на структуру with
 189    pvartype    field, isfield;//Поле структуры
 190 
 191    uint   flglvallate; //Флаг позднее связывание с lvalue операцией   
 192    uint   type;
 193    puint  parsc, parsb, parse, psrc;//Указатели в стэке параметров
 194    uint   numtypes;    //Количество различных типов для коллекции
 195    uint   num;         //Текущее количество
 196    uint   stsize;      //Размер текущего элемента коллекции
 197    pubyte name;         
 198    uint   len;
 199    uint   dwsize;      //Подсчет сумарного размера
 200    uint   i;   
 201    
 202 D("Expr start\n" );
 203 // Инициализация
 204    stackc = stackb = _compile->stkopers;
 205    parsc = _compile->stkpars;
 206    tokc = tokb = _compile->stkops;
 207    flgexp = 1;
 208    lastlex = 0;
 209    bropen = 0;
 210    flglvallate = 0;
 211    laststate = L_UNARY_OPEN;
 212    maxlex = curlex + min( STACK_OPERS / sizeof( soper ), min( STACK_OPS / sizeof( exptoken ), STACK_PARS / sizeof( uint ) ));   
 213    firstlex = curlex;
 214 
 215 //Цикл первого прохода
 216    while ( 1 )
 217    {
 218    //Предварительная обработка
 219       if ( curlex->type == LEXEM_KEYWORD &&
 220            curlex->key == KEY_AS )
 221       {
 222          curlex->type = LEXEM_OPER;
 223          curlex->oper.operid = OpAs;
 224       }      
 225 
 226       switch ( curlex->type )
 227       {
 228          case LEXEM_OPER: 
 229             curop = (psoper)&opers[curop_id = curlex->oper.operid]; 
 230             curop_flgs = curop->flgs;
 231             curop_before = curop->before;
 232             //Первичная обработка оператора
 233             if ( curop_flgs & OPF_OPEN )//Открывающие скобки
 234             {               
 235                if ( curop_id == OpLcrbrack )
 236                   flgexp = 0;//Если в конце выражения откр. фиг. скобка, то выходим из цикла
 237                else
 238                {
 239                   state = L_UNARY_OPEN;
 240                   bropen++;
 241                }
 242             }
 243             else
 244             if ( curop_flgs & OPF_CLOSE )//Закрывающие скобки
 245             {               
 246                if ( bropen )
 247                {
 248                   state = L_POST_CLOSE;
 249                   bropen--;
 250                }
 251                else
 252                {
 253                   if ( curop_id == OpRcrbrack ||
 254                        ( stackc != stackb ||
 255                        tokc != tokb ))
 256                      flgexp = 0;//Непарная скобка
 257                   else
 258                      msg( MSyntax | MSG_LEXNAMEERR, curlex );
 259                }
 260             }
 261             else
 262             if ( curop_id == OpLine ) // Перенос строки
 263             {
 264                if ( laststate & L_BINARY || bropen > 0 )
 265                   goto next;
 266                flgexp = 0;
 267             }
 268             else
 269             if ( curop_id == OpComma && !bropen )//, - Запятая
 270             {
 271                if ( flg & ( EXPR_VAR | EXPR_COMMA ) )
 272                   flgexp = 0;
 273                else
 274                   msg( MSyntax | MSG_LEXNAMEERR, curlex );
 275             }
 276             else
 277             if ( curop_flgs & OPF_UNDEF ) //Неопределённый оператор
 278             {
 279                if ( laststate & ( L_OPERAND | L_POST_CLOSE ))
 280                {
 281                   curop = ( psoper )&opers[curop_id = ++curlex->oper.operid];
 282                   curop_flgs = curop->flgs;
 283                   curop_before = curop->before;
 284                }
 285             }
 286             
 287          //Установка текущего состояния
 288             if ( curop_flgs & OPF_BINARY )
 289             {
 290                state = L_BINARY;
 291             }
 292             else
 293             if ( curop_flgs & OPF_UNARY )
 294             {
 295                state = L_UNARY_OPEN;
 296             }
 297             else
 298             if ( curop_flgs & OPF_POST )
 299             {
 300                state = L_POST_CLOSE;
 301             }
 302             
 303          //Цикл выталкивания из стека операций            
 304             while ( stackc != stackb )
 305             {               
 306                stackop_id = (stackc-1)->operid;
 307                stackop = (psoper)&opers[stackop_id];
 308                stackop_after = stackop->after;
 309                stackop_flgs = stackop->flgs;               
 310                if ( !flgexp || stackop_after >= curop_before )
 311                {
 312                   stackc--;
 313                   if ( stackop_flgs & OPF_OPEN )
 314                   {
 315                      if ( stackop_id != curop_id - 1 && 
 316                            ( stackop_id != OpCollect || curop_id != OpRcrbrack ) )
 317                         msg( MNotopenbr | MSG_LEXERR , curlex );
 318                   }
 319                   if ( !( stackop_flgs & ( OPF_OPEN | OPF_CLOSE ) ||
 320                        stackop_id == OpComma ) )
 321                   {
 322                      tokc->lex = stackc->lex;
 323                      //?Не проще будет tokc->left = stackc->left
 324                      if ( stackop_flgs & OPF_BINARY || stackc->flg & FTOK_FUNC )
 325                         tokc->left = stackc->left;
 326                      else
 327                         tokc->left = 0;
 328 
 329                      tokc->flg = stackc->flg;
 330                      tokc->val = stackc->val;
 331                      tokc->pars = stackc->pars;
 332 
 333                      if ( stackop_flgs & OPF_LVALUE )
 334                      {
 335                         if ( stackop_flgs & OPF_BINARY )
 336                            tokc->left->flg |= FTOK_LVALUE;
 337                         else
 338                            (tokc-1)->flg |= FTOK_LVALUE;
 339                      }
 340                      tokc++;
 341                   }
 342                }
 343                if ( flgexp && stackop_after <= curop_before )
 344                {  //Выход из цикла выталкивания
 345                   break;
 346                }
 347             }
 348             
 349          //Конечная обработка системной лексемы, добавление в стэк операций
 350             if ( flgexp )
 351             {
 352 
 353                if ( curop_id == OpLsqbrack )
 354                {
 355                   (tokc-1)->flg |= FTOK_ADDFUNCPAR;
 356                   STACK_ADDARR();
 357                   laststate = state;
 358                }
 359                else if ( curop_id == OpCollect )
 360                {
 361                   STACK_ADDFUNC( FTOK_COLLECT );
 362                   //laststate = state;
 363                   laststate = laststate | L_FUNC;
 364                }
 365                stackc->flg = FTOK_OPER;
 366                //Конечная обработка
 367                if ( stackc != stackb )
 368                {
 369                   if ( curop_flgs & OPF_OPEN && laststate & L_FUNC )
 370                   {
 371                      laststate = laststate & ~L_FUNC;
 372                      stackc->flg |= FTOK_FUNCPAR;
 373                      stackc->pars = bropen;
 374                      stackc->val = (uint)(stackc-1);
 375                   }
 376                   if ( curop_flgs & OPF_CLOSE &&
 377                        stackc != stackb &&
 378                        ( stackc-1)->flg & FTOK_FUNCPAR &&
 379                        lastlex->type == LEXEM_OPER &&
 380                        ((psoper)&opers[lastlex->oper.operid])->flgs & OPF_OPEN )
 381                   {                     
 382                      laststate = L_OPERAND;
 383                      if ( (stackc-1)->flg & FTOK_FUNC )
 384                         ( stackc-1)->flg &= ~FTOK_FUNCPAR;
 385                   }
 386                   else
 387                   if ( ( curop_id == OpComma ||
 388                          (curop_flgs & OPF_CLOSE) ) &&
 389                          stackc != stackb &&
 390                       ((stackc-1)->flg & FTOK_FUNCPAR) )
 391                   {                     
 392                      if ( !( curop_flgs & OPF_CLOSE ) ||
 393                         ( stackc-1)->flg & FTOK_FUNC ||
 394                         (stackc-1)->pars == bropen - 1 )
 395                      {
 396                         if ( ( stackc-1)->flg & FTOK_FUNC )
 397                         {
 398                            stackc->val = (uint)(stackc-1);
 399                            ( stackc-1)->flg &= ~FTOK_FUNCPAR;
 400                         }
 401                         else
 402                         {
 403                            stackc->val = (stackc-1)->val;
 404                            stackc->pars = bropen;
 405                         }
 406                         stackc->flg = FTOK_FUNCPAR;
 407                         ((pexpoper)(stackc->val))->pars++;
 408                         (tokc-1)->flg |= FTOK_FUNCPAR;
 409                         if ( ((pexpoper)(stackc->val))->lex->type == LEXEM_OPER  &&
 410                              ((pexpoper)(stackc->val))->lex->oper.operid == OpQuest )
 411                         {
 412                            if ( ((pexpoper)(stackc->val))->pars == 1 )
 413                               (tokc-1)->flg |= FTOK_QUESTFIRST;
 414                            else if ( ((pexpoper)(stackc->val))->pars == 2 )
 415                               (tokc-1)->flg |= FTOK_QUESTSECOND;
 416                            else if ( ((pexpoper)(stackc->val))->pars == 3 )
 417                               (tokc-1)->flg |= FTOK_QUESTTHIRD;
 418                         }
 419                         else if ( ( ((pexpoper)(stackc->val))->flg & FTOK_NOFLAGS ) == 
 420                                     FTOK_SIZEOF )
 421                         {
 422                            if ( (( tokc - 1 )->flg & FTOK_NOFLAGS ) == FTOK_TYPE )
 423                            {
 424                               tokc--;
 425                               ((pexpoper)(stackc->val))->val = tokc->type;                
 426                            }
 427                            else
 428                            {
 429                               ((pexpoper)(stackc->val))->val = 0;                   
 430                            }
 431                         }
 432                      }
 433                   }
 434                }
 435 
 436                if ( curop_id == OpLogand )
 437                   (tokc-1)->flg |= FTOK_OPAND;
 438                else
 439                   if ( curop_id == OpLogor )
 440                      (tokc-1)->flg |= FTOK_OPOR;
 441                if ( curop_id == OpQuest )
 442                {  //Создание фиктивной функции для операции ?                  
 443                   stackc->flg = FTOK_QUEST | FTOK_FUNC | FTOK_FUNCPAR;
 444                   stackc->pars = 0;
 445                   state = L_UNARY_OPEN | L_FUNC;
 446                }
 447                else if ( curop_id == OpCollect )
 448                {
 449                   //Фиктивного операнда для создания новой переменной-коллекции
 450                   tokc->lex = curlex;
 451                   tokc->flg = FTOK_COLLECTNEW | FTOK_ADDFUNCPAR;
 452                   tokc->val = 0;
 453                   tokc++;
 454                }
 455                else if ( curop_id == OpStrout )
 456                {
 457                   tokc->cmdbytecode = CGetText;
 458                   tokc->lex = curlex;
 459                   tokc->flg = FTOK_BYTECODE;
 460                   tokc->pars = 0;
 461                   tokc++;
 462                }
 463                else if ( curop_id == OpWith )
 464                {
 465                   tokc->lex = curlex;
 466                   tokc->flg = FTOK_LOCVAR | FTOK_WITH;
 467                   tokc->offlocvar = 0;
 468                   tokc++;
 469                   curop_id = OpPoint;
 470                }                  
 471                stackc->lex = curlex;
 472                stackc->operid = curop_id;
 473                stackc->left = tokc-1;
 474                stackc++;
 475             }            
 476             break;            
 477 
 478             // Обработка операндов
 479             case LEXEM_NAME://Идентификатор
 480                if ( stackc != stackb )
 481                {
 482                   if ( (stackc-1)->operid == OpPoint )
 483                   {
 484                      stackc--;
 485                      if ( curlex->flag & LEXF_CALL )
 486                      {  //Вызов метода                        
 487                         curlex->flag |= LEXF_METHOD;
 488                         //Добавляем в стэк фиктивную операцию
 489                         (tokc-1)->flg |= FTOK_ADDFUNCPAR;
 490                         STACK_ADDMETHOD( FTOK_METHODFUNC );
 491                      }
 492                      else
 493                      {  //Поле
 494                         tokc->lex = curlex;
 495                         tokc->flg = FTOK_FIELD;                        
 496                         tokc++;
 497                         state = L_OPERAND;
 498                      }
 499                      break;
 500                   }
 501                   else if ( (stackc-1)->operid == OpLate )
 502                   {   //Отложенный метод-свойство
 503                      stackc--;
 504                      if ( curlex->flag & LEXF_CALL )
 505                      {
 506                         //Позднее связываение в стэк операций
 507                         (tokc-1)->flg |= FTOK_ADDFUNCPAR;                        
 508                         stackc->val = 0;
 509                         curlex->flag |= LEXF_METHOD;                        
 510                         STACK_ADDFUNC( FTOK_LATE );
 511                         (stackc-1)->flg = FTOK_LATE | FTOK_FUNC;
 512                         
 513                         //Заголовок коллекции
 514                         tokc->lex = curlex;
 515                         tokc->flg = FTOK_COLLECTNEW | FTOK_COLLECTIONLATE;                        
 516                         tokc->val = 0;
 517                         tokc++;
 518 
 519                         //Коллекция в стэк операций
 520                         STACK_ADDFUNC( FTOK_COLLECT | FTOK_COLLECTIONLATE);
 521                         
 522                      }
 523                      else
 524                      {                        
 525                         //Заголовок коллекции
 526                         tokc->lex = curlex;
 527                         tokc->flg = FTOK_COLLECTNEW | FTOK_COLLECTIONLATE;
 528                         tokc->val = 0;
 529                         tokc++;
 530 
 531                         //Коллекция
 532                         tokc->lex = curlex;
 533                         tokc->flg = FTOK_FUNC | FTOK_COLLECT | FTOK_COLLECTIONLATE;
 534                         tokc->pars = 0;
 535                         tokc->val = 0;
 536                         tokc++;
 537 
 538                         //Позднее связывание
 539                         tokc->lex = curlex;
 540                         tokc->flg = FTOK_LATE;
 541                         tokc->val = 0;
 542                         tokc->pars = 0;
 543                         tokc++;
 544                         
 545                         state = L_OPERAND;                        
 546                      }
 547                      break;
 548                   }
 549                }
 550                if ( phitem = (phashiuint)hash_find( &fd.nvars, lexem_getname( curlex )) )
 551                {  //Идентификатор есть в таблице локальных переменных
 552                   if ( off = phitem->val )
 553                   {                     
 554                      pvar = ( pfvar)(fd.bvars.data+off);
 555                      if ( pvar->flg & FVAR_SUBFUNC )
 556                      {  // Подфункция
 557                         if ( !( curlex->flag & LEXF_CALL ) )
 558                            msg( MExpopenbr | MSG_LEXERR , curlex );
 559                         stackc->val = off;
 560                         //Добавляем в стэк фиктивную операцию
 561                         STACK_ADDFUNC( FTOK_SUBFUNC );
 562                      }
 563                      else
 564                      {  // Локальная переменная
 565                         tokc->lex = curlex;
 566                         tokc->flg = FTOK_LOCVAR;
 567                         tokc->offlocvar = off;
 568                         tokc++;
 569                         state = L_OPERAND;
 570                      }
 571                      break;
 572                   }
 573                }
 574                id = bc_getid( curlex );
 575                if ( id )
 576                //Проверка в глобальной таблице
 577                switch ( (( pvmobj )PCMD( id ))->type )
 578                {
 579                   case OVM_BYTECODE:
 580                   case OVM_EXFUNC:
 581                   case OVM_STACKCMD:                     
 582 
 583                      if ( curlex->flag & LEXF_CALL )
 584                      {  
 585                         //Добавляем в стэк фиктивную операцию
 586                         STACK_ADDFUNC(FTOK_GLOBFUNC);                        
 587                         if ( (( pvmobj )PCMD( id ))->flag & GHBC_TEXT )
 588                         {
 589                            (stackc-1)->flg |= FTOK_TEXT;
 590                         }
 591                      }
 592                      else
 593                      {  //Возможно взятие адреса функции
 594                         if ( (( pvmobj )PCMD( id ))->nextname )
 595                            msg( MNoaddrfunc | MSG_LEXNAMEERR, curlex );
 596                         tokc->idglobfunc = (( pvmobj )PCMD( id ))->id;
 597                         tokc->lex = curlex;
 598                         tokc->flg = FTOK_GLOBFUNCADDR;
 599                         tokc->pars = 0;
 600                         tokc++;
 601                         state = L_OPERAND;
 602                      }
 603                      break;
 604                   case OVM_TYPE:
 605                      if ( curlex->flag & LEXF_CALL )
 606                      {  //Преобразование типа
 607                         stackc->val = 0;
 608                         curlex->flag |= LEXF_METHOD;
 609                         //Добавляем в стэк фиктивную операцию
 610                         STACK_ADDFUNC( FTOK_GLOBFUNC );
 611                      }
 612                      else
 613                      {  //Тип для приведения
 614                         tokc->lex = curlex;
 615                         tokc->type = bc_type( curlex );
 616                         if ( lastlex && lastlex->type == LEXEM_OPER && lastlex->oper.operid == OpPtr )
 617                         {                           
 618                            tokc->flg = FTOK_PTRTYPE;
 619                            stackc--;
 620                         }
 621                         else                        
 622                            tokc->flg = FTOK_TYPE;
 623                         
 624                         curlex = desc_idtype( curlex, &desctype );
 625                         curlex--;
 626                         tokc->oftype = desctype.oftype;
 627                         
 628                         state = L_OPERAND;
 629                         tokc++;
 630                      }
 631                      break;
 632                   case OVM_GLOBAL://Глобальная переменная
 633                      tokc->lex = curlex;
 634                      tokc->idglobvar = id;
 635                      tokc->flg = FTOK_GLOBVAR;
 636                      state = L_OPERAND;
 637                      tokc++;
 638                      break;
 639                   case OVM_ALIAS:
 640                      tokc->lex = curlex;
 641                      tokc->idalias = alias_getid( id );
 642                      tokc->flg = FTOK_ALIAS;
 643                      state = L_OPERAND;
 644                      tokc++;
 645                      break;
 646                }
 647                else
 648                   msg( MUnkname | MSG_LEXNAMEERR, curlex );//Неизвестный идентификатор
 649                break;
 650 
 651             case LEXEM_NUMBER://Число
 652                tokc->lex = curlex;
 653                tokc->flg = FTOK_NUMBER;
 654                tokc->type = curlex->num.type;
 655                tokc->oftype = 0;
 656                tokc++;
 657                state = L_OPERAND;               
 658                break;
 659 
 660             case LEXEM_STRING://Строка                
 661                tokc->strbin = lexem_getstr( curlex );
 662                //print( "LEXEM_STRING %x %c\n", tokc->strbin->use, tokc->strbin->data[0] );
 663                tokc->flg = FTOK_STRBIN;
 664                tokc->lex = curlex;
 665                tokc->type = TStr;
 666                tokc->oftype = 0;
 667                tokc++;
 668                state = L_OPERAND;
 669                break;
 670 
 671             case LEXEM_BINARY://Двоичные данные
 672                tokc->strbin = lexem_getstr( curlex );
 673                tokc->flg = FTOK_STRBIN;
 674                tokc->lex = curlex;
 675                tokc->type = TBuf;
 676                tokc->oftype = 0;
 677                tokc++;
 678                state = L_OPERAND;               
 679                break;
 680 
 681             case LEXEM_KEYWORD:               
 682                if ( ( curlex->key == KEY_FUNC ||
 683                       curlex->key == KEY_STDCALL ||
 684                       curlex->key == KEY_CDECL ) &&
 685                     (stackc-1)->operid == OpPtr )
 686                {  //Вызов функции по адресу                  
 687                   stackc->val = 0;
 688                   //Добавляем в стэк фиктивную операцию
 689                   STACK_ADDFUNC( FTOK_ADDRFUNC );
 690                }
 691                else
 692                {
 693                   if ( curlex->key == KEY_SIZEOF )
 694                   {  
 695                      //Добавляем в стэк фиктивную операцию
 696                      STACK_ADDFUNC( FTOK_SIZEOF );
 697                   }                 
 698                   else
 699                      msg( MNokeyword | MSG_LEXERR, curlex );
 700                }
 701                break;
 702             default:
 703                msg( MUnkname | MSG_LEXNAMEERR, curlex );
 704       }
 705 // Проверка синтаксиса выражения
 706       if ( flgexp )
 707       {         
 708          switch ( laststate )
 709          {
 710             case L_OPERAND:
 711             case L_POST_CLOSE:
 712                if ( state & L_OPERAND ||
 713                     state & L_UNARY_OPEN )
 714                {
 715                   msg( MUnexpoper | MSG_LEXERR, curlex );
 716                }
 717                break;
 718             default:
 719                if ( state & L_BINARY ||
 720                     state & L_POST_CLOSE )
 721                   msg( MMustoper | MSG_LEXERR, curlex );
 722          }
 723          laststate = state;
 724       }
 725       else
 726       {
 727          if ( ( laststate == L_UNARY_OPEN && tokc != tokb ) ||
 728               laststate == L_BINARY )
 729             msg( MMustoper | MSG_LEXERR, curlex );
 730          break;
 731       }
 732 next:
 733       lastlex = curlex;
 734       curlex = lexem_next( curlex, 0 );
 735       if ( curlex > maxlex )
 736          msg( MExpmuch | MSG_LEXERR, curlex );
 737    }
 738    D( "Bytecode start\n" );
 739    if ( tokb != tokc )
 740    {
 741       out_debugtrace( firstlex );
 742    }
 743     /*  && _compile->flag & CMPL_DEBUG )
 744    {  
 745       out_adduints( 3, 
 746          CDwload, 
 747          str_pos2line( _compile->cur->src, firstlex->pos, 0 ) + 1, 
 748          CDbgTrace );
 749    }*/
 750 //Цикл формирования байткода
 751    for ( toki = tokb; toki < tokc; toki++ )
 752    {
 753       lex = toki->lex;
 754       if ( toki->flg & FTOK_LVALUE &&
 755             (  ( toki->flg & FTOK_NOFLAGS ) == FTOK_NUMBER ||
 756                ( toki->flg & FTOK_NOFLAGS ) == FTOK_TYPE
 757             ) )
 758       {
 759          msg( MExplvalue | MSG_LEXERR, lex );
 760       }      
 761 
 762       switch( toki->flg & FTOK_NOFLAGS )
 763       {
 764          case FTOK_LOCVAR: //Локальная переменная
 765             toki->offout = fd.bout->use;
 766             if ( toki->flg & FTOK_WITH )
 767             {
 768                out_add2uint( CVarload, 0 );
 769             }
 770             else
 771             {
 772                pvar = ( pfvar)(fd.bvars.data + toki->offlocvar);
 773                toki->type = pvar->type;
 774 
 775                if ( toki->flg & FTOK_LVALUE &&
 776                      (( pvmobj )PCMD( toki->type ))->flag & GHTY_STACK )
 777                   out_adduint( CVarptrload );
 778                else
 779                   out_adduint( CVarload );
 780                out_adduint( pvar->num );
 781                toki->oftype = pvar->oftype;
 782             }
 783             break;
 784 
 785          case FTOK_GLOBVAR: //Глобальная переменная
 786             out_add2uint( CPtrglobal, toki->idglobvar );
 787             pglobvar = ((povmglobal)PCMD( toki->idglobvar ))->type;
 788             ptype = (( povmtype )PCMD( toki->type = pglobvar->type ));            
 789             if ( !(toki->flg & FTOK_LVALUE) &&
 790                (ptype->vmo.flag & GHTY_STACK ) )
 791             {
 792                 out_adduint( ptype->stsize == 1 ? CGetI : CGetL );
 793             }
 794             toki->oftype = pglobvar->oftype;
 795             break;
 796 
 797          case FTOK_GLOBFUNCADDR://Взятие адреса функции
 798             if ( toki->flg & FTOK_LVALUE && toki + 1 < tokc  )
 799             {
 800                lex = (toki + 1)->lex;
 801                if ( lex->type == LEXEM_OPER && lex->oper.operid == OpAddr )
 802                {
 803                   out_add2uint( CCmdload, toki->idglobfunc );
 804                   break;
 805                }
 806             }
 807             msg( MExpopenbr | MSG_LEXERR, lex );
 808             break;
 809 
 810          case FTOK_METHODFUNC://Метод
 811             off = (uint)( parsc - 2 * toki->pars );
 812             //if ( (toki-1)->flg & FTOK_WITH )
 813             //D( "left %x %x %x\n", (toki->left-1)->flg, (toki->left)->flg, (toki->left+1)->flg );
 814             if ( (toki->left)->flg & FTOK_WITH )
 815             {               
 816                //D( "Method with\n" );
 817                isfield = 0;               
 818                for ( pwith = ( pfwith)( fd.bwith.data + fd.bwith.use ) - 1; 
 819                      pwith >= ( pfwith )fd.bwith.data; pwith-- )
 820                {
 821                   *(puint)off = pwith->type;
 822                   *((puint)off + 1 ) = pwith->oftype;                  
 823                   if ( pfunc = bc_method( lex, toki->pars, ( puint )off ) )
 824                       break;                  
 825                }               
 826                if ( pfunc )
 827                {                  
 828                   toki->left->type = pwith->type;
 829                   toki->left->oftype = pwith->oftype;
 830                }
 831                else
 832                {                     
 833                   msg( MUnkoper | MSG_LEXNAMEERR, lex );               
 834                }
 835             }
 836             else
 837             {               
 838                *((( puint )off)++) = toki->left->type;
 839                *(puint)off = toki->left->oftype;
 840             }
 841          case FTOK_GLOBFUNC://Глобальная функция         
 842             parsc -= 2 * toki->pars;                        
 843             pfunc = bc_func( lex, toki->pars, parsc );            
 844             toki->type = pfunc->ret->type;
 845             toki->oftype = pfunc->ret->oftype;            
 846             if ( pfunc->vmo.flag & GHBC_RESULT )
 847             {
 848                //Заводим фиктивную локальную переменную
 849                out_add2uint( CVarload, var_addtmp( toki->type, toki->oftype ));
 850             }
 851             out_adduint( pfunc->vmo.id );
 852 
 853             if ( ((( pvmobj )PCMD( toki->type ))->flag & GHTY_STACK ) && 
 854                   ( toki->flg & FTOK_LVALUE ))
 855                msg( MExplvalue | MSG_LEXERR, lex );
 856             break;
 857 
 858          case FTOK_SIZEOF:                                    
 859             if ( toki->parofsize )
 860             {  
 861                if ( toki->pars != 1 )
 862                   msg( MCountpars | MSG_LEXNAMEERR, lex );                              
 863                out_add2uint( CDwload, (( povmtype )PCMD( toki->parofsize ))->size );               
 864             }
 865             else
 866             {               
 867                parsc -= 2 * toki->pars;
 868                out_adduint( bc_funcname( lex, "sizeof", toki->pars, parsc )->vmo.id);               
 869             }
 870             toki->type = TUint;
 871             toki->oftype = 0;            
 872             break;
 873 
 874          case FTOK_SUBFUNC: //Локальная функция
 875             //Подфункция
 876             //Проверка совпадения типов параметров
 877             parsc -= 2 * toki->pars;
 878             pvar = ( pfvar)(fd.bvars.data + toki->offlocvar );
 879             if ( pvar->pars == toki->pars )
 880             {
 881                psrc = (puint)(fd.bvardef.data + pvar->offbvardef );
 882                parsb = parsc;
 883                for ( i = 0; i < toki->pars; i++ )
 884                {
 885                   if ( *psrc != *parsb )
 886                      goto errpars;
 887                   parsb++;
 888                   psrc++;
 889                   if ( *( pubyte )( ((pubyte)psrc)++ ) & VAR_OFTYPE )
 890                   {
 891                      if ( *psrc != *parsb )
 892                         goto errpars;
 893                      psrc++;
 894                   }
 895                   else
 896                      if ( *parsb )
 897                         goto errpars;
 898                   parsb++;
 899                   continue;
 900 errpars:
 901                   msg( MTypepars | MSG_LEXNAMEERR, lex );
 902                }
 903             }
 904             else
 905             {
 906                msg( MCountpars | MSG_LEXNAMEERR, lex );
 907             }
 908             toki->type = pvar->type;
 909             toki->oftype = pvar->oftype;
 910             out_add2uint( CSubcall, pvar->addr );
 911             if ( ((( pvmobj )PCMD( toki->type ))->flag & GHTY_STACK ) && 
 912                   ( toki->flg & FTOK_LVALUE ))
 913                msg( MExplvalue | MSG_LEXERR, lex );
 914             break;
 915 
 916          case FTOK_COLLECTNEW: //Создание переменной с типом коллекция
 917             //Заводим переменную и загружаем её в стэк            
 918             D( "FTOK_COLLECTNEW\n" );
 919             out_add2uint( CVarload, var_addtmp( TCollection, 0 ));
 920             break;
 921 
 922          case FTOK_COLLECT: //Загрузка коллекции             
 923             if ( toki->flg & FTOK_COLLECTIONLATE && (toki+1)->flg & FTOK_LVALUE )
 924                break;            
 925 latecol:
 926             
 927             if ( flglvallate )
 928             {
 929                toktmp = toki;
 930                toki = toki->left - 1;
 931                lex = toki->lex;
 932                toki->pars++;
 933             }
 934             D( "FTOK_COLLECT\n" );
 935             if ( toki->pars )
 936             {
 937                parse = parsc;
 938                parsc -= 2 * toki->pars;             
 939                parsb = parsc;               
 940                parsc -= 2;
 941                type = 0; //Тип предыдущего элемента
 942                num = 0;//Количество dword одного типа
 943                off = fd.bout->use + sizeof( uint );
 944                out_add2uint( CDwsload, 0 );//Команда загрузки последовательности dword
 945                                         //Количество загружаемых dwords
 946                dwsize = 0;//Общий размер данных в dword, 1=последний тип
 947                numtypes = 1;//Количество описаний типов
 948                for ( ; parsb < parse; parsb += 2 )
 949                {
 950                   if ( *parsb )
 951                   {
 952                      dwsize += stsize = (( povmtype )PCMD( *parsb ))->stsize;
 953                      if ( *parsb != type || num == 0xFF )
 954                      {  //Смена типа или большой размер
 955                         if ( type )
 956                         {  //Запись типа и количества
 957                            out_adduint( ( num << 24 ) | type );
 958                            numtypes++;
 959                         }
 960                         type = *parsb;
 961                         num = 0;
 962                      }
 963                      num += stsize;
 964                   }
 965                }
 966                *( puint )( fd.bout->data + off ) = numtypes;
 967                //Запись последнего элемента
 968                out_adduints( 3, ( num << 24 ) | type, CCollectadd, dwsize + numtypes );
 969             }
 970             toki->type = TCollection;
 971             toki->oftype = 0;
 972             if ( flglvallate )
 973             {
 974                goto late;
 975             }
 976             break;
 977 
 978          case FTOK_LATE:             
 979             if ( toki->flg & FTOK_LVALUE )
 980             {               
 981                toki->flg |= FTOK_LVALLATE;
 982                break;
 983             }
 984 late:
 985             D( "FTOK_LATE\n" );
 986             if ( flglvallate )
 987             {
 988                toki = toki + 1;               
 989             }                                    
 990             
 991             out_adduints( 3, CResload,
 992                         bc_resource( lexem_getname( toki->lex ) ),
 993                         bc_find( toki->lex, "res_getstr", 1, TUint));
 994             
 995             if ( toki->lex->flag & LEXF_METHOD )
 996             {
 997                parsc -= 2;
 998                type = toki->left->type;
 999             }
1000             else
1001             {
1002                type = (toki-3)->type;
1003             }
1004 
1005             //Вызов метода является отложенным
1006             if ( flglvallate )
1007             {
1008                name = "@setval";
1009             }
1010             else
1011             {
1012                if ( toki + 1 < tokc ) //является ли лексема последней нет операций в стэке
1013                {
1014                   //   является ли следующая лексема FTOK_LATE
1015                   if (  ((toki+1)->flg & FTOK_NOFLAGS) == FTOK_COLLECTNEW &&
1016                         (toki+1)->flg & FTOK_COLLECTIONLATE )
1017                   {
1018                      name = "@getobj";
1019                   }
1020                   else
1021                   {
1022                      name = "@getval";
1023                   }
1024                }
1025                else
1026                {
1027                   name = "@call";
1028                }
1029             }
1030             
1031             //Формируем параметры методов
1032             parsb = parsc;
1033             *(parsb++) = type;
1034             *(parsb++) = 0;            
1035             *(parsb++) = TCollection;
1036             *(parsb++) = 0;
1037             *(parsb++) = TStr;
1038             *(parsb++) = 0;
1039                         
1040             pfunc = bc_funcname( lex, name, 3, parsc );                        
1041 
1042             toki->type = pfunc->ret->type;
1043             toki->oftype = pfunc->ret->oftype;
1044             
1045             if ( pfunc->vmo.flag & GHBC_RESULT )
1046             {
1047                //Заводим фиктивную локальную переменную
1048                out_add2uint( CVarload, var_addtmp( toki->type, toki->oftype ) );
1049             }
1050             out_adduint( pfunc->vmo.id );
1051             
1052             if ( flglvallate )
1053             {               
1054                toki = toktmp;
1055                flglvallate = 0;
1056             }            
1057             break;
1058 
1059          case FTOK_ADDRFUNC://Вызов функции по указателю
1060 
1061             out_adduint( ( lex->key == KEY_FUNC) ? CCmdcall : CCallstd );
1062             dwsize = 0;
1063             parsb = parsc;
1064             parsc -= 2 * toki->pars;            
1065             while ( parsb > parsc )
1066             {
1067                parsb -= 2;
1068                dwsize += (( povmtype)PCMD( *parsb ))->stsize;
1069             }
1070             if ( lex->key == KEY_STDCALL )
1071                out_adduint( 0 );
1072             else if (lex->key == KEY_CDECL )
1073                out_adduint( 1 );
1074             out_adduint( dwsize );            
1075             toki->type = TUint;
1076             toki->oftype = 0;            
1077             break;
1078 
1079          case FTOK_ARR://Массив
1080             parsc -= 2 * toki->pars;
1081             
1082             pfunc = bc_funcname( lex, "@index", toki->pars, parsc );
1083             if ( pfunc->vmo.flag & GHBC_RESULT )
1084             {
1085                //Заводим фиктивную локальную переменную
1086                out_add2uint( CVarload, var_addtmp( pfunc->ret->type, pfunc->ret->oftype ));
1087             }
1088             out_adduint( pfunc->vmo.id );
1089             
1090 
1091             if ( !toki->left->oftype )
1092             {
1093                if ( !( toki->type = (( povmtype)PCMD( toki->left->type ))->index.type ))
1094                {
1095                   toki->type = TUint;
1096                }
1097             }
1098             else
1099             {
1100                toki->type = toki->left->oftype;
1101             }
1102             toki->oftype = 0;
1103 
1104             if ( !(toki->flg & FTOK_LVALUE) &&
1105                  (( pvmobj )PCMD( toki->type ))->flag & GHTY_STACK )
1106             {
1107                out_adduint( artypes[ toki->type ]  );
1108             }
1109             break;
1110 
1111          case FTOK_FIELD://Поле            
1112             if ( (toki-1)->flg & FTOK_WITH )
1113             {               
1114                isfield = 0;
1115                for ( pwith = ( pfwith)( fd.bwith.data + fd.bwith.use ) - 1; 
1116                      pwith >= ( pfwith )fd.bwith.data; pwith-- )
1117                {                  
1118                   if ( isfield = type_fieldname( pwith->type, lexem_getname( lex ) ) )
1119                       break;                
1120                   if ( toki->flg & FTOK_LVALUE )
1121                   {                     
1122                      pfunc = bc_isproperty( lex, pwith->type );                                      
1123                   }
1124                   else
1125                   {
1126                      parsb = parsc;
1127                      *( parsb++ ) = pwith->type;
1128                      *( parsb++ ) = 0;
1129                      pfunc = bc_method( lex, 1, parsc );
1130                   }
1131                   if ( pfunc )
1132                       break;
1133                }
1134                if ( isfield || pfunc )
1135                {                  
1136                   (toki-1)->type = pwith->type;
1137                   *( puint )(fd.bout->data + (toki-1)->offout + sizeof( uint )) = 
1138                            pwith->num;
1139                }
1140                else
1141                {
1142                    msg( MUnkoper | MSG_LEXNAMEERR, lex );
1143                }
1144             }            
1145             isfield = type_field( lex, (toki-1)->type );            
1146             if ( isfield )
1147             {               
1148                field = isfield;
1149                off = field->off;
1150                while ( toki + 1 < tokc && ((toki+1)->flg & FTOK_NOFLAGS ) == FTOK_FIELD )
1151                {
1152                   lex = (++toki)->lex;
1153                   isfield = type_field( lex, field->type );
1154                   if ( isfield )
1155                   {
1156                      field = isfield;
1157                      off += field->off;
1158                   }
1159                   else
1160                   {
1161                      toki--;
1162                      break;
1163                   }
1164                }
1165                toki->type = field->type;
1166                toki->oftype = field->oftype;
1167                if ( off )
1168                {
1169                   out_adduints( 3, CDwload, off, CAddUIUI );
1170                }
1171                if ( !( toki->flg & FTOK_LVALUE ) &&
1172                      (( pvmobj )PCMD( toki->type ))->flag & GHTY_STACK )
1173                {
1174                   out_adduint( artypes[ toki->type ] );
1175                }
1176                if (!isfield) toki++;
1177             }            
1178             if (!isfield)//Поле является свойством
1179             {    
1180                if ( toki->flg & FTOK_LVALUE )
1181                {
1182                   toki->flg |= FTOK_LVALPROPERTY;
1183                }
1184                else
1185                {  
1186                   pfunc = bc_property( lex, (toki-1)->type, 0 );                                  
1187                   toki->type = pfunc->ret->type;
1188                   toki->oftype = pfunc->ret->oftype;                  
1189                   if ( pfunc->vmo.flag & GHBC_RESULT )
1190                   {  //Заводим фиктивную локальную переменную
1191                      out_add2uint( CVarload, var_addtmp( toki->type, toki->oftype ));
1192                   }
1193                   out_adduint( pfunc->vmo.id );                                    
1194                }
1195                
1196             }
1197             break;
1198 
1199          case FTOK_NUMBER:  //Число
1200             if ( (( povmtype)PCMD( toki->type ))->stsize == 2 )
1201             {
1202                out_adduint( CQwload );
1203                out_addulong( lex->num.vlong );
1204             }
1205             else
1206                out_add2uint( CDwload, lex->num.vint );
1207             break;
1208 
1209          case FTOK_TYPE: //Получение идентификатора типа
1210             //toki->oftype = 0;
1211             type = toki->type;
1212             if ( toki < tokc - 1 &&
1213                  ( (( toki+1 )->flg & FTOK_NOFLAGS ) == FTOK_OPER ) &&
1214                   ( toki+1 )->lex->oper.operid == OpAs )
1215             {               
1216                break;
1217             }
1218             out_add2uint( type >= KERNEL_COUNT ? CCmdload : CDwload, type );
1219             toki->oftype = 0;
1220             toki->type = TUint;
1221             break;
1222 
1223          case FTOK_PTRTYPE: //Приведение указателя к типу            
1224             if ( !( toki->flg & FTOK_LVALUE ) && 
1225                   (( pvmobj )PCMD( toki->type ))->flag & GHTY_STACK )
1226                out_adduint( artypes[ toki->type ] );            
1227             break;
1228 
1229          case FTOK_OPER: //Системная лексема, оператор,            
1230             curop = (psoper)&opers[curop_id = lex->oper.operid];
1231             if ( curop_id == OpAs )
1232             {
1233                if ( ( toki->left->flg & FTOK_NOFLAGS ) == FTOK_LOCVAR )
1234                {
1235                   pvar = ( pfvar )(fd.bvars.data + toki->left->offlocvar );
1236                   if ( pvar->flg & FVAR_UINTAS || toki->left->type == TUint )
1237                   {
1238                      if ( toki->flg & FTOK_LVALUE )
1239                         msg( MExplvalue | MSG_LEXERR, lex );
1240 
1241                      buf_expand( &fd.bvarsas, sizeof( fvaras ));
1242                      pvaras = (( pfvaras )(fd.bvarsas.data + fd.bvarsas.use ));
1243                      fd.bvarsas.use += sizeof( fvaras );
1244 
1245                      pvaras->offbvar = toki->left->offlocvar;
1246                      pvaras->type = pvar->type;
1247                      pvaras->oftype = pvar->oftype;
1248 
1249                      pvar->type = (toki-1)->type;
1250                      pvar->oftype = (toki-1)->oftype;
1251 
1252                      if ( (toki-1)->type != TUint &&
1253                           (( pvmobj )PCMD( (toki - 1)->type ))->flag & GHTY_STACK )
1254                         msg( MAsright | MSG_LEXERR, lex );
1255                      pvar->flg |= FVAR_UINTAS;
1256                      if ( ((toki-1)->flg & FTOK_NOFLAGS) == FTOK_TYPE )
1257                      {
1258                         *(puint)(fd.bout->data + toki->left->offout ) = CVarload;
1259                      }
1260                      else
1261                      {
1262                         if ( toki->left->type != TUint )
1263                         {
1264                            *(puint)(fd.bout->data + toki->left->offout ) = CVarptrload;
1265                         }
1266                         out_adduint( CSetI );
1267                      }
1268                      toki->type = (toki-1)->type;
1269                      toki->oftype = (toki-1)->oftype;
1270                      break;
1271                   }
1272                }
1273                msg( MAsleft | MSG_LEXERR, lex );
1274             }
1275             else if ( curop_id == OpStrtext || curop_id == OpStrout ||
1276                        ( curop_id == OpStradd && !toki->left->type ) )//?
1277             {
1278                if ( type_isinherit( (toki-1)->type, TStr ) )
1279                   out_adduint( CSetText );
1280                else if ( !( ( (toki-1)->flg & FTOK_TEXT ) ||
1281                     (((toki-1)->flg & FTOK_NOFLAGS) == FTOK_OPER  &&
1282                     ((toki-2)->flg & FTOK_NOFLAGS) == FTOK_ADDRFUNC )))
1283                   msg( MVarstr | MSG_LEXERR, lex );
1284                toki->type = 0;
1285                toki->oftype = 0;
1286                break;
1287             }
1288             else  if ( curop_id == OpAddset &&
1289                           toki->left->type == TCollection )
1290             {
1291                out_adduints( 4, CDwload,
1292                            ( 1 << 24 ) | (toki-1)->type,//Тип правого операнда
1293                            CCollectadd,
1294                            (( povmtype )PCMD( (toki-1)->type ))->stsize + 1 );
1295                toki->type = TCollection;
1296                toki->oftype = 0;
1297                break;
1298             }
1299             else if ( curop_id == OpStradd )
1300             {
1301                if ( (toki-1)->flg & FTOK_TEXT ||
1302                     (((toki-1)->flg & FTOK_NOFLAGS) == FTOK_OPER  &&
1303                     ((toki-2)->flg & FTOK_NOFLAGS) == FTOK_ADDRFUNC ))
1304                {
1305                   toki->type = TStr;
1306                   toki->oftype = 0;
1307                   break;
1308                }
1309                else
1310                {                    
1311                   lex->oper.operid = OpAddset;                  
1312                }
1313             }
1314             if ( (toki->left && ( toki->left->flg & FTOK_LVALPROPERTY )) ||
1315                  ((toki-1)->flg & FTOK_LVALPROPERTY ))
1316             {
1317                if ( curop_id == OpSet )
1318                {                  
1319                   pfunc = bc_property( toki->left->lex, (toki->left-1)->type, 
1320                                        (toki-1)->type );                
1321                   out_adduint( pfunc->vmo.id );
1322                   toki->type = pfunc->ret->type;
1323                   toki->oftype = pfunc->ret->oftype;
1324                }
1325                else
1326                {
1327                   if ( curop_id == OpAddr )
1328                   {
1329                      pfunc = bc_property( (toki-1)->lex, (toki-2)->type, 0 );                                  
1330                      toki->type = pfunc->ret->type;
1331                      toki->oftype = pfunc->ret->oftype;                  
1332                      if ( pfunc->vmo.flag & GHBC_RESULT )
1333                      {  //Заводим фиктивную локальную переменную
1334                         out_add2uint( CVarload, var_addtmp( toki->type, toki->oftype ));
1335                      }
1336                      out_adduint( pfunc->vmo.id );
1337 
1338                      if ( ((( pvmobj )PCMD( toki->type ))->flag & GHTY_STACK ) )
1339                         msg( MExplvalue | MSG_LEXERR, lex );
1340                      toki->type = TUint; 
1341                      toki->oftype = 0</