Improve parsing of scalar literals

* Unify parsing of string literals and scalar literals, to (e.g.) ensure escapes are handled uniformly. Notably, this makes unicode escapes valid in scalar literals.
* Add a variety of custom error messages about specific failure cases of parsing string/scalar literals. For example, if we're expecting a string (e.g. a package name in the header) and the user tried using single quotes, give a clear message about that.
* Fix formatting of unicode escapes (they previously used {}, now correctly use () to match roc strings)
This commit is contained in:
Joshua Warner 2023-01-07 14:41:08 -08:00
parent 6fc593142d
commit 94070e8ba6
No known key found for this signature in database
GPG key ID: 89AD497003F93FDD
22 changed files with 411 additions and 173 deletions

View file

@ -431,14 +431,30 @@ impl<'a> Formattable for Expr<'a> {
}
}
fn needs_unicode_escape(ch: char) -> bool {
matches!(ch, '\u{0000}'..='\u{001f}' | '\u{007f}'..='\u{009f}')
}
pub(crate) fn format_sq_literal(buf: &mut Buf, s: &str) {
buf.push('\'');
for c in s.chars() {
if c == '"' {
buf.push_char_literal('"')
} else {
for escaped in c.escape_default() {
buf.push_char_literal(escaped);
match c {
'"' => buf.push_str("\""),
'\'' => buf.push_str("\\\'"),
'\t' => buf.push_str("\\t"),
'\r' => buf.push_str("\\r"),
'\n' => buf.push_str("\\n"),
'\\' => buf.push_str("\\\\"),
_ => {
if needs_unicode_escape(c) {
buf.push_str(&format!("\\u({:x})", c as u32))
} else {
buf.push_char_literal(c)
}
}
}
}
}