mirror of
https://github.com/roc-lang/roc.git
synced 2025-08-03 19:58:18 +00:00
Un-macro add
This commit is contained in:
parent
64290a8cf6
commit
41d7d02e2a
6 changed files with 89 additions and 138 deletions
|
@ -138,7 +138,7 @@ where
|
|||
E: 'a + SpaceProblem,
|
||||
{
|
||||
parser::map_with_arena(
|
||||
and!(spaces(), parser),
|
||||
and(spaces(), parser),
|
||||
|arena: &'a Bump, (space_list, loc_expr): (&'a [CommentOrNewline<'a>], Loc<S>)| {
|
||||
if space_list.is_empty() {
|
||||
loc_expr
|
||||
|
@ -161,7 +161,7 @@ where
|
|||
E: 'a + SpaceProblem,
|
||||
{
|
||||
parser::map_with_arena(
|
||||
and!(space0_e(indent_problem), parser),
|
||||
and(space0_e(indent_problem), parser),
|
||||
|arena: &'a Bump, (space_list, loc_expr): (&'a [CommentOrNewline<'a>], Loc<S>)| {
|
||||
if space_list.is_empty() {
|
||||
loc_expr
|
||||
|
@ -184,7 +184,7 @@ where
|
|||
E: 'a + SpaceProblem,
|
||||
{
|
||||
parser::map_with_arena(
|
||||
and!(parser, space0_e(indent_problem)),
|
||||
and(parser, space0_e(indent_problem)),
|
||||
|arena: &'a Bump, (loc_expr, space_list): (Loc<S>, &'a [CommentOrNewline<'a>])| {
|
||||
if space_list.is_empty() {
|
||||
loc_expr
|
||||
|
|
|
@ -10,7 +10,7 @@ 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, indented_seq,
|
||||
self, and, 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,
|
||||
|
@ -132,7 +132,7 @@ 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>> {
|
||||
map_with_arena!(
|
||||
loc!(and!(
|
||||
loc!(and(
|
||||
specialize_err(EExpr::InParens, loc_expr_in_parens_help()),
|
||||
record_field_access_chain()
|
||||
)),
|
||||
|
@ -273,7 +273,7 @@ fn loc_possibly_negative_or_negated_term<'a>(
|
|||
let initial = state.clone();
|
||||
|
||||
let (_, (loc_op, loc_expr), state) =
|
||||
and!(loc!(unary_negate()), loc_term(options)).parse(arena, state, min_indent)?;
|
||||
and(loc!(unary_negate()), loc_term(options)).parse(arena, state, min_indent)?;
|
||||
|
||||
let loc_expr = numeric_negate_expression(arena, initial, loc_op, loc_expr, &[]);
|
||||
|
||||
|
@ -282,7 +282,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)
|
||||
loc!(specialize_err(EExpr::Number, number_literal_help())),
|
||||
loc!(map_with_arena!(
|
||||
and!(
|
||||
and(
|
||||
loc!(byte(b'!', EExpr::Start)),
|
||||
space0_before_e(loc_term(options), EExpr::IndentStart)
|
||||
),
|
||||
|
@ -1296,7 +1296,7 @@ fn opaque_signature_with_space_before<'a>() -> impl Parser<
|
|||
),
|
||||
EExpr<'a>,
|
||||
> {
|
||||
and!(
|
||||
and(
|
||||
specialize_err(
|
||||
EExpr::Type,
|
||||
space0_before_e(
|
||||
|
@ -1306,8 +1306,8 @@ fn opaque_signature_with_space_before<'a>() -> impl Parser<
|
|||
),
|
||||
optional(backtrackable(specialize_err(
|
||||
EExpr::Type,
|
||||
space0_before_e(type_annotation::implements_abilities(), EType::TIndentStart,),
|
||||
)))
|
||||
space0_before_e(type_annotation::implements_abilities(), EType::TIndentStart),
|
||||
))),
|
||||
)
|
||||
}
|
||||
|
||||
|
@ -1488,7 +1488,7 @@ mod ability {
|
|||
absolute_indented_seq(
|
||||
specialize_err(|_, pos| EAbility::DemandName(pos), loc!(lowercase_ident())),
|
||||
skip_first(
|
||||
and!(
|
||||
and(
|
||||
// TODO: do we get anything from picking up spaces here?
|
||||
space0_e(EAbility::DemandName),
|
||||
byte(b':', EAbility::DemandColon)
|
||||
|
@ -2368,7 +2368,7 @@ fn closure_help<'a>(options: ExprParseOptions) -> impl Parser<'a, Expr<'a>, EClo
|
|||
byte_indent(b'\\', EClosure::Start),
|
||||
// Once we see the '\', we're committed to parsing this as a closure.
|
||||
// It may turn out to be malformed, but it is definitely a closure.
|
||||
and!(
|
||||
and(
|
||||
// Parse the params
|
||||
// Params are comma-separated
|
||||
sep_by1_e(
|
||||
|
@ -2406,7 +2406,7 @@ mod when {
|
|||
/// Parser for when expressions.
|
||||
pub fn expr_help<'a>(options: ExprParseOptions) -> impl Parser<'a, Expr<'a>, EWhen<'a>> {
|
||||
map_with_arena!(
|
||||
and!(
|
||||
and(
|
||||
indented_seq(
|
||||
parser::keyword(keyword::WHEN, EWhen::When),
|
||||
space0_around_e_no_after_indent_check(
|
||||
|
@ -2458,7 +2458,7 @@ mod when {
|
|||
}));
|
||||
|
||||
let branch_parser = map!(
|
||||
and!(
|
||||
and(
|
||||
then(
|
||||
branch_alternatives(options, Some(pattern_indent_level)),
|
||||
move |_arena, state, _, ((indent_column, loc_patterns), loc_guard)| {
|
||||
|
@ -2511,7 +2511,7 @@ mod when {
|
|||
check_for_arrow: false,
|
||||
..options
|
||||
};
|
||||
and!(
|
||||
and(
|
||||
branch_alternatives_help(pattern_indent_level),
|
||||
one_of![
|
||||
map!(
|
||||
|
@ -2530,7 +2530,7 @@ mod when {
|
|||
Some
|
||||
),
|
||||
|_, s, _| Ok((NoProgress, None, s))
|
||||
]
|
||||
],
|
||||
)
|
||||
}
|
||||
|
||||
|
@ -2631,20 +2631,20 @@ mod when {
|
|||
|
||||
fn if_branch<'a>() -> impl Parser<'a, (Loc<Expr<'a>>, Loc<Expr<'a>>), EIf<'a>> {
|
||||
skip_second(
|
||||
and!(
|
||||
and(
|
||||
skip_second(
|
||||
space0_around_ee(
|
||||
specialize_err_ref(EIf::Condition, loc_expr(true)),
|
||||
EIf::IndentCondition,
|
||||
EIf::IndentThenToken,
|
||||
),
|
||||
parser::keyword(keyword::THEN, EIf::Then)
|
||||
parser::keyword(keyword::THEN, EIf::Then),
|
||||
),
|
||||
space0_around_ee(
|
||||
specialize_err_ref(EIf::ThenBranch, loc_expr(true)),
|
||||
EIf::IndentThenBranch,
|
||||
EIf::IndentElseToken,
|
||||
)
|
||||
),
|
||||
),
|
||||
parser::keyword(keyword::ELSE, EIf::Else),
|
||||
)
|
||||
|
@ -2727,9 +2727,9 @@ fn if_expr_help<'a>(options: ExprParseOptions) -> impl Parser<'a, Expr<'a>, EIf<
|
|||
|
||||
// try to parse another `if`
|
||||
// NOTE this drops spaces between the `else` and the `if`
|
||||
let optional_if = and!(
|
||||
let optional_if = and(
|
||||
backtrackable(space0_e(EIf::IndentIf)),
|
||||
parser::keyword(keyword::IF, EIf::If)
|
||||
parser::keyword(keyword::IF, EIf::If),
|
||||
);
|
||||
|
||||
match optional_if.parse(arena, state.clone(), min_indent) {
|
||||
|
@ -2981,13 +2981,13 @@ pub fn record_field<'a>() -> impl Parser<'a, RecordField<'a>, ERecord<'a>> {
|
|||
use RecordField::*;
|
||||
|
||||
map_with_arena!(
|
||||
and!(
|
||||
and(
|
||||
specialize_err(|_, pos| ERecord::Field(pos), loc!(lowercase_ident())),
|
||||
and!(
|
||||
and(
|
||||
spaces(),
|
||||
optional(either!(
|
||||
and!(byte(b':', ERecord::Colon), record_field_expr()),
|
||||
and!(
|
||||
and(byte(b':', ERecord::Colon), record_field_expr()),
|
||||
and(
|
||||
byte(b'?', ERecord::QuestionMark),
|
||||
spaces_before(specialize_err_ref(ERecord::Expr, loc_expr(false)))
|
||||
)
|
||||
|
@ -3029,10 +3029,10 @@ enum RecordFieldExpr<'a> {
|
|||
|
||||
fn record_field_expr<'a>() -> impl Parser<'a, RecordFieldExpr<'a>, ERecord<'a>> {
|
||||
map_with_arena!(
|
||||
and!(
|
||||
and(
|
||||
spaces(),
|
||||
either!(
|
||||
and!(
|
||||
and(
|
||||
two_bytes(b'<', b'-', ERecord::Arrow),
|
||||
spaces_before(specialize_err_ref(ERecord::Expr, loc_expr(false)))
|
||||
),
|
||||
|
@ -3096,10 +3096,10 @@ fn record_help<'a>() -> impl Parser<'a, RecordHelp<'a>, ERecord<'a>> {
|
|||
|
||||
fn record_literal_help<'a>() -> impl Parser<'a, Expr<'a>, EExpr<'a>> {
|
||||
then(
|
||||
and!(
|
||||
and(
|
||||
specialize_err(EExpr::Record, record_help()),
|
||||
// there can be field access, e.g. `{ x : 4 }.x`
|
||||
record_field_access_chain()
|
||||
record_field_access_chain(),
|
||||
),
|
||||
move |arena, state, _, (record, accessors)| {
|
||||
let expr_result = match record.update {
|
||||
|
|
|
@ -4,7 +4,7 @@ use crate::ast::{
|
|||
use crate::blankspace::space0_e;
|
||||
use crate::expr::merge_spaces;
|
||||
use crate::ident::{lowercase_ident, UppercaseIdent};
|
||||
use crate::parser::{byte, skip_second, specialize_err, EPackageEntry, EPackageName, Parser};
|
||||
use crate::parser::{and, byte, skip_second, specialize_err, EPackageEntry, EPackageName, Parser};
|
||||
use crate::parser::{optional, then};
|
||||
use crate::string_literal;
|
||||
use roc_module::symbol::{ModuleId, Symbol};
|
||||
|
@ -342,10 +342,10 @@ pub fn package_entry<'a>() -> impl Parser<'a, Spaced<'a, PackageEntry<'a>>, EPac
|
|||
// e.g. "uc" in `uc: roc/unicode 1.0.0`
|
||||
//
|
||||
// (Indirect dependencies don't have a shorthand.)
|
||||
and!(
|
||||
optional(and!(
|
||||
and(
|
||||
optional(and(
|
||||
skip_second(
|
||||
and!(
|
||||
and(
|
||||
specialize_err(|_, pos| EPackageEntry::Shorthand(pos), lowercase_ident()),
|
||||
space0_e(EPackageEntry::IndentPackage)
|
||||
),
|
||||
|
|
|
@ -9,9 +9,10 @@ use crate::header::{
|
|||
use crate::ident::{self, lowercase_ident, unqualified_ident, uppercase, UppercaseIdent};
|
||||
use crate::parser::Progress::{self, *};
|
||||
use crate::parser::{
|
||||
backtrackable, byte, increment_min_indent, optional, reset_min_indent, skip_first, skip_second,
|
||||
specialize_err, two_bytes, EExposes, EGenerates, EGeneratesWith, EHeader, EImports, EPackages,
|
||||
EProvides, ERequires, ETypedIdent, Parser, SourceError, SpaceProblem, SyntaxError,
|
||||
and, backtrackable, byte, increment_min_indent, optional, reset_min_indent, skip_first,
|
||||
skip_second, specialize_err, two_bytes, EExposes, EGenerates, EGeneratesWith, EHeader,
|
||||
EImports, EPackages, EProvides, ERequires, ETypedIdent, Parser, SourceError, SpaceProblem,
|
||||
SyntaxError,
|
||||
};
|
||||
use crate::state::State;
|
||||
use crate::string_literal::{self, parse_str_literal};
|
||||
|
@ -413,7 +414,7 @@ where
|
|||
E: 'a + SpaceProblem,
|
||||
{
|
||||
map!(
|
||||
and!(
|
||||
and(
|
||||
skip_second(
|
||||
// parse any leading space before the keyword
|
||||
backtrackable(space0_e(indent_problem1)),
|
||||
|
@ -560,8 +561,8 @@ fn typed_ident<'a>() -> impl Parser<'a, Spaced<'a, TypedIdent<'a>>, ETypedIdent<
|
|||
//
|
||||
// printLine : Str -> Effect {}
|
||||
map!(
|
||||
and!(
|
||||
and!(
|
||||
and(
|
||||
and(
|
||||
loc!(specialize_err(
|
||||
|_, pos| ETypedIdent::Identifier(pos),
|
||||
lowercase_ident()
|
||||
|
@ -611,8 +612,8 @@ fn imports_entry<'a>() -> impl Parser<'a, Spaced<'a, ImportsEntry<'a>>, EImports
|
|||
|
||||
one_of!(
|
||||
map!(
|
||||
and!(
|
||||
and!(
|
||||
and(
|
||||
and(
|
||||
// e.g. `pf.`
|
||||
optional(backtrackable(skip_second(
|
||||
shortname(),
|
||||
|
@ -649,14 +650,14 @@ fn imports_entry<'a>() -> impl Parser<'a, Spaced<'a, ImportsEntry<'a>>, EImports
|
|||
)
|
||||
.trace("normal_import"),
|
||||
map!(
|
||||
and!(
|
||||
and!(
|
||||
and(
|
||||
and(
|
||||
// e.g. "filename"
|
||||
// TODO: str literal allows for multiline strings. We probably don't want that for file names.
|
||||
specialize_err(|_, pos| EImports::StrLiteral(pos), parse_str_literal()),
|
||||
// e.g. as
|
||||
and!(
|
||||
and!(
|
||||
and(
|
||||
and(
|
||||
space0_e(EImports::AsKeyword),
|
||||
two_bytes(b'a', b's', EImports::AsKeyword)
|
||||
),
|
||||
|
|
|
@ -1462,8 +1462,8 @@ where
|
|||
macro_rules! collection_inner {
|
||||
($elem:expr, $delimiter:expr, $space_before:expr) => {
|
||||
map_with_arena!(
|
||||
and!(
|
||||
and!(
|
||||
$crate::parser::and(
|
||||
$crate::parser::and(
|
||||
$crate::blankspace::spaces(),
|
||||
$crate::parser::trailing_sep_by0(
|
||||
$delimiter,
|
||||
|
@ -1622,49 +1622,47 @@ where
|
|||
/// Runs two parsers in succession. If both parsers succeed, the output is a tuple of both outputs.
|
||||
/// Both parsers must have the same error type.
|
||||
///
|
||||
/// # Examples
|
||||
/// # Example
|
||||
///
|
||||
/// ```
|
||||
/// # #![forbid(unused_imports)]
|
||||
/// # use roc_parse::state::State;
|
||||
/// # use crate::roc_parse::parser::{Parser, Progress, word, byte};
|
||||
/// # use crate::roc_parse::parser::{Parser, Progress, and, word};
|
||||
/// # use roc_region::all::Position;
|
||||
/// # use roc_parse::and;
|
||||
/// # use bumpalo::Bump;
|
||||
/// # #[derive(Debug, PartialEq)]
|
||||
/// # enum Problem {
|
||||
/// # NotFound(Position),
|
||||
/// # }
|
||||
/// # let arena = Bump::new();
|
||||
/// # fn foo<'a>(arena: &'a Bump) {
|
||||
/// let parser = and!(
|
||||
/// word("hello", Problem::NotFound),
|
||||
/// byte(b',', Problem::NotFound)
|
||||
/// );
|
||||
/// let parser1 = word("hello", Problem::NotFound);
|
||||
/// let parser2 = word(", ", Problem::NotFound);
|
||||
/// let parser = and(parser1, parser2);
|
||||
///
|
||||
/// // 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, ((), ()));
|
||||
/// assert_eq!(state.pos().offset, 6);
|
||||
/// assert_eq!(output, ((),()));
|
||||
/// assert_eq!(state.pos(), Position::new(7));
|
||||
///
|
||||
/// let (progress, err) = parser.parse(&arena, State::new("hello! world".as_bytes()), 0).unwrap_err();
|
||||
/// // Error case
|
||||
/// let (progress, err) = parser.parse(&arena, State::new("hello!! world".as_bytes()), 0).unwrap_err();
|
||||
/// assert_eq!(progress, Progress::MadeProgress);
|
||||
/// assert_eq!(err, Problem::NotFound(Position::new(5)));
|
||||
/// # }
|
||||
/// # foo(&arena);
|
||||
/// ```
|
||||
#[macro_export]
|
||||
macro_rules! and {
|
||||
($p1:expr, $p2:expr) => {
|
||||
move |arena: &'a bumpalo::Bump, state: $crate::state::State<'a>, min_indent: u32| match $p1
|
||||
.parse(arena, state, min_indent)
|
||||
{
|
||||
Ok((p1, out1, state)) => match $p2.parse(arena, state, min_indent) {
|
||||
Ok((p2, out2, state)) => Ok((p1.or(p2), (out1, out2), state)),
|
||||
Err((p2, fail)) => Err((p1.or(p2), fail)),
|
||||
},
|
||||
Err((progress, fail)) => Err((progress, fail)),
|
||||
}
|
||||
};
|
||||
pub fn and<'a, Output1, Output2, E: 'a>(
|
||||
p1: impl Parser<'a, Output1, E>,
|
||||
p2: impl Parser<'a, Output2, E>,
|
||||
) -> impl Parser<'a, (Output1, Output2), E> {
|
||||
move |arena: &'a bumpalo::Bump, state: crate::state::State<'a>, min_indent: u32| match p1
|
||||
.parse(arena, state, min_indent)
|
||||
{
|
||||
Ok((p1, out1, state)) => match p2.parse(arena, state, min_indent) {
|
||||
Ok((p2, out2, state)) => Ok((p1.or(p2), (out1, out2), state)),
|
||||
Err((p2, fail)) => Err((p1.or(p2), fail)),
|
||||
},
|
||||
Err((progress, fail)) => Err((progress, fail)),
|
||||
}
|
||||
}
|
||||
|
||||
/// Take as input something that looks like a struct literal where values are parsers
|
||||
|
@ -1715,7 +1713,7 @@ pub fn indented_seq<'a, O, E: 'a>(
|
|||
}
|
||||
}
|
||||
|
||||
/// Similar to [`and!`], but we modify the `min_indent` of the second parser to be
|
||||
/// Similar to [`and`], but we modify the `min_indent` of the second parser to be
|
||||
/// 1 greater than the `column()` at the start of the first parser.
|
||||
pub fn absolute_indented_seq<'a, Output1, Output2, E: 'a>(
|
||||
p1: impl Parser<'a, Output1, E>,
|
||||
|
@ -2173,9 +2171,9 @@ where
|
|||
#[macro_export]
|
||||
macro_rules! byte_check_indent {
|
||||
($byte_to_match:expr, $problem:expr, $min_indent:expr, $indent_problem:expr) => {
|
||||
and!(
|
||||
$crate::parser::and(
|
||||
byte($byte_to_match, $problem),
|
||||
$crate::parser::check_indent($min_indent, $indent_problem)
|
||||
$crate::parser::check_indent($min_indent, $indent_problem),
|
||||
)
|
||||
};
|
||||
}
|
||||
|
@ -2545,54 +2543,6 @@ pub fn between<'a, Before, Inner, After, Err: 'a>(
|
|||
skip_first(opening_brace, skip_second(inner, closing_brace))
|
||||
}
|
||||
|
||||
/// Runs two parsers in succession. If both parsers succeed, the output is a tuple of both outputs.
|
||||
/// Both parsers must have the same error type.
|
||||
///
|
||||
/// This is a function version of the [`and!`] macro.
|
||||
/// For some reason, some usages won't compile unless they use this instead of the macro version.
|
||||
///
|
||||
/// # Example
|
||||
///
|
||||
/// ```
|
||||
/// # #![forbid(unused_imports)]
|
||||
/// # use roc_parse::state::State;
|
||||
/// # use crate::roc_parse::parser::{Parser, Progress, and, word};
|
||||
/// # use roc_region::all::Position;
|
||||
/// # use bumpalo::Bump;
|
||||
/// # #[derive(Debug, PartialEq)]
|
||||
/// # enum Problem {
|
||||
/// # NotFound(Position),
|
||||
/// # }
|
||||
/// # let arena = Bump::new();
|
||||
/// let parser1 = word("hello", Problem::NotFound);
|
||||
/// let parser2 = word(", ", Problem::NotFound);
|
||||
/// let parser = and(parser1, parser2);
|
||||
///
|
||||
/// // 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, ((),()));
|
||||
/// assert_eq!(state.pos(), Position::new(7));
|
||||
///
|
||||
/// // Error case
|
||||
/// let (progress, err) = parser.parse(&arena, State::new("hello!! world".as_bytes()), 0).unwrap_err();
|
||||
/// assert_eq!(progress, Progress::MadeProgress);
|
||||
/// assert_eq!(err, Problem::NotFound(Position::new(5)));
|
||||
/// ```
|
||||
#[inline(always)]
|
||||
pub fn and<'a, P1, P2, A, B, E>(p1: P1, p2: P2) -> impl Parser<'a, (A, B), E>
|
||||
where
|
||||
P1: Parser<'a, A, E>,
|
||||
P2: Parser<'a, B, E>,
|
||||
P1: 'a,
|
||||
P2: 'a,
|
||||
A: 'a,
|
||||
B: 'a,
|
||||
E: 'a,
|
||||
{
|
||||
and!(p1, p2)
|
||||
}
|
||||
|
||||
/// Adds location info. This is a function version the [`loc!`] macro.
|
||||
///
|
||||
/// For some reason, some usages won't compile unless they use this instead of the macro version.
|
||||
|
|
|
@ -9,7 +9,7 @@ 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, increment_min_indent, skip_first, skip_second, then, ERecord,
|
||||
absolute_column_min_indent, and, increment_min_indent, skip_first, skip_second, then, ERecord,
|
||||
ETypeAbilityImpl,
|
||||
};
|
||||
use crate::parser::{
|
||||
|
@ -117,7 +117,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>> {
|
||||
map_with_arena!(
|
||||
and!(
|
||||
and(
|
||||
one_of!(
|
||||
loc_wildcard(),
|
||||
loc_inferred(),
|
||||
|
@ -137,7 +137,7 @@ fn term<'a>(stop_at_surface_has: bool) -> impl Parser<'a, Loc<TypeAnnotation<'a>
|
|||
// Inline alias notation, e.g. [Nil, Cons a (List a)] as List a
|
||||
one_of![
|
||||
map!(
|
||||
and!(
|
||||
and(
|
||||
skip_second(
|
||||
backtrackable(space0_e(EType::TIndentEnd)),
|
||||
crate::parser::keyword(keyword::AS, EType::TEnd)
|
||||
|
@ -209,7 +209,7 @@ fn loc_applied_arg<'a>(
|
|||
stop_at_surface_has: bool,
|
||||
) -> impl Parser<'a, Loc<TypeAnnotation<'a>>, EType<'a>> {
|
||||
map_with_arena!(
|
||||
and!(
|
||||
and(
|
||||
backtrackable(space0_e(EType::TIndentStart)),
|
||||
one_of!(
|
||||
loc_wildcard(),
|
||||
|
@ -242,7 +242,7 @@ fn loc_type_in_parens<'a>(
|
|||
stop_at_surface_has: bool,
|
||||
) -> impl Parser<'a, Loc<TypeAnnotation<'a>>, ETypeInParens<'a>> {
|
||||
then(
|
||||
loc!(and!(
|
||||
loc!(and(
|
||||
collection_trailing_sep_e!(
|
||||
byte(b'(', ETypeInParens::Open),
|
||||
specialize_err_ref(ETypeInParens::Type, expression(true, false)),
|
||||
|
@ -399,7 +399,7 @@ fn record_type<'a>(
|
|||
|
||||
fn applied_type<'a>(stop_at_surface_has: bool) -> impl Parser<'a, TypeAnnotation<'a>, EType<'a>> {
|
||||
map!(
|
||||
and!(
|
||||
and(
|
||||
specialize_err(EType::TApply, concrete_type()),
|
||||
// Optionally parse space-separated arguments for the constructor,
|
||||
// e.g. `Str Float` in `Map Str Float`
|
||||
|
@ -432,7 +432,7 @@ fn loc_applied_args_e<'a>(
|
|||
// Hash & Eq & ...
|
||||
fn ability_chain<'a>() -> impl Parser<'a, Vec<'a, Loc<TypeAnnotation<'a>>>, EType<'a>> {
|
||||
map!(
|
||||
and!(
|
||||
and(
|
||||
space0_before_optional_after(
|
||||
specialize_err(EType::TApply, loc!(concrete_type())),
|
||||
EType::TIndentStart,
|
||||
|
@ -460,7 +460,7 @@ fn ability_chain<'a>() -> impl Parser<'a, Vec<'a, Loc<TypeAnnotation<'a>>>, ETyp
|
|||
fn implements_clause<'a>() -> impl Parser<'a, Loc<ImplementsClause<'a>>, EType<'a>> {
|
||||
map!(
|
||||
// Suppose we are trying to parse "a implements Hash"
|
||||
and!(
|
||||
and(
|
||||
space0_around_ee(
|
||||
// Parse "a", with appropriate spaces
|
||||
specialize_err(
|
||||
|
@ -497,9 +497,9 @@ fn implements_clause<'a>() -> impl Parser<'a, Loc<ImplementsClause<'a>>, EType<'
|
|||
fn implements_clause_chain<'a>(
|
||||
) -> impl Parser<'a, (&'a [CommentOrNewline<'a>], &'a [Loc<ImplementsClause<'a>>]), EType<'a>> {
|
||||
move |arena, state: State<'a>, min_indent: u32| {
|
||||
let (_, (spaces_before, ()), state) = and!(
|
||||
let (_, (spaces_before, ()), state) = and(
|
||||
space0_e(EType::TIndentStart),
|
||||
word(crate::keyword::WHERE, EType::TWhereBar)
|
||||
word(crate::keyword::WHERE, EType::TWhereBar),
|
||||
)
|
||||
.parse(arena, state, min_indent)?;
|
||||
|
||||
|
@ -584,7 +584,7 @@ fn expression<'a>(
|
|||
let (p1, first, state) = space0_before_e(term(stop_at_surface_has), EType::TIndentStart)
|
||||
.parse(arena, state, min_indent)?;
|
||||
|
||||
let result = and![
|
||||
let result = and(
|
||||
zero_or_more!(skip_first(
|
||||
byte(b',', EType::TFunctionArgument),
|
||||
one_of![
|
||||
|
@ -599,10 +599,10 @@ fn expression<'a>(
|
|||
.trace("type_annotation:expression:rest_args"),
|
||||
skip_second(
|
||||
space0_e(EType::TIndentStart),
|
||||
two_bytes(b'-', b'>', EType::TStart)
|
||||
two_bytes(b'-', b'>', EType::TStart),
|
||||
)
|
||||
.trace("type_annotation:expression:arrow")
|
||||
]
|
||||
.trace("type_annotation:expression:arrow"),
|
||||
)
|
||||
.parse(arena, state.clone(), min_indent);
|
||||
|
||||
let (progress, annot, state) = match result {
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue