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
220#[unsafe(no_mangle)]
225pub unsafe extern "C" fn patch_seq_2dup(stack: Stack) -> Stack {
226 assert!(!stack.is_null(), "2dup: stack is empty");
227 let (rest, b) = unsafe { pop(stack) };
228 assert!(!rest.is_null(), "2dup: stack has only one value");
229 let (rest, a) = unsafe { pop(rest) };
230 let stack = unsafe { push(rest, a.clone()) };
231 let stack = unsafe { push(stack, b.clone()) };
232 let stack = unsafe { push(stack, a) };
233 unsafe { push(stack, b) }
234}
235
236#[unsafe(no_mangle)]
241pub unsafe extern "C" fn patch_seq_3drop(stack: Stack) -> Stack {
242 assert!(!stack.is_null(), "3drop: stack is empty");
243 let (rest, _c) = unsafe { pop(stack) };
244 assert!(!rest.is_null(), "3drop: stack has only one value");
245 let (rest, _b) = unsafe { pop(rest) };
246 assert!(!rest.is_null(), "3drop: stack has only two values");
247 let (rest, _a) = unsafe { pop(rest) };
248 rest
249}
250
251pub unsafe fn pick(stack: Stack, n: usize) -> Stack {
262 assert!(!stack.is_null(), "pick: stack is empty");
263
264 let mut current = stack;
266 for i in 0..n {
267 assert!(
268 !current.is_null(),
269 "pick: stack has only {} values, need at least {}",
270 i + 1,
271 n + 1
272 );
273 current = unsafe { (*current).next };
274 }
275
276 assert!(
277 !current.is_null(),
278 "pick: stack has only {} values, need at least {}",
279 n,
280 n + 1
281 );
282
283 let value = unsafe { (*current).value.clone() };
285
286 unsafe { push(stack, value) }
288}
289
290#[unsafe(no_mangle)]
322pub unsafe extern "C" fn patch_seq_pick_op(stack: Stack) -> Stack {
323 use crate::value::Value;
324
325 assert!(!stack.is_null(), "pick: stack is empty");
326
327 let depth_value = unsafe { &(*stack).value };
329 let n = match depth_value {
330 Value::Int(i) => {
331 if *i < 0 {
332 panic!("pick: depth must be non-negative, got {}", i);
333 }
334 *i as usize
335 }
336 _ => panic!(
337 "pick: expected Int depth on top of stack, got {:?}",
338 depth_value
339 ),
340 };
341
342 let mut count = 0;
344 let mut current = unsafe { (*stack).next };
345 while !current.is_null() {
346 count += 1;
347 current = unsafe { (*current).next };
348 }
349
350 if count < n + 1 {
355 panic!(
356 "pick: cannot access depth {} - stack has only {} value{} (need at least {})",
357 n,
358 count,
359 if count == 1 { "" } else { "s" },
360 n + 1
361 );
362 }
363
364 let (stack, _) = unsafe { pop(stack) };
366 unsafe { pick(stack, n) }
367}
368
369#[unsafe(no_mangle)]
383pub unsafe extern "C" fn patch_seq_roll(stack: Stack) -> Stack {
384 use crate::value::Value;
385
386 assert!(!stack.is_null(), "roll: stack is empty");
387
388 let depth_value = unsafe { &(*stack).value };
390 let n = match depth_value {
391 Value::Int(i) => {
392 if *i < 0 {
393 panic!("roll: depth must be non-negative, got {}", i);
394 }
395 *i as usize
396 }
397 _ => panic!(
398 "roll: expected Int depth on top of stack, got {:?}",
399 depth_value
400 ),
401 };
402
403 let (stack, _) = unsafe { pop(stack) };
405
406 if n == 0 {
408 return stack;
410 }
411 if n == 1 {
412 return unsafe { patch_seq_swap(stack) };
414 }
415 if n == 2 {
416 return unsafe { patch_seq_rot(stack) };
418 }
419
420 let mut count = 0;
425 let mut current = stack;
426 while !current.is_null() && count <= n {
427 count += 1;
428 current = unsafe { (*current).next };
429 }
430
431 if count < n + 1 {
432 panic!(
433 "roll: cannot rotate {} items - stack has only {} value{}",
434 n + 1,
435 count,
436 if count == 1 { "" } else { "s" }
437 );
438 }
439
440 let mut items = Vec::with_capacity(n + 1);
442 let mut current_stack = stack;
443 for _ in 0..=n {
444 let (rest, val) = unsafe { pop(current_stack) };
445 items.push(val);
446 current_stack = rest;
447 }
448
449 let top_item = items.swap_remove(n);
457
458 for val in items.into_iter().rev() {
461 current_stack = unsafe { push(current_stack, val) };
462 }
463 current_stack = unsafe { push(current_stack, top_item) };
465
466 current_stack
467}
468
469pub unsafe fn clone_stack(stack: Stack) -> Stack {
481 if stack.is_null() {
482 return std::ptr::null_mut();
483 }
484
485 let mut values = Vec::new();
487 let mut current = stack;
488 while !current.is_null() {
489 values.push(unsafe { (*current).value.clone() });
490 current = unsafe { (*current).next };
491 }
492
493 let mut new_stack: Stack = std::ptr::null_mut();
496 for value in values.into_iter().rev() {
497 let node = Box::new(StackNode {
498 value,
499 next: new_stack,
500 });
501 new_stack = Box::into_raw(node);
502 }
503
504 new_stack
505}
506
507pub use patch_seq_2dup as two_dup;
509pub use patch_seq_3drop as three_drop;
510pub use patch_seq_drop_op as drop_op;
511pub use patch_seq_dup as dup;
512pub use patch_seq_nip as nip;
513pub use patch_seq_over as over;
514pub use patch_seq_pick_op as pick_op;
515pub use patch_seq_push_value as push_value;
516pub use patch_seq_roll as roll;
517pub use patch_seq_rot as rot;
518pub use patch_seq_swap as swap;
519pub use patch_seq_tuck as tuck;
520
521#[cfg(test)]
522mod tests {
523 use super::*;
524 use std::sync::Arc;
525
526 fn make_stack(values: &[i64]) -> Stack {
528 unsafe {
529 let mut stack = std::ptr::null_mut();
530 for &val in values {
531 stack = push(stack, Value::Int(val));
532 }
533 stack
534 }
535 }
536
537 fn drain_stack(mut stack: Stack) -> Vec<Value> {
539 unsafe {
540 let mut values = Vec::new();
541 while !is_empty(stack) {
542 let (rest, val) = pop(stack);
543 stack = rest;
544 values.push(val);
545 }
546 values
547 }
548 }
549
550 fn assert_stack_ints(stack: Stack, expected: &[i64]) {
552 let values = drain_stack(stack);
553 let ints: Vec<i64> = values
554 .into_iter()
555 .map(|v| match v {
556 Value::Int(n) => n,
557 _ => panic!("Expected Int, got {:?}", v),
558 })
559 .collect();
560 assert_eq!(ints, expected);
561 }
562
563 #[test]
564 fn test_push_pop() {
565 unsafe {
566 let stack = std::ptr::null_mut();
567 assert!(is_empty(stack));
568
569 let stack = push(stack, Value::Int(42));
570 assert!(!is_empty(stack));
571
572 let (stack, value) = pop(stack);
573 assert_eq!(value, Value::Int(42));
574 assert!(is_empty(stack));
575 }
576 }
577
578 #[test]
579 fn test_multiple_values() {
580 unsafe {
581 let mut stack = std::ptr::null_mut();
582
583 stack = push(stack, Value::Int(1));
584 stack = push(stack, Value::Int(2));
585 stack = push(stack, Value::Int(3));
586
587 let (stack, val) = pop(stack);
588 assert_eq!(val, Value::Int(3));
589
590 let (stack, val) = pop(stack);
591 assert_eq!(val, Value::Int(2));
592
593 let (stack, val) = pop(stack);
594 assert_eq!(val, Value::Int(1));
595
596 assert!(is_empty(stack));
597 }
598 }
599
600 #[test]
601 fn test_peek() {
602 unsafe {
603 let stack = push(std::ptr::null_mut(), Value::Int(42));
604 let peeked = peek(stack);
605 assert_eq!(*peeked, Value::Int(42));
606
607 let (stack, value) = pop(stack);
609 assert_eq!(value, Value::Int(42));
610 assert!(is_empty(stack));
611 }
612 }
613
614 #[test]
615 fn test_dup() {
616 unsafe {
617 let stack = push(std::ptr::null_mut(), Value::Int(42));
618 let stack = dup(stack);
619
620 let (stack, val1) = pop(stack);
622 assert_eq!(val1, Value::Int(42));
623
624 let (stack, val2) = pop(stack);
625 assert_eq!(val2, Value::Int(42));
626
627 assert!(is_empty(stack));
628 }
629 }
630
631 #[test]
632 fn test_drop() {
633 unsafe {
634 let mut stack = std::ptr::null_mut();
635 stack = push(stack, Value::Int(1));
636 stack = push(stack, Value::Int(2));
637 stack = push(stack, Value::Int(3));
638
639 stack = drop(stack);
641
642 let (stack, val) = pop(stack);
644 assert_eq!(val, Value::Int(2));
645
646 let (stack, val) = pop(stack);
647 assert_eq!(val, Value::Int(1));
648
649 assert!(is_empty(stack));
650 }
651 }
652
653 #[test]
654 fn test_swap() {
655 unsafe {
656 let mut stack = std::ptr::null_mut();
657 stack = push(stack, Value::Int(1));
658 stack = push(stack, Value::Int(2));
659
660 stack = swap(stack);
662
663 let (stack, val) = pop(stack);
664 assert_eq!(val, Value::Int(1));
665
666 let (stack, val) = pop(stack);
667 assert_eq!(val, Value::Int(2));
668
669 assert!(is_empty(stack));
670 }
671 }
672
673 #[test]
674 fn test_composition() {
675 unsafe {
684 let mut stack = make_stack(&[1, 2, 3]);
685
686 stack = swap(stack);
687 stack = drop(stack);
688 stack = dup(stack);
689
690 assert_stack_ints(stack, &[3, 3, 1]);
691 }
692 }
693
694 #[test]
695 fn test_over() {
696 unsafe {
698 let mut stack = std::ptr::null_mut();
699 stack = push(stack, Value::Int(1));
700 stack = push(stack, Value::Int(2));
701
702 stack = over(stack); let (stack, val) = pop(stack);
705 assert_eq!(val, Value::Int(1));
706
707 let (stack, val) = pop(stack);
708 assert_eq!(val, Value::Int(2));
709
710 let (stack, val) = pop(stack);
711 assert_eq!(val, Value::Int(1));
712
713 assert!(is_empty(stack));
714 }
715 }
716
717 #[test]
718 fn test_rot() {
719 unsafe {
721 let mut stack = std::ptr::null_mut();
722 stack = push(stack, Value::Int(1));
723 stack = push(stack, Value::Int(2));
724 stack = push(stack, Value::Int(3));
725
726 stack = rot(stack); let (stack, val) = pop(stack);
729 assert_eq!(val, Value::Int(1));
730
731 let (stack, val) = pop(stack);
732 assert_eq!(val, Value::Int(3));
733
734 let (stack, val) = pop(stack);
735 assert_eq!(val, Value::Int(2));
736
737 assert!(is_empty(stack));
738 }
739 }
740
741 #[test]
742 fn test_nip() {
743 unsafe {
745 let mut stack = std::ptr::null_mut();
746 stack = push(stack, Value::Int(1));
747 stack = push(stack, Value::Int(2));
748
749 stack = nip(stack); let (stack, val) = pop(stack);
752 assert_eq!(val, Value::Int(2));
753
754 assert!(is_empty(stack));
755 }
756 }
757
758 #[test]
759 fn test_tuck() {
760 unsafe {
762 let mut stack = std::ptr::null_mut();
763 stack = push(stack, Value::Int(1));
764 stack = push(stack, Value::Int(2));
765
766 stack = tuck(stack); let (stack, val) = pop(stack);
769 assert_eq!(val, Value::Int(2));
770
771 let (stack, val) = pop(stack);
772 assert_eq!(val, Value::Int(1));
773
774 let (stack, val) = pop(stack);
775 assert_eq!(val, Value::Int(2));
776
777 assert!(is_empty(stack));
778 }
779 }
780
781 #[test]
782 fn test_critical_shuffle_pattern() {
783 unsafe {
797 let mut stack = make_stack(&[1, 2, 3, 4, 5]);
798
799 stack = rot(stack);
803 stack = swap(stack);
809 stack = rot(stack);
815 stack = rot(stack);
821 stack = swap(stack);
827 assert_stack_ints(stack, &[4, 3, 5, 2, 1]);
835 }
836 }
837
838 #[test]
839 fn test_pick_0_is_dup() {
840 unsafe {
842 let mut stack = std::ptr::null_mut();
843 stack = push(stack, Value::Int(42));
844
845 stack = pick(stack, 0);
846
847 let (stack, val) = pop(stack);
848 assert_eq!(val, Value::Int(42));
849
850 let (stack, val) = pop(stack);
851 assert_eq!(val, Value::Int(42));
852
853 assert!(is_empty(stack));
854 }
855 }
856
857 #[test]
858 fn test_pick_1_is_over() {
859 unsafe {
861 let mut stack = std::ptr::null_mut();
862 stack = push(stack, Value::Int(1));
863 stack = push(stack, Value::Int(2));
864
865 stack = pick(stack, 1);
866
867 let (stack, val) = pop(stack);
868 assert_eq!(val, Value::Int(1));
869
870 let (stack, val) = pop(stack);
871 assert_eq!(val, Value::Int(2));
872
873 let (stack, val) = pop(stack);
874 assert_eq!(val, Value::Int(1));
875
876 assert!(is_empty(stack));
877 }
878 }
879
880 #[test]
881 fn test_pick_deep() {
882 unsafe {
884 let mut stack = std::ptr::null_mut();
885 stack = push(stack, Value::Int(1));
886 stack = push(stack, Value::Int(2));
887 stack = push(stack, Value::Int(3));
888 stack = push(stack, Value::Int(4));
889 stack = push(stack, Value::Int(5));
890
891 stack = pick(stack, 3); let (stack, val) = pop(stack);
897 assert_eq!(val, Value::Int(2));
898
899 let (stack, val) = pop(stack);
900 assert_eq!(val, Value::Int(5));
901
902 let (stack, val) = pop(stack);
903 assert_eq!(val, Value::Int(4));
904
905 let (stack, val) = pop(stack);
906 assert_eq!(val, Value::Int(3));
907
908 let (stack, val) = pop(stack);
909 assert_eq!(val, Value::Int(2));
910
911 let (stack, val) = pop(stack);
912 assert_eq!(val, Value::Int(1));
913
914 assert!(is_empty(stack));
915 }
916 }
917
918 #[test]
919 fn test_multifield_variant_survives_shuffle() {
920 use crate::value::VariantData;
924
925 unsafe {
926 let nil = Value::Variant(Arc::new(VariantData::new(0, vec![])));
929 let cons = Value::Variant(Arc::new(VariantData::new(
930 1,
931 vec![Value::Int(42), nil.clone()],
932 )));
933
934 let mut stack = std::ptr::null_mut();
936 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;
951 while !is_empty(stack) {
952 let (rest, val) = pop(stack);
953 stack = rest;
954 if matches!(val, Value::Variant(_)) {
955 found_variant = Some(val);
956 }
957 }
958
959 assert!(found_variant.is_some(), "Variant was lost during shuffle!");
961
962 if let Some(Value::Variant(variant_data)) = found_variant {
963 assert_eq!(variant_data.tag, 1, "Variant tag corrupted!");
964 assert_eq!(
965 variant_data.fields.len(),
966 2,
967 "Variant field count corrupted!"
968 );
969 assert_eq!(
970 variant_data.fields[0],
971 Value::Int(42),
972 "First field corrupted!"
973 );
974
975 if let Value::Variant(nil_data) = &variant_data.fields[1] {
977 assert_eq!(nil_data.tag, 0, "Nested variant tag corrupted!");
978 assert_eq!(nil_data.fields.len(), 0, "Nested variant should be empty!");
979 } else {
980 panic!("Second field should be a Variant!");
981 }
982 }
983 }
984 }
985
986 #[test]
987 fn test_arbitrary_depth_operations() {
988 unsafe {
991 let mut stack = std::ptr::null_mut();
992
993 for i in 0..100 {
995 stack = push(stack, Value::Int(i));
996 }
997
998 stack = dup(stack); stack = swap(stack); stack = over(stack); stack = rot(stack); stack = drop(stack); stack = pick(stack, 50); let mut count = 0;
1010 while !is_empty(stack) {
1011 let (rest, _val) = pop(stack);
1012 stack = rest;
1013 count += 1;
1014 }
1015
1016 assert_eq!(count, 102);
1018 }
1019 }
1020
1021 #[test]
1022 fn test_operation_composition_completeness() {
1023 unsafe {
1026 let mut stack = std::ptr::null_mut();
1027
1028 for i in 1..=10 {
1030 stack = push(stack, Value::Int(i));
1031 }
1032
1033 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;
1047 let mut current = stack;
1048 while !current.is_null() {
1049 depth += 1;
1050 current = (*current).next;
1051 }
1052
1053 assert!(depth > 0, "Stack should not be empty after operations");
1054 }
1055 }
1056
1057 #[test]
1058 fn test_pick_at_arbitrary_depths() {
1059 unsafe {
1062 let mut stack = std::ptr::null_mut();
1063
1064 for i in 0..50 {
1066 stack = push(stack, Value::Int(i * 10));
1067 }
1068
1069 stack = pick(stack, 0); let (mut stack, val) = pop(stack);
1075 assert_eq!(val, Value::Int(490));
1076
1077 stack = pick(stack, 10); let (mut stack, val) = pop(stack);
1079 assert_eq!(val, Value::Int(390)); stack = pick(stack, 40); let (stack, val) = pop(stack);
1083 assert_eq!(val, Value::Int(90)); let mut count = 0;
1087 let mut current = stack;
1088 while !current.is_null() {
1089 count += 1;
1090 current = (*current).next;
1091 }
1092
1093 assert_eq!(count, 50, "Stack depth should be unchanged");
1094 }
1095 }
1096
1097 #[test]
1098 fn test_pick_op_equivalence_to_dup() {
1099 unsafe {
1101 let mut stack = std::ptr::null_mut();
1102 stack = push(stack, Value::Int(42));
1103 stack = push(stack, Value::Int(0)); stack = pick_op(stack);
1106
1107 let (stack, val1) = pop(stack);
1109 assert_eq!(val1, Value::Int(42));
1110 let (stack, val2) = pop(stack);
1111 assert_eq!(val2, Value::Int(42));
1112 assert!(stack.is_null());
1113 }
1114 }
1115
1116 #[test]
1117 fn test_pick_op_equivalence_to_over() {
1118 unsafe {
1120 let mut stack = std::ptr::null_mut();
1121 stack = push(stack, Value::Int(10));
1122 stack = push(stack, Value::Int(20));
1123 stack = push(stack, Value::Int(1)); stack = pick_op(stack);
1126
1127 let (stack, val1) = pop(stack);
1129 assert_eq!(val1, Value::Int(10));
1130 let (stack, val2) = pop(stack);
1131 assert_eq!(val2, Value::Int(20));
1132 let (stack, val3) = pop(stack);
1133 assert_eq!(val3, Value::Int(10));
1134 assert!(stack.is_null());
1135 }
1136 }
1137
1138 #[test]
1139 fn test_pick_op_deep_access() {
1140 unsafe {
1142 let mut stack = std::ptr::null_mut();
1143 for i in 0..10 {
1144 stack = push(stack, Value::Int(i));
1145 }
1146 stack = push(stack, Value::Int(5)); stack = pick_op(stack);
1149
1150 let (stack, val) = pop(stack);
1152 assert_eq!(val, Value::Int(4));
1153
1154 let mut count = 0;
1156 let mut current = stack;
1157 while !current.is_null() {
1158 count += 1;
1159 current = (*current).next;
1160 }
1161 assert_eq!(count, 10);
1162 }
1163 }
1164
1165 #[test]
1171 fn test_roll_0_is_noop() {
1172 unsafe {
1174 let mut stack = std::ptr::null_mut();
1175 stack = push(stack, Value::Int(42));
1176 stack = push(stack, Value::Int(0)); stack = roll(stack);
1179
1180 let (stack, val) = pop(stack);
1181 assert_eq!(val, Value::Int(42));
1182 assert!(stack.is_null());
1183 }
1184 }
1185
1186 #[test]
1187 fn test_roll_1_is_swap() {
1188 unsafe {
1190 let mut stack = std::ptr::null_mut();
1191 stack = push(stack, Value::Int(1));
1192 stack = push(stack, Value::Int(2));
1193 stack = push(stack, Value::Int(1)); stack = roll(stack);
1196
1197 let (stack, val1) = pop(stack);
1199 assert_eq!(val1, Value::Int(1));
1200 let (stack, val2) = pop(stack);
1201 assert_eq!(val2, Value::Int(2));
1202 assert!(stack.is_null());
1203 }
1204 }
1205
1206 #[test]
1207 fn test_roll_2_is_rot() {
1208 unsafe {
1210 let mut stack = std::ptr::null_mut();
1211 stack = push(stack, Value::Int(1));
1212 stack = push(stack, Value::Int(2));
1213 stack = push(stack, Value::Int(3));
1214 stack = push(stack, Value::Int(2)); stack = roll(stack);
1217
1218 let (stack, val1) = pop(stack);
1220 assert_eq!(val1, Value::Int(1));
1221 let (stack, val2) = pop(stack);
1222 assert_eq!(val2, Value::Int(3));
1223 let (stack, val3) = pop(stack);
1224 assert_eq!(val3, Value::Int(2));
1225 assert!(stack.is_null());
1226 }
1227 }
1228
1229 #[test]
1230 fn test_roll_3_rotates_4_items() {
1231 unsafe {
1233 let mut stack = std::ptr::null_mut();
1234 stack = push(stack, Value::Int(1)); stack = push(stack, Value::Int(2));
1236 stack = push(stack, Value::Int(3));
1237 stack = push(stack, Value::Int(4)); stack = push(stack, Value::Int(3)); stack = roll(stack);
1241
1242 let (stack, val1) = pop(stack);
1244 assert_eq!(val1, Value::Int(1)); let (stack, val2) = pop(stack);
1246 assert_eq!(val2, Value::Int(4));
1247 let (stack, val3) = pop(stack);
1248 assert_eq!(val3, Value::Int(3));
1249 let (stack, val4) = pop(stack);
1250 assert_eq!(val4, Value::Int(2));
1251 assert!(stack.is_null());
1252 }
1253 }
1254
1255 #[test]
1256 fn test_roll_deep() {
1257 unsafe {
1259 let mut stack = std::ptr::null_mut();
1260 for i in 0..10 {
1261 stack = push(stack, Value::Int(i));
1262 }
1263 stack = push(stack, Value::Int(5)); stack = roll(stack);
1267
1268 let (stack, val) = pop(stack);
1271 assert_eq!(val, Value::Int(4)); let (stack, val) = pop(stack);
1275 assert_eq!(val, Value::Int(9));
1276 let (stack, val) = pop(stack);
1277 assert_eq!(val, Value::Int(8));
1278 let (stack, val) = pop(stack);
1279 assert_eq!(val, Value::Int(7));
1280 let (stack, val) = pop(stack);
1281 assert_eq!(val, Value::Int(6));
1282 let (stack, val) = pop(stack);
1283 assert_eq!(val, Value::Int(5));
1284 let (stack, val) = pop(stack);
1286 assert_eq!(val, Value::Int(3));
1287 let (stack, val) = pop(stack);
1288 assert_eq!(val, Value::Int(2));
1289 let (stack, val) = pop(stack);
1290 assert_eq!(val, Value::Int(1));
1291 let (stack, val) = pop(stack);
1292 assert_eq!(val, Value::Int(0));
1293 assert!(stack.is_null());
1294 }
1295 }
1296
1297 #[test]
1298 fn test_roll_with_extra_stack() {
1299 unsafe {
1301 let mut stack = std::ptr::null_mut();
1302 stack = push(stack, Value::Int(100)); stack = push(stack, Value::Int(1));
1304 stack = push(stack, Value::Int(2));
1305 stack = push(stack, Value::Int(3));
1306 stack = push(stack, Value::Int(4));
1307 stack = push(stack, Value::Int(3)); stack = roll(stack);
1310
1311 let (stack, val1) = pop(stack);
1313 assert_eq!(val1, Value::Int(1));
1314 let (stack, val2) = pop(stack);
1315 assert_eq!(val2, Value::Int(4));
1316 let (stack, val3) = pop(stack);
1317 assert_eq!(val3, Value::Int(3));
1318 let (stack, val4) = pop(stack);
1319 assert_eq!(val4, Value::Int(2));
1320 let (stack, val5) = pop(stack);
1321 assert_eq!(val5, Value::Int(100)); assert!(stack.is_null());
1323 }
1324 }
1325
1326 #[test]
1327 fn test_operations_preserve_stack_integrity() {
1328 unsafe {
1331 let mut stack = std::ptr::null_mut();
1332
1333 for i in 0..20 {
1334 stack = push(stack, Value::Int(i));
1335 }
1336
1337 stack = swap(stack);
1339 stack = rot(stack);
1340 stack = swap(stack);
1341 stack = rot(stack);
1342 stack = over(stack);
1343 stack = tuck(stack);
1344
1345 let mut visited = std::collections::HashSet::new();
1349 let mut current = stack;
1350 let mut count = 0;
1351
1352 while !current.is_null() {
1353 assert!(
1355 visited.insert(current as usize),
1356 "Detected cycle in stack - next pointer corruption!"
1357 );
1358
1359 count += 1;
1360 current = (*current).next;
1361
1362 assert!(
1364 count < 1000,
1365 "Stack walk exceeded reasonable depth - likely corrupted"
1366 );
1367 }
1368
1369 assert!(count > 0, "Stack should have elements");
1370 }
1371 }
1372
1373 #[test]
1374 fn test_nested_variants_with_deep_stacks() {
1375 use crate::value::VariantData;
1378
1379 unsafe {
1380 let nil = Value::Variant(Arc::new(VariantData::new(0, vec![])));
1382 let cons3 = Value::Variant(Arc::new(VariantData::new(1, vec![Value::Int(3), nil])));
1383 let cons2 = Value::Variant(Arc::new(VariantData::new(1, vec![Value::Int(2), cons3])));
1384 let cons1 = Value::Variant(Arc::new(VariantData::new(1, vec![Value::Int(1), cons2])));
1385
1386 let mut stack = std::ptr::null_mut();
1388 for i in 0..30 {
1389 stack = push(stack, Value::Int(i));
1390 }
1391 stack = push(stack, cons1.clone());
1392 for i in 30..60 {
1393 stack = push(stack, Value::Int(i));
1394 }
1395
1396 for _ in 0..10 {
1398 stack = rot(stack);
1399 stack = swap(stack);
1400 stack = over(stack);
1401 stack = drop(stack);
1402 }
1403
1404 let mut found_variant = None;
1406 while !is_empty(stack) {
1407 let (rest, val) = pop(stack);
1408 stack = rest;
1409 if let Value::Variant(ref vdata) = val
1410 && vdata.tag == 1
1411 && vdata.fields.len() == 2
1412 && let Value::Int(1) = vdata.fields[0]
1413 {
1414 found_variant = Some(val);
1415 break;
1416 }
1417 }
1418
1419 assert!(
1420 found_variant.is_some(),
1421 "Nested variant lost during deep stack operations"
1422 );
1423 }
1424 }
1425}