Skip to main content

seq_runtime/arithmetic/
peek.rs

1//! Peek/pop helpers the compiler uses for conditional branches: extract
2//! the top Int or Bool without moving ownership (`peek_*_value`), then
3//! free the slot (`pop_stack`).
4
5use crate::stack::{Stack, peek, pop};
6use crate::value::Value;
7
8/// # Safety
9/// Stack must not be null and top must be an Int.
10#[unsafe(no_mangle)]
11pub unsafe extern "C" fn patch_seq_peek_int_value(stack: Stack) -> i64 {
12    assert!(!stack.is_null(), "peek_int_value: stack is empty");
13
14    // Peek and extract — use pop/push-free path via peek()
15    let val = unsafe { peek(stack) };
16    match val {
17        Value::Int(i) => i,
18        other => panic!("peek_int_value: expected Int on stack, got {:?}", other),
19    }
20}
21
22/// Peek at a bool value on top of stack without popping (for pattern matching)
23///
24/// # Safety
25/// Stack must have a Bool value on top
26#[unsafe(no_mangle)]
27pub unsafe extern "C" fn patch_seq_peek_bool_value(stack: Stack) -> bool {
28    assert!(!stack.is_null(), "peek_bool_value: stack is empty");
29
30    let val = unsafe { peek(stack) };
31    match val {
32        Value::Bool(b) => b,
33        other => panic!("peek_bool_value: expected Bool on stack, got {:?}", other),
34    }
35}
36
37/// Helper for popping without extracting the value (for conditionals)
38///
39/// Pops the top stack node and returns the updated stack pointer.
40/// Used after peek_int_value to free the condition value's stack node.
41///
42/// Stack effect: ( n -- )
43///
44/// # Safety
45/// Stack must not be empty
46#[unsafe(no_mangle)]
47pub unsafe extern "C" fn patch_seq_pop_stack(stack: Stack) -> Stack {
48    assert!(!stack.is_null(), "pop_stack: stack is empty");
49    let (rest, _value) = unsafe { pop(stack) };
50    rest
51}