mirror of
https://github.com/roc-lang/roc.git
synced 2025-09-30 15:21:12 +00:00
Un-macro map_with_arena
This commit is contained in:
parent
f6c977fb96
commit
a9724dda5e
5 changed files with 74 additions and 124 deletions
|
@ -11,10 +11,10 @@ use crate::ident::{integer_ident, lowercase_ident, parse_ident, Accessor, Ident}
|
||||||
use crate::keyword;
|
use crate::keyword;
|
||||||
use crate::parser::{
|
use crate::parser::{
|
||||||
self, and, backtrackable, between, byte, byte_indent, increment_min_indent, indented_seq,
|
self, and, backtrackable, between, byte, byte_indent, increment_min_indent, indented_seq,
|
||||||
line_min_indent, loc, map, optional, reset_min_indent, sep_by1, sep_by1_e, set_min_indent,
|
line_min_indent, loc, map, map_with_arena, optional, reset_min_indent, sep_by1, sep_by1_e,
|
||||||
skip_first, skip_second, specialize_err, specialize_err_ref, then, two_bytes, EClosure,
|
set_min_indent, skip_first, skip_second, specialize_err, specialize_err_ref, then, two_bytes,
|
||||||
EExpect, EExpr, EIf, EInParens, EList, ENumber, EPattern, ERecord, EString, EType, EWhen,
|
EClosure, EExpect, EExpr, EIf, EInParens, EList, ENumber, EPattern, ERecord, EString, EType,
|
||||||
Either, ParseResult, Parser,
|
EWhen, Either, ParseResult, Parser,
|
||||||
};
|
};
|
||||||
use crate::pattern::{closure_param, loc_implements_parser};
|
use crate::pattern::{closure_param, loc_implements_parser};
|
||||||
use crate::state::State;
|
use crate::state::State;
|
||||||
|
@ -131,10 +131,10 @@ fn loc_expr_in_parens_help<'a>() -> impl Parser<'a, Loc<Expr<'a>>, EInParens<'a>
|
||||||
}
|
}
|
||||||
|
|
||||||
fn loc_expr_in_parens_etc_help<'a>() -> impl Parser<'a, Loc<Expr<'a>>, EExpr<'a>> {
|
fn loc_expr_in_parens_etc_help<'a>() -> impl Parser<'a, Loc<Expr<'a>>, EExpr<'a>> {
|
||||||
map_with_arena!(
|
map_with_arena(
|
||||||
loc(and(
|
loc(and(
|
||||||
specialize_err(EExpr::InParens, loc_expr_in_parens_help()),
|
specialize_err(EExpr::InParens, loc_expr_in_parens_help()),
|
||||||
record_field_access_chain()
|
record_field_access_chain(),
|
||||||
)),
|
)),
|
||||||
move |arena: &'a Bump, value: Loc<(Loc<Expr<'a>>, Vec<'a, Accessor<'a>>)>| {
|
move |arena: &'a Bump, value: Loc<(Loc<Expr<'a>>, Vec<'a, Accessor<'a>>)>| {
|
||||||
let Loc {
|
let Loc {
|
||||||
|
@ -153,7 +153,7 @@ fn loc_expr_in_parens_etc_help<'a>() -> impl Parser<'a, Loc<Expr<'a>>, EExpr<'a>
|
||||||
}
|
}
|
||||||
|
|
||||||
Loc::at(region, value)
|
Loc::at(region, value)
|
||||||
}
|
},
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -189,7 +189,7 @@ fn loc_term_or_underscore_or_conditional<'a>(
|
||||||
loc(underscore_expression()),
|
loc(underscore_expression()),
|
||||||
loc(record_literal_help()),
|
loc(record_literal_help()),
|
||||||
loc(specialize_err(EExpr::List, list_literal_help())),
|
loc(specialize_err(EExpr::List, list_literal_help())),
|
||||||
loc(map_with_arena!(
|
loc(map_with_arena(
|
||||||
assign_or_destructure_identifier(),
|
assign_or_destructure_identifier(),
|
||||||
ident_to_expr
|
ident_to_expr
|
||||||
)),
|
)),
|
||||||
|
@ -212,7 +212,7 @@ fn loc_term_or_underscore<'a>(
|
||||||
loc(underscore_expression()),
|
loc(underscore_expression()),
|
||||||
loc(record_literal_help()),
|
loc(record_literal_help()),
|
||||||
loc(specialize_err(EExpr::List, list_literal_help())),
|
loc(specialize_err(EExpr::List, list_literal_help())),
|
||||||
loc(map_with_arena!(
|
loc(map_with_arena(
|
||||||
assign_or_destructure_identifier(),
|
assign_or_destructure_identifier(),
|
||||||
ident_to_expr
|
ident_to_expr
|
||||||
)),
|
)),
|
||||||
|
@ -230,7 +230,7 @@ fn loc_term<'a>(options: ExprParseOptions) -> impl Parser<'a, Loc<Expr<'a>>, EEx
|
||||||
loc(specialize_err(EExpr::Closure, closure_help(options))),
|
loc(specialize_err(EExpr::Closure, closure_help(options))),
|
||||||
loc(record_literal_help()),
|
loc(record_literal_help()),
|
||||||
loc(specialize_err(EExpr::List, list_literal_help())),
|
loc(specialize_err(EExpr::List, list_literal_help())),
|
||||||
loc(map_with_arena!(
|
loc(map_with_arena(
|
||||||
assign_or_destructure_identifier(),
|
assign_or_destructure_identifier(),
|
||||||
ident_to_expr
|
ident_to_expr
|
||||||
)),
|
)),
|
||||||
|
@ -281,7 +281,7 @@ fn loc_possibly_negative_or_negated_term<'a>(
|
||||||
},
|
},
|
||||||
// this will parse negative numbers, which the unary negate thing up top doesn't (for now)
|
// this will parse negative numbers, which the unary negate thing up top doesn't (for now)
|
||||||
loc(specialize_err(EExpr::Number, number_literal_help())),
|
loc(specialize_err(EExpr::Number, number_literal_help())),
|
||||||
loc(map_with_arena!(
|
loc(map_with_arena(
|
||||||
and(
|
and(
|
||||||
loc(byte(b'!', EExpr::Start)),
|
loc(byte(b'!', EExpr::Start)),
|
||||||
space0_before_e(loc_term(options), EExpr::IndentStart)
|
space0_before_e(loc_term(options), EExpr::IndentStart)
|
||||||
|
@ -2359,7 +2359,7 @@ pub fn toplevel_defs<'a>() -> impl Parser<'a, Defs<'a>, EExpr<'a>> {
|
||||||
|
|
||||||
fn closure_help<'a>(options: ExprParseOptions) -> impl Parser<'a, Expr<'a>, EClosure<'a>> {
|
fn closure_help<'a>(options: ExprParseOptions) -> impl Parser<'a, Expr<'a>, EClosure<'a>> {
|
||||||
// closure_help_help(options)
|
// closure_help_help(options)
|
||||||
map_with_arena!(
|
map_with_arena(
|
||||||
// After the first token, all other tokens must be indented past the start of the line
|
// 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)
|
// All closures start with a '\' - e.g. (\x -> x + 1)
|
||||||
|
@ -2384,16 +2384,16 @@ fn closure_help<'a>(options: ExprParseOptions) -> impl Parser<'a, Expr<'a>, EClo
|
||||||
// Parse the body
|
// Parse the body
|
||||||
space0_before_e(
|
space0_before_e(
|
||||||
specialize_err_ref(EClosure::Body, expr_start(options)),
|
specialize_err_ref(EClosure::Body, expr_start(options)),
|
||||||
EClosure::IndentBody
|
EClosure::IndentBody,
|
||||||
)
|
),
|
||||||
)
|
),
|
||||||
)
|
),
|
||||||
),
|
),
|
||||||
|arena: &'a Bump, (params, body)| {
|
|arena: &'a Bump, (params, body)| {
|
||||||
let params: Vec<'a, Loc<Pattern<'a>>> = params;
|
let params: Vec<'a, Loc<Pattern<'a>>> = params;
|
||||||
let params: &'a [Loc<Pattern<'a>>] = params.into_bump_slice();
|
let params: &'a [Loc<Pattern<'a>>] = params.into_bump_slice();
|
||||||
Expr::Closure(params, arena.alloc(body))
|
Expr::Closure(params, arena.alloc(body))
|
||||||
}
|
},
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2403,7 +2403,7 @@ mod when {
|
||||||
|
|
||||||
/// Parser for when expressions.
|
/// Parser for when expressions.
|
||||||
pub fn expr_help<'a>(options: ExprParseOptions) -> impl Parser<'a, Expr<'a>, EWhen<'a>> {
|
pub fn expr_help<'a>(options: ExprParseOptions) -> impl Parser<'a, Expr<'a>, EWhen<'a>> {
|
||||||
map_with_arena!(
|
map_with_arena(
|
||||||
and(
|
and(
|
||||||
indented_seq(
|
indented_seq(
|
||||||
parser::keyword(keyword::WHEN, EWhen::When),
|
parser::keyword(keyword::WHEN, EWhen::When),
|
||||||
|
@ -2847,7 +2847,7 @@ fn ident_to_expr<'a>(arena: &'a Bump, src: Ident<'a>) -> Expr<'a> {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn list_literal_help<'a>() -> impl Parser<'a, Expr<'a>, EList<'a>> {
|
fn list_literal_help<'a>() -> impl Parser<'a, Expr<'a>, EList<'a>> {
|
||||||
map_with_arena!(
|
map_with_arena(
|
||||||
collection_trailing_sep_e!(
|
collection_trailing_sep_e!(
|
||||||
byte(b'[', EList::Open),
|
byte(b'[', EList::Open),
|
||||||
specialize_err_ref(EList::Expr, loc_expr(false)),
|
specialize_err_ref(EList::Expr, loc_expr(false)),
|
||||||
|
@ -2858,7 +2858,7 @@ fn list_literal_help<'a>() -> impl Parser<'a, Expr<'a>, EList<'a>> {
|
||||||
|arena, elements: Collection<'a, _>| {
|
|arena, elements: Collection<'a, _>| {
|
||||||
let elements = elements.ptrify_items(arena);
|
let elements = elements.ptrify_items(arena);
|
||||||
Expr::List(elements)
|
Expr::List(elements)
|
||||||
}
|
},
|
||||||
)
|
)
|
||||||
.trace("list_literal")
|
.trace("list_literal")
|
||||||
}
|
}
|
||||||
|
@ -2978,7 +2978,7 @@ impl<'a> Spaceable<'a> for RecordField<'a> {
|
||||||
pub fn record_field<'a>() -> impl Parser<'a, RecordField<'a>, ERecord<'a>> {
|
pub fn record_field<'a>() -> impl Parser<'a, RecordField<'a>, ERecord<'a>> {
|
||||||
use RecordField::*;
|
use RecordField::*;
|
||||||
|
|
||||||
map_with_arena!(
|
map_with_arena(
|
||||||
and(
|
and(
|
||||||
specialize_err(|_, pos| ERecord::Field(pos), loc(lowercase_ident())),
|
specialize_err(|_, pos| ERecord::Field(pos), loc(lowercase_ident())),
|
||||||
and(
|
and(
|
||||||
|
@ -2989,8 +2989,8 @@ pub fn record_field<'a>() -> impl Parser<'a, RecordField<'a>, ERecord<'a>> {
|
||||||
byte(b'?', ERecord::QuestionMark),
|
byte(b'?', ERecord::QuestionMark),
|
||||||
spaces_before(specialize_err_ref(ERecord::Expr, loc_expr(false)))
|
spaces_before(specialize_err_ref(ERecord::Expr, loc_expr(false)))
|
||||||
)
|
)
|
||||||
))
|
)),
|
||||||
)
|
),
|
||||||
),
|
),
|
||||||
|arena: &'a bumpalo::Bump, (loc_label, (spaces, opt_loc_val))| {
|
|arena: &'a bumpalo::Bump, (loc_label, (spaces, opt_loc_val))| {
|
||||||
match opt_loc_val {
|
match opt_loc_val {
|
||||||
|
@ -3016,7 +3016,7 @@ pub fn record_field<'a>() -> impl Parser<'a, RecordField<'a>, ERecord<'a>> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
},
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -3026,7 +3026,7 @@ enum RecordFieldExpr<'a> {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn record_field_expr<'a>() -> impl Parser<'a, RecordFieldExpr<'a>, ERecord<'a>> {
|
fn record_field_expr<'a>() -> impl Parser<'a, RecordFieldExpr<'a>, ERecord<'a>> {
|
||||||
map_with_arena!(
|
map_with_arena(
|
||||||
and(
|
and(
|
||||||
spaces(),
|
spaces(),
|
||||||
either!(
|
either!(
|
||||||
|
@ -3035,29 +3035,27 @@ fn record_field_expr<'a>() -> impl Parser<'a, RecordFieldExpr<'a>, ERecord<'a>>
|
||||||
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)| {
|
|arena: &'a bumpalo::Bump, (spaces, either)| match either {
|
||||||
match either {
|
Either::First((_, loc_expr)) => RecordFieldExpr::Apply(spaces, loc_expr),
|
||||||
Either::First((_, loc_expr)) => RecordFieldExpr::Apply(spaces, loc_expr),
|
Either::Second(loc_expr) => RecordFieldExpr::Value({
|
||||||
Either::Second(loc_expr) => RecordFieldExpr::Value({
|
if spaces.is_empty() {
|
||||||
if spaces.is_empty() {
|
loc_expr
|
||||||
loc_expr
|
} else {
|
||||||
} else {
|
arena
|
||||||
arena
|
.alloc(loc_expr.value)
|
||||||
.alloc(loc_expr.value)
|
.with_spaces_before(spaces, loc_expr.region)
|
||||||
.with_spaces_before(spaces, loc_expr.region)
|
}
|
||||||
}
|
}),
|
||||||
}),
|
},
|
||||||
}
|
|
||||||
}
|
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn record_updateable_identifier<'a>() -> impl Parser<'a, Expr<'a>, ERecord<'a>> {
|
fn record_updateable_identifier<'a>() -> impl Parser<'a, Expr<'a>, ERecord<'a>> {
|
||||||
specialize_err(
|
specialize_err(
|
||||||
|_, pos| ERecord::Updateable(pos),
|
|_, pos| ERecord::Updateable(pos),
|
||||||
map_with_arena!(parse_ident, ident_to_expr),
|
map_with_arena(parse_ident, ident_to_expr),
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -3184,7 +3182,7 @@ fn apply_expr_access_chain<'a>(
|
||||||
}
|
}
|
||||||
|
|
||||||
fn string_like_literal_help<'a>() -> impl Parser<'a, Expr<'a>, EString<'a>> {
|
fn string_like_literal_help<'a>() -> impl Parser<'a, Expr<'a>, EString<'a>> {
|
||||||
map_with_arena!(
|
map_with_arena(
|
||||||
crate::string_literal::parse_str_like_literal(),
|
crate::string_literal::parse_str_like_literal(),
|
||||||
|arena, lit| match lit {
|
|arena, lit| match lit {
|
||||||
StrLikeLiteral::Str(s) => Expr::Str(s),
|
StrLikeLiteral::Str(s) => Expr::Str(s),
|
||||||
|
@ -3192,7 +3190,7 @@ fn string_like_literal_help<'a>() -> impl Parser<'a, Expr<'a>, EString<'a>> {
|
||||||
// TODO: preserve the original escaping
|
// TODO: preserve the original escaping
|
||||||
Expr::SingleQuote(s.to_str_in(arena))
|
Expr::SingleQuote(s.to_str_in(arena))
|
||||||
}
|
}
|
||||||
}
|
},
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -5,7 +5,8 @@ use crate::blankspace::space0_e;
|
||||||
use crate::expr::merge_spaces;
|
use crate::expr::merge_spaces;
|
||||||
use crate::ident::{lowercase_ident, UppercaseIdent};
|
use crate::ident::{lowercase_ident, UppercaseIdent};
|
||||||
use crate::parser::{
|
use crate::parser::{
|
||||||
and, byte, loc, skip_second, specialize_err, EPackageEntry, EPackageName, Parser,
|
and, byte, loc, map_with_arena, skip_second, specialize_err, EPackageEntry, EPackageName,
|
||||||
|
Parser,
|
||||||
};
|
};
|
||||||
use crate::parser::{optional, then};
|
use crate::parser::{optional, then};
|
||||||
use crate::string_literal;
|
use crate::string_literal;
|
||||||
|
@ -339,7 +340,7 @@ pub struct PackageEntry<'a> {
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn package_entry<'a>() -> impl Parser<'a, Spaced<'a, PackageEntry<'a>>, EPackageEntry<'a>> {
|
pub fn package_entry<'a>() -> impl Parser<'a, Spaced<'a, PackageEntry<'a>>, EPackageEntry<'a>> {
|
||||||
map_with_arena!(
|
map_with_arena(
|
||||||
// You may optionally have a package shorthand,
|
// You may optionally have a package shorthand,
|
||||||
// e.g. "uc" in `uc: roc/unicode 1.0.0`
|
// e.g. "uc" in `uc: roc/unicode 1.0.0`
|
||||||
//
|
//
|
||||||
|
@ -349,13 +350,13 @@ pub fn package_entry<'a>() -> impl Parser<'a, Spaced<'a, PackageEntry<'a>>, EPac
|
||||||
skip_second(
|
skip_second(
|
||||||
and(
|
and(
|
||||||
specialize_err(|_, pos| EPackageEntry::Shorthand(pos), lowercase_ident()),
|
specialize_err(|_, pos| EPackageEntry::Shorthand(pos), lowercase_ident()),
|
||||||
space0_e(EPackageEntry::IndentPackage)
|
space0_e(EPackageEntry::IndentPackage),
|
||||||
),
|
),
|
||||||
byte(b':', EPackageEntry::Colon)
|
byte(b':', EPackageEntry::Colon),
|
||||||
),
|
),
|
||||||
space0_e(EPackageEntry::IndentPackage)
|
space0_e(EPackageEntry::IndentPackage),
|
||||||
)),
|
)),
|
||||||
loc(specialize_err(EPackageEntry::BadPackage, package_name()))
|
loc(specialize_err(EPackageEntry::BadPackage, package_name())),
|
||||||
),
|
),
|
||||||
move |arena, (opt_shorthand, package_or_path)| {
|
move |arena, (opt_shorthand, package_or_path)| {
|
||||||
let entry = match opt_shorthand {
|
let entry = match opt_shorthand {
|
||||||
|
@ -376,7 +377,7 @@ pub fn package_entry<'a>() -> impl Parser<'a, Spaced<'a, PackageEntry<'a>>, EPac
|
||||||
};
|
};
|
||||||
|
|
||||||
Spaced::Item(entry)
|
Spaced::Item(entry)
|
||||||
}
|
},
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1457,24 +1457,24 @@ where
|
||||||
#[macro_export]
|
#[macro_export]
|
||||||
macro_rules! collection_inner {
|
macro_rules! collection_inner {
|
||||||
($elem:expr, $delimiter:expr, $space_before:expr) => {
|
($elem:expr, $delimiter:expr, $space_before:expr) => {
|
||||||
map_with_arena!(
|
$crate::parser::map_with_arena(
|
||||||
$crate::parser::and(
|
$crate::parser::and(
|
||||||
$crate::parser::and(
|
$crate::parser::and(
|
||||||
$crate::blankspace::spaces(),
|
$crate::blankspace::spaces(),
|
||||||
$crate::parser::trailing_sep_by0(
|
$crate::parser::trailing_sep_by0(
|
||||||
$delimiter,
|
$delimiter,
|
||||||
$crate::blankspace::spaces_before_optional_after($elem,)
|
$crate::blankspace::spaces_before_optional_after($elem),
|
||||||
)
|
),
|
||||||
),
|
),
|
||||||
$crate::blankspace::spaces()
|
$crate::blankspace::spaces(),
|
||||||
),
|
),
|
||||||
|arena: &'a bumpalo::Bump,
|
|arena: &'a bumpalo::Bump,
|
||||||
((spaces, mut parsed_elems), mut final_comments): (
|
((spaces, mut parsed_elems), mut final_comments): (
|
||||||
(
|
(
|
||||||
&'a [$crate::ast::CommentOrNewline<'a>],
|
&'a [$crate::ast::CommentOrNewline<'a>],
|
||||||
bumpalo::collections::vec::Vec<'a, Loc<_>>
|
bumpalo::collections::vec::Vec<'a, Loc<_>>,
|
||||||
),
|
),
|
||||||
&'a [$crate::ast::CommentOrNewline<'a>]
|
&'a [$crate::ast::CommentOrNewline<'a>],
|
||||||
)| {
|
)| {
|
||||||
if !spaces.is_empty() {
|
if !spaces.is_empty() {
|
||||||
if let Some(first) = parsed_elems.first_mut() {
|
if let Some(first) = parsed_elems.first_mut() {
|
||||||
|
@ -1490,7 +1490,7 @@ macro_rules! collection_inner {
|
||||||
parsed_elems.into_bump_slice(),
|
parsed_elems.into_bump_slice(),
|
||||||
final_comments,
|
final_comments,
|
||||||
)
|
)
|
||||||
}
|
},
|
||||||
)
|
)
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
@ -2214,53 +2214,6 @@ pub fn map<'a, Output, MappedOutput, E: 'a>(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Maps/transforms the `Ok` result of parsing using the given function.
|
|
||||||
/// Similar to [`map`], but the transform function also takes a bump allocator.
|
|
||||||
///
|
|
||||||
/// # Example
|
|
||||||
///
|
|
||||||
/// ```
|
|
||||||
/// # #![forbid(unused_imports)]
|
|
||||||
/// # use roc_parse::state::State;
|
|
||||||
/// # use crate::roc_parse::parser::{Parser, Progress, word};
|
|
||||||
/// # use roc_region::all::Position;
|
|
||||||
/// # use roc_parse::map_with_arena;
|
|
||||||
/// # use bumpalo::Bump;
|
|
||||||
/// # #[derive(Debug, PartialEq)]
|
|
||||||
/// # enum Problem {
|
|
||||||
/// # NotFound(Position),
|
|
||||||
/// # }
|
|
||||||
/// # let arena = Bump::new();
|
|
||||||
/// let parser = map_with_arena!(
|
|
||||||
/// word("hello", Problem::NotFound),
|
|
||||||
/// |_arena, _output| "new output!"
|
|
||||||
/// );
|
|
||||||
///
|
|
||||||
/// // Success case
|
|
||||||
/// let (progress, output, state) = parser.parse(&arena, State::new("hello, world".as_bytes()), 0).unwrap();
|
|
||||||
/// assert_eq!(progress, Progress::MadeProgress);
|
|
||||||
/// assert_eq!(output, "new output!");
|
|
||||||
/// assert_eq!(state.pos(), Position::new(5));
|
|
||||||
///
|
|
||||||
/// // Error case
|
|
||||||
/// let (progress, err) = parser.parse(&arena, State::new("bye, world".as_bytes()), 0).unwrap_err();
|
|
||||||
/// assert_eq!(progress, Progress::NoProgress);
|
|
||||||
/// assert_eq!(err, Problem::NotFound(Position::zero()));
|
|
||||||
/// ```
|
|
||||||
#[macro_export]
|
|
||||||
macro_rules! map_with_arena {
|
|
||||||
($parser:expr, $transform:expr) => {
|
|
||||||
move |arena, state, min_indent| {
|
|
||||||
#[allow(clippy::redundant_closure_call)]
|
|
||||||
$parser
|
|
||||||
.parse(arena, state, min_indent)
|
|
||||||
.map(|(progress, output, next_state)| {
|
|
||||||
(progress, $transform(arena, output), next_state)
|
|
||||||
})
|
|
||||||
}
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Applies the parser as many times as possible.
|
/// Applies the parser as many times as possible.
|
||||||
/// This parser will only fail if the given parser makes partial progress.
|
/// This parser will only fail if the given parser makes partial progress.
|
||||||
#[macro_export]
|
#[macro_export]
|
||||||
|
@ -2538,9 +2491,6 @@ pub fn between<'a, Before, Inner, After, Err: 'a>(
|
||||||
/// Maps/transforms the `Ok` result of parsing using the given function.
|
/// Maps/transforms the `Ok` result of parsing using the given function.
|
||||||
/// Similar to [`map`], but the transform function also takes a bump allocator.
|
/// Similar to [`map`], but the transform function also takes a bump allocator.
|
||||||
///
|
///
|
||||||
/// For some reason, some usages won't compile unless they use this instead of the macro version.
|
|
||||||
/// This is likely because the lifetime `'a` is not defined at the call site.
|
|
||||||
///
|
|
||||||
/// # Example
|
/// # Example
|
||||||
///
|
///
|
||||||
/// ```
|
/// ```
|
||||||
|
@ -2577,14 +2527,14 @@ pub fn map_with_arena<'a, P, F, Before, After, E>(
|
||||||
) -> impl Parser<'a, After, E>
|
) -> impl Parser<'a, After, E>
|
||||||
where
|
where
|
||||||
P: Parser<'a, Before, E>,
|
P: Parser<'a, Before, E>,
|
||||||
P: 'a,
|
|
||||||
F: Fn(&'a Bump, Before) -> After,
|
F: Fn(&'a Bump, Before) -> After,
|
||||||
F: 'a,
|
|
||||||
Before: 'a,
|
|
||||||
After: 'a,
|
|
||||||
E: 'a,
|
E: 'a,
|
||||||
{
|
{
|
||||||
map_with_arena!(parser, transform)
|
move |arena, state, min_indent| {
|
||||||
|
parser
|
||||||
|
.parse(arena, state, min_indent)
|
||||||
|
.map(|(progress, output, next_state)| (progress, transform(arena, output), next_state))
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Creates a new parser that does not progress but still forwards the output of
|
/// Creates a new parser that does not progress but still forwards the output of
|
||||||
|
|
|
@ -4,8 +4,9 @@ use crate::ident::{lowercase_ident, parse_ident, Accessor, Ident};
|
||||||
use crate::keyword;
|
use crate::keyword;
|
||||||
use crate::parser::Progress::{self, *};
|
use crate::parser::Progress::{self, *};
|
||||||
use crate::parser::{
|
use crate::parser::{
|
||||||
self, backtrackable, byte, fail_when, loc, map, optional, skip_first, specialize_err,
|
self, backtrackable, byte, fail_when, loc, map, map_with_arena, optional, skip_first,
|
||||||
specialize_err_ref, then, three_bytes, two_bytes, EPattern, PInParens, PList, PRecord, Parser,
|
specialize_err, specialize_err_ref, then, three_bytes, two_bytes, EPattern, PInParens, PList,
|
||||||
|
PRecord, Parser,
|
||||||
};
|
};
|
||||||
use crate::state::State;
|
use crate::state::State;
|
||||||
use crate::string_literal::StrLikeLiteral;
|
use crate::string_literal::StrLikeLiteral;
|
||||||
|
@ -255,7 +256,7 @@ fn number_pattern_help<'a>() -> impl Parser<'a, Pattern<'a>, EPattern<'a>> {
|
||||||
fn string_like_pattern_help<'a>() -> impl Parser<'a, Pattern<'a>, EPattern<'a>> {
|
fn string_like_pattern_help<'a>() -> impl Parser<'a, Pattern<'a>, EPattern<'a>> {
|
||||||
specialize_err(
|
specialize_err(
|
||||||
|_, pos| EPattern::Start(pos),
|
|_, pos| EPattern::Start(pos),
|
||||||
map_with_arena!(
|
map_with_arena(
|
||||||
crate::string_literal::parse_str_like_literal(),
|
crate::string_literal::parse_str_like_literal(),
|
||||||
|arena, lit| match lit {
|
|arena, lit| match lit {
|
||||||
StrLikeLiteral::Str(s) => Pattern::StrLiteral(s),
|
StrLikeLiteral::Str(s) => Pattern::StrLiteral(s),
|
||||||
|
@ -263,7 +264,7 @@ fn string_like_pattern_help<'a>() -> impl Parser<'a, Pattern<'a>, EPattern<'a>>
|
||||||
// TODO: preserve the original escaping
|
// TODO: preserve the original escaping
|
||||||
Pattern::SingleQuote(s.to_str_in(arena))
|
Pattern::SingleQuote(s.to_str_in(arena))
|
||||||
}
|
}
|
||||||
}
|
},
|
||||||
),
|
),
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
|
@ -9,8 +9,8 @@ use crate::expr::{record_field, FoundApplyValue};
|
||||||
use crate::ident::{lowercase_ident, lowercase_ident_keyword_e};
|
use crate::ident::{lowercase_ident, lowercase_ident_keyword_e};
|
||||||
use crate::keyword;
|
use crate::keyword;
|
||||||
use crate::parser::{
|
use crate::parser::{
|
||||||
absolute_column_min_indent, and, increment_min_indent, loc, map, skip_first, skip_second,
|
absolute_column_min_indent, and, increment_min_indent, loc, map, map_with_arena, skip_first,
|
||||||
succeed, then, ERecord, ETypeAbilityImpl,
|
skip_second, succeed, then, ERecord, ETypeAbilityImpl,
|
||||||
};
|
};
|
||||||
use crate::parser::{
|
use crate::parser::{
|
||||||
allocated, backtrackable, byte, fail, optional, specialize_err, specialize_err_ref, two_bytes,
|
allocated, backtrackable, byte, fail, optional, specialize_err, specialize_err_ref, two_bytes,
|
||||||
|
@ -116,7 +116,7 @@ fn parse_type_alias_after_as<'a>() -> impl Parser<'a, TypeHeader<'a>, EType<'a>>
|
||||||
}
|
}
|
||||||
|
|
||||||
fn term<'a>(stop_at_surface_has: bool) -> impl Parser<'a, Loc<TypeAnnotation<'a>>, EType<'a>> {
|
fn term<'a>(stop_at_surface_has: bool) -> impl Parser<'a, Loc<TypeAnnotation<'a>>, EType<'a>> {
|
||||||
map_with_arena!(
|
map_with_arena(
|
||||||
and(
|
and(
|
||||||
one_of!(
|
one_of!(
|
||||||
loc_wildcard(),
|
loc_wildcard(),
|
||||||
|
@ -147,7 +147,7 @@ fn term<'a>(stop_at_surface_has: bool) -> impl Parser<'a, Loc<TypeAnnotation<'a>
|
||||||
Some
|
Some
|
||||||
),
|
),
|
||||||
succeed(None)
|
succeed(None)
|
||||||
]
|
],
|
||||||
),
|
),
|
||||||
|arena: &'a Bump,
|
|arena: &'a Bump,
|
||||||
(loc_ann, opt_as): (Loc<TypeAnnotation<'a>>, Option<(&'a [_], TypeHeader<'a>)>)| {
|
(loc_ann, opt_as): (Loc<TypeAnnotation<'a>>, Option<(&'a [_], TypeHeader<'a>)>)| {
|
||||||
|
@ -163,7 +163,7 @@ fn term<'a>(stop_at_surface_has: bool) -> impl Parser<'a, Loc<TypeAnnotation<'a>
|
||||||
|
|
||||||
None => loc_ann,
|
None => loc_ann,
|
||||||
}
|
}
|
||||||
}
|
},
|
||||||
)
|
)
|
||||||
.trace("type_annotation:term")
|
.trace("type_annotation:term")
|
||||||
}
|
}
|
||||||
|
@ -208,7 +208,7 @@ fn loc_inferred<'a>() -> impl Parser<'a, Loc<TypeAnnotation<'a>>, EType<'a>> {
|
||||||
fn loc_applied_arg<'a>(
|
fn loc_applied_arg<'a>(
|
||||||
stop_at_surface_has: bool,
|
stop_at_surface_has: bool,
|
||||||
) -> impl Parser<'a, Loc<TypeAnnotation<'a>>, EType<'a>> {
|
) -> impl Parser<'a, Loc<TypeAnnotation<'a>>, EType<'a>> {
|
||||||
map_with_arena!(
|
map_with_arena(
|
||||||
and(
|
and(
|
||||||
backtrackable(space0_e(EType::TIndentStart)),
|
backtrackable(space0_e(EType::TIndentStart)),
|
||||||
one_of!(
|
one_of!(
|
||||||
|
@ -225,7 +225,7 @@ fn loc_applied_arg<'a>(
|
||||||
)),
|
)),
|
||||||
loc(specialize_err(EType::TApply, concrete_type())),
|
loc(specialize_err(EType::TApply, concrete_type())),
|
||||||
loc(parse_type_variable(stop_at_surface_has))
|
loc(parse_type_variable(stop_at_surface_has))
|
||||||
)
|
),
|
||||||
),
|
),
|
||||||
|arena: &'a Bump, (spaces, argument): (&'a [_], Loc<TypeAnnotation<'a>>)| {
|
|arena: &'a Bump, (spaces, argument): (&'a [_], Loc<TypeAnnotation<'a>>)| {
|
||||||
if spaces.is_empty() {
|
if spaces.is_empty() {
|
||||||
|
@ -234,7 +234,7 @@ fn loc_applied_arg<'a>(
|
||||||
let Loc { region, value } = argument;
|
let Loc { region, value } = argument;
|
||||||
arena.alloc(value).with_spaces_before(spaces, region)
|
arena.alloc(value).with_spaces_before(spaces, region)
|
||||||
}
|
}
|
||||||
}
|
},
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue