This commit is contained in:
Richard Feldman 2020-07-26 23:42:47 -04:00
parent 13c589af7d
commit 153308dbf1
5 changed files with 24 additions and 31 deletions

View file

@ -1539,11 +1539,11 @@ pub fn ident_without_apply<'a>() -> impl Parser<'a, Expr<'a>> {
pub fn equals_with_indent<'a>() -> impl Parser<'a, u16> {
move |_arena, state: State<'a>| {
match state.bytes.first() {
Some(&byte) if byte == '=' as u8 => {
Some(&byte) if byte == b'=' => {
match state.bytes.get(1) {
// The '=' must not be followed by another `=` or `>`
// (See equals_for_def() for explanation)
Some(&next_byte) if next_byte != '=' as u8 && next_byte != '>' as u8 => {
Some(&next_byte) if next_byte != b'=' && next_byte != b'>' => {
Ok((state.indent_col, state.advance_without_indenting(1)?))
}
Some(_) => Err(unexpected(0, state, Attempting::Def)),
@ -1562,9 +1562,7 @@ pub fn equals_with_indent<'a>() -> impl Parser<'a, u16> {
pub fn colon_with_indent<'a>() -> impl Parser<'a, u16> {
move |_arena, state: State<'a>| match state.bytes.first() {
Some(&byte) if byte == ':' as u8 => {
Ok((state.indent_col, state.advance_without_indenting(1)?))
}
Some(&byte) if byte == b':' => Ok((state.indent_col, state.advance_without_indenting(1)?)),
Some(_) => Err(unexpected(0, state, Attempting::Def)),
None => Err(unexpected_eof(0, Attempting::Def, state)),
}

View file

@ -69,7 +69,7 @@ pub fn module_name<'a>() -> impl Parser<'a, ModuleName<'a>> {
return Err(unexpected(0, state, Attempting::Module));
};
let mut buf = String::with_capacity_in(1, arena);
let mut buf = String::with_capacity_in(4, arena);
buf.push(first_letter);
@ -84,9 +84,9 @@ pub fn module_name<'a>() -> impl Parser<'a, ModuleName<'a>> {
// * ASCII digits - e.g. `1` but not `¾`, both of which pass .is_numeric()
// * A '.' separating module parts
if ch.is_alphabetic() || ch.is_ascii_digit() {
buf.push(ch);
state = state.advance_without_indenting(bytes_parsed)?;
buf.push(ch);
} else if ch == '.' {
match peek_utf8_char_at(&state, 1) {
Ok((next, next_bytes_parsed)) => {

View file

@ -10,7 +10,7 @@ pub fn number_literal<'a>() -> impl Parser<'a, Expr<'a>> {
match bytes.next() {
Some(&first_byte) => {
// Number literals must start with either an '-' or a digit.
if first_byte == '-' as u8 || (first_byte as char).is_ascii_digit() {
if first_byte == b'-' || (first_byte as char).is_ascii_digit() {
parse_number_literal(first_byte as char, bytes, state)
} else {
Err(unexpected(1, state, Attempting::NumberLiteral))
@ -50,7 +50,7 @@ where
let is_potentially_non_base10 = || {
(bytes_parsed == 1 && first_ch == '0')
|| (bytes_parsed == 2 && first_ch == '-' && prev_byte == '0' as u8)
|| (bytes_parsed == 2 && first_ch == '-' && prev_byte == b'0')
};
match next_byte as char {
@ -146,12 +146,12 @@ enum LiteralType {
Binary,
}
fn from_base<'a>(
fn from_base(
base: Base,
first_ch: char,
bytes_parsed: usize,
state: State<'a>,
) -> ParseResult<'a, Expr<'a>> {
state: State<'_>,
) -> ParseResult<'_, Expr<'_>> {
let is_negative = first_ch == '-';
let bytes = if is_negative {
&state.bytes[3..bytes_parsed]

View file

@ -5,7 +5,7 @@ use encode_unicode::CharExt;
use roc_region::all::{Located, Region};
use std::fmt;
use std::str::from_utf8;
use std::{char, mem, u16};
use std::{char, u16};
/// A position in a source file.
#[derive(Clone, PartialEq, Eq)]
@ -451,10 +451,8 @@ pub fn utf8_char2<'a>() -> impl Parser<'a, char> {
move |_arena, state: State<'a>| {
if !state.bytes.is_empty() {
match char::from_utf8_slice_start(state.bytes) {
Ok((ch, bytes_parsed)) => {
return Ok((ch, state.advance_without_indenting(bytes_parsed)?))
}
Err(_) => return state.fail(FailReason::BadUtf8),
Ok((ch, bytes_parsed)) => Ok((ch, state.advance_without_indenting(bytes_parsed)?)),
Err(_) => state.fail(FailReason::BadUtf8),
}
} else {
Err(unexpected_eof(0, state.attempting, state))
@ -511,11 +509,8 @@ pub fn ascii_string<'a>(keyword: &'static str) -> impl Parser<'a, ()> {
// TODO do this comparison in one SIMD instruction (on supported systems)
match state.bytes.get(0..len) {
// SAFETY: Roc language keywords are statically known to contain only
// ASCII characters, which means their &str will be 100% u8 values in
// memory, and thus can be safely interpreted as &[u8]
Some(next_str) => {
if next_str == unsafe { mem::transmute::<&'static str, &'a [u8]>(keyword) } {
if next_str == keyword.as_bytes() {
Ok(((), state.advance_without_indenting(len)?))
} else {
Err(unexpected(len, state, Attempting::Keyword))
@ -1167,7 +1162,7 @@ where
attempt!(attempting, parser)
}
pub fn parse_utf8<'a>(bytes: &'a [u8]) -> Result<&'a str, FailReason> {
pub fn parse_utf8(bytes: &[u8]) -> Result<&str, FailReason> {
match from_utf8(bytes) {
Ok(string) => Ok(string),
Err(_) => Err(FailReason::BadUtf8),

View file

@ -16,7 +16,7 @@ pub fn parse<'a>() -> impl Parser<'a, StringLiteral<'a>> {
// If this doesn't, it must not be a string literal!
match bytes.next() {
Some(&byte) => {
if byte != '"' as u8 {
if byte != b'"' {
return Err(unexpected(0, state, Attempting::StringLiteral));
}
}
@ -35,16 +35,16 @@ pub fn parse<'a>() -> impl Parser<'a, StringLiteral<'a>> {
// Since we're keeping the entire raw string, all we need to track is
// how many characters we've parsed. So far, that's 1 (the opening `"`).
let mut parsed_chars = 1;
let mut prev_byte = '"' as u8;
let mut prev_byte = b'"';
while let Some(&byte) = bytes.next() {
parsed_chars += 1;
// Potentially end the string (unless this is an escaped `"`!)
if byte == '"' as u8 && prev_byte != '\\' as u8 {
if byte == b'"' && prev_byte != b'\\' {
let (string, state) = if parsed_chars == 2 {
match bytes.next() {
Some(byte) if *byte == '"' as u8 => {
Some(byte) if *byte == b'"' => {
// If the first three chars were all `"`, then this
// literal begins with `"""` and is a block string.
return parse_block_string(arena, state, &mut bytes);
@ -65,7 +65,7 @@ pub fn parse<'a>() -> impl Parser<'a, StringLiteral<'a>> {
};
return Ok((StringLiteral::Line(string), state));
} else if byte == '\n' as u8 {
} else if byte == b'\n' {
// This is a single-line string, which cannot have newlines!
// Treat this as an unclosed string literal, and consume
// all remaining chars. This will mask all other errors, but
@ -100,7 +100,7 @@ where
{
// So far we have consumed the `"""` and that's it.
let mut parsed_chars = 3;
let mut prev_byte = '"' as u8;
let mut prev_byte = b'"';
let mut quotes_seen = 0;
// start at 3 to omit the opening `"`.
@ -112,7 +112,7 @@ where
parsed_chars += 1;
// Potentially end the string (unless this is an escaped `"`!)
if *byte == '"' as u8 && prev_byte != '\\' as u8 {
if *byte == b'"' && prev_byte != b'\\' {
if quotes_seen == 2 {
// three consecutive qoutes, end string
@ -131,7 +131,7 @@ where
};
}
quotes_seen += 1;
} else if *byte == '\n' as u8 {
} else if *byte == b'\n' {
// note this includes the newline
let line_bytes = &state.bytes[line_start..parsed_chars];