Merge pull request #188 from HigherOrderCO/feature/sc-439/refactor-some-recursive-passes-to-stack-based

[sc-439] Refactor some recursive passes to stack based
This commit is contained in:
imaqtkatt 2024-02-12 11:36:50 -03:00 committed by GitHub
commit 2bd63b9494
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
24 changed files with 267 additions and 249 deletions

View File

@ -48,8 +48,8 @@ impl Term {
fst.encode_builtins();
snd.encode_builtins();
}
Term::Mat { matched: scrutinee, arms } => {
scrutinee.encode_builtins();
Term::Mat { matched, arms } => {
matched.encode_builtins();
for (pat, arm) in arms {
pat.encode_builtins();
arm.encode_builtins();

View File

@ -37,27 +37,32 @@ impl Book {
impl Pattern {
fn check(&self, arities: &HashMap<Name, usize>) -> Result<(), String> {
match self {
Pattern::Ctr(name, args) => {
let arity = arities.get(name).unwrap();
let args = args.len();
if *arity != args {
Err(format!("Arity error. Constructor '{}' expects {} fields, found {}.", name, arity, args))
} else {
Ok(())
let mut to_check = vec![self];
while let Some(pat) = to_check.pop() {
match pat {
Pattern::Ctr(name, args) => {
let arity = arities.get(name).unwrap();
let args = args.len();
if *arity != args {
return Err(format!(
"Arity error. Constructor '{}' expects {} fields, found {}.",
name, arity, args
));
}
}
}
Pattern::Tup(fst, snd) => {
fst.check(arities)?;
snd.check(arities)
}
Pattern::Lst(els) => {
for el in els {
el.check(arities)?;
Pattern::Tup(fst, snd) => {
to_check.push(fst);
to_check.push(snd);
}
Ok(())
Pattern::Lst(els) => {
for el in els {
to_check.push(el);
}
}
Pattern::Var(..) | Pattern::Num(..) => {}
}
Pattern::Var(..) | Pattern::Num(..) => Ok(()),
}
Ok(())
}
}

View File

@ -59,8 +59,8 @@ impl Term {
val.check_unbound_pats(is_ctr)?;
nxt.check_unbound_pats(is_ctr)?;
}
Term::Mat { matched: scrutinee, arms } => {
scrutinee.check_unbound_pats(is_ctr)?;
Term::Mat { matched, arms } => {
matched.check_unbound_pats(is_ctr)?;
for (pat, body) in arms {
pat.check_unbounds(is_ctr)?;
body.check_unbound_pats(is_ctr)?;

View File

@ -95,8 +95,8 @@ pub fn check_uses<'a>(
check_uses(fst, scope, globals)?;
check_uses(snd, scope, globals)?;
}
Term::Mat { matched: scrutinee, arms } => {
check_uses(scrutinee, scope, globals)?;
Term::Mat { matched, arms } => {
check_uses(matched, scope, globals)?;
for (pat, term) in arms {
pat.names().for_each(|nam| push_scope(Some(nam), scope));

View File

@ -59,11 +59,11 @@ impl fmt::Display for Term {
Term::App { tag, fun, arg } => {
write!(f, "{}({} {})", tag.display_padded(), fun.display_app(tag), arg)
}
Term::Mat { matched: scrutinee, arms } => {
Term::Mat { matched, arms } => {
write!(
f,
"match {} {{ {} }}",
scrutinee,
matched,
DisplayJoin(|| arms.iter().map(|(pat, term)| display!("{}: {}", pat, term)), "; "),
)
}

View File

@ -283,8 +283,8 @@ impl Term {
nxt.subst(from, to);
}
}
Term::Mat { matched: scrutinee, arms } => {
scrutinee.subst(from, to);
Term::Mat { matched, arms } => {
matched.subst(from, to);
for (rule, term) in arms {
let can_subst;
@ -318,8 +318,8 @@ impl Term {
Term::Lnk { nam } if nam == from => {
*self = to.clone();
}
Term::Mat { matched: scrutinee, arms } => {
scrutinee.subst_unscoped(from, to);
Term::Mat { matched, arms } => {
matched.subst_unscoped(from, to);
arms.iter_mut().for_each(|(_, arm)| arm.subst_unscoped(from, to));
}
Term::Lst { els } => els.iter_mut().for_each(|el| el.subst_unscoped(from, to)),
@ -389,8 +389,8 @@ impl Term {
go(fst, free_vars);
go(snd, free_vars);
}
Term::Mat { matched: scrutinee, arms } => {
go(scrutinee, free_vars);
Term::Mat { matched, arms } => {
go(matched, free_vars);
for (rule, term) in arms {
let mut new_scope = IndexMap::new();
@ -430,8 +430,8 @@ impl Term {
Term::Lnk { nam } => {
uses.insert(nam.clone());
}
Term::Mat { matched: scrutinee, arms } => {
go(scrutinee, decls, uses);
Term::Mat { matched, arms } => {
go(matched, decls, uses);
for (_, arm) in arms {
go(arm, decls, uses);
}

View File

@ -209,19 +209,19 @@ impl<'a> Reader<'a> {
term
}
/// Enters both ports 1 and 2 of a node,
/// Returning a Term if is possible to simplify the net, or the Terms on the two ports of the node.
/// Enters both ports 1 and 2 of a node,
/// Returning a Term if is possible to simplify the net, or the Terms on the two ports of the node.
/// The two possible outcomes are always equivalent.
///
/// If:
/// - The node Kind is CON/TUP/DUP
/// - Both ports 1 and 2 are connected to the same node on slots 1 and 2 respectively
/// - That node Kind is the same as the given node Kind
///
/// Then:
/// If:
/// - The node Kind is CON/TUP/DUP
/// - Both ports 1 and 2 are connected to the same node on slots 1 and 2 respectively
/// - That node Kind is the same as the given node Kind
///
/// Then:
/// Reads the port 0 of the connected node, and returns that term.
///
/// Otherwise:
/// Otherwise:
/// Returns the terms on ports 1 and 2 of the given node.
///
/// # Example
@ -230,7 +230,7 @@ impl<'a> Reader<'a> {
/// // λa let (a, b) = a; (a, b)
/// ([a b] [a b])
///
/// // The node `(a, b)` is just a reconstruction of the destructuring of `a`,
/// // The node `(a, b)` is just a reconstruction of the destructuring of `a`,
/// // So we can skip both steps and just return the "value" unchanged:
///
/// // λa a
@ -301,8 +301,8 @@ impl Term {
| Term::Opx { fst, snd, .. } => {
fst.insert_split(split, threshold)? + snd.insert_split(split, threshold)?
}
Term::Mat { matched: scrutinee, arms } => {
let mut n = scrutinee.insert_split(split, threshold)?;
Term::Mat { matched, arms } => {
let mut n = matched.insert_split(split, threshold)?;
for arm in arms {
n += arm.1.insert_split(split, threshold)?;
}
@ -365,8 +365,8 @@ impl Term {
fst.fix_names(id_counter, book);
snd.fix_names(id_counter, book);
}
Term::Mat { matched: scrutinee, arms } => {
scrutinee.fix_names(id_counter, book);
Term::Mat { matched, arms } => {
matched.fix_names(id_counter, book);
for (rule, term) in arms {
if let Pattern::Num(MatchNum::Succ(Some(nam))) = rule {

View File

@ -161,10 +161,10 @@ impl<'a> EncodeTermState<'a> {
Some(Port(app, 2))
}
// core: & cond ~ (zero succ) ret
Term::Mat { matched: scrutinee, arms } => {
Term::Mat { matched, arms } => {
let if_ = self.inet.new_node(Mat);
let cond = self.encode_term(scrutinee, Port(if_, 0));
let cond = self.encode_term(matched, Port(if_, 0));
self.link_local(Port(if_, 0), cond);
debug_assert!(matches!(arms[0].0, Pattern::Num(MatchNum::Zero)));

View File

@ -1,7 +1,7 @@
use std::collections::{hash_map::Entry, HashMap};
use crate::{
term::{Adt, AdtEncoding, Book, Name, Tag, Term, LCONS, LNIL, SCONS, SNIL},
term::{Adt, AdtEncoding, Book, Name, Tag, Term, LIST, STRING},
Warning,
};
use indexmap::IndexSet;
@ -95,44 +95,44 @@ impl Book {
uses: &mut Definitions,
adt_encoding: AdtEncoding,
) {
self.find_manual_adt_encoding(term, uses, adt_encoding);
let mut to_find = vec![term];
match term {
Term::Ref { nam: def_name } => match self.ctrs.get(def_name) {
Some(name) => self.insert_ctrs_used(name, uses, adt_encoding),
None => self.insert_used(def_name, used, uses, adt_encoding),
},
while let Some(term) = to_find.pop() {
self.find_manual_adt_encoding(term, uses, adt_encoding);
Term::Lam { bod, .. } | Term::Chn { bod, .. } => {
self.find_used_definitions(bod, used, uses, adt_encoding)
}
Term::Let { val: fst, nxt: snd, .. }
| Term::Dup { val: fst, nxt: snd, .. }
| Term::App { fun: fst, arg: snd, .. }
| Term::Sup { fst, snd, .. }
| Term::Tup { fst, snd }
| Term::Opx { fst, snd, .. } => {
self.find_used_definitions(fst, used, uses, adt_encoding);
self.find_used_definitions(snd, used, uses, adt_encoding);
}
Term::Mat { matched: scrutinee, arms } => {
self.find_used_definitions(scrutinee, used, uses, adt_encoding);
for (_, term) in arms {
self.find_used_definitions(term, used, uses, adt_encoding);
match term {
Term::Ref { nam: def_name } => match self.ctrs.get(def_name) {
Some(name) => self.insert_ctrs_used(name, uses, adt_encoding),
None => self.insert_used(def_name, used, uses, adt_encoding),
},
Term::Lam { bod, .. } | Term::Chn { bod, .. } => to_find.push(bod),
Term::Let { val: fst, nxt: snd, .. }
| Term::Dup { val: fst, nxt: snd, .. }
| Term::App { fun: fst, arg: snd, .. }
| Term::Sup { fst, snd, .. }
| Term::Tup { fst, snd }
| Term::Opx { fst, snd, .. } => {
to_find.push(fst);
to_find.push(snd);
}
}
Term::Lst { els } => {
self.insert_ctrs_used(&Name::new(LCONS), uses, adt_encoding);
self.insert_ctrs_used(&Name::new(LNIL), uses, adt_encoding);
for term in els {
self.find_used_definitions(term, used, uses, adt_encoding);
Term::Mat { matched, arms } => {
to_find.push(matched);
for (_, bod) in arms {
to_find.push(bod);
}
}
Term::Lst { els } => {
self.insert_ctrs_used(&Name::new(LIST), uses, adt_encoding);
for term in els {
to_find.push(term);
}
}
Term::Str { .. } => {
self.insert_ctrs_used(&Name::new(STRING), uses, adt_encoding);
}
Term::Var { .. } | Term::Lnk { .. } | Term::Num { .. } | Term::Era | Term::Err => (),
}
Term::Str { .. } => {
self.insert_ctrs_used(&Name::new(SCONS), uses, adt_encoding);
self.insert_ctrs_used(&Name::new(SNIL), uses, adt_encoding);
}
Term::Var { .. } | Term::Lnk { .. } | Term::Num { .. } | Term::Era | Term::Err => (),
}
}

View File

@ -13,76 +13,78 @@ impl Book {
impl Term {
pub fn desugar_implicit_match_binds(&mut self, ctrs: &IndexMap<Name, Name>, adts: &IndexMap<Name, Adt>) {
match self {
Term::Mat { matched: scrutinee, .. } => {
let scrutinee = if let Term::Var { nam } = scrutinee.as_ref() {
nam.clone()
} else {
let Term::Mat { matched: scrutinee, arms } = std::mem::take(self) else { unreachable!() };
let mut to_desugar = vec![self];
let nam = Name::new("%temp%scrutinee");
while let Some(term) = to_desugar.pop() {
match term {
Term::Mat { matched, .. } => {
let matched = if let Term::Var { nam } = matched.as_ref() {
nam.clone()
} else {
let Term::Mat { matched, arms } = std::mem::take(term) else { unreachable!() };
*self = Term::Let {
pat: Pattern::Var(Some(nam.clone())),
val: scrutinee,
nxt: Box::new(Term::Mat { matched: Box::new(Term::Var { nam: nam.clone() }), arms }),
let nam = Name::new("%matched");
*term = Term::Let {
pat: Pattern::Var(Some(nam.clone())),
val: matched,
nxt: Box::new(Term::Mat { matched: Box::new(Term::Var { nam: nam.clone() }), arms }),
};
nam
};
nam
};
let (Term::Mat { arms, .. } | Term::Let { nxt: box Term::Mat { arms, .. }, .. }) = term else {
unreachable!()
};
let (Term::Mat { arms, .. } | Term::Let { nxt: box Term::Mat { arms, .. }, .. }) = self else {
unreachable!()
};
for (pat, body) in arms {
match pat {
Pattern::Var(_) => (),
Pattern::Ctr(nam, pat_args) => {
let adt = ctrs.get(nam).unwrap();
let Adt { ctrs, .. } = adts.get(adt).unwrap();
let ctr_args = ctrs.get(nam).unwrap();
if pat_args.is_empty() && !ctr_args.is_empty() {
// Implicit ctr args
*pat_args =
ctr_args.iter().map(|x| Pattern::Var(Some(format!("{scrutinee}.{x}").into()))).collect();
for (pat, body) in arms {
match pat {
Pattern::Var(_) => (),
Pattern::Ctr(nam, pat_args) => {
let adt = ctrs.get(nam).unwrap();
let Adt { ctrs, .. } = adts.get(adt).unwrap();
let ctr_args = ctrs.get(nam).unwrap();
if pat_args.is_empty() && !ctr_args.is_empty() {
// Implicit ctr args
*pat_args =
ctr_args.iter().map(|field| Pattern::Var(Some(format!("{matched}.{field}").into()))).collect();
}
}
Pattern::Num(MatchNum::Zero) => (),
Pattern::Num(MatchNum::Succ(Some(_))) => (),
Pattern::Num(MatchNum::Succ(p @ None)) => {
// Implicit num arg
*p = Some(Some(format!("{matched}-1").into()));
}
Pattern::Tup(_, _) => (),
Pattern::Lst(..) => unreachable!(),
}
Pattern::Num(MatchNum::Zero) => (),
Pattern::Num(MatchNum::Succ(Some(_))) => (),
Pattern::Num(MatchNum::Succ(p @ None)) => {
// Implicit num arg
*p = Some(Some(format!("{scrutinee}-1").into()));
}
Pattern::Tup(_, _) => (),
Pattern::Lst(..) => unreachable!(),
to_desugar.push(body);
}
body.desugar_implicit_match_binds(ctrs, adts);
}
Term::Let { pat: Pattern::Var(_), val: fst, nxt: snd }
| Term::App { fun: fst, arg: snd, .. }
| Term::Dup { val: fst, nxt: snd, .. }
| Term::Tup { fst, snd }
| Term::Sup { fst, snd, .. }
| Term::Opx { fst, snd, .. } => {
to_desugar.push(fst);
to_desugar.push(snd);
}
Term::Lam { bod, .. } | Term::Chn { bod, .. } => to_desugar.push(bod),
Term::Era
| Term::Ref { .. }
| Term::Num { .. }
| Term::Str { .. }
| Term::Lnk { .. }
| Term::Var { .. }
| Term::Err => (),
Term::Let { pat: _, .. } => {
unreachable!("Expected destructor let expressions to have been desugared already")
}
Term::Lst { .. } => unreachable!("Should have been desugared already"),
}
Term::Let { pat: Pattern::Var(_), val: fst, nxt: snd }
| Term::App { fun: fst, arg: snd, .. }
| Term::Dup { val: fst, nxt: snd, .. }
| Term::Tup { fst, snd }
| Term::Sup { fst, snd, .. }
| Term::Opx { fst, snd, .. } => {
fst.desugar_implicit_match_binds(ctrs, adts);
snd.desugar_implicit_match_binds(ctrs, adts);
}
Term::Lam { bod, .. } | Term::Chn { bod, .. } => {
bod.desugar_implicit_match_binds(ctrs, adts);
}
Term::Era
| Term::Ref { .. }
| Term::Num { .. }
| Term::Str { .. }
| Term::Lnk { .. }
| Term::Var { .. }
| Term::Err => (),
Term::Let { pat: _, .. } => {
unreachable!("Expected destructor let expressions to have been desugared already")
}
Term::Lst { .. } => unreachable!("Should have been desugared already"),
}
}
}

View File

@ -23,8 +23,8 @@ impl Term {
fst.desugar_let_destructors();
snd.desugar_let_destructors();
}
Term::Mat { matched: scrutinee, arms } => {
scrutinee.desugar_let_destructors();
Term::Mat { matched, arms } => {
matched.desugar_let_destructors();
for (_, arm) in arms {
arm.desugar_let_destructors();
}

View File

@ -230,8 +230,8 @@ impl Term {
val_detach & nxt_detach
}
Term::Mat { matched: scrutinee, arms } => {
let mut detach = go(scrutinee, depth + 1, term_info);
Term::Mat { matched, arms } => {
let mut detach = go(matched, depth + 1, term_info);
let parent_scope = term_info.replace_scope(HashSet::new());
for (pat, term) in arms {

View File

@ -320,8 +320,8 @@ fn normal_order_step(term: &mut Term) -> bool {
_ => normal_order_step(fun) || normal_order_step(arg),
}
}
Term::Mat { matched: scrutinee, arms } => {
if normal_order_step(scrutinee) {
Term::Mat { matched, arms } => {
if normal_order_step(matched) {
return true;
}
for (_, arm) in arms {
@ -401,8 +401,8 @@ fn subst_rule_body(term: &mut Term, subst_var: &Name, body: &Term, name_gen: &mu
term.subst(subst_var, body);
}
Term::Mat { matched: scrutinee, arms } => {
subst_rule_body(scrutinee, subst_var, body, name_gen);
Term::Mat { matched, arms } => {
subst_rule_body(matched, subst_var, body, name_gen);
for (_, arm) in arms {
subst_rule_body(arm, subst_var, body, name_gen);
}

View File

@ -54,8 +54,8 @@ impl Term {
fst.eta_reduction();
snd.eta_reduction();
}
Term::Mat { matched: scrutinee, arms } => {
scrutinee.eta_reduction();
Term::Mat { matched, arms } => {
matched.eta_reduction();
for (pat, term) in arms {
debug_assert!(pat.is_detached_num_match());
term.eta_reduction();

View File

@ -8,55 +8,58 @@ impl Book {
pub fn inline(&mut self) {
let mut inlineables = HashSet::new();
for (def_name, def) in self.defs.iter() {
def.assert_no_pattern_matching_rules();
if def.rules[0].body.is_inlineable() {
if def.rule().body.is_inlineable() {
inlineables.insert(def_name.clone());
}
}
let defs = self.defs.clone();
for def in self.defs.values_mut() {
def.rules[0].body.inline(&inlineables, &defs);
def.rule_mut().body.inline(&inlineables, &defs);
}
}
}
impl Term {
fn inline(&mut self, inlineables: &HashSet<Name>, defs: &IndexMap<Name, Definition>) {
match self {
Term::Ref { nam: def_name } => {
if inlineables.contains(def_name) {
*self = defs.get(def_name).unwrap().rules[0].body.clone();
let mut to_inline = vec![self];
while let Some(term) = to_inline.pop() {
match term {
Term::Ref { nam: def_name } => {
if inlineables.contains(def_name) {
*term = defs.get(def_name).unwrap().rule().body.clone();
}
}
}
Term::Lam { bod, .. } => bod.inline(inlineables, defs),
Term::Lam { bod, .. } => to_inline.push(bod),
Term::App { fun: fst, arg: snd, .. }
| Term::Dup { val: fst, nxt: snd, .. }
| Term::Opx { fst, snd, .. }
| Term::Sup { fst, snd, .. }
| Term::Tup { fst, snd } => {
fst.inline(inlineables, defs);
snd.inline(inlineables, defs);
}
Term::Mat { arms, .. } => {
for (_, bod) in arms {
bod.inline(inlineables, defs);
Term::App { fun: fst, arg: snd, .. }
| Term::Dup { val: fst, nxt: snd, .. }
| Term::Opx { fst, snd, .. }
| Term::Sup { fst, snd, .. }
| Term::Tup { fst, snd } => {
to_inline.push(fst);
to_inline.push(snd);
}
Term::Mat { arms, .. } => {
for (_, bod) in arms {
to_inline.push(bod);
}
}
Term::Var { .. }
| Term::Chn { .. }
| Term::Lnk { .. }
| Term::Let { .. }
| Term::Num { .. }
| Term::Str { .. }
| Term::Lst { .. }
| Term::Era => {}
Term::Err => unreachable!(),
}
Term::Var { .. }
| Term::Chn { .. }
| Term::Lnk { .. }
| Term::Let { .. }
| Term::Num { .. }
| Term::Str { .. }
| Term::Lst { .. }
| Term::Era => {}
Term::Err => unreachable!(),
}
}

View File

@ -70,8 +70,8 @@ fn count_var_uses_in_term(term: &Term, uses: &mut HashMap<Name, Val>) {
count_var_uses_in_term(fst, uses);
count_var_uses_in_term(snd, uses);
}
Term::Mat { matched: scrutinee, arms } => {
count_var_uses_in_term(scrutinee, uses);
Term::Mat { matched, arms } => {
count_var_uses_in_term(matched, uses);
for (rule, term) in arms {
if let Pattern::Num(MatchNum::Succ(Some(nam))) = rule {
add_var(nam.as_ref(), uses);
@ -211,8 +211,8 @@ fn term_to_affine(
term_to_affine(fst, var_uses, inst_count, let_bodies);
term_to_affine(snd, var_uses, inst_count, let_bodies);
}
Term::Mat { matched: scrutinee, arms } => {
term_to_affine(scrutinee, var_uses, inst_count, let_bodies);
Term::Mat { matched, arms } => {
term_to_affine(matched, var_uses, inst_count, let_bodies);
for (rule, term) in arms {
match rule {
Pattern::Num(MatchNum::Succ(Some(nam))) => {

View File

@ -20,22 +20,26 @@ impl Book {
impl Pattern {
pub fn resolve_ctrs(&mut self, is_ctr: &impl Fn(&Name) -> bool) {
match self {
Pattern::Var(Some(nam)) => {
if is_ctr(nam) {
*self = Pattern::Ctr(nam.clone(), vec![]);
let mut to_resolve = vec![self];
while let Some(pat) = to_resolve.pop() {
match pat {
Pattern::Var(Some(nam)) => {
if is_ctr(nam) {
*pat = Pattern::Ctr(nam.clone(), vec![]);
}
}
}
Pattern::Ctr(_, args) | Pattern::Lst(args) => {
for arg in args {
arg.resolve_ctrs(is_ctr);
Pattern::Ctr(_, args) | Pattern::Lst(args) => {
for arg in args {
to_resolve.push(arg);
}
}
Pattern::Var(None) => (),
Pattern::Num(_) => (),
Pattern::Tup(fst, snd) => {
to_resolve.push(fst);
to_resolve.push(snd);
}
}
Pattern::Var(None) => (),
Pattern::Num(_) => (),
Pattern::Tup(fst, snd) => {
fst.resolve_ctrs(is_ctr);
snd.resolve_ctrs(is_ctr);
}
}
}
@ -43,36 +47,40 @@ impl Pattern {
impl Term {
pub fn resolve_ctrs_in_pats(&mut self, is_ctr: &impl Fn(&Name) -> bool) {
match self {
Term::Let { pat, val, nxt } => {
pat.resolve_ctrs(is_ctr);
val.resolve_ctrs_in_pats(is_ctr);
nxt.resolve_ctrs_in_pats(is_ctr);
}
Term::Mat { matched: scrutinee, arms } => {
scrutinee.resolve_ctrs_in_pats(is_ctr);
for (pat, body) in arms {
let mut to_resolve = vec![self];
while let Some(pat) = to_resolve.pop() {
match pat {
Term::Let { pat, val, nxt } => {
pat.resolve_ctrs(is_ctr);
body.resolve_ctrs_in_pats(is_ctr);
to_resolve.push(val);
to_resolve.push(nxt);
}
Term::Mat { matched, arms } => {
to_resolve.push(matched);
for (pat, body) in arms {
pat.resolve_ctrs(is_ctr);
to_resolve.push(body);
}
}
Term::App { fun: fst, arg: snd, .. }
| Term::Tup { fst, snd }
| Term::Dup { val: fst, nxt: snd, .. }
| Term::Sup { fst, snd, .. }
| Term::Opx { fst, snd, .. } => {
to_resolve.push(fst);
to_resolve.push(snd);
}
Term::Lam { bod, .. } | Term::Chn { bod, .. } => to_resolve.push(bod),
Term::Var { .. }
| Term::Lnk { .. }
| Term::Ref { .. }
| Term::Num { .. }
| Term::Str { .. }
| Term::Lst { .. }
| Term::Era
| Term::Err => (),
}
Term::App { fun: fst, arg: snd, .. }
| Term::Tup { fst, snd }
| Term::Dup { val: fst, nxt: snd, .. }
| Term::Sup { fst, snd, .. }
| Term::Opx { fst, snd, .. } => {
fst.resolve_ctrs_in_pats(is_ctr);
snd.resolve_ctrs_in_pats(is_ctr);
}
Term::Lam { bod, .. } | Term::Chn { bod, .. } => bod.resolve_ctrs_in_pats(is_ctr),
Term::Var { .. }
| Term::Lnk { .. }
| Term::Ref { .. }
| Term::Num { .. }
| Term::Str { .. }
| Term::Lst { .. }
| Term::Era
| Term::Err => (),
}
}
}

View File

@ -86,8 +86,8 @@ impl Term {
fst.resolve_refs(def_names, scope)?;
snd.resolve_refs(def_names, scope)?;
}
Term::Mat { matched: scrutinee, arms } => {
scrutinee.resolve_refs(def_names, scope)?;
Term::Mat { matched, arms } => {
matched.resolve_refs(def_names, scope)?;
for (pat, term) in arms {
let nam = if let Pattern::Num(MatchNum::Succ(Some(nam))) = pat { nam.as_ref() } else { None };
push_scope(nam, scope);

View File

@ -41,8 +41,8 @@ impl Term {
fst.resugar_tagged_scott(book, errs);
snd.resugar_tagged_scott(book, errs);
}
Term::Mat { matched: scrutinee, arms } => {
scrutinee.resugar_tagged_scott(book, errs);
Term::Mat { matched, arms } => {
matched.resugar_tagged_scott(book, errs);
for (_, arm) in arms {
arm.resugar_tagged_scott(book, errs);
}
@ -220,9 +220,9 @@ impl Term {
}
}
let scrutinee = Box::new(std::mem::take(cur));
let matched = Box::new(std::mem::take(cur));
let arms = arms.into_iter().rev().map(|(pat, term)| (pat, std::mem::take(term))).collect();
*self = Term::Mat { matched: scrutinee, arms };
*self = Term::Mat { matched, arms };
self.resugar_tagged_scott(book, errs);
}

View File

@ -38,8 +38,8 @@ impl Term {
// (SNil)
Term::Ref { nam: def_name } if def_name.as_str() == SNIL => *self = Term::Str { val: String::new() },
Term::Mat { matched: scrutinee, arms } => {
scrutinee.resugar_strings();
Term::Mat { matched, arms } => {
matched.resugar_strings();
for (_, arm) in arms {
arm.resugar_strings();
}

View File

@ -56,8 +56,8 @@ pub fn subst_ref_to_ref(term: &mut Term, ref_map: &BTreeMap<Name, Name>) -> bool
let snd_subst = subst_ref_to_ref(snd, ref_map);
fst_subst | snd_subst
}
Term::Mat { matched: scrutinee, arms } => {
let mut subst = subst_ref_to_ref(scrutinee, ref_map);
Term::Mat { matched, arms } => {
let mut subst = subst_ref_to_ref(matched, ref_map);
for (_, term) in arms {
subst |= subst_ref_to_ref(term, ref_map);
}

View File

@ -61,8 +61,8 @@ impl UniqueNameGenerator {
*snd = self.pop(snd.as_ref());
*fst = self.pop(fst.as_ref());
}
Term::Mat { matched: scrutinee, arms } => {
self.unique_names_in_term(scrutinee);
Term::Mat { matched, arms } => {
self.unique_names_in_term(matched);
for (pat, term) in arms {
pat.names().for_each(|nam| self.push(Some(nam)));
self.unique_names_in_term(term);

View File

@ -3,9 +3,9 @@ source: tests/golden_tests.rs
input_file: tests/golden_tests/encode_pattern_match/match_adt_unscoped_var.hvm
---
TaggedScott:
(Foo) = λ$x let %temp%scrutinee = (Some 1); (Bar$match$1_$_Foo$match$1 %temp%scrutinee $x)
(Foo) = λ$x let %matched = (Some 1); (Bar$match$1_$_Foo$match$1 %matched $x)
(Bar) = (let %temp%scrutinee = (Some 1); (Bar$match$1_$_Foo$match$1 %temp%scrutinee $x) λ$x *)
(Bar) = (let %matched = (Some 1); (Bar$match$1_$_Foo$match$1 %matched $x) λ$x *)
(main) = *
@ -16,9 +16,9 @@ TaggedScott:
(Some) = λval #Maybe λNone #Maybe λSome #Maybe.Some.val (Some val)
Scott:
(Foo) = λ$x let %temp%scrutinee = (Some 1); (Bar$match$1_$_Foo$match$1 %temp%scrutinee $x)
(Foo) = λ$x let %matched = (Some 1); (Bar$match$1_$_Foo$match$1 %matched $x)
(Bar) = (let %temp%scrutinee = (Some 1); (Bar$match$1_$_Foo$match$1 %temp%scrutinee $x) λ$x *)
(Bar) = (let %matched = (Some 1); (Bar$match$1_$_Foo$match$1 %matched $x) λ$x *)
(main) = *

View File

@ -3,7 +3,7 @@ source: tests/golden_tests.rs
input_file: tests/golden_tests/encode_pattern_match/match_list_sugar.hvm
---
TaggedScott:
(main) = let %temp%scrutinee = LNil; (main$match$1 %temp%scrutinee)
(main) = let %matched = LNil; (main$match$1 %matched)
(main$match$1) = λa #List (a #List.LCons.head λb #List.LCons.tail λc 1 0)
@ -12,7 +12,7 @@ TaggedScott:
(LCons) = λhead λtail #List λLCons #List λLNil #List.LCons.tail (#List.LCons.head (LCons head) tail)
Scott:
(main) = let %temp%scrutinee = LNil; (main$match$1 %temp%scrutinee)
(main) = let %matched = LNil; (main$match$1 %matched)
(main$match$1) = λa (a λb λc 1 0)