use super::super::super::HighLevelEmitter;
impl HighLevelEmitter {
pub(in super::super::super) fn inline_condition_temps(statements: &mut [String]) {
let mut index = 0;
while index < statements.len() {
if let Some(condition) = Self::extract_while_condition(&statements[index]) {
if let Some((idx, inlined)) =
Self::condition_inline_candidate(statements, index, &condition)
{
statements[index] = format!("while {inlined} {{");
statements[idx].clear();
}
} else if let Some((init, condition, increment)) =
Self::parse_for_parts(&statements[index])
{
if let Some((idx, inlined)) =
Self::condition_inline_candidate(statements, index, &condition)
{
statements[index] = format!("for ({init}; {inlined}; {increment}) {{");
statements[idx].clear();
}
} else if let Some(condition) = Self::extract_if_condition(&statements[index]) {
if let Some((idx, inlined)) =
Self::condition_inline_candidate(statements, index, &condition)
{
statements[index] = format!("if {inlined} {{");
statements[idx].clear();
}
}
index += 1;
}
}
fn condition_inline_candidate(
statements: &[String],
index: usize,
condition: &str,
) -> Option<(usize, String)> {
let idx = Self::previous_code_line(statements, index)?;
let assign = Self::parse_assignment(&statements[idx])?;
if !Self::should_inline_condition(&assign.rhs) {
return None;
}
if assign.lhs == condition {
Some((idx, assign.rhs))
} else if condition.strip_prefix('!').map(str::trim) == Some(assign.lhs.as_str()) {
Some((idx, format!("!({})", assign.rhs)))
} else {
None
}
}
}
#[cfg(test)]
mod tests {
use super::super::super::super::HighLevelEmitter;
#[test]
fn inlines_negated_loop_condition_temp() {
let mut statements = vec![
"let t2 = loc0 > 3;".to_string(),
"while !t2 {".to_string(),
"}".to_string(),
];
HighLevelEmitter::inline_condition_temps(&mut statements);
assert_eq!(statements[0], "", "the materialised temp must be removed");
assert_eq!(statements[1], "while !(loc0 > 3) {");
}
#[test]
fn inlines_negated_for_condition_temp() {
let mut statements = vec![
"let t2 = loc0 > 3;".to_string(),
"for (let loc0 = 0; !t2; loc0 += 1) {".to_string(),
"}".to_string(),
];
HighLevelEmitter::inline_condition_temps(&mut statements);
assert_eq!(statements[0], "");
assert_eq!(
statements[1],
"for (let loc0 = 0; !(loc0 > 3); loc0 += 1) {"
);
}
#[test]
fn still_inlines_bare_condition_temp() {
let mut statements = vec![
"let t2 = loc0 > 3;".to_string(),
"while t2 {".to_string(),
"}".to_string(),
];
HighLevelEmitter::inline_condition_temps(&mut statements);
assert_eq!(statements[0], "");
assert_eq!(statements[1], "while loc0 > 3 {");
}
}