rscel 1.0.8

Cel interpreter in rust
Documentation
mod interp;
mod types;

pub use interp::Interpreter;
pub use types::*;

#[cfg(test)]
mod test {
    use crate::{types::CelByteCode, CelValue};

    use super::{
        types::{ByteCode, JmpWhen},
        Interpreter,
    };
    use test_case::test_case;

    #[test_case(ByteCode::Add, 7.into())]
    #[test_case(ByteCode::Sub, 1.into())]
    #[test_case(ByteCode::Mul, 12.into())]
    #[test_case(ByteCode::Div, 1.into())]
    #[test_case(ByteCode::Mod, 1.into())]
    #[test_case(ByteCode::Lt, false.into())]
    #[test_case(ByteCode::Le, false.into())]
    #[test_case(ByteCode::Eq, false.into())]
    #[test_case(ByteCode::Ne, true.into())]
    #[test_case(ByteCode::Ge, true.into())]
    #[test_case(ByteCode::Gt, true.into())]
    fn test_interp_ops(op: ByteCode, expected: CelValue) {
        let mut prog =
            CelByteCode::from_vec(vec![ByteCode::Push(4.into()), ByteCode::Push(3.into())]);
        prog.push(op);
        let interp = Interpreter::empty();

        assert!(interp.run_raw(&prog, true).unwrap() == expected);
    }

    #[test]
    fn test_backward_jump_loop_executes() {
        let prog = CelByteCode::from_vec(vec![
            ByteCode::Push(0.into()),
            ByteCode::Dup,
            ByteCode::Push(2.into()),
            ByteCode::Lt,
            ByteCode::JmpCond {
                when: JmpWhen::False,
                dist: 3,
            },
            ByteCode::Push(1.into()),
            ByteCode::Add,
            ByteCode::Jmp(-7),
        ]);

        let interp = Interpreter::empty();
        let result = interp.run_raw(&prog, true).unwrap();

        assert_eq!(result, 2.into());
    }
}