Skip to content

Commit

Permalink
More tail call optimizations
Browse files Browse the repository at this point in the history
  • Loading branch information
Jemtaly authored Sep 10, 2023
1 parent 24e1f64 commit 7605dab
Show file tree
Hide file tree
Showing 4 changed files with 42 additions and 20 deletions.
19 changes: 13 additions & 6 deletions lambda_cbn.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -245,14 +245,21 @@ class Tree {
}
} else if (auto parg = std::get_if<TokenIdx::Arg>(&token)) {
auto &[shr, rec] = **parg;
if (not rec) {
shr.calc();
rec = true;
}
if (parg->use_count() == 1) {
*this = Tree(std::move(shr));
if (not rec) {
*this = Tree(std::move(shr));
TAIL_CALL calc();
} else {
*this = Tree(std::move(shr));
}
} else {
*this = shr;
if (not rec) {
shr.calc();
rec = true;
*this = shr;
} else {
*this = shr;
}
}
} else if (auto ppar = std::get_if<TokenIdx::Par>(&token)) {
throw std::runtime_error("unbound variable: $" + *ppar);
Expand Down
12 changes: 8 additions & 4 deletions lambda_cbn.rs
Original file line number Diff line number Diff line change
Expand Up @@ -165,11 +165,15 @@ impl Tree {
},
Tree::Arg(arg) => {
let (shr, rec) = &mut *arg.borrow_mut();
if !*rec {
*shr = mem::replace(shr, Tree::Empty).calculate()?;
*rec = true;
if Rc::strong_count(&arg) == 1 {
if !*rec { mem::replace(shr, Tree::Empty).calculate() } else { Ok(mem::replace(shr, Tree::Empty)) }
} else {
if !*rec {
*shr = mem::replace(shr, Tree::Empty).calculate()?;
*rec = true;
}
Ok(shr.clone())
}
Ok(if Rc::strong_count(&arg) == 1 { mem::replace(shr, Tree::Empty) } else { shr.clone() })
}
Tree::Par(par) => {
Err(format!("unbound variable: ${}", par))
Expand Down
19 changes: 13 additions & 6 deletions lambda_cbv.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -249,14 +249,21 @@ class Tree {
}
} else if (auto parg = std::get_if<TokenIdx::Arg>(&token)) {
auto &[shr, rec] = **parg;
if (not rec) {
shr.calc();
rec = true;
}
if (parg->use_count() == 1) {
*this = Tree(std::move(shr));
if (not rec) {
*this = Tree(std::move(shr));
TAIL_CALL calc();
} else {
*this = Tree(std::move(shr));
}
} else {
*this = shr;
if (not rec) {
shr.calc();
rec = true;
*this = shr;
} else {
*this = shr;
}
}
} else if (auto ppar = std::get_if<TokenIdx::Par>(&token)) {
throw std::runtime_error("unbound variable: $" + *ppar);
Expand Down
12 changes: 8 additions & 4 deletions lambda_cbv.rs
Original file line number Diff line number Diff line change
Expand Up @@ -168,11 +168,15 @@ impl Tree {
},
Tree::Arg(arg) => {
let (shr, rec) = &mut *arg.borrow_mut();
if !*rec {
*shr = mem::replace(shr, Tree::Empty).calculate(map)?;
*rec = true;
if Rc::strong_count(&arg) == 1 {
if !*rec { mem::replace(shr, Tree::Empty).calculate(map) } else { Ok(mem::replace(shr, Tree::Empty)) }
} else {
if !*rec {
*shr = mem::replace(shr, Tree::Empty).calculate(map)?;
*rec = true;
}
Ok(shr.clone())
}
Ok(if Rc::strong_count(&arg) == 1 { mem::replace(shr, Tree::Empty) } else { shr.clone() })
}
Tree::Par(par) => {
Err(format!("unbound variable: ${}", par))
Expand Down

0 comments on commit 7605dab

Please sign in to comment.