1use crate::pool;
2use crate::value::Value;
3
4pub struct StackNode {
10 pub value: Value,
12
13 pub next: *mut StackNode,
16}
17
18pub type Stack = *mut StackNode;
22
23pub unsafe fn push(stack: Stack, value: Value) -> Stack {
34 pool::pool_allocate(value, stack)
35}
36
37pub unsafe fn pop(stack: Stack) -> (Stack, Value) {
48 assert!(!stack.is_null(), "pop: stack is empty");
49
50 unsafe {
51 let rest = (*stack).next;
52 let value = std::mem::replace(&mut (*stack).value, Value::Int(0));
56
57 pool::pool_free(stack);
59
60 (rest, value)
61 }
62}
63
64pub unsafe fn pop_two(stack: Stack, op_name: &str) -> (Stack, Value, Value) {
76 assert!(!stack.is_null(), "{}: stack is empty", op_name);
77 let (rest, b) = unsafe { pop(stack) };
78 assert!(!rest.is_null(), "{}: need two values", op_name);
79 let (rest, a) = unsafe { pop(rest) };
80 (rest, a, b)
81}
82
83pub fn is_empty(stack: Stack) -> bool {
85 stack.is_null()
86}
87
88pub unsafe fn peek<'a>(stack: Stack) -> &'a Value {
94 assert!(!stack.is_null(), "peek: stack is empty");
95 unsafe { &(*stack).value }
96}
97
98#[unsafe(no_mangle)]
103pub unsafe extern "C" fn patch_seq_dup(stack: Stack) -> Stack {
104 assert!(!stack.is_null(), "dup: stack is empty");
105 let value = unsafe { (*stack).value.clone() };
110 unsafe { push(stack, value) }
111}
112
113pub unsafe fn drop(stack: Stack) -> Stack {
118 assert!(!stack.is_null(), "drop: stack is empty");
119 let (rest, _) = unsafe { pop(stack) };
120 rest
121}
122
123#[unsafe(no_mangle)]
130pub unsafe extern "C" fn patch_seq_drop_op(stack: Stack) -> Stack {
131 unsafe { drop(stack) }
132}
133
134#[allow(improper_ctypes_definitions)]
142#[unsafe(no_mangle)]
143pub unsafe extern "C" fn patch_seq_push_value(stack: Stack, value: Value) -> Stack {
144 unsafe { push(stack, value) }
145}
146
147#[unsafe(no_mangle)]
152pub unsafe extern "C" fn patch_seq_swap(stack: Stack) -> Stack {
153 assert!(!stack.is_null(), "swap: stack is empty");
154 let (rest, b) = unsafe { pop(stack) };
155 assert!(!rest.is_null(), "swap: stack has only one value");
156 let (rest, a) = unsafe { pop(rest) };
157 let stack = unsafe { push(rest, b) };
158 unsafe { push(stack, a) }
159}
160
161#[unsafe(no_mangle)]
166pub unsafe extern "C" fn patch_seq_over(stack: Stack) -> Stack {
167 assert!(!stack.is_null(), "over: stack is empty");
168 let (rest, b) = unsafe { pop(stack) };
169 assert!(!rest.is_null(), "over: stack has only one value");
170 let a = unsafe { (*rest).value.clone() };
171 let stack = unsafe { push(rest, b) };
172 unsafe { push(stack, a) }
173}
174
175#[unsafe(no_mangle)]
180pub unsafe extern "C" fn patch_seq_rot(stack: Stack) -> Stack {
181 assert!(!stack.is_null(), "rot: stack is empty");
182 let (rest, c) = unsafe { pop(stack) };
183 assert!(!rest.is_null(), "rot: stack has only one value");
184 let (rest, b) = unsafe { pop(rest) };
185 assert!(!rest.is_null(), "rot: stack has only two values");
186 let (rest, a) = unsafe { pop(rest) };
187 let stack = unsafe { push(rest, b) };
188 let stack = unsafe { push(stack, c) };
189 unsafe { push(stack, a) }
190}
191
192#[unsafe(no_mangle)]
197pub unsafe extern "C" fn patch_seq_nip(stack: Stack) -> Stack {
198 assert!(!stack.is_null(), "nip: stack is empty");
199 let (rest, b) = unsafe { pop(stack) };
200 assert!(!rest.is_null(), "nip: stack has only one value");
201 let (rest, _a) = unsafe { pop(rest) };
202 unsafe { push(rest, b) }
203}
204
205#[unsafe(no_mangle)]
210pub unsafe extern "C" fn patch_seq_tuck(stack: Stack) -> Stack {
211 assert!(!stack.is_null(), "tuck: stack is empty");
212 let (rest, b) = unsafe { pop(stack) };
213 assert!(!rest.is_null(), "tuck: stack has only one value");
214 let (rest, a) = unsafe { pop(rest) };
215 let stack = unsafe { push(rest, b.clone()) };
216 let stack = unsafe { push(stack, a) };
217 unsafe { push(stack, b) }
218}
219
220pub unsafe fn pick(stack: Stack, n: usize) -> Stack {
231 assert!(!stack.is_null(), "pick: stack is empty");
232
233 let mut current = stack;
235 for i in 0..n {
236 assert!(
237 !current.is_null(),
238 "pick: stack has only {} values, need at least {}",
239 i + 1,
240 n + 1
241 );
242 current = unsafe { (*current).next };
243 }
244
245 assert!(
246 !current.is_null(),
247 "pick: stack has only {} values, need at least {}",
248 n,
249 n + 1
250 );
251
252 let value = unsafe { (*current).value.clone() };
254
255 unsafe { push(stack, value) }
257}
258
259#[unsafe(no_mangle)]
291pub unsafe extern "C" fn patch_seq_pick_op(stack: Stack) -> Stack {
292 use crate::value::Value;
293
294 assert!(!stack.is_null(), "pick: stack is empty");
295
296 let depth_value = unsafe { &(*stack).value };
298 let n = match depth_value {
299 Value::Int(i) => {
300 if *i < 0 {
301 panic!("pick: depth must be non-negative, got {}", i);
302 }
303 *i as usize
304 }
305 _ => panic!(
306 "pick: expected Int depth on top of stack, got {:?}",
307 depth_value
308 ),
309 };
310
311 let mut count = 0;
313 let mut current = unsafe { (*stack).next };
314 while !current.is_null() {
315 count += 1;
316 current = unsafe { (*current).next };
317 }
318
319 if count < n + 1 {
324 panic!(
325 "pick: cannot access depth {} - stack has only {} value{} (need at least {})",
326 n,
327 count,
328 if count == 1 { "" } else { "s" },
329 n + 1
330 );
331 }
332
333 let (stack, _) = unsafe { pop(stack) };
335 unsafe { pick(stack, n) }
336}
337
338#[unsafe(no_mangle)]
352pub unsafe extern "C" fn patch_seq_roll(stack: Stack) -> Stack {
353 use crate::value::Value;
354
355 assert!(!stack.is_null(), "roll: stack is empty");
356
357 let depth_value = unsafe { &(*stack).value };
359 let n = match depth_value {
360 Value::Int(i) => {
361 if *i < 0 {
362 panic!("roll: depth must be non-negative, got {}", i);
363 }
364 *i as usize
365 }
366 _ => panic!(
367 "roll: expected Int depth on top of stack, got {:?}",
368 depth_value
369 ),
370 };
371
372 let (stack, _) = unsafe { pop(stack) };
374
375 if n == 0 {
377 return stack;
379 }
380 if n == 1 {
381 return unsafe { patch_seq_swap(stack) };
383 }
384 if n == 2 {
385 return unsafe { patch_seq_rot(stack) };
387 }
388
389 let mut count = 0;
394 let mut current = stack;
395 while !current.is_null() && count <= n {
396 count += 1;
397 current = unsafe { (*current).next };
398 }
399
400 if count < n + 1 {
401 panic!(
402 "roll: cannot rotate {} items - stack has only {} value{}",
403 n + 1,
404 count,
405 if count == 1 { "" } else { "s" }
406 );
407 }
408
409 let mut items = Vec::with_capacity(n + 1);
411 let mut current_stack = stack;
412 for _ in 0..=n {
413 let (rest, val) = unsafe { pop(current_stack) };
414 items.push(val);
415 current_stack = rest;
416 }
417
418 let top_item = items.swap_remove(n);
426
427 for val in items.into_iter().rev() {
430 current_stack = unsafe { push(current_stack, val) };
431 }
432 current_stack = unsafe { push(current_stack, top_item) };
434
435 current_stack
436}
437
438pub use patch_seq_drop_op as drop_op;
440pub use patch_seq_dup as dup;
441pub use patch_seq_nip as nip;
442pub use patch_seq_over as over;
443pub use patch_seq_pick_op as pick_op;
444pub use patch_seq_push_value as push_value;
445pub use patch_seq_roll as roll;
446pub use patch_seq_rot as rot;
447pub use patch_seq_swap as swap;
448pub use patch_seq_tuck as tuck;
449
450#[cfg(test)]
451mod tests {
452 use super::*;
453
454 fn make_stack(values: &[i64]) -> Stack {
456 unsafe {
457 let mut stack = std::ptr::null_mut();
458 for &val in values {
459 stack = push(stack, Value::Int(val));
460 }
461 stack
462 }
463 }
464
465 fn drain_stack(mut stack: Stack) -> Vec<Value> {
467 unsafe {
468 let mut values = Vec::new();
469 while !is_empty(stack) {
470 let (rest, val) = pop(stack);
471 stack = rest;
472 values.push(val);
473 }
474 values
475 }
476 }
477
478 fn assert_stack_ints(stack: Stack, expected: &[i64]) {
480 let values = drain_stack(stack);
481 let ints: Vec<i64> = values
482 .into_iter()
483 .map(|v| match v {
484 Value::Int(n) => n,
485 _ => panic!("Expected Int, got {:?}", v),
486 })
487 .collect();
488 assert_eq!(ints, expected);
489 }
490
491 #[test]
492 fn test_push_pop() {
493 unsafe {
494 let stack = std::ptr::null_mut();
495 assert!(is_empty(stack));
496
497 let stack = push(stack, Value::Int(42));
498 assert!(!is_empty(stack));
499
500 let (stack, value) = pop(stack);
501 assert_eq!(value, Value::Int(42));
502 assert!(is_empty(stack));
503 }
504 }
505
506 #[test]
507 fn test_multiple_values() {
508 unsafe {
509 let mut stack = std::ptr::null_mut();
510
511 stack = push(stack, Value::Int(1));
512 stack = push(stack, Value::Int(2));
513 stack = push(stack, Value::Int(3));
514
515 let (stack, val) = pop(stack);
516 assert_eq!(val, Value::Int(3));
517
518 let (stack, val) = pop(stack);
519 assert_eq!(val, Value::Int(2));
520
521 let (stack, val) = pop(stack);
522 assert_eq!(val, Value::Int(1));
523
524 assert!(is_empty(stack));
525 }
526 }
527
528 #[test]
529 fn test_peek() {
530 unsafe {
531 let stack = push(std::ptr::null_mut(), Value::Int(42));
532 let peeked = peek(stack);
533 assert_eq!(*peeked, Value::Int(42));
534
535 let (stack, value) = pop(stack);
537 assert_eq!(value, Value::Int(42));
538 assert!(is_empty(stack));
539 }
540 }
541
542 #[test]
543 fn test_dup() {
544 unsafe {
545 let stack = push(std::ptr::null_mut(), Value::Int(42));
546 let stack = dup(stack);
547
548 let (stack, val1) = pop(stack);
550 assert_eq!(val1, Value::Int(42));
551
552 let (stack, val2) = pop(stack);
553 assert_eq!(val2, Value::Int(42));
554
555 assert!(is_empty(stack));
556 }
557 }
558
559 #[test]
560 fn test_drop() {
561 unsafe {
562 let mut stack = std::ptr::null_mut();
563 stack = push(stack, Value::Int(1));
564 stack = push(stack, Value::Int(2));
565 stack = push(stack, Value::Int(3));
566
567 stack = drop(stack);
569
570 let (stack, val) = pop(stack);
572 assert_eq!(val, Value::Int(2));
573
574 let (stack, val) = pop(stack);
575 assert_eq!(val, Value::Int(1));
576
577 assert!(is_empty(stack));
578 }
579 }
580
581 #[test]
582 fn test_swap() {
583 unsafe {
584 let mut stack = std::ptr::null_mut();
585 stack = push(stack, Value::Int(1));
586 stack = push(stack, Value::Int(2));
587
588 stack = swap(stack);
590
591 let (stack, val) = pop(stack);
592 assert_eq!(val, Value::Int(1));
593
594 let (stack, val) = pop(stack);
595 assert_eq!(val, Value::Int(2));
596
597 assert!(is_empty(stack));
598 }
599 }
600
601 #[test]
602 fn test_composition() {
603 unsafe {
612 let mut stack = make_stack(&[1, 2, 3]);
613
614 stack = swap(stack);
615 stack = drop(stack);
616 stack = dup(stack);
617
618 assert_stack_ints(stack, &[3, 3, 1]);
619 }
620 }
621
622 #[test]
623 fn test_over() {
624 unsafe {
626 let mut stack = std::ptr::null_mut();
627 stack = push(stack, Value::Int(1));
628 stack = push(stack, Value::Int(2));
629
630 stack = over(stack); let (stack, val) = pop(stack);
633 assert_eq!(val, Value::Int(1));
634
635 let (stack, val) = pop(stack);
636 assert_eq!(val, Value::Int(2));
637
638 let (stack, val) = pop(stack);
639 assert_eq!(val, Value::Int(1));
640
641 assert!(is_empty(stack));
642 }
643 }
644
645 #[test]
646 fn test_rot() {
647 unsafe {
649 let mut stack = std::ptr::null_mut();
650 stack = push(stack, Value::Int(1));
651 stack = push(stack, Value::Int(2));
652 stack = push(stack, Value::Int(3));
653
654 stack = rot(stack); let (stack, val) = pop(stack);
657 assert_eq!(val, Value::Int(1));
658
659 let (stack, val) = pop(stack);
660 assert_eq!(val, Value::Int(3));
661
662 let (stack, val) = pop(stack);
663 assert_eq!(val, Value::Int(2));
664
665 assert!(is_empty(stack));
666 }
667 }
668
669 #[test]
670 fn test_nip() {
671 unsafe {
673 let mut stack = std::ptr::null_mut();
674 stack = push(stack, Value::Int(1));
675 stack = push(stack, Value::Int(2));
676
677 stack = nip(stack); let (stack, val) = pop(stack);
680 assert_eq!(val, Value::Int(2));
681
682 assert!(is_empty(stack));
683 }
684 }
685
686 #[test]
687 fn test_tuck() {
688 unsafe {
690 let mut stack = std::ptr::null_mut();
691 stack = push(stack, Value::Int(1));
692 stack = push(stack, Value::Int(2));
693
694 stack = tuck(stack); let (stack, val) = pop(stack);
697 assert_eq!(val, Value::Int(2));
698
699 let (stack, val) = pop(stack);
700 assert_eq!(val, Value::Int(1));
701
702 let (stack, val) = pop(stack);
703 assert_eq!(val, Value::Int(2));
704
705 assert!(is_empty(stack));
706 }
707 }
708
709 #[test]
710 fn test_critical_shuffle_pattern() {
711 unsafe {
725 let mut stack = make_stack(&[1, 2, 3, 4, 5]);
726
727 stack = rot(stack);
731 stack = swap(stack);
737 stack = rot(stack);
743 stack = rot(stack);
749 stack = swap(stack);
755 assert_stack_ints(stack, &[4, 3, 5, 2, 1]);
763 }
764 }
765
766 #[test]
767 fn test_pick_0_is_dup() {
768 unsafe {
770 let mut stack = std::ptr::null_mut();
771 stack = push(stack, Value::Int(42));
772
773 stack = pick(stack, 0);
774
775 let (stack, val) = pop(stack);
776 assert_eq!(val, Value::Int(42));
777
778 let (stack, val) = pop(stack);
779 assert_eq!(val, Value::Int(42));
780
781 assert!(is_empty(stack));
782 }
783 }
784
785 #[test]
786 fn test_pick_1_is_over() {
787 unsafe {
789 let mut stack = std::ptr::null_mut();
790 stack = push(stack, Value::Int(1));
791 stack = push(stack, Value::Int(2));
792
793 stack = pick(stack, 1);
794
795 let (stack, val) = pop(stack);
796 assert_eq!(val, Value::Int(1));
797
798 let (stack, val) = pop(stack);
799 assert_eq!(val, Value::Int(2));
800
801 let (stack, val) = pop(stack);
802 assert_eq!(val, Value::Int(1));
803
804 assert!(is_empty(stack));
805 }
806 }
807
808 #[test]
809 fn test_pick_deep() {
810 unsafe {
812 let mut stack = std::ptr::null_mut();
813 stack = push(stack, Value::Int(1));
814 stack = push(stack, Value::Int(2));
815 stack = push(stack, Value::Int(3));
816 stack = push(stack, Value::Int(4));
817 stack = push(stack, Value::Int(5));
818
819 stack = pick(stack, 3); let (stack, val) = pop(stack);
825 assert_eq!(val, Value::Int(2));
826
827 let (stack, val) = pop(stack);
828 assert_eq!(val, Value::Int(5));
829
830 let (stack, val) = pop(stack);
831 assert_eq!(val, Value::Int(4));
832
833 let (stack, val) = pop(stack);
834 assert_eq!(val, Value::Int(3));
835
836 let (stack, val) = pop(stack);
837 assert_eq!(val, Value::Int(2));
838
839 let (stack, val) = pop(stack);
840 assert_eq!(val, Value::Int(1));
841
842 assert!(is_empty(stack));
843 }
844 }
845
846 #[test]
847 fn test_multifield_variant_survives_shuffle() {
848 use crate::value::VariantData;
852
853 unsafe {
854 let nil = Value::Variant(Box::new(VariantData::new(0, vec![])));
857 let cons = Value::Variant(Box::new(VariantData::new(
858 1,
859 vec![Value::Int(42), nil.clone()],
860 )));
861
862 let mut stack = std::ptr::null_mut();
864 stack = push(stack, Value::Int(100)); stack = push(stack, Value::Int(200)); stack = push(stack, cons.clone()); stack = push(stack, Value::Int(300)); stack = push(stack, Value::Int(400)); stack = rot(stack); stack = swap(stack); stack = rot(stack); stack = rot(stack); stack = swap(stack); let mut found_variant = None;
879 while !is_empty(stack) {
880 let (rest, val) = pop(stack);
881 stack = rest;
882 if matches!(val, Value::Variant(_)) {
883 found_variant = Some(val);
884 }
885 }
886
887 assert!(found_variant.is_some(), "Variant was lost during shuffle!");
889
890 if let Some(Value::Variant(variant_data)) = found_variant {
891 assert_eq!(variant_data.tag, 1, "Variant tag corrupted!");
892 assert_eq!(
893 variant_data.fields.len(),
894 2,
895 "Variant field count corrupted!"
896 );
897 assert_eq!(
898 variant_data.fields[0],
899 Value::Int(42),
900 "First field corrupted!"
901 );
902
903 if let Value::Variant(nil_data) = &variant_data.fields[1] {
905 assert_eq!(nil_data.tag, 0, "Nested variant tag corrupted!");
906 assert_eq!(nil_data.fields.len(), 0, "Nested variant should be empty!");
907 } else {
908 panic!("Second field should be a Variant!");
909 }
910 }
911 }
912 }
913
914 #[test]
915 fn test_arbitrary_depth_operations() {
916 unsafe {
919 let mut stack = std::ptr::null_mut();
920
921 for i in 0..100 {
923 stack = push(stack, Value::Int(i));
924 }
925
926 stack = dup(stack); stack = swap(stack); stack = over(stack); stack = rot(stack); stack = drop(stack); stack = pick(stack, 50); let mut count = 0;
938 while !is_empty(stack) {
939 let (rest, _val) = pop(stack);
940 stack = rest;
941 count += 1;
942 }
943
944 assert_eq!(count, 102);
946 }
947 }
948
949 #[test]
950 fn test_operation_composition_completeness() {
951 unsafe {
954 let mut stack = std::ptr::null_mut();
955
956 for i in 1..=10 {
958 stack = push(stack, Value::Int(i));
959 }
960
961 stack = dup(stack); stack = over(stack); stack = rot(stack); stack = swap(stack); stack = nip(stack); stack = tuck(stack); stack = pick(stack, 5); stack = drop(stack); let mut depth = 0;
975 let mut current = stack;
976 while !current.is_null() {
977 depth += 1;
978 current = (*current).next;
979 }
980
981 assert!(depth > 0, "Stack should not be empty after operations");
982 }
983 }
984
985 #[test]
986 fn test_pick_at_arbitrary_depths() {
987 unsafe {
990 let mut stack = std::ptr::null_mut();
991
992 for i in 0..50 {
994 stack = push(stack, Value::Int(i * 10));
995 }
996
997 stack = pick(stack, 0); let (mut stack, val) = pop(stack);
1003 assert_eq!(val, Value::Int(490));
1004
1005 stack = pick(stack, 10); let (mut stack, val) = pop(stack);
1007 assert_eq!(val, Value::Int(390)); stack = pick(stack, 40); let (stack, val) = pop(stack);
1011 assert_eq!(val, Value::Int(90)); let mut count = 0;
1015 let mut current = stack;
1016 while !current.is_null() {
1017 count += 1;
1018 current = (*current).next;
1019 }
1020
1021 assert_eq!(count, 50, "Stack depth should be unchanged");
1022 }
1023 }
1024
1025 #[test]
1026 fn test_pick_op_equivalence_to_dup() {
1027 unsafe {
1029 let mut stack = std::ptr::null_mut();
1030 stack = push(stack, Value::Int(42));
1031 stack = push(stack, Value::Int(0)); stack = pick_op(stack);
1034
1035 let (stack, val1) = pop(stack);
1037 assert_eq!(val1, Value::Int(42));
1038 let (stack, val2) = pop(stack);
1039 assert_eq!(val2, Value::Int(42));
1040 assert!(stack.is_null());
1041 }
1042 }
1043
1044 #[test]
1045 fn test_pick_op_equivalence_to_over() {
1046 unsafe {
1048 let mut stack = std::ptr::null_mut();
1049 stack = push(stack, Value::Int(10));
1050 stack = push(stack, Value::Int(20));
1051 stack = push(stack, Value::Int(1)); stack = pick_op(stack);
1054
1055 let (stack, val1) = pop(stack);
1057 assert_eq!(val1, Value::Int(10));
1058 let (stack, val2) = pop(stack);
1059 assert_eq!(val2, Value::Int(20));
1060 let (stack, val3) = pop(stack);
1061 assert_eq!(val3, Value::Int(10));
1062 assert!(stack.is_null());
1063 }
1064 }
1065
1066 #[test]
1067 fn test_pick_op_deep_access() {
1068 unsafe {
1070 let mut stack = std::ptr::null_mut();
1071 for i in 0..10 {
1072 stack = push(stack, Value::Int(i));
1073 }
1074 stack = push(stack, Value::Int(5)); stack = pick_op(stack);
1077
1078 let (stack, val) = pop(stack);
1080 assert_eq!(val, Value::Int(4));
1081
1082 let mut count = 0;
1084 let mut current = stack;
1085 while !current.is_null() {
1086 count += 1;
1087 current = (*current).next;
1088 }
1089 assert_eq!(count, 10);
1090 }
1091 }
1092
1093 #[test]
1099 fn test_roll_0_is_noop() {
1100 unsafe {
1102 let mut stack = std::ptr::null_mut();
1103 stack = push(stack, Value::Int(42));
1104 stack = push(stack, Value::Int(0)); stack = roll(stack);
1107
1108 let (stack, val) = pop(stack);
1109 assert_eq!(val, Value::Int(42));
1110 assert!(stack.is_null());
1111 }
1112 }
1113
1114 #[test]
1115 fn test_roll_1_is_swap() {
1116 unsafe {
1118 let mut stack = std::ptr::null_mut();
1119 stack = push(stack, Value::Int(1));
1120 stack = push(stack, Value::Int(2));
1121 stack = push(stack, Value::Int(1)); stack = roll(stack);
1124
1125 let (stack, val1) = pop(stack);
1127 assert_eq!(val1, Value::Int(1));
1128 let (stack, val2) = pop(stack);
1129 assert_eq!(val2, Value::Int(2));
1130 assert!(stack.is_null());
1131 }
1132 }
1133
1134 #[test]
1135 fn test_roll_2_is_rot() {
1136 unsafe {
1138 let mut stack = std::ptr::null_mut();
1139 stack = push(stack, Value::Int(1));
1140 stack = push(stack, Value::Int(2));
1141 stack = push(stack, Value::Int(3));
1142 stack = push(stack, Value::Int(2)); stack = roll(stack);
1145
1146 let (stack, val1) = pop(stack);
1148 assert_eq!(val1, Value::Int(1));
1149 let (stack, val2) = pop(stack);
1150 assert_eq!(val2, Value::Int(3));
1151 let (stack, val3) = pop(stack);
1152 assert_eq!(val3, Value::Int(2));
1153 assert!(stack.is_null());
1154 }
1155 }
1156
1157 #[test]
1158 fn test_roll_3_rotates_4_items() {
1159 unsafe {
1161 let mut stack = std::ptr::null_mut();
1162 stack = push(stack, Value::Int(1)); stack = push(stack, Value::Int(2));
1164 stack = push(stack, Value::Int(3));
1165 stack = push(stack, Value::Int(4)); stack = push(stack, Value::Int(3)); stack = roll(stack);
1169
1170 let (stack, val1) = pop(stack);
1172 assert_eq!(val1, Value::Int(1)); let (stack, val2) = pop(stack);
1174 assert_eq!(val2, Value::Int(4));
1175 let (stack, val3) = pop(stack);
1176 assert_eq!(val3, Value::Int(3));
1177 let (stack, val4) = pop(stack);
1178 assert_eq!(val4, Value::Int(2));
1179 assert!(stack.is_null());
1180 }
1181 }
1182
1183 #[test]
1184 fn test_roll_deep() {
1185 unsafe {
1187 let mut stack = std::ptr::null_mut();
1188 for i in 0..10 {
1189 stack = push(stack, Value::Int(i));
1190 }
1191 stack = push(stack, Value::Int(5)); stack = roll(stack);
1195
1196 let (stack, val) = pop(stack);
1199 assert_eq!(val, Value::Int(4)); let (stack, val) = pop(stack);
1203 assert_eq!(val, Value::Int(9));
1204 let (stack, val) = pop(stack);
1205 assert_eq!(val, Value::Int(8));
1206 let (stack, val) = pop(stack);
1207 assert_eq!(val, Value::Int(7));
1208 let (stack, val) = pop(stack);
1209 assert_eq!(val, Value::Int(6));
1210 let (stack, val) = pop(stack);
1211 assert_eq!(val, Value::Int(5));
1212 let (stack, val) = pop(stack);
1214 assert_eq!(val, Value::Int(3));
1215 let (stack, val) = pop(stack);
1216 assert_eq!(val, Value::Int(2));
1217 let (stack, val) = pop(stack);
1218 assert_eq!(val, Value::Int(1));
1219 let (stack, val) = pop(stack);
1220 assert_eq!(val, Value::Int(0));
1221 assert!(stack.is_null());
1222 }
1223 }
1224
1225 #[test]
1226 fn test_roll_with_extra_stack() {
1227 unsafe {
1229 let mut stack = std::ptr::null_mut();
1230 stack = push(stack, Value::Int(100)); stack = push(stack, Value::Int(1));
1232 stack = push(stack, Value::Int(2));
1233 stack = push(stack, Value::Int(3));
1234 stack = push(stack, Value::Int(4));
1235 stack = push(stack, Value::Int(3)); stack = roll(stack);
1238
1239 let (stack, val1) = pop(stack);
1241 assert_eq!(val1, Value::Int(1));
1242 let (stack, val2) = pop(stack);
1243 assert_eq!(val2, Value::Int(4));
1244 let (stack, val3) = pop(stack);
1245 assert_eq!(val3, Value::Int(3));
1246 let (stack, val4) = pop(stack);
1247 assert_eq!(val4, Value::Int(2));
1248 let (stack, val5) = pop(stack);
1249 assert_eq!(val5, Value::Int(100)); assert!(stack.is_null());
1251 }
1252 }
1253
1254 #[test]
1255 fn test_operations_preserve_stack_integrity() {
1256 unsafe {
1259 let mut stack = std::ptr::null_mut();
1260
1261 for i in 0..20 {
1262 stack = push(stack, Value::Int(i));
1263 }
1264
1265 stack = swap(stack);
1267 stack = rot(stack);
1268 stack = swap(stack);
1269 stack = rot(stack);
1270 stack = over(stack);
1271 stack = tuck(stack);
1272
1273 let mut visited = std::collections::HashSet::new();
1277 let mut current = stack;
1278 let mut count = 0;
1279
1280 while !current.is_null() {
1281 assert!(
1283 visited.insert(current as usize),
1284 "Detected cycle in stack - next pointer corruption!"
1285 );
1286
1287 count += 1;
1288 current = (*current).next;
1289
1290 assert!(
1292 count < 1000,
1293 "Stack walk exceeded reasonable depth - likely corrupted"
1294 );
1295 }
1296
1297 assert!(count > 0, "Stack should have elements");
1298 }
1299 }
1300
1301 #[test]
1302 fn test_nested_variants_with_deep_stacks() {
1303 use crate::value::VariantData;
1306
1307 unsafe {
1308 let nil = Value::Variant(Box::new(VariantData::new(0, vec![])));
1310 let cons3 = Value::Variant(Box::new(VariantData::new(1, vec![Value::Int(3), nil])));
1311 let cons2 = Value::Variant(Box::new(VariantData::new(1, vec![Value::Int(2), cons3])));
1312 let cons1 = Value::Variant(Box::new(VariantData::new(1, vec![Value::Int(1), cons2])));
1313
1314 let mut stack = std::ptr::null_mut();
1316 for i in 0..30 {
1317 stack = push(stack, Value::Int(i));
1318 }
1319 stack = push(stack, cons1.clone());
1320 for i in 30..60 {
1321 stack = push(stack, Value::Int(i));
1322 }
1323
1324 for _ in 0..10 {
1326 stack = rot(stack);
1327 stack = swap(stack);
1328 stack = over(stack);
1329 stack = drop(stack);
1330 }
1331
1332 let mut found_variant = None;
1334 while !is_empty(stack) {
1335 let (rest, val) = pop(stack);
1336 stack = rest;
1337 if let Value::Variant(ref vdata) = val
1338 && vdata.tag == 1
1339 && vdata.fields.len() == 2
1340 && let Value::Int(1) = vdata.fields[0]
1341 {
1342 found_variant = Some(val);
1343 break;
1344 }
1345 }
1346
1347 assert!(
1348 found_variant.is_some(),
1349 "Nested variant lost during deep stack operations"
1350 );
1351 }
1352 }
1353}