diff --git a/src/StgSharp.RegularAnalysis/Text/TextRegexSourceGen.GenClass.SingleIR.cs b/src/StgSharp.RegularAnalysis/Text/TextRegexSourceGen.GenClass.SingleIR.cs index 14ca3d24..4def43ef 100644 --- a/src/StgSharp.RegularAnalysis/Text/TextRegexSourceGen.GenClass.SingleIR.cs +++ b/src/StgSharp.RegularAnalysis/Text/TextRegexSourceGen.GenClass.SingleIR.cs @@ -88,8 +88,8 @@ namespace StgSharp.RegularAnalysis.Text return -1; } string group_name = pack.GroupName; - string begin = sc.GroupBegin(group_name); - string end = sc.GroupEnd(group_name); + string begin = sc.GetVarGroupBegin(group_name); + string end = sc.GetVarGroupEnd(group_name); _ = code.AppendLine(begin).AppendLine(end); return 1; } @@ -165,17 +165,21 @@ namespace StgSharp.RegularAnalysis.Text string counter = sc.RequireNewCounter(); // TODO cannot check real count outside the cycle - _ = code.AppendLine($@"int {counter} = 0;", // + _ = code.AppendLine($@"int {counter} = 0;", // @$"for(; {counter}<{leave}; {counter}++)", // "{", // - @$"if({sc.InputSpan}[{sc.Position}..].StartWith({literal}))", // + @$"if(!{sc.RemainingSpan}.StartWith({literal}))", // "{", // - @$"{sc.Position}+={seq.Length};", // + $@"break;", // "}", // "}", // - @$"if({counter}>{min})", // TODO match here + @$"if({counter}>{min})", // + "{", // in case match + sc.MakeRemainOffset(counter), // + "}", // $@"else", // - "}"); // TODO fail here + "{", // TODO fail here + "}"); // return 1; } @@ -192,10 +196,13 @@ namespace StgSharp.RegularAnalysis.Text } string seq = match_seq.Pattern; string literal = FormatStringLiteral(seq); - _ = code.AppendLine(@$"if({sc.InputSpan}[{sc.Position}..].StartWith({literal}))") + _ = code.AppendLine(@$"if({sc.RemainingSpan}.StartWith({literal}))") .AppendLine("{") .AppendLine($"{sc.StepResult} = true;") - .AppendLine($@"{sc.Position} += {seq.Length};") + .AppendLine(sc.MakeRemainOffset(seq.Length)) + .AppendLine("}") + .AppendLine("else") + .AppendLine("{")//TODO fail here .AppendLine("}"); return 1; } @@ -237,7 +244,7 @@ namespace StgSharp.RegularAnalysis.Text _case_code = GenLine(set, sc, ")"); _ = code.AppendLine(_case_code) .AppendLine("{") - .AppendLine("-------------------------------------")// TODO case success + .AppendLine(sc.MakeRemainOffset(1))// TODO case success .AppendLine("}"); return 1; } @@ -245,9 +252,11 @@ namespace StgSharp.RegularAnalysis.Text private static string GenLine( RegexCharSet set, SourceGenContext sc, - string end_of_line + string end_of_line, + string symbol_of_offset = "" ) { + string offset = string.IsNullOrEmpty(symbol_of_offset) ? "0" : $"{symbol_of_offset}"; switch (set.Type) { case CharSetType.Single: @@ -256,7 +265,7 @@ namespace StgSharp.RegularAnalysis.Text { // more than 8 different chars, using string match string literal = FormatStringLiteral(cases); - return $@"{literal}.Contains({sc.InputSpan}[{sc.Position}]) {end_of_line}"; + return $@"{literal}.Contains({sc.RemainingSpan}[{offset}]) {end_of_line}"; } else { StringBuilder sb = new(); @@ -265,10 +274,10 @@ namespace StgSharp.RegularAnalysis.Text for (int j = 0; j < cases.Length - 1; j++) { literal = FormatCharLiteral(cases[j]); - _ = sb.Append(CultureInfo.InvariantCulture, $@"{sc.InputSpan}[{sc.Position}] == {literal} ||"); + _ = sb.Append(CultureInfo.InvariantCulture, $@"{sc.RemainingSpan}[{offset}] == {literal} ||"); } literal = FormatCharLiteral(cases[^1]); - _ = sb.Append(CultureInfo.InvariantCulture, $@"{sc.InputSpan}[{sc.Position}] == {literal}") + _ = sb.Append(CultureInfo.InvariantCulture, $@"{sc.RemainingSpan}[{offset}] == {literal}") .Append(CultureInfo.InvariantCulture, @$") {end_of_line}"); return sb.ToString(); } @@ -276,15 +285,15 @@ namespace StgSharp.RegularAnalysis.Text string rule = set.Value; char lo = rule[0]; char hi = rule[1]; - return $@"({sc.InputSpan}[{sc.Position}] >= '{lo}' && {sc.InputSpan}[{sc.Position}] <= '{hi}') {end_of_line}"; + return $@"({sc.RemainingSpan}[{offset}] >= '{lo}' && {sc.RemainingSpan}[{offset}] <= '{hi}') {end_of_line}"; case CharSetType.Set: string accept_mark = set.Accept ? string.Empty : "!"; return set.Value switch { - "s" => $@"{accept_mark}char.IsWhiteSpace({sc.InputSpan}[{sc.Position}]) {end_of_line}", - "d" => $@"{accept_mark}char.IsDigit({sc.InputSpan}[{sc.Position}]) {end_of_line}", - "w" => $@"{accept_mark}IsCharWord({sc.InputSpan}[{sc.Position}]) {end_of_line}", + "s" => $@"{accept_mark}char.IsWhiteSpace({sc.RemainingSpan}[{offset})] {end_of_line}", + "d" => $@"{accept_mark}char.IsDigit({sc.RemainingSpan}[{offset})] {end_of_line}", + "w" => $@"{accept_mark}IsCharWord({sc.RemainingSpan}[{offset})] {end_of_line}", _ => string.Empty }; case CharSetType.None: diff --git a/src/StgSharp.RegularAnalysis/Text/TextRegexSourceGen.GenClass.cs b/src/StgSharp.RegularAnalysis/Text/TextRegexSourceGen.GenClass.cs index cf550287..18ac24ce 100644 --- a/src/StgSharp.RegularAnalysis/Text/TextRegexSourceGen.GenClass.cs +++ b/src/StgSharp.RegularAnalysis/Text/TextRegexSourceGen.GenClass.cs @@ -269,6 +269,7 @@ namespace StgSharp.RegularAnalysis.Text _ = sb.Append(c); } list.Add(new(sb.ToString(), CharSetType.Single, true)); + return [.. list]; } else { for (; seq.Length > 0; ) @@ -343,7 +344,7 @@ namespace StgSharp.RegularAnalysis.Text case 'd': sets.Add(new("d", CharSetType.Set, accept)); break; - case '['or'('or')'or']'or'\\'or'\"': + case '[' or '(' or ')' or ']' or '\\' or '\"': _ = single_char.Add(remain[pos + 1]); break; default: diff --git a/src/StgSharp.RegularAnalysis/Text/TextRegexSourceGen.GenContext.cs b/src/StgSharp.RegularAnalysis/Text/TextRegexSourceGen.GenContext.cs index 5cf3f20f..6186a4e5 100644 --- a/src/StgSharp.RegularAnalysis/Text/TextRegexSourceGen.GenContext.cs +++ b/src/StgSharp.RegularAnalysis/Text/TextRegexSourceGen.GenContext.cs @@ -5,6 +5,7 @@ // SPDX-License-Identifier: MIT // ----------------------------------------------------------------------------- +using Microsoft.CodeAnalysis.Text; using StgSharp.RegularAnalysis.Abstraction; using System; using System.Collections.Generic; @@ -29,11 +30,6 @@ namespace StgSharp.RegularAnalysis.Text private sealed class SourceGenContext { - /// - /// Active pointer. Indexes the next unconsumed element of the input. - /// - public const string _cursor = "__cur"; - /// /// Name of the match method parameter holding the input sequence. /// @@ -54,7 +50,7 @@ namespace StgSharp.RegularAnalysis.Text private readonly SortedSet _lineSlots = []; private readonly SortedSet _regionSlots = []; - public string Position { get; } = _cursor; + public string RemainingSpan { get; } = "__remaining_span"; public string InputSpan { get; } = _inputSpan; @@ -75,7 +71,7 @@ namespace StgSharp.RegularAnalysis.Text return null!; } - _ = emitter.AppendLine($@"int {_cursor} = 0;") + _ = emitter.AppendLine($@"{ROS_char} {RemainingSpan} = {_inputSpan};") .AppendLine($@"bool {_stepResult} = true;"); foreach (int region in _regionSlots) { @@ -95,14 +91,14 @@ namespace StgSharp.RegularAnalysis.Text return emitter; } - public string GroupBegin( + public string GetVarGroupBegin( string name ) { return $"__g{ResolveGroup(name)}_begin"; } - public string GroupEnd( + public string GetVarGroupEnd( string name ) { @@ -133,6 +129,20 @@ namespace StgSharp.RegularAnalysis.Text return $"__l{line}_ok"; } + public string MakeRemainOffset( + string offset_name + ) + { + return @$"{RemainingSpan} = {RemainingSpan}[{offset_name}..];"; + } + + public string MakeRemainOffset( + int offset + ) + { + return @$"{RemainingSpan} = {RemainingSpan}[{offset}..];"; + } + /// /// Records that some prefix observes the result of the instruction at line .