mirror of
https://github.com/roc-lang/roc.git
synced 2025-09-28 22:34:45 +00:00
optimize keyword parsing
This commit is contained in:
parent
c2525d2407
commit
5029469825
1 changed files with 18 additions and 22 deletions
|
@ -1128,31 +1128,27 @@ where
|
|||
ToError: Fn(Row, Col) -> E,
|
||||
E: 'a,
|
||||
{
|
||||
move |arena, state: State<'a>| {
|
||||
let initial_state = state.clone();
|
||||
// first parse the keyword characters
|
||||
let (_, _, after_keyword_state) = ascii_string(keyword)
|
||||
.parse(arena, state)
|
||||
.map_err(|(_, _, state)| (NoProgress, if_error(state.line, state.column), state))?;
|
||||
move |_, mut state: State<'a>| {
|
||||
let width = keyword.len();
|
||||
|
||||
// then we must have at least one space character
|
||||
// TODO this is potentially wasteful if there are a lot of spaces
|
||||
match peek_utf8_char(&after_keyword_state) {
|
||||
Ok((next, _width)) if next == ' ' || next == '#' || next == '\n' => {
|
||||
// give back the state after parsing the keyword, but before the whitespace
|
||||
// that way we can attach the whitespace to whatever follows
|
||||
Ok((MadeProgress, (), after_keyword_state))
|
||||
if !state.bytes.starts_with(keyword.as_bytes()) {
|
||||
return Err((NoProgress, if_error(state.line, state.column), state));
|
||||
}
|
||||
|
||||
// the next character should not be an identifier character
|
||||
// to prevent treating `whence` or `iffy` as keywords
|
||||
match state.bytes.get(width) {
|
||||
Some(next) if *next == b' ' || *next == b'#' || *next == b'\n' => {
|
||||
state.column += width as u16;
|
||||
state.bytes = &state.bytes[width..];
|
||||
Ok((MadeProgress, (), state))
|
||||
}
|
||||
_ => {
|
||||
// this is not a keyword, maybe it's `whence` or `iffy`
|
||||
// anyway, make no progress and return the initial state
|
||||
// so we can try something else
|
||||
Err((
|
||||
NoProgress,
|
||||
if_error(initial_state.line, initial_state.column),
|
||||
initial_state,
|
||||
))
|
||||
None => {
|
||||
state.column += width as u16;
|
||||
state.bytes = &state.bytes[width..];
|
||||
Ok((MadeProgress, (), state))
|
||||
}
|
||||
Some(_) => Err((NoProgress, if_error(state.line, state.column), state)),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue