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 unsafe fn clone_stack(stack: Stack) -> Stack {
450 if stack.is_null() {
451 return std::ptr::null_mut();
452 }
453
454 let mut values = Vec::new();
456 let mut current = stack;
457 while !current.is_null() {
458 values.push(unsafe { (*current).value.clone() });
459 current = unsafe { (*current).next };
460 }
461
462 let mut new_stack: Stack = std::ptr::null_mut();
465 for value in values.into_iter().rev() {
466 let node = Box::new(StackNode {
467 value,
468 next: new_stack,
469 });
470 new_stack = Box::into_raw(node);
471 }
472
473 new_stack
474}
475
476pub use patch_seq_drop_op as drop_op;
478pub use patch_seq_dup as dup;
479pub use patch_seq_nip as nip;
480pub use patch_seq_over as over;
481pub use patch_seq_pick_op as pick_op;
482pub use patch_seq_push_value as push_value;
483pub use patch_seq_roll as roll;
484pub use patch_seq_rot as rot;
485pub use patch_seq_swap as swap;
486pub use patch_seq_tuck as tuck;
487
488#[cfg(test)]
489mod tests {
490 use super::*;
491 use std::sync::Arc;
492
493 fn make_stack(values: &[i64]) -> Stack {
495 unsafe {
496 let mut stack = std::ptr::null_mut();
497 for &val in values {
498 stack = push(stack, Value::Int(val));
499 }
500 stack
501 }
502 }
503
504 fn drain_stack(mut stack: Stack) -> Vec<Value> {
506 unsafe {
507 let mut values = Vec::new();
508 while !is_empty(stack) {
509 let (rest, val) = pop(stack);
510 stack = rest;
511 values.push(val);
512 }
513 values
514 }
515 }
516
517 fn assert_stack_ints(stack: Stack, expected: &[i64]) {
519 let values = drain_stack(stack);
520 let ints: Vec<i64> = values
521 .into_iter()
522 .map(|v| match v {
523 Value::Int(n) => n,
524 _ => panic!("Expected Int, got {:?}", v),
525 })
526 .collect();
527 assert_eq!(ints, expected);
528 }
529
530 #[test]
531 fn test_push_pop() {
532 unsafe {
533 let stack = std::ptr::null_mut();
534 assert!(is_empty(stack));
535
536 let stack = push(stack, Value::Int(42));
537 assert!(!is_empty(stack));
538
539 let (stack, value) = pop(stack);
540 assert_eq!(value, Value::Int(42));
541 assert!(is_empty(stack));
542 }
543 }
544
545 #[test]
546 fn test_multiple_values() {
547 unsafe {
548 let mut stack = std::ptr::null_mut();
549
550 stack = push(stack, Value::Int(1));
551 stack = push(stack, Value::Int(2));
552 stack = push(stack, Value::Int(3));
553
554 let (stack, val) = pop(stack);
555 assert_eq!(val, Value::Int(3));
556
557 let (stack, val) = pop(stack);
558 assert_eq!(val, Value::Int(2));
559
560 let (stack, val) = pop(stack);
561 assert_eq!(val, Value::Int(1));
562
563 assert!(is_empty(stack));
564 }
565 }
566
567 #[test]
568 fn test_peek() {
569 unsafe {
570 let stack = push(std::ptr::null_mut(), Value::Int(42));
571 let peeked = peek(stack);
572 assert_eq!(*peeked, Value::Int(42));
573
574 let (stack, value) = pop(stack);
576 assert_eq!(value, Value::Int(42));
577 assert!(is_empty(stack));
578 }
579 }
580
581 #[test]
582 fn test_dup() {
583 unsafe {
584 let stack = push(std::ptr::null_mut(), Value::Int(42));
585 let stack = dup(stack);
586
587 let (stack, val1) = pop(stack);
589 assert_eq!(val1, Value::Int(42));
590
591 let (stack, val2) = pop(stack);
592 assert_eq!(val2, Value::Int(42));
593
594 assert!(is_empty(stack));
595 }
596 }
597
598 #[test]
599 fn test_drop() {
600 unsafe {
601 let mut stack = std::ptr::null_mut();
602 stack = push(stack, Value::Int(1));
603 stack = push(stack, Value::Int(2));
604 stack = push(stack, Value::Int(3));
605
606 stack = drop(stack);
608
609 let (stack, val) = pop(stack);
611 assert_eq!(val, Value::Int(2));
612
613 let (stack, val) = pop(stack);
614 assert_eq!(val, Value::Int(1));
615
616 assert!(is_empty(stack));
617 }
618 }
619
620 #[test]
621 fn test_swap() {
622 unsafe {
623 let mut stack = std::ptr::null_mut();
624 stack = push(stack, Value::Int(1));
625 stack = push(stack, Value::Int(2));
626
627 stack = swap(stack);
629
630 let (stack, val) = pop(stack);
631 assert_eq!(val, Value::Int(1));
632
633 let (stack, val) = pop(stack);
634 assert_eq!(val, Value::Int(2));
635
636 assert!(is_empty(stack));
637 }
638 }
639
640 #[test]
641 fn test_composition() {
642 unsafe {
651 let mut stack = make_stack(&[1, 2, 3]);
652
653 stack = swap(stack);
654 stack = drop(stack);
655 stack = dup(stack);
656
657 assert_stack_ints(stack, &[3, 3, 1]);
658 }
659 }
660
661 #[test]
662 fn test_over() {
663 unsafe {
665 let mut stack = std::ptr::null_mut();
666 stack = push(stack, Value::Int(1));
667 stack = push(stack, Value::Int(2));
668
669 stack = over(stack); let (stack, val) = pop(stack);
672 assert_eq!(val, Value::Int(1));
673
674 let (stack, val) = pop(stack);
675 assert_eq!(val, Value::Int(2));
676
677 let (stack, val) = pop(stack);
678 assert_eq!(val, Value::Int(1));
679
680 assert!(is_empty(stack));
681 }
682 }
683
684 #[test]
685 fn test_rot() {
686 unsafe {
688 let mut stack = std::ptr::null_mut();
689 stack = push(stack, Value::Int(1));
690 stack = push(stack, Value::Int(2));
691 stack = push(stack, Value::Int(3));
692
693 stack = rot(stack); let (stack, val) = pop(stack);
696 assert_eq!(val, Value::Int(1));
697
698 let (stack, val) = pop(stack);
699 assert_eq!(val, Value::Int(3));
700
701 let (stack, val) = pop(stack);
702 assert_eq!(val, Value::Int(2));
703
704 assert!(is_empty(stack));
705 }
706 }
707
708 #[test]
709 fn test_nip() {
710 unsafe {
712 let mut stack = std::ptr::null_mut();
713 stack = push(stack, Value::Int(1));
714 stack = push(stack, Value::Int(2));
715
716 stack = nip(stack); let (stack, val) = pop(stack);
719 assert_eq!(val, Value::Int(2));
720
721 assert!(is_empty(stack));
722 }
723 }
724
725 #[test]
726 fn test_tuck() {
727 unsafe {
729 let mut stack = std::ptr::null_mut();
730 stack = push(stack, Value::Int(1));
731 stack = push(stack, Value::Int(2));
732
733 stack = tuck(stack); let (stack, val) = pop(stack);
736 assert_eq!(val, Value::Int(2));
737
738 let (stack, val) = pop(stack);
739 assert_eq!(val, Value::Int(1));
740
741 let (stack, val) = pop(stack);
742 assert_eq!(val, Value::Int(2));
743
744 assert!(is_empty(stack));
745 }
746 }
747
748 #[test]
749 fn test_critical_shuffle_pattern() {
750 unsafe {
764 let mut stack = make_stack(&[1, 2, 3, 4, 5]);
765
766 stack = rot(stack);
770 stack = swap(stack);
776 stack = rot(stack);
782 stack = rot(stack);
788 stack = swap(stack);
794 assert_stack_ints(stack, &[4, 3, 5, 2, 1]);
802 }
803 }
804
805 #[test]
806 fn test_pick_0_is_dup() {
807 unsafe {
809 let mut stack = std::ptr::null_mut();
810 stack = push(stack, Value::Int(42));
811
812 stack = pick(stack, 0);
813
814 let (stack, val) = pop(stack);
815 assert_eq!(val, Value::Int(42));
816
817 let (stack, val) = pop(stack);
818 assert_eq!(val, Value::Int(42));
819
820 assert!(is_empty(stack));
821 }
822 }
823
824 #[test]
825 fn test_pick_1_is_over() {
826 unsafe {
828 let mut stack = std::ptr::null_mut();
829 stack = push(stack, Value::Int(1));
830 stack = push(stack, Value::Int(2));
831
832 stack = pick(stack, 1);
833
834 let (stack, val) = pop(stack);
835 assert_eq!(val, Value::Int(1));
836
837 let (stack, val) = pop(stack);
838 assert_eq!(val, Value::Int(2));
839
840 let (stack, val) = pop(stack);
841 assert_eq!(val, Value::Int(1));
842
843 assert!(is_empty(stack));
844 }
845 }
846
847 #[test]
848 fn test_pick_deep() {
849 unsafe {
851 let mut stack = std::ptr::null_mut();
852 stack = push(stack, Value::Int(1));
853 stack = push(stack, Value::Int(2));
854 stack = push(stack, Value::Int(3));
855 stack = push(stack, Value::Int(4));
856 stack = push(stack, Value::Int(5));
857
858 stack = pick(stack, 3); let (stack, val) = pop(stack);
864 assert_eq!(val, Value::Int(2));
865
866 let (stack, val) = pop(stack);
867 assert_eq!(val, Value::Int(5));
868
869 let (stack, val) = pop(stack);
870 assert_eq!(val, Value::Int(4));
871
872 let (stack, val) = pop(stack);
873 assert_eq!(val, Value::Int(3));
874
875 let (stack, val) = pop(stack);
876 assert_eq!(val, Value::Int(2));
877
878 let (stack, val) = pop(stack);
879 assert_eq!(val, Value::Int(1));
880
881 assert!(is_empty(stack));
882 }
883 }
884
885 #[test]
886 fn test_multifield_variant_survives_shuffle() {
887 use crate::value::VariantData;
891
892 unsafe {
893 let nil = Value::Variant(Arc::new(VariantData::new(0, vec![])));
896 let cons = Value::Variant(Arc::new(VariantData::new(
897 1,
898 vec![Value::Int(42), nil.clone()],
899 )));
900
901 let mut stack = std::ptr::null_mut();
903 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;
918 while !is_empty(stack) {
919 let (rest, val) = pop(stack);
920 stack = rest;
921 if matches!(val, Value::Variant(_)) {
922 found_variant = Some(val);
923 }
924 }
925
926 assert!(found_variant.is_some(), "Variant was lost during shuffle!");
928
929 if let Some(Value::Variant(variant_data)) = found_variant {
930 assert_eq!(variant_data.tag, 1, "Variant tag corrupted!");
931 assert_eq!(
932 variant_data.fields.len(),
933 2,
934 "Variant field count corrupted!"
935 );
936 assert_eq!(
937 variant_data.fields[0],
938 Value::Int(42),
939 "First field corrupted!"
940 );
941
942 if let Value::Variant(nil_data) = &variant_data.fields[1] {
944 assert_eq!(nil_data.tag, 0, "Nested variant tag corrupted!");
945 assert_eq!(nil_data.fields.len(), 0, "Nested variant should be empty!");
946 } else {
947 panic!("Second field should be a Variant!");
948 }
949 }
950 }
951 }
952
953 #[test]
954 fn test_arbitrary_depth_operations() {
955 unsafe {
958 let mut stack = std::ptr::null_mut();
959
960 for i in 0..100 {
962 stack = push(stack, Value::Int(i));
963 }
964
965 stack = dup(stack); stack = swap(stack); stack = over(stack); stack = rot(stack); stack = drop(stack); stack = pick(stack, 50); let mut count = 0;
977 while !is_empty(stack) {
978 let (rest, _val) = pop(stack);
979 stack = rest;
980 count += 1;
981 }
982
983 assert_eq!(count, 102);
985 }
986 }
987
988 #[test]
989 fn test_operation_composition_completeness() {
990 unsafe {
993 let mut stack = std::ptr::null_mut();
994
995 for i in 1..=10 {
997 stack = push(stack, Value::Int(i));
998 }
999
1000 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;
1014 let mut current = stack;
1015 while !current.is_null() {
1016 depth += 1;
1017 current = (*current).next;
1018 }
1019
1020 assert!(depth > 0, "Stack should not be empty after operations");
1021 }
1022 }
1023
1024 #[test]
1025 fn test_pick_at_arbitrary_depths() {
1026 unsafe {
1029 let mut stack = std::ptr::null_mut();
1030
1031 for i in 0..50 {
1033 stack = push(stack, Value::Int(i * 10));
1034 }
1035
1036 stack = pick(stack, 0); let (mut stack, val) = pop(stack);
1042 assert_eq!(val, Value::Int(490));
1043
1044 stack = pick(stack, 10); let (mut stack, val) = pop(stack);
1046 assert_eq!(val, Value::Int(390)); stack = pick(stack, 40); let (stack, val) = pop(stack);
1050 assert_eq!(val, Value::Int(90)); let mut count = 0;
1054 let mut current = stack;
1055 while !current.is_null() {
1056 count += 1;
1057 current = (*current).next;
1058 }
1059
1060 assert_eq!(count, 50, "Stack depth should be unchanged");
1061 }
1062 }
1063
1064 #[test]
1065 fn test_pick_op_equivalence_to_dup() {
1066 unsafe {
1068 let mut stack = std::ptr::null_mut();
1069 stack = push(stack, Value::Int(42));
1070 stack = push(stack, Value::Int(0)); stack = pick_op(stack);
1073
1074 let (stack, val1) = pop(stack);
1076 assert_eq!(val1, Value::Int(42));
1077 let (stack, val2) = pop(stack);
1078 assert_eq!(val2, Value::Int(42));
1079 assert!(stack.is_null());
1080 }
1081 }
1082
1083 #[test]
1084 fn test_pick_op_equivalence_to_over() {
1085 unsafe {
1087 let mut stack = std::ptr::null_mut();
1088 stack = push(stack, Value::Int(10));
1089 stack = push(stack, Value::Int(20));
1090 stack = push(stack, Value::Int(1)); stack = pick_op(stack);
1093
1094 let (stack, val1) = pop(stack);
1096 assert_eq!(val1, Value::Int(10));
1097 let (stack, val2) = pop(stack);
1098 assert_eq!(val2, Value::Int(20));
1099 let (stack, val3) = pop(stack);
1100 assert_eq!(val3, Value::Int(10));
1101 assert!(stack.is_null());
1102 }
1103 }
1104
1105 #[test]
1106 fn test_pick_op_deep_access() {
1107 unsafe {
1109 let mut stack = std::ptr::null_mut();
1110 for i in 0..10 {
1111 stack = push(stack, Value::Int(i));
1112 }
1113 stack = push(stack, Value::Int(5)); stack = pick_op(stack);
1116
1117 let (stack, val) = pop(stack);
1119 assert_eq!(val, Value::Int(4));
1120
1121 let mut count = 0;
1123 let mut current = stack;
1124 while !current.is_null() {
1125 count += 1;
1126 current = (*current).next;
1127 }
1128 assert_eq!(count, 10);
1129 }
1130 }
1131
1132 #[test]
1138 fn test_roll_0_is_noop() {
1139 unsafe {
1141 let mut stack = std::ptr::null_mut();
1142 stack = push(stack, Value::Int(42));
1143 stack = push(stack, Value::Int(0)); stack = roll(stack);
1146
1147 let (stack, val) = pop(stack);
1148 assert_eq!(val, Value::Int(42));
1149 assert!(stack.is_null());
1150 }
1151 }
1152
1153 #[test]
1154 fn test_roll_1_is_swap() {
1155 unsafe {
1157 let mut stack = std::ptr::null_mut();
1158 stack = push(stack, Value::Int(1));
1159 stack = push(stack, Value::Int(2));
1160 stack = push(stack, Value::Int(1)); stack = roll(stack);
1163
1164 let (stack, val1) = pop(stack);
1166 assert_eq!(val1, Value::Int(1));
1167 let (stack, val2) = pop(stack);
1168 assert_eq!(val2, Value::Int(2));
1169 assert!(stack.is_null());
1170 }
1171 }
1172
1173 #[test]
1174 fn test_roll_2_is_rot() {
1175 unsafe {
1177 let mut stack = std::ptr::null_mut();
1178 stack = push(stack, Value::Int(1));
1179 stack = push(stack, Value::Int(2));
1180 stack = push(stack, Value::Int(3));
1181 stack = push(stack, Value::Int(2)); stack = roll(stack);
1184
1185 let (stack, val1) = pop(stack);
1187 assert_eq!(val1, Value::Int(1));
1188 let (stack, val2) = pop(stack);
1189 assert_eq!(val2, Value::Int(3));
1190 let (stack, val3) = pop(stack);
1191 assert_eq!(val3, Value::Int(2));
1192 assert!(stack.is_null());
1193 }
1194 }
1195
1196 #[test]
1197 fn test_roll_3_rotates_4_items() {
1198 unsafe {
1200 let mut stack = std::ptr::null_mut();
1201 stack = push(stack, Value::Int(1)); stack = push(stack, Value::Int(2));
1203 stack = push(stack, Value::Int(3));
1204 stack = push(stack, Value::Int(4)); stack = push(stack, Value::Int(3)); stack = roll(stack);
1208
1209 let (stack, val1) = pop(stack);
1211 assert_eq!(val1, Value::Int(1)); let (stack, val2) = pop(stack);
1213 assert_eq!(val2, Value::Int(4));
1214 let (stack, val3) = pop(stack);
1215 assert_eq!(val3, Value::Int(3));
1216 let (stack, val4) = pop(stack);
1217 assert_eq!(val4, Value::Int(2));
1218 assert!(stack.is_null());
1219 }
1220 }
1221
1222 #[test]
1223 fn test_roll_deep() {
1224 unsafe {
1226 let mut stack = std::ptr::null_mut();
1227 for i in 0..10 {
1228 stack = push(stack, Value::Int(i));
1229 }
1230 stack = push(stack, Value::Int(5)); stack = roll(stack);
1234
1235 let (stack, val) = pop(stack);
1238 assert_eq!(val, Value::Int(4)); let (stack, val) = pop(stack);
1242 assert_eq!(val, Value::Int(9));
1243 let (stack, val) = pop(stack);
1244 assert_eq!(val, Value::Int(8));
1245 let (stack, val) = pop(stack);
1246 assert_eq!(val, Value::Int(7));
1247 let (stack, val) = pop(stack);
1248 assert_eq!(val, Value::Int(6));
1249 let (stack, val) = pop(stack);
1250 assert_eq!(val, Value::Int(5));
1251 let (stack, val) = pop(stack);
1253 assert_eq!(val, Value::Int(3));
1254 let (stack, val) = pop(stack);
1255 assert_eq!(val, Value::Int(2));
1256 let (stack, val) = pop(stack);
1257 assert_eq!(val, Value::Int(1));
1258 let (stack, val) = pop(stack);
1259 assert_eq!(val, Value::Int(0));
1260 assert!(stack.is_null());
1261 }
1262 }
1263
1264 #[test]
1265 fn test_roll_with_extra_stack() {
1266 unsafe {
1268 let mut stack = std::ptr::null_mut();
1269 stack = push(stack, Value::Int(100)); stack = push(stack, Value::Int(1));
1271 stack = push(stack, Value::Int(2));
1272 stack = push(stack, Value::Int(3));
1273 stack = push(stack, Value::Int(4));
1274 stack = push(stack, Value::Int(3)); stack = roll(stack);
1277
1278 let (stack, val1) = pop(stack);
1280 assert_eq!(val1, Value::Int(1));
1281 let (stack, val2) = pop(stack);
1282 assert_eq!(val2, Value::Int(4));
1283 let (stack, val3) = pop(stack);
1284 assert_eq!(val3, Value::Int(3));
1285 let (stack, val4) = pop(stack);
1286 assert_eq!(val4, Value::Int(2));
1287 let (stack, val5) = pop(stack);
1288 assert_eq!(val5, Value::Int(100)); assert!(stack.is_null());
1290 }
1291 }
1292
1293 #[test]
1294 fn test_operations_preserve_stack_integrity() {
1295 unsafe {
1298 let mut stack = std::ptr::null_mut();
1299
1300 for i in 0..20 {
1301 stack = push(stack, Value::Int(i));
1302 }
1303
1304 stack = swap(stack);
1306 stack = rot(stack);
1307 stack = swap(stack);
1308 stack = rot(stack);
1309 stack = over(stack);
1310 stack = tuck(stack);
1311
1312 let mut visited = std::collections::HashSet::new();
1316 let mut current = stack;
1317 let mut count = 0;
1318
1319 while !current.is_null() {
1320 assert!(
1322 visited.insert(current as usize),
1323 "Detected cycle in stack - next pointer corruption!"
1324 );
1325
1326 count += 1;
1327 current = (*current).next;
1328
1329 assert!(
1331 count < 1000,
1332 "Stack walk exceeded reasonable depth - likely corrupted"
1333 );
1334 }
1335
1336 assert!(count > 0, "Stack should have elements");
1337 }
1338 }
1339
1340 #[test]
1341 fn test_nested_variants_with_deep_stacks() {
1342 use crate::value::VariantData;
1345
1346 unsafe {
1347 let nil = Value::Variant(Arc::new(VariantData::new(0, vec![])));
1349 let cons3 = Value::Variant(Arc::new(VariantData::new(1, vec![Value::Int(3), nil])));
1350 let cons2 = Value::Variant(Arc::new(VariantData::new(1, vec![Value::Int(2), cons3])));
1351 let cons1 = Value::Variant(Arc::new(VariantData::new(1, vec![Value::Int(1), cons2])));
1352
1353 let mut stack = std::ptr::null_mut();
1355 for i in 0..30 {
1356 stack = push(stack, Value::Int(i));
1357 }
1358 stack = push(stack, cons1.clone());
1359 for i in 30..60 {
1360 stack = push(stack, Value::Int(i));
1361 }
1362
1363 for _ in 0..10 {
1365 stack = rot(stack);
1366 stack = swap(stack);
1367 stack = over(stack);
1368 stack = drop(stack);
1369 }
1370
1371 let mut found_variant = None;
1373 while !is_empty(stack) {
1374 let (rest, val) = pop(stack);
1375 stack = rest;
1376 if let Value::Variant(ref vdata) = val
1377 && vdata.tag == 1
1378 && vdata.fields.len() == 2
1379 && let Value::Int(1) = vdata.fields[0]
1380 {
1381 found_variant = Some(val);
1382 break;
1383 }
1384 }
1385
1386 assert!(
1387 found_variant.is_some(),
1388 "Nested variant lost during deep stack operations"
1389 );
1390 }
1391 }
1392}