bend/fun/transform/
resugar_list.rs1use crate::{
2 fun::{builtins, Pattern, Tag, Term},
3 maybe_grow, AdtEncoding,
4};
5
6impl Term {
7 pub fn resugar_lists(&mut self, adt_encoding: AdtEncoding) {
9 match adt_encoding {
10 AdtEncoding::Scott => self.resugar_lists_scott(),
11 AdtEncoding::NumScott => self.resugar_lists_num_scott(),
12 }
13 }
14
15 fn resugar_lists_num_scott(&mut self) {
17 maybe_grow(|| {
18 if let Term::Ref { nam } = self {
24 if nam == builtins::LNIL {
25 *self = Term::List { els: vec![] };
26 }
27 }
28 if let Term::Lam { tag: Tag::Static, pat, bod } = self {
30 if let Pattern::Var(Some(var_lam)) = pat.as_mut() {
31 if let Term::App { tag: Tag::Static, fun, arg: tail } = bod.as_mut() {
32 if let Term::App { tag: Tag::Static, fun, arg: head } = fun.as_mut() {
33 if let Term::App { tag: Tag::Static, fun, arg } = fun.as_mut() {
34 if let Term::Var { nam: var_app } = fun.as_mut() {
35 if let Term::Ref { nam } = arg.as_mut() {
36 if var_lam == var_app && nam == builtins::LCONS_TAG_REF {
37 let l = build_list_num_scott(tail.as_mut(), vec![std::mem::take(head)]);
38 match l {
39 Ok(l) => *self = Term::List { els: l.into_iter().map(|x| *x).collect() },
40 Err(mut l) => {
42 *head = l.pop().unwrap();
43 assert!(l.is_empty())
44 }
45 }
46 }
47 }
48 }
49 }
50 }
51 }
52 }
53 }
54 if let Term::App { tag: Tag::Static, fun, arg: tail } = self {
56 if let Term::App { tag: Tag::Static, fun, arg: head } = fun.as_mut() {
57 if let Term::Ref { nam } = fun.as_mut() {
58 if nam == builtins::LCONS {
59 let l = build_list_num_scott(tail.as_mut(), vec![std::mem::take(head)]);
60 match l {
61 Ok(l) => *self = Term::List { els: l.into_iter().map(|x| *x).collect() },
62 Err(mut l) => {
64 *head = l.pop().unwrap();
65 assert!(l.is_empty())
66 }
67 }
68 }
69 }
70 }
71 }
72
73 for child in self.children_mut() {
74 child.resugar_lists_num_scott();
75 }
76 })
77 }
78
79 fn resugar_lists_scott(&mut self) {
81 maybe_grow(|| {
82 if let Term::Ref { nam } = self {
88 if nam == builtins::LNIL {
89 *self = Term::List { els: vec![] };
90 }
91 }
92 if let Term::Lam { tag: Tag::Static, pat, bod } = self {
94 if let Pattern::Var(None) = pat.as_mut() {
95 if let Term::Lam { tag: Tag::Static, pat, bod } = bod.as_mut() {
96 if let Pattern::Var(Some(var_lam)) = pat.as_mut() {
97 if let Term::App { tag: Tag::Static, fun, arg: tail } = bod.as_mut() {
98 if let Term::App { tag: Tag::Static, fun, arg: head } = fun.as_mut() {
99 if let Term::Var { nam: var_app } = fun.as_mut() {
100 if var_lam == var_app {
101 let l = build_list_scott(tail.as_mut(), vec![std::mem::take(head)]);
102 match l {
103 Ok(l) => *self = Term::List { els: l.into_iter().map(|x| *x).collect() },
104 Err(mut l) => {
106 *head = l.pop().unwrap();
107 assert!(l.is_empty())
108 }
109 }
110 }
111 }
112 }
113 }
114 }
115 }
116 }
117 }
118 if let Term::App { tag: Tag::Static, fun, arg: tail } = self {
120 if let Term::App { tag: Tag::Static, fun, arg: head } = fun.as_mut() {
121 if let Term::Ref { nam } = fun.as_mut() {
122 if nam == builtins::LCONS {
123 let l = build_list_scott(tail.as_mut(), vec![std::mem::take(head)]);
124 match l {
125 Ok(l) => *self = Term::List { els: l.into_iter().map(|x| *x).collect() },
126 Err(mut l) => {
128 *head = l.pop().unwrap();
129 assert!(l.is_empty())
130 }
131 }
132 }
133 }
134 }
135 }
136
137 for child in self.children_mut() {
138 child.resugar_lists_scott();
139 }
140 })
141 }
142}
143
144#[allow(clippy::vec_box)]
147fn build_list_num_scott(term: &mut Term, mut l: Vec<Box<Term>>) -> Result<Vec<Box<Term>>, Vec<Box<Term>>> {
148 maybe_grow(|| {
149 if let Term::Ref { nam } = term {
151 if nam == builtins::LNIL {
152 return Ok(l);
153 }
154 }
155 if let Term::Lam { tag: Tag::Static, pat, bod } = term {
157 if let Pattern::Var(Some(var_lam)) = pat.as_mut() {
158 if let Term::App { tag: Tag::Static, fun, arg: tail } = bod.as_mut() {
159 if let Term::App { tag: Tag::Static, fun, arg: head } = fun.as_mut() {
160 if let Term::App { tag: Tag::Static, fun, arg } = fun.as_mut() {
161 if let Term::Var { nam: var_app } = fun.as_mut() {
162 if let Term::Ref { nam } = arg.as_mut() {
163 if var_lam == var_app && nam == builtins::LCONS_TAG_REF {
164 l.push(std::mem::take(head));
166 let l = build_list_num_scott(tail, l);
167 match l {
168 Ok(l) => return Ok(l),
169 Err(mut l) => {
170 *head = l.pop().unwrap();
172 return Err(l);
173 }
174 }
175 }
176 }
177 }
178 }
179 }
180 }
181 }
182 }
183 if let Term::App { tag: Tag::Static, fun, arg: tail } = term {
185 if let Term::App { tag: Tag::Static, fun, arg: head } = fun.as_mut() {
186 if let Term::Ref { nam } = fun.as_mut() {
187 if nam == builtins::LCONS {
188 l.push(std::mem::take(head));
190 let l = build_list_num_scott(tail, l);
191 match l {
192 Ok(l) => return Ok(l),
193 Err(mut l) => {
194 *head = l.pop().unwrap();
196 return Err(l);
197 }
198 }
199 }
200 }
201 }
202 }
203 Err(l)
205 })
206}
207
208#[allow(clippy::vec_box)]
209fn build_list_scott(term: &mut Term, mut l: Vec<Box<Term>>) -> Result<Vec<Box<Term>>, Vec<Box<Term>>> {
210 maybe_grow(|| {
211 if let Term::Ref { nam } = term {
213 if nam == builtins::LNIL {
214 return Ok(l);
215 }
216 }
217 if let Term::Lam { tag: Tag::Static, pat, bod } = term {
219 if let Pattern::Var(None) = pat.as_mut() {
220 if let Term::Lam { tag: Tag::Static, pat, bod } = bod.as_mut() {
221 if let Pattern::Var(Some(var_lam)) = pat.as_mut() {
222 if let Term::App { tag: Tag::Static, fun, arg: tail } = bod.as_mut() {
223 if let Term::App { tag: Tag::Static, fun, arg: head } = fun.as_mut() {
224 if let Term::Var { nam: var_app } = fun.as_mut() {
225 if var_lam == var_app {
226 l.push(std::mem::take(head));
228 let l = build_list_scott(tail, l);
229 match l {
230 Ok(l) => return Ok(l),
231 Err(mut l) => {
232 *head = l.pop().unwrap();
234 return Err(l);
235 }
236 }
237 }
238 }
239 }
240 }
241 }
242 }
243 }
244 }
245 if let Term::App { tag: Tag::Static, fun, arg: tail } = term {
247 if let Term::App { tag: Tag::Static, fun, arg: head } = fun.as_mut() {
248 if let Term::Ref { nam } = fun.as_mut() {
249 if nam == builtins::LCONS {
250 l.push(std::mem::take(head));
252 let l = build_list_scott(tail, l);
253 match l {
254 Ok(l) => return Ok(l),
255 Err(mut l) => {
256 *head = l.pop().unwrap();
258 return Err(l);
259 }
260 }
261 }
262 }
263 }
264 }
265 Err(l)
267 })
268}