diff --git a/Cargo.lock b/Cargo.lock index 242c4e14..22d44e02 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -144,9 +144,9 @@ checksum = "79296716171880943b8470b5f8d03aa55eb2e645a4874bdbb28adb49162e012c" [[package]] name = "capitalize" -version = "0.1.0" +version = "0.3.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "702cfe2f052c6542d55a9924efef63dd315c168cc4f315a824fb0f47da4e11c8" +checksum = "6b5271031022835ee8c7582fe67403bd6cb3d962095787af7921027234bab5bf" [[package]] name = "cc" @@ -299,9 +299,9 @@ checksum = "2304e00983f87ffb38b55b444b5e3b60a884b5d30c0fca7d82fe33449bbe55ea" [[package]] name = "heraclitus-compiler" -version = "1.5.8" +version = "1.6.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1b30d37150dbf5477a91ad1a9546eab07c3f73225dbe61dd9a8bacd7074deb43" +checksum = "3db5a87f8cf478caf29544c97ee49f35fcc88fd5f4fe80fe514ef8ca4f217111" dependencies = [ "capitalize", "colored", diff --git a/Cargo.toml b/Cargo.toml index 8a684d32..3d51449f 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -7,7 +7,7 @@ repository = "https://github.com/Ph0enixKM/Amber" # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html [dependencies] -heraclitus-compiler = "1.5.8" +heraclitus-compiler = "1.6.1" similar-string = "1.4.2" colored = "2.0.0" itertools = "0.11.0" diff --git a/src/modules/expression/literal/mod.rs b/src/modules/expression/literal/mod.rs index 95cca30a..fbb7de9c 100644 --- a/src/modules/expression/literal/mod.rs +++ b/src/modules/expression/literal/mod.rs @@ -15,7 +15,12 @@ pub fn parse_interpolated_region(meta: &mut ParserMetadata, letter: char) -> Res let mut strings = vec![]; let mut interps = vec![]; // Handle full string - if let Ok(word) = token_by(meta, |word| word.starts_with(letter) && (word.ends_with(letter) && !word.ends_with(format!("\\{}", letter).as_str())) && word.len() > 1) { + if let Ok(word) = token_by(meta, |word| { + let is_escaped = + !word.ends_with(format!("\\\\{}", letter).as_str()) + && word.ends_with(format!("\\{}", letter).as_str()); + word.starts_with(letter) && word.ends_with(letter) && word.len() > 1 && !is_escaped + }) { let stripped = word.chars().take(word.chars().count() - 1).skip(1).collect::(); strings.push(stripped); Ok((strings, interps)) @@ -40,7 +45,10 @@ pub fn parse_interpolated_region(meta: &mut ParserMetadata, letter: char) -> Res } else { strings.push(tok.word.clone()); - if tok.word.ends_with(letter) && !tok.word.ends_with(format!("\\{}", letter).as_str()) { + let is_escaped = + !tok.word.ends_with(format!("\\\\{}", letter).as_str()) + && tok.word.ends_with(format!("\\{}", letter).as_str()); + if tok.word.ends_with(letter) && !is_escaped { meta.increment_index(); // Right trim the symbol let trimmed = strings.last().unwrap() @@ -126,6 +134,7 @@ fn translate_escaped_string(string: String, is_str: bool) -> String { chars.next(); }, Some('\\') => { + result.push('\\'); result.push('\\'); chars.next(); }, @@ -170,4 +179,4 @@ pub fn translate_interpolated_region(strings: Vec, interps: Vec, is_even = !is_even; } result.join("") -} \ No newline at end of file +} diff --git a/src/tests/validity.rs b/src/tests/validity.rs index f4e390bb..ce44266f 100644 --- a/src/tests/validity.rs +++ b/src/tests/validity.rs @@ -41,6 +41,16 @@ fn text_escaped() { test_amber!("echo \"Hello \\\"World\\\"\"", "Hello \"World\""); } +#[test] +fn text_unescaped_after() { + test_amber!("echo \"Hello\\\\\"", "Hello\\"); +} + +#[test] +fn text_unescaped_before() { + test_amber!("echo \"Hello\\\\{12}\"", "Hello\\12"); +} + #[test] fn bool() { test_amber!("echo true", "1");