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 fn is_empty(stack: Stack) -> bool {
66 stack.is_null()
67}
68
69pub unsafe fn peek<'a>(stack: Stack) -> &'a Value {
75 assert!(!stack.is_null(), "peek: stack is empty");
76 unsafe { &(*stack).value }
77}
78
79#[unsafe(no_mangle)]
84pub unsafe extern "C" fn patch_seq_dup(stack: Stack) -> Stack {
85 assert!(!stack.is_null(), "dup: stack is empty");
86 let value = unsafe { (*stack).value.clone() };
91 unsafe { push(stack, value) }
92}
93
94pub unsafe fn drop(stack: Stack) -> Stack {
99 assert!(!stack.is_null(), "drop: stack is empty");
100 let (rest, _) = unsafe { pop(stack) };
101 rest
102}
103
104#[unsafe(no_mangle)]
111pub unsafe extern "C" fn patch_seq_drop_op(stack: Stack) -> Stack {
112 unsafe { drop(stack) }
113}
114
115#[allow(improper_ctypes_definitions)]
123#[unsafe(no_mangle)]
124pub unsafe extern "C" fn patch_seq_push_value(stack: Stack, value: Value) -> Stack {
125 unsafe { push(stack, value) }
126}
127
128#[unsafe(no_mangle)]
133pub unsafe extern "C" fn patch_seq_swap(stack: Stack) -> Stack {
134 assert!(!stack.is_null(), "swap: stack is empty");
135 let (rest, b) = unsafe { pop(stack) };
136 assert!(!rest.is_null(), "swap: stack has only one value");
137 let (rest, a) = unsafe { pop(rest) };
138 let stack = unsafe { push(rest, b) };
139 unsafe { push(stack, a) }
140}
141
142#[unsafe(no_mangle)]
147pub unsafe extern "C" fn patch_seq_over(stack: Stack) -> Stack {
148 assert!(!stack.is_null(), "over: stack is empty");
149 let (rest, b) = unsafe { pop(stack) };
150 assert!(!rest.is_null(), "over: stack has only one value");
151 let a = unsafe { (*rest).value.clone() };
152 let stack = unsafe { push(rest, b) };
153 unsafe { push(stack, a) }
154}
155
156#[unsafe(no_mangle)]
161pub unsafe extern "C" fn patch_seq_rot(stack: Stack) -> Stack {
162 assert!(!stack.is_null(), "rot: stack is empty");
163 let (rest, c) = unsafe { pop(stack) };
164 assert!(!rest.is_null(), "rot: stack has only one value");
165 let (rest, b) = unsafe { pop(rest) };
166 assert!(!rest.is_null(), "rot: stack has only two values");
167 let (rest, a) = unsafe { pop(rest) };
168 let stack = unsafe { push(rest, b) };
169 let stack = unsafe { push(stack, c) };
170 unsafe { push(stack, a) }
171}
172
173#[unsafe(no_mangle)]
178pub unsafe extern "C" fn patch_seq_nip(stack: Stack) -> Stack {
179 assert!(!stack.is_null(), "nip: stack is empty");
180 let (rest, b) = unsafe { pop(stack) };
181 assert!(!rest.is_null(), "nip: stack has only one value");
182 let (rest, _a) = unsafe { pop(rest) };
183 unsafe { push(rest, b) }
184}
185
186#[unsafe(no_mangle)]
191pub unsafe extern "C" fn patch_seq_tuck(stack: Stack) -> Stack {
192 assert!(!stack.is_null(), "tuck: stack is empty");
193 let (rest, b) = unsafe { pop(stack) };
194 assert!(!rest.is_null(), "tuck: stack has only one value");
195 let (rest, a) = unsafe { pop(rest) };
196 let stack = unsafe { push(rest, b.clone()) };
197 let stack = unsafe { push(stack, a) };
198 unsafe { push(stack, b) }
199}
200
201pub unsafe fn pick(stack: Stack, n: usize) -> Stack {
212 assert!(!stack.is_null(), "pick: stack is empty");
213
214 let mut current = stack;
216 for i in 0..n {
217 assert!(
218 !current.is_null(),
219 "pick: stack has only {} values, need at least {}",
220 i + 1,
221 n + 1
222 );
223 current = unsafe { (*current).next };
224 }
225
226 assert!(
227 !current.is_null(),
228 "pick: stack has only {} values, need at least {}",
229 n,
230 n + 1
231 );
232
233 let value = unsafe { (*current).value.clone() };
235
236 unsafe { push(stack, value) }
238}
239
240#[unsafe(no_mangle)]
272pub unsafe extern "C" fn patch_seq_pick_op(stack: Stack) -> Stack {
273 use crate::value::Value;
274
275 assert!(!stack.is_null(), "pick: stack is empty");
276
277 let depth_value = unsafe { &(*stack).value };
279 let n = match depth_value {
280 Value::Int(i) => {
281 if *i < 0 {
282 panic!("pick: depth must be non-negative, got {}", i);
283 }
284 *i as usize
285 }
286 _ => panic!(
287 "pick: expected Int depth on top of stack, got {:?}",
288 depth_value
289 ),
290 };
291
292 let mut count = 0;
294 let mut current = unsafe { (*stack).next };
295 while !current.is_null() {
296 count += 1;
297 current = unsafe { (*current).next };
298 }
299
300 if count < n + 1 {
305 panic!(
306 "pick: cannot access depth {} - stack has only {} value{} (need at least {})",
307 n,
308 count,
309 if count == 1 { "" } else { "s" },
310 n + 1
311 );
312 }
313
314 let (stack, _) = unsafe { pop(stack) };
316 unsafe { pick(stack, n) }
317}
318
319#[unsafe(no_mangle)]
333pub unsafe extern "C" fn patch_seq_roll(stack: Stack) -> Stack {
334 use crate::value::Value;
335
336 assert!(!stack.is_null(), "roll: stack is empty");
337
338 let depth_value = unsafe { &(*stack).value };
340 let n = match depth_value {
341 Value::Int(i) => {
342 if *i < 0 {
343 panic!("roll: depth must be non-negative, got {}", i);
344 }
345 *i as usize
346 }
347 _ => panic!(
348 "roll: expected Int depth on top of stack, got {:?}",
349 depth_value
350 ),
351 };
352
353 let (stack, _) = unsafe { pop(stack) };
355
356 if n == 0 {
358 return stack;
360 }
361 if n == 1 {
362 return unsafe { patch_seq_swap(stack) };
364 }
365 if n == 2 {
366 return unsafe { patch_seq_rot(stack) };
368 }
369
370 let mut count = 0;
375 let mut current = stack;
376 while !current.is_null() && count <= n {
377 count += 1;
378 current = unsafe { (*current).next };
379 }
380
381 if count < n + 1 {
382 panic!(
383 "roll: cannot rotate {} items - stack has only {} value{}",
384 n + 1,
385 count,
386 if count == 1 { "" } else { "s" }
387 );
388 }
389
390 let mut items = Vec::with_capacity(n + 1);
392 let mut current_stack = stack;
393 for _ in 0..=n {
394 let (rest, val) = unsafe { pop(current_stack) };
395 items.push(val);
396 current_stack = rest;
397 }
398
399 let top_item = items.swap_remove(n);
407
408 for val in items.into_iter().rev() {
411 current_stack = unsafe { push(current_stack, val) };
412 }
413 current_stack = unsafe { push(current_stack, top_item) };
415
416 current_stack
417}
418
419pub use patch_seq_drop_op as drop_op;
421pub use patch_seq_dup as dup;
422pub use patch_seq_nip as nip;
423pub use patch_seq_over as over;
424pub use patch_seq_pick_op as pick_op;
425pub use patch_seq_push_value as push_value;
426pub use patch_seq_roll as roll;
427pub use patch_seq_rot as rot;
428pub use patch_seq_swap as swap;
429pub use patch_seq_tuck as tuck;
430
431#[cfg(test)]
432mod tests {
433 use super::*;
434
435 fn make_stack(values: &[i64]) -> Stack {
437 unsafe {
438 let mut stack = std::ptr::null_mut();
439 for &val in values {
440 stack = push(stack, Value::Int(val));
441 }
442 stack
443 }
444 }
445
446 fn drain_stack(mut stack: Stack) -> Vec<Value> {
448 unsafe {
449 let mut values = Vec::new();
450 while !is_empty(stack) {
451 let (rest, val) = pop(stack);
452 stack = rest;
453 values.push(val);
454 }
455 values
456 }
457 }
458
459 fn assert_stack_ints(stack: Stack, expected: &[i64]) {
461 let values = drain_stack(stack);
462 let ints: Vec<i64> = values
463 .into_iter()
464 .map(|v| match v {
465 Value::Int(n) => n,
466 _ => panic!("Expected Int, got {:?}", v),
467 })
468 .collect();
469 assert_eq!(ints, expected);
470 }
471
472 #[test]
473 fn test_push_pop() {
474 unsafe {
475 let stack = std::ptr::null_mut();
476 assert!(is_empty(stack));
477
478 let stack = push(stack, Value::Int(42));
479 assert!(!is_empty(stack));
480
481 let (stack, value) = pop(stack);
482 assert_eq!(value, Value::Int(42));
483 assert!(is_empty(stack));
484 }
485 }
486
487 #[test]
488 fn test_multiple_values() {
489 unsafe {
490 let mut stack = std::ptr::null_mut();
491
492 stack = push(stack, Value::Int(1));
493 stack = push(stack, Value::Int(2));
494 stack = push(stack, Value::Int(3));
495
496 let (stack, val) = pop(stack);
497 assert_eq!(val, Value::Int(3));
498
499 let (stack, val) = pop(stack);
500 assert_eq!(val, Value::Int(2));
501
502 let (stack, val) = pop(stack);
503 assert_eq!(val, Value::Int(1));
504
505 assert!(is_empty(stack));
506 }
507 }
508
509 #[test]
510 fn test_peek() {
511 unsafe {
512 let stack = push(std::ptr::null_mut(), Value::Int(42));
513 let peeked = peek(stack);
514 assert_eq!(*peeked, Value::Int(42));
515
516 let (stack, value) = pop(stack);
518 assert_eq!(value, Value::Int(42));
519 assert!(is_empty(stack));
520 }
521 }
522
523 #[test]
524 fn test_dup() {
525 unsafe {
526 let stack = push(std::ptr::null_mut(), Value::Int(42));
527 let stack = dup(stack);
528
529 let (stack, val1) = pop(stack);
531 assert_eq!(val1, Value::Int(42));
532
533 let (stack, val2) = pop(stack);
534 assert_eq!(val2, Value::Int(42));
535
536 assert!(is_empty(stack));
537 }
538 }
539
540 #[test]
541 fn test_drop() {
542 unsafe {
543 let mut stack = std::ptr::null_mut();
544 stack = push(stack, Value::Int(1));
545 stack = push(stack, Value::Int(2));
546 stack = push(stack, Value::Int(3));
547
548 stack = drop(stack);
550
551 let (stack, val) = pop(stack);
553 assert_eq!(val, Value::Int(2));
554
555 let (stack, val) = pop(stack);
556 assert_eq!(val, Value::Int(1));
557
558 assert!(is_empty(stack));
559 }
560 }
561
562 #[test]
563 fn test_swap() {
564 unsafe {
565 let mut stack = std::ptr::null_mut();
566 stack = push(stack, Value::Int(1));
567 stack = push(stack, Value::Int(2));
568
569 stack = swap(stack);
571
572 let (stack, val) = pop(stack);
573 assert_eq!(val, Value::Int(1));
574
575 let (stack, val) = pop(stack);
576 assert_eq!(val, Value::Int(2));
577
578 assert!(is_empty(stack));
579 }
580 }
581
582 #[test]
583 fn test_composition() {
584 unsafe {
593 let mut stack = make_stack(&[1, 2, 3]);
594
595 stack = swap(stack);
596 stack = drop(stack);
597 stack = dup(stack);
598
599 assert_stack_ints(stack, &[3, 3, 1]);
600 }
601 }
602
603 #[test]
604 fn test_over() {
605 unsafe {
607 let mut stack = std::ptr::null_mut();
608 stack = push(stack, Value::Int(1));
609 stack = push(stack, Value::Int(2));
610
611 stack = over(stack); let (stack, val) = pop(stack);
614 assert_eq!(val, Value::Int(1));
615
616 let (stack, val) = pop(stack);
617 assert_eq!(val, Value::Int(2));
618
619 let (stack, val) = pop(stack);
620 assert_eq!(val, Value::Int(1));
621
622 assert!(is_empty(stack));
623 }
624 }
625
626 #[test]
627 fn test_rot() {
628 unsafe {
630 let mut stack = std::ptr::null_mut();
631 stack = push(stack, Value::Int(1));
632 stack = push(stack, Value::Int(2));
633 stack = push(stack, Value::Int(3));
634
635 stack = rot(stack); let (stack, val) = pop(stack);
638 assert_eq!(val, Value::Int(1));
639
640 let (stack, val) = pop(stack);
641 assert_eq!(val, Value::Int(3));
642
643 let (stack, val) = pop(stack);
644 assert_eq!(val, Value::Int(2));
645
646 assert!(is_empty(stack));
647 }
648 }
649
650 #[test]
651 fn test_nip() {
652 unsafe {
654 let mut stack = std::ptr::null_mut();
655 stack = push(stack, Value::Int(1));
656 stack = push(stack, Value::Int(2));
657
658 stack = nip(stack); let (stack, val) = pop(stack);
661 assert_eq!(val, Value::Int(2));
662
663 assert!(is_empty(stack));
664 }
665 }
666
667 #[test]
668 fn test_tuck() {
669 unsafe {
671 let mut stack = std::ptr::null_mut();
672 stack = push(stack, Value::Int(1));
673 stack = push(stack, Value::Int(2));
674
675 stack = tuck(stack); let (stack, val) = pop(stack);
678 assert_eq!(val, Value::Int(2));
679
680 let (stack, val) = pop(stack);
681 assert_eq!(val, Value::Int(1));
682
683 let (stack, val) = pop(stack);
684 assert_eq!(val, Value::Int(2));
685
686 assert!(is_empty(stack));
687 }
688 }
689
690 #[test]
691 fn test_critical_shuffle_pattern() {
692 unsafe {
706 let mut stack = make_stack(&[1, 2, 3, 4, 5]);
707
708 stack = rot(stack);
712 stack = swap(stack);
718 stack = rot(stack);
724 stack = rot(stack);
730 stack = swap(stack);
736 assert_stack_ints(stack, &[4, 3, 5, 2, 1]);
744 }
745 }
746
747 #[test]
748 fn test_pick_0_is_dup() {
749 unsafe {
751 let mut stack = std::ptr::null_mut();
752 stack = push(stack, Value::Int(42));
753
754 stack = pick(stack, 0);
755
756 let (stack, val) = pop(stack);
757 assert_eq!(val, Value::Int(42));
758
759 let (stack, val) = pop(stack);
760 assert_eq!(val, Value::Int(42));
761
762 assert!(is_empty(stack));
763 }
764 }
765
766 #[test]
767 fn test_pick_1_is_over() {
768 unsafe {
770 let mut stack = std::ptr::null_mut();
771 stack = push(stack, Value::Int(1));
772 stack = push(stack, Value::Int(2));
773
774 stack = pick(stack, 1);
775
776 let (stack, val) = pop(stack);
777 assert_eq!(val, Value::Int(1));
778
779 let (stack, val) = pop(stack);
780 assert_eq!(val, Value::Int(2));
781
782 let (stack, val) = pop(stack);
783 assert_eq!(val, Value::Int(1));
784
785 assert!(is_empty(stack));
786 }
787 }
788
789 #[test]
790 fn test_pick_deep() {
791 unsafe {
793 let mut stack = std::ptr::null_mut();
794 stack = push(stack, Value::Int(1));
795 stack = push(stack, Value::Int(2));
796 stack = push(stack, Value::Int(3));
797 stack = push(stack, Value::Int(4));
798 stack = push(stack, Value::Int(5));
799
800 stack = pick(stack, 3); let (stack, val) = pop(stack);
806 assert_eq!(val, Value::Int(2));
807
808 let (stack, val) = pop(stack);
809 assert_eq!(val, Value::Int(5));
810
811 let (stack, val) = pop(stack);
812 assert_eq!(val, Value::Int(4));
813
814 let (stack, val) = pop(stack);
815 assert_eq!(val, Value::Int(3));
816
817 let (stack, val) = pop(stack);
818 assert_eq!(val, Value::Int(2));
819
820 let (stack, val) = pop(stack);
821 assert_eq!(val, Value::Int(1));
822
823 assert!(is_empty(stack));
824 }
825 }
826
827 #[test]
828 fn test_multifield_variant_survives_shuffle() {
829 use crate::value::VariantData;
833
834 unsafe {
835 let nil = Value::Variant(Box::new(VariantData::new(0, vec![])));
838 let cons = Value::Variant(Box::new(VariantData::new(
839 1,
840 vec![Value::Int(42), nil.clone()],
841 )));
842
843 let mut stack = std::ptr::null_mut();
845 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;
860 while !is_empty(stack) {
861 let (rest, val) = pop(stack);
862 stack = rest;
863 if matches!(val, Value::Variant(_)) {
864 found_variant = Some(val);
865 }
866 }
867
868 assert!(found_variant.is_some(), "Variant was lost during shuffle!");
870
871 if let Some(Value::Variant(variant_data)) = found_variant {
872 assert_eq!(variant_data.tag, 1, "Variant tag corrupted!");
873 assert_eq!(
874 variant_data.fields.len(),
875 2,
876 "Variant field count corrupted!"
877 );
878 assert_eq!(
879 variant_data.fields[0],
880 Value::Int(42),
881 "First field corrupted!"
882 );
883
884 if let Value::Variant(nil_data) = &variant_data.fields[1] {
886 assert_eq!(nil_data.tag, 0, "Nested variant tag corrupted!");
887 assert_eq!(nil_data.fields.len(), 0, "Nested variant should be empty!");
888 } else {
889 panic!("Second field should be a Variant!");
890 }
891 }
892 }
893 }
894
895 #[test]
896 fn test_arbitrary_depth_operations() {
897 unsafe {
900 let mut stack = std::ptr::null_mut();
901
902 for i in 0..100 {
904 stack = push(stack, Value::Int(i));
905 }
906
907 stack = dup(stack); stack = swap(stack); stack = over(stack); stack = rot(stack); stack = drop(stack); stack = pick(stack, 50); let mut count = 0;
919 while !is_empty(stack) {
920 let (rest, _val) = pop(stack);
921 stack = rest;
922 count += 1;
923 }
924
925 assert_eq!(count, 102);
927 }
928 }
929
930 #[test]
931 fn test_operation_composition_completeness() {
932 unsafe {
935 let mut stack = std::ptr::null_mut();
936
937 for i in 1..=10 {
939 stack = push(stack, Value::Int(i));
940 }
941
942 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;
956 let mut current = stack;
957 while !current.is_null() {
958 depth += 1;
959 current = (*current).next;
960 }
961
962 assert!(depth > 0, "Stack should not be empty after operations");
963 }
964 }
965
966 #[test]
967 fn test_pick_at_arbitrary_depths() {
968 unsafe {
971 let mut stack = std::ptr::null_mut();
972
973 for i in 0..50 {
975 stack = push(stack, Value::Int(i * 10));
976 }
977
978 stack = pick(stack, 0); let (mut stack, val) = pop(stack);
984 assert_eq!(val, Value::Int(490));
985
986 stack = pick(stack, 10); let (mut stack, val) = pop(stack);
988 assert_eq!(val, Value::Int(390)); stack = pick(stack, 40); let (stack, val) = pop(stack);
992 assert_eq!(val, Value::Int(90)); let mut count = 0;
996 let mut current = stack;
997 while !current.is_null() {
998 count += 1;
999 current = (*current).next;
1000 }
1001
1002 assert_eq!(count, 50, "Stack depth should be unchanged");
1003 }
1004 }
1005
1006 #[test]
1007 fn test_pick_op_equivalence_to_dup() {
1008 unsafe {
1010 let mut stack = std::ptr::null_mut();
1011 stack = push(stack, Value::Int(42));
1012 stack = push(stack, Value::Int(0)); stack = pick_op(stack);
1015
1016 let (stack, val1) = pop(stack);
1018 assert_eq!(val1, Value::Int(42));
1019 let (stack, val2) = pop(stack);
1020 assert_eq!(val2, Value::Int(42));
1021 assert!(stack.is_null());
1022 }
1023 }
1024
1025 #[test]
1026 fn test_pick_op_equivalence_to_over() {
1027 unsafe {
1029 let mut stack = std::ptr::null_mut();
1030 stack = push(stack, Value::Int(10));
1031 stack = push(stack, Value::Int(20));
1032 stack = push(stack, Value::Int(1)); stack = pick_op(stack);
1035
1036 let (stack, val1) = pop(stack);
1038 assert_eq!(val1, Value::Int(10));
1039 let (stack, val2) = pop(stack);
1040 assert_eq!(val2, Value::Int(20));
1041 let (stack, val3) = pop(stack);
1042 assert_eq!(val3, Value::Int(10));
1043 assert!(stack.is_null());
1044 }
1045 }
1046
1047 #[test]
1048 fn test_pick_op_deep_access() {
1049 unsafe {
1051 let mut stack = std::ptr::null_mut();
1052 for i in 0..10 {
1053 stack = push(stack, Value::Int(i));
1054 }
1055 stack = push(stack, Value::Int(5)); stack = pick_op(stack);
1058
1059 let (stack, val) = pop(stack);
1061 assert_eq!(val, Value::Int(4));
1062
1063 let mut count = 0;
1065 let mut current = stack;
1066 while !current.is_null() {
1067 count += 1;
1068 current = (*current).next;
1069 }
1070 assert_eq!(count, 10);
1071 }
1072 }
1073
1074 #[test]
1080 fn test_roll_0_is_noop() {
1081 unsafe {
1083 let mut stack = std::ptr::null_mut();
1084 stack = push(stack, Value::Int(42));
1085 stack = push(stack, Value::Int(0)); stack = roll(stack);
1088
1089 let (stack, val) = pop(stack);
1090 assert_eq!(val, Value::Int(42));
1091 assert!(stack.is_null());
1092 }
1093 }
1094
1095 #[test]
1096 fn test_roll_1_is_swap() {
1097 unsafe {
1099 let mut stack = std::ptr::null_mut();
1100 stack = push(stack, Value::Int(1));
1101 stack = push(stack, Value::Int(2));
1102 stack = push(stack, Value::Int(1)); stack = roll(stack);
1105
1106 let (stack, val1) = pop(stack);
1108 assert_eq!(val1, Value::Int(1));
1109 let (stack, val2) = pop(stack);
1110 assert_eq!(val2, Value::Int(2));
1111 assert!(stack.is_null());
1112 }
1113 }
1114
1115 #[test]
1116 fn test_roll_2_is_rot() {
1117 unsafe {
1119 let mut stack = std::ptr::null_mut();
1120 stack = push(stack, Value::Int(1));
1121 stack = push(stack, Value::Int(2));
1122 stack = push(stack, Value::Int(3));
1123 stack = push(stack, Value::Int(2)); stack = roll(stack);
1126
1127 let (stack, val1) = pop(stack);
1129 assert_eq!(val1, Value::Int(1));
1130 let (stack, val2) = pop(stack);
1131 assert_eq!(val2, Value::Int(3));
1132 let (stack, val3) = pop(stack);
1133 assert_eq!(val3, Value::Int(2));
1134 assert!(stack.is_null());
1135 }
1136 }
1137
1138 #[test]
1139 fn test_roll_3_rotates_4_items() {
1140 unsafe {
1142 let mut stack = std::ptr::null_mut();
1143 stack = push(stack, Value::Int(1)); stack = push(stack, Value::Int(2));
1145 stack = push(stack, Value::Int(3));
1146 stack = push(stack, Value::Int(4)); stack = push(stack, Value::Int(3)); stack = roll(stack);
1150
1151 let (stack, val1) = pop(stack);
1153 assert_eq!(val1, Value::Int(1)); let (stack, val2) = pop(stack);
1155 assert_eq!(val2, Value::Int(4));
1156 let (stack, val3) = pop(stack);
1157 assert_eq!(val3, Value::Int(3));
1158 let (stack, val4) = pop(stack);
1159 assert_eq!(val4, Value::Int(2));
1160 assert!(stack.is_null());
1161 }
1162 }
1163
1164 #[test]
1165 fn test_roll_deep() {
1166 unsafe {
1168 let mut stack = std::ptr::null_mut();
1169 for i in 0..10 {
1170 stack = push(stack, Value::Int(i));
1171 }
1172 stack = push(stack, Value::Int(5)); stack = roll(stack);
1176
1177 let (stack, val) = pop(stack);
1180 assert_eq!(val, Value::Int(4)); let (stack, val) = pop(stack);
1184 assert_eq!(val, Value::Int(9));
1185 let (stack, val) = pop(stack);
1186 assert_eq!(val, Value::Int(8));
1187 let (stack, val) = pop(stack);
1188 assert_eq!(val, Value::Int(7));
1189 let (stack, val) = pop(stack);
1190 assert_eq!(val, Value::Int(6));
1191 let (stack, val) = pop(stack);
1192 assert_eq!(val, Value::Int(5));
1193 let (stack, val) = pop(stack);
1195 assert_eq!(val, Value::Int(3));
1196 let (stack, val) = pop(stack);
1197 assert_eq!(val, Value::Int(2));
1198 let (stack, val) = pop(stack);
1199 assert_eq!(val, Value::Int(1));
1200 let (stack, val) = pop(stack);
1201 assert_eq!(val, Value::Int(0));
1202 assert!(stack.is_null());
1203 }
1204 }
1205
1206 #[test]
1207 fn test_roll_with_extra_stack() {
1208 unsafe {
1210 let mut stack = std::ptr::null_mut();
1211 stack = push(stack, Value::Int(100)); stack = push(stack, Value::Int(1));
1213 stack = push(stack, Value::Int(2));
1214 stack = push(stack, Value::Int(3));
1215 stack = push(stack, Value::Int(4));
1216 stack = push(stack, Value::Int(3)); stack = roll(stack);
1219
1220 let (stack, val1) = pop(stack);
1222 assert_eq!(val1, Value::Int(1));
1223 let (stack, val2) = pop(stack);
1224 assert_eq!(val2, Value::Int(4));
1225 let (stack, val3) = pop(stack);
1226 assert_eq!(val3, Value::Int(3));
1227 let (stack, val4) = pop(stack);
1228 assert_eq!(val4, Value::Int(2));
1229 let (stack, val5) = pop(stack);
1230 assert_eq!(val5, Value::Int(100)); assert!(stack.is_null());
1232 }
1233 }
1234
1235 #[test]
1236 fn test_operations_preserve_stack_integrity() {
1237 unsafe {
1240 let mut stack = std::ptr::null_mut();
1241
1242 for i in 0..20 {
1243 stack = push(stack, Value::Int(i));
1244 }
1245
1246 stack = swap(stack);
1248 stack = rot(stack);
1249 stack = swap(stack);
1250 stack = rot(stack);
1251 stack = over(stack);
1252 stack = tuck(stack);
1253
1254 let mut visited = std::collections::HashSet::new();
1258 let mut current = stack;
1259 let mut count = 0;
1260
1261 while !current.is_null() {
1262 assert!(
1264 visited.insert(current as usize),
1265 "Detected cycle in stack - next pointer corruption!"
1266 );
1267
1268 count += 1;
1269 current = (*current).next;
1270
1271 assert!(
1273 count < 1000,
1274 "Stack walk exceeded reasonable depth - likely corrupted"
1275 );
1276 }
1277
1278 assert!(count > 0, "Stack should have elements");
1279 }
1280 }
1281
1282 #[test]
1283 fn test_nested_variants_with_deep_stacks() {
1284 use crate::value::VariantData;
1287
1288 unsafe {
1289 let nil = Value::Variant(Box::new(VariantData::new(0, vec![])));
1291 let cons3 = Value::Variant(Box::new(VariantData::new(1, vec![Value::Int(3), nil])));
1292 let cons2 = Value::Variant(Box::new(VariantData::new(1, vec![Value::Int(2), cons3])));
1293 let cons1 = Value::Variant(Box::new(VariantData::new(1, vec![Value::Int(1), cons2])));
1294
1295 let mut stack = std::ptr::null_mut();
1297 for i in 0..30 {
1298 stack = push(stack, Value::Int(i));
1299 }
1300 stack = push(stack, cons1.clone());
1301 for i in 30..60 {
1302 stack = push(stack, Value::Int(i));
1303 }
1304
1305 for _ in 0..10 {
1307 stack = rot(stack);
1308 stack = swap(stack);
1309 stack = over(stack);
1310 stack = drop(stack);
1311 }
1312
1313 let mut found_variant = None;
1315 while !is_empty(stack) {
1316 let (rest, val) = pop(stack);
1317 stack = rest;
1318 if let Value::Variant(ref vdata) = val
1319 && vdata.tag == 1
1320 && vdata.fields.len() == 2
1321 && let Value::Int(1) = vdata.fields[0]
1322 {
1323 found_variant = Some(val);
1324 break;
1325 }
1326 }
1327
1328 assert!(
1329 found_variant.is_some(),
1330 "Nested variant lost during deep stack operations"
1331 );
1332 }
1333 }
1334}