Improve if statement and top-level jump handling
This commit is contained in:
		
							parent
							
								
									704060703b
								
							
						
					
					
						commit
						2a9c03249c
					
				@ -212,8 +212,8 @@ impl Backward {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
pub struct If {
 | 
					pub struct If {
 | 
				
			||||||
	pub cond: Expression,
 | 
						pub cond: Expression,
 | 
				
			||||||
	pub body: Vec<Statement>,
 | 
						pub truthy: Vec<Statement>,
 | 
				
			||||||
	pub other: Option<Vec<Statement>>,
 | 
						pub falsey: Option<Vec<Statement>>,
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
impl If {
 | 
					impl If {
 | 
				
			||||||
@ -222,11 +222,11 @@ impl If {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
		self.cond.accept(visitor);
 | 
							self.cond.accept(visitor);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		for v in &self.body {
 | 
							for v in &self.truthy {
 | 
				
			||||||
			v.accept(visitor);
 | 
								v.accept(visitor);
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		if let Some(v) = &self.other {
 | 
							if let Some(v) = &self.falsey {
 | 
				
			||||||
			for v in v {
 | 
								for v in v {
 | 
				
			||||||
				v.accept(visitor);
 | 
									v.accept(visitor);
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
@ -403,13 +403,11 @@ pub struct Function {
 | 
				
			|||||||
	pub num_param: u32,
 | 
						pub num_param: u32,
 | 
				
			||||||
	pub num_local: u32,
 | 
						pub num_local: u32,
 | 
				
			||||||
	pub num_stack: u32,
 | 
						pub num_stack: u32,
 | 
				
			||||||
	pub body: Vec<Statement>,
 | 
						pub body: Forward,
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
impl Function {
 | 
					impl Function {
 | 
				
			||||||
	pub fn accept<V: Visitor>(&self, visitor: &mut V) {
 | 
						pub fn accept<V: Visitor>(&self, visitor: &mut V) {
 | 
				
			||||||
		for v in &self.body {
 | 
							self.body.accept(visitor);
 | 
				
			||||||
			v.accept(visitor);
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
				
			|||||||
@ -31,8 +31,8 @@ fn local_sum(list: &[Local]) -> u32 {
 | 
				
			|||||||
	list.iter().map(Local::count).sum()
 | 
						list.iter().map(Local::count).sum()
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
fn is_else_stat(list: &[Instruction]) -> bool {
 | 
					fn is_else_stat(inst: &Instruction) -> bool {
 | 
				
			||||||
	list.get(0) == Some(&Instruction::Else)
 | 
						inst == &Instruction::Else
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
impl<'a> Transformer<'a> {
 | 
					impl<'a> Transformer<'a> {
 | 
				
			||||||
@ -51,7 +51,7 @@ impl<'a> Transformer<'a> {
 | 
				
			|||||||
		debug_assert!(self.name != usize::MAX, "Not an indexed value");
 | 
							debug_assert!(self.name != usize::MAX, "Not an indexed value");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		let func = &self.wasm.code_section().unwrap().bodies()[self.name];
 | 
							let func = &self.wasm.code_section().unwrap().bodies()[self.name];
 | 
				
			||||||
		let body = self.new_stored_body(&mut func.code().elements());
 | 
							let body = self.new_forward(&mut func.code().elements());
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		Function {
 | 
							Function {
 | 
				
			||||||
			num_param: self.arity.in_arity[self.name].num_param,
 | 
								num_param: self.arity.in_arity[self.name].num_param,
 | 
				
			||||||
@ -205,7 +205,9 @@ impl<'a> Transformer<'a> {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
		let mut stat = Vec::new();
 | 
							let mut stat = Vec::new();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		while let Some(inst) = list.get(0) {
 | 
							loop {
 | 
				
			||||||
 | 
								let inst = &list[0];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
			*list = &list[1..];
 | 
								*list = &list[1..];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
			if let Ok(op) = UnOp::try_from(inst) {
 | 
								if let Ok(op) = UnOp::try_from(inst) {
 | 
				
			||||||
@ -384,13 +386,17 @@ impl<'a> Transformer<'a> {
 | 
				
			|||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	fn new_if(&mut self, cond: Expression, list: &mut &[Instruction]) -> If {
 | 
						fn new_if(&mut self, cond: Expression, list: &mut &[Instruction]) -> If {
 | 
				
			||||||
		let body = self.new_stored_body(list);
 | 
							let copied = list.clone();
 | 
				
			||||||
		let other = is_else_stat(list).then(|| {
 | 
							let truthy = self.new_stored_body(list);
 | 
				
			||||||
			*list = &list[1..];
 | 
					 | 
				
			||||||
			self.new_stored_body(list)
 | 
					 | 
				
			||||||
		});
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
		If { cond, body, other }
 | 
							let last = copied.len() - list.len() - 1;
 | 
				
			||||||
 | 
							let falsey = is_else_stat(&copied[last]).then(|| self.new_stored_body(list));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							If {
 | 
				
			||||||
 | 
								cond,
 | 
				
			||||||
 | 
								truthy,
 | 
				
			||||||
 | 
								falsey,
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	fn new_backward(&mut self, list: &mut &[Instruction]) -> Backward {
 | 
						fn new_backward(&mut self, list: &mut &[Instruction]) -> Backward {
 | 
				
			||||||
 | 
				
			|||||||
@ -271,7 +271,11 @@ impl If {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
		d.edition.start_if(&var, w)?;
 | 
							d.edition.start_if(&var, w)?;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		self.body.iter().try_for_each(|s| s.output(d, w))?;
 | 
							self.truthy.iter().try_for_each(|s| s.output(d, w))?;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							if let Some(v) = &self.falsey {
 | 
				
			||||||
 | 
								v.iter().try_for_each(|s| s.output(d, w))?;
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		d.edition.end_if(rem, w)?;
 | 
							d.edition.end_if(rem, w)?;
 | 
				
			||||||
		d.label_list.pop().unwrap();
 | 
							d.label_list.pop().unwrap();
 | 
				
			||||||
@ -478,7 +482,7 @@ impl Function {
 | 
				
			|||||||
		self.write_visitor_list(w)?;
 | 
							self.write_visitor_list(w)?;
 | 
				
			||||||
		self.write_variable_list(w)?;
 | 
							self.write_variable_list(w)?;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		self.body.iter().try_for_each(|s| s.output(d, w))?;
 | 
							self.body.output(d, w)?;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		write!(w, "end ")
 | 
							write!(w, "end ")
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
				
			|||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user