libertyparse 0.3.0

Liberty cell library parser
Documentation
//! Formatting of liberty object.
//! currently only function (LogicExpr) is supported.

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)");
}