use super::*;
use std::fmt::{ Display, Formatter, Result };
impl Display for LogicExpr {
#[inline]
fn fmt(&self, f: &mut Formatter) -> Result {
let mut stack = Vec::<String>::new();
for inst in &self.compiled {
use LogicExprInst::*;
match inst {
PushVar(var) => stack.push(var.as_str().into()),
PushConst(b) => stack.push(format!("{}", *b as u8)),
Op(op) => match op {
b'&' | b'|' | b'^' => {
let b = stack.pop().unwrap();
let a = stack.pop().unwrap();
stack.push(format!("({}{}{})", a, *op as char, b))
},
b'!' => {
let a = stack.pop().unwrap();
stack.push(format!("!{}", a))
},
_ => unreachable!()
}
}
}
assert_eq!(stack.len(), 1);
write!(f, "{}", stack.pop().unwrap())
}
}
#[test]
fn test_logicexpr_format() {
use LogicExprInst::*;
assert_eq!(format!("{}", LogicExpr {
compiled: vec![PushVar("a".into()), PushVar("b".into()), Op(b'&')]
}), "(a&b)");
assert_eq!(format!("{}", LogicExpr {
compiled: vec![PushVar("a".into()), Op(b'!'),
PushVar("b".into()), Op(b'&'),
PushVar("c".into()), Op(b'^'),
PushConst(true), Op(b'|')]
}), "(((!a&b)^c)|1)");
}