use super::handle_expr;
use crate::{foil, foil_expr};
use proc_macro2::TokenStream;
use quote::quote;
use syn::{BinOp, Expr, ExprBinary, Ident};
pub fn handle_binary(expr: &ExprBinary, var: &Ident) -> TokenStream {
let ExprBinary {
left, right, op, ..
} = expr;
let dl = handle_expr(left, var);
let dr = handle_expr(right, var);
match op {
BinOp::Add(_) | BinOp::AddAssign(_) => {
quote! {
#dl + #dr
}
}
BinOp::Div(_) | BinOp::DivAssign(_) => {
quote! {
(#right * #dl - #left * #dr) / (#right * #right)
}
}
BinOp::Mul(_) | BinOp::MulAssign(_) => {
if let Expr::Paren(pl) = *left.clone() {
if let Expr::Paren(pr) = *right.clone() {
foil(&pl, &pr, var)
} else {
foil_expr(right, &pl, var)
}
} else if let Expr::Paren(pr) = *right.clone() {
if let Expr::Paren(pl) = *left.clone() {
foil(&pl, &pr, var)
} else {
foil_expr(left, &pr, var)
}
} else {
quote! {
#dl * #right + #dr * #left
}
}
}
BinOp::Sub(_) | BinOp::SubAssign(_) => {
quote! {
#dl - #dr
}
}
_ => panic!("Unsupported operation!"),
}
}