text regex source gen framework is briefly done. Going on ir2code
This commit is contained in:
@@ -0,0 +1,89 @@
|
||||
// -----------------------------------------------------------------------------
|
||||
// file="TextRegexSourceGen.GenClass"
|
||||
// Project: StgSharp
|
||||
// Copyright (c) Nitload.
|
||||
// SPDX-License-Identifier: MIT
|
||||
// -----------------------------------------------------------------------------
|
||||
|
||||
using StgSharp.RegularAnalysis.Abstraction;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Runtime.InteropServices;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace StgSharp.RegularAnalysis.Text
|
||||
{
|
||||
internal partial class TextRegexSourceGen
|
||||
{
|
||||
|
||||
internal static SequenceEmitter<string> GenerateSource(
|
||||
TextRegexSource source
|
||||
)
|
||||
{
|
||||
SequenceEmitter<string> se = new();
|
||||
List<SequenceEmitter<string>> sub_match_list = [];
|
||||
|
||||
RegexInfo info = source.Info;
|
||||
List<RegexIR> ir = source.IRs;
|
||||
ReadOnlySpan<RegexIR> ir_sp = CollectionsMarshal.AsSpan(ir);
|
||||
RegexIR[] window = new RegexIR[8];
|
||||
Span<RegexIR> scan_win = window;
|
||||
|
||||
const string current_ptr = "current_ptr";
|
||||
|
||||
_ = se.AppendLine($@"public override MatchResult Match({ROS_char} text)")//
|
||||
.AppendLine(@"{");
|
||||
|
||||
int region_count = info.RegionCount;
|
||||
for (int i = 0; i < region_count; i++)
|
||||
{
|
||||
_ = se.AppendLine($@"int region_{i}_start = -1;")//
|
||||
.AppendLine($@"int region_{i}_end = -1;")
|
||||
.AppendLine($@"bool region_{i}_success;");
|
||||
}
|
||||
|
||||
_ = se.AppendLine($@"int {current_ptr} = 0;");
|
||||
|
||||
int index = 0;
|
||||
do
|
||||
{
|
||||
int count = int.Min(8, ir_sp.Length - index);
|
||||
ir_sp.Slice(index, count).CopyTo(scan_win);
|
||||
if (TryGenerateMatch(scan_win, se) > 0) { }
|
||||
} while (index < ir.Count);
|
||||
|
||||
foreach (SequenceEmitter<string> _sub in sub_match_list)
|
||||
{
|
||||
_ = se.AppendLine() //
|
||||
.Append(_sub);
|
||||
}
|
||||
|
||||
_ = se.Append(@"}");
|
||||
|
||||
return se;
|
||||
/**/
|
||||
int TryGenerateMatch(
|
||||
Span<RegexIR> scan_win,
|
||||
SequenceEmitter<string> sb
|
||||
)
|
||||
{
|
||||
if (scan_win[0] is not RegexMatchSeqIR seq) {
|
||||
return -1;
|
||||
}
|
||||
string pattern = seq.Pattern;
|
||||
int length = pattern.Length;
|
||||
_ = sb.AppendLine()
|
||||
.AppendLine($@"if(text[{current_ptr}..({current_ptr} + {length})] == {pattern})")
|
||||
.AppendLine($@"{{")
|
||||
.AppendLine($@"{current_ptr} += {length};")
|
||||
.AppendLine($@"}}");
|
||||
|
||||
return 1;
|
||||
}
|
||||
/**/
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user