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