cairo-native 0.9.0-rc.5

A compiler to convert Cairo's IR Sierra code to MLIR and execute it.
use core::nullable::{NullableTrait};
use core::num::traits::Bounded;
use starknet::EthAddress;
use core::dict::{Felt252Dict, Felt252DictTrait};

#[derive(Destruct, Default)]
pub struct Stack {
    pub items: Felt252Dict<Nullable<u256>>,
    pub len: usize,
}

pub trait StackTrait {
    fn new() -> Stack;
    fn push(ref self: Stack, item: u256) -> Result<(), ()>;
    fn pop(ref self: Stack) -> Result<u256, ()>;
    fn peek_at(ref self: Stack, index: usize) -> Result<u256, ()>;
    fn len(self: @Stack) -> usize;
}

impl StackImpl of StackTrait {
    #[inline(always)]
    fn new() -> Stack {
        Default::default()
    }

    /// Pushes a new bytes32 word onto the stack.
    ///
    /// When pushing an item to the stack, we will compute
    /// an index which corresponds to the index in the dict the item will be stored at.
    /// The internal index is computed as follows:
    ///
    /// index = len(Stack_i) + i * STACK_SEGMENT_SIZE
    ///
    /// # Errors
    ///
    /// If the stack is full, returns with a StackOverflow error.
    #[inline(always)]
    fn push(ref self: Stack, item: u256) -> Result<(), ()> {
        let length = self.len();

        self.items.insert(length.into(), NullableTrait::new(item));
        self.len += 1;
        println!("stack_push top {:?}", self.peek_at(0).unwrap());
        Result::Ok(())
    }

    /// Pops the top item off the stack.
    ///
    /// # Errors
    ///
    /// If the stack is empty, returns with a StackOverflow error.
    #[inline(always)]
    fn pop(ref self: Stack) -> Result<u256, ()> {
        self.len -= 1;
        let item = self.items.get(self.len().into());
        println!("stack_pop top {:?}", item.deref());
        Result::Ok(item.deref())
    }

    #[inline(always)]
    fn peek_at(ref self: Stack, index: usize) -> Result<u256, ()> {
        let position = self.len() - 1 - index;
        let item = self.items.get(position.into());

        Result::Ok(item.deref())
    }

    #[inline(always)]
    fn len(self: @Stack) -> usize {
        *self.len
    }
}

pub fn main() -> u256 {
    let mut stack = StackImpl::new();

    stack.push(0).unwrap();
    stack.push(0).unwrap();
    stack.push(0).unwrap();
    stack.push(0).unwrap();
    stack.push(0).unwrap();
    stack.push(4).unwrap();
    stack.pop().unwrap()
}