mirror of
https://github.com/roc-lang/roc.git
synced 2024-09-20 15:27:45 +03:00
Parse impl blocks in abilities
This commit is contained in:
parent
d4d073d8c6
commit
85599e3a9a
@ -434,13 +434,23 @@ pub struct HasClause<'a> {
|
||||
pub ability: AbilityName<'a>,
|
||||
}
|
||||
|
||||
#[derive(Debug, Copy, Clone, PartialEq)]
|
||||
pub enum HasImpls<'a> {
|
||||
// `{ eq: myEq }`
|
||||
HasImpls(Collection<'a, Loc<AssignedField<'a, TypeAnnotation<'a>>>>),
|
||||
|
||||
// We preserve this for the formatter; canonicalization ignores it.
|
||||
SpaceBefore(&'a HasImpls<'a>, &'a [CommentOrNewline<'a>]),
|
||||
SpaceAfter(&'a HasImpls<'a>, &'a [CommentOrNewline<'a>]),
|
||||
}
|
||||
|
||||
/// `Eq` or `Eq { eq: myEq }`
|
||||
#[derive(Debug, Copy, Clone, PartialEq)]
|
||||
pub enum HasAbility<'a> {
|
||||
HasAbility {
|
||||
/// Should be a zero-argument `Apply` or an error; we'll check this in canonicalization
|
||||
ability: Loc<TypeAnnotation<'a>>,
|
||||
impls: Collection<'a, Loc<AssignedField<'a, TypeAnnotation<'a>>>>,
|
||||
impls: Option<Loc<HasImpls<'a>>>,
|
||||
},
|
||||
|
||||
// We preserve this for the formatter; canonicalization ignores it.
|
||||
@ -987,6 +997,15 @@ impl<'a> Spaceable<'a> for Has<'a> {
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a> Spaceable<'a> for HasImpls<'a> {
|
||||
fn before(&'a self, spaces: &'a [CommentOrNewline<'a>]) -> Self {
|
||||
HasImpls::SpaceBefore(self, spaces)
|
||||
}
|
||||
fn after(&'a self, spaces: &'a [CommentOrNewline<'a>]) -> Self {
|
||||
HasImpls::SpaceAfter(self, spaces)
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a> Spaceable<'a> for HasAbility<'a> {
|
||||
fn before(&'a self, spaces: &'a [CommentOrNewline<'a>]) -> Self {
|
||||
HasAbility::SpaceBefore(self, spaces)
|
||||
@ -1089,6 +1108,7 @@ impl_extract_spaces!(Tag);
|
||||
impl_extract_spaces!(AssignedField<T>);
|
||||
impl_extract_spaces!(TypeAnnotation);
|
||||
impl_extract_spaces!(HasAbility);
|
||||
impl_extract_spaces!(HasImpls);
|
||||
|
||||
impl<'a, T: Copy> ExtractSpaces<'a> for Spaced<'a, T> {
|
||||
type Item = T;
|
||||
|
@ -103,6 +103,7 @@ impl_space_problem! {
|
||||
ETypeRecord<'a>,
|
||||
ETypeTagUnion<'a>,
|
||||
ETypedIdent<'a>,
|
||||
ETypeAbilityImpl<'a>,
|
||||
EWhen<'a>,
|
||||
EAbility<'a>,
|
||||
PInParens<'a>,
|
||||
@ -578,6 +579,7 @@ pub enum EType<'a> {
|
||||
TFunctionArgument(Position),
|
||||
TWhereBar(Position),
|
||||
THasClause(Position),
|
||||
TAbilityImpl(ETypeAbilityImpl<'a>, Position),
|
||||
///
|
||||
TIndentStart(Position),
|
||||
TIndentEnd(Position),
|
||||
@ -648,6 +650,42 @@ pub enum ETypeInlineAlias {
|
||||
ArgumentNotLowercase(Position),
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, PartialEq, Eq)]
|
||||
pub enum ETypeAbilityImpl<'a> {
|
||||
End(Position),
|
||||
Open(Position),
|
||||
|
||||
Field(Position),
|
||||
Colon(Position),
|
||||
Optional(Position),
|
||||
Type(&'a EType<'a>, Position),
|
||||
|
||||
Space(BadInputError, Position),
|
||||
|
||||
IndentOpen(Position),
|
||||
IndentColon(Position),
|
||||
IndentOptional(Position),
|
||||
IndentEnd(Position),
|
||||
}
|
||||
|
||||
impl<'a> From<ETypeRecord<'a>> for ETypeAbilityImpl<'a> {
|
||||
fn from(e: ETypeRecord<'a>) -> Self {
|
||||
match e {
|
||||
ETypeRecord::End(p) => ETypeAbilityImpl::End(p),
|
||||
ETypeRecord::Open(p) => ETypeAbilityImpl::Open(p),
|
||||
ETypeRecord::Field(p) => ETypeAbilityImpl::Field(p),
|
||||
ETypeRecord::Colon(p) => ETypeAbilityImpl::Colon(p),
|
||||
ETypeRecord::Optional(p) => ETypeAbilityImpl::Optional(p),
|
||||
ETypeRecord::Type(t, p) => ETypeAbilityImpl::Type(t, p),
|
||||
ETypeRecord::Space(s, p) => ETypeAbilityImpl::Space(s, p),
|
||||
ETypeRecord::IndentOpen(p) => ETypeAbilityImpl::IndentOpen(p),
|
||||
ETypeRecord::IndentColon(p) => ETypeAbilityImpl::IndentColon(p),
|
||||
ETypeRecord::IndentOptional(p) => ETypeAbilityImpl::IndentOptional(p),
|
||||
ETypeRecord::IndentEnd(p) => ETypeAbilityImpl::IndentEnd(p),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct SourceError<'a, T> {
|
||||
pub problem: T,
|
||||
|
@ -1,16 +1,16 @@
|
||||
use crate::ast::{
|
||||
AssignedField, CommentOrNewline, HasAbilities, HasAbility, HasClause, Pattern, Spaced, Tag,
|
||||
TypeAnnotation, TypeHeader,
|
||||
AssignedField, CommentOrNewline, HasAbilities, HasAbility, HasClause, HasImpls, Pattern,
|
||||
Spaced, Tag, TypeAnnotation, TypeHeader,
|
||||
};
|
||||
use crate::blankspace::{space0_around_ee, space0_before_e, space0_e};
|
||||
use crate::ident::lowercase_ident;
|
||||
use crate::keyword;
|
||||
use crate::parser::then;
|
||||
use crate::parser::{
|
||||
allocated, backtrackable, optional, specialize, specialize_ref, word1, word2, word3, EType,
|
||||
ETypeApply, ETypeInParens, ETypeInlineAlias, ETypeRecord, ETypeTagUnion, ParseResult, Parser,
|
||||
Progress::{self, *},
|
||||
};
|
||||
use crate::parser::{then, ETypeAbilityImpl};
|
||||
use crate::state::State;
|
||||
use bumpalo::collections::vec::Vec;
|
||||
use bumpalo::Bump;
|
||||
@ -504,14 +504,37 @@ pub fn has_abilities<'a>(min_indent: u32) -> impl Parser<'a, Loc<HasAbilities<'a
|
||||
)
|
||||
}
|
||||
|
||||
fn parse_has_ability<'a>(_min_indent: u32) -> impl Parser<'a, HasAbility<'a>, EType<'a>> {
|
||||
fn parse_has_ability<'a>(min_indent: u32) -> impl Parser<'a, HasAbility<'a>, EType<'a>> {
|
||||
map!(
|
||||
loc!(specialize(EType::TApply, parse_concrete_type)),
|
||||
|ability| {
|
||||
HasAbility::HasAbility {
|
||||
ability,
|
||||
impls: Default::default(),
|
||||
}
|
||||
and!(
|
||||
loc!(specialize(EType::TApply, parse_concrete_type)),
|
||||
optional(space0_before_e(
|
||||
loc!(map!(
|
||||
specialize(
|
||||
EType::TAbilityImpl,
|
||||
collection_trailing_sep_e!(
|
||||
word1(b'{', ETypeAbilityImpl::Open),
|
||||
specialize(
|
||||
|e: ETypeRecord<'_>, _| e.into(),
|
||||
loc!(record_type_field(min_indent + 1))
|
||||
),
|
||||
word1(b',', ETypeAbilityImpl::End),
|
||||
word1(b'}', ETypeAbilityImpl::End),
|
||||
min_indent,
|
||||
ETypeAbilityImpl::Open,
|
||||
ETypeAbilityImpl::IndentEnd,
|
||||
AssignedField::SpaceBefore
|
||||
)
|
||||
),
|
||||
HasImpls::HasImpls
|
||||
)),
|
||||
min_indent + 1,
|
||||
EType::TIndentEnd
|
||||
))
|
||||
),
|
||||
|(ability, impls): (_, Option<_>)| {
|
||||
dbg!(1, &ability, &impls);
|
||||
HasAbility::HasAbility { ability, impls }
|
||||
}
|
||||
)
|
||||
}
|
||||
|
@ -5,4 +5,17 @@ A := a | a has Other has [Eq, Hash]
|
||||
A := a | a has Other
|
||||
has [Eq, Hash]
|
||||
|
||||
A := U8 has [Eq {eq}, Hash {hash}]
|
||||
|
||||
A := U8 has [Eq {eq, eq1}]
|
||||
|
||||
A := U8 has [Eq {eq, eq1}, Hash]
|
||||
|
||||
A := U8 has [Hash, Eq {eq, eq1}]
|
||||
|
||||
A := U8 has []
|
||||
|
||||
A := a | a has Other
|
||||
has [Eq {eq}, Hash {hash}]
|
||||
|
||||
0
|
||||
|
Loading…
Reference in New Issue
Block a user