Implement fast pred access function

This commit is contained in:
imaqtkatt 2024-06-24 12:45:15 -03:00
parent 4b131204e4
commit c23952f443
3 changed files with 27 additions and 3 deletions

View File

@ -12,6 +12,7 @@ and this project does not currently adhere to a particular versioning scheme.
- Improve error messages for redefinition of types and objects. ([#485][gh-485])
- Don't allow tabs to be used for indentation or spacing. ([#463][gh-463])
- Rename builtin function `sleep` to `IO/nanosleep`. ([#581][gh-581])
- Equational number pattern compilation to use the predecessor variable when possible. ([#470][gh-470])
### Fixed
@ -333,6 +334,7 @@ and this project does not currently adhere to a particular versioning scheme.
[gh-465]: https://github.com/HigherOrderCO/Bend/issues/465
[gh-466]: https://github.com/HigherOrderCO/Bend/issues/466
[gh-467]: https://github.com/HigherOrderCO/Bend/issues/467
[gh-470]: https://github.com/HigherOrderCO/Bend/issues/470
[gh-475]: https://github.com/HigherOrderCO/Bend/issues/475
[gh-478]: https://github.com/HigherOrderCO/Bend/issues/478
[gh-479]: https://github.com/HigherOrderCO/Bend/issues/479

View File

@ -1,6 +1,7 @@
use crate::{
diagnostics::{Diagnostics, WarningType},
fun::{builtins, Adts, Constructors, Ctx, Definition, FanKind, Name, Num, Pattern, Rule, Tag, Term},
maybe_grow,
};
use std::collections::{BTreeSet, HashSet};
@ -301,8 +302,10 @@ fn num_rule(
let mut body = rule.body.clone();
if let Some(var) = var {
let last_num = *nums.last().unwrap();
let var_recovered = Term::add_num(Term::Var { nam: pred_var.clone() }, Num::U24(1 + last_num));
let curr_num = 1 + last_num;
let var_recovered = Term::add_num(Term::Var { nam: pred_var.clone() }, Num::U24(curr_num));
body = Term::Use { nam: Some(var.clone()), val: Box::new(var_recovered), nxt: Box::new(body) };
fast_pred_access(&mut body, curr_num, var, &pred_var);
}
let rule = Rule { pats: rule.pats[1..].to_vec(), body };
new_rules.push(rule);
@ -340,6 +343,25 @@ fn num_rule(
Ok(term)
}
/// Replaces `body` to `pred_var` if the term is a operation that subtracts the given var by the current
/// switch number.
fn fast_pred_access(body: &mut Term, curr_num: u32, var: &Name, pred_var: &Name) {
maybe_grow(|| {
if let Term::Oper { opr: crate::fun::Op::SUB, fst, snd } = body {
if let Term::Num { val: crate::fun::Num::U24(val) } = &**snd {
if let Term::Var { nam } = &**fst {
if nam == var && *val == curr_num {
*body = Term::Var { nam: pred_var.clone() };
}
}
}
}
for child in body.children_mut() {
fast_pred_access(child, curr_num, var, pred_var)
}
})
}
/// When the first column has constructors, create a branch on the constructors
/// of the first arg.
///

View File

@ -7,7 +7,7 @@ Scott
(pred2) = λa switch a { 0: 0; _: λb switch b { 0: 0; _: λc c; }; }
(pred3) = λa switch a { 0: 0; _: λb switch b { 0: 0; _: λc switch c { 0: 0; _: λd (- (+ d 3) 3); }; }; }
(pred3) = λa switch a { 0: 0; _: λb switch b { 0: 0; _: λc switch c { 0: 0; _: λd d; }; }; }
(zero) = λa switch a { 0: 1; _: λb switch b { 0: 0; _: λ* 0; }; }
@ -18,7 +18,7 @@ NumScott
(pred2) = λa switch a { 0: 0; _: λb switch b { 0: 0; _: λc c; }; }
(pred3) = λa switch a { 0: 0; _: λb switch b { 0: 0; _: λc switch c { 0: 0; _: λd (- (+ d 3) 3); }; }; }
(pred3) = λa switch a { 0: 0; _: λb switch b { 0: 0; _: λc switch c { 0: 0; _: λd d; }; }; }
(zero) = λa switch a { 0: 1; _: λb switch b { 0: 0; _: λ* 0; }; }