macro_optim 1.0.0

A Rust procedural macro crate for optimizing and simplifying various expressions at compile time.
use proc_macro::TokenStream;
use quote::quote;
use syn::{parse_macro_input, Expr, ExprBinary, BinOp, Lit, ExprLit};

#[proc_macro_attribute]
pub fn macro_optim(_attr: TokenStream, item: TokenStream) -> TokenStream {
    let expr = parse_macro_input!(item as Expr);
    let optimized = optimize_expr(expr);
    quote! { #optimized }.into()
}

fn optimize_expr(expr: Expr) -> Expr {
    match expr {
        Expr::Binary(ExprBinary { attrs, left, op, right }) => {
            let left = Box::new(optimize_expr(*left));
            let right = Box::new(optimize_expr(*right));
            
            match (&*left, &op, &*right) {
                (Expr::Lit(ExprLit { lit: Lit::Int(l), .. }), BinOp::Add(_), Expr::Lit(ExprLit { lit: Lit::Int(r), .. })) => {
                    let l_val = l.base10_parse::<i64>().unwrap();
                    let r_val = r.base10_parse::<i64>().unwrap();
                    return Expr::Lit(ExprLit {
                        attrs: vec![],
                        lit: Lit::Int(syn::LitInt::new(&(l_val + r_val).to_string(), proc_macro2::Span::call_site())),
                    });
                },
                (Expr::Lit(ExprLit { lit: Lit::Int(l), .. }), BinOp::Mul(_), Expr::Lit(ExprLit { lit: Lit::Int(r), .. })) => {
                    let l_val = l.base10_parse::<i64>().unwrap();
                    let r_val = r.base10_parse::<i64>().unwrap();
                    return Expr::Lit(ExprLit {
                        attrs: vec![],
                        lit: Lit::Int(syn::LitInt::new(&(l_val * r_val).to_string(), proc_macro2::Span::call_site())),
                    });
                },
                (Expr::Lit(ExprLit { lit: Lit::Float(l), .. }), BinOp::Add(_), Expr::Lit(ExprLit { lit: Lit::Float(r), .. })) => {
                    let l_val = l.base10_parse::<f64>().unwrap();
                    let r_val = r.base10_parse::<f64>().unwrap();
                    return Expr::Lit(ExprLit {
                        attrs: vec![],
                        lit: Lit::Float(syn::LitFloat::new(&(l_val + r_val).to_string(), proc_macro2::Span::call_site())),
                    });
                },
                (Expr::Lit(ExprLit { lit: Lit::Float(l), .. }), BinOp::Mul(_), Expr::Lit(ExprLit { lit: Lit::Float(r), .. })) => {
                    let l_val = l.base10_parse::<f64>().unwrap();
                    let r_val = r.base10_parse::<f64>().unwrap();
                    return Expr::Lit(ExprLit {
                        attrs: vec![],
                        lit: Lit::Float(syn::LitFloat::new(&(l_val * r_val).to_string(), proc_macro2::Span::call_site())),
                    });
                },
                _ => {}
            }
            
            Expr::Binary(ExprBinary { attrs, left, op, right })
        },
        _ => expr,
    }
}