Un-macro indented_seq

This commit is contained in:
Jackson Wambolt 2024-04-14 23:59:40 -05:00
parent 60fa7ebe9e
commit 1b4b0a0aa1
No known key found for this signature in database
GPG key ID: 76F29A42FEE8811C
2 changed files with 31 additions and 29 deletions

View file

@ -10,10 +10,11 @@ use crate::blankspace::{
use crate::ident::{integer_ident, lowercase_ident, parse_ident, Accessor, Ident};
use crate::keyword;
use crate::parser::{
self, backtrackable, between, byte, byte_indent, increment_min_indent, line_min_indent,
optional, reset_min_indent, sep_by1, sep_by1_e, set_min_indent, skip_first, skip_second,
specialize_err, specialize_err_ref, then, two_bytes, EClosure, EExpect, EExpr, EIf, EInParens,
EList, ENumber, EPattern, ERecord, EString, EType, EWhen, Either, ParseResult, Parser,
self, backtrackable, between, byte, byte_indent, increment_min_indent, indented_seq,
line_min_indent, optional, reset_min_indent, sep_by1, sep_by1_e, set_min_indent, skip_first,
skip_second, specialize_err, specialize_err_ref, then, two_bytes, EClosure, EExpect, EExpr,
EIf, EInParens, EList, ENumber, EPattern, ERecord, EString, EType, EWhen, Either, ParseResult,
Parser,
};
use crate::pattern::{closure_param, loc_implements_parser};
use crate::state::State;
@ -2362,7 +2363,7 @@ fn closure_help<'a>(options: ExprParseOptions) -> impl Parser<'a, Expr<'a>, EClo
// closure_help_help(options)
map_with_arena!(
// After the first token, all other tokens must be indented past the start of the line
indented_seq!(
indented_seq(
// All closures start with a '\' - e.g. (\x -> x + 1)
byte_indent(b'\\', EClosure::Start),
// Once we see the '\', we're committed to parsing this as a closure.
@ -2406,7 +2407,7 @@ mod when {
pub fn expr_help<'a>(options: ExprParseOptions) -> impl Parser<'a, Expr<'a>, EWhen<'a>> {
map_with_arena!(
and!(
indented_seq!(
indented_seq(
parser::keyword(keyword::WHEN, EWhen::When),
space0_around_e_no_after_indent_check(
specialize_err_ref(EWhen::Condition, expr_start(options)),
@ -2417,7 +2418,7 @@ mod when {
// ambiguity. The formatter will fix it up.
//
// We require that branches are indented relative to the line containing the `is`.
indented_seq!(
indented_seq(
parser::keyword(keyword::IS, EWhen::Is),
branches(options)
)

View file

@ -1686,32 +1686,33 @@ macro_rules! record {
};
}
/// Similar to [`and!`], but we modify the `min_indent` of the second parser to be
/// 1 greater than the `line_indent()` at the start of the first parser.
#[macro_export]
macro_rules! indented_seq {
($p1:expr, $p2:expr) => {
move |arena: &'a bumpalo::Bump, state: $crate::state::State<'a>, _min_indent: u32| {
let start_indent = state.line_indent();
/// Similar to [`and`], but we modify the `min_indent` of the second parser
/// (`parser`) to be 1 greater than the `line_indent()` at the start of the
/// first parser (`before`).
pub fn indented_seq<'a, O, E: 'a>(
before: impl Parser<'a, (), E>,
parser: impl Parser<'a, O, E>,
) -> impl Parser<'a, O, E> {
move |arena: &'a bumpalo::Bump, state: crate::state::State<'a>, _min_indent: u32| {
let start_indent = state.line_indent();
// TODO: we should account for min_indent here, but this doesn't currently work
// because min_indent is sometimes larger than it really should be, which is in turn
// due to uses of `increment_indent`.
//
// let p1_indent = std::cmp::max(start_indent, min_indent);
// TODO: we should account for min_indent here, but this doesn't currently work
// because min_indent is sometimes larger than it really should be, which is in turn
// due to uses of `increment_indent`.
//
// let p1_indent = std::cmp::max(start_indent, min_indent);
let p1_indent = start_indent;
let p2_indent = p1_indent + 1;
let p1_indent = start_indent;
let p2_indent = p1_indent + 1;
match $p1.parse(arena, state, p1_indent) {
Ok((p1, (), state)) => match $p2.parse(arena, state, p2_indent) {
Ok((p2, out2, state)) => Ok((p1.or(p2), out2, state)),
Err((p2, fail)) => Err((p1.or(p2), fail)),
},
Err((progress, fail)) => Err((progress, fail)),
}
match before.parse(arena, state, p1_indent) {
Ok((p1, (), state)) => match parser.parse(arena, state, p2_indent) {
Ok((p2, out2, state)) => Ok((p1.or(p2), out2, state)),
Err((p2, fail)) => Err((p1.or(p2), fail)),
},
Err((progress, fail)) => Err((progress, fail)),
}
};
}
}
/// Similar to [`and!`], but we modify the `min_indent` of the second parser to be