22
22
#include "lstring.h"
23
23
#include "ltable.h"
24
24
#include "lzio.h"
25
+ #include "lauxlib.h"
25
26
26
27
27
28
#define next (ls ) (ls->current = ls->mpos < ls->mlen ? char2int(ls->mstr[ls->mpos++]) : zgetc(ls->z))
@@ -483,6 +484,31 @@ static int llex (LexState *ls, SemInfo *seminfo) {
483
484
char q = ls -> current ;
484
485
switch (q )
485
486
{
487
+ case '(' :
488
+ {
489
+ next (ls );
490
+ q = ls -> current ;
491
+ next (ls );
492
+ for (;;) {
493
+ if (ls -> current == q ) {
494
+ next (ls );
495
+ if (ls -> current == ')' ) {
496
+ next (ls ); break ;
497
+ } else {
498
+ save (ls , q );
499
+ save_and_next (ls );
500
+ }
501
+ } else if (ls -> current == EOZ )
502
+ luaX_lexerror (ls , "unfinished macro function definition" , 0 );
503
+ else if (ls -> current == '\n' ) {
504
+ ++ ls -> linenumber ;
505
+ save_and_next (ls );
506
+ }
507
+ else save_and_next (ls );
508
+ }
509
+ q = '(' ;
510
+ break ;
511
+ }
486
512
case '\'' :
487
513
case '"' :
488
514
{
@@ -491,8 +517,13 @@ static int llex (LexState *ls, SemInfo *seminfo) {
491
517
{
492
518
if (ls -> current == EOZ )
493
519
luaX_lexerror (ls , "unfinished string at macro definition" , 0 );
494
- if (ls -> current == '\n' )
520
+ else if (ls -> current == '\n' )
495
521
luaX_lexerror (ls , "unfinished string at macro definition" , TK_STRING );
522
+ else if (ls -> current == '\\' ) {
523
+ save_and_next (ls );
524
+ if (ls -> current == EOZ )
525
+ luaX_lexerror (ls , "unfinished string at macro definition" , TK_STRING );
526
+ }
496
527
save_and_next (ls );
497
528
}
498
529
save_and_next (ls );
@@ -538,7 +569,12 @@ static int llex (LexState *ls, SemInfo *seminfo) {
538
569
case '-' : case '0' : case '1' : case '2' : case '3' : case '4' :
539
570
case '.' : case '5' : case '6' : case '7' : case '8' : case '9' :
540
571
{
541
- while (!isspace (ls -> current ) && ls -> current != EOZ ) save_and_next (ls );
572
+ if (q == '-' ) {
573
+ save_and_next (ls );
574
+ if (!isdigit (ls -> current ) && ls -> current != '.' )
575
+ luaX_lexerror (ls , "invalid number at macro definition" , 0 );
576
+ }
577
+ while (isalnum (ls -> current ) || ls -> current == '.' ) save_and_next (ls );
542
578
break ;
543
579
}
544
580
case '`' : case '~' : case '!' : case '#' : case '$' : case '%' : case '^' :
@@ -570,6 +606,12 @@ static int llex (LexState *ls, SemInfo *seminfo) {
570
606
if (val ) strcpy (val , ls -> buff -> buffer );
571
607
lua_pushstring (L , val );
572
608
luaZ_resetbuffer (ls -> buff );
609
+ if (q == '(' ) {
610
+ if (luaL_loadstring (L , val ))
611
+ luaX_lexerror (ls , lua_tostring (L , -1 ), 0 );
612
+ else
613
+ lua_remove (L , -2 );
614
+ }
573
615
lua_rawset (L , -3 );
574
616
lua_setglobal (L , MACRO );
575
617
free (key );
@@ -584,6 +626,96 @@ static int llex (LexState *ls, SemInfo *seminfo) {
584
626
save (ls , '\0' );
585
627
char * k = ls -> buff -> buffer ;
586
628
lua_getfield (L , -1 , k );
629
+
630
+ if (lua_isfunction (L , -1 )) {
631
+ lua_newtable (L );
632
+ lua_pushstring (L ,getstr (ls -> source ));
633
+ lua_rawseti (L ,-2 ,0 );
634
+ if (ls -> current != '(' )
635
+ luaX_lexerror (ls , "invalid macro function call" , 0 );
636
+ int parens = 1 ;
637
+ next (ls );
638
+ int t , i ;
639
+ for (i = 1 ; ;i ++ ) {
640
+ t = llex (ls , seminfo );
641
+ if (t == ')' && -- parens == 0 ) break ;
642
+ else if (t == '(' ) ++ parens ;
643
+ switch (t )
644
+ {
645
+ case TK_EOS : case EOZ :
646
+ luaX_lexerror (ls , "unfinished macro function call" , 0 );
647
+ case TK_STRING :
648
+ {
649
+ const char * str = getstr (seminfo -> ts );
650
+ TString * ts = seminfo -> ts ;
651
+ size_t len = ts -> tsv .len ;
652
+ char * res = (char * ) malloc (4 * len + 2 );
653
+ res [0 ] = '"' ;
654
+ size_t j = 0 ;
655
+ size_t i ;
656
+ for (i = 0 ; i < len ; i ++ ) {
657
+ switch (str [i ])
658
+ {
659
+ case '\a' : res [++ j ] = '\\' ; res [++ j ] = 'a' ; break ;
660
+ case '\b' : res [++ j ] = '\\' ; res [++ j ] = 'b' ; break ;
661
+ case '\f' : res [++ j ] = '\\' ; res [++ j ] = 'f' ; break ;
662
+ case '\t' : res [++ j ] = '\\' ; res [++ j ] = 't' ; break ;
663
+ case '\v' : res [++ j ] = '\\' ; res [++ j ] = 'v' ; break ;
664
+ case '\n' : res [++ j ] = '\\' ; res [++ j ] = 'n' ; break ;
665
+ case '\r' : res [++ j ] = '\\' ; res [++ j ] = 'r' ; break ;
666
+ case '"' : res [++ j ] = '\\' ; res [++ j ] = '"' ; break ;
667
+ case '\0' :
668
+ res [++ j ] = '\\' ;
669
+ res [++ j ] = '0' ;
670
+ res [++ j ] = '0' ;
671
+ res [++ j ] = '0' ;
672
+ break ;
673
+ default :
674
+ res [++ j ] = str [i ];
675
+ break ;
676
+ }
677
+ }
678
+ res [++ j ] = '"' ;
679
+ res [++ j ] = '\0' ;
680
+ lua_pushstring (L , res );
681
+ free (res );
682
+ break ;
683
+ }
684
+ case TK_NAME :
685
+ lua_pushstring (L ,getstr (seminfo -> ts ));
686
+ break ;
687
+ case TK_NUMBER :
688
+ {
689
+ const char * str = ls -> buff -> buffer ;
690
+ if (str [0 ] == '0' ) lua_pushstring (L ,str );
691
+ else {
692
+ char * res = (char * ) malloc (strlen (str ) + 1 );
693
+ res [0 ] = '\0' ;
694
+ strcat (res , "0" );
695
+ strcat (res , str );
696
+ lua_pushstring (L ,res );
697
+ }
698
+ break ;
699
+ }
700
+ default :
701
+ if (t < FIRST_RESERVED )
702
+ {
703
+ char s [2 ]= {t ,0 };
704
+ lua_pushstring (L ,s );
705
+ }
706
+ else
707
+ lua_pushstring (L ,luaX_tokens [t - FIRST_RESERVED ]);
708
+ break ;
709
+ }
710
+ lua_rawseti (L ,-2 ,i );
711
+ }
712
+ lua_call (L ,1 ,1 );
713
+ if (!lua_isstring (L , -1 ))
714
+ luaX_lexerror (ls , "macro function call should return string" , 0 );
715
+ lua_pushstring (L , " " );
716
+ lua_concat (L , 2 );
717
+ }
718
+
587
719
if (lua_isstring (L , -1 )) {
588
720
luaZ_resetbuffer (ls -> buff );
589
721
const char * s = lua_tostring (L , -1 );
0 commit comments