Files
luby/crates/luaify/src/transform.rs

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");
}
}