use crate::utils::instruction::Extract; use quote::quote; use syn::parse_macro_input; mod utils; /// `run_instruction!(function_name, output_stack, push state, any amount of /// comma separated stacks by name ; (the semicolon instructs use whether the instruction /// has multiple outputs. If ; passed, assumes multiple, without assumes just one output))` /// /// An instruction for int add would be: /// `run_instruction!(_add, int, state, int, int)` /// assuming the _add function takes two integers and returns a single value (Hint: It does). /// /// Important notice: the order in which the last amount /// of stacks are passed in matters. The first `int` identifier will tell /// the macro to pop the top int first, the second `int` will pop the next int /// and so on. This even works with multiple different types of stacks. /// /// Another important notice: This macro generates boundary checking as well. /// If there are not enough items in the stack to run the function, it /// will not be called. /// /// A function with multiple outputs, for example this one: /// ``` /// fn aux_iadd(x: i128, y: i128) -> Option> { /// Some(vec![x + y, x - y]) /// } /// /// // rush_macro::run_instruction!(aux_iadd, int, _state, int, int;); /// ``` /// would have the ; placed at the end of the instruction. Check rush's `tests/instruction_test.rs` /// file for an example using this code. /// /// Suggestion: If you need to pull an index from the int stack, make it the first argument /// to your function. /// /// If there is an instruction with no stacks as input, must put a comma at the end. #[proc_macro] pub fn run_instruction(input: proc_macro::TokenStream) -> proc_macro::TokenStream { let f = parse_macro_input!(input as Extract); quote! { #f }.into() } #[cfg(test)] mod tests { #[test] fn it_works() { assert!(true); } }