diff --git a/rush_macro/src/lib.rs b/rush_macro/src/lib.rs index 8ae668b..84e49a3 100644 --- a/rush_macro/src/lib.rs +++ b/rush_macro/src/lib.rs @@ -1,34 +1,16 @@ use crate::utils::canextractstate::Extract; -use crate::utils::extractidents::ExtractIdents; -use crate::utils::varfunc::VarFunc; use quote::quote; use syn::parse_macro_input; mod utils; -/// Runs a function passed as the first argument with a variable amount of functions -/// passed to it afterward. -#[proc_macro] -pub fn run_func(input: proc_macro::TokenStream) -> proc_macro::TokenStream { - let f = parse_macro_input!(input as VarFunc); - quote! { #f }.into() -} - /// Checks to see if extracting values from a state is possible. #[proc_macro] -pub fn run_canextract(input: proc_macro::TokenStream) -> proc_macro::TokenStream { +pub fn run_instruction(input: proc_macro::TokenStream) -> proc_macro::TokenStream { let f = parse_macro_input!(input as Extract); quote! { #f }.into() } -/// Returns the arguments to this proc macro in a usable way to other -/// functions. Check the utils file for a more in depth explanation. -#[proc_macro] -pub fn run_extractidents(input: proc_macro::TokenStream) -> proc_macro::TokenStream { - let f = parse_macro_input!(input as ExtractIdents); - quote! { #f }.into() -} - #[cfg(test)] mod tests { #[test] diff --git a/rush_macro/src/utils/canextractstate.rs b/rush_macro/src/utils/canextractstate.rs index c0b4e80..8a4ac62 100644 --- a/rush_macro/src/utils/canextractstate.rs +++ b/rush_macro/src/utils/canextractstate.rs @@ -1,10 +1,11 @@ -// Extract: State (`,` Stack `:` Amount)* +// This Stack that isn't repeated is the desired output stack. +// Extract: Function, Stack, State, (`,` Stack)* +// +// Function: identifier // // State: identifier // // Stack: identifier -// -// Amount: expression use crate::utils::parse_zero_or_more; use proc_macro2::TokenStream as TokenStream2; @@ -13,20 +14,31 @@ use std::cmp::PartialEq; use syn::parse::{Parse, ParseStream}; pub struct Extract { + func: Function, + out_stack: Stack, state: State, stacks: Vec, } impl Parse for Extract { fn parse(input: ParseStream) -> syn::Result { + let func = input.parse()?; + let out_stack = input.parse()?; let state = input.parse()?; let stacks = parse_zero_or_more(input); - Ok(Extract { state, stacks }) + Ok(Extract { + func, + out_stack, + state, + stacks, + }) } } impl ToTokens for Extract { fn to_tokens(&self, tokens: &mut TokenStream2) { + let inner_func = &self.func; + let inner_out_stack = &self.out_stack.0; let inner_state = &self.state.0; let stacks = &self.stacks; @@ -43,8 +55,16 @@ impl ToTokens for Extract { quote! { #inner_state.#inner_stack.len() >= #count } }); + let values = stacks.iter().map(|stack| { + let inner_stack = &&stack.0; + quote! { #inner_state.#inner_stack.pop().unwrap() } + }); + tokens.extend(quote! { - true #(&& (#conditions))* + if true #(&& (#conditions))* { + let result = vec![#inner_func(#(#values, )*)]; + #inner_state.#inner_out_stack.extend(result.iter()); + } }); } } @@ -53,6 +73,7 @@ struct State(syn::Ident); impl Parse for State { fn parse(input: ParseStream) -> syn::Result { + _ = input.parse::(); syn::Ident::parse(input).map(Self) } } @@ -83,3 +104,17 @@ impl PartialEq for &Stack { self.0 == other.0 } } + +struct Function(syn::Ident); + +impl Parse for Function { + fn parse(input: ParseStream) -> syn::Result { + syn::Ident::parse(input).map(Self) + } +} + +impl ToTokens for Function { + fn to_tokens(&self, tokens: &mut TokenStream2) { + self.0.to_tokens(tokens) + } +} diff --git a/rush_macro/src/utils/extractidents.rs b/rush_macro/src/utils/extractidents.rs deleted file mode 100644 index 0027e95..0000000 --- a/rush_macro/src/utils/extractidents.rs +++ /dev/null @@ -1,65 +0,0 @@ -//! Extracts identifiers from a passed list of them. -//! -//! IdentExtract: identifier CommaIdentifier* -//! -//! CommaIdentifier: (, identifier) -//! -//! For Example: -//! run_extract_idents!(int, int, int) would return (literally): -//! `int, int, int` to rust - -use crate::utils::parse_zero_or_more; -use proc_macro2::TokenStream as TokenStream2; -use quote::{ToTokens, quote}; -use std::io::stdout; -use syn::parse::{Parse, ParseStream}; - -pub struct ExtractIdents { - ident: syn::Ident, - comma_idents: Vec, -} - -impl Parse for ExtractIdents { - fn parse(input: ParseStream) -> syn::Result { - let ident = input.parse()?; - let comma_idents = parse_zero_or_more(input); - Ok(Self { - ident, - comma_idents, - }) - } -} - -impl ToTokens for ExtractIdents { - fn to_tokens(&self, tokens: &mut TokenStream2) { - let first_ident = &self.ident; - let comma_idents = &self.comma_idents; - - /*tokens.extend(quote! { #first_ident }); - for id in comma_idents { - let syn_id = &id.0; - tokens.(syn_id); - }*/ - - let output = quote! { - #first_ident #(, #comma_idents)* - }; - - tokens.extend(output); - } -} - -pub struct CommaIdentifiers(syn::Ident); - -impl Parse for CommaIdentifiers { - fn parse(input: ParseStream) -> syn::Result { - _ = input.parse::()?; - syn::Ident::parse(input).map(Self) - } -} - -impl ToTokens for CommaIdentifiers { - fn to_tokens(&self, tokens: &mut TokenStream2) { - self.0.to_tokens(tokens) - } -} diff --git a/rush_macro/src/utils/extractstate.rs b/rush_macro/src/utils/extractstate.rs deleted file mode 100644 index 3b25241..0000000 --- a/rush_macro/src/utils/extractstate.rs +++ /dev/null @@ -1,8 +0,0 @@ -// The parsing will be same for canextractstate.rs but -// instead of chaining trues at the end, will just chain the values. - -use crate::utils::parse_zero_or_more; -use proc_macro2::TokenStream as TokenStream2; -use quote::{ToTokens, quote}; -use std::cmp::PartialEq; -use syn::parse::{Parse, ParseStream}; diff --git a/rush_macro/src/utils/mod.rs b/rush_macro/src/utils/mod.rs index 0725128..c963bb0 100644 --- a/rush_macro/src/utils/mod.rs +++ b/rush_macro/src/utils/mod.rs @@ -1,9 +1,6 @@ use syn::parse::{Parse, ParseStream}; pub mod canextractstate; -pub mod extractidents; -mod extractstate; -pub mod varfunc; fn parse_zero_or_more(input: ParseStream) -> Vec { let mut result = Vec::new(); diff --git a/rush_macro/src/utils/varfunc.rs b/rush_macro/src/utils/varfunc.rs deleted file mode 100644 index 3812b70..0000000 --- a/rush_macro/src/utils/varfunc.rs +++ /dev/null @@ -1,62 +0,0 @@ -// Run: Function Argument* -// -// Function: identifier -// -// Argument: (, expression) - -use crate::utils::parse_zero_or_more; -use proc_macro2::TokenStream as TokenStream2; -use quote::{ToTokens, quote}; -use syn::parse::{Parse, ParseStream}; - -pub struct VarFunc { - func: Function, - args: Vec, -} - -impl Parse for VarFunc { - fn parse(input: ParseStream) -> syn::Result { - let func = input.parse()?; - let args = parse_zero_or_more(input); - Ok(Self { func, args }) - } -} - -impl ToTokens for VarFunc { - fn to_tokens(&self, tokens: &mut TokenStream2) { - let function = &self.func; - let args = &self.args; - tokens.extend(quote! { - #function(#(#args),*) - }) - } -} - -struct Function(syn::Ident); - -impl Parse for Function { - fn parse(input: ParseStream) -> syn::Result { - syn::Ident::parse(input).map(Self) - } -} - -impl ToTokens for Function { - fn to_tokens(&self, tokens: &mut TokenStream2) { - self.0.to_tokens(tokens) - } -} - -struct Argument(syn::Expr); - -impl Parse for Argument { - fn parse(input: ParseStream) -> syn::Result { - _ = input.parse::()?; - syn::Expr::parse(input).map(Self) - } -} - -impl ToTokens for Argument { - fn to_tokens(&self, tokens: &mut TokenStream2) { - self.0.to_tokens(tokens) - } -} diff --git a/rush_macro/tests/extractidents_test.rs b/rush_macro/tests/extractidents_test.rs deleted file mode 100644 index 94a4b15..0000000 --- a/rush_macro/tests/extractidents_test.rs +++ /dev/null @@ -1,8 +0,0 @@ -use rush_macro::run_extractidents; - -#[test] -fn extractidents_test() { - assert!(true); - - // I'm not sure how to test this tbh. -} diff --git a/rush_macro/tests/var_func_test.rs b/rush_macro/tests/var_func_test.rs deleted file mode 100644 index daaf598..0000000 --- a/rush_macro/tests/var_func_test.rs +++ /dev/null @@ -1,11 +0,0 @@ -use rush_macro::run_func; - -fn uadd(x: usize, y: usize, z: usize) -> usize { - x + y + z -} - -#[test] -fn run_func_test() { - let res = run_func!(uadd, 1, 4, 2); - assert_eq!(res, 7); -} diff --git a/src/instructions/mod.rs b/src/instructions/mod.rs index ec6d49e..93f6e10 100644 --- a/src/instructions/mod.rs +++ b/src/instructions/mod.rs @@ -4,7 +4,7 @@ use crate::instructions::logical::*; use crate::instructions::numeric::*; use crate::instructions::vector::*; use crate::push::state::PushState; -use rush_macro::{run_canextract, run_extractidents, run_func}; +use rush_macro::run_instruction; #[macro_use] pub mod macros { @@ -307,12 +307,10 @@ pub mod macros { /// Runs a function and ensures needed variables are extracted from a state without error macro_rules! make_instruction_new { - ($prefix:ident, $func:ident, $($stacks:ident), *) => { + ($func:ident, $prefix:ident, $out_stack:ident, $($stacks:ident), *) => { paste::item! { pub fn [< $prefix $func >] (state: &mut PushState) { - if run_canextract!(state, run_extractidents!($($stacks), *)) { - $func extract_state_vals!(state, $($stacks), *) - } + run_instruction!($func, $out_stack, state, $($stacks), *); } } }; @@ -799,7 +797,9 @@ mod tests { let mut test_state = EMPTY_STATE; - test_state.int = vec![0, 1]; - let test_instr = make_instruction_new!(int, _test_func, int, int); + test_state.int = vec![1, 2]; + make_instruction_new!(_test_func, int, int, int, int); + int_test_func(&mut test_state); + assert_eq!(vec![3], test_state.int); } } diff --git a/tests/extractstate_test.rs b/tests/extractstate_test.rs index 838f284..35226c5 100644 --- a/tests/extractstate_test.rs +++ b/tests/extractstate_test.rs @@ -1,15 +1,19 @@ use rush::push::state::EMPTY_STATE; -use rush_macro::run_canextract; +use rush_macro::run_instruction; + +fn iadd(x: i128, y: i128) -> i128 { + x + y +} #[test] fn run_extract_test() { let mut test_state = EMPTY_STATE; test_state.int = vec![1, 2]; - let res = run_canextract!(test_state, int, int, float); - assert_eq!(false, res); + run_instruction!(iadd, int, test_state, int, int); + assert_eq!(vec![3], test_state.int); - test_state.int = vec![1, 2]; - let res = run_canextract!(test_state, int, int); - assert_eq!(true, res); + /*test_state.int = vec![1]; + run_instruction!(iadd, int, test_state, int, int); + assert_eq!(vec![1], test_state.int);*/ }