mod expression_reducer; mod scope; use full_moon::ast::*; use crate::visitor::Visitor; pub struct ConstantFolder { locals: Box> } impl ConstantFolder { pub fn new() -> Self { ConstantFolder{ locals: Box::new(vec![]) } } fn register_local(&mut self, name: String, value: Option) { let locals = &*self.locals; let var = expression_reducer::Variable::with_value( name, value, locals ); self.locals.push(var); } fn assign(&mut self, name: String, value: Option) { let locals = &*self.locals; let var = expression_reducer::Variable::with_value( name, value, locals ); { let mut iter = self.locals.iter_mut(); let it = iter.find(|it| it.name() == var.name()); it.map(|old| old.assign_value(var)); }; } } 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) => { panic!("assignment Var::Expression is not supported") } Var::Name(n) => n.token().to_string(), _ => unreachable!() }); let expr = expressions.next().map(|x| x.clone() /* reduced */); match name { Some(name) => { self.assign(name, expr); } None => { 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); let reduced = expression_reducer::reduce_expression_value_function_call(function_call.clone(), &*self.locals); println!("{:?}", reduced); } 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 */); match name { Some(name) => { self.register_local(name, expr); } None => { 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); } }