seq_runtime/variant_ops/
access.rs1use crate::stack::{Stack, pop, push};
4use crate::value::Value;
5
6#[unsafe(no_mangle)]
13pub unsafe extern "C" fn patch_seq_variant_field_count(stack: Stack) -> Stack {
14 unsafe {
15 let (stack, value) = pop(stack);
16
17 match value {
18 Value::Variant(variant_data) => {
19 let count = variant_data.fields.len() as i64;
20 push(stack, Value::Int(count))
21 }
22 _ => panic!("variant-field-count: expected Variant, got {:?}", value),
23 }
24 }
25}
26
27#[unsafe(no_mangle)]
34pub unsafe extern "C" fn patch_seq_variant_tag(stack: Stack) -> Stack {
35 unsafe {
36 let (stack, value) = pop(stack);
37
38 match value {
39 Value::Variant(variant_data) => {
40 push(stack, Value::Symbol(variant_data.tag.clone()))
42 }
43 _ => panic!("variant-tag: expected Variant, got {:?}", value),
44 }
45 }
46}
47
48#[unsafe(no_mangle)]
60pub unsafe extern "C" fn patch_seq_symbol_eq_cstr(stack: Stack, c_str: *const i8) -> Stack {
61 use std::ffi::CStr;
62
63 unsafe {
64 let (stack, value) = pop(stack);
65 let symbol_str = match value {
66 Value::Symbol(s) => s,
67 _ => panic!("symbol_eq_cstr: expected Symbol, got {:?}", value),
68 };
69
70 let expected = CStr::from_ptr(c_str)
71 .to_str()
72 .expect("Invalid UTF-8 in variant name");
73
74 let is_equal = symbol_str.as_str() == expected;
75 push(stack, Value::Bool(is_equal))
76 }
77}
78
79#[unsafe(no_mangle)]
90pub unsafe extern "C" fn patch_seq_variant_field_at(stack: Stack) -> Stack {
91 unsafe {
92 let (stack, index_val) = pop(stack);
93 let index = match index_val {
94 Value::Int(i) => i,
95 _ => panic!(
96 "variant-field-at: expected Int (index), got {:?}",
97 index_val
98 ),
99 };
100
101 if index < 0 {
102 panic!("variant-field-at: index cannot be negative: {}", index);
103 }
104
105 let (stack, variant_val) = pop(stack);
106
107 match variant_val {
108 Value::Variant(variant_data) => {
109 let idx = index as usize;
110 if idx >= variant_data.fields.len() {
111 panic!(
112 "variant-field-at: index {} out of bounds (variant has {} fields)",
113 index,
114 variant_data.fields.len()
115 );
116 }
117
118 let field = variant_data.fields[idx].clone();
120 push(stack, field)
121 }
122 _ => panic!("variant-field-at: expected Variant, got {:?}", variant_val),
123 }
124 }
125}