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 unsafe fn pop_three(stack: Stack, op_name: &str) -> (Stack, Value, Value, Value) {
93 assert!(!stack.is_null(), "{}: stack is empty", op_name);
94 let (rest, c) = unsafe { pop(stack) };
95 assert!(!rest.is_null(), "{}: need at least two values", op_name);
96 let (rest, b) = unsafe { pop(rest) };
97 assert!(!rest.is_null(), "{}: need at least three values", op_name);
98 let (rest, a) = unsafe { pop(rest) };
99 (rest, a, b, c)
100}
101
102pub fn is_empty(stack: Stack) -> bool {
104 stack.is_null()
105}
106
107pub unsafe fn peek<'a>(stack: Stack) -> &'a Value {
113 assert!(!stack.is_null(), "peek: stack is empty");
114 unsafe { &(*stack).value }
115}
116
117#[unsafe(no_mangle)]
122pub unsafe extern "C" fn patch_seq_dup(stack: Stack) -> Stack {
123 assert!(!stack.is_null(), "dup: stack is empty");
124 let value = unsafe { (*stack).value.clone() };
129 unsafe { push(stack, value) }
130}
131
132pub unsafe fn drop(stack: Stack) -> Stack {
137 assert!(!stack.is_null(), "drop: stack is empty");
138 let (rest, _) = unsafe { pop(stack) };
139 rest
140}
141
142#[unsafe(no_mangle)]
149pub unsafe extern "C" fn patch_seq_drop_op(stack: Stack) -> Stack {
150 unsafe { drop(stack) }
151}
152
153#[allow(improper_ctypes_definitions)]
161#[unsafe(no_mangle)]
162pub unsafe extern "C" fn patch_seq_push_value(stack: Stack, value: Value) -> Stack {
163 unsafe { push(stack, value) }
164}
165
166#[unsafe(no_mangle)]
171pub unsafe extern "C" fn patch_seq_swap(stack: Stack) -> Stack {
172 let (rest, a, b) = unsafe { pop_two(stack, "swap") };
173 let stack = unsafe { push(rest, b) };
174 unsafe { push(stack, a) }
175}
176
177#[unsafe(no_mangle)]
182pub unsafe extern "C" fn patch_seq_over(stack: Stack) -> Stack {
183 let (rest, a, b) = unsafe { pop_two(stack, "over") };
184 let stack = unsafe { push(rest, a.clone()) };
185 let stack = unsafe { push(stack, b) };
186 unsafe { push(stack, a) }
187}
188
189#[unsafe(no_mangle)]
194pub unsafe extern "C" fn patch_seq_rot(stack: Stack) -> Stack {
195 let (rest, a, b, c) = unsafe { pop_three(stack, "rot") };
196 let stack = unsafe { push(rest, b) };
197 let stack = unsafe { push(stack, c) };
198 unsafe { push(stack, a) }
199}
200
201#[unsafe(no_mangle)]
206pub unsafe extern "C" fn patch_seq_nip(stack: Stack) -> Stack {
207 let (rest, _a, b) = unsafe { pop_two(stack, "nip") };
208 unsafe { push(rest, b) }
209}
210
211#[unsafe(no_mangle)]
216pub unsafe extern "C" fn patch_seq_tuck(stack: Stack) -> Stack {
217 let (rest, a, b) = unsafe { pop_two(stack, "tuck") };
218 let stack = unsafe { push(rest, b.clone()) };
219 let stack = unsafe { push(stack, a) };
220 unsafe { push(stack, b) }
221}
222
223#[unsafe(no_mangle)]
228pub unsafe extern "C" fn patch_seq_2dup(stack: Stack) -> Stack {
229 let (rest, a, b) = unsafe { pop_two(stack, "2dup") };
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 let (rest, _a, _b, _c) = unsafe { pop_three(stack, "3drop") };
243 rest
244}
245
246pub unsafe fn pick(stack: Stack, n: usize) -> Stack {
257 assert!(!stack.is_null(), "pick: stack is empty");
258
259 let mut current = stack;
261 for i in 0..n {
262 assert!(
263 !current.is_null(),
264 "pick: stack has only {} values, need at least {}",
265 i + 1,
266 n + 1
267 );
268 current = unsafe { (*current).next };
269 }
270
271 assert!(
272 !current.is_null(),
273 "pick: stack has only {} values, need at least {}",
274 n,
275 n + 1
276 );
277
278 let value = unsafe { (*current).value.clone() };
280
281 unsafe { push(stack, value) }
283}
284
285#[unsafe(no_mangle)]
317pub unsafe extern "C" fn patch_seq_pick_op(stack: Stack) -> Stack {
318 use crate::value::Value;
319
320 assert!(!stack.is_null(), "pick: stack is empty");
321
322 let depth_value = unsafe { &(*stack).value };
324 let n = match depth_value {
325 Value::Int(i) => {
326 if *i < 0 {
327 panic!("pick: depth must be non-negative, got {}", i);
328 }
329 *i as usize
330 }
331 _ => panic!(
332 "pick: expected Int depth on top of stack, got {:?}",
333 depth_value
334 ),
335 };
336
337 let mut count = 0;
339 let mut current = unsafe { (*stack).next };
340 while !current.is_null() {
341 count += 1;
342 current = unsafe { (*current).next };
343 }
344
345 if count < n + 1 {
350 panic!(
351 "pick: cannot access depth {} - stack has only {} value{} (need at least {})",
352 n,
353 count,
354 if count == 1 { "" } else { "s" },
355 n + 1
356 );
357 }
358
359 let (stack, _) = unsafe { pop(stack) };
361 unsafe { pick(stack, n) }
362}
363
364#[unsafe(no_mangle)]
378pub unsafe extern "C" fn patch_seq_roll(stack: Stack) -> Stack {
379 use crate::value::Value;
380
381 assert!(!stack.is_null(), "roll: stack is empty");
382
383 let depth_value = unsafe { &(*stack).value };
385 let n = match depth_value {
386 Value::Int(i) => {
387 if *i < 0 {
388 panic!("roll: depth must be non-negative, got {}", i);
389 }
390 *i as usize
391 }
392 _ => panic!(
393 "roll: expected Int depth on top of stack, got {:?}",
394 depth_value
395 ),
396 };
397
398 let (stack, _) = unsafe { pop(stack) };
400
401 if n == 0 {
403 return stack;
405 }
406 if n == 1 {
407 return unsafe { patch_seq_swap(stack) };
409 }
410 if n == 2 {
411 return unsafe { patch_seq_rot(stack) };
413 }
414
415 let mut count = 0;
420 let mut current = stack;
421 while !current.is_null() && count <= n {
422 count += 1;
423 current = unsafe { (*current).next };
424 }
425
426 if count < n + 1 {
427 panic!(
428 "roll: cannot rotate {} items - stack has only {} value{}",
429 n + 1,
430 count,
431 if count == 1 { "" } else { "s" }
432 );
433 }
434
435 let mut items = Vec::with_capacity(n + 1);
437 let mut current_stack = stack;
438 for _ in 0..=n {
439 let (rest, val) = unsafe { pop(current_stack) };
440 items.push(val);
441 current_stack = rest;
442 }
443
444 let top_item = items.swap_remove(n);
452
453 for val in items.into_iter().rev() {
456 current_stack = unsafe { push(current_stack, val) };
457 }
458 current_stack = unsafe { push(current_stack, top_item) };
460
461 current_stack
462}
463
464pub unsafe fn clone_stack(stack: Stack) -> Stack {
476 if stack.is_null() {
477 return std::ptr::null_mut();
478 }
479
480 let mut values = Vec::new();
482 let mut current = stack;
483 while !current.is_null() {
484 values.push(unsafe { (*current).value.clone() });
485 current = unsafe { (*current).next };
486 }
487
488 let mut new_stack: Stack = std::ptr::null_mut();
491 for value in values.into_iter().rev() {
492 let node = Box::new(StackNode {
493 value,
494 next: new_stack,
495 });
496 new_stack = Box::into_raw(node);
497 }
498
499 new_stack
500}
501
502pub use patch_seq_2dup as two_dup;
504pub use patch_seq_3drop as three_drop;
505pub use patch_seq_drop_op as drop_op;
506pub use patch_seq_dup as dup;
507pub use patch_seq_nip as nip;
508pub use patch_seq_over as over;
509pub use patch_seq_pick_op as pick_op;
510pub use patch_seq_push_value as push_value;
511pub use patch_seq_roll as roll;
512pub use patch_seq_rot as rot;
513pub use patch_seq_swap as swap;
514pub use patch_seq_tuck as tuck;
515
516#[cfg(test)]
517mod tests {
518 use super::*;
519 use std::sync::Arc;
520
521 fn make_stack(values: &[i64]) -> Stack {
523 unsafe {
524 let mut stack = std::ptr::null_mut();
525 for &val in values {
526 stack = push(stack, Value::Int(val));
527 }
528 stack
529 }
530 }
531
532 fn drain_stack(mut stack: Stack) -> Vec<Value> {
534 unsafe {
535 let mut values = Vec::new();
536 while !is_empty(stack) {
537 let (rest, val) = pop(stack);
538 stack = rest;
539 values.push(val);
540 }
541 values
542 }
543 }
544
545 fn assert_stack_ints(stack: Stack, expected: &[i64]) {
547 let values = drain_stack(stack);
548 let ints: Vec<i64> = values
549 .into_iter()
550 .map(|v| match v {
551 Value::Int(n) => n,
552 _ => panic!("Expected Int, got {:?}", v),
553 })
554 .collect();
555 assert_eq!(ints, expected);
556 }
557
558 #[test]
559 fn test_push_pop() {
560 unsafe {
561 let stack = std::ptr::null_mut();
562 assert!(is_empty(stack));
563
564 let stack = push(stack, Value::Int(42));
565 assert!(!is_empty(stack));
566
567 let (stack, value) = pop(stack);
568 assert_eq!(value, Value::Int(42));
569 assert!(is_empty(stack));
570 }
571 }
572
573 #[test]
574 fn test_multiple_values() {
575 unsafe {
576 let mut stack = std::ptr::null_mut();
577
578 stack = push(stack, Value::Int(1));
579 stack = push(stack, Value::Int(2));
580 stack = push(stack, Value::Int(3));
581
582 let (stack, val) = pop(stack);
583 assert_eq!(val, Value::Int(3));
584
585 let (stack, val) = pop(stack);
586 assert_eq!(val, Value::Int(2));
587
588 let (stack, val) = pop(stack);
589 assert_eq!(val, Value::Int(1));
590
591 assert!(is_empty(stack));
592 }
593 }
594
595 #[test]
596 fn test_peek() {
597 unsafe {
598 let stack = push(std::ptr::null_mut(), Value::Int(42));
599 let peeked = peek(stack);
600 assert_eq!(*peeked, Value::Int(42));
601
602 let (stack, value) = pop(stack);
604 assert_eq!(value, Value::Int(42));
605 assert!(is_empty(stack));
606 }
607 }
608
609 #[test]
610 fn test_dup() {
611 unsafe {
612 let stack = push(std::ptr::null_mut(), Value::Int(42));
613 let stack = dup(stack);
614
615 let (stack, val1) = pop(stack);
617 assert_eq!(val1, Value::Int(42));
618
619 let (stack, val2) = pop(stack);
620 assert_eq!(val2, Value::Int(42));
621
622 assert!(is_empty(stack));
623 }
624 }
625
626 #[test]
627 fn test_drop() {
628 unsafe {
629 let mut stack = std::ptr::null_mut();
630 stack = push(stack, Value::Int(1));
631 stack = push(stack, Value::Int(2));
632 stack = push(stack, Value::Int(3));
633
634 stack = drop(stack);
636
637 let (stack, val) = pop(stack);
639 assert_eq!(val, Value::Int(2));
640
641 let (stack, val) = pop(stack);
642 assert_eq!(val, Value::Int(1));
643
644 assert!(is_empty(stack));
645 }
646 }
647
648 #[test]
649 fn test_swap() {
650 unsafe {
651 let mut stack = std::ptr::null_mut();
652 stack = push(stack, Value::Int(1));
653 stack = push(stack, Value::Int(2));
654
655 stack = swap(stack);
657
658 let (stack, val) = pop(stack);
659 assert_eq!(val, Value::Int(1));
660
661 let (stack, val) = pop(stack);
662 assert_eq!(val, Value::Int(2));
663
664 assert!(is_empty(stack));
665 }
666 }
667
668 #[test]
669 fn test_composition() {
670 unsafe {
679 let mut stack = make_stack(&[1, 2, 3]);
680
681 stack = swap(stack);
682 stack = drop(stack);
683 stack = dup(stack);
684
685 assert_stack_ints(stack, &[3, 3, 1]);
686 }
687 }
688
689 #[test]
690 fn test_over() {
691 unsafe {
693 let mut stack = std::ptr::null_mut();
694 stack = push(stack, Value::Int(1));
695 stack = push(stack, Value::Int(2));
696
697 stack = over(stack); 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 let (stack, val) = pop(stack);
706 assert_eq!(val, Value::Int(1));
707
708 assert!(is_empty(stack));
709 }
710 }
711
712 #[test]
713 fn test_rot() {
714 unsafe {
716 let mut stack = std::ptr::null_mut();
717 stack = push(stack, Value::Int(1));
718 stack = push(stack, Value::Int(2));
719 stack = push(stack, Value::Int(3));
720
721 stack = rot(stack); let (stack, val) = pop(stack);
724 assert_eq!(val, Value::Int(1));
725
726 let (stack, val) = pop(stack);
727 assert_eq!(val, Value::Int(3));
728
729 let (stack, val) = pop(stack);
730 assert_eq!(val, Value::Int(2));
731
732 assert!(is_empty(stack));
733 }
734 }
735
736 #[test]
737 fn test_nip() {
738 unsafe {
740 let mut stack = std::ptr::null_mut();
741 stack = push(stack, Value::Int(1));
742 stack = push(stack, Value::Int(2));
743
744 stack = nip(stack); let (stack, val) = pop(stack);
747 assert_eq!(val, Value::Int(2));
748
749 assert!(is_empty(stack));
750 }
751 }
752
753 #[test]
754 fn test_tuck() {
755 unsafe {
757 let mut stack = std::ptr::null_mut();
758 stack = push(stack, Value::Int(1));
759 stack = push(stack, Value::Int(2));
760
761 stack = tuck(stack); let (stack, val) = pop(stack);
764 assert_eq!(val, Value::Int(2));
765
766 let (stack, val) = pop(stack);
767 assert_eq!(val, Value::Int(1));
768
769 let (stack, val) = pop(stack);
770 assert_eq!(val, Value::Int(2));
771
772 assert!(is_empty(stack));
773 }
774 }
775
776 #[test]
777 fn test_critical_shuffle_pattern() {
778 unsafe {
792 let mut stack = make_stack(&[1, 2, 3, 4, 5]);
793
794 stack = rot(stack);
798 stack = swap(stack);
804 stack = rot(stack);
810 stack = rot(stack);
816 stack = swap(stack);
822 assert_stack_ints(stack, &[4, 3, 5, 2, 1]);
830 }
831 }
832
833 #[test]
834 fn test_pick_0_is_dup() {
835 unsafe {
837 let mut stack = std::ptr::null_mut();
838 stack = push(stack, Value::Int(42));
839
840 stack = pick(stack, 0);
841
842 let (stack, val) = pop(stack);
843 assert_eq!(val, Value::Int(42));
844
845 let (stack, val) = pop(stack);
846 assert_eq!(val, Value::Int(42));
847
848 assert!(is_empty(stack));
849 }
850 }
851
852 #[test]
853 fn test_pick_1_is_over() {
854 unsafe {
856 let mut stack = std::ptr::null_mut();
857 stack = push(stack, Value::Int(1));
858 stack = push(stack, Value::Int(2));
859
860 stack = pick(stack, 1);
861
862 let (stack, val) = pop(stack);
863 assert_eq!(val, Value::Int(1));
864
865 let (stack, val) = pop(stack);
866 assert_eq!(val, Value::Int(2));
867
868 let (stack, val) = pop(stack);
869 assert_eq!(val, Value::Int(1));
870
871 assert!(is_empty(stack));
872 }
873 }
874
875 #[test]
876 fn test_pick_deep() {
877 unsafe {
879 let mut stack = std::ptr::null_mut();
880 stack = push(stack, Value::Int(1));
881 stack = push(stack, Value::Int(2));
882 stack = push(stack, Value::Int(3));
883 stack = push(stack, Value::Int(4));
884 stack = push(stack, Value::Int(5));
885
886 stack = pick(stack, 3); let (stack, val) = pop(stack);
892 assert_eq!(val, Value::Int(2));
893
894 let (stack, val) = pop(stack);
895 assert_eq!(val, Value::Int(5));
896
897 let (stack, val) = pop(stack);
898 assert_eq!(val, Value::Int(4));
899
900 let (stack, val) = pop(stack);
901 assert_eq!(val, Value::Int(3));
902
903 let (stack, val) = pop(stack);
904 assert_eq!(val, Value::Int(2));
905
906 let (stack, val) = pop(stack);
907 assert_eq!(val, Value::Int(1));
908
909 assert!(is_empty(stack));
910 }
911 }
912
913 #[test]
914 fn test_multifield_variant_survives_shuffle() {
915 use crate::value::VariantData;
919
920 unsafe {
921 let nil = Value::Variant(Arc::new(VariantData::new(0, vec![])));
924 let cons = Value::Variant(Arc::new(VariantData::new(
925 1,
926 vec![Value::Int(42), nil.clone()],
927 )));
928
929 let mut stack = std::ptr::null_mut();
931 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;
946 while !is_empty(stack) {
947 let (rest, val) = pop(stack);
948 stack = rest;
949 if matches!(val, Value::Variant(_)) {
950 found_variant = Some(val);
951 }
952 }
953
954 assert!(found_variant.is_some(), "Variant was lost during shuffle!");
956
957 if let Some(Value::Variant(variant_data)) = found_variant {
958 assert_eq!(variant_data.tag, 1, "Variant tag corrupted!");
959 assert_eq!(
960 variant_data.fields.len(),
961 2,
962 "Variant field count corrupted!"
963 );
964 assert_eq!(
965 variant_data.fields[0],
966 Value::Int(42),
967 "First field corrupted!"
968 );
969
970 if let Value::Variant(nil_data) = &variant_data.fields[1] {
972 assert_eq!(nil_data.tag, 0, "Nested variant tag corrupted!");
973 assert_eq!(nil_data.fields.len(), 0, "Nested variant should be empty!");
974 } else {
975 panic!("Second field should be a Variant!");
976 }
977 }
978 }
979 }
980
981 #[test]
982 fn test_arbitrary_depth_operations() {
983 unsafe {
986 let mut stack = std::ptr::null_mut();
987
988 for i in 0..100 {
990 stack = push(stack, Value::Int(i));
991 }
992
993 stack = dup(stack); stack = swap(stack); stack = over(stack); stack = rot(stack); stack = drop(stack); stack = pick(stack, 50); let mut count = 0;
1005 while !is_empty(stack) {
1006 let (rest, _val) = pop(stack);
1007 stack = rest;
1008 count += 1;
1009 }
1010
1011 assert_eq!(count, 102);
1013 }
1014 }
1015
1016 #[test]
1017 fn test_operation_composition_completeness() {
1018 unsafe {
1021 let mut stack = std::ptr::null_mut();
1022
1023 for i in 1..=10 {
1025 stack = push(stack, Value::Int(i));
1026 }
1027
1028 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;
1042 let mut current = stack;
1043 while !current.is_null() {
1044 depth += 1;
1045 current = (*current).next;
1046 }
1047
1048 assert!(depth > 0, "Stack should not be empty after operations");
1049 }
1050 }
1051
1052 #[test]
1053 fn test_pick_at_arbitrary_depths() {
1054 unsafe {
1057 let mut stack = std::ptr::null_mut();
1058
1059 for i in 0..50 {
1061 stack = push(stack, Value::Int(i * 10));
1062 }
1063
1064 stack = pick(stack, 0); let (mut stack, val) = pop(stack);
1070 assert_eq!(val, Value::Int(490));
1071
1072 stack = pick(stack, 10); let (mut stack, val) = pop(stack);
1074 assert_eq!(val, Value::Int(390)); stack = pick(stack, 40); let (stack, val) = pop(stack);
1078 assert_eq!(val, Value::Int(90)); let mut count = 0;
1082 let mut current = stack;
1083 while !current.is_null() {
1084 count += 1;
1085 current = (*current).next;
1086 }
1087
1088 assert_eq!(count, 50, "Stack depth should be unchanged");
1089 }
1090 }
1091
1092 #[test]
1093 fn test_pick_op_equivalence_to_dup() {
1094 unsafe {
1096 let mut stack = std::ptr::null_mut();
1097 stack = push(stack, Value::Int(42));
1098 stack = push(stack, Value::Int(0)); stack = pick_op(stack);
1101
1102 let (stack, val1) = pop(stack);
1104 assert_eq!(val1, Value::Int(42));
1105 let (stack, val2) = pop(stack);
1106 assert_eq!(val2, Value::Int(42));
1107 assert!(stack.is_null());
1108 }
1109 }
1110
1111 #[test]
1112 fn test_pick_op_equivalence_to_over() {
1113 unsafe {
1115 let mut stack = std::ptr::null_mut();
1116 stack = push(stack, Value::Int(10));
1117 stack = push(stack, Value::Int(20));
1118 stack = push(stack, Value::Int(1)); stack = pick_op(stack);
1121
1122 let (stack, val1) = pop(stack);
1124 assert_eq!(val1, Value::Int(10));
1125 let (stack, val2) = pop(stack);
1126 assert_eq!(val2, Value::Int(20));
1127 let (stack, val3) = pop(stack);
1128 assert_eq!(val3, Value::Int(10));
1129 assert!(stack.is_null());
1130 }
1131 }
1132
1133 #[test]
1134 fn test_pick_op_deep_access() {
1135 unsafe {
1137 let mut stack = std::ptr::null_mut();
1138 for i in 0..10 {
1139 stack = push(stack, Value::Int(i));
1140 }
1141 stack = push(stack, Value::Int(5)); stack = pick_op(stack);
1144
1145 let (stack, val) = pop(stack);
1147 assert_eq!(val, Value::Int(4));
1148
1149 let mut count = 0;
1151 let mut current = stack;
1152 while !current.is_null() {
1153 count += 1;
1154 current = (*current).next;
1155 }
1156 assert_eq!(count, 10);
1157 }
1158 }
1159
1160 #[test]
1166 fn test_roll_0_is_noop() {
1167 unsafe {
1169 let mut stack = std::ptr::null_mut();
1170 stack = push(stack, Value::Int(42));
1171 stack = push(stack, Value::Int(0)); stack = roll(stack);
1174
1175 let (stack, val) = pop(stack);
1176 assert_eq!(val, Value::Int(42));
1177 assert!(stack.is_null());
1178 }
1179 }
1180
1181 #[test]
1182 fn test_roll_1_is_swap() {
1183 unsafe {
1185 let mut stack = std::ptr::null_mut();
1186 stack = push(stack, Value::Int(1));
1187 stack = push(stack, Value::Int(2));
1188 stack = push(stack, Value::Int(1)); stack = roll(stack);
1191
1192 let (stack, val1) = pop(stack);
1194 assert_eq!(val1, Value::Int(1));
1195 let (stack, val2) = pop(stack);
1196 assert_eq!(val2, Value::Int(2));
1197 assert!(stack.is_null());
1198 }
1199 }
1200
1201 #[test]
1202 fn test_roll_2_is_rot() {
1203 unsafe {
1205 let mut stack = std::ptr::null_mut();
1206 stack = push(stack, Value::Int(1));
1207 stack = push(stack, Value::Int(2));
1208 stack = push(stack, Value::Int(3));
1209 stack = push(stack, Value::Int(2)); stack = roll(stack);
1212
1213 let (stack, val1) = pop(stack);
1215 assert_eq!(val1, Value::Int(1));
1216 let (stack, val2) = pop(stack);
1217 assert_eq!(val2, Value::Int(3));
1218 let (stack, val3) = pop(stack);
1219 assert_eq!(val3, Value::Int(2));
1220 assert!(stack.is_null());
1221 }
1222 }
1223
1224 #[test]
1225 fn test_roll_3_rotates_4_items() {
1226 unsafe {
1228 let mut stack = std::ptr::null_mut();
1229 stack = push(stack, Value::Int(1)); stack = push(stack, Value::Int(2));
1231 stack = push(stack, Value::Int(3));
1232 stack = push(stack, Value::Int(4)); stack = push(stack, Value::Int(3)); stack = roll(stack);
1236
1237 let (stack, val1) = pop(stack);
1239 assert_eq!(val1, Value::Int(1)); let (stack, val2) = pop(stack);
1241 assert_eq!(val2, Value::Int(4));
1242 let (stack, val3) = pop(stack);
1243 assert_eq!(val3, Value::Int(3));
1244 let (stack, val4) = pop(stack);
1245 assert_eq!(val4, Value::Int(2));
1246 assert!(stack.is_null());
1247 }
1248 }
1249
1250 #[test]
1251 fn test_roll_deep() {
1252 unsafe {
1254 let mut stack = std::ptr::null_mut();
1255 for i in 0..10 {
1256 stack = push(stack, Value::Int(i));
1257 }
1258 stack = push(stack, Value::Int(5)); stack = roll(stack);
1262
1263 let (stack, val) = pop(stack);
1266 assert_eq!(val, Value::Int(4)); let (stack, val) = pop(stack);
1270 assert_eq!(val, Value::Int(9));
1271 let (stack, val) = pop(stack);
1272 assert_eq!(val, Value::Int(8));
1273 let (stack, val) = pop(stack);
1274 assert_eq!(val, Value::Int(7));
1275 let (stack, val) = pop(stack);
1276 assert_eq!(val, Value::Int(6));
1277 let (stack, val) = pop(stack);
1278 assert_eq!(val, Value::Int(5));
1279 let (stack, val) = pop(stack);
1281 assert_eq!(val, Value::Int(3));
1282 let (stack, val) = pop(stack);
1283 assert_eq!(val, Value::Int(2));
1284 let (stack, val) = pop(stack);
1285 assert_eq!(val, Value::Int(1));
1286 let (stack, val) = pop(stack);
1287 assert_eq!(val, Value::Int(0));
1288 assert!(stack.is_null());
1289 }
1290 }
1291
1292 #[test]
1293 fn test_roll_with_extra_stack() {
1294 unsafe {
1296 let mut stack = std::ptr::null_mut();
1297 stack = push(stack, Value::Int(100)); stack = push(stack, Value::Int(1));
1299 stack = push(stack, Value::Int(2));
1300 stack = push(stack, Value::Int(3));
1301 stack = push(stack, Value::Int(4));
1302 stack = push(stack, Value::Int(3)); stack = roll(stack);
1305
1306 let (stack, val1) = pop(stack);
1308 assert_eq!(val1, Value::Int(1));
1309 let (stack, val2) = pop(stack);
1310 assert_eq!(val2, Value::Int(4));
1311 let (stack, val3) = pop(stack);
1312 assert_eq!(val3, Value::Int(3));
1313 let (stack, val4) = pop(stack);
1314 assert_eq!(val4, Value::Int(2));
1315 let (stack, val5) = pop(stack);
1316 assert_eq!(val5, Value::Int(100)); assert!(stack.is_null());
1318 }
1319 }
1320
1321 #[test]
1322 fn test_operations_preserve_stack_integrity() {
1323 unsafe {
1326 let mut stack = std::ptr::null_mut();
1327
1328 for i in 0..20 {
1329 stack = push(stack, Value::Int(i));
1330 }
1331
1332 stack = swap(stack);
1334 stack = rot(stack);
1335 stack = swap(stack);
1336 stack = rot(stack);
1337 stack = over(stack);
1338 stack = tuck(stack);
1339
1340 let mut visited = std::collections::HashSet::new();
1344 let mut current = stack;
1345 let mut count = 0;
1346
1347 while !current.is_null() {
1348 assert!(
1350 visited.insert(current as usize),
1351 "Detected cycle in stack - next pointer corruption!"
1352 );
1353
1354 count += 1;
1355 current = (*current).next;
1356
1357 assert!(
1359 count < 1000,
1360 "Stack walk exceeded reasonable depth - likely corrupted"
1361 );
1362 }
1363
1364 assert!(count > 0, "Stack should have elements");
1365 }
1366 }
1367
1368 #[test]
1369 fn test_nested_variants_with_deep_stacks() {
1370 use crate::value::VariantData;
1373
1374 unsafe {
1375 let nil = Value::Variant(Arc::new(VariantData::new(0, vec![])));
1377 let cons3 = Value::Variant(Arc::new(VariantData::new(1, vec![Value::Int(3), nil])));
1378 let cons2 = Value::Variant(Arc::new(VariantData::new(1, vec![Value::Int(2), cons3])));
1379 let cons1 = Value::Variant(Arc::new(VariantData::new(1, vec![Value::Int(1), cons2])));
1380
1381 let mut stack = std::ptr::null_mut();
1383 for i in 0..30 {
1384 stack = push(stack, Value::Int(i));
1385 }
1386 stack = push(stack, cons1.clone());
1387 for i in 30..60 {
1388 stack = push(stack, Value::Int(i));
1389 }
1390
1391 for _ in 0..10 {
1393 stack = rot(stack);
1394 stack = swap(stack);
1395 stack = over(stack);
1396 stack = drop(stack);
1397 }
1398
1399 let mut found_variant = None;
1401 while !is_empty(stack) {
1402 let (rest, val) = pop(stack);
1403 stack = rest;
1404 if let Value::Variant(ref vdata) = val
1405 && vdata.tag == 1
1406 && vdata.fields.len() == 2
1407 && let Value::Int(1) = vdata.fields[0]
1408 {
1409 found_variant = Some(val);
1410 break;
1411 }
1412 }
1413
1414 assert!(
1415 found_variant.is_some(),
1416 "Nested variant lost during deep stack operations"
1417 );
1418 }
1419 }
1420}