From c23952f443ccf2582fbf2916b4c69e43aedc7956 Mon Sep 17 00:00:00 2001 From: imaqtkatt Date: Mon, 24 Jun 2024 12:45:15 -0300 Subject: [PATCH 1/2] Implement fast pred access function --- CHANGELOG.md | 2 ++ src/fun/transform/desugar_match_defs.rs | 24 ++++++++++++++++++- ...de_pattern_match__match_num_pred.bend.snap | 4 ++-- 3 files changed, 27 insertions(+), 3 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index edce6c016..824d21086 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -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 diff --git a/src/fun/transform/desugar_match_defs.rs b/src/fun/transform/desugar_match_defs.rs index 26d5db1f6..4b79144cf 100644 --- a/src/fun/transform/desugar_match_defs.rs +++ b/src/fun/transform/desugar_match_defs.rs @@ -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. /// diff --git a/tests/snapshots/encode_pattern_match__match_num_pred.bend.snap b/tests/snapshots/encode_pattern_match__match_num_pred.bend.snap index 93d32c985..a3125d796 100644 --- a/tests/snapshots/encode_pattern_match__match_num_pred.bend.snap +++ b/tests/snapshots/encode_pattern_match__match_num_pred.bend.snap @@ -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; }; } From 042773a8370c9da68d46b88fc456263ae1114541 Mon Sep 17 00:00:00 2001 From: imaqtkatt Date: Mon, 24 Jun 2024 13:33:51 -0300 Subject: [PATCH 2/2] Rename current variable --- src/fun/transform/desugar_match_defs.rs | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/src/fun/transform/desugar_match_defs.rs b/src/fun/transform/desugar_match_defs.rs index 4b79144cf..b1b7bb774 100644 --- a/src/fun/transform/desugar_match_defs.rs +++ b/src/fun/transform/desugar_match_defs.rs @@ -302,10 +302,10 @@ fn num_rule( let mut body = rule.body.clone(); if let Some(var) = var { let last_num = *nums.last().unwrap(); - let curr_num = 1 + last_num; - let var_recovered = Term::add_num(Term::Var { nam: pred_var.clone() }, Num::U24(curr_num)); + let cur_num = 1 + last_num; + let var_recovered = Term::add_num(Term::Var { nam: pred_var.clone() }, Num::U24(cur_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); + fast_pred_access(&mut body, cur_num, var, &pred_var); } let rule = Rule { pats: rule.pats[1..].to_vec(), body }; new_rules.push(rule); @@ -345,19 +345,19 @@ fn num_rule( /// 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) { +fn fast_pred_access(body: &mut Term, cur_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 { + if nam == var && *val == cur_num { *body = Term::Var { nam: pred_var.clone() }; } } } } for child in body.children_mut() { - fast_pred_access(child, curr_num, var, pred_var) + fast_pred_access(child, cur_num, var, pred_var) } }) }