vyre-conform 0.1.0

Conformance suite for vyre backends — proves byte-identical output to CPU reference
Documentation
use crate::spec::{EngineInvariant, EngineSpec};

#[cfg(test)]
pub(crate) mod tests {
    use super::{build_eval_input, build_program_bytecode, cpu_fn, spec};
    use crate::spec::EngineInvariant;

    #[test]
    fn spec_has_correct_invariants() {
        let s = spec();
        assert_eq!(s.id, "engine.eval");
        assert!(s.invariants.contains(&EngineInvariant::Deterministic));
        assert!(s.invariants.contains(&EngineInvariant::BoundedResources));
    }

    #[test]
    fn cpu_fn_is_deterministic() {
        let prog = build_program_bytecode(&[
            (1, 0),  // PushTrue
            (30, 0), // Halt
        ]);
        let plan = super::types::ConformEvaluationPlan {
            program_signal_counts: &[0],
            signal_to_programs: &[[0, 0]],
            program_list: &[],
            signal_local_ids: &[],
            sentinel_signal_ids: &[],
            file_boundaries: &[],
            max_cached_positions: 1,
            max_fired: 1024,
        };
        let input = build_eval_input(
            &[prog],
            &plan,
            &[],
            &super::types::ConformFileContext::default(),
            b"",
        );
        let out1 = cpu_fn(&input);
        let out2 = cpu_fn(&input);
        assert_eq!(out1, out2);
        assert_eq!(out1, vec![1]);
    }

    #[test]
    fn cpu_fn_evaluates_string_match() {
        // Program 0: PushStringMatched(0) -> Halt
        let prog = build_program_bytecode(&[
            (3, 0),  // PushStringMatched(signal 0)
            (30, 0), // Halt
        ]);
        let plan = super::types::ConformEvaluationPlan {
            program_signal_counts: &[1],
            signal_to_programs: &[[0, 1]],
            program_list: &[0],
            signal_local_ids: &[0],
            sentinel_signal_ids: &[],
            file_boundaries: &[],
            max_cached_positions: 1,
            max_fired: 1024,
        };
        let matches = vec![super::types::ConformMatchEvent {
            signal_id: 0,
            start: 5,
            end: 7,
        }];
        let input = build_eval_input(
            &[prog],
            &plan,
            &matches,
            &super::types::ConformFileContext::default(),
            b"",
        );
        let out = cpu_fn(&input);
        assert_eq!(out, vec![1]);
    }

    #[test]
    fn cpu_fn_bounded_resources_no_stack_overflow() {
        // Build a 32-deep stack: PushTrue 33 times, then And 32 times.
        let mut insts = Vec::new();
        for _ in 0..33 {
            insts.push((1, 0)); // PushTrue
        }
        for _ in 0..32 {
            insts.push((11, 0)); // And
        }
        insts.push((30, 0)); // Halt
        let prog = build_program_bytecode(&insts);
        let plan = super::types::ConformEvaluationPlan {
            program_signal_counts: &[0],
            signal_to_programs: &[[0, 0]],
            program_list: &[],
            signal_local_ids: &[],
            sentinel_signal_ids: &[],
            file_boundaries: &[],
            max_cached_positions: 1,
            max_fired: 1024,
        };
        let input = build_eval_input(
            &[prog],
            &plan,
            &[],
            &super::types::ConformFileContext::default(),
            b"",
        );
        let out = cpu_fn(&input);
        assert_eq!(out, vec![1]);
    }

    #[inline]
    pub(crate) fn build_eval_input_for_invariants() -> Vec<u8> {
        // Simple program: PushTrue -> Halt
        let prog = build_program_bytecode(&[
            (1, 0),  // PushTrue
            (30, 0), // Halt
        ]);
        let plan = super::types::ConformEvaluationPlan {
            program_signal_counts: &[0],
            signal_to_programs: &[[0, 0]],
            program_list: &[],
            signal_local_ids: &[],
            sentinel_signal_ids: &[],
            file_boundaries: &[],
            max_cached_positions: 1,
            max_fired: 1024,
        };
        build_eval_input(
            &[prog],
            &plan,
            &[],
            &super::types::ConformFileContext::default(),
            b"",
        )
    }
}