use crate::stack::{Stack, pop_two, push};
use crate::value::Value;
#[unsafe(no_mangle)]
pub unsafe extern "C" fn patch_seq_push_int(stack: Stack, value: i64) -> Stack {
unsafe { push(stack, Value::Int(value)) }
}
#[unsafe(no_mangle)]
pub unsafe extern "C" fn patch_seq_push_bool(stack: Stack, value: bool) -> Stack {
unsafe { push(stack, Value::Bool(value)) }
}
#[unsafe(no_mangle)]
pub unsafe extern "C" fn patch_seq_add(stack: Stack) -> Stack {
let (rest, a, b) = unsafe { pop_two(stack, "add") };
match (a, b) {
(Value::Int(a_val), Value::Int(b_val)) => unsafe {
push(rest, Value::Int(a_val.wrapping_add(b_val)))
},
_ => panic!("add: expected two integers on stack"),
}
}
#[unsafe(no_mangle)]
pub unsafe extern "C" fn patch_seq_subtract(stack: Stack) -> Stack {
let (rest, a, b) = unsafe { pop_two(stack, "subtract") };
match (a, b) {
(Value::Int(a_val), Value::Int(b_val)) => unsafe {
push(rest, Value::Int(a_val.wrapping_sub(b_val)))
},
_ => panic!("subtract: expected two integers on stack"),
}
}
#[unsafe(no_mangle)]
pub unsafe extern "C" fn patch_seq_multiply(stack: Stack) -> Stack {
let (rest, a, b) = unsafe { pop_two(stack, "multiply") };
match (a, b) {
(Value::Int(a_val), Value::Int(b_val)) => unsafe {
push(rest, Value::Int(a_val.wrapping_mul(b_val)))
},
_ => panic!("multiply: expected two integers on stack"),
}
}
#[unsafe(no_mangle)]
pub unsafe extern "C" fn patch_seq_divide(stack: Stack) -> Stack {
let (rest, a, b) = unsafe { pop_two(stack, "divide") };
match (a, b) {
(Value::Int(_a_val), Value::Int(0)) => {
let stack = unsafe { push(rest, Value::Int(0)) };
unsafe { push(stack, Value::Bool(false)) }
}
(Value::Int(a_val), Value::Int(b_val)) => {
let stack = unsafe { push(rest, Value::Int(a_val.wrapping_div(b_val))) };
unsafe { push(stack, Value::Bool(true)) }
}
_ => {
panic!("divide: expected two integers on stack");
}
}
}
#[unsafe(no_mangle)]
pub unsafe extern "C" fn patch_seq_modulo(stack: Stack) -> Stack {
let (rest, a, b) = unsafe { pop_two(stack, "modulo") };
match (a, b) {
(Value::Int(_a_val), Value::Int(0)) => {
let stack = unsafe { push(rest, Value::Int(0)) };
unsafe { push(stack, Value::Bool(false)) }
}
(Value::Int(a_val), Value::Int(b_val)) => {
let stack = unsafe { push(rest, Value::Int(a_val.wrapping_rem(b_val))) };
unsafe { push(stack, Value::Bool(true)) }
}
_ => {
panic!("modulo: expected two integers on stack");
}
}
}