mirror of
https://github.com/roc-lang/roc.git
synced 2025-09-28 22:34:45 +00:00
cleanup
This commit is contained in:
parent
91271d0308
commit
4b8f5fb477
1 changed files with 51 additions and 44 deletions
|
@ -2,13 +2,10 @@ use crate::ast::{CommentOrNewline, Spaceable, StrLiteral, TypeAnnotation};
|
|||
use crate::blankspace::space0;
|
||||
use crate::ident::lowercase_ident;
|
||||
use crate::parser::{
|
||||
ascii_char, optional, peek_utf8_char, specialize, unexpected_eof, Either, ParseResult, Parser,
|
||||
Progress, Progress::*, State, SyntaxError,
|
||||
ascii_char, optional, specialize, Either, Parser, Progress, Progress::*, State, SyntaxError,
|
||||
};
|
||||
use crate::string_literal;
|
||||
use bumpalo::collections::String;
|
||||
use bumpalo::collections::Vec;
|
||||
use bumpalo::Bump;
|
||||
use inlinable_string::InlinableString;
|
||||
use roc_region::all::Loc;
|
||||
|
||||
|
@ -274,24 +271,22 @@ pub fn package_entry<'a>() -> impl Parser<'a, PackageEntry<'a>, SyntaxError<'a>>
|
|||
}
|
||||
|
||||
pub fn package_or_path<'a>() -> impl Parser<'a, PackageOrPath<'a>, SyntaxError<'a>> {
|
||||
map!(
|
||||
either!(
|
||||
one_of![
|
||||
map!(
|
||||
specialize(
|
||||
|e, r, c| SyntaxError::Expr(crate::parser::EExpr::Str(e, r, c)),
|
||||
string_literal::parse()
|
||||
),
|
||||
PackageOrPath::Path
|
||||
),
|
||||
map!(
|
||||
and!(
|
||||
package_name(),
|
||||
skip_first!(one_or_more!(ascii_char(b' ')), package_version())
|
||||
)
|
||||
),
|
||||
|answer| {
|
||||
match answer {
|
||||
Either::First(str_literal) => PackageOrPath::Path(str_literal),
|
||||
Either::Second((name, version)) => PackageOrPath::Package(name, version),
|
||||
}
|
||||
}
|
||||
)
|
||||
),
|
||||
|(name, version)| { PackageOrPath::Package(name, version) }
|
||||
)
|
||||
]
|
||||
}
|
||||
|
||||
fn package_version<'a>() -> impl Parser<'a, Version<'a>, SyntaxError<'a>> {
|
||||
|
@ -300,45 +295,57 @@ fn package_version<'a>() -> impl Parser<'a, Version<'a>, SyntaxError<'a>> {
|
|||
|
||||
#[inline(always)]
|
||||
pub fn package_name<'a>() -> impl Parser<'a, PackageName<'a>, SyntaxError<'a>> {
|
||||
use encode_unicode::CharExt;
|
||||
// e.g. rtfeldman/blah
|
||||
//
|
||||
// Package names and accounts can be capitalized and can contain dashes.
|
||||
// They cannot contain underscores or other special characters.
|
||||
// They must be ASCII.
|
||||
|
||||
map!(
|
||||
and!(
|
||||
parse_package_part,
|
||||
skip_first!(ascii_char(b'/'), parse_package_part)
|
||||
),
|
||||
|(account, pkg)| { PackageName { account, pkg } }
|
||||
)
|
||||
}
|
||||
|_, mut state: State<'a>| match chomp_package_part(state.bytes) {
|
||||
Err(progress) => Err((progress, SyntaxError::ConditionFailed, state)),
|
||||
Ok(account) => {
|
||||
let mut chomped = account.len();
|
||||
if let Ok(('/', width)) = char::from_utf8_slice_start(&state.bytes[chomped..]) {
|
||||
chomped += width;
|
||||
match chomp_package_part(&state.bytes[chomped..]) {
|
||||
Err(progress) => Err((progress, SyntaxError::ConditionFailed, state)),
|
||||
Ok(pkg) => {
|
||||
chomped += pkg.len();
|
||||
|
||||
fn parse_package_part<'a>(
|
||||
arena: &'a Bump,
|
||||
mut state: State<'a>,
|
||||
) -> ParseResult<'a, &'a str, SyntaxError<'a>> {
|
||||
let mut part_buf = String::new_in(arena); // The current "part" (parts are dot-separated.)
|
||||
state.column += chomped as u16;
|
||||
state.bytes = &state.bytes[chomped..];
|
||||
|
||||
while !state.bytes.is_empty() {
|
||||
match peek_utf8_char(&state) {
|
||||
Ok((ch, bytes_parsed)) => {
|
||||
if ch == '-' || ch.is_ascii_alphanumeric() {
|
||||
part_buf.push(ch);
|
||||
|
||||
state = state.advance_without_indenting(bytes_parsed)?;
|
||||
} else {
|
||||
let progress = Progress::progress_when(!part_buf.is_empty());
|
||||
return Ok((progress, part_buf.into_bump_str(), state));
|
||||
let value = PackageName { account, pkg };
|
||||
Ok((MadeProgress, value, state))
|
||||
}
|
||||
}
|
||||
}
|
||||
Err(reason) => {
|
||||
let progress = Progress::progress_when(!part_buf.is_empty());
|
||||
return state.fail(arena, progress, reason);
|
||||
} else {
|
||||
Err((MadeProgress, SyntaxError::ConditionFailed, state))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Err(unexpected_eof(arena, state, 0))
|
||||
}
|
||||
|
||||
fn chomp_package_part<'a>(buffer: &'a [u8]) -> Result<&'a str, Progress> {
|
||||
use encode_unicode::CharExt;
|
||||
|
||||
let mut chomped = 0;
|
||||
|
||||
while let Ok((ch, width)) = char::from_utf8_slice_start(&buffer[chomped..]) {
|
||||
if ch == '-' || ch.is_ascii_alphanumeric() {
|
||||
chomped += width;
|
||||
} else {
|
||||
// we're done
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if chomped == 0 {
|
||||
Err(Progress::NoProgress)
|
||||
} else {
|
||||
let name = unsafe { std::str::from_utf8_unchecked(&buffer[..chomped]) };
|
||||
|
||||
Ok(name)
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue