@@ -63,6 +63,15 @@ void LuaParser::Next() {
6363 _invalid = true ;
6464}
6565
66+ void LuaParser::NextAs (LuaTokenKind kind) {
67+ auto me = MarkEvent (MarkEventType::EatToken);
68+ me.U .Token .Kind = kind;
69+ me.U .Token .Index = _tokenIndex;
70+ _events.push_back (me);
71+ _tokenIndex++;
72+ _invalid = true ;
73+ }
74+
6675LuaTokenKind LuaParser::LookAhead () {
6776 std::size_t nextIndex = _tokenIndex + 1 ;
6877
@@ -103,6 +112,14 @@ LuaTokenKind LuaParser::Current() {
103112 return _current;
104113}
105114
115+ std::string_view LuaParser::CurrentText () {
116+ if (_tokenIndex < _tokens.size ()) {
117+ auto range = _tokens[_tokenIndex].Range ;
118+ return _file->GetSource ().substr (range.StartOffset , range.GetEndOffset () - range.StartOffset + 1 );
119+ }
120+ return " " ;
121+ }
122+
106123void LuaParser::SkipComment () {
107124 for (; _tokenIndex < _tokens.size (); _tokenIndex++) {
108125 switch (_tokens[_tokenIndex].TokenType ) {
@@ -453,6 +470,12 @@ void LuaParser::GotoStatement() {
453470// exprStat -> call | assignment
454471// assignment -> varList '=' exprList
455472void LuaParser::ExpressionStatement () {
473+ if (Current () == TK_NAME && CurrentText () == " global" ) {
474+ if (TryGlobalStatement ()) {
475+ return ;
476+ }
477+ }
478+
456479 auto m = Mark ();
457480 SuffixedExpression ();
458481 if (Current () == ' =' || Current () == ' ,' ) {
@@ -475,6 +498,66 @@ void LuaParser::ExpressionStatement() {
475498 }
476499}
477500
501+ bool LuaParser::TryGlobalStatement () {
502+ auto m = Mark ();
503+ switch (LookAhead ()) {
504+ case ' *' :
505+ Next ();// Global
506+ Next ();
507+
508+ TestAndNext (' ;' );
509+ m.Complete (*this , LuaSyntaxNodeKind::GlobalStatement);
510+ return true ;
511+ case ' <' :
512+ Next ();// Global
513+ LocalAttribute ();
514+
515+ switch (Current ()) {
516+ case TK_NAME:
517+ GlobalNameList ();
518+ break ;
519+ case ' *' :
520+ Next ();
521+ break ;
522+ default :
523+ break ;
524+ }
525+ TestAndNext (' ;' );
526+ m.Complete (*this , LuaSyntaxNodeKind::GlobalStatement);
527+ return true ;
528+ case TK_FUNCTION:
529+ Next ();// Global
530+ Next ();// Function
531+ CheckName ();
532+ FunctionBody ();
533+ TestAndNext (' ;' );
534+ m.Complete (*this , LuaSyntaxNodeKind::FunctionStatement);
535+ break ;
536+ case TK_NAME:
537+ Next ();// Global
538+ GlobalNameList ();
539+ TestAndNext (' ;' );
540+ m.Complete (*this , LuaSyntaxNodeKind::GlobalStatement);
541+ return true ;
542+ default :
543+ break ;
544+ }
545+
546+ m.Undo (*this );
547+ return false ;
548+ }
549+
550+ void LuaParser::GlobalNameList () {
551+ do {
552+ CheckName ();
553+ LocalAttribute ();
554+ } while (TestAndNext (' ,' ));
555+
556+ if (TestAndNext (' =' )) {
557+ ExpressionList ();
558+ }
559+ }
560+
478561void LuaParser::Condition () {
479562 Expression ();
480563}
@@ -692,6 +775,9 @@ void LuaParser::ParamList() {
692775 case TK_DOTS: {
693776 isVararg = true ;
694777 Next ();
778+ if (Current () == TK_NAME) {
779+ Next ();
780+ }
695781 break ;
696782 }
697783 case ' )' : {
0 commit comments