PageRenderTime 48ms CodeModel.GetById 12ms RepoModel.GetById 0ms app.codeStats 1ms

/src/compiler/lexem.c

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