EnglishРусский  

   ..

   alias.c

   alias.h

   bcodes.c

   bcodes.h

   body.c

   compile.c

   compile.h

   define.c

   define.h

   desc.c

   expr.c

   extern.c

   for.c

   foreach.c

   func.c

   func.h

   global.c

   global.h

   goto.c

   if.c

   ifdef.c

   ifdef.h

   import.c

   import.h

   include.c

   include.h

   jump.c

   lexem.c

   lexem.h

   macro.c

   macro.h

   operlist.txt

   out.c

   out.h

   subfunc.c

   switch.c

   type.c

   type.h

   vars.c

   while.c

   with.c

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

Ads

Installer and installation software
Commercial and Freeware installers.

   1 /******************************************************************************
   2 *
   3 * Copyright (C) 2006, The Gentee Group. All rights reserved. 
   4 * This file is part of the Gentee open source project - http://www.gentee.com. 
   5 * 
   6 * THIS FILE IS PROVIDED UNDER THE TERMS OF THE GENTEE LICENSE ("AGREEMENT"). 
   7 * ANY USE, REPRODUCTION OR DISTRIBUTION OF THIS FILE CONSTITUTES RECIPIENTS 
   8 * ACCEPTANCE OF THE AGREEMENT.
   9 *
  10 * ID: lexem 18.10.06 0.0.A.
  11 *
  12 * Author: Alexey Krivonogov ( gentee )
  13 *
  14 * Summary: Working with lexems
  15 *
  16 ******************************************************************************/
  17 
  18 #include "lexem.h"
  19 #include "compile.h"
  20 #include "../genteeapi/gentee.h"
  21 #include "../lex/lex.h"
  22 #include "../lex/lexgentee.h"
  23 #include "operlist.h"
  24 #include "ifdef.h"
  25 #include "macro.h"
  26 #include "../common/file.h"
  27 
  28 uint _istext; // processing text function
  29 uint _ishex;  // /h mode in binary
  30 uint _bimode; // 1 2 4 or 8 in binary
  31 
  32 /*-----------------------------------------------------------------------------
  33 *
  34 * ID: lexem_delete 30.10.06 0.0.A.
  35 * 
  36 * Summary: Delete the array of lexems.
  37 *
  38 -----------------------------------------------------------------------------*/
  39 
  40 void  STDCALL  lexem_delete( parr lexems )
  41 {
  42 /*   plexem pil, end;
  43 
  44    pil = ( plexem )arr_ptr( lexems, 0 );
  45    end = ( plexem )arr_ptr( lexems, arr_count( lexems ));
  46    while ( pil < end )
  47    {
  48       if ( pil->type == LEXEM_STRING )
  49          str_delete( &pil->string );
  50       if ( pil->type == LEXEM_BINARY )
  51          buf_delete( &pil->binary );
  52       pil++;
  53    }*/
  54    arr_delete( lexems );
  55 }
  56 
  57 /*-----------------------------------------------------------------------------
  58 *
  59 * ID: lexem_isys 30.10.06 0.0.A.
  60 * 
  61 * Summary: If a lexem equals a character.
  62 *
  63 -----------------------------------------------------------------------------*/
  64 
  65 uint  STDCALL lexem_isys( plexem plex, uint ch )
  66 {
  67    return ( plex->type == LEXEM_OPER && plex->oper.name == ch );
  68 }
  69 
  70 /*-----------------------------------------------------------------------------
  71 *
  72 * ID: lexem_new 30.10.06 0.0.A.
  73 * 
  74 * Summary: Create a new lexem.
  75 *
  76 -----------------------------------------------------------------------------*/
  77 
  78 plexem  STDCALL  lexem_new( parr lexems, uint pos, uint type, uint param )
  79 {
  80    plexem     pl;
  81 
  82    pl = ( plexem )arr_append( lexems );
  83    pl->pos = pos;
  84    pl->type = ( ubyte )type;
  85    switch ( type )
  86    {
  87       case LEXEM_OPER:
  88          pl->oper.name = param;
  89          if ( param == ';' )
  90             pl->oper.operid = OpLine;
  91          else
  92             pl->oper.operid = hash_getuint( &_compile->opers, ( pubyte )¶m );
  93          break;
  94       case LEXEM_NUMBER:
  95          num_getval( str_ptr( _compile->cur->src ) + pos, &pl->num );
  96          break;
  97       case LEXEM_STRING:
  98       case LEXEM_FILENAME:
  99          pl->strid = arr_count( &_compile->string ) - 1;
 100          break;
 101       case LEXEM_BINARY:
 102          pl->binid = arr_count( &_compile->binary ) - 1;
 103          break;
 104    }
 105    return pl;
 106 }
 107 
 108 /*-----------------------------------------------------------------------------
 109 *
 110 * ID: lexem_line 30.10.06 0.0.A.
 111 * 
 112 * Summary: Create a new line lexem.
 113 *
 114 -----------------------------------------------------------------------------*/
 115 
 116 plexem  STDCALL  lexem_line( parr lexems, uint pos )
 117 {
 118    return lexem_new( lexems, pos, LEXEM_OPER, ';' );
 119 }
 120 
 121 /*-----------------------------------------------------------------------------
 122 *
 123 * ID: lexem_name 30.10.06 0.0.A.
 124 * 
 125 * Summary: Create LEXEM_NAME lexem.
 126 *
 127 -----------------------------------------------------------------------------*/
 128 
 129 plexem  STDCALL  lexem_nameptr( parr lexems, uint pos, uint value, pubyte name )
 130 {
 131    phashitem  phi;
 132    plexem     pl;
 133 
 134    phi = hash_create( &_compile->names, name );
 135 //   printf("%s = %i pos = %i len = %i\n", name, phi->id, pil->pos, pil->len );
 136    pl = ( plexem )arr_append( lexems );
 137    pl->pos = pos;
 138    if ( value )
 139    {
 140       pl->type = LEXEM_KEYWORD;
 141       pl->key = value;
 142    }
 143    else
 144    {
 145       pl->type = LEXEM_NAME;
 146       pl->nameid = phi->id;
 147    }
 148    return pl;
 149 }
 150 
 151 /*-----------------------------------------------------------------------------
 152 *
 153 * ID: lexem_name 30.10.06 0.0.A.
 154 * 
 155 * Summary: Create LEXEM_NAME lexem.
 156 *
 157 -----------------------------------------------------------------------------*/
 158 
 159 plexem  STDCALL  lexem_name( parr lexems, plexitem pil )
 160 {
 161    ubyte      name[256];
 162 //   phashitem  phi;
 163 //   plexem     pl;
 164 
 165    if ( pil->len > 255 )
 166       msg( MLongname | MSG_EXIT | MSG_POS, pil->pos );
 167 
 168    mem_copy( name, str_ptr( _compile->cur->src ) + pil->pos, pil->len );
 169    if ( name[ pil->len - 1 ] == '$' ) // Для макросов $name$
 170       pil->len--;
 171    name[ pil->len ] = 0;
 172 
 173    return lexem_nameptr( lexems, pil->pos, pil->value, name );
 174 /*   phi = hash_create( &_compile->names, name );
 175 //   printf("%s = %i pos = %i len = %i\n", name, phi->id, pil->pos, pil->len );
 176    pl = ( plexem )arr_append( lexems );
 177    pl->pos = pil->pos;
 178    if ( pil->value )
 179    {
 180       pl->type = LEXEM_KEYWORD;
 181       pl->key = pil->value;
 182    }
 183    else
 184    {
 185       pl->type = LEXEM_NAME;
 186       pl->nameid = phi->id;
 187    }
 188    return pl;*/
 189 }
 190 
 191 /*-----------------------------------------------------------------------------
 192 *
 193 * ID: lexem_str2macro 30.10.06 0.0.A.
 194 * 
 195 * Summary: Convert $name or $name$ in strings or binary to LEXEM_MACRO.
 196 *
 197 -----------------------------------------------------------------------------*/
 198 
 199 void  STDCALL  lexem_str2macro( parr lexems, plexitem litem, plexitem pil, 
 200                                 uint off )
 201 {
 202    uint    len = 1;
 203    uint    j = off + len;
 204    pubyte  ptr = str_ptr( _compile->cur->src ) + pil->pos;
 205 
 206    while ( _name[ ptr[ j ]] )
 207       j++;
 208    if ( ptr[ j ] == '$' )
 209       j++;
 210 
 211    litem->type = G_MACRO;
 212    litem->pos = pil->pos + off;
 213    litem->len = j - off;
 214    litem->value = 0;
 215 
 216    lexem_name( lexems, litem )->type = LEXEM_MACRO;
 217 
 218    litem->pos = pil->pos + j;
 219    litem->len = pil->len - j;
 220 }
 221 
 222 /*-----------------------------------------------------------------------------
 223 *
 224 * ID: lexem_macrostr 30.10.06 0.0.A.
 225 * 
 226 * Summary: Create LEXEM_STRING lexem from MACROSTR.
 227 *
 228 -----------------------------------------------------------------------------*/
 229 
 230 uint  STDCALL  lexem_macrostr( parr lexems, plexitem pil, uint shift, uint type )
 231 {
 232    pstr      out;
 233    pubyte    ptr, cur;
 234    uint      i, end;
 235    plexem    pl;
 236 
 237    if ( !pil->len ) 
 238       return 1;
 239    out = str_init( ( pstr )arr_append( &_compile->string ));
 240    ptr = str_ptr( str_reserve( out, pil->len ));
 241 
 242    pl = lexem_new( lexems, pil->pos, type, 0 );
 243    end = pil->len - ( type == LEXEM_STRING ? 1 : 0 );
 244 /*   pl = ( plexem )arr_append( lexems );
 245    pl->pos = pil->pos;
 246    pl->type = LEXEM_STRING;
 247    pl->strid = arr_count( &_compile->string ) - 1;*/
 248 
 249    cur = str_ptr( _compile->cur->src ) + pil->pos;
 250    for ( i = shift; i < end; i++ )
 251    {
 252       if ( type == LEXEM_STRING && cur[ i ] == '"' )
 253       {
 254          *ptr++ = '"';
 255          i++;
 256       }
 257       else
 258          if ( cur[ i ] == '$' )
 259          {
 260             if ( _name[ cur[ i + 1 ]] != 2 ) /* не имя */
 261             {
 262                *ptr++ = '$';
 263                if ( cur[ i + 1 ] == '$' )
 264                   i++;
 265             }
 266             else
 267             {
 268                lexitem  litem;
 269 
 270                *ptr = 0;
 271                str_setlen( out, ptr - str_ptr( out ));
 272                lexem_str2macro( lexems, &litem, pil, i );
 273                lexem_macrostr( lexems, &litem, 0, type );
 274                return 1;
 275             }
 276          }
 277          else
 278             *ptr++ = cur[i];
 279    }
 280 //   if ( cur[i] != '"' )
 281 //      msg( MUneofsb | MSG_LEXERR, pl );
 282 
 283    *ptr = 0;
 284    str_setlen( out, ptr - str_ptr( out ));
 285    return 1;
 286 }
 287 
 288 /*-----------------------------------------------------------------------------
 289 *
 290 * ID: lexem_oper 30.10.06 0.0.A.
 291 * 
 292 * Summary: Create LEXEM_OPER lexem.
 293 *
 294 -----------------------------------------------------------------------------*/
 295 
 296 plexem  STDCALL  lexem_oper( parr lexems, uint pos, uint lexsys )
 297 {
 298  /*  plexem     pl;
 299 
 300    pl = ( plexem )arr_append( lexems );
 301    pl->pos = pos;
 302    pl->type = LEXEM_OPER;
 303    pl->oper.name = lexsys;
 304    pl->oper.operid = hash_getuint( &_compile->opers, ( pubyte )&lexsys );;*/
 305    return lexem_new( lexems, pos, LEXEM_OPER, lexsys );
 306 }
 307 
 308 /*-----------------------------------------------------------------------------
 309 *
 310 * ID: lexem_string 30.10.06 0.0.A.
 311 * 
 312 * Summary: Create LEXEM_STRING lexem from MACROSTR.
 313 *
 314 -----------------------------------------------------------------------------*/
 315 
 316 uint  STDCALL  lexem_endtext( parr lexems, uint pos )
 317 {
 318    _istext = 0;
 319    lexem_oper( lexems, pos, '}' );
 320    return 1;
 321 }
 322 
 323 /*-----------------------------------------------------------------------------
 324 *
 325 * ID: lexem_emptystr 30.10.06 0.0.A.
 326 * 
 327 * Summary: Create empty LEXEM_STRING lexem.
 328 *
 329 -----------------------------------------------------------------------------*/
 330 
 331 plexem  STDCALL  lexem_emptystr( parr lexems, uint pos )
 332 {
 333    str_init( ( pstr )arr_append( &_compile->string ));
 334   
 335    return lexem_new( lexems, pos, LEXEM_STRING, 0 );
 336 }
 337 
 338 /*-----------------------------------------------------------------------------
 339 *
 340 * ID: lexem_string 30.10.06 0.0.A.
 341 * 
 342 * Summary: Create LEXEM_STRING lexem from MACROSTR.
 343 *
 344 -----------------------------------------------------------------------------*/
 345 
 346 uint  STDCALL  lexem_string( parr lexems, plexitem pil, uint shift, uint text )
 347 {
 348    pstr      out;
 349    pubyte    ptr, cur, start;
 350    ubyte     ch, prev;
 351    uint      i, k, len, pos;
 352    plexem    pl;
 353    lexitem   litem;
 354 
 355    if ( !pil->len ) 
 356       return 1;
 357 
 358    cur = str_ptr( _compile->cur->src ) + pil->pos;
 359    if ( shift && cur[ 0 ] == ')' )
 360    {
 361       lexem_oper( lexems, pil->pos, ')' );
 362       if ( !text )
 363          lexem_oper( lexems, pil->pos, LSYS_PLUSEQ )->oper.operid = OpStrappend;
 364    }
 365    if ( text )
 366    {
 367       lexem_line( lexems, pil->pos );
 368       lexem_oper( lexems, pil->pos, 0 )->oper.operid = OpStrtext;
 369    }
 370 
 371    out = str_init( ( pstr )arr_append( &_compile->string ));
 372    start = ptr = str_ptr( str_reserve( out, pil->len ));
 373    
 374 /*   pl = ( plexem )arr_append( lexems );
 375    pl->pos = pil->pos;
 376    pl->type = LEXEM_STRING;
 377    pl->strid = arr_count( &_compile->string ) - 1;*/
 378    pl = lexem_new( lexems, pil->pos, LEXEM_STRING, 0 );
 379 //   print("String pos=%i len = %i\n", pil->pos, pil->len );
 380    for ( i = shift; i < pil->len - 1; i++ )
 381    {
 382       if ( cur[i] == '\\' )
 383       {
 384          pos = pil->pos + i;
 385          i++;
 386 //         print("String x=%i %c\n", i, cur[i] );
 387          switch ( cur[ i ] )
 388          {
 389             case '\\' :
 390             case '"' :
 391                *ptr++ = cur[ i ];
 392                break;
 393             case 'r' :
 394                *ptr++ = 0xd;
 395                break;
 396             case 'n' :
 397                *ptr++ = 0xa;
 398                break;
 399             case 't' :
 400                *ptr++ = 0x9;
 401                break;
 402             case 'l' :
 403                *ptr++ = 0xd;
 404                *ptr++ = 0xa;
 405                break;
 406             case 0xd :
 407             case 0xa :
 408                if ( cur[ i ] == 0xd && cur[ i + 1 ] == 0xa )
 409                   i++;
 410                break;
 411             case '#':
 412                if ( ptr > start )
 413                   ch = *--ptr;
 414                while ( ptr > start )
 415                {
 416                   prev = *( ptr - 1 );
 417                   if ( ch== prev || (( ch == 0xa || ch == 0xd ) && 
 418                       ( prev == 0xa || prev == 0xd )) ||
 419                       (( ch == ' ' || ch == 0x9 ) && 
 420                       ( prev == ' ' || prev == 0x9 )) )
 421                      ptr--;
 422                   else
 423                      break;
 424                }
 425                break;
 426             case '0':
 427                i++;
 428                *ptr++ = ( _hex[cur[ i ]] << 4 ) + _hex[ cur[ i + 1 ]];
 429                i++;
 430                break;
 431             case '*':  // Надо ли это?
 432                while ( ++i < pil->len - 1 )
 433                {
 434                   if ( cur[ i ] == '*' && cur[ i + 1 ] == '\\' )
 435                      break;
 436                }
 437                i++;
 438                break;
 439             case '$':
 440                *ptr = 0;
 441                str_setlen( out, ptr - str_ptr( out ));
 442                
 443                lexem_str2macro( lexems, &litem, pil, i );
 444                lexem_string( lexems, &litem, 0, text );
 445                return 1;
 446             case '[':
 447                k = i;
 448                len = 1;
 449                while ( ++k < pil->len - 1 && cur[ k ] != ']' )
 450                len = k - i + 1;
 451                   
 452                while ( ++k < pil->len - 1 )
 453                {
 454                   if ( cur[ k ] == '[' && !mem_cmp( cur + k, cur + i, len ))
 455                   {
 456                      k += len;
 457                      break;
 458                   }
 459                   *ptr++ = cur[k];
 460                }
 461                i = k;
 462                break;
 463             case '(':       
 464                if ( text )
 465                {
 466                   lexem_line( lexems, pos );
 467                   lexem_oper( lexems, pos, '@' );
 468                   lexem_emptystr( lexems, pos );
 469                   // Может быть новый alloc для элементов
 470                   // Надо присваивать заново !
 471                   out = ( pstr )arrdata_get( &_compile->string, 
 472                                  arr_count( &_compile->string ) - 2 );
 473  //                 lexem_oper( lexems, pos, 0 )->oper.operid = OpStrset;
 474 //                  lexem_oper( lexems, pos, '(' );
 475                }
 476 //               else
 477 //               {
 478                   // +=
 479                   lexem_oper( lexems, pos, LSYS_PLUSEQ )->oper.operid = OpStrappend;
 480                   lexem_oper( lexems, pos, '(' );
 481 //               }
 482                goto stop;
 483             default:
 484                if ( text )
 485                {
 486                   switch ( cur[ i ] )
 487                   {
 488                      case '!' :
 489                         lexem_endtext( lexems, pos );
 490                         goto stop;
 491                      case '{' :
 492                         lexem_line( lexems, pos );
 493                         goto stop;
 494                      case '@' :
 495                         lexem_line( lexems, pos );
 496                         lexem_oper( lexems, pos, '@' );
 497                         goto stop;
 498                   } 
 499                }
 500                msg( MUnksbcmd | MSG_EXIT | MSG_VALUE | MSG_POS, pos, 
 501                     cur[ i ] );
 502          }
 503 //         i++;
 504          continue;
 505       }
 506       *ptr++ = cur[i];
 507    }
 508 //   if ( cur[i] != '"' && cur[ i + 1 ] != '\\' )
 509 //      msg( MUneofsb | MSG_LEXERR, pl );
 510 //end:
 511 //   if ( text )
 512 //   {
 513 //      if ( cur[ i + 1 ]!= '!' && cur[ i + 1 ] != '(' && cur[ i + 1 ] != '{')
 514 //         *ptr++ = cur[ pil->len - 1 ];
 515 //   }
 516 //   else
 517       if ( cur[ pil->len - 1 ] != '"' )//&& cur[ pil->len - 1 ] != '(')
 518          *ptr++ = cur[ pil->len - 1 ];
 519 stop:
 520    *ptr = 0;
 521    str_setlen( out, ptr - str_ptr( out ));
 522 //   print( "Out=%s len=%i num=%i\n", str_ptr( out ), str_len( out ),
 523 //          arr_count( &_compile->string ));
 524    return 1;
 525 }
 526 
 527 /*-----------------------------------------------------------------------------
 528 *
 529 * ID: lexem_binary 30.10.06 0.0.A.
 530 * 
 531 * Summary: Create LEXEM_BINARY lexem.
 532 *
 533 -----------------------------------------------------------------------------*/
 534 
 535 uint  STDCALL  lexem_binary( parr lexems, plexitem pil, uint shift )
 536 {
 537    pbuf      out;
 538    pubyte    cur;
 539    uint      i, k, pos;
 540    plexem    pl;
 541    lexitem   litem;
 542    number    num;
 543 
 544    if ( !pil->len ) 
 545       return 1;
 546 
 547    cur = str_ptr( _compile->cur->src ) + pil->pos;
 548    if ( shift && cur[ 0 ] == ')' )
 549    {
 550       lexem_oper( lexems, pil->pos, ')' );
 551       lexem_oper( lexems, pil->pos, LSYS_PLUSEQ )->oper.operid = OpStrappend;
 552    }
 553 
 554    out = buf_init( ( pstr )arr_append( &_compile->binary ));
 555    buf_reserve( out, pil->len );
 556    
 557    pl = lexem_new( lexems, pil->pos, LEXEM_BINARY, 0 );
 558 
 559    for ( i = shift; i < pil->len - 1; i++ )
 560    {
 561       if ( cur[i] <= ' ' || cur[i] == ',' || cur[i] == ';'  )
 562          continue;
 563       if ( cur[i] == '\\' )
 564       {
 565          pos = pil->pos + i;
 566          i++;
 567          switch ( cur[ i ] )
 568          {
 569             case '"':
 570                while ( ++i < pil->len - 1 )
 571                {
 572                   if ( cur[ i ] == '"' )
 573                      break;
 574                   buf_appendch( out, cur[i] );
 575                }
 576                break;
 577             case '*':
 578                while ( ++i < pil->len - 1 )
 579                {
 580                   if ( cur[ i ] == '*' && cur[ i + 1 ] == '\\' )
 581                      break;
 582                }
 583                i++;
 584                break;
 585             case '$':
 586                lexem_str2macro( lexems, &litem, pil, i );
 587                lexem_binary( lexems, &litem, 0 );
 588                // Может быть новый alloc для элементов
 589                // Надо присваивать заново !
 590                out = ( pbuf )arrdata_get( &_compile->binary, 
 591                               arr_count( &_compile->binary ) - 2 );
 592                return 1;
 593             case '(':       
 594                   // +=
 595                lexem_oper( lexems, pos, LSYS_PLUSEQ )->oper.operid = OpStrappend;
 596                lexem_oper( lexems, pos, '(' );
 597                return 1;
 598             case 'h':
 599             case 'i':
 600                _ishex = ( cur[ i ] == 'h' ? 1 : 0 );
 601                switch ( cur[ i + 1 ] ) {
 602                   case '2':
 603                   case '4':
 604                   case '8':
 605                      _bimode = cur[ ++i ] - '0';
 606                      break;
 607                   default:
 608                      _bimode = 1;
 609                      break;
 610                }
 611                break;
 612             default:
 613                msg( MUnksbcmd | MSG_EXIT | MSG_VALUE | MSG_POS, pos, 
 614                     cur[ i ] );
 615          }
 616          continue;
 617       }
 618       if ( _ishex )
 619          k = num_gethex( cur + i, &num, _bimode ) - cur;
 620       else
 621          k = num_getval( cur + i, &num ) - cur;
 622       if ( i == k )
 623          msg( MUnkbinch | MSG_EXIT | MSG_POS | MSG_VALUE, pil->pos + i, cur[i] );
 624       switch ( num.type )
 625       {
 626          case TFloat:
 627             buf_append( out, ( pubyte )&num.vfloat, sizeof( float ));
 628             break;
 629          case TLong:
 630          case TUlong:
 631          case TDouble:
 632             buf_append( out, ( pubyte )&num.vdouble, sizeof( double ));
 633             break;
 634          default:
 635 //               printf("Append =%i i=%i k=%i\n", num.vint, i, k );
 636             buf_append( out, ( pubyte )&num.vint, _bimode );
 637       }
 638       i = k - 1;
 639 //      *ptr++ = cur[i];
 640    }
 641 //   if ( cur[ pil->len - 1 ] != '\'' )//&& cur[ pil->len - 1 ] != '(')
 642 //         *ptr++ = cur[ pil->len - 1 ];
 643 //stop:
 644 //   *ptr = 0;
 645 //   str_setlen( out, ptr - str_ptr( out ));
 646 
 647 //   printf( str_ptr( out ));
 648    return 1;
 649 }
 650 
 651 /* -----------------------------------------------------------------------------
 652 *
 653 * ID: lexem_number 30.10.06 0.0.A.
 654 * 
 655 * Summary: Create LEXEM_NUMBER lexem.
 656 *
 657 ----------------------------------------------------------------------------
 658 
 659 uint  STDCALL  lexem_number( parr lexems, plexitem pil )
 660 {
 661    plexem    pl;
 662 
 663    pl = ( plexem )arr_append( lexems );
 664    pl->pos = pil->pos;
 665    pl->type = LEXEM_NUMBER;
 666    num_getval( str_ptr( _compile->cur->src ) + pil->pos, &pl->num );
 667    return 1;
 668 }
 669 */
 670 
 671 /*-----------------------------------------------------------------------------
 672 *
 673 * ID: lexem_load 30.10.06 0.0.A.
 674 * 
 675 * Summary: The creating the array of lexems.
 676 *
 677 -----------------------------------------------------------------------------*/
 678 
 679 uint  STDCALL  lexem_load( parr lexems, parr input )
 680 {
 681    plexitem pil, end;
 682    uint     off = _compile->cur->off;
 683    pubyte   src = str_ptr( _compile->cur->src );
 684    uint     colon = 0;
 685    uint     lexsys, shift;
 686    plexem   plex;
 687 
 688    _istext = 0;
 689    arr_init( lexems, sizeof( lexem ));
 690    arr_step( lexems, 512 );
 691    arr_reserve( lexems, arr_count( input ) + 100 );
 692 
 693    if ( !arr_count( input ))
 694       return 1;
 695    pil = ( plexitem )arr_ptr( input, 0 );
 696    end = ( plexitem )arr_ptr( input, arr_count( input ));
 697    while ( pil < end )
 698    {
 699       pil->pos += off;
 700 //      printf("Pos=%i len=%i type=%X %s\n", pil->pos, pil->len, pil->type,
 701 //               src + pil->pos );
 702       switch ( pil->type )
 703       {
 704          case G_NAME:
 705             lexem_name( lexems, pil );
 706             break;
 707          case G_LINE:
 708             while ( colon )   // if ':' was
 709             {
 710                lexem_oper( lexems, pil->pos, '}' );
 711                colon--;
 712             }
 713             lexem_line( lexems, pil->pos );
 714             break;
 715          case G_OPERCHAR:
 716             switch ( src[ pil->pos ] )
 717             {
 718                case '(': 
 719                   (( plexem )arr_ptr( lexems, arr_count( lexems ) - 1 ))->flag |= LEXF_CALL;
 720                   break;
 721                case '[': 
 722                   (( plexem )arr_ptr( lexems, arr_count( lexems ) - 1 ))->flag |= LEXF_ARR;
 723                   break;
 724             }
 725             lexsys = 0;
 726             mem_copy( &lexsys, src + pil->pos, pil->len );
 727             lexem_oper( lexems, pil->pos, lexsys );
 728             break;
 729          case G_SYSCHAR:
 730             if ( src[ pil->pos ] == ';' )
 731                lexem_line( lexems, pil->pos );
 732             else
 733                if ( src[ pil->pos ] == ':' )
 734                {
 735                   lexem_oper( lexems, pil->pos, '{' );
 736                   colon++;
 737                }
 738             break;
 739          case G_NUMBER:
 740             lexem_new( lexems, pil->pos, LEXEM_NUMBER, 0 );
 741             break;
 742          case G_MACRO:
 743             lexem_name( lexems, pil )->type = LEXEM_MACRO;
 744             break;
 745          case G_MACROSTR:
 746             lexem_macrostr( lexems, pil, 2 /* $" */, LEXEM_STRING );
 747             break;
 748          case G_STRING:
 749             lexem_string( lexems, pil, ( src[ pil->pos ] == '"' ||
 750                           src[ pil->pos ] == ')' ) ? 1 : 0 /* " */, 0 );
 751             break;
 752          case G_TEXTSTR:
 753             if ( _istext ) 
 754                shift = 1;
 755             else
 756             {
 757                _istext = 1;
 758                shift = 0;
 759                lexem_oper( lexems, pil->pos, '{' );
 760 //               lexem_nameptr( lexems, pil->pos, 0, "str" );
 761 //               lexem_nameptr( lexems, pil->pos, 0, "text" );
 762 //               lexem_line( lexems, pil->pos );
 763             }
 764             lexem_string( lexems, pil, shift, 1 );
 765             break;
 766          case G_BINARY:
 767             if ( src[ pil->pos + 2 ] == '\'')
 768             {
 769                plex = lexem_new( lexems, pil->pos, LEXEM_NUMBER, 0 );
 770                plex->num.type = TUint;
 771                plex->num.vint = src[ pil->pos + 1 ];
 772                break;
 773             }
 774             if ( src[ pil->pos ] == '\'' )
 775             {
 776                _ishex = 1;
 777                _bimode = 1;
 778             }
 779             lexem_binary( lexems, pil, ( src[ pil->pos ] == '\'' ||
 780                           src[ pil->pos ] == ')' ) ? 1 : 0 /* ' */ );
 781             break;
 782          case G_FILENAME:
 783             lexem_macrostr( lexems, pil, 1 /* \< */, LEXEM_FILENAME );
 784             break;
 785       }
 786 //      printf("ID=%x pos=%i len=%i \n", pil->type, pil->pos, pil->len,
 787 //             input + pil->pos );
 788       pil++;
 789    }
 790    pil--;
 791    while ( colon )   // if ':' was
 792    {
 793       lexem_oper( lexems, pil->pos, '}' );
 794       colon--;
 795    }
 796    if ( _istext )
 797       lexem_endtext( lexems, pil->pos );
 798    // Проверка на незаконченные строки и двоичные данные
 799    lexsys = 0;
 800    switch ( pil->type )
 801    {
 802       case G_MACROSTR:
 803       case G_STRING:
 804          lexsys = '"';
 805          break;
 806       case G_FILENAME:
 807          lexsys = '>';
 808          break;
 809       case G_BINARY:
 810          lexsys = '\'';
 811          break;
 812    }
 813    if ( lexsys &&  src[ pil->pos + pil->len - 1 ] != lexsys )
 814       msg( MUneofsb | MSG_LEXERR, arr_top( lexems ));
 815    return 1;
 816 }
 817 
 818 /*-----------------------------------------------------------------------------
 819 *
 820 * ID: lexem_getname 30.10.06 0.0.A.
 821 * 
 822 * Summary: Get a pointer to name identifier.
 823 *
 824 -----------------------------------------------------------------------------*/
 825 
 826 pubyte  STDCALL  lexem_getname( plexem plex )
 827 {
 828    return hash_name( &_compile->names, plex->nameid );
 829 }
 830 
 831 /*-----------------------------------------------------------------------------
 832 *
 833 * ID: lexem_get 30.10.06 0.0.A.
 834 * 
 835 * Summary: Get a pointer to string, binary.
 836 *
 837 -----------------------------------------------------------------------------*/
 838 
 839 pstr  STDCALL  lexem_getstr( plexem plex )
 840 {
 841    switch ( plex->type )
 842    {
 843       case  LEXEM_STRING:
 844       case  LEXEM_FILENAME:
 845         return arrdata_get( &_compile->string, plex->strid );
 846       case  LEXEM_BINARY:
 847       case  LEXEM_COLLECT:
 848         return arrdata_get( &_compile->binary, plex->binid );
 849    }
 850    return 0;
 851 }
 852 
 853 /*-----------------------------------------------------------------------------
 854 *
 855 * ID: lexem_file 01.12.06 0.0.A.
 856 * 
 857 * Summary: Get the filename.
 858 *
 859 -----------------------------------------------------------------------------*/
 860 
 861 void lexem_file( plexem powner, plexem plex )
 862 {
 863    uint first = powner == plex ? 1 : 0;
 864    pstr output = lexem_getstr( powner );
 865    pbuf data = &_compile->cur->lexems->data;
 866 
 867    if ( *str_index( output, str_len( output ) - 1 ) == '>' )
 868    {
 869       powner->type = LEXEM_STRING;
 870       return;
 871    }
 872    plex++;
 873    if ( ( pubyte )plex >= data->data + data->use )
 874       goto error;
 875 
 876    if ( plex->type == LEXEM_MACRO )
 877    {
 878       plex = macro_get( plex );
 879       if ( plex->type == LEXEM_STRING )
 880          plex->type = LEXEM_FILENAME;
 881       else
 882          msg( MUnsmoper | MSG_LEXNAMEERR, plex );
 883    }
 884    if ( plex->type == LEXEM_FILENAME )
 885    {
 886       str_add( lexem_getstr( powner ), lexem_getstr( plex ));
 887       plex->type = LEXEM_SKIP;
 888       lexem_file( powner, plex );
 889       return;
 890    }
 891 error:
 892    msg( MUneofsb | MSG_LEXERR, powner );
 893 }
 894 
 895 /*-----------------------------------------------------------------------------
 896 *
 897 * ID: lexem_strbin 01.12.06 0.0.A.
 898 * 
 899 * Summary: Get the string or binary lexems.
 900 *
 901 -----------------------------------------------------------------------------*/
 902 
 903 void lexem_strbin( plexem powner, plexem plex )
 904 {
 905    uint first = powner == plex ? 1 : 0;
 906    pstr output;
 907    pbuf data = &_compile->cur->lexems->data;
 908 
 909    do 
 910    {
 911       plex++;
 912       if ( ( pubyte )plex >= data->data + data->use )
 913          return;
 914    }
 915    while ( plex->type == LEXEM_SKIP );
 916 
 917    if ( plex->type == LEXEM_MACRO )
 918       plex = macro_get( plex );
 919    if ( plex->type == LEXEM_FILENAME )
 920    {
 921       pstr sfile;
 922 
 923       lexem_file( plex, plex );
 924       sfile = str_trim( str_new( str_ptr( lexem_getstr( plex )) + 1 ), 
 925                                  '>', TRIM_RIGHT );
 926       file2buf( sfile, buf_init( ( pbuf )arr_append( &_compile->binary )), 
 927                 plex->pos );
 928       plex->type = LEXEM_BINARY;
 929       plex->binid = arr_count( &_compile->binary ) - 1;
 930       str_destroy( sfile );
 931    }
 932    if ( plex->type == LEXEM_STRING || plex->type == LEXEM_BINARY )
 933    {
 934       if ( first )
 935       {
 936          if ( powner->type == LEXEM_STRING )   
 937          {
 938             output = str_init( ( pstr )arr_append( &_compile->string ));
 939             str_copy( output, lexem_getstr(  powner ));
 940             powner->strid = arr_count( &_compile->string ) - 1;
 941          }
 942          else
 943          {
 944             output = buf_init( ( pbuf )arr_append( &_compile->binary ));
 945             buf_set( output, lexem_getstr(  powner ));
 946             powner->binid = arr_count( &_compile->binary ) - 1;
 947          }
 948       }
 949       else
 950          output = lexem_getstr( powner );
 951 
 952       if ( powner->type == LEXEM_STRING )   
 953       {
 954          str_add( output, lexem_getstr( plex ));
 955          // Добавились довичные данные без нуля в конце
 956          if ( plex->type == LEXEM_BINARY && buf_index( output, 
 957                 buf_len( output ) - 1 ))
 958             buf_appendch( output, 0 );
 959       }
 960       else
 961          buf_add( output, lexem_getstr( plex ));
 962 
 963       plex->type = LEXEM_SKIP;
 964       lexem_strbin( powner, plex );
 965 //      printf("OK 1=%i-%i - %s - %s------\n", plex->type, powner->strid, 
 966 //         str_ptr(lexem_getstr(  powner )), str_ptr( output  ));
 967    }
 968 }
 969 
 970 /*-----------------------------------------------------------------------------
 971 *
 972 * ID: lexem_get 30.10.06 0.0.A.
 973 * 
 974 * Summary: Get the next lexem. If plex == 0 returns the first lexem
 975 *
 976 -----------------------------------------------------------------------------*/
 977 
 978 plexem  STDCALL  lexem_next( plexem plex, uint flag )
 979 {
 980    pbuf data = &_compile->cur->lexems->data;
 981 
 982    if ( flag & LEXNEXT_LCURLY )
 983    {
 984 /*      while ( ( plex->type == LEXEM_OPER && plex->oper.operid == OpLine ) ||
 985              plex->type == LEXEM_SKIP )
 986          plex++;*/
 987       if ( !lexem_isys( plex, LSYS_LCURLY ))
 988          msg( MLcurly | MSG_POS | MSG_EXIT, plex->pos );
 989    }
 990    if ( flag & LEXNEXT_SKIPLINE )
 991    {
 992       while ( ( plex->type == LEXEM_OPER && plex->oper.operid == OpLine ) ||
 993              plex->type == LEXEM_SKIP )
 994          plex++;
 995       return plex;
 996    }
 997 
 998    if ( !plex )
 999       plex = ( plexem )data->data;
1000    else
1001       plex++;
1002 
1003 again:
1004    while ( 1 )
1005    {
1006       if ( ( pubyte )plex >= data->data + data->use )
1007       {    
1008          if ( flag & LEXNEXT_NULL )
1009             return 0;
1010          else
1011             msg( MUneof | MSG_POS | MSG_EXIT, str_len( _compile->cur->src ));
1012       }
1013       if ( flag & LEXNEXT_IGNLINE && plex->type == LEXEM_OPER && 
1014              plex->oper.operid == OpLine )
1015          goto next;
1016       if ( flag & LEXNEXT_IGNCOMMA && lexem_isys( plex, LSYS_COMMA ))
1017          goto next;
1018       if ( plex->type != LEXEM_SKIP )
1019          break;
1020 next:
1021       plex++;
1022    }
1023    if ( !( flag & LEXNEXT_NOMACRO ))
1024    {
1025       if ( plex->type == LEXEM_MACRO || ( plex->type == LEXEM_NAME && 
1026           !( flag & LEXNEXT_NAMEDEF )) )
1027          plex = macro_get( plex );
1028 
1029       if ( plex->type == LEXEM_STRING || plex->type == LEXEM_BINARY )
1030       {
1031          lexem_strbin( plex, plex );
1032 //      printf( "string= %i %s\n", plex->strid, str_ptr( lexem_getstr(  plex )));
1033       }
1034       if ( plex->type == LEXEM_KEYWORD && plex->key == KEY_IFDEF )
1035       {
1036          plex = ifdef( plex );
1037          goto again;
1038       }
1039    }
1040    if ( flag & LEXNEXT_NAME && plex->type != LEXEM_NAME )
1041       msg( MExpname | MSG_LEXERR, plex );
1042   
1043    return plex;
1044 }
1045 
1046 /*-----------------------------------------------------------------------------
1047 *
1048 * ID: lexem_copy 30.10.06 0.0.A.
1049 * 
1050 * Summary: Copy lexems
1051 *
1052 -----------------------------------------------------------------------------*/
1053 
1054 plexem STDCALL lexem_copy( plexem dest, plexem src )
1055 {
1056    uint pos = dest->pos;
1057    mem_copy( dest, src, sizeof( lexem ));
1058    dest->pos = pos;
1059    return dest;
1060 }
1061 
1062 //--------------------------------------------------------------------------
1063