69 lines
1.7 KiB
Rust
69 lines
1.7 KiB
Rust
use crate::utils::syn_error;
|
|
use syn::{spanned::*, visit_mut::*, *};
|
|
|
|
pub fn transform(expr: &mut Expr) -> Result<()> {
|
|
let mut visitor = Visitor::new();
|
|
visitor.visit_expr_mut(expr);
|
|
visitor.result
|
|
}
|
|
|
|
pub fn transform_chunk(block: &mut Block) -> Result<()> {
|
|
let mut visitor = Visitor::new();
|
|
visitor.visit_block_mut(block);
|
|
visitor.result
|
|
}
|
|
|
|
#[derive(Debug)]
|
|
struct Visitor {
|
|
result: Result<()>,
|
|
}
|
|
|
|
impl Visitor {
|
|
fn new() -> Self {
|
|
Self { result: Ok(()) }
|
|
}
|
|
}
|
|
|
|
impl VisitMut for Visitor {
|
|
fn visit_expr_unary_mut(&mut self, un: &mut ExprUnary) {
|
|
match self.transform_unary(un) {
|
|
res @ Err(_) => self.result = res,
|
|
_ => visit_expr_unary_mut(self, un),
|
|
}
|
|
}
|
|
|
|
fn visit_expr_match_mut(&mut self, mat: &mut ExprMatch) {
|
|
match self.transform_match(mat) {
|
|
res @ Err(_) => self.result = res,
|
|
_ => visit_expr_match_mut(self, mat),
|
|
}
|
|
}
|
|
}
|
|
|
|
impl Visitor {
|
|
fn transform_unary(&mut self, un: &mut ExprUnary) -> Result<()> {
|
|
//
|
|
// separates a nested negation unary operator with parentheses, because the double hyphen
|
|
// `--` indicates a comment in lua.
|
|
//
|
|
// before:
|
|
// --a
|
|
// after:
|
|
// -(-a)
|
|
//
|
|
if let UnOp::Neg(_) = un.op
|
|
&& let Expr::Unary(ref inner) = *un.expr
|
|
&& let UnOp::Neg(_) = inner.op
|
|
{
|
|
un.expr = Box::new(parse_quote_spanned!(inner.span() => (#inner)));
|
|
}
|
|
|
|
Ok(())
|
|
}
|
|
|
|
fn transform_match(&mut self, mat: &mut ExprMatch) -> Result<()> {
|
|
// TODO:
|
|
syn_error!(mat, "match-to-if transformation not yet implemented");
|
|
}
|
|
}
|