use crate::{
fun::{builtins, Name, Num, Pattern, Tag, Term},
maybe_grow, AdtEncoding,
};
impl Term {
pub fn resugar_strings(&mut self, adt_encoding: AdtEncoding) {
match adt_encoding {
AdtEncoding::Scott => self.resugar_strings_scott(),
AdtEncoding::NumScott => self.resugar_strings_num_scott(),
}
}
fn resugar_strings_num_scott(&mut self) {
maybe_grow(|| {
if let Term::Ref { nam } = self {
if nam == builtins::SNIL {
*self = Term::str("");
}
}
if let Term::Lam { tag: Tag::Static, pat, bod } = self {
if let Pattern::Var(Some(var_lam)) = pat.as_mut() {
if let Term::App { tag: Tag::Static, fun, arg: tail } = bod.as_mut() {
if let Term::App { tag: Tag::Static, fun, arg: head } = fun.as_mut() {
if let Term::App { tag: Tag::Static, fun, arg } = fun.as_mut() {
if let Term::Var { nam: var_app } = fun.as_mut() {
if let Term::Ref { nam: Name(nam) } = arg.as_mut() {
if let Term::Num { val: Num::U24(head) } = head.as_mut() {
if var_lam == var_app && nam == builtins::SCONS_TAG_REF {
let head = char::from_u32(*head).unwrap_or(char::REPLACEMENT_CHARACTER);
if let Some(str) = build_string_num_scott(tail, head.to_string()) {
*self = Term::str(&str);
} else {
}
}
}
}
}
}
}
}
}
}
if let Term::App { tag: Tag::Static, fun, arg: tail } = self {
if let Term::App { tag: Tag::Static, fun, arg: head } = fun.as_mut() {
if let Term::Ref { nam } = fun.as_mut() {
if let Term::Num { val: Num::U24(head) } = head.as_mut() {
if nam == builtins::SCONS {
let head = char::from_u32(*head).unwrap_or(char::REPLACEMENT_CHARACTER);
if let Some(str) = build_string_num_scott(tail, head.to_string()) {
*self = Term::str(&str);
} else {
}
}
}
}
}
}
for child in self.children_mut() {
child.resugar_strings_num_scott();
}
})
}
fn resugar_strings_scott(&mut self) {
maybe_grow(|| {
if let Term::Ref { nam } = self {
if nam == builtins::SNIL {
*self = Term::str("");
}
}
if let Term::Lam { tag: Tag::Static, pat, bod } = self {
if let Pattern::Var(None) = pat.as_mut() {
if let Term::Lam { tag: Tag::Static, pat, bod } = bod.as_mut() {
if let Pattern::Var(Some(var_lam)) = pat.as_mut() {
if let Term::App { tag: Tag::Static, fun, arg: tail } = bod.as_mut() {
if let Term::App { tag: Tag::Static, fun, arg: head } = fun.as_mut() {
if let Term::Var { nam: var_app } = fun.as_mut() {
if let Term::Num { val: Num::U24(head) } = head.as_mut() {
if var_lam == var_app {
let head = char::from_u32(*head).unwrap_or(char::REPLACEMENT_CHARACTER);
if let Some(str) = build_string_scott(tail, head.to_string()) {
*self = Term::str(&str);
} else {
}
}
}
}
}
}
}
}
}
}
if let Term::App { tag: Tag::Static, fun, arg: tail } = self {
if let Term::App { tag: Tag::Static, fun, arg: head } = fun.as_mut() {
if let Term::Ref { nam } = fun.as_mut() {
if let Term::Num { val: Num::U24(head) } = head.as_mut() {
if nam == builtins::SCONS {
let head = char::from_u32(*head).unwrap_or(char::REPLACEMENT_CHARACTER);
if let Some(str) = build_string_num_scott(tail, head.to_string()) {
*self = Term::str(&str);
} else {
}
}
}
}
}
}
for child in self.children_mut() {
child.resugar_strings_scott();
}
})
}
}
fn build_string_num_scott(term: &Term, mut s: String) -> Option<String> {
maybe_grow(|| {
if let Term::Ref { nam } = term {
if nam == builtins::SNIL {
return Some(s);
}
}
if let Term::Lam { tag: Tag::Static, pat, bod } = term {
if let Pattern::Var(Some(var_lam)) = pat.as_ref() {
if let Term::App { tag: Tag::Static, fun, arg: tail } = bod.as_ref() {
if let Term::App { tag: Tag::Static, fun, arg: head } = fun.as_ref() {
if let Term::App { tag: Tag::Static, fun, arg } = fun.as_ref() {
if let Term::Var { nam: var_app } = fun.as_ref() {
if let Term::Ref { nam } = arg.as_ref() {
if let Term::Num { val: Num::U24(head) } = head.as_ref() {
if var_lam == var_app && nam == builtins::SCONS_TAG_REF {
let head = char::from_u32(*head).unwrap_or(char::REPLACEMENT_CHARACTER);
s.push(head);
return build_string_num_scott(tail, s);
}
}
}
}
}
}
}
}
}
if let Term::App { tag: Tag::Static, fun, arg: tail } = term {
if let Term::App { tag: Tag::Static, fun, arg: head } = fun.as_ref() {
if let Term::Ref { nam } = fun.as_ref() {
if let Term::Num { val: Num::U24(head) } = head.as_ref() {
if nam == builtins::SCONS {
let head = char::from_u32(*head).unwrap_or(char::REPLACEMENT_CHARACTER);
s.push(head);
return build_string_num_scott(tail, s);
}
}
}
}
}
None
})
}
fn build_string_scott(term: &Term, mut s: String) -> Option<String> {
maybe_grow(|| {
if let Term::Ref { nam } = term {
if nam == builtins::SNIL {
return Some(s);
}
}
if let Term::Lam { tag: Tag::Static, pat, bod } = term {
if let Pattern::Var(None) = pat.as_ref() {
if let Term::Lam { tag: Tag::Static, pat, bod } = bod.as_ref() {
if let Pattern::Var(Some(var_lam)) = pat.as_ref() {
if let Term::App { tag: Tag::Static, fun, arg: tail } = bod.as_ref() {
if let Term::App { tag: Tag::Static, fun, arg: head } = fun.as_ref() {
if let Term::Var { nam: var_app } = fun.as_ref() {
if let Term::Num { val: Num::U24(head) } = head.as_ref() {
if var_lam == var_app {
let head = char::from_u32(*head).unwrap_or(char::REPLACEMENT_CHARACTER);
s.push(head);
return build_string_scott(tail, s);
}
}
}
}
}
}
}
}
}
if let Term::App { tag: Tag::Static, fun, arg: tail } = term {
if let Term::App { tag: Tag::Static, fun, arg: head } = fun.as_ref() {
if let Term::Ref { nam } = fun.as_ref() {
if let Term::Num { val: Num::U24(head) } = head.as_ref() {
if nam == builtins::SCONS {
let head = char::from_u32(*head).unwrap_or(char::REPLACEMENT_CHARACTER);
s.push(head);
return build_string_scott(tail, s);
}
}
}
}
}
None
})
}