Browse Source

Update: support `\ddd` escape sequence

AnnulusGames 1 year ago
parent
commit
184f171f7d
2 changed files with 39 additions and 5 deletions
  1. 12 3
      src/Lua/CodeAnalysis/Compilation/LuaCompiler.cs
  2. 27 2
      src/Lua/Internal/StringHelper.cs

+ 12 - 3
src/Lua/CodeAnalysis/Compilation/LuaCompiler.cs

@@ -69,9 +69,18 @@ public sealed class LuaCompiler : ISyntaxNodeVisitor<ScopeCompilationContext, bo
 
 
     public bool VisitStringLiteralNode(StringLiteralNode node, ScopeCompilationContext context)
     public bool VisitStringLiteralNode(StringLiteralNode node, ScopeCompilationContext context)
     {
     {
-        var str = node.IsShortLiteral
-            ? StringHelper.FromStringLiteral(node.Text.Span)
-            : node.Text.ToString();
+        string? str;
+        if (node.IsShortLiteral)
+        {
+            if (!StringHelper.TryFromStringLiteral(node.Text.Span, out str))
+            {
+                throw new LuaParseException(context.Function.ChunkName, node.Position, $"invalid escape sequence near '{node.Text}'");
+            }
+        }
+        else
+        {
+            str = node.Text.ToString();
+        }
 
 
         var index = context.Function.GetConstantIndex(str);
         var index = context.Function.GetConstantIndex(str);
         context.PushInstruction(Instruction.LoadK(context.StackPosition, index), node.Position, true);
         context.PushInstruction(Instruction.LoadK(context.StackPosition, index), node.Position, true);

+ 27 - 2
src/Lua/Internal/StringHelper.cs

@@ -1,3 +1,4 @@
+using System.Diagnostics.CodeAnalysis;
 using System.Runtime.CompilerServices;
 using System.Runtime.CompilerServices;
 using System.Text;
 using System.Text;
 
 
@@ -17,7 +18,7 @@ internal static class StringHelper
         return i > j ? "" : s.AsSpan()[(i - 1)..j];
         return i > j ? "" : s.AsSpan()[(i - 1)..j];
     }
     }
 
 
-    public static string FromStringLiteral(ReadOnlySpan<char> literal)
+    public static bool TryFromStringLiteral(ReadOnlySpan<char> literal, [NotNullWhen(true)] out string? result)
     {
     {
         var builder = new ValueStringBuilder(literal.Length);
         var builder = new ValueStringBuilder(literal.Length);
         for (int i = 0; i < literal.Length; i++)
         for (int i = 0; i < literal.Length; i++)
@@ -66,6 +67,29 @@ internal static class StringHelper
                     case ']':
                     case ']':
                         builder.Append(']');
                         builder.Append(']');
                         break;
                         break;
+                    default:
+                        if (char.IsDigit(c))
+                        {
+                            var start = i;
+                            for (int j = 0; j < 3; j++)
+                            {
+                                if (i >= literal.Length) break;
+                                i++;
+                                c = literal[i];
+                                if (!char.IsDigit(c)) break;
+                            }
+
+                            Console.WriteLine((char)int.Parse(literal[start..i]));
+
+                            builder.Append((char)int.Parse(literal[start..i]));
+                            i--;
+                        }
+                        else
+                        {
+                            result = null;
+                            return false;
+                        }
+                        break;
                 }
                 }
             }
             }
             else
             else
@@ -74,6 +98,7 @@ internal static class StringHelper
             }
             }
         }
         }
 
 
-        return builder.ToString();
+        result = builder.ToString();
+        return true;
     }
     }
 }
 }