fix ! bug for Record and Tuple Access

This commit is contained in:
Luke Boswell 2024-04-02 14:17:22 +11:00
parent a28cd251ab
commit 584d41f621
No known key found for this signature in database
GPG key ID: F6DB3C9DB47377B0
2 changed files with 68 additions and 19 deletions

View file

@ -192,9 +192,11 @@ pub fn parse_ident<'a>(
match chomp_identifier_chain(arena, state.bytes(), state.pos()) {
Ok((width, ident)) => {
let mut state = advance_state!(state, width as usize)?;
let state = advance_state!(state, width as usize)?;
if let Ident::Access {
module_name, parts, ..
module_name,
parts,
suffixed,
} = ident
{
if module_name.is_empty() {
@ -207,19 +209,15 @@ pub fn parse_ident<'a>(
}
}
// Parse any `!` suffixes
let mut suffixed = 0u8;
while state.bytes().starts_with(b"!") {
suffixed = suffixed.saturating_add(1);
state = state.advance(1);
}
let new_ident = Ident::Access {
module_name,
parts,
suffixed,
};
return Ok((MadeProgress, new_ident, state));
return Ok((
MadeProgress,
Ident::Access {
module_name,
parts,
suffixed,
},
state,
));
}
Ok((MadeProgress, ident, state))
@ -530,10 +528,22 @@ fn chomp_identifier_chain<'a>(
chomped += width as usize;
// Parse any `!` suffixes
let mut suffixed = 0;
while let Ok((ch, width)) = char::from_utf8_slice_start(&buffer[chomped..]) {
if ch == '!' {
suffixed += 1;
chomped += width;
} else {
// we're done
break;
}
}
let ident = Ident::Access {
module_name,
parts: parts.into_bump_slice(),
suffixed: 0,
suffixed,
};
Ok((chomped as u32, ident))
@ -562,15 +572,30 @@ fn chomp_identifier_chain<'a>(
} else if first_is_uppercase {
// just one segment, starting with an uppercase letter; that's a tag
let value = unsafe { std::str::from_utf8_unchecked(&buffer[..chomped]) };
Ok((chomped as u32, Ident::Tag(value)))
} else {
// just one segment, starting with a lowercase letter; that's a normal identifier
let value = unsafe { std::str::from_utf8_unchecked(&buffer[..chomped]) };
// Parse any `!` suffixes
let mut suffixed = 0;
while let Ok((ch, width)) = char::from_utf8_slice_start(&buffer[chomped..]) {
if ch == '!' {
suffixed += 1;
chomped += width;
} else {
// we're done
break;
}
}
let ident = Ident::Access {
module_name: "",
parts: arena.alloc([Accessor::RecordField(value)]),
suffixed: 0,
suffixed,
};
Ok((chomped as u32, ident))
}
}