@@ -1,18 +1,39 @@
11use core::panic;
2+use murmur3::murmur3_32;
23use num_integer::Integer;
34use std::{
4− cmp::Ordering,
5+ borrow::Borrow,
56 collections::BTreeMap,
67 iter::{once, repeat_n, zip},
78 rc::Rc,
89};
910
1011use crate::{
11− interpreter::{slam, InterpreterContext},
12− noun::{self, cell, Atom, Bite, Noun},
12+ interpreter::{slam_pulled_gate, InterpreterContext, TTanks, EMPTY_TANKS},
13+ noun::{self, cell, AsNoun, Atom, Edge, Hair, Nail, Noun},
1314};
1415
16+fn traverse_iter_result<E: Clone, T: Clone, I: Iterator<Item = Result<T, E>>>(
17+ xs: I,
18+) -> Result<Vec<T>, E> {
19+ let mut target: Vec<T> = Vec::new();
20+
21+ for x in xs {
22+ target.push(x.clone()?)
23+ }
24+
25+ Ok(target)
26+}
27+
1528pub type Jets = BTreeMap<noun::Hash, Jet>;
29+pub type DoubleJets = BTreeMap<noun::Hash, DoubleJet>;
30+
31+pub fn generate_double_jets() -> DoubleJets {
32+ BTreeMap::from([
33+ (210326504639957723220404138306543145797, JUST),
34+ // (255213039400865122956425872354360738044, STIR),
35+ ])
36+}
1637
1738pub fn generate_jets() -> Jets {
1839 BTreeMap::from([
@@ -54,7 +75,7 @@ pub fn generate_jets() -> Jets {
5475 (288515703007942177334798811660651439897, SNAG),
5576 (322006565952434408151902864454572452802, SNIP),
5677 (290837622185731774795798043954046795930, SNOC),
57− (255402796382159268271460433298209603428, SORT),
78+ // (255402796382159268271460433298209603428, SORT),
5879 (10111398404342329752608067595798409804, SPIN),
5980 (209194119090564757355985847956576215234, SPUN),
6081 (103985097318911737222583881947453560061, TURN),
@@ -74,43 +95,76 @@ pub fn generate_jets() -> Jets {
7495 (92956425869648916777812729456192604084, REP),
7596 (302196507237993702819920888576650809366, REV),
7697 (111192034817574564051316537756194881830, RIP),
98+ (194882429025651072335997865399571359986, RUN),
99+ (52890757765966568893620799383929397067, RUT),
100+ (189837220965666741450798472864087835815, SEW),
101+ (122271149828189266412416527758198690539, SWP),
102+ (315388312266248574424227833154020891850, XEB),
103+ (26880808488368366377851132561579207892, CON),
104+ (311027486926441687148059942599447850754, DIS),
105+ (330927609077697663248483044495963838437, MIX),
106+ (39579736615539990724554083585557839000, NOT),
107+ (3482046397915506566435874021936376320, LAST),
108+ (124976064672625230427889101290245200507, TRIP),
109+ (4078279288073906183633157465551067635, MUK),
110+ (261900159748071234702685239353558471892, MUG),
111+ (198191257620924788695943358402651905954, AOR),
112+ (299422828284010240628877806738195667652, DOR),
113+ (166326796552601297695313176538120818632, GOR),
114+ (7942398240152905363972500667649380756, MOR),
115+ (315687984998079865981003916817293521765, LOOK),
77116 ])
78117}
79118
80−pub type Jet = fn(ctx: &InterpreterContext, Rc<Noun>) -> Rc<Noun>;
119+pub type Jet = fn(ctx: &mut InterpreterContext, &Rc<Noun>) -> Result<Rc<Noun>, TTanks>;
120+pub type DoubleJet = fn(ctx: &mut InterpreterContext, &Rc<Noun>, &Rc<Noun>) -> Option<Rc<Noun>>;
81121
82−static BINARY_ATOM: fn(Rc<Noun>, fn(&Atom, &Atom) -> Atom) -> Rc<Noun> =
83− |n: Rc<Noun>, f: fn(&Atom, &Atom) -> Atom| {
84− let Noun::Cell { p, q, .. } = (*n).clone() else {
85− panic!()
86− };
87− Rc::new(Noun::Atom(f(p.as_atom().unwrap(), q.as_atom().unwrap())))
122+static BINARY_ATOM: fn(&Rc<Noun>, fn(&Atom, &Atom) -> Atom) -> Result<Rc<Noun>, TTanks> =
123+ |n: &Rc<Noun>, f: fn(&Atom, &Atom) -> Atom| {
124+ let (p, q) = n.as_cell().ok_or(TTanks::new())?;
125+ Ok(Rc::new(Noun::Atom(f(
126+ p.as_atom().ok_or(TTanks::new())?,
127+ q.as_atom().ok_or(TTanks::new())?,
128+ ))))
88129 };
89130
90−static BINARY_ATOM_LOOB: fn(&InterpreterContext, Rc<Noun>, fn(&Atom, &Atom) -> bool) -> Rc<Noun> =
91− |ctx: &InterpreterContext, n: Rc<Noun>, f: fn(&Atom, &Atom) -> bool| {
92− let Noun::Cell { p, q, .. } = (*n).clone() else {
93− panic!()
94− };
95−
96− if f(p.as_atom().unwrap(), q.as_atom().unwrap()) {
97− ctx.nouns.sig.clone()
131+static BINARY_ATOM_LOOB: fn(
132+ &InterpreterContext,
133+ &Rc<Noun>,
134+ fn(&Atom, &Atom) -> bool,
135+) -> Result<Rc<Noun>, TTanks> =
136+ |ctx: &InterpreterContext, n: &Rc<Noun>, f: fn(&Atom, &Atom) -> bool| {
137+ let (p, q) = n.as_cell().ok_or(TTanks::new())?;
138+
139+ if f(
140+ p.as_atom().ok_or(TTanks::new())?,
141+ q.as_atom().ok_or(TTanks::new())?,
142+ ) {
143+ Ok(ctx.nouns.sig.clone())
98144 } else {
99− ctx.nouns.one.clone()
145+ Ok(ctx.nouns.one.clone())
100146 }
101147 };
102148
103−static BINARY_ATOM_PAIR: fn(Rc<Noun>, fn(&Atom, &Atom) -> (Atom, Atom)) -> Rc<Noun> =
104− |n: Rc<Noun>, f: fn(&Atom, &Atom) -> (Atom, Atom)| {
105− let Noun::Cell { p, q, .. } = (*n).clone() else {
106− panic!()
107− };
108− let (a, b) = f(p.as_atom().unwrap(), q.as_atom().unwrap());
109− cell(Rc::new(Noun::Atom(a)), Rc::new(Noun::Atom(b)))
110− };
149+static BINARY_ATOM_PAIR: fn(
150+ &Rc<Noun>,
151+ fn(&Atom, &Atom) -> (Atom, Atom),
152+) -> Result<Rc<Noun>, TTanks> = |n: &Rc<Noun>, f: fn(&Atom, &Atom) -> (Atom, Atom)| {
153+ let (p, q) = n.as_cell().ok_or(TTanks::new())?;
154+
155+ let (a, b) = f(
156+ p.as_atom().ok_or(TTanks::new())?,
157+ q.as_atom().ok_or(TTanks::new())?,
158+ );
159+ Ok(cell(&Rc::new(Noun::Atom(a)), &Rc::new(Noun::Atom(b))))
160+};
111161
112162static ADD: Jet = |_ctx, n| BINARY_ATOM(n, |a, b| a + b);
113−static DEC: Jet = |_ctx, n| Rc::new(Noun::Atom(n.as_atom().unwrap() - 1u32));
163+static DEC: Jet = |_ctx, n| {
164+ Ok(Rc::new(Noun::Atom(
165+ n.as_atom().ok_or(TTanks::new())? - 1u32,
166+ )))
167+};
114168static DVR: Jet = |_ctx, n| BINARY_ATOM_PAIR(n, |a, b| a.div_rem(&b));
115169static DIV: Jet = |_ctx, n| BINARY_ATOM(n, |a, b| a / b);
116170static GTE: Jet = |ctx, n| BINARY_ATOM_LOOB(ctx, n, |a, b| a >= b);
@@ -124,40 +178,42 @@ static MUL: Jet = |_ctx, n| BINARY_ATOM(n, |a, b| a * b);
124178static SUB: Jet = |_ctx, n| BINARY_ATOM(n, |a, b| a - b);
125179
126180static CAP: Jet = |ctx, n| {
127− let Noun::Atom(n) = (*n).clone() else {
128− panic!()
129− };
130− CAP_ATOM(ctx, n)
181+ let n = n.as_atom().ok_or(TTanks::new())?;
182+ CAP_ATOM(ctx, n.clone())
131183};
132−static CAP_ATOM: fn(&InterpreterContext, Atom) -> Rc<Noun> = |ctx, n: Atom| {
184+
185+static CAP_ATOM: fn(&InterpreterContext, Atom) -> Result<Rc<Noun>, TTanks> = |ctx, n: Atom| {
133186 let mut n_iter = n.iter_u32_digits();
134187
135188 match n_iter.len() {
136− 0 => panic!(),
189+ 0 => Err(TTanks::new()),
137190 1 => CAP_U32(ctx, n_iter.next().unwrap()),
138191 _ => CAP_ATOM(ctx, n >> 1),
139192 }
140193};
141−static CAP_U32: fn(ctx: &InterpreterContext, u32) -> Rc<Noun> = |ctx, n| match n {
142− 0 | 1 => panic!(),
143− 2 => ctx.nouns.two.clone(),
144− 3 => ctx.nouns.three.clone(),
194+static CAP_U32: fn(ctx: &InterpreterContext, u32) -> Result<Rc<Noun>, TTanks> = |ctx, n| match n {
195+ 0 | 1 => Err(TTanks::new()),
196+ 2 => Ok(ctx.nouns.two.clone()),
197+ 3 => Ok(ctx.nouns.three.clone()),
145198 n => CAP_U32(ctx, n >> 1),
146199};
147200
148201static MAS: Jet = |ctx, n| {
149− let Noun::Atom(n) = (*n).clone() else {
150− panic!()
151− };
152− Rc::new(Noun::Atom(MAS_ATOM(ctx, n)))
202+ let n = n.as_atom().ok_or(TTanks::new())?;
203+ Ok(Rc::new(Noun::Atom(
204+ MAS_ATOM(ctx, n.clone()).ok_or(TTanks::new())?,
205+ )))
153206};
154−static MAS_ATOM: fn(&InterpreterContext, Atom) -> Atom = |ctx, n| {
207+static MAS_ATOM: fn(&InterpreterContext, Atom) -> Option<Atom> = |ctx, n| {
155208 let mut n_iter = n.iter_u32_digits();
156209
157210 match n_iter.len() {
158− 0 => panic!(),
159− 1 => Atom::new(vec![MAS_U32(n_iter.next().unwrap())]),
160− _ => (&n & &ctx.big_uints.one) + (MAS_ATOM(ctx, &n >> 1) << 1),
211+ 0 => None,
212+ 1 => match n_iter.next().unwrap() {
213+ 1 => None,
214+ x => Some(Atom::new(vec![MAS_U32(x)])),
215+ },
216+ _ => Some((&n & &ctx.big_uints.one) + (MAS_ATOM(ctx, &n >> 1)? << 1)),
161217 }
162218};
163219static MAS_U32: fn(u32) -> u32 = |n| match n {
@@ -167,26 +223,24 @@ static MAS_U32: fn(u32) -> u32 = |n| match n {
167223};
168224
169225static PEG: Jet = |ctx, n| {
170− let Noun::Cell { p: a, q: b, .. } = (*n).clone() else {
171− panic!()
172− };
226+ let (a, b) = n.as_cell().ok_or(TTanks::new())?;
173227
174− let a = a.as_atom().unwrap();
175− let b = b.as_atom().unwrap();
228+ let a = a.as_atom().ok_or(TTanks::new())?;
229+ let b = b.as_atom().ok_or(TTanks::new())?;
176230
177231 if *a == Atom::ZERO {
178− panic!()
232+ return Err(TTanks::new());
179233 };
180234
181− Rc::new(Noun::Atom(PEG_ATOM(ctx, a, b.clone())))
235+ Ok(Rc::new(Noun::Atom(PEG_ATOM(ctx, a, b.clone())?)))
182236};
183−static PEG_ATOM: fn(&InterpreterContext, &Atom, Atom) -> Atom = |ctx, a, b| {
237+static PEG_ATOM: fn(&InterpreterContext, &Atom, Atom) -> Result<Atom, TTanks> = |ctx, a, b| {
184238 let mut b_iter = b.iter_u32_digits();
185239
186240 match b_iter.len() {
187− 0 => panic!(),
188− 1 => PEG_U32(a, b_iter.next().unwrap()),
189− _ => (&b & &ctx.big_uints.one) + (PEG_ATOM(ctx, a, b >> 1) << 1),
241+ 0 => Err(TTanks::new()),
242+ 1 => Ok(PEG_U32(a, b_iter.next().unwrap())),
243+ _ => Ok((&b & &ctx.big_uints.one) + (PEG_ATOM(ctx, a, b >> 1)? << 1)),
190244 }
191245};
192246static PEG_U32: fn(&Atom, u32) -> Atom = |a, b| match b {
@@ -198,12 +252,12 @@ static PEG_U32: fn(&Atom, u32) -> Atom = |a, b| match b {
198252};
199253
200254static FAND: Jet = |ctx, n| {
201− let (nedl, hstk) = n.as_cell().unwrap();
255+ let (nedl, hstk) = n.as_cell().ok_or(TTanks::new())?;
202256 if nedl.is_sig() || hstk.is_sig() {
203− return ctx.nouns.sig.clone();
257+ return Ok(ctx.nouns.sig.clone());
204258 }
205259
206− let nedl: Vec<Rc<Noun>> = nedl.list_iter().collect();
260+ let nedl: Vec<&Rc<Noun>> = nedl.list_iter().collect();
207261
208262 let mut result: Vec<u32> = Vec::new();
209263
@@ -224,16 +278,16 @@ static FAND: Jet = |ctx, n| {
224278 inner_iter = iter.clone();
225279 }
226280
227− Noun::list(result.iter().map(|a| Noun::from_u32(*a)))
281+ Ok(Noun::list(result.iter().map(|a| Noun::from_u32(*a))))
228282};
229283
230284static FIND: Jet = |ctx, n| {
231− let (nedl, hstk) = n.as_cell().unwrap();
285+ let (nedl, hstk) = n.as_cell().ok_or(TTanks::new())?;
232286 if nedl.is_sig() || hstk.is_sig() {
233− return ctx.nouns.sig.clone();
287+ return Ok(ctx.nouns.sig.clone());
234288 }
235289
236− let nedl: Vec<Rc<Noun>> = nedl.list_iter().collect();
290+ let nedl: Vec<&Rc<Noun>> = nedl.list_iter().collect();
237291
238292 let mut iter = zip(0.., hstk.list_iter());
239293
@@ -246,28 +300,28 @@ static FIND: Jet = |ctx, n| {
246300 .collect::<Vec<_>>()
247301 == nedl
248302 {
249− return Rc::new(Noun::from_u32(i)).unit();
303+ return Ok(Rc::new(Noun::from_u32(i)).unit());
250304 }
251305
252306 inner_iter = iter.clone();
253307 }
254308
255− return ctx.nouns.sig.clone();
309+ return Ok(ctx.nouns.sig.clone());
256310};
257311
258312static FLOP: Jet = |ctx, n| {
259− n.list_iter()
260− .fold(ctx.nouns.sig.clone(), |tail, head| cell(head, tail))
313+ Ok(n.list_iter()
314+ .fold(ctx.nouns.sig.clone(), |tail, head| cell(&head, &tail)))
261315};
262316
263317static GULF: Jet = |_ctx, n| {
264− let (from, to) = n.as_cell().unwrap();
318+ let (from, to) = n.as_cell().ok_or(TTanks::new())?;
265319
266− let mut from = (*from.as_atom().unwrap()).clone();
267− let to = to.as_atom().unwrap().clone();
320+ let mut from = (*from.as_atom().ok_or(TTanks::new())?).clone();
321+ let to = to.as_atom().ok_or(TTanks::new())?.clone();
268322
269323 if from > to {
270− panic!()
324+ return Err(TTanks::new());
271325 }
272326
273327 let mut tmp = Vec::new();
@@ -277,384 +331,434 @@ static GULF: Jet = |_ctx, n| {
277331 from += 1u32;
278332 }
279333
280− Noun::list(tmp.iter().rev().map(|a| Noun::Atom(a.clone())))
334+ Ok(Noun::list(tmp.iter().rev().map(|a| Noun::Atom(a.clone()))))
281335};
282336
283337static INTO: Jet = |_ctx, n| {
284− let (a, b) = n.as_cell().unwrap();
285− let (b, c) = b.as_cell().unwrap();
338+ let (a, b) = n.as_cell().ok_or(TTanks::new())?;
339+ let (b, c) = b.as_cell().ok_or(TTanks::new())?;
286340
287− let mut b_iter = b.as_atom().unwrap().iter_u32_digits();
341+ let mut b_iter = b.as_atom().ok_or(TTanks::new())?.iter_u32_digits();
288342
289343 match b_iter.len() {
290− 0 => cell(c, a),
344+ 0 => Ok(cell(&c, &a)),
291345 1 => {
292346 let l = a.list_iter();
293347 let b = b_iter.next().unwrap() as usize;
294− Noun::list_refs(
348+ Ok(Noun::list_refs(
295349 l.clone()
296350 .take(b)
297351 .chain(once(c))
298352 .chain(l.skip(b))
299353 .collect::<Vec<_>>()
300354 .iter()
301− .map(|x| x.clone()),
302− )
355+ .cloned()
356+ .cloned(),
357+ ))
303358 }
304− _ => Noun::list_refs(
359+ _ => Ok(Noun::list_refs(
305360 a.list_iter()
306361 .chain(once(c))
307362 .collect::<Vec<_>>()
308363 .iter()
309− .map(|x| x.clone()),
310− ),
364+ .cloned()
365+ .cloned(),
366+ )),
311367 }
312368};
313369
314370static JOIN: Jet = |_ctx, n| {
315− let (sep, list) = n.as_cell().unwrap();
316− Noun::list_refs(
371+ let (sep, list) = n.as_cell().ok_or(TTanks::new())?;
372+ Ok(Noun::list_refs(
317373 list.list_iter()
318374 .intersperse(sep)
319375 .collect::<Vec<_>>()
320376 .iter()
321− .map(|x| x.clone()),
322− )
377+ .cloned()
378+ .cloned(),
379+ ))
323380};
324381
325−static LENT: Jet = |_ctx, n| Rc::new(Noun::from_u32(n.list_iter().fold(0u32, |l, _| l + 1)));
382+static LENT: Jet = |_ctx, n| {
383+ Ok(Rc::new(Noun::from_u32(
384+ n.list_iter().fold(0u32, |l, _| l + 1),
385+ )))
386+};
326387
327388static LEVY: Jet = |ctx, n| {
328− let (a, b) = n.as_cell().unwrap();
329− if a.list_iter()
330− .all(|n| slam(ctx, b.clone(), n) == ctx.nouns.y)
389+ let (a, b) = n.as_cell().ok_or(TTanks::new())?;
390+ if traverse_iter_result(a.list_iter().map(|n| slam_pulled_gate(ctx, b, n)))?
391+ .iter()
392+ .all(|x| x.is_y())
331393 {
332− ctx.nouns.y.clone()
394+ Ok(ctx.nouns.y.clone())
333395 } else {
334− ctx.nouns.n.clone()
396+ Ok(ctx.nouns.n.clone())
335397 }
336398};
337399
338400static LIEN: Jet = |ctx, n| {
339− let (a, b) = n.as_cell().unwrap();
340− if a.list_iter()
341− .any(|n| slam(ctx, b.clone(), n) == ctx.nouns.y)
401+ let (a, b) = n.as_cell().ok_or(TTanks::new())?;
402+ if traverse_iter_result(a.list_iter().map(|n| slam_pulled_gate(ctx, b, n)))?
403+ .iter()
404+ .any(|x| x.is_y())
342405 {
343− ctx.nouns.y.clone()
406+ Ok(ctx.nouns.y.clone())
344407 } else {
345− ctx.nouns.n.clone()
408+ Ok(ctx.nouns.n.clone())
346409 }
347410};
348411
349412static MURN: Jet = |ctx, n| {
350− let (a, b) = n.as_cell().unwrap();
413+ let (a, b) = n.as_cell().ok_or(TTanks::new())?;
351414
352− Noun::list_refs(
353− a.list_iter()
354− .filter_map(|n| slam(ctx, b.clone(), n).as_unit())
355− .collect::<Vec<_>>()
356− .iter()
357− .map(|x| x.clone()),
358− )
415+ Ok(Noun::list_refs(
416+ traverse_iter_result(
417+ a.list_iter()
418+ .map(|n| Ok(slam_pulled_gate(ctx, b, n)?.as_unit().cloned())),
419+ )?
420+ .iter()
421+ .filter_map(|x| x.clone()),
422+ ))
359423};
360424
361425static REAP: Jet = |_ctx, n| {
362− let (a, b) = n.as_cell().unwrap();
426+ let (a, b) = n.as_cell().ok_or(TTanks::new())?;
363427
364− Noun::list_refs(repeat_n(b, a.as_u32().unwrap() as usize))
428+ Ok(Noun::list_refs(repeat_n(
429+ b.clone(),
430+ a.as_u32().unwrap() as usize,
431+ )))
365432};
366433
367−static REAR: Jet = |_ctx, n| n.list_iter().last().unwrap();
434+static REAR: Jet = |_ctx, n| n.list_iter().last().ok_or(TTanks::new()).cloned();
368435
369436static REEL: Jet = |ctx, n| {
370− let (list, gate) = n.as_cell().unwrap();
437+ let (list, gate) = n.as_cell().ok_or(TTanks::new())?;
371438
372439 list.list_iter().collect::<Vec<_>>().iter().rfold(
373− gate.clone().gate_sample().unwrap().as_cell().unwrap().1,
374− |acc, next| slam(ctx, gate.clone(), cell(next.clone(), acc)),
440+ Ok(gate
441+ .gate_sample()
442+ .ok_or(TTanks::new())?
443+ .as_cell()
444+ .ok_or(TTanks::new())?
445+ .1
446+ .clone()),
447+ |acc, next| {
448+ let acc = acc?;
449+ slam_pulled_gate(ctx, gate, &cell(&next, &acc))
450+ },
375451 )
376452};
377453
378454static ROLL: Jet = |ctx, n| {
379− let (list, gate) = n.as_cell().unwrap();
455+ let (list, gate) = n.as_cell().ok_or(TTanks::new())?;
380456
381457 list.list_iter().fold(
382− gate.clone().gate_sample().unwrap().as_cell().unwrap().1,
383− |acc, next| slam(ctx, gate.clone(), cell(next.clone(), acc)),
458+ Ok(gate
459+ .clone()
460+ .gate_sample()
461+ .ok_or(TTanks::new())?
462+ .as_cell()
463+ .ok_or(TTanks::new())?
464+ .1
465+ .clone()),
466+ |acc, next| {
467+ let acc = acc?;
468+ slam_pulled_gate(ctx, gate, &cell(&next, &acc))
469+ },
384470 )
385471};
386472
387473static SCAG: Jet = |_ctx, n| {
388− let (a, b) = n.as_cell().unwrap();
474+ let (a, b) = n.as_cell().ok_or(TTanks::new())?;
389475
390− Noun::list_refs(
476+ Ok(Noun::list_refs(
391477 b.list_iter()
392478 .take(a.as_u32().unwrap() as usize)
393479 .collect::<Vec<_>>()
394480 .iter()
395− .map(|x| x.clone()),
396− )
481+ .cloned()
482+ .cloned(),
483+ ))
397484};
398485
399486static SKID: Jet = |ctx, n| {
400− let (list, gate) = n.as_cell().unwrap();
487+ let (list, gate) = n.as_cell().ok_or(TTanks::new())?;
401488
402− let (ys, ns): (Vec<Rc<Noun>>, _) = list
403− .list_iter()
404− .partition(|n| slam(ctx, gate.clone(), n.clone()).is_y());
489+ let slammed_n = traverse_iter_result(
490+ list.list_iter()
491+ .map(|n| Ok((slam_pulled_gate(ctx, gate, n)?, n))),
492+ )?;
493+ let (ys, ns): (Vec<_>, _) = slammed_n.iter().partition(|(l, _)| l.is_y());
405494
406− cell(
407− Noun::list_refs(ys.iter().cloned()),
408− Noun::list_refs(ns.iter().cloned()),
409− )
495+ Ok(cell(
496+ &Noun::list_refs(ys.iter().map(|(_, x)| (*x).clone())),
497+ &Noun::list_refs(ns.iter().map(|(_, x)| (*x).clone())),
498+ ))
410499};
411500
412501static SKIM: Jet = |ctx, n| {
413− let (list, gate) = n.as_cell().unwrap();
502+ let (list, gate) = n.as_cell().ok_or(TTanks::new())?;
414503
415− Noun::list_refs(
416− list.list_iter()
417− .filter(|n| slam(ctx, gate.clone(), n.clone()).is_y())
418− .collect::<Vec<_>>()
419− .iter()
420− .cloned(),
421− )
504+ Ok(Noun::list_refs(
505+ traverse_iter_result(
506+ list.list_iter()
507+ .map(|n| Ok((slam_pulled_gate(ctx, gate, n)?, n))),
508+ )?
509+ .iter()
510+ .filter(|(l, _)| l.is_y())
511+ .map(|(_, x)| (*x).clone()),
512+ ))
422513};
423514
424515static SKIP: Jet = |ctx, n| {
425− let (list, gate) = n.as_cell().unwrap();
516+ let (list, gate) = n.as_cell().ok_or(TTanks::new())?;
426517
427− Noun::list_refs(
428− list.list_iter()
429− .filter(|n| slam(ctx, gate.clone(), n.clone()).is_n())
430− .collect::<Vec<_>>()
431− .iter()
432− .cloned(),
433− )
518+ Ok(Noun::list_refs(
519+ traverse_iter_result(
520+ list.list_iter()
521+ .map(|n| Ok((slam_pulled_gate(ctx, gate, n)?, n))),
522+ )?
523+ .iter()
524+ .filter(|(l, _)| l.is_y())
525+ .map(|(_, x)| (*x).clone()),
526+ ))
434527};
435528
436529static SLAG: Jet = |ctx, n| {
437− let (a, list) = n.as_cell().unwrap();
530+ let (a, list) = n.as_cell().ok_or(TTanks::new())?;
438531
439− let mut a_iter = a.as_atom().unwrap().iter_u32_digits();
532+ let mut a_iter = a.as_atom().ok_or(TTanks::new())?.iter_u32_digits();
440533
441534 match a_iter.len() {
442− 0 => list,
443− 1 => Noun::list_refs(
535+ 0 => Ok(list.clone()),
536+ 1 => Ok(Noun::list_refs(
444537 list.list_iter()
445538 .skip(a_iter.next().unwrap() as usize)
446539 .collect::<Vec<_>>()
447540 .iter()
541+ .cloned()
448542 .cloned(),
449− ),
450− _ => ctx.nouns.sig.clone(),
543+ )),
544+ _ => Ok(ctx.nouns.sig.clone()),
451545 }
452546};
453547
454548static SNAG: Jet = |_ctx, n| {
455− let (a, list) = n.as_cell().unwrap();
549+ let (a, list) = n.as_cell().ok_or(TTanks::new())?;
456550
457− list.list_iter().nth(a.as_u32().unwrap() as usize).unwrap()
551+ list.list_iter()
552+ .nth(a.as_u32().unwrap() as usize)
553+ .cloned()
554+ .ok_or(TTanks::new())
458555};
459556
460557static SNIP: Jet = |_ctx, n| {
461− Noun::list_refs(
558+ Ok(Noun::list_refs(
462559 n.list_iter()
463560 .collect::<Vec<_>>()
464561 .iter()
465562 .rev()
466563 .skip(1)
467564 .rev()
565+ .cloned()
468566 .cloned(),
469− )
567+ ))
470568};
471569
472570static SNOC: Jet = |_ctx, n| {
473− let (list, b) = n.as_cell().unwrap();
571+ let (list, b) = n.as_cell().ok_or(TTanks::new())?;
474572
475− Noun::list_refs(
573+ Ok(Noun::list_refs(
476574 list.list_iter()
477575 .chain(once(b))
478576 .collect::<Vec<_>>()
479577 .iter()
578+ .cloned()
480579 .cloned(),
481− )
580+ ))
482581};
483582
484−static SORT: Jet = |ctx, n| {
485− let (list, lth) = n.as_cell().unwrap();
583+// static SORT: Jet = |ctx, n| {
584+// let (list, lth) = n.as_cell().unwrap();
486585
487− let mut v: Vec<_> = list.list_iter().collect();
586+// let mut v: Vec<_> = list.list_iter().collect();
488587
489− v.sort_by(|a, b| {
490− if slam(ctx, lth.clone(), cell(a.clone(), b.clone())).is_y() {
491− Ordering::Less
492− } else if slam(ctx, lth.clone(), cell(b.clone(), a.clone())).is_y() {
493− Ordering::Greater
494− } else {
495− Ordering::Equal
496− }
497− });
588+// v.sort_by(|a, b| {
589+// if slam(ctx, lth.clone(), cell(a.clone(), b.clone())) == ctx.nouns.some_y {
590+// Ordering::Less
591+// } else if slam(ctx, lth.clone(), cell(b.clone(), a.clone())) == ctx.nouns.some_y {
592+// Ordering::Greater
593+// } else {
594+// Ordering::Equal
595+// }
596+// });
498597
499− Noun::list_refs(v.iter().cloned())
500−};
598+// Some(Noun::list_refs(v.iter().cloned()))
599+// };
501600
502601static SPIN: Jet = |ctx, n| {
503− let (list, b) = n.as_cell().unwrap();
504− let (mut acc, gate) = b.as_cell().unwrap();
602+ let (list, b) = n.as_cell().ok_or(TTanks::new())?;
603+ let (acc, gate) = b.as_cell().ok_or(TTanks::new())?;
505604
506605 let mut res = Vec::new();
606+ let mut acc = acc.clone();
507607
508608 for n in list.list_iter() {
509− let (el, new_acc) = slam(ctx, gate.clone(), cell(n, acc)).as_cell().unwrap();
510− acc = new_acc;
511− res.push(el);
609+ let foo = slam_pulled_gate(ctx, gate, &cell(&n, &acc))?;
610+ let (el, new_acc) = foo.as_cell().ok_or(TTanks::new())?;
611+ acc = new_acc.clone();
612+ res.push(el.clone());
512613 }
513614
514− cell(Noun::list_refs(res.iter().cloned()), acc)
615+ Ok(cell(&Noun::list_refs(res.iter().cloned()), &acc))
515616};
516617
517618static SPUN: Jet = |ctx, n| {
518− let (list, gate) = n.as_cell().unwrap();
619+ let (list, gate) = n.as_cell().ok_or(TTanks::new())?;
519620
520621 let mut res = Vec::new();
521− let mut acc = gate.clone().gate_sample().unwrap().as_cell().unwrap().1;
622+ let mut acc = gate
623+ .gate_sample()
624+ .ok_or(TTanks::new())?
625+ .as_cell()
626+ .ok_or(TTanks::new())?
627+ .1
628+ .clone();
522629
523630 for n in list.list_iter() {
524− let (el, new_acc) = slam(ctx, gate.clone(), cell(n, acc)).as_cell().unwrap();
525− acc = new_acc;
526− res.push(el);
631+ let foo = slam_pulled_gate(ctx, gate, &cell(&n, &acc))?;
632+ let (el, new_acc) = foo.as_cell().ok_or(TTanks::new())?;
633+ acc = new_acc.clone();
634+ res.push(el.clone());
527635 }
528636
529− cell(Noun::list_refs(res.iter().cloned()), acc)
637+ Ok(cell(&Noun::list_refs(res.iter().cloned()), &acc))
530638};
531639
532640static TURN: Jet = |ctx, n| {
533− let (list, gate) = n.as_cell().unwrap();
534− Noun::list_refs(
535− list.list_iter()
536− .map(|x| slam(ctx, gate.clone(), x))
537− .collect::<Vec<_>>()
641+ let (list, gate) = n.as_cell().ok_or(TTanks::new())?;
642+ Ok(Noun::list_refs(
643+ traverse_iter_result(list.list_iter().map(|x| slam_pulled_gate(ctx, gate, x)))?
538644 .iter()
539645 .cloned(),
540− )
646+ ))
541647};
542648
543649static WELD: Jet = |_ctx, n| {
544− let (a, b) = n.as_cell().unwrap();
650+ let (a, b) = n.as_cell().ok_or(TTanks::new())?;
545651
546− Noun::list_refs(
652+ Ok(Noun::list_refs(
547653 a.list_iter()
548654 .chain(b.list_iter())
549655 .collect::<Vec<_>>()
550656 .iter()
657+ .cloned()
551658 .cloned(),
552− )
659+ ))
553660};
554661
555662static WELP: Jet = WELD;
556663
557664static ZING: Jet = |_ctx, n| {
558− Noun::list_refs(
665+ Ok(Noun::list_refs(
559666 n.list_iter()
560667 .map(|l| l.list_iter())
561668 .flatten()
562669 .collect::<Vec<_>>()
563670 .iter()
671+ .cloned()
564672 .cloned(),
565− )
673+ ))
566674};
567675
568−static BEX: Jet = |ctx, n| Rc::new(Noun::Atom(&ctx.big_uints.one << n.as_u32().unwrap()));
676+static BEX: Jet = |ctx, n| {
677+ Ok(Rc::new(Noun::Atom(
678+ &ctx.big_uints.one << n.as_u32().unwrap(),
679+ )))
680+};
569681
570682static END: Jet = |ctx, n| {
571− let (a, b) = n.as_cell().unwrap();
572− let bite = a.as_bite().unwrap();
683+ let (a, b) = n.as_cell().ok_or(TTanks::new())?;
684+ let bite = a.as_bite();
573685
574686 let bits = bite.bits();
575687
576688 let mask = (&ctx.big_uints.one << bits) - &ctx.big_uints.one;
577689
578− Rc::new(Noun::Atom(mask & b.as_atom().unwrap()))
690+ Ok(Rc::new(Noun::Atom(
691+ mask & b.as_atom().ok_or(TTanks::new())?,
692+ )))
579693};
580694
581695static CAN: Jet = |ctx, n| {
582− let (a, b) = n.as_cell().unwrap();
696+ let (a, b) = n.as_cell().ok_or(TTanks::new())?;
583697 let bloq = a.as_u32().unwrap();
584698 let bloq_ = 2u32.pow(bloq);
585699
586− let atom: Atom =
587− b.list_iter()
588− .collect::<Vec<_>>()
589− .iter()
590− .rfold(ctx.big_uints.zero.clone(), |acc, next| {
591− let (p, q) = next.as_cell().unwrap();
592− let step = p.as_u32().unwrap();
593− let bits = bloq_ * step;
594− let mask = (&ctx.big_uints.one << bits) - &ctx.big_uints.one;
595−
596− (acc << bits) | (mask & q.as_atom().unwrap())
597− });
598− Rc::new(Noun::Atom(atom))
700+ let atom: Option<Atom> = b.list_iter().collect::<Vec<_>>().iter().rfold(
701+ Some(ctx.big_uints.zero.clone()),
702+ |acc, next| {
703+ let (p, q) = next.as_cell()?;
704+ let step = p.as_u32().unwrap();
705+ let bits = bloq_ * step;
706+ let mask = (&ctx.big_uints.one << bits) - &ctx.big_uints.one;
707+
708+ Some((acc? << bits) | (mask & q.as_atom()?))
709+ },
710+ );
711+ Ok(Rc::new(Noun::Atom(atom.ok_or(TTanks::new())?)))
599712};
600713
601714static CAT: Jet = |_ctx, n| {
602− let (bloq, b) = n.as_cell().unwrap();
603− let (b, c) = b.as_cell().unwrap();
715+ let (bloq, b) = n.as_cell().ok_or(TTanks::new())?;
716+ let (b, c) = b.as_cell().ok_or(TTanks::new())?;
604717
605− let bloq = bloq.as_u32().unwrap();
606− let b = b.as_atom().unwrap();
607− let c = c.as_atom().unwrap();
718+ let bloq = bloq.as_u32().ok_or(TTanks::new())?;
719+ let b = b.as_atom().ok_or(TTanks::new())?;
720+ let c = c.as_atom().ok_or(TTanks::new())?;
608721
609− Rc::new(Noun::Atom(
610− (c << (met(bloq, b.clone()) * 2u32.pow(bloq))) | b,
611− ))
722+ Ok(Rc::new(Noun::Atom(
723+ (c << (met(bloq, &b) * 2u32.pow(bloq))) | b,
724+ )))
612725};
613726
614727static MET: Jet = |_ctx, n| {
615− let (bloq, b) = n.as_cell().unwrap();
616− let b: Atom = b.as_atom().unwrap().clone();
728+ let (bloq, b) = n.as_cell().ok_or(TTanks::new())?;
729+ let b: Atom = b.as_atom().ok_or(TTanks::new())?.clone();
617730 let bloq = bloq.as_u32().unwrap();
618731
619− Rc::new(Noun::from_u32(met(bloq, b)))
732+ Ok(Rc::new(Noun::from_u32(met(bloq, &b))))
620733};
621734
622−fn met(bloq: u32, mut a: Atom) -> u32 {
623− let bits = 2u32.pow(bloq);
624−
625− let mut c = 0;
626−
627− while a > Atom::ZERO {
628− a = a >> bits;
629− c += 1;
630− }
631−
632− c
735+fn met(bloq: u32, a: &Atom) -> u32 {
736+ (a.bits() as u32).div_ceil(2u32.pow(bloq))
633737}
634738
635739static CUT: Jet = |ctx, n| {
636− let (a, b) = n.as_cell().unwrap();
637− let (b, d) = b.as_cell().unwrap();
638− let (b, c) = b.as_cell().unwrap();
740+ let (a, b) = n.as_cell().ok_or(TTanks::new())?;
741+ let (b, d) = b.as_cell().ok_or(TTanks::new())?;
742+ let (b, c) = b.as_cell().ok_or(TTanks::new())?;
639743
640744 let bits = 2u32.pow(a.as_u32().unwrap());
641745
642746 let mask = (&ctx.big_uints.one << (bits * c.as_u32().unwrap())) - &ctx.big_uints.one;
643747
644− Rc::new(Noun::Atom(
645− (d.as_atom().unwrap() >> (bits * b.as_u32().unwrap())) & mask,
646− ))
748+ Ok(Rc::new(Noun::Atom(
749+ (d.as_atom().ok_or(TTanks::new())? >> (bits * b.as_u32().unwrap())) & mask,
750+ )))
647751};
648752
649753static FIL: Jet = |ctx, n| {
650− let (a, b) = n.as_cell().unwrap();
651− let (b, c) = b.as_cell().unwrap();
754+ let (a, b) = n.as_cell().ok_or(TTanks::new())?;
755+ let (b, c) = b.as_cell().ok_or(TTanks::new())?;
652756
653757 let bits = 2u32.pow(a.as_u32().unwrap());
654758
655759 let mask = (&ctx.big_uints.one << bits) - &ctx.big_uints.one;
656760
657− let src = c.as_atom().unwrap() & mask;
761+ let src = c.as_atom().ok_or(TTanks::new())? & mask;
658762
659763 let mut target = ctx.big_uints.zero.clone();
660764
@@ -662,45 +766,45 @@ static FIL: Jet = |ctx, n| {
662766 target = (target << bits) | &src;
663767 }
664768
665− Rc::new(Noun::Atom(target))
769+ Ok(Rc::new(Noun::Atom(target)))
666770};
667771
668772static LSH: Jet = |_ctx, n| {
669− let (a, b) = n.as_cell().unwrap();
670− let a = a.as_bite().unwrap();
671− let b = b.as_atom().unwrap();
773+ let (a, b) = n.as_cell().ok_or(TTanks::new())?;
774+ let a = a.as_bite();
775+ let b = b.as_atom().ok_or(TTanks::new())?;
672776
673− Rc::new(Noun::Atom(b << a.bits()))
777+ Ok(Rc::new(Noun::Atom(b << a.bits())))
674778};
675779
676780static RSH: Jet = |_ctx, n| {
677− let (a, b) = n.as_cell().unwrap();
678− let a = a.as_bite().unwrap();
679− let b = b.as_atom().unwrap();
781+ let (a, b) = n.as_cell().ok_or(TTanks::new())?;
782+ let a = a.as_bite();
783+ let b = b.as_atom().ok_or(TTanks::new())?;
680784
681− Rc::new(Noun::Atom(b >> a.bits()))
785+ Ok(Rc::new(Noun::Atom(b >> a.bits())))
682786};
683787
684−static RAP: Jet = |ctx, n| {
685− let (bloq, b) = n.as_cell().unwrap();
788+pub static RAP: Jet = |ctx, n| {
789+ let (bloq, b) = n.as_cell().ok_or(TTanks::new())?;
686790 let bloq = bloq.as_u32().unwrap();
687791 let bits = 2u32.pow(bloq);
688792
689793 let mut target = ctx.big_uints.zero.clone();
690794
691795 for el in b.list_iter().collect::<Vec<_>>().iter().rev() {
692− let el = el.as_atom().unwrap();
796+ let el = el.as_atom().ok_or(TTanks::new())?;
693797 if el != &ctx.big_uints.zero {
694− target = (target << (bits * met(bloq, el.clone()))) | el;
798+ target = (target << (bits * met(bloq, &el))) | el;
695799 }
696800 }
697801
698− Rc::new(Noun::Atom(target))
802+ Ok(Rc::new(Noun::Atom(target)))
699803};
700804
701805static REP: Jet = |ctx, n| {
702− let (bite, b) = n.as_cell().unwrap();
703− let bite = bite.as_bite().unwrap();
806+ let (bite, b) = n.as_cell().ok_or(TTanks::new())?;
807+ let bite = bite.as_bite();
704808
705809 let bits = bite.bits();
706810 let mask = (&ctx.big_uints.one << bits) - &ctx.big_uints.one;
@@ -708,18 +812,18 @@ static REP: Jet = |ctx, n| {
708812 let mut target = ctx.big_uints.zero.clone();
709813
710814 for el in b.list_iter().collect::<Vec<_>>().iter().rev() {
711− target = (target << bits) | (el.as_atom().unwrap() & &mask);
815+ target = (target << bits) | (el.as_atom().ok_or(TTanks::new())? & &mask);
712816 }
713817
714− Rc::new(Noun::Atom(target))
818+ Ok(Rc::new(Noun::Atom(target)))
715819};
716820
717821static REV: Jet = |ctx, n| {
718− let (bloq, b) = n.as_cell().unwrap();
719− let (len, dat) = b.as_cell().unwrap();
822+ let (bloq, b) = n.as_cell().ok_or(TTanks::new())?;
823+ let (len, dat) = b.as_cell().ok_or(TTanks::new())?;
720824 let bloq = bloq.as_u32().unwrap();
721825 let len = len.as_u32().unwrap();
722− let mut dat: Atom = dat.as_atom().unwrap().clone();
826+ let mut dat: Atom = dat.as_atom().ok_or(TTanks::new())?.clone();
723827
724828 let bits = 2u32.pow(bloq);
725829 let mask = (&ctx.big_uints.one << bits) - &ctx.big_uints.one;
@@ -731,13 +835,13 @@ static REV: Jet = |ctx, n| {
731835 dat = dat >> bits;
732836 }
733837
734− Rc::new(Noun::Atom(target))
838+ Ok(Rc::new(Noun::Atom(target)))
735839};
736840
737841static RIP: Jet = |ctx, n| {
738− let (bite, b) = n.as_cell().unwrap();
739− let bite = bite.as_bite().unwrap();
740− let mut b: Atom = b.as_atom().unwrap().clone();
842+ let (bite, b) = n.as_cell().ok_or(TTanks::new())?;
843+ let bite = bite.as_bite();
844+ let mut b: Atom = b.as_atom().ok_or(TTanks::new())?.clone();
741845
742846 let bits = bite.bits();
743847 let mask = (&ctx.big_uints.one << bits) - &ctx.big_uints.one;
@@ -749,5 +853,418 @@ static RIP: Jet = |ctx, n| {
749853 b = b >> bits;
750854 }
751855
752− Noun::list_refs(target.iter().cloned())
856+ Ok(Noun::list_refs(target.iter().cloned()))
857+};
858+
859+static RUN: Jet = |ctx, n| {
860+ let (bite, b) = n.as_cell().ok_or(TTanks::new())?;
861+ let (b, gate) = b.as_cell().ok_or(TTanks::new())?;
862+
863+ let bite = bite.as_bite();
864+ let mut b: Atom = b.as_atom().ok_or(TTanks::new())?.clone();
865+
866+ let bits = bite.bits();
867+ let mask = (&ctx.big_uints.one << bits) - &ctx.big_uints.one;
868+
869+ let mut target = ctx.big_uints.zero.clone();
870+
871+ while b > ctx.big_uints.zero {
872+ target = (target << bits)
873+ | ((*slam_pulled_gate(ctx, gate, &Rc::new(Noun::Atom(&mask & &b)))?)
874+ .as_atom()
875+ .ok_or(TTanks::new())?
876+ & &mask);
877+ b = b >> bits;
878+ }
879+
880+ Ok(Rc::new(Noun::Atom(target)))
881+};
882+
883+static RUT: Jet = |ctx, n| {
884+ let (bite, b) = n.as_cell().ok_or(TTanks::new())?;
885+ let (b, gate) = b.as_cell().ok_or(TTanks::new())?;
886+
887+ let bite = bite.as_bite();
888+ let mut b: Atom = b.as_atom().ok_or(TTanks::new())?.clone();
889+
890+ let bits = bite.bits();
891+ let mask = (&ctx.big_uints.one << bits) - &ctx.big_uints.one;
892+
893+ let mut target = Vec::new();
894+
895+ while b > ctx.big_uints.zero {
896+ target.push(
897+ (*slam_pulled_gate(ctx, gate, &Rc::new(Noun::Atom(&mask & &b)))?)
898+ .as_atom()
899+ .ok_or(TTanks::new())?
900+ & &mask,
901+ );
902+ b = b >> bits;
903+ }
904+
905+ Ok(Noun::list(target.iter().cloned().map(Noun::Atom)))
906+};
907+
908+static SEW: Jet = |ctx, n| {
909+ let (a, b) = n.as_cell().ok_or(TTanks::new())?;
910+ let (b, recipient) = b.as_cell().ok_or(TTanks::new())?;
911+ let (sew_start, c) = b.as_cell().ok_or(TTanks::new())?;
912+ let (number_of_blocks, donor) = c.as_cell().ok_or(TTanks::new())?;
913+ let recipient = recipient.as_atom().ok_or(TTanks::new())?;
914+ let donor = donor.as_atom().ok_or(TTanks::new())?;
915+
916+ let bloq = a.as_u32().unwrap();
917+ let bits = 2u32.pow(bloq);
918+ let mask = ((&ctx.big_uints.one << (bits * number_of_blocks.as_u32().unwrap()))
919+ - &ctx.big_uints.one)
920+ << (sew_start.as_u32().unwrap() * bits);
921+
922+ let apendix = recipient & &mask;
923+
924+ let target = (recipient ^ apendix) | (donor & mask);
925+
926+ Ok(Rc::new(Noun::Atom(target)))
927+};
928+
929+static SWP: Jet = |ctx, n| {
930+ let (bloq, b) = n.as_cell().ok_or(TTanks::new())?;
931+ let bloq = bloq.as_u32().unwrap();
932+ let bits = 2u32.pow(bloq);
933+ let mask = (&ctx.big_uints.one << bits) - &ctx.big_uints.one;
934+
935+ let mut source = b.as_atom().ok_or(TTanks::new())?.clone();
936+ let mut target = ctx.big_uints.zero.clone();
937+
938+ while source > ctx.big_uints.zero {
939+ target = (target << bits) | (&source & &mask);
940+ source = source >> bits;
941+ }
942+
943+ Ok(Rc::new(Noun::Atom(target)))
753944};
945+
946+static XEB: Jet = |_ctx, n| {
947+ let mut a = n.as_atom().ok_or(TTanks::new())?.clone();
948+
949+ let mut c = 0;
950+
951+ while a > Atom::ZERO {
952+ a = a >> 1;
953+ c += 1;
954+ }
955+
956+ Ok(Rc::new(Noun::from_u32(c)))
957+};
958+
959+static CON: Jet = |_ctx, n| BINARY_ATOM(n, |a, b| a | b);
960+static DIS: Jet = |_ctx, n| BINARY_ATOM(n, |a, b| a & b);
961+static MIX: Jet = |_ctx, n| BINARY_ATOM(n, |a, b| a ^ b);
962+
963+static NOT: Jet = |ctx, n| {
964+ let (a, b) = n.as_cell().ok_or(TTanks::new())?;
965+ let (b, c) = b.as_cell().ok_or(TTanks::new())?;
966+
967+ let bloq = a.as_u32().unwrap();
968+ let bits = 2u32.pow(bloq);
969+ let mask = (&ctx.big_uints.one << (bits * b.as_u32().unwrap())) - &ctx.big_uints.one;
970+
971+ let target = c.as_atom().ok_or(TTanks::new())? ^ &mask;
972+
973+ Ok(Rc::new(Noun::Atom(target)))
974+};
975+
976+static LAST: Jet = |_ctx, n| {
977+ let (a, b) = n.as_cell().ok_or(TTanks::new())?;
978+ let a = a.as_hair().ok_or(TTanks::new())?;
979+ let b = b.as_hair().ok_or(TTanks::new())?;
980+ Ok(Noun::from_hair(last(&a, &b)))
981+};
982+
983+fn last<'a>(a: &'a Hair, b: &'a Hair) -> &'a Hair {
984+ if a.line == b.line {
985+ if a.column > b.column {
986+ a
987+ } else {
988+ b
989+ }
990+ } else {
991+ if a.line > b.line {
992+ a
993+ } else {
994+ b
995+ }
996+ }
997+}
998+
999+static TRIP: Jet = |_ctx, n| {
1000+ let a = n.as_atom().ok_or(TTanks::new())?;
1001+ Ok(Noun::list(
1002+ a.to_bytes_le().iter().map(|b| Noun::from_u32(*b as u32)),
1003+ ))
1004+};
1005+
1006+static MUK: Jet = |_ctx, n| {
1007+ let (seed, len) = n.as_cell().ok_or(TTanks::new())?;
1008+ let (len, key) = len.as_cell().ok_or(TTanks::new())?;
1009+ let seed = seed.as_u32().ok_or(TTanks::new())?;
1010+ let len = len.as_u32().ok_or(TTanks::new())?;
1011+ let key = key.as_atom().ok_or(TTanks::new())?;
1012+
1013+ Ok(Rc::new(Noun::from_u32(muk(seed, len, key))))
1014+};
1015+
1016+static AOR: Jet = |ctx, n| {
1017+ let (a, b) = n.as_cell().ok_or(EMPTY_TANKS)?;
1018+
1019+ if a == b {
1020+ Ok(ctx.nouns.y.clone())
1021+ } else {
1022+ match (a.borrow(), b.borrow()) {
1023+ (Noun::Cell { .. }, Noun::Atom(_)) => Ok(ctx.nouns.n.clone()),
1024+ (Noun::Cell { p: a_p, q: a_q, .. }, Noun::Cell { p: b_p, q: b_q, .. }) => {
1025+ if a_p == b_p {
1026+ AOR(ctx, &cell(a_q, b_q))
1027+ } else {
1028+ AOR(ctx, &cell(a_p, b_p))
1029+ }
1030+ }
1031+ (Noun::Atom(_), Noun::Cell { .. }) => Ok(ctx.nouns.y.clone()),
1032+ (Noun::Atom(a), Noun::Atom(b)) => {
1033+ let a = a.to_bytes_le();
1034+ let b = b.to_bytes_le();
1035+
1036+ let mut i = 0;
1037+ loop {
1038+ let c = a.get(i).unwrap_or(&0);
1039+ let d = b.get(i).unwrap_or(&0);
1040+
1041+ if a[0] == b[0] {
1042+ i += 1;
1043+ } else {
1044+ if c < d {
1045+ return Ok(ctx.nouns.y.clone());
1046+ } else {
1047+ return Ok(ctx.nouns.n.clone());
1048+ }
1049+ }
1050+ }
1051+ }
1052+ }
1053+ }
1054+};
1055+
1056+static DOR: Jet = |ctx, n| {
1057+ let (a, b) = n.as_cell().ok_or(EMPTY_TANKS)?;
1058+
1059+ if a == b {
1060+ Ok(ctx.nouns.y.clone())
1061+ } else {
1062+ match (a.borrow(), b.borrow()) {
1063+ (Noun::Cell { .. }, Noun::Atom(_)) => Ok(ctx.nouns.n.clone()),
1064+ (Noun::Cell { p: a_p, q: a_q, .. }, Noun::Cell { p: b_p, q: b_q, .. }) => {
1065+ if a_p == b_p {
1066+ DOR(ctx, &cell(a_q, b_q))
1067+ } else {
1068+ DOR(ctx, &cell(a_p, b_p))
1069+ }
1070+ }
1071+ (Noun::Atom(_), Noun::Cell { .. }) => Ok(ctx.nouns.y.clone()),
1072+ (Noun::Atom(a), Noun::Atom(b)) => {
1073+ if a < b {
1074+ Ok(ctx.nouns.y.clone())
1075+ } else {
1076+ Ok(ctx.nouns.n.clone())
1077+ }
1078+ }
1079+ }
1080+ }
1081+};
1082+
1083+static GOR: Jet = |ctx, n| {
1084+ let (a, b) = n.as_cell().ok_or(EMPTY_TANKS)?;
1085+ let c = a.mug();
1086+ let d = b.mug();
1087+
1088+ if c == d {
1089+ DOR(ctx, n)
1090+ } else {
1091+ if c < d {
1092+ Ok(ctx.nouns.y.clone())
1093+ } else {
1094+ Ok(ctx.nouns.n.clone())
1095+ }
1096+ }
1097+};
1098+
1099+static GOR_PAIR: fn(&mut InterpreterContext, &Rc<Noun>, &Rc<Noun>) -> Result<bool, TTanks> =
1100+ |ctx, a, b| {
1101+ let c = a.mug();
1102+ let d = b.mug();
1103+
1104+ if c == d {
1105+ Ok(DOR(ctx, &(a.clone(), b.clone()).as_noun())? == ctx.nouns.y)
1106+ } else {
1107+ Ok(c < d)
1108+ }
1109+ };
1110+
1111+static MOR: Jet = |ctx, n| {
1112+ let (a, b) = n.as_cell().ok_or(EMPTY_TANKS)?;
1113+ let c = Noun::from_u32(a.mug()).mug();
1114+ let d = Noun::from_u32(b.mug()).mug();
1115+
1116+ if c == d {
1117+ DOR(ctx, n)
1118+ } else {
1119+ if c < d {
1120+ Ok(ctx.nouns.y.clone())
1121+ } else {
1122+ Ok(ctx.nouns.n.clone())
1123+ }
1124+ }
1125+};
1126+
1127+static LOOK: Jet = |ctx, n| {
1128+ let (cog, dab) = n.as_cell().ok_or(EMPTY_TANKS)?;
1129+ LOOK_PAIR(ctx, Atom::new(vec![1]), cog, dab)
1130+};
1131+
1132+static LOOK_PAIR: fn(
1133+ &mut InterpreterContext,
1134+ Atom,
1135+ &Rc<Noun>,
1136+ &Rc<Noun>,
1137+) -> Result<Rc<Noun>, TTanks> = |ctx, axe, cog, dab| {
1138+ if dab.is_sig() {
1139+ Ok(ctx.nouns.sig.clone())
1140+ } else {
1141+ let (node, b, c) = dab.tuple_3().ok_or(EMPTY_TANKS)?;
1142+ let l = b;
1143+ let r = c;
1144+ let (p, q) = node.as_cell().ok_or(EMPTY_TANKS)?;
1145+ if b.is_sig() && c.is_sig() {
1146+ if cog == p {
1147+ Ok((ctx.nouns.sig.clone(), Noun::Atom(axe), q.clone()).as_noun())
1148+ } else {
1149+ Ok(ctx.nouns.sig.clone())
1150+ }
1151+ } else if b.is_sig() {
1152+ if cog == p {
1153+ Ok((ctx.nouns.sig.clone(), PEG_U32(&axe, 2), q.clone()).as_noun())
1154+ } else if GOR_PAIR(ctx, cog, p)? {
1155+ Ok(ctx.nouns.sig.clone())
1156+ } else {
1157+ LOOK_PAIR(ctx, PEG_U32(&axe, 3), cog, r)
1158+ }
1159+ } else if c.is_sig() {
1160+ if cog == p {
1161+ Ok((ctx.nouns.sig.clone(), PEG_U32(&axe, 2), q.clone()).as_noun())
1162+ } else if GOR_PAIR(ctx, cog, p)? {
1163+ LOOK_PAIR(ctx, PEG_U32(&axe, 3), cog, l)
1164+ } else {
1165+ Ok(ctx.nouns.sig.clone())
1166+ }
1167+ } else {
1168+ if cog == p {
1169+ Ok((ctx.nouns.sig.clone(), PEG_U32(&axe, 2), q.clone()).as_noun())
1170+ } else if GOR_PAIR(ctx, cog, p)? {
1171+ LOOK_PAIR(ctx, PEG_U32(&axe, 6), cog, l)
1172+ } else {
1173+ LOOK_PAIR(ctx, PEG_U32(&axe, 7), cog, r)
1174+ }
1175+ }
1176+ }
1177+};
1178+
1179+static JUST: DoubleJet = |ctx, n, m| {
1180+ let char = n.as_atom()?;
1181+ let nail = m.as_nail()?;
1182+ if *nail.rest == ctx.nouns.sig {
1183+ Some(fail(nail).as_noun())
1184+ } else {
1185+ let (i, _) = nail.rest.as_cell()?;
1186+ let i = i.as_atom()?;
1187+ if i == char {
1188+ Some(next(nail)?.as_noun())
1189+ } else {
1190+ Some(fail(nail).as_noun())
1191+ }
1192+ }
1193+};
1194+
1195+// static STIR: DoubleJet = |ctx, n, m| {
1196+// let (rud, raq) = n.as_cell()?;
1197+// let (raq, fel) = raq.as_cell()?;
1198+// let tub = m.as_nail()?;
1199+
1200+// let mut lef = Vec::new();
1201+// let mut vex = slam(ctx, fel, tub)?.as;
1202+// if vex.
1203+// };
1204+
1205+fn next<'a>(nail: Nail<'a>) -> Option<Edge<'a>> {
1206+ if **nail.rest == Noun::SIG {
1207+ Some(fail(nail))
1208+ } else {
1209+ let (i, t) = nail.rest.as_cell()?;
1210+ let zac = lust(i.as_atom()?.clone(), nail.hair);
1211+ // cell(zac, cell(Rc::new(Noun::SIG), cell(i, cell(zac, t))))
1212+ Some(Edge {
1213+ hair: zac.clone(),
1214+ result: Some((i, Nail { hair: zac, rest: t })),
1215+ })
1216+ }
1217+}
1218+
1219+fn lust(char: Atom, hair: Hair) -> Hair {
1220+ if char == Atom::from_slice(&vec![10]) {
1221+ Hair {
1222+ line: hair.line + 1,
1223+ column: 1,
1224+ }
1225+ } else {
1226+ Hair {
1227+ line: hair.line,
1228+ column: hair.column + 1,
1229+ }
1230+ }
1231+}
1232+
1233+fn fail(nail: Nail) -> Edge {
1234+ Edge {
1235+ hair: nail.hair,
1236+ result: None,
1237+ }
1238+}
1239+
1240+const MUG: Jet = |__ctx, n| Ok(Rc::new(Noun::from_u32(n.mug())));
1241+
1242+pub fn mum(syd: u32, fal: u32, key: &Atom) -> u32 {
1243+ let wyd = met(3, &key);
1244+ let mut i = 0;
1245+ loop {
1246+ if i == 8 {
1247+ break fal;
1248+ } else {
1249+ let haz = muk(syd, wyd, &key);
1250+ let ham = (haz >> 31) ^ (haz & !(1 << 31));
1251+ if ham == 0 {
1252+ i += 1;
1253+ continue;
1254+ } else {
1255+ break ham;
1256+ }
1257+ }
1258+ }
1259+}
1260+
1261+fn muk(seed: u32, len: u32, key: &Atom) -> u32 {
1262+ let key: Vec<_> = key
1263+ .to_bytes_le()
1264+ .iter()
1265+ .take(len as usize)
1266+ .cloned()
1267+ .collect();
1268+
1269+ murmur3_32(&mut &*key, seed).unwrap()
1270+}