mirror of
https://github.com/roc-lang/roc.git
synced 2024-10-04 22:27:55 +03:00
Un-macro map
This commit is contained in:
parent
41d7d02e2a
commit
3394aab650
@ -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, optional, reset_min_indent, sep_by1, sep_by1_e, set_min_indent, skip_first,
|
line_min_indent, map, optional, reset_min_indent, sep_by1, sep_by1_e, set_min_indent,
|
||||||
skip_second, specialize_err, specialize_err_ref, then, two_bytes, EClosure, EExpect, EExpr,
|
skip_first, skip_second, specialize_err, specialize_err_ref, then, two_bytes, EClosure,
|
||||||
EIf, EInParens, EList, ENumber, EPattern, ERecord, EString, EType, EWhen, Either, ParseResult,
|
EExpect, EExpr, EIf, EInParens, EList, ENumber, EPattern, ERecord, EString, EType, EWhen,
|
||||||
Parser,
|
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;
|
||||||
@ -163,8 +163,8 @@ fn record_field_access_chain<'a>() -> impl Parser<'a, Vec<'a, Accessor<'a>>, EEx
|
|||||||
specialize_err(
|
specialize_err(
|
||||||
|_, pos| EExpr::Access(pos),
|
|_, pos| EExpr::Access(pos),
|
||||||
one_of!(
|
one_of!(
|
||||||
map!(lowercase_ident(), Accessor::RecordField),
|
map(lowercase_ident(), Accessor::RecordField),
|
||||||
map!(integer_ident(), Accessor::TupleIndex),
|
map(integer_ident(), Accessor::TupleIndex),
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
))
|
))
|
||||||
@ -1483,7 +1483,7 @@ mod ability {
|
|||||||
|
|
||||||
/// Parses a single ability demand line; see `parse_demand`.
|
/// Parses a single ability demand line; see `parse_demand`.
|
||||||
fn parse_demand_help<'a>() -> impl Parser<'a, AbilityMember<'a>, EAbility<'a>> {
|
fn parse_demand_help<'a>() -> impl Parser<'a, AbilityMember<'a>, EAbility<'a>> {
|
||||||
map!(
|
map(
|
||||||
// Require the type to be more indented than the name
|
// Require the type to be more indented than the name
|
||||||
absolute_indented_seq(
|
absolute_indented_seq(
|
||||||
specialize_err(|_, pos| EAbility::DemandName(pos), loc!(lowercase_ident())),
|
specialize_err(|_, pos| EAbility::DemandName(pos), loc!(lowercase_ident())),
|
||||||
@ -1491,17 +1491,15 @@ mod ability {
|
|||||||
and(
|
and(
|
||||||
// TODO: do we get anything from picking up spaces here?
|
// TODO: do we get anything from picking up spaces here?
|
||||||
space0_e(EAbility::DemandName),
|
space0_e(EAbility::DemandName),
|
||||||
byte(b':', EAbility::DemandColon)
|
byte(b':', EAbility::DemandColon),
|
||||||
),
|
),
|
||||||
specialize_err(EAbility::Type, type_annotation::located(true))
|
specialize_err(EAbility::Type, type_annotation::located(true)),
|
||||||
)
|
),
|
||||||
),
|
),
|
||||||
|(name, typ): (Loc<&'a str>, Loc<TypeAnnotation<'a>>)| {
|
|(name, typ): (Loc<&'a str>, Loc<TypeAnnotation<'a>>)| AbilityMember {
|
||||||
AbilityMember {
|
name: name.map_owned(Spaced::Item),
|
||||||
name: name.map_owned(Spaced::Item),
|
typ,
|
||||||
typ,
|
},
|
||||||
}
|
|
||||||
}
|
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2457,7 +2455,7 @@ mod when {
|
|||||||
guard: loc_first_guard,
|
guard: loc_first_guard,
|
||||||
}));
|
}));
|
||||||
|
|
||||||
let branch_parser = map!(
|
let branch_parser = map(
|
||||||
and(
|
and(
|
||||||
then(
|
then(
|
||||||
branch_alternatives(options, Some(pattern_indent_level)),
|
branch_alternatives(options, Some(pattern_indent_level)),
|
||||||
@ -2470,7 +2468,7 @@ mod when {
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
branch_result(original_indent + 1)
|
branch_result(original_indent + 1),
|
||||||
),
|
),
|
||||||
|((patterns, guard), expr)| {
|
|((patterns, guard), expr)| {
|
||||||
let patterns: Vec<'a, _> = patterns;
|
let patterns: Vec<'a, _> = patterns;
|
||||||
@ -2479,7 +2477,7 @@ mod when {
|
|||||||
value: expr,
|
value: expr,
|
||||||
guard,
|
guard,
|
||||||
}
|
}
|
||||||
}
|
},
|
||||||
);
|
);
|
||||||
|
|
||||||
while !state.bytes().is_empty() {
|
while !state.bytes().is_empty() {
|
||||||
@ -2514,7 +2512,7 @@ mod when {
|
|||||||
and(
|
and(
|
||||||
branch_alternatives_help(pattern_indent_level),
|
branch_alternatives_help(pattern_indent_level),
|
||||||
one_of![
|
one_of![
|
||||||
map!(
|
map(
|
||||||
skip_first(
|
skip_first(
|
||||||
parser::keyword(keyword::IF, EWhen::IfToken),
|
parser::keyword(keyword::IF, EWhen::IfToken),
|
||||||
// TODO we should require space before the expression but not after
|
// TODO we should require space before the expression but not after
|
||||||
@ -3199,7 +3197,7 @@ fn string_like_literal_help<'a>() -> impl Parser<'a, Expr<'a>, EString<'a>> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn positive_number_literal_help<'a>() -> impl Parser<'a, Expr<'a>, ENumber> {
|
fn positive_number_literal_help<'a>() -> impl Parser<'a, Expr<'a>, ENumber> {
|
||||||
map!(
|
map(
|
||||||
crate::number_literal::positive_number_literal(),
|
crate::number_literal::positive_number_literal(),
|
||||||
|literal| {
|
|literal| {
|
||||||
use crate::number_literal::NumLiteral::*;
|
use crate::number_literal::NumLiteral::*;
|
||||||
@ -3217,12 +3215,12 @@ fn positive_number_literal_help<'a>() -> impl Parser<'a, Expr<'a>, ENumber> {
|
|||||||
is_negative,
|
is_negative,
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
}
|
},
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn number_literal_help<'a>() -> impl Parser<'a, Expr<'a>, ENumber> {
|
fn number_literal_help<'a>() -> impl Parser<'a, Expr<'a>, ENumber> {
|
||||||
map!(crate::number_literal::number_literal(), |literal| {
|
map(crate::number_literal::number_literal(), |literal| {
|
||||||
use crate::number_literal::NumLiteral::*;
|
use crate::number_literal::NumLiteral::*;
|
||||||
|
|
||||||
match literal {
|
match literal {
|
||||||
|
@ -9,7 +9,7 @@ use crate::header::{
|
|||||||
use crate::ident::{self, lowercase_ident, unqualified_ident, uppercase, UppercaseIdent};
|
use crate::ident::{self, lowercase_ident, unqualified_ident, uppercase, UppercaseIdent};
|
||||||
use crate::parser::Progress::{self, *};
|
use crate::parser::Progress::{self, *};
|
||||||
use crate::parser::{
|
use crate::parser::{
|
||||||
and, backtrackable, byte, increment_min_indent, optional, reset_min_indent, skip_first,
|
and, backtrackable, byte, increment_min_indent, map, optional, reset_min_indent, skip_first,
|
||||||
skip_second, specialize_err, two_bytes, EExposes, EGenerates, EGeneratesWith, EHeader,
|
skip_second, specialize_err, two_bytes, EExposes, EGenerates, EGeneratesWith, EHeader,
|
||||||
EImports, EPackages, EProvides, ERequires, ETypedIdent, Parser, SourceError, SpaceProblem,
|
EImports, EPackages, EProvides, ERequires, ETypedIdent, Parser, SourceError, SpaceProblem,
|
||||||
SyntaxError,
|
SyntaxError,
|
||||||
@ -54,35 +54,35 @@ pub fn header<'a>() -> impl Parser<'a, Module<'a>, EHeader<'a>> {
|
|||||||
record!(Module {
|
record!(Module {
|
||||||
comments: space0_e(EHeader::IndentStart),
|
comments: space0_e(EHeader::IndentStart),
|
||||||
header: one_of![
|
header: one_of![
|
||||||
map!(
|
map(
|
||||||
skip_first(
|
skip_first(
|
||||||
keyword("interface", EHeader::Start),
|
keyword("interface", EHeader::Start),
|
||||||
increment_min_indent(interface_header())
|
increment_min_indent(interface_header())
|
||||||
),
|
),
|
||||||
Header::Interface
|
Header::Interface
|
||||||
),
|
),
|
||||||
map!(
|
map(
|
||||||
skip_first(
|
skip_first(
|
||||||
keyword("app", EHeader::Start),
|
keyword("app", EHeader::Start),
|
||||||
increment_min_indent(app_header())
|
increment_min_indent(app_header())
|
||||||
),
|
),
|
||||||
Header::App
|
Header::App
|
||||||
),
|
),
|
||||||
map!(
|
map(
|
||||||
skip_first(
|
skip_first(
|
||||||
keyword("package", EHeader::Start),
|
keyword("package", EHeader::Start),
|
||||||
increment_min_indent(package_header())
|
increment_min_indent(package_header())
|
||||||
),
|
),
|
||||||
Header::Package
|
Header::Package
|
||||||
),
|
),
|
||||||
map!(
|
map(
|
||||||
skip_first(
|
skip_first(
|
||||||
keyword("platform", EHeader::Start),
|
keyword("platform", EHeader::Start),
|
||||||
increment_min_indent(platform_header())
|
increment_min_indent(platform_header())
|
||||||
),
|
),
|
||||||
Header::Platform
|
Header::Platform
|
||||||
),
|
),
|
||||||
map!(
|
map(
|
||||||
skip_first(
|
skip_first(
|
||||||
keyword("hosted", EHeader::Start),
|
keyword("hosted", EHeader::Start),
|
||||||
increment_min_indent(hosted_header())
|
increment_min_indent(hosted_header())
|
||||||
@ -220,9 +220,9 @@ fn provides_to_package<'a>() -> impl Parser<'a, To<'a>, EProvides<'a>> {
|
|||||||
one_of![
|
one_of![
|
||||||
specialize_err(
|
specialize_err(
|
||||||
|_, pos| EProvides::Identifier(pos),
|
|_, pos| EProvides::Identifier(pos),
|
||||||
map!(lowercase_ident(), To::ExistingPackage)
|
map(lowercase_ident(), To::ExistingPackage)
|
||||||
),
|
),
|
||||||
specialize_err(EProvides::Package, map!(package_name(), To::NewPackage))
|
specialize_err(EProvides::Package, map(package_name(), To::NewPackage))
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -309,7 +309,7 @@ where
|
|||||||
F: Copy,
|
F: Copy,
|
||||||
E: 'a,
|
E: 'a,
|
||||||
{
|
{
|
||||||
loc!(map!(
|
loc!(map(
|
||||||
specialize_err(|_, pos| to_expectation(pos), ident::uppercase()),
|
specialize_err(|_, pos| to_expectation(pos), ident::uppercase()),
|
||||||
Spaced::Item
|
Spaced::Item
|
||||||
))
|
))
|
||||||
@ -323,7 +323,7 @@ where
|
|||||||
F: Copy,
|
F: Copy,
|
||||||
E: 'a,
|
E: 'a,
|
||||||
{
|
{
|
||||||
loc!(map!(
|
loc!(map(
|
||||||
specialize_err(|_, pos| to_expectation(pos), unqualified_ident()),
|
specialize_err(|_, pos| to_expectation(pos), unqualified_ident()),
|
||||||
|n| Spaced::Item(ExposedName::new(n))
|
|n| Spaced::Item(ExposedName::new(n))
|
||||||
))
|
))
|
||||||
@ -358,7 +358,7 @@ fn requires_rigids<'a>(
|
|||||||
byte(b'{', ERequires::ListStart),
|
byte(b'{', ERequires::ListStart),
|
||||||
specialize_err(
|
specialize_err(
|
||||||
|_, pos| ERequires::Rigid(pos),
|
|_, pos| ERequires::Rigid(pos),
|
||||||
loc!(map!(ident::uppercase(), Spaced::Item))
|
loc!(map(ident::uppercase(), Spaced::Item))
|
||||||
),
|
),
|
||||||
byte(b',', ERequires::ListEnd),
|
byte(b',', ERequires::ListEnd),
|
||||||
byte(b'}', ERequires::ListEnd),
|
byte(b'}', ERequires::ListEnd),
|
||||||
@ -413,24 +413,22 @@ fn spaces_around_keyword<'a, K: Keyword, E>(
|
|||||||
where
|
where
|
||||||
E: 'a + SpaceProblem,
|
E: 'a + SpaceProblem,
|
||||||
{
|
{
|
||||||
map!(
|
map(
|
||||||
and(
|
and(
|
||||||
skip_second(
|
skip_second(
|
||||||
// parse any leading space before the keyword
|
// parse any leading space before the keyword
|
||||||
backtrackable(space0_e(indent_problem1)),
|
backtrackable(space0_e(indent_problem1)),
|
||||||
// parse the keyword
|
// parse the keyword
|
||||||
crate::parser::keyword(K::KEYWORD, expectation)
|
crate::parser::keyword(K::KEYWORD, expectation),
|
||||||
),
|
),
|
||||||
// parse the trailing space
|
// parse the trailing space
|
||||||
space0_e(indent_problem2)
|
space0_e(indent_problem2),
|
||||||
),
|
),
|
||||||
|(before, after)| {
|
move |(before, after)| Spaces {
|
||||||
Spaces {
|
before,
|
||||||
before,
|
item: keyword_item,
|
||||||
item: keyword_item,
|
after,
|
||||||
after,
|
},
|
||||||
}
|
|
||||||
}
|
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -465,7 +463,7 @@ where
|
|||||||
F: Copy,
|
F: Copy,
|
||||||
E: 'a,
|
E: 'a,
|
||||||
{
|
{
|
||||||
loc!(map!(
|
loc!(map(
|
||||||
specialize_err(|_, pos| to_expectation(pos), module_name()),
|
specialize_err(|_, pos| to_expectation(pos), module_name()),
|
||||||
Spaced::Item
|
Spaced::Item
|
||||||
))
|
))
|
||||||
@ -560,25 +558,25 @@ fn typed_ident<'a>() -> impl Parser<'a, Spaced<'a, TypedIdent<'a>>, ETypedIdent<
|
|||||||
// e.g.
|
// e.g.
|
||||||
//
|
//
|
||||||
// printLine : Str -> Effect {}
|
// printLine : Str -> Effect {}
|
||||||
map!(
|
map(
|
||||||
and(
|
and(
|
||||||
and(
|
and(
|
||||||
loc!(specialize_err(
|
loc!(specialize_err(
|
||||||
|_, pos| ETypedIdent::Identifier(pos),
|
|_, pos| ETypedIdent::Identifier(pos),
|
||||||
lowercase_ident()
|
lowercase_ident()
|
||||||
)),
|
)),
|
||||||
space0_e(ETypedIdent::IndentHasType)
|
space0_e(ETypedIdent::IndentHasType),
|
||||||
),
|
),
|
||||||
skip_first(
|
skip_first(
|
||||||
byte(b':', ETypedIdent::HasType),
|
byte(b':', ETypedIdent::HasType),
|
||||||
space0_before_e(
|
space0_before_e(
|
||||||
specialize_err(
|
specialize_err(
|
||||||
ETypedIdent::Type,
|
ETypedIdent::Type,
|
||||||
reset_min_indent(type_annotation::located(true))
|
reset_min_indent(type_annotation::located(true)),
|
||||||
),
|
),
|
||||||
ETypedIdent::IndentType,
|
ETypedIdent::IndentType,
|
||||||
)
|
),
|
||||||
)
|
),
|
||||||
),
|
),
|
||||||
|((ident, spaces_before_colon), ann)| {
|
|((ident, spaces_before_colon), ann)| {
|
||||||
Spaced::Item(TypedIdent {
|
Spaced::Item(TypedIdent {
|
||||||
@ -586,7 +584,7 @@ fn typed_ident<'a>() -> impl Parser<'a, Spaced<'a, TypedIdent<'a>>, ETypedIdent<
|
|||||||
spaces_before_colon,
|
spaces_before_colon,
|
||||||
ann,
|
ann,
|
||||||
})
|
})
|
||||||
}
|
},
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -611,7 +609,7 @@ fn imports_entry<'a>() -> impl Parser<'a, Spaced<'a, ImportsEntry<'a>>, EImports
|
|||||||
);
|
);
|
||||||
|
|
||||||
one_of!(
|
one_of!(
|
||||||
map!(
|
map(
|
||||||
and(
|
and(
|
||||||
and(
|
and(
|
||||||
// e.g. `pf.`
|
// e.g. `pf.`
|
||||||
@ -649,7 +647,7 @@ fn imports_entry<'a>() -> impl Parser<'a, Spaced<'a, ImportsEntry<'a>>, EImports
|
|||||||
}
|
}
|
||||||
)
|
)
|
||||||
.trace("normal_import"),
|
.trace("normal_import"),
|
||||||
map!(
|
map(
|
||||||
and(
|
and(
|
||||||
and(
|
and(
|
||||||
// e.g. "filename"
|
// e.g. "filename"
|
||||||
|
@ -2194,7 +2194,7 @@ macro_rules! byte_check_indent {
|
|||||||
/// # NotFound(Position),
|
/// # NotFound(Position),
|
||||||
/// # }
|
/// # }
|
||||||
/// # let arena = Bump::new();
|
/// # let arena = Bump::new();
|
||||||
/// let parser = map!(
|
/// let parser = map(
|
||||||
/// word("hello", Problem::NotFound),
|
/// word("hello", Problem::NotFound),
|
||||||
/// |_output| "new output!"
|
/// |_output| "new output!"
|
||||||
/// );
|
/// );
|
||||||
@ -2210,20 +2210,19 @@ macro_rules! byte_check_indent {
|
|||||||
/// assert_eq!(progress, Progress::NoProgress);
|
/// assert_eq!(progress, Progress::NoProgress);
|
||||||
/// assert_eq!(err, Problem::NotFound(Position::zero()));
|
/// assert_eq!(err, Problem::NotFound(Position::zero()));
|
||||||
/// ```
|
/// ```
|
||||||
#[macro_export]
|
pub fn map<'a, Output, MappedOutput, E: 'a>(
|
||||||
macro_rules! map {
|
parser: impl Parser<'a, Output, E>,
|
||||||
($parser:expr, $transform:expr) => {
|
transform: impl Fn(Output) -> MappedOutput,
|
||||||
move |arena, state, min_indent| {
|
) -> impl Parser<'a, MappedOutput, E> {
|
||||||
#[allow(clippy::redundant_closure_call)]
|
move |arena, state, min_indent| {
|
||||||
$parser
|
parser
|
||||||
.parse(arena, state, min_indent)
|
.parse(arena, state, min_indent)
|
||||||
.map(|(progress, output, next_state)| (progress, $transform(output), next_state))
|
.map(|(progress, output, next_state)| (progress, transform(output), next_state))
|
||||||
}
|
}
|
||||||
};
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// 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.
|
||||||
///
|
///
|
||||||
/// # Example
|
/// # Example
|
||||||
///
|
///
|
||||||
@ -2580,9 +2579,7 @@ where
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// 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.
|
||||||
///
|
|
||||||
/// Function version of the [`map_with_arena!`] macro.
|
|
||||||
///
|
///
|
||||||
/// For some reason, some usages won't compile unless they use this instead of the macro version.
|
/// 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.
|
/// This is likely because the lifetime `'a` is not defined at the call site.
|
||||||
|
@ -4,8 +4,8 @@ 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, optional, skip_first, specialize_err, specialize_err_ref,
|
self, backtrackable, byte, fail_when, map, optional, skip_first, specialize_err,
|
||||||
then, three_bytes, two_bytes, EPattern, PInParens, PList, PRecord, Parser,
|
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;
|
||||||
@ -232,7 +232,7 @@ fn loc_pattern_in_parens_help<'a>() -> impl Parser<'a, Loc<Pattern<'a>>, PInPare
|
|||||||
fn number_pattern_help<'a>() -> impl Parser<'a, Pattern<'a>, EPattern<'a>> {
|
fn number_pattern_help<'a>() -> impl Parser<'a, Pattern<'a>, EPattern<'a>> {
|
||||||
specialize_err(
|
specialize_err(
|
||||||
EPattern::NumLiteral,
|
EPattern::NumLiteral,
|
||||||
map!(crate::number_literal::number_literal(), |literal| {
|
map(crate::number_literal::number_literal(), |literal| {
|
||||||
use crate::number_literal::NumLiteral::*;
|
use crate::number_literal::NumLiteral::*;
|
||||||
|
|
||||||
match literal {
|
match literal {
|
||||||
@ -269,7 +269,7 @@ fn string_like_pattern_help<'a>() -> impl Parser<'a, Pattern<'a>, EPattern<'a>>
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn list_pattern_help<'a>() -> impl Parser<'a, Pattern<'a>, PList<'a>> {
|
fn list_pattern_help<'a>() -> impl Parser<'a, Pattern<'a>, PList<'a>> {
|
||||||
map!(
|
map(
|
||||||
collection_trailing_sep_e!(
|
collection_trailing_sep_e!(
|
||||||
byte(b'[', PList::Open),
|
byte(b'[', PList::Open),
|
||||||
list_element_pattern(),
|
list_element_pattern(),
|
||||||
@ -277,7 +277,7 @@ fn list_pattern_help<'a>() -> impl Parser<'a, Pattern<'a>, PList<'a>> {
|
|||||||
byte(b']', PList::End),
|
byte(b']', PList::End),
|
||||||
Pattern::SpaceBefore
|
Pattern::SpaceBefore
|
||||||
),
|
),
|
||||||
Pattern::List
|
Pattern::List,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -502,15 +502,15 @@ fn loc_ident_pattern_help<'a>(
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn underscore_pattern_help<'a>() -> impl Parser<'a, Pattern<'a>, EPattern<'a>> {
|
fn underscore_pattern_help<'a>() -> impl Parser<'a, Pattern<'a>, EPattern<'a>> {
|
||||||
map!(
|
map(
|
||||||
skip_first(
|
skip_first(
|
||||||
byte(b'_', EPattern::Underscore),
|
byte(b'_', EPattern::Underscore),
|
||||||
optional(lowercase_ident_pattern())
|
optional(lowercase_ident_pattern()),
|
||||||
),
|
),
|
||||||
|output| match output {
|
|output| match output {
|
||||||
Some(name) => Pattern::Underscore(name),
|
Some(name) => Pattern::Underscore(name),
|
||||||
None => Pattern::Underscore(""),
|
None => Pattern::Underscore(""),
|
||||||
}
|
},
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -520,7 +520,7 @@ fn lowercase_ident_pattern<'a>() -> impl Parser<'a, &'a str, EPattern<'a>> {
|
|||||||
|
|
||||||
#[inline(always)]
|
#[inline(always)]
|
||||||
fn record_pattern_help<'a>() -> impl Parser<'a, Pattern<'a>, PRecord<'a>> {
|
fn record_pattern_help<'a>() -> impl Parser<'a, Pattern<'a>, PRecord<'a>> {
|
||||||
map!(
|
map(
|
||||||
collection_trailing_sep_e!(
|
collection_trailing_sep_e!(
|
||||||
byte(b'{', PRecord::Open),
|
byte(b'{', PRecord::Open),
|
||||||
record_pattern_field(),
|
record_pattern_field(),
|
||||||
@ -528,7 +528,7 @@ fn record_pattern_help<'a>() -> impl Parser<'a, Pattern<'a>, PRecord<'a>> {
|
|||||||
byte(b'}', PRecord::End),
|
byte(b'}', PRecord::End),
|
||||||
Pattern::SpaceBefore
|
Pattern::SpaceBefore
|
||||||
),
|
),
|
||||||
Pattern::RecordDestructure
|
Pattern::RecordDestructure,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -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, skip_first, skip_second, then, ERecord,
|
absolute_column_min_indent, and, increment_min_indent, map, skip_first, skip_second, then,
|
||||||
ETypeAbilityImpl,
|
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,
|
||||||
@ -136,7 +136,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
|
// Inline alias notation, e.g. [Nil, Cons a (List a)] as List a
|
||||||
one_of![
|
one_of![
|
||||||
map!(
|
map(
|
||||||
and(
|
and(
|
||||||
skip_second(
|
skip_second(
|
||||||
backtrackable(space0_e(EType::TIndentEnd)),
|
backtrackable(space0_e(EType::TIndentEnd)),
|
||||||
@ -170,7 +170,7 @@ fn term<'a>(stop_at_surface_has: bool) -> impl Parser<'a, Loc<TypeAnnotation<'a>
|
|||||||
|
|
||||||
/// The `*` type variable, e.g. in (List *) Wildcard,
|
/// The `*` type variable, e.g. in (List *) Wildcard,
|
||||||
fn loc_wildcard<'a>() -> impl Parser<'a, Loc<TypeAnnotation<'a>>, EType<'a>> {
|
fn loc_wildcard<'a>() -> impl Parser<'a, Loc<TypeAnnotation<'a>>, EType<'a>> {
|
||||||
map!(loc!(byte(b'*', EType::TWildcard)), |loc_val: Loc<()>| {
|
map(loc!(byte(b'*', EType::TWildcard)), |loc_val: Loc<()>| {
|
||||||
loc_val.map(|_| TypeAnnotation::Wildcard)
|
loc_val.map(|_| TypeAnnotation::Wildcard)
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
@ -398,12 +398,12 @@ fn record_type<'a>(
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn applied_type<'a>(stop_at_surface_has: bool) -> impl Parser<'a, TypeAnnotation<'a>, EType<'a>> {
|
fn applied_type<'a>(stop_at_surface_has: bool) -> impl Parser<'a, TypeAnnotation<'a>, EType<'a>> {
|
||||||
map!(
|
map(
|
||||||
and(
|
and(
|
||||||
specialize_err(EType::TApply, concrete_type()),
|
specialize_err(EType::TApply, concrete_type()),
|
||||||
// Optionally parse space-separated arguments for the constructor,
|
// Optionally parse space-separated arguments for the constructor,
|
||||||
// e.g. `Str Float` in `Map Str Float`
|
// e.g. `Str Float` in `Map Str Float`
|
||||||
loc_applied_args_e(stop_at_surface_has)
|
loc_applied_args_e(stop_at_surface_has),
|
||||||
),
|
),
|
||||||
|(ctor, args): (TypeAnnotation<'a>, Vec<'a, Loc<TypeAnnotation<'a>>>)| {
|
|(ctor, args): (TypeAnnotation<'a>, Vec<'a, Loc<TypeAnnotation<'a>>>)| {
|
||||||
match &ctor {
|
match &ctor {
|
||||||
@ -418,7 +418,7 @@ fn applied_type<'a>(stop_at_surface_has: bool) -> impl Parser<'a, TypeAnnotation
|
|||||||
TypeAnnotation::Malformed(_) => ctor,
|
TypeAnnotation::Malformed(_) => ctor,
|
||||||
_ => unreachable!(),
|
_ => unreachable!(),
|
||||||
}
|
}
|
||||||
}
|
},
|
||||||
)
|
)
|
||||||
.trace("type_annotation:applied_type")
|
.trace("type_annotation:applied_type")
|
||||||
}
|
}
|
||||||
@ -431,7 +431,7 @@ fn loc_applied_args_e<'a>(
|
|||||||
|
|
||||||
// Hash & Eq & ...
|
// Hash & Eq & ...
|
||||||
fn ability_chain<'a>() -> impl Parser<'a, Vec<'a, Loc<TypeAnnotation<'a>>>, EType<'a>> {
|
fn ability_chain<'a>() -> impl Parser<'a, Vec<'a, Loc<TypeAnnotation<'a>>>, EType<'a>> {
|
||||||
map!(
|
map(
|
||||||
and(
|
and(
|
||||||
space0_before_optional_after(
|
space0_before_optional_after(
|
||||||
specialize_err(EType::TApply, loc!(concrete_type())),
|
specialize_err(EType::TApply, loc!(concrete_type())),
|
||||||
@ -445,37 +445,37 @@ fn ability_chain<'a>() -> impl Parser<'a, Vec<'a, Loc<TypeAnnotation<'a>>>, ETyp
|
|||||||
EType::TIndentStart,
|
EType::TIndentStart,
|
||||||
EType::TIndentEnd,
|
EType::TIndentEnd,
|
||||||
)
|
)
|
||||||
))
|
)),
|
||||||
),
|
),
|
||||||
|(first_ability, mut other_abilities): (
|
|(first_ability, mut other_abilities): (
|
||||||
Loc<TypeAnnotation<'a>>,
|
Loc<TypeAnnotation<'a>>,
|
||||||
Vec<'a, Loc<TypeAnnotation<'a>>>
|
Vec<'a, Loc<TypeAnnotation<'a>>>,
|
||||||
)| {
|
)| {
|
||||||
other_abilities.insert(0, first_ability);
|
other_abilities.insert(0, first_ability);
|
||||||
other_abilities
|
other_abilities
|
||||||
}
|
},
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn implements_clause<'a>() -> impl Parser<'a, Loc<ImplementsClause<'a>>, EType<'a>> {
|
fn implements_clause<'a>() -> impl Parser<'a, Loc<ImplementsClause<'a>>, EType<'a>> {
|
||||||
map!(
|
map(
|
||||||
// Suppose we are trying to parse "a implements Hash"
|
// Suppose we are trying to parse "a implements Hash"
|
||||||
and(
|
and(
|
||||||
space0_around_ee(
|
space0_around_ee(
|
||||||
// Parse "a", with appropriate spaces
|
// Parse "a", with appropriate spaces
|
||||||
specialize_err(
|
specialize_err(
|
||||||
|_, pos| EType::TBadTypeVariable(pos),
|
|_, pos| EType::TBadTypeVariable(pos),
|
||||||
loc!(map!(lowercase_ident(), Spaced::Item)),
|
loc!(map(lowercase_ident(), Spaced::Item)),
|
||||||
),
|
),
|
||||||
EType::TIndentStart,
|
EType::TIndentStart,
|
||||||
EType::TIndentEnd
|
EType::TIndentEnd,
|
||||||
),
|
),
|
||||||
skip_first(
|
skip_first(
|
||||||
// Parse "implements"; we don't care about this keyword
|
// Parse "implements"; we don't care about this keyword
|
||||||
word(crate::keyword::IMPLEMENTS, EType::TImplementsClause),
|
word(crate::keyword::IMPLEMENTS, EType::TImplementsClause),
|
||||||
// Parse "Hash & ..."; this may be qualified from another module like "Hash.Hash"
|
// Parse "Hash & ..."; this may be qualified from another module like "Hash.Hash"
|
||||||
absolute_column_min_indent(ability_chain())
|
absolute_column_min_indent(ability_chain()),
|
||||||
)
|
),
|
||||||
),
|
),
|
||||||
|(var, abilities): (Loc<Spaced<'a, &'a str>>, Vec<'a, Loc<TypeAnnotation<'a>>>)| {
|
|(var, abilities): (Loc<Spaced<'a, &'a str>>, Vec<'a, Loc<TypeAnnotation<'a>>>)| {
|
||||||
let abilities_region = Region::span_across(
|
let abilities_region = Region::span_across(
|
||||||
@ -488,7 +488,7 @@ fn implements_clause<'a>() -> impl Parser<'a, Loc<ImplementsClause<'a>>, EType<'
|
|||||||
abilities: abilities.into_bump_slice(),
|
abilities: abilities.into_bump_slice(),
|
||||||
};
|
};
|
||||||
Loc::at(region, implements_clause)
|
Loc::at(region, implements_clause)
|
||||||
}
|
},
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -530,7 +530,7 @@ pub fn implements_abilities<'a>() -> impl Parser<'a, Loc<ImplementsAbilities<'a>
|
|||||||
word(crate::keyword::IMPLEMENTS, EType::TImplementsClause),
|
word(crate::keyword::IMPLEMENTS, EType::TImplementsClause),
|
||||||
// Parse "Hash"; this may be qualified from another module like "Hash.Hash"
|
// Parse "Hash"; this may be qualified from another module like "Hash.Hash"
|
||||||
space0_before_e(
|
space0_before_e(
|
||||||
loc!(map!(
|
loc!(map(
|
||||||
collection_trailing_sep_e!(
|
collection_trailing_sep_e!(
|
||||||
byte(b'[', EType::TStart),
|
byte(b'[', EType::TStart),
|
||||||
loc!(parse_implements_ability()),
|
loc!(parse_implements_ability()),
|
||||||
@ -549,7 +549,7 @@ fn parse_implements_ability<'a>() -> impl Parser<'a, ImplementsAbility<'a>, ETyp
|
|||||||
increment_min_indent(record!(ImplementsAbility::ImplementsAbility {
|
increment_min_indent(record!(ImplementsAbility::ImplementsAbility {
|
||||||
ability: loc!(specialize_err(EType::TApply, concrete_type())),
|
ability: loc!(specialize_err(EType::TApply, concrete_type())),
|
||||||
impls: optional(backtrackable(space0_before_e(
|
impls: optional(backtrackable(space0_before_e(
|
||||||
loc!(map!(
|
loc!(map(
|
||||||
specialize_err(
|
specialize_err(
|
||||||
EType::TAbilityImpl,
|
EType::TAbilityImpl,
|
||||||
collection_trailing_sep_e!(
|
collection_trailing_sep_e!(
|
||||||
|
Loading…
Reference in New Issue
Block a user