status update

This commit is contained in:
Rowan Torbitzky-Lane 2025-04-17 22:18:23 -05:00
parent 41e2d94e1c
commit cb2e61e8d3
10 changed files with 205 additions and 107 deletions

View File

@ -1,22 +1,34 @@
use crate::utils::extractstate::Extract;
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_extract(input: proc_macro::TokenStream) -> proc_macro::TokenStream {
pub fn run_canextract(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]

View File

@ -0,0 +1,85 @@
// Extract: State (`,` Stack `:` Amount)*
//
// State: identifier
//
// Stack: identifier
//
// Amount: expression
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};
pub struct Extract {
state: State,
stacks: Vec<Stack>,
}
impl Parse for Extract {
fn parse(input: ParseStream) -> syn::Result<Self> {
let state = input.parse()?;
let stacks = parse_zero_or_more(input);
Ok(Extract { state, stacks })
}
}
impl ToTokens for Extract {
fn to_tokens(&self, tokens: &mut TokenStream2) {
let inner_state = &self.state.0;
let stacks = &self.stacks;
let mut counts = Vec::new();
for stack in stacks {
match counts.iter_mut().find(|(x, _)| x == stack) {
Some((_, count)) => *count += 1,
None => counts.push((stack, 1usize)),
}
}
let conditions = counts.iter().map(|(stack, count)| {
let inner_stack = &stack.0;
quote! { #inner_state.#inner_stack.len() >= #count }
});
tokens.extend(quote! {
true #(&& (#conditions))*
});
}
}
struct State(syn::Ident);
impl Parse for State {
fn parse(input: ParseStream) -> syn::Result<Self> {
syn::Ident::parse(input).map(Self)
}
}
impl ToTokens for State {
fn to_tokens(&self, tokens: &mut TokenStream2) {
self.0.to_tokens(tokens)
}
}
struct Stack(syn::Ident);
impl Parse for Stack {
fn parse(input: ParseStream) -> syn::Result<Self> {
_ = input.parse::<syn::Token![,]>();
syn::Ident::parse(input).map(Self)
}
}
impl ToTokens for Stack {
fn to_tokens(&self, tokens: &mut TokenStream2) {
self.0.to_tokens(tokens)
}
}
impl PartialEq<Stack> for &Stack {
fn eq(&self, other: &Stack) -> bool {
self.0 == other.0
}
}

View File

@ -0,0 +1,65 @@
//! 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<CommaIdentifiers>,
}
impl Parse for ExtractIdents {
fn parse(input: ParseStream) -> syn::Result<Self> {
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<Self> {
_ = input.parse::<syn::Token![,]>()?;
syn::Ident::parse(input).map(Self)
}
}
impl ToTokens for CommaIdentifiers {
fn to_tokens(&self, tokens: &mut TokenStream2) {
self.0.to_tokens(tokens)
}
}

View File

@ -1,83 +1,8 @@
// Extract: State (`,` Stack `:` Amount)*
//
// State: identifier
//
// Stack: identifier
//
// Amount: expression
// 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};
pub struct Extract {
state: State,
stacks: Vec<Stack>,
}
impl Parse for Extract {
fn parse(input: ParseStream) -> syn::Result<Self> {
let state = input.parse()?;
let stacks = parse_zero_or_more(input);
Ok(Extract { state, stacks })
}
}
impl ToTokens for Extract {
fn to_tokens(&self, tokens: &mut TokenStream2) {
let inner_state = &self.state.0;
let stacks = &self.stacks;
let mut counts = Vec::new();
for stack in stacks {
match counts.iter_mut().find(|(x, _)| x == stack) {
Some((_, count)) => *count += 1,
None => counts.push((stack, 1)),
}
}
for (stack, count) in counts {
let inner_stack = &stack.0;
tokens.extend(quote! {
#inner_state.#inner_stack < #count
})
}
}
}
struct State(syn::Ident);
impl Parse for State {
fn parse(input: ParseStream) -> syn::Result<Self> {
syn::Ident::parse(input).map(Self)
}
}
impl ToTokens for State {
fn to_tokens(&self, tokens: &mut TokenStream2) {
self.0.to_tokens(tokens)
}
}
struct Stack(syn::Ident);
impl Parse for Stack {
fn parse(input: ParseStream) -> syn::Result<Self> {
_ = input.parse::<syn::Token![,]>();
syn::Ident::parse(input).map(Self)
}
}
impl ToTokens for Stack {
fn to_tokens(&self, tokens: &mut TokenStream2) {
self.0.to_tokens(tokens)
}
}
impl PartialEq<Stack> for &Stack {
fn eq(&self, other: &Stack) -> bool {
self.0 == other.0
}
}

View File

@ -1,6 +1,8 @@
use syn::parse::{Parse, ParseStream};
pub mod extractstate;
pub mod canextractstate;
pub mod extractidents;
mod extractstate;
pub mod varfunc;
fn parse_zero_or_more<T: Parse>(input: ParseStream) -> Vec<T> {

View File

@ -0,0 +1,8 @@
use rush_macro::run_extractidents;
#[test]
fn extractidents_test() {
assert!(true);
// I'm not sure how to test this tbh.
}

View File

@ -4,6 +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};
#[macro_use]
pub mod macros {
@ -309,7 +310,9 @@ pub mod macros {
($prefix:ident, $func:ident, $($stacks:ident), *) => {
paste::item! {
pub fn [< $prefix $func >] (state: &mut PushState) {
run_func!($func, extract_state_vals!(state, $($stacks), *))
if run_canextract!(state, run_extractidents!($($stacks), *)) {
$func extract_state_vals!(state, $($stacks), *)
}
}
}
};
@ -325,16 +328,6 @@ pub mod macros {
($state.$stack.pop().unwrap(), $(extract_state_vals!($state, $rest)), *)
};
}
/// Runs a given function passed in the first argument with all the sequential arguments
/// in order.
macro_rules! run_func_old {
() => {};
($func:ident, $($args:expr), *) => {
$func($($args), *)
};
($($args:expr), *) => { $args, run_func!(*) };
}
}
pub mod code;
@ -787,20 +780,6 @@ mod tests {
use super::*;
use crate::push::state::EMPTY_STATE;
#[test]
fn run_func_test() {
pub fn uadd(x: usize, y: usize, z: usize) -> usize {
x + y + z
}
pub fn make_instruction_expr_test() -> usize {
run_func_old!(uadd, 1, 2, 3)
}
let res = make_instruction_expr_test();
assert_eq!(res, 6);
}
#[test]
fn extract_state_vals_test() {
let mut test_state = EMPTY_STATE;
@ -821,6 +800,6 @@ 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);
let test_instr = make_instruction_new!(int, _test_func, int, int);
}
}

View File

@ -1 +1,2 @@
pub mod instructions;
pub mod push;

View File

@ -21,4 +21,10 @@ fn main() {
code_instructions();
let mut empty_state = EMPTY_STATE;
interpret_program(&mut empty_state, 1000, 1000);
let mut counts: Vec<(&str, usize)> = vec![];
counts.push(("int", 2));
counts.push(("float", 1));
// counts.iter().map()
}

View File

@ -0,0 +1,15 @@
use rush::push::state::EMPTY_STATE;
use rush_macro::run_canextract;
#[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);
test_state.int = vec![1, 2];
let res = run_canextract!(test_state, int, int);
assert_eq!(true, res);
}