mirror of
https://github.com/roc-lang/roc.git
synced 2025-09-26 13:29:12 +00:00
move suffixed parsing into chomp_identifier_chain
This commit is contained in:
parent
d988eadbb1
commit
370ac1e6b8
4 changed files with 43 additions and 17 deletions
|
@ -1829,18 +1829,6 @@ fn parse_expr_end<'a>(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
.map(|(progress, expr, state)| {
|
|
||||||
// If the next thing after the expression is a `!`, then it's Suffixed
|
|
||||||
if state.bytes().starts_with(b"!") {
|
|
||||||
(
|
|
||||||
progress,
|
|
||||||
Expr::Suffixed(arena.alloc(expr)),
|
|
||||||
state.advance(1),
|
|
||||||
)
|
|
||||||
} else {
|
|
||||||
(progress, expr, state)
|
|
||||||
}
|
|
||||||
})
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn loc_expr<'a>(accept_multi_backpassing: bool) -> impl Parser<'a, Loc<Expr<'a>>, EExpr<'a>> {
|
pub fn loc_expr<'a>(accept_multi_backpassing: bool) -> impl Parser<'a, Loc<Expr<'a>>, EExpr<'a>> {
|
||||||
|
@ -2510,12 +2498,19 @@ fn ident_to_expr<'a>(arena: &'a Bump, src: Ident<'a>) -> Expr<'a> {
|
||||||
match src {
|
match src {
|
||||||
Ident::Tag(string) => Expr::Tag(string),
|
Ident::Tag(string) => Expr::Tag(string),
|
||||||
Ident::OpaqueRef(string) => Expr::OpaqueRef(string),
|
Ident::OpaqueRef(string) => Expr::OpaqueRef(string),
|
||||||
Ident::Access { module_name, parts } => {
|
Ident::Access {
|
||||||
|
module_name,
|
||||||
|
parts,
|
||||||
|
suffixed,
|
||||||
|
} => {
|
||||||
let mut iter = parts.iter();
|
let mut iter = parts.iter();
|
||||||
|
|
||||||
// The first value in the iterator is the variable name,
|
// The first value in the iterator is the variable name,
|
||||||
// e.g. `foo` in `foo.bar.baz`
|
// e.g. `foo` in `foo.bar.baz`
|
||||||
let mut answer = match iter.next() {
|
let mut answer = match iter.next() {
|
||||||
|
Some(Accessor::RecordField(ident)) if suffixed => {
|
||||||
|
Expr::Suffixed(arena.alloc(Expr::Var { module_name, ident }))
|
||||||
|
}
|
||||||
Some(Accessor::RecordField(ident)) => Expr::Var { module_name, ident },
|
Some(Accessor::RecordField(ident)) => Expr::Var { module_name, ident },
|
||||||
Some(Accessor::TupleIndex(_)) => {
|
Some(Accessor::TupleIndex(_)) => {
|
||||||
// TODO: make this state impossible to represent in Ident::Access,
|
// TODO: make this state impossible to represent in Ident::Access,
|
||||||
|
|
|
@ -42,6 +42,7 @@ pub enum Ident<'a> {
|
||||||
Access {
|
Access {
|
||||||
module_name: &'a str,
|
module_name: &'a str,
|
||||||
parts: &'a [Accessor<'a>],
|
parts: &'a [Accessor<'a>],
|
||||||
|
suffixed: bool,
|
||||||
},
|
},
|
||||||
/// `.foo { foo: 42 }` or `.1 (1, 2, 3)`
|
/// `.foo { foo: 42 }` or `.1 (1, 2, 3)`
|
||||||
AccessorFunction(Accessor<'a>),
|
AccessorFunction(Accessor<'a>),
|
||||||
|
@ -55,7 +56,9 @@ impl<'a> Ident<'a> {
|
||||||
|
|
||||||
match self {
|
match self {
|
||||||
Tag(string) | OpaqueRef(string) => string.len(),
|
Tag(string) | OpaqueRef(string) => string.len(),
|
||||||
Access { module_name, parts } => {
|
Access {
|
||||||
|
module_name, parts, ..
|
||||||
|
} => {
|
||||||
let mut len = if module_name.is_empty() {
|
let mut len = if module_name.is_empty() {
|
||||||
0
|
0
|
||||||
} else {
|
} else {
|
||||||
|
@ -190,7 +193,10 @@ pub fn parse_ident<'a>(
|
||||||
match chomp_identifier_chain(arena, state.bytes(), state.pos()) {
|
match chomp_identifier_chain(arena, state.bytes(), state.pos()) {
|
||||||
Ok((width, ident)) => {
|
Ok((width, ident)) => {
|
||||||
let state = advance_state!(state, width as usize)?;
|
let state = advance_state!(state, width as usize)?;
|
||||||
if let Ident::Access { module_name, parts } = ident {
|
if let Ident::Access {
|
||||||
|
module_name, parts, ..
|
||||||
|
} = ident
|
||||||
|
{
|
||||||
if module_name.is_empty() {
|
if module_name.is_empty() {
|
||||||
if let Some(first) = parts.first() {
|
if let Some(first) = parts.first() {
|
||||||
for keyword in crate::keyword::KEYWORDS.iter() {
|
for keyword in crate::keyword::KEYWORDS.iter() {
|
||||||
|
@ -202,6 +208,21 @@ pub fn parse_ident<'a>(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Parse a suffixed `!` expression
|
||||||
|
if state.bytes().starts_with(b"!") {
|
||||||
|
if let Ident::Access {
|
||||||
|
module_name, parts, ..
|
||||||
|
} = ident
|
||||||
|
{
|
||||||
|
let new_ident = Ident::Access {
|
||||||
|
module_name,
|
||||||
|
parts,
|
||||||
|
suffixed: true,
|
||||||
|
};
|
||||||
|
return Ok((MadeProgress, new_ident, state.advance(1)));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
Ok((MadeProgress, ident, state))
|
Ok((MadeProgress, ident, state))
|
||||||
}
|
}
|
||||||
Err((0, _)) => Err((NoProgress, EExpr::Start(state.pos()))),
|
Err((0, _)) => Err((NoProgress, EExpr::Start(state.pos()))),
|
||||||
|
@ -513,6 +534,7 @@ fn chomp_identifier_chain<'a>(
|
||||||
let ident = Ident::Access {
|
let ident = Ident::Access {
|
||||||
module_name,
|
module_name,
|
||||||
parts: parts.into_bump_slice(),
|
parts: parts.into_bump_slice(),
|
||||||
|
suffixed: false,
|
||||||
};
|
};
|
||||||
|
|
||||||
Ok((chomped as u32, ident))
|
Ok((chomped as u32, ident))
|
||||||
|
@ -548,6 +570,7 @@ fn chomp_identifier_chain<'a>(
|
||||||
let ident = Ident::Access {
|
let ident = Ident::Access {
|
||||||
module_name: "",
|
module_name: "",
|
||||||
parts: arena.alloc([Accessor::RecordField(value)]),
|
parts: arena.alloc([Accessor::RecordField(value)]),
|
||||||
|
suffixed: false,
|
||||||
};
|
};
|
||||||
Ok((chomped as u32, ident))
|
Ok((chomped as u32, ident))
|
||||||
}
|
}
|
||||||
|
|
|
@ -381,7 +381,9 @@ fn loc_ident_pattern_help<'a>(
|
||||||
Ok((MadeProgress, loc_pat, state))
|
Ok((MadeProgress, loc_pat, state))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Ident::Access { module_name, parts } => {
|
Ident::Access {
|
||||||
|
module_name, parts, ..
|
||||||
|
} => {
|
||||||
// Plain identifiers (e.g. `foo`) are allowed in patterns, but
|
// Plain identifiers (e.g. `foo`) are allowed in patterns, but
|
||||||
// more complex ones (e.g. `Foo.bar` or `foo.bar.baz`) are not.
|
// more complex ones (e.g. `Foo.bar` or `foo.bar.baz`) are not.
|
||||||
|
|
||||||
|
|
|
@ -999,7 +999,13 @@ fn markdown_to_html(
|
||||||
arena.reset();
|
arena.reset();
|
||||||
|
|
||||||
match parse_ident(&arena, state, 0) {
|
match parse_ident(&arena, state, 0) {
|
||||||
Ok((_, Ident::Access { module_name, parts }, _)) => {
|
Ok((
|
||||||
|
_,
|
||||||
|
Ident::Access {
|
||||||
|
module_name, parts, ..
|
||||||
|
},
|
||||||
|
_,
|
||||||
|
)) => {
|
||||||
let mut iter = parts.iter();
|
let mut iter = parts.iter();
|
||||||
|
|
||||||
match iter.next() {
|
match iter.next() {
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue