///|
/// Adapt the Perl frontend of `walkzzz/re-mbt` for ASCII-only contracts.
///
/// re-mbt exposes byte-oriented APIs. This adapter intentionally accepts only
/// ASCII patterns and inputs, where byte offsets equal MoonBit StringView code
/// unit offsets. It reports non-ASCII values as adapter-domain errors rather
/// than guessing at an encoding conversion.
pub fn rembt_ascii_perl_adapter() -> EngineAdapter {
EngineAdapter::new(id="walkzzz/re-mbt/Perl (ASCII)", compile=pattern => {
if !is_ascii(pattern) {
return Err(
"adapter-domain: re-mbt Perl adapter currently accepts ASCII patterns only",
)
}
let compiled = Ok(@rembt.Perl::compile_pat(@rembt.sb(pattern))) catch {
_ => Err("re-mbt Perl frontend rejected the pattern")
}
match compiled {
Err(message) => Err(message)
Ok(regex) =>
Ok(
CompiledMatcher::new(observe=input => {
if !is_ascii(input) {
return Err(
"adapter-domain: re-mbt Perl adapter currently accepts ASCII inputs only",
)
}
let groups_result = Ok(@rembt.exec_opt(regex, @rembt.sb(input))) catch {
_ => Err("re-mbt Perl matcher raised an error")
}
match groups_result {
Err(message) => Err(message)
Ok(None) => Ok(None)
Ok(Some(groups)) => {
let text = match @rembt.GroupT::get_opt(groups, 0) {
Some(bytes) => @rembt.bs(bytes)
None => ""
}
let (start, end) = match @rembt.GroupT::offset_opt(groups, 0) {
Some(offsets) => offsets
None =>
return Err(
"re-mbt returned a match without group-zero offsets",
)
}
let captures : Array[String?] = []
for index = 1
index < @rembt.GroupT::nb_groups(groups)
index = index + 1 {
captures.push(
@rembt.GroupT::get_opt(groups, index).map(bytes => {
@rembt.bs(bytes)
}),
)
}
Ok(Some({ text, start, end, captures, }))
}
}
}),
)
}
})
}
///|
fn is_ascii(value : String) -> Bool {
for char in value {
if char.to_int() > 127 {
return false
}
}
true
}