Browse Source

Fix: backslash with real newline in short literal doesn't work

Akeit0 9 months ago
parent
commit
6a842ede57

+ 15 - 1
src/Lua/CodeAnalysis/Syntax/Lexer.cs

@@ -311,6 +311,7 @@ public ref struct Lexer
             var quote = c1;
             var stringStartOffset = offset;
             var isTerminated = false;
+            var escape = false;
 
             while (span.Length > offset)
             {
@@ -318,12 +319,20 @@ public ref struct Lexer
 
                 if (c is '\n' or '\r')
                 {
+                    if (escape)
+                    {
+                        escape = false;
+                        Advance(1);
+                        continue;
+                    }
+
                     break;
                 }
 
                 if (c is '\\')
                 {
                     Advance(1);
+                    escape = true;
                     if (span.Length <= offset) break;
                 }
                 else if (c == quote)
@@ -331,7 +340,12 @@ public ref struct Lexer
                     isTerminated = true;
                     break;
                 }
+                else
+                {
+                    escape = false;
+                }
 
+                
                 Advance(1);
             }
 
@@ -534,4 +548,4 @@ public ref struct Lexer
             ('a' <= c && c <= 'z') ||
             StringHelper.IsNumber(c);
     }
-}
+}

+ 3 - 7
src/Lua/Internal/StringHelper.cs

@@ -38,11 +38,6 @@ internal static class StringHelper
                         break;
                     case '\r':
                         builder.Append('\r');
-                        // check CRLF
-                        if (i + 1 < literal.Length && literal[i + 1] is '\n')
-                        {
-                            i++;
-                        }
                         break;
                     case 'a':
                         builder.Append('\a');
@@ -306,6 +301,7 @@ internal static class StringHelper
                             builder.Append(c);
                             break;
                     }
+
                     isEscapeSequence = false;
                 }
             }
@@ -358,7 +354,7 @@ internal static class StringHelper
     public static bool IsDigit(char c)
     {
         return IsNumber(c) ||
-            ('a' <= c && c <= 'f') ||
-            ('A' <= c && c <= 'F');
+               ('a' <= c && c <= 'f') ||
+               ('A' <= c && c <= 'F');
     }
 }

+ 19 - 0
tests/Lua.Tests/ParserTests.cs

@@ -25,5 +25,24 @@ end";
             Assert.That(actual, Is.TypeOf<IfStatementNode>());
             Assert.That(actual.ToString(), Is.EqualTo(expected.ToString()));
         }
+        
+        [Test]
+        public void Test_MultiLine_ShortString()
+        {
+            var source = 
+"""
+print "Hello,\
+World!"
+""";
+            var actual = LuaSyntaxTree.Parse(source).Nodes[0]; 
+             Assert.That(actual, Is.TypeOf<CallFunctionStatementNode>());
+             var literal =((StringLiteralNode)((CallFunctionStatementNode)actual).Expression.ArgumentNodes[0]).Text.ToString();
+             Assert.That(literal,  Is.EqualTo(
+                 """
+                 Hello,\
+                 World!
+                 """
+                 ));
+        }
     }
 }