diff --git a/src/asm/parse.rs b/src/asm/parse.rs index 84736c4..e81c20b 100644 --- a/src/asm/parse.rs +++ b/src/asm/parse.rs @@ -1,7 +1,7 @@ use super::Token; use crate::Register; use logos::{Logos, Source}; -use std::{borrow::Cow, collections::HashMap, iter::Peekable, ops::Range}; +use std::{borrow::Cow, collections::HashMap, iter::Peekable, ops::Range, str::CharIndices}; pub fn parse(_unit: impl std::fmt::Display, source: &str) -> Result { Parser::new(source).parse() @@ -680,7 +680,7 @@ where { match tokens.next() { Some((Token::String(value), span)) => { - let unescaped = crate::str::unescape_str(value).map_err(|_| Error::eof())?; + let unescaped = unescape_str(value).map_err(|_| Error::eof())?; Ok((unescaped, span)) } Some((token, span)) => Err(Error::new( @@ -694,3 +694,46 @@ where fn merge_spans(start: &Range, end: &Range) -> Range { start.start..end.end } + +#[derive(Debug)] +#[allow(unused)] +pub struct InvalidCharacterEscape(pub char, pub usize); + +pub fn unescape_str(s: &str) -> Result, InvalidCharacterEscape> { + fn escape_inner(c: &str, i: &mut CharIndices<'_>) -> Result { + let mut buffer = c.to_owned(); + let mut in_escape = true; + + for (index, c) in i { + match (in_escape, c) { + (false, '\\') => { + in_escape = true; + continue; + } + (false, c) => buffer.push(c), + (true, '\\') => buffer.push('\\'), + (true, 'n') => buffer.push('\n'), + (true, '0') => buffer.push('\0'), + (true, '"') => buffer.push('"'), + (true, '\'') => buffer.push('\''), + (true, 'r') => buffer.push('\r'), + (true, 't') => buffer.push('\t'), + (true, c) => Err(InvalidCharacterEscape(c, index))?, + } + + in_escape = false; + } + + Ok(buffer) + } + + let mut char_indicies = s.char_indices(); + for (index, c) in &mut char_indicies { + let scanned = &s[..index]; + if c == '\\' { + return Ok(Cow::Owned(escape_inner(scanned, &mut char_indicies)?)); + } + } + + Ok(Cow::Borrowed(s)) +} diff --git a/src/lib.rs b/src/lib.rs index 209ae71..68218f7 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -4,7 +4,6 @@ use std::io::{Read, Write}; pub mod asm; pub mod ops; pub mod reg; -pub mod str; use ops::Operation; use reg::Register; diff --git a/src/str.rs b/src/str.rs deleted file mode 100644 index 1026a40..0000000 --- a/src/str.rs +++ /dev/null @@ -1,59 +0,0 @@ -use std::{borrow::Cow, str::CharIndices}; - -#[derive(Debug)] -pub struct InvalidCharacterEscape(pub char, pub usize); - -pub fn unescape_str(s: &str) -> Result, InvalidCharacterEscape> { - fn escape_inner(c: &str, i: &mut CharIndices<'_>) -> Result { - let mut buffer = c.to_owned(); - let mut in_escape = true; - - for (index, c) in i { - match (in_escape, c) { - (false, '\\') => { - in_escape = true; - continue; - } - (false, c) => buffer.push(c), - (true, '\\') => buffer.push('\\'), - (true, 'n') => buffer.push('\n'), - (true, '0') => buffer.push('\0'), - (true, '"') => buffer.push('"'), - (true, '\'') => buffer.push('\''), - (true, 'r') => buffer.push('\r'), - (true, 't') => buffer.push('\t'), - (true, c) => Err(InvalidCharacterEscape(c, index))?, - } - - in_escape = false; - } - - Ok(buffer) - } - - let mut char_indicies = s.char_indices(); - for (index, c) in &mut char_indicies { - let scanned = &s[..index]; - if c == '\\' { - return Ok(Cow::Owned(escape_inner(scanned, &mut char_indicies)?)); - } - } - - Ok(Cow::Borrowed(s)) -} - -#[cfg(test)] -mod tests { - use std::borrow::Cow; - - use super::unescape_str; - - #[test] - fn no_unescapes() { - let s = "Hello, this string should have no characters that need unescaping."; - let u = unescape_str(s).unwrap(); - - assert!(matches!(u, Cow::Borrowed(_))); - assert_eq!(s, u); - } -}