mirror of
https://github.com/roc-lang/roc.git
synced 2025-11-02 22:01:20 +00:00
Un-macro either
This commit is contained in:
parent
2f776f366f
commit
02c98f7519
4 changed files with 37 additions and 39 deletions
|
|
@ -10,11 +10,11 @@ use crate::blankspace::{
|
|||
use crate::ident::{integer_ident, lowercase_ident, parse_ident, Accessor, Ident};
|
||||
use crate::keyword;
|
||||
use crate::parser::{
|
||||
self, and, backtrackable, between, byte, byte_indent, increment_min_indent, indented_seq,
|
||||
line_min_indent, loc, map, map_with_arena, optional, reset_min_indent, sep_by1, sep_by1_e,
|
||||
set_min_indent, skip_first, skip_second, specialize_err, specialize_err_ref, then, two_bytes,
|
||||
zero_or_more, EClosure, EExpect, EExpr, EIf, EInParens, EList, ENumber, EPattern, ERecord,
|
||||
EString, EType, EWhen, Either, ParseResult, Parser,
|
||||
self, and, backtrackable, between, byte, byte_indent, either, increment_min_indent,
|
||||
indented_seq, line_min_indent, loc, map, map_with_arena, optional, reset_min_indent, sep_by1,
|
||||
sep_by1_e, set_min_indent, skip_first, skip_second, specialize_err, specialize_err_ref, then,
|
||||
two_bytes, zero_or_more, 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;
|
||||
|
|
@ -622,7 +622,7 @@ pub fn parse_single_def<'a>(
|
|||
|
||||
let parse_expect_vanilla = crate::parser::keyword(crate::keyword::EXPECT, EExpect::Expect);
|
||||
let parse_expect_fx = crate::parser::keyword(crate::keyword::EXPECT_FX, EExpect::Expect);
|
||||
let parse_expect = either!(parse_expect_fx, parse_expect_vanilla);
|
||||
let parse_expect = either(parse_expect_fx, parse_expect_vanilla);
|
||||
|
||||
match space0_after_e(crate::pattern::loc_pattern_help(), EPattern::IndentEnd).parse(
|
||||
arena,
|
||||
|
|
@ -2983,12 +2983,12 @@ pub fn record_field<'a>() -> impl Parser<'a, RecordField<'a>, ERecord<'a>> {
|
|||
specialize_err(|_, pos| ERecord::Field(pos), loc(lowercase_ident())),
|
||||
and(
|
||||
spaces(),
|
||||
optional(either!(
|
||||
optional(either(
|
||||
and(byte(b':', ERecord::Colon), record_field_expr()),
|
||||
and(
|
||||
byte(b'?', ERecord::QuestionMark),
|
||||
spaces_before(specialize_err_ref(ERecord::Expr, loc_expr(false)))
|
||||
)
|
||||
spaces_before(specialize_err_ref(ERecord::Expr, loc_expr(false))),
|
||||
),
|
||||
)),
|
||||
),
|
||||
),
|
||||
|
|
@ -3029,12 +3029,12 @@ fn record_field_expr<'a>() -> impl Parser<'a, RecordFieldExpr<'a>, ERecord<'a>>
|
|||
map_with_arena(
|
||||
and(
|
||||
spaces(),
|
||||
either!(
|
||||
either(
|
||||
and(
|
||||
two_bytes(b'<', b'-', ERecord::Arrow),
|
||||
spaces_before(specialize_err_ref(ERecord::Expr, loc_expr(false)))
|
||||
spaces_before(specialize_err_ref(ERecord::Expr, loc_expr(false))),
|
||||
),
|
||||
specialize_err_ref(ERecord::Expr, loc_expr(false))
|
||||
specialize_err_ref(ERecord::Expr, loc_expr(false)),
|
||||
),
|
||||
),
|
||||
|arena: &'a bumpalo::Bump, (spaces, either)| match either {
|
||||
|
|
|
|||
|
|
@ -2403,7 +2403,7 @@ macro_rules! debug {
|
|||
/// # }
|
||||
/// # let arena = Bump::new();
|
||||
/// # fn foo<'a>(arena: &'a Bump) {
|
||||
/// let parser = either!(
|
||||
/// let parser = either(
|
||||
/// word("hello", Problem::NotFound),
|
||||
/// word("bye", Problem::NotFound)
|
||||
/// );
|
||||
|
|
@ -2426,27 +2426,25 @@ macro_rules! debug {
|
|||
/// # }
|
||||
/// # foo(&arena);
|
||||
/// ```
|
||||
#[macro_export]
|
||||
macro_rules! either {
|
||||
($p1:expr, $p2:expr) => {
|
||||
move |arena: &'a bumpalo::Bump, state: $crate::state::State<'a>, min_indent: u32| {
|
||||
let original_state = state.clone();
|
||||
match $p1.parse(arena, state, min_indent) {
|
||||
Ok((progress, output, state)) => {
|
||||
Ok((progress, $crate::parser::Either::First(output), state))
|
||||
}
|
||||
Err((NoProgress, _)) => {
|
||||
match $p2.parse(arena, original_state.clone(), min_indent) {
|
||||
Ok((progress, output, state)) => {
|
||||
Ok((progress, $crate::parser::Either::Second(output), state))
|
||||
}
|
||||
Err((progress, fail)) => Err((progress, fail)),
|
||||
}
|
||||
}
|
||||
Err((MadeProgress, fail)) => Err((MadeProgress, fail)),
|
||||
pub fn either<'a, OutputLeft, OutputRight, E: 'a>(
|
||||
p1: impl Parser<'a, OutputLeft, E>,
|
||||
p2: impl Parser<'a, OutputRight, E>,
|
||||
) -> impl Parser<'a, Either<OutputLeft, OutputRight>, E> {
|
||||
move |arena: &'a bumpalo::Bump, state: crate::state::State<'a>, min_indent: u32| {
|
||||
let original_state = state.clone();
|
||||
match p1.parse(arena, state, min_indent) {
|
||||
Ok((progress, output, state)) => {
|
||||
Ok((progress, crate::parser::Either::First(output), state))
|
||||
}
|
||||
Err((NoProgress, _)) => match p2.parse(arena, original_state.clone(), min_indent) {
|
||||
Ok((progress, output, state)) => {
|
||||
Ok((progress, crate::parser::Either::Second(output), state))
|
||||
}
|
||||
Err((progress, fail)) => Err((progress, fail)),
|
||||
},
|
||||
Err((MadeProgress, fail)) => Err((MadeProgress, fail)),
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
/// Given three parsers, parse them all but ignore the output of the first and last one.
|
||||
|
|
|
|||
|
|
@ -2,12 +2,12 @@ use crate::ast::{Implements, Pattern, PatternAs, Spaceable};
|
|||
use crate::blankspace::{space0_e, spaces, spaces_before};
|
||||
use crate::ident::{lowercase_ident, parse_ident, Accessor, Ident};
|
||||
use crate::keyword;
|
||||
use crate::parser::Progress::*;
|
||||
use crate::parser::{
|
||||
self, backtrackable, byte, fail_when, loc, map, map_with_arena, optional, skip_first,
|
||||
specialize_err, specialize_err_ref, then, three_bytes, two_bytes, zero_or_more, EPattern,
|
||||
PInParens, PList, PRecord, Parser,
|
||||
};
|
||||
use crate::parser::{either, Progress::*};
|
||||
use crate::state::State;
|
||||
use crate::string_literal::StrLikeLiteral;
|
||||
use bumpalo::collections::string::String;
|
||||
|
|
@ -547,9 +547,9 @@ fn record_pattern_field<'a>() -> impl Parser<'a, Loc<Pattern<'a>>, PRecord<'a>>
|
|||
|
||||
// Having a value is optional; both `{ email }` and `{ email: blah }` work.
|
||||
// (This is true in both literals and types.)
|
||||
let (_, opt_loc_val, state) = optional(either!(
|
||||
let (_, opt_loc_val, state) = optional(either(
|
||||
byte(b':', PRecord::Colon),
|
||||
byte(b'?', PRecord::Optional)
|
||||
byte(b'?', PRecord::Optional),
|
||||
))
|
||||
.parse(arena, state, min_indent)?;
|
||||
|
||||
|
|
|
|||
|
|
@ -9,8 +9,8 @@ use crate::expr::{record_field, FoundApplyValue};
|
|||
use crate::ident::{lowercase_ident, lowercase_ident_keyword_e};
|
||||
use crate::keyword;
|
||||
use crate::parser::{
|
||||
absolute_column_min_indent, and, increment_min_indent, loc, map, map_with_arena, skip_first,
|
||||
skip_second, succeed, then, zero_or_more, ERecord, ETypeAbilityImpl,
|
||||
absolute_column_min_indent, and, either, increment_min_indent, loc, map, map_with_arena,
|
||||
skip_first, skip_second, succeed, then, zero_or_more, ERecord, ETypeAbilityImpl,
|
||||
};
|
||||
use crate::parser::{
|
||||
allocated, backtrackable, byte, fail, optional, specialize_err, specialize_err_ref, two_bytes,
|
||||
|
|
@ -332,9 +332,9 @@ fn record_type_field<'a>() -> impl Parser<'a, AssignedField<'a, TypeAnnotation<'
|
|||
|
||||
// Having a value is optional; both `{ email }` and `{ email: blah }` work.
|
||||
// (This is true in both literals and types.)
|
||||
let (_, opt_loc_val, state) = optional(either!(
|
||||
let (_, opt_loc_val, state) = optional(either(
|
||||
byte(b':', ETypeRecord::Colon),
|
||||
byte(b'?', ETypeRecord::Optional)
|
||||
byte(b'?', ETypeRecord::Optional),
|
||||
))
|
||||
.parse(arena, state, min_indent)?;
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue