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