add single ir generator methods

This commit is contained in:
Youmu Liu
2026-08-03 20:03:16 +08:00
parent 85ca22d1aa
commit 029092b438
7 changed files with 280 additions and 118 deletions
@@ -72,9 +72,9 @@ namespace StgSharp.RegularAnalysis.Text
* lives in test/SingleFile/regex.cs.
*/
private const string current_ptr = "cur_ptr_global";
private const string offset = "offset";
private const string orig_text = "text";
// private const string current_ptr = "cur_ptr_global"; // global match cursor
// private const string offset = "offset"; //
// private const string orig_text = "text"; //
#region L0 method level
@@ -155,10 +155,11 @@ namespace StgSharp.RegularAnalysis.Text
.AppendLine($@"int region_{i}_end = -1;")
.AppendLine($@"bool region_{i}_success;");
}
/*
_ = se.AppendLine($@"int {current_ptr} = 0;")
.AppendLine($@"int {offset} = 0;")
.AppendLine();
/**/
// _ = sc.GenVarDefine(se);
@@ -177,6 +178,14 @@ namespace StgSharp.RegularAnalysis.Text
#endregion
private enum RegionExitMethod
{
Break,
Continue
}
#region shared helpers
[MethodImpl(MethodImplOptions.AggressiveInlining)]
@@ -224,14 +233,14 @@ namespace StgSharp.RegularAnalysis.Text
}
internal record struct RegexCharSet(
string Value,
CharSetType Type,
bool Accept
internal record class RegexCharSet(
string Value,
CharSetType Type,
bool Accept
)
{
public override readonly string ToString()
public override string ToString()
{
return $"{{value:{Value}, type:{Type}, accept:{Accept}}}";
}
@@ -244,34 +253,45 @@ namespace StgSharp.RegularAnalysis.Text
)
{
// range or single
HashSet<char> single_char = [];
if (source[0] == '[')
{
int idx;
accept = source[1] != '^';
idx = accept ? 1 : 2;
List<RegexCharSet> list = [];
ReadOnlySpan<char> seq = source.Slice(idx, source.Length - idx - 1);
if (seq.IndexOf('-') == -1)
{
return [new RegexCharSet(seq.ToString(), CharSetType.Single, true)];
SplitSet(single_char, seq, list);
StringBuilder sb = new();
foreach (char c in single_char) {
_ = sb.Append(c);
}
list.Add(new(sb.ToString(), CharSetType.Single, true));
} else
{
List<RegexCharSet> list = [];
for (; seq.Length > 0; )
{
int pos = seq.IndexOf('-');
if (pos == -1)
{
// has no range
SplitSet(seq, list);
SplitSet(single_char, seq, list);
break;
} else if (pos > 1)
{
// has other sequence before range
SplitSet(seq[0..(pos - 1)], list);
SplitSet(single_char, seq[0..(pos - 1)], list);
}
list.Add(new($"{seq[pos - 1]}{seq[pos + 1]}", CharSetType.Range, true));
seq = seq[(pos + 2)..];
}
StringBuilder sb = new();
foreach (char c in single_char) {
_ = sb.Append(c);
}
list.Add(new(sb.ToString(), CharSetType.Single, true));
return [.. list];
}
} else if (source[0] == '\\')
@@ -293,6 +313,7 @@ namespace StgSharp.RegularAnalysis.Text
}
static void SplitSet(
HashSet<char> single_char,
ReadOnlySpan<char> seq,
List<RegexCharSet> sets
)
@@ -310,19 +331,31 @@ namespace StgSharp.RegularAnalysis.Text
sets.Add(new RegexCharSet(singles.ToString(), CharSetType.Single, true));
}
bool accept = char.IsAsciiLetterUpper(remain[pos + 1]);
RegexCharSet set_set = char.ToLower(remain[pos + 1], CultureInfo.InvariantCulture)
switch
switch (char.ToLower(remain[pos + 1], CultureInfo.InvariantCulture))
{
's' => new("s", CharSetType.Set, accept),
'w' => new("w", CharSetType.Set, accept),
'd' => new("d", CharSetType.Set, accept),
_ => throw new NotSupportedException()
};
sets.Add(set_set);
case 's':
sets.Add(new("s", CharSetType.Set, accept));
break;
case 'w':
sets.Add(new("w", CharSetType.Set, accept));
break;
case 'd':
sets.Add(new("d", CharSetType.Set, accept));
break;
case '['or'('or')'or']'or'\\'or'\"':
_ = single_char.Add(remain[pos + 1]);
break;
default:
throw new InvalidCastException($"Unknown char or charset {remain[0..1]}");
}
remain = remain[(pos + 2)..];
}
if (remain.Length > 0) {
sets.Add(new RegexCharSet(remain.ToString(), CharSetType.Single, true));
if (remain.Length > 0)
{
foreach (char c in remain) {
_ = single_char.Add(c);
}
}
}
}