Вроде что-то получилось:
macro RangePattern(body)
syntax ("my", body) {
SandboxImpl.DoTransform(Macros.ImplicitCTX(), body)
}
module SandboxImpl {
public DoTransform(typer: Typer, body: PExpr) : PExpr {
Macros.DefineCTX(typer);
if (body is <[ match ($val) { ..$cases } ]>)
{
def cases =
cases.Map(case =>
match (case) {
| <[case: | $minExpr < $pvar < $maxExpr when $guard => $res ]>
| <[case: | $minExpr < $pvar < $maxExpr => $res ]> with guard = <[ true ]> =>
def guards = <[ $val > $minExpr && $val < $maxExpr && $guard ]>;
<[ case: | $pvar when $guards => $res ]>
| x => x
});
<[ match ($val) { ..$cases } ]>
}
else
{
Message.Error(body.Location, $"Syntax error '$body'");
<[ () ]>
}
}
}
Работает на таком выражении:
my match (2) {
| 1 < x < 4 => x
| 1 < x < 4 when x > 1 => x + 1
| x when x > 10 => 1
}