From 8037bc66cf394bc711da52259b816dfd052627b6 Mon Sep 17 00:00:00 2001 From: SabrinaJewson Date: Thu, 30 Mar 2023 19:24:34 +0100 Subject: [PATCH 1/3] Replace `next!` with a `next_item` function --- src/expand.rs | 30 ++++++++++++++---------------- 1 file changed, 14 insertions(+), 16 deletions(-) diff --git a/src/expand.rs b/src/expand.rs index 4af74f1..42fe748 100644 --- a/src/expand.rs +++ b/src/expand.rs @@ -189,21 +189,8 @@ impl Expand for [u8] { *dest = source.clone(); } - macro_rules! next { - () => { - match parse(input) { - Ok((rest, item)) => { - input = rest; - item - } - - Err(_) => return Err(error::Expand::Invalid.into()), - } - }; - } - 'main: while !input.is_empty() { - match next!() { + match next_item(&mut input)? { Item::Conditional(Conditional::If) => { conditional = true; } @@ -217,7 +204,7 @@ impl Expand for [u8] { let mut level = 0; while !input.is_empty() { - match next!() { + match next_item(&mut input)? { Item::Conditional(Conditional::End) | Item::Conditional(Conditional::Else) if level == 0 => @@ -245,7 +232,7 @@ impl Expand for [u8] { let mut level = 0; while !input.is_empty() { - match next!() { + match next_item(&mut input)? { Item::Conditional(Conditional::End) if level == 0 => continue 'main, Item::Conditional(Conditional::If) => level += 1, @@ -534,6 +521,17 @@ impl Expand for [u8] { } } +fn next_item<'input>(input: &mut &'input [u8]) -> error::Result> { + Ok(match parse(input) { + Ok((rest, item)) => { + *input = rest; + item + } + + Err(_) => return Err(error::Expand::Invalid.into()), + }) +} + #[cfg(test)] mod test { #[test] From 92da16780b86dd1ca77d7d7c0d74c22697eec8e2 Mon Sep 17 00:00:00 2001 From: SabrinaJewson Date: Thu, 30 Mar 2023 19:29:51 +0100 Subject: [PATCH 2/3] Remove use of loop labels --- src/expand.rs | 29 ++++++++++++----------------- 1 file changed, 12 insertions(+), 17 deletions(-) diff --git a/src/expand.rs b/src/expand.rs index 42fe748..1f191a3 100644 --- a/src/expand.rs +++ b/src/expand.rs @@ -189,7 +189,7 @@ impl Expand for [u8] { *dest = source.clone(); } - 'main: while !input.is_empty() { + while !input.is_empty() { match next_item(&mut input)? { Item::Conditional(Conditional::If) => { conditional = true; @@ -203,24 +203,21 @@ impl Expand for [u8] { Some(Parameter::Number(0)) => { let mut level = 0; - while !input.is_empty() { + loop { + if input.is_empty() { + return Err(error::Expand::Invalid.into()); + } match next_item(&mut input)? { - Item::Conditional(Conditional::End) - | Item::Conditional(Conditional::Else) + Item::Conditional(Conditional::End | Conditional::Else) if level == 0 => { - continue 'main + break } - Item::Conditional(Conditional::If) => level += 1, - Item::Conditional(Conditional::End) => level -= 1, - _ => (), } } - - return Err(error::Expand::Invalid.into()); } Some(_) => (), @@ -231,19 +228,17 @@ impl Expand for [u8] { Item::Conditional(Conditional::Else) if conditional => { let mut level = 0; - while !input.is_empty() { + loop { + if input.is_empty() { + return Err(error::Expand::Invalid.into()); + } match next_item(&mut input)? { - Item::Conditional(Conditional::End) if level == 0 => continue 'main, - + Item::Conditional(Conditional::End) if level == 0 => break, Item::Conditional(Conditional::If) => level += 1, - Item::Conditional(Conditional::End) => level -= 1, - _ => (), } } - - return Err(error::Expand::Invalid.into()); } Item::Conditional(..) => return Err(error::Expand::Invalid.into()), From 6145512a25393fe2c334336557e5d8d4240230e5 Mon Sep 17 00:00:00 2001 From: SabrinaJewson Date: Thu, 30 Mar 2023 19:33:09 +0100 Subject: [PATCH 3/3] Extract binary and unary evaluation to a function --- src/expand.rs | 78 +++++++++++++++++++++++++++++---------------------- 1 file changed, 44 insertions(+), 34 deletions(-) diff --git a/src/expand.rs b/src/expand.rs index 1f191a3..d07e82e 100644 --- a/src/expand.rs +++ b/src/expand.rs @@ -307,36 +307,7 @@ impl Expand for [u8] { Item::Operation(Operation::Binary(operation)) => match (stack.pop(), stack.pop()) { (Some(Parameter::Number(y)), Some(Parameter::Number(x))) => { - stack.push(Parameter::Number(match operation { - Binary::Add => x + y, - Binary::Subtract => x - y, - Binary::Multiply => x * y, - Binary::Divide => { - if y != 0 { - x / y - } else { - 0 - } - } - Binary::Remainder => { - if y != 0 { - x % y - } else { - 0 - } - } - - Binary::AND => x & y, - Binary::OR => x | y, - Binary::XOR => x ^ y, - - Binary::And => (x != 0 && y != 0) as i32, - Binary::Or => (x != 0 || y != 0) as i32, - - Binary::Equal => (x == y) as i32, - Binary::Greater => (x > y) as i32, - Binary::Lesser => (x < y) as i32, - })) + stack.push(Parameter::Number(eval_binary(operation, x, y))) } (Some(_), Some(_)) => return Err(error::Expand::TypeMismatch.into()), @@ -345,10 +316,9 @@ impl Expand for [u8] { }, Item::Operation(Operation::Unary(operation)) => match stack.pop() { - Some(Parameter::Number(x)) => stack.push(Parameter::Number(match operation { - Unary::Not => (x != 0) as i32, - Unary::NOT => !x, - })), + Some(Parameter::Number(x)) => { + stack.push(Parameter::Number(eval_unary(operation, x))) + } Some(_) => return Err(error::Expand::TypeMismatch.into()), @@ -527,6 +497,46 @@ fn next_item<'input>(input: &mut &'input [u8]) -> error::Result> { }) } +fn eval_binary(operation: Binary, x: i32, y: i32) -> i32 { + match operation { + Binary::Add => x + y, + Binary::Subtract => x - y, + Binary::Multiply => x * y, + Binary::Divide => { + if y != 0 { + x / y + } else { + 0 + } + } + Binary::Remainder => { + if y != 0 { + x % y + } else { + 0 + } + } + + Binary::AND => x & y, + Binary::OR => x | y, + Binary::XOR => x ^ y, + + Binary::And => (x != 0 && y != 0) as i32, + Binary::Or => (x != 0 || y != 0) as i32, + + Binary::Equal => (x == y) as i32, + Binary::Greater => (x > y) as i32, + Binary::Lesser => (x < y) as i32, + } +} + +fn eval_unary(operation: Unary, x: i32) -> i32 { + match operation { + Unary::Not => (x != 0) as i32, + Unary::NOT => !x, + } +} + #[cfg(test)] mod test { #[test]