use alloc::vec::Vec;
use miden_core::{
Felt, ONE, ZERO,
program::{MIN_STACK_DEPTH, StackInputs},
};
use super::{dup_nth, op_cswap, op_cswapw, op_pad, op_push, op_swap, op_swap_double_word};
use crate::{
fast::FastProcessor,
processor::{Processor, StackInterface},
};
#[test]
fn test_op_push() {
let mut processor = FastProcessor::new(StackInputs::default());
assert_eq!(MIN_STACK_DEPTH as u32, processor.stack_depth());
let expected = build_expected(&[]);
assert_eq!(expected, processor.stack_top());
op_push(&mut processor, ONE).unwrap();
let expected = build_expected(&[1]);
assert_eq!(MIN_STACK_DEPTH as u32 + 1, processor.stack_depth());
assert_eq!(expected, processor.stack_top());
op_push(&mut processor, Felt::new(3)).unwrap();
let expected = build_expected(&[3, 1]);
assert_eq!(MIN_STACK_DEPTH as u32 + 2, processor.stack_depth());
assert_eq!(expected, processor.stack_top());
}
#[test]
fn test_op_pad() {
let mut processor = FastProcessor::new(StackInputs::default());
op_push(&mut processor, ONE).unwrap();
let expected = build_expected(&[1]);
assert_eq!(expected, processor.stack_top());
op_pad(&mut processor).unwrap();
let expected = build_expected(&[0, 1]);
assert_eq!(MIN_STACK_DEPTH as u32 + 2, processor.stack_depth());
assert_eq!(expected, processor.stack_top());
op_pad(&mut processor).unwrap();
let expected = build_expected(&[0, 0, 1]);
assert_eq!(MIN_STACK_DEPTH as u32 + 3, processor.stack_depth());
assert_eq!(expected, processor.stack_top());
}
#[test]
fn test_op_drop() {
let mut processor = FastProcessor::new(StackInputs::default());
op_push(&mut processor, ONE).unwrap();
op_push(&mut processor, Felt::new(2)).unwrap();
Processor::stack_mut(&mut processor).decrement_size().unwrap();
let expected = build_expected(&[1]);
assert_eq!(expected, processor.stack_top());
assert_eq!(MIN_STACK_DEPTH as u32 + 1, processor.stack_depth());
Processor::stack_mut(&mut processor).decrement_size().unwrap();
let expected = build_expected(&[]);
assert_eq!(expected, processor.stack_top());
assert_eq!(MIN_STACK_DEPTH as u32, processor.stack_depth());
Processor::stack_mut(&mut processor).decrement_size().unwrap();
}
#[test]
fn test_op_dup() {
let mut processor = FastProcessor::new(StackInputs::default());
op_push(&mut processor, ONE).unwrap();
let expected = build_expected(&[1]);
assert_eq!(expected, processor.stack_top());
dup_nth(&mut processor, 0).unwrap();
let expected = build_expected(&[1, 1]);
assert_eq!(expected, processor.stack_top());
dup_nth(&mut processor, 2).unwrap();
Processor::stack_mut(&mut processor).decrement_size().unwrap();
let mut expected_arr = [ONE; 16];
for i in 2..17u64 {
op_push(&mut processor, Felt::new(i)).unwrap();
expected_arr[16 - i as usize] = Felt::new(i);
}
let expected: Vec<Felt> = expected_arr.iter().rev().cloned().collect();
assert_eq!(&expected[..], processor.stack_top());
dup_nth(&mut processor, 15).unwrap();
assert_eq!(ONE, processor.stack_get(0));
for (i, element) in expected_arr.iter().enumerate().take(15) {
assert_eq!(*element, processor.stack_get(i + 1));
}
dup_nth(&mut processor, 7).unwrap();
assert_eq!(Felt::new(10), processor.stack_get(0));
assert_eq!(ONE, processor.stack_get(1));
Processor::stack_mut(&mut processor).decrement_size().unwrap();
Processor::stack_mut(&mut processor).decrement_size().unwrap();
Processor::stack_mut(&mut processor).decrement_size().unwrap();
Processor::stack_mut(&mut processor).decrement_size().unwrap();
assert_eq!(MIN_STACK_DEPTH as u32 + 15, processor.stack_depth());
for i in 0..14 {
assert_eq!(expected_arr[i + 2], processor.stack_get(i));
}
assert_eq!(ONE, processor.stack_get(14));
assert_eq!(ZERO, processor.stack_get(15));
}
#[test]
fn test_op_swap() {
let mut processor =
FastProcessor::new(StackInputs::new(&[Felt::new(3), Felt::new(2), Felt::new(1)]).unwrap());
op_swap(&mut processor);
let expected = build_expected(&[2, 3, 1]);
assert_eq!(expected, processor.stack_top());
let mut processor = FastProcessor::new(StackInputs::default());
op_swap(&mut processor);
}
#[test]
fn test_op_swapw() {
let mut processor = FastProcessor::new(
StackInputs::new(&[
Felt::new(9),
Felt::new(8),
Felt::new(7),
Felt::new(6),
Felt::new(5),
Felt::new(4),
Felt::new(3),
Felt::new(2),
Felt::new(1),
])
.unwrap(),
);
Processor::stack_mut(&mut processor).swapw_nth(1);
let expected = build_expected(&[5, 4, 3, 2, 9, 8, 7, 6, 1]);
assert_eq!(expected, processor.stack_top());
let mut processor = FastProcessor::new(StackInputs::default());
Processor::stack_mut(&mut processor).swapw_nth(1);
}
#[test]
fn test_op_swapw2() {
let mut processor = FastProcessor::new(
StackInputs::new(&[
Felt::new(13),
Felt::new(12),
Felt::new(11),
Felt::new(10),
Felt::new(9),
Felt::new(8),
Felt::new(7),
Felt::new(6),
Felt::new(5),
Felt::new(4),
Felt::new(3),
Felt::new(2),
Felt::new(1),
])
.unwrap(),
);
Processor::stack_mut(&mut processor).swapw_nth(2);
let expected = build_expected(&[5, 4, 3, 2, 9, 8, 7, 6, 13, 12, 11, 10, 1]);
assert_eq!(expected, processor.stack_top());
let mut processor = FastProcessor::new(StackInputs::default());
Processor::stack_mut(&mut processor).swapw_nth(2);
}
#[test]
fn test_op_swapw3() {
let mut processor = FastProcessor::new(
StackInputs::new(&[
Felt::new(16),
Felt::new(15),
Felt::new(14),
Felt::new(13),
Felt::new(12),
Felt::new(11),
Felt::new(10),
Felt::new(9),
Felt::new(8),
Felt::new(7),
Felt::new(6),
Felt::new(5),
Felt::new(4),
Felt::new(3),
Felt::new(2),
Felt::new(1),
])
.unwrap(),
);
Processor::stack_mut(&mut processor).swapw_nth(3);
let expected = build_expected(&[4, 3, 2, 1, 12, 11, 10, 9, 8, 7, 6, 5, 16, 15, 14, 13]);
assert_eq!(expected, processor.stack_top());
let mut processor = FastProcessor::new(StackInputs::default());
Processor::stack_mut(&mut processor).swapw_nth(3);
}
#[test]
fn test_op_swapdw() {
let mut processor = FastProcessor::new(
StackInputs::new(&[
Felt::new(16),
Felt::new(15),
Felt::new(14),
Felt::new(13),
Felt::new(12),
Felt::new(11),
Felt::new(10),
Felt::new(9),
Felt::new(8),
Felt::new(7),
Felt::new(6),
Felt::new(5),
Felt::new(4),
Felt::new(3),
Felt::new(2),
Felt::new(1),
])
.unwrap(),
);
op_swap_double_word(&mut processor);
let expected = build_expected(&[8, 7, 6, 5, 4, 3, 2, 1, 16, 15, 14, 13, 12, 11, 10, 9]);
assert_eq!(expected, processor.stack_top());
let mut processor = FastProcessor::new(StackInputs::default());
op_swap_double_word(&mut processor);
}
#[test]
fn test_op_movup() {
let mut processor = FastProcessor::new(
StackInputs::new(&[
Felt::new(1),
Felt::new(2),
Felt::new(3),
Felt::new(4),
Felt::new(5),
Felt::new(6),
Felt::new(7),
Felt::new(8),
Felt::new(9),
Felt::new(10),
Felt::new(11),
Felt::new(12),
Felt::new(13),
Felt::new(14),
Felt::new(15),
Felt::new(16),
])
.unwrap(),
);
Processor::stack_mut(&mut processor).rotate_left(3);
let expected = build_expected(&[3, 1, 2, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16]);
assert_eq!(expected, processor.stack_top());
Processor::stack_mut(&mut processor).rotate_left(4);
let expected = build_expected(&[4, 3, 1, 2, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16]);
assert_eq!(expected, processor.stack_top());
Processor::stack_mut(&mut processor).rotate_left(8);
let expected = build_expected(&[8, 4, 3, 1, 2, 5, 6, 7, 9, 10, 11, 12, 13, 14, 15, 16]);
assert_eq!(expected, processor.stack_top());
Processor::stack_mut(&mut processor).rotate_left(9);
let expected = build_expected(&[9, 8, 4, 3, 1, 2, 5, 6, 7, 10, 11, 12, 13, 14, 15, 16]);
assert_eq!(expected, processor.stack_top());
let mut processor = FastProcessor::new(StackInputs::default());
Processor::stack_mut(&mut processor).rotate_left(3);
}
#[test]
fn test_op_movdn() {
let mut processor = FastProcessor::new(
StackInputs::new(&[
Felt::new(1),
Felt::new(2),
Felt::new(3),
Felt::new(4),
Felt::new(5),
Felt::new(6),
Felt::new(7),
Felt::new(8),
Felt::new(9),
Felt::new(10),
Felt::new(11),
Felt::new(12),
Felt::new(13),
Felt::new(14),
Felt::new(15),
Felt::new(16),
])
.unwrap(),
);
Processor::stack_mut(&mut processor).rotate_right(3);
let expected = build_expected(&[2, 3, 1, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16]);
assert_eq!(expected, processor.stack_top());
Processor::stack_mut(&mut processor).rotate_right(4);
let expected = build_expected(&[3, 1, 4, 2, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16]);
assert_eq!(expected, processor.stack_top());
Processor::stack_mut(&mut processor).rotate_right(8);
let expected = build_expected(&[1, 4, 2, 5, 6, 7, 8, 3, 9, 10, 11, 12, 13, 14, 15, 16]);
assert_eq!(expected, processor.stack_top());
Processor::stack_mut(&mut processor).rotate_right(9);
let expected = build_expected(&[4, 2, 5, 6, 7, 8, 3, 9, 1, 10, 11, 12, 13, 14, 15, 16]);
assert_eq!(expected, processor.stack_top());
let mut processor = FastProcessor::new(StackInputs::default());
Processor::stack_mut(&mut processor).rotate_right(3);
}
#[test]
fn test_op_cswap() {
let mut processor = FastProcessor::new(
StackInputs::new(&[Felt::new(0), Felt::new(1), Felt::new(2), Felt::new(3), Felt::new(4)])
.unwrap(),
);
op_cswap(&mut processor).unwrap();
let expected = build_expected(&[1, 2, 3, 4]);
assert_eq!(expected, processor.stack_top());
op_cswap(&mut processor).unwrap();
let expected = build_expected(&[3, 2, 4]);
assert_eq!(expected, processor.stack_top());
assert!(op_cswap(&mut processor).is_err());
let mut processor = FastProcessor::new(StackInputs::default());
assert!(op_cswap(&mut processor).is_ok());
}
#[test]
fn test_op_cswapw() {
let mut processor = FastProcessor::new(
StackInputs::new(&[
Felt::new(0),
Felt::new(1),
Felt::new(2),
Felt::new(3),
Felt::new(4),
Felt::new(5),
Felt::new(6),
Felt::new(7),
Felt::new(8),
Felt::new(9),
Felt::new(10),
Felt::new(11),
])
.unwrap(),
);
op_cswapw(&mut processor).unwrap();
let expected = build_expected(&[1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11]);
assert_eq!(expected, processor.stack_top());
op_cswapw(&mut processor).unwrap();
let expected = build_expected(&[6, 7, 8, 9, 2, 3, 4, 5, 10, 11]);
assert_eq!(expected, processor.stack_top());
assert!(op_cswapw(&mut processor).is_err());
let mut processor = FastProcessor::new(StackInputs::default());
assert!(op_cswapw(&mut processor).is_ok());
}
fn build_expected(values: &[u64]) -> Vec<Felt> {
let mut expected = vec![ZERO; 16];
for (i, &value) in values.iter().enumerate() {
expected[15 - i] = Felt::new(value);
}
expected
}