use crate::stack::{Stack, push};
use crate::value::Value;
#[unsafe(no_mangle)]
pub unsafe extern "C" fn patch_seq_env_get_int(
env_data: *const Value,
env_len: usize,
index: i32,
) -> i64 {
if env_data.is_null() {
panic!("env_get_int: null environment pointer");
}
if index < 0 {
panic!("env_get_int: index cannot be negative: {}", index);
}
let idx = index as usize;
if idx >= env_len {
panic!(
"env_get_int: index {} out of bounds for environment of size {}",
index, env_len
);
}
let value = unsafe { &*env_data.add(idx) };
match value {
Value::Int(n) => *n,
_ => panic!(
"env_get_int: expected Int at index {}, got {:?}",
index, value
),
}
}
#[allow(improper_ctypes_definitions)]
#[unsafe(no_mangle)]
pub unsafe extern "C" fn patch_seq_env_get_string(
env_data: *const Value,
env_len: usize,
index: i32,
) -> crate::seqstring::SeqString {
if env_data.is_null() {
panic!("env_get_string: null environment pointer");
}
if index < 0 {
panic!("env_get_string: index cannot be negative: {}", index);
}
let idx = index as usize;
if idx >= env_len {
panic!(
"env_get_string: index {} out of bounds for environment of size {}",
index, env_len
);
}
let value = unsafe { &*env_data.add(idx) };
match value {
Value::String(s) => s.clone(),
_ => panic!(
"env_get_string: expected String at index {}, got {:?}",
index, value
),
}
}
#[unsafe(no_mangle)]
pub unsafe extern "C" fn patch_seq_env_push_string(
stack: Stack,
env_data: *const Value,
env_len: usize,
index: i32,
) -> Stack {
if env_data.is_null() {
panic!("env_push_string: null environment pointer");
}
if index < 0 {
panic!("env_push_string: index cannot be negative: {}", index);
}
let idx = index as usize;
if idx >= env_len {
panic!(
"env_push_string: index {} out of bounds for environment of size {}",
index, env_len
);
}
let value = unsafe { &*env_data.add(idx) };
match value {
Value::String(s) => unsafe { push(stack, Value::String(s.clone())) },
_ => panic!(
"env_push_string: expected String at index {}, got {:?}",
index, value
),
}
}
#[unsafe(no_mangle)]
pub unsafe extern "C" fn patch_seq_env_push_value(
stack: Stack,
env_data: *const Value,
env_len: usize,
index: i32,
) -> Stack {
if env_data.is_null() {
panic!("env_push_value: null environment pointer");
}
if index < 0 {
panic!("env_push_value: index cannot be negative: {}", index);
}
let idx = index as usize;
if idx >= env_len {
panic!(
"env_push_value: index {} out of bounds for environment of size {}",
index, env_len
);
}
let value = unsafe { (*env_data.add(idx)).clone() };
debug_assert!(
!matches!(value, Value::Int(_) | Value::Bool(_) | Value::Float(_)),
"env_push_value called for primitive type {:?} — use the specialized getter",
value
);
unsafe { push(stack, value) }
}
#[unsafe(no_mangle)]
pub unsafe extern "C" fn patch_seq_env_get_bool(
env_data: *const Value,
env_len: usize,
index: i32,
) -> i64 {
if env_data.is_null() {
panic!("env_get_bool: null environment pointer");
}
if index < 0 {
panic!("env_get_bool: index cannot be negative: {}", index);
}
let idx = index as usize;
if idx >= env_len {
panic!(
"env_get_bool: index {} out of bounds for environment of size {}",
index, env_len
);
}
let value = unsafe { &*env_data.add(idx) };
match value {
Value::Bool(b) => {
if *b {
1
} else {
0
}
}
_ => panic!(
"env_get_bool: expected Bool at index {}, got {:?}",
index, value
),
}
}
#[unsafe(no_mangle)]
pub unsafe extern "C" fn patch_seq_env_get_float(
env_data: *const Value,
env_len: usize,
index: i32,
) -> f64 {
if env_data.is_null() {
panic!("env_get_float: null environment pointer");
}
if index < 0 {
panic!("env_get_float: index cannot be negative: {}", index);
}
let idx = index as usize;
if idx >= env_len {
panic!(
"env_get_float: index {} out of bounds for environment of size {}",
index, env_len
);
}
let value = unsafe { &*env_data.add(idx) };
match value {
Value::Float(f) => *f,
_ => panic!(
"env_get_float: expected Float at index {}, got {:?}",
index, value
),
}
}
#[unsafe(no_mangle)]
pub unsafe extern "C" fn patch_seq_env_get_quotation(
env_data: *const Value,
env_len: usize,
index: i32,
) -> i64 {
if env_data.is_null() {
panic!("env_get_quotation: null environment pointer");
}
if index < 0 {
panic!("env_get_quotation: index cannot be negative: {}", index);
}
let idx = index as usize;
if idx >= env_len {
panic!(
"env_get_quotation: index {} out of bounds for environment of size {}",
index, env_len
);
}
let value = unsafe { &*env_data.add(idx) };
match value {
Value::Quotation { impl_, .. } => *impl_ as i64,
_ => panic!(
"env_get_quotation: expected Quotation at index {}, got {:?}",
index, value
),
}
}