mod expression_reducer; use full_moon::ast::*; use crate::visitor::Visitor; fn is_standard_library(name: String) -> bool { let standard_library_names: Vec<&str> = vec![ "math", "string", "table", "bit" ]; return false } pub struct ConstantFolder { locals: Vec } impl ConstantFolder { pub fn new() -> Self { ConstantFolder{ locals: vec![] } } fn register_local(&mut self, name: Option, value: Option) -> bool { if name.is_none() { return false } self.locals.push( expression_reducer::Variable::with_value( name.unwrap(), value, &self.locals )); true } fn assign(&mut self, name: Option, value: Option) -> bool { if name.is_none() { return false } let var = expression_reducer::Variable::with_value( name.unwrap(), value, &self.locals ); { let mut iter = self.locals.iter_mut(); let it = iter.find(|it| it.name() == var.name()); it.map(|old| old.assign_value(var)); }; true } } impl Visitor for ConstantFolder { fn visit_assignment<'a>(&mut self, assignment: &Assignment<'a>) { let mut names = assignment.variables().iter(); let mut expressions = assignment.expressions().iter(); loop { let name = names.next().map(|x| match x { Var::Expression(var_expr) => { var_expr.to_string() } Var::Name(n) => n.token().to_string(), _ => { "".to_string() } }); let expr = expressions.next().map(|x| x.clone() /* reduced */); if !self.assign(name, expr) { break } } } fn visit_do<'a>(&mut self, do_: &Do<'a>) { println!("visit do {}", do_); } fn visit_function_call<'a>(&mut self, function_call: &FunctionCall<'a>) { println!("visit function_call {}", function_call); } fn visit_function_declaration<'a>(&mut self, function_declaration: &FunctionDeclaration<'a>) { println!("visit function_declaration {}", function_declaration); } fn visit_generic_for<'a>(&mut self, generic_for: &GenericFor<'a>) { println!("visit generic_for {}", generic_for); } fn visit_if<'a>(&mut self, if_: &If<'a>) { println!("visit if {}", if_); } fn visit_local_assignment<'a>(&mut self, local_assignment: &LocalAssignment<'a>) { let mut names = local_assignment.names().iter(); let mut expressions = local_assignment.expressions().iter(); loop { let name = names.next().map(|x| x.token().to_string()); let expr = expressions.next().map(|x| x.clone() /* reduced */); if !self.register_local(name, expr) { break } } } fn visit_local_function<'a>(&mut self, local_function: &LocalFunction<'a>) { println!("visit local_function {}", local_function); } fn visit_numeric_for<'a>(&mut self, numeric_for: &NumericFor<'a>) { println!("visit numeric_for {}", numeric_for); } fn visit_repeat<'a>(&mut self, repeat: &Repeat<'a>) { println!("visit repeat {}", repeat); } fn visit_while<'a>(&mut self, while_: &While<'a>) { println!("visit while {}", while_); } fn visit_goto<'a>(&mut self, goto: &lua52::Goto<'a>) { println!("visit goto {}", goto); } fn visit_label<'a>(&mut self, label: &lua52::Label<'a>) { println!("visit label {}", label); } }