@@ -1,27 +1,39 @@
11use core::panic;
2+use murmur3::murmur3_32;
23use num_integer::Integer;
34use std::{
5+ borrow::Borrow,
46 collections::BTreeMap,
57 iter::{once, repeat_n, zip},
68 rc::Rc,
79};
810
911use crate::{
10− interpreter::{slam, InterpreterContext},
11− noun::{self, cell, Atom, Noun},
12+ interpreter::{slam_pulled_gate, InterpreterContext, TTanks, EMPTY_TANKS},
13+ noun::{self, cell, AsNoun, Atom, Edge, Hair, Nail, Noun},
1214};
1315
14−fn traverse_iter_option<T: Clone, I: Iterator<Item = Option<T>>>(xs: I) -> Option<Vec<T>> {
16+fn traverse_iter_result<E: Clone, T: Clone, I: Iterator<Item = Result<T, E>>>(
17+ xs: I,
18+) -> Result<Vec<T>, E> {
1519 let mut target: Vec<T> = Vec::new();
1620
1721 for x in xs {
1822 target.push(x.clone()?)
1923 }
2024
21− Some(target)
25+ Ok(target)
2226}
2327
2428pub 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+}
2537
2638pub fn generate_jets() -> Jets {
2739 BTreeMap::from([
@@ -92,41 +104,67 @@ pub fn generate_jets() -> Jets {
92104 (311027486926441687148059942599447850754, DIS),
93105 (330927609077697663248483044495963838437, MIX),
94106 (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),
95116 ])
96117}
97118
98−pub type Jet = fn(ctx: &InterpreterContext, Rc<Noun>) -> Option<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>>;
99121
100−static BINARY_ATOM: fn(Rc<Noun>, fn(&Atom, &Atom) -> Atom) -> Option<Rc<Noun>> =
101− |n: Rc<Noun>, f: fn(&Atom, &Atom) -> Atom| {
102− let (p, q) = n.as_cell()?;
103− Some(Rc::new(Noun::Atom(f(p.as_atom()?, q.as_atom()?))))
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+ ))))
104129 };
105130
106131static BINARY_ATOM_LOOB: fn(
107132 &InterpreterContext,
108− Rc<Noun>,
133+ &Rc<Noun>,
109134 fn(&Atom, &Atom) -> bool,
110−) -> Option<Rc<Noun>> = |ctx: &InterpreterContext, n: Rc<Noun>, f: fn(&Atom, &Atom) -> bool| {
111− let (p, q) = n.as_cell()?;
112−
113− if f(p.as_atom()?, q.as_atom()?) {
114− Some(ctx.nouns.sig.clone())
115− } else {
116− Some(ctx.nouns.one.clone())
117− }
118−};
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())
144+ } else {
145+ Ok(ctx.nouns.one.clone())
146+ }
147+ };
119148
120−static BINARY_ATOM_PAIR: fn(Rc<Noun>, fn(&Atom, &Atom) -> (Atom, Atom)) -> Option<Rc<Noun>> =
121− |n: Rc<Noun>, f: fn(&Atom, &Atom) -> (Atom, Atom)| {
122− let (p, q) = n.as_cell()?;
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())?;
123154
124− let (a, b) = f(p.as_atom()?, q.as_atom()?);
125− Some(cell(Rc::new(Noun::Atom(a)), Rc::new(Noun::Atom(b))))
126− };
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+};
127161
128162static ADD: Jet = |_ctx, n| BINARY_ATOM(n, |a, b| a + b);
129−static DEC: Jet = |_ctx, n| Some(Rc::new(Noun::Atom(n.as_atom()? - 1u32)));
163+static DEC: Jet = |_ctx, n| {
164+ Ok(Rc::new(Noun::Atom(
165+ n.as_atom().ok_or(TTanks::new())? - 1u32,
166+ )))
167+};
130168static DVR: Jet = |_ctx, n| BINARY_ATOM_PAIR(n, |a, b| a.div_rem(&b));
131169static DIV: Jet = |_ctx, n| BINARY_ATOM(n, |a, b| a / b);
132170static GTE: Jet = |ctx, n| BINARY_ATOM_LOOB(ctx, n, |a, b| a >= b);
@@ -140,29 +178,31 @@ static MUL: Jet = |_ctx, n| BINARY_ATOM(n, |a, b| a * b);
140178static SUB: Jet = |_ctx, n| BINARY_ATOM(n, |a, b| a - b);
141179
142180static CAP: Jet = |ctx, n| {
143− let n = n.as_atom()?;
181+ let n = n.as_atom().ok_or(TTanks::new())?;
144182 CAP_ATOM(ctx, n.clone())
145183};
146184
147−static CAP_ATOM: fn(&InterpreterContext, Atom) -> Option<Rc<Noun>> = |ctx, n: Atom| {
185+static CAP_ATOM: fn(&InterpreterContext, Atom) -> Result<Rc<Noun>, TTanks> = |ctx, n: Atom| {
148186 let mut n_iter = n.iter_u32_digits();
149187
150188 match n_iter.len() {
151− 0 => None,
189+ 0 => Err(TTanks::new()),
152190 1 => CAP_U32(ctx, n_iter.next().unwrap()),
153191 _ => CAP_ATOM(ctx, n >> 1),
154192 }
155193};
156−static CAP_U32: fn(ctx: &InterpreterContext, u32) -> Option<Rc<Noun>> = |ctx, n| match n {
157− 0 | 1 => None,
158− 2 => Some(ctx.nouns.two.clone()),
159− 3 => Some(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()),
160198 n => CAP_U32(ctx, n >> 1),
161199};
162200
163201static MAS: Jet = |ctx, n| {
164− let n = n.as_atom()?;
165− Some(Rc::new(Noun::Atom(MAS_ATOM(ctx, n.clone())?)))
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+ )))
166206};
167207static MAS_ATOM: fn(&InterpreterContext, Atom) -> Option<Atom> = |ctx, n| {
168208 let mut n_iter = n.iter_u32_digits();
@@ -183,24 +223,24 @@ static MAS_U32: fn(u32) -> u32 = |n| match n {
183223};
184224
185225static PEG: Jet = |ctx, n| {
186− let (a, b) = n.as_cell()?;
226+ let (a, b) = n.as_cell().ok_or(TTanks::new())?;
187227
188− let a = a.as_atom()?;
189− let b = b.as_atom()?;
228+ let a = a.as_atom().ok_or(TTanks::new())?;
229+ let b = b.as_atom().ok_or(TTanks::new())?;
190230
191231 if *a == Atom::ZERO {
192− return None;
232+ return Err(TTanks::new());
193233 };
194234
195− Some(Rc::new(Noun::Atom(PEG_ATOM(ctx, a, b.clone())?)))
235+ Ok(Rc::new(Noun::Atom(PEG_ATOM(ctx, a, b.clone())?)))
196236};
197−static PEG_ATOM: fn(&InterpreterContext, &Atom, Atom) -> Option<Atom> = |ctx, a, b| {
237+static PEG_ATOM: fn(&InterpreterContext, &Atom, Atom) -> Result<Atom, TTanks> = |ctx, a, b| {
198238 let mut b_iter = b.iter_u32_digits();
199239
200240 match b_iter.len() {
201− 0 => None,
202− 1 => Some(PEG_U32(a, b_iter.next().unwrap())),
203− _ => Some((&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)),
204244 }
205245};
206246static PEG_U32: fn(&Atom, u32) -> Atom = |a, b| match b {
@@ -212,12 +252,12 @@ static PEG_U32: fn(&Atom, u32) -> Atom = |a, b| match b {
212252};
213253
214254static FAND: Jet = |ctx, n| {
215− let (nedl, hstk) = n.as_cell()?;
255+ let (nedl, hstk) = n.as_cell().ok_or(TTanks::new())?;
216256 if nedl.is_sig() || hstk.is_sig() {
217− return Some(ctx.nouns.sig.clone());
257+ return Ok(ctx.nouns.sig.clone());
218258 }
219259
220− let nedl: Vec<Rc<Noun>> = nedl.list_iter().collect();
260+ let nedl: Vec<&Rc<Noun>> = nedl.list_iter().collect();
221261
222262 let mut result: Vec<u32> = Vec::new();
223263
@@ -238,16 +278,16 @@ static FAND: Jet = |ctx, n| {
238278 inner_iter = iter.clone();
239279 }
240280
241− Some(Noun::list(result.iter().map(|a| Noun::from_u32(*a))))
281+ Ok(Noun::list(result.iter().map(|a| Noun::from_u32(*a))))
242282};
243283
244284static FIND: Jet = |ctx, n| {
245− let (nedl, hstk) = n.as_cell()?;
285+ let (nedl, hstk) = n.as_cell().ok_or(TTanks::new())?;
246286 if nedl.is_sig() || hstk.is_sig() {
247− return Some(ctx.nouns.sig.clone());
287+ return Ok(ctx.nouns.sig.clone());
248288 }
249289
250− let nedl: Vec<Rc<Noun>> = nedl.list_iter().collect();
290+ let nedl: Vec<&Rc<Noun>> = nedl.list_iter().collect();
251291
252292 let mut iter = zip(0.., hstk.list_iter());
253293
@@ -260,30 +300,28 @@ static FIND: Jet = |ctx, n| {
260300 .collect::<Vec<_>>()
261301 == nedl
262302 {
263− return Some(Rc::new(Noun::from_u32(i)).unit());
303+ return Ok(Rc::new(Noun::from_u32(i)).unit());
264304 }
265305
266306 inner_iter = iter.clone();
267307 }
268308
269− return Some(ctx.nouns.sig.clone());
309+ return Ok(ctx.nouns.sig.clone());
270310};
271311
272312static FLOP: Jet = |ctx, n| {
273− Some(
274− n.list_iter()
275− .fold(ctx.nouns.sig.clone(), |tail, head| cell(head, tail)),
276− )
313+ Ok(n.list_iter()
314+ .fold(ctx.nouns.sig.clone(), |tail, head| cell(&head, &tail)))
277315};
278316
279317static GULF: Jet = |_ctx, n| {
280− let (from, to) = n.as_cell()?;
318+ let (from, to) = n.as_cell().ok_or(TTanks::new())?;
281319
282− let mut from = (*from.as_atom()?).clone();
283− let to = to.as_atom()?.clone();
320+ let mut from = (*from.as_atom().ok_or(TTanks::new())?).clone();
321+ let to = to.as_atom().ok_or(TTanks::new())?.clone();
284322
285323 if from > to {
286− return None;
324+ return Err(TTanks::new());
287325 }
288326
289327 let mut tmp = Vec::new();
@@ -293,220 +331,251 @@ static GULF: Jet = |_ctx, n| {
293331 from += 1u32;
294332 }
295333
296− Some(Noun::list(tmp.iter().rev().map(|a| Noun::Atom(a.clone()))))
334+ Ok(Noun::list(tmp.iter().rev().map(|a| Noun::Atom(a.clone()))))
297335};
298336
299337static INTO: Jet = |_ctx, n| {
300− let (a, b) = n.as_cell()?;
301− let (b, c) = b.as_cell()?;
338+ let (a, b) = n.as_cell().ok_or(TTanks::new())?;
339+ let (b, c) = b.as_cell().ok_or(TTanks::new())?;
302340
303− let mut b_iter = b.as_atom()?.iter_u32_digits();
341+ let mut b_iter = b.as_atom().ok_or(TTanks::new())?.iter_u32_digits();
304342
305343 match b_iter.len() {
306− 0 => Some(cell(c, a)),
344+ 0 => Ok(cell(&c, &a)),
307345 1 => {
308346 let l = a.list_iter();
309347 let b = b_iter.next().unwrap() as usize;
310− Some(Noun::list_refs(
348+ Ok(Noun::list_refs(
311349 l.clone()
312350 .take(b)
313351 .chain(once(c))
314352 .chain(l.skip(b))
315353 .collect::<Vec<_>>()
316354 .iter()
317− .map(|x| x.clone()),
355+ .cloned()
356+ .cloned(),
318357 ))
319358 }
320− _ => Some(Noun::list_refs(
359+ _ => Ok(Noun::list_refs(
321360 a.list_iter()
322361 .chain(once(c))
323362 .collect::<Vec<_>>()
324363 .iter()
325− .map(|x| x.clone()),
364+ .cloned()
365+ .cloned(),
326366 )),
327367 }
328368};
329369
330370static JOIN: Jet = |_ctx, n| {
331− let (sep, list) = n.as_cell()?;
332− Some(Noun::list_refs(
371+ let (sep, list) = n.as_cell().ok_or(TTanks::new())?;
372+ Ok(Noun::list_refs(
333373 list.list_iter()
334374 .intersperse(sep)
335375 .collect::<Vec<_>>()
336376 .iter()
377+ .cloned()
337378 .cloned(),
338379 ))
339380};
340381
341382static LENT: Jet = |_ctx, n| {
342− Some(Rc::new(Noun::from_u32(
383+ Ok(Rc::new(Noun::from_u32(
343384 n.list_iter().fold(0u32, |l, _| l + 1),
344385 )))
345386};
346387
347388static LEVY: Jet = |ctx, n| {
348− let (a, b) = n.as_cell()?;
349− if traverse_iter_option(a.list_iter().map(|n| slam(ctx, b.clone(), n)))?
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)))?
350391 .iter()
351392 .all(|x| x.is_y())
352393 {
353− Some(ctx.nouns.y.clone())
394+ Ok(ctx.nouns.y.clone())
354395 } else {
355− Some(ctx.nouns.n.clone())
396+ Ok(ctx.nouns.n.clone())
356397 }
357398};
358399
359400static LIEN: Jet = |ctx, n| {
360− let (a, b) = n.as_cell()?;
361− if traverse_iter_option(a.list_iter().map(|n| slam(ctx, b.clone(), n)))?
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)))?
362403 .iter()
363404 .any(|x| x.is_y())
364405 {
365− Some(ctx.nouns.y.clone())
406+ Ok(ctx.nouns.y.clone())
366407 } else {
367− Some(ctx.nouns.n.clone())
408+ Ok(ctx.nouns.n.clone())
368409 }
369410};
370411
371412static MURN: Jet = |ctx, n| {
372− let (a, b) = n.as_cell()?;
413+ let (a, b) = n.as_cell().ok_or(TTanks::new())?;
373414
374− Some(Noun::list_refs(
375− a.list_iter()
376− .filter_map(|n| slam(ctx, b.clone(), n)?.as_unit())
377− .collect::<Vec<_>>()
378− .iter()
379− .map(|x| x.clone()),
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()),
380422 ))
381423};
382424
383425static REAP: Jet = |_ctx, n| {
384− let (a, b) = n.as_cell()?;
426+ let (a, b) = n.as_cell().ok_or(TTanks::new())?;
385427
386− Some(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+ )))
387432};
388433
389−static REAR: Jet = |_ctx, n| n.list_iter().last();
434+static REAR: Jet = |_ctx, n| n.list_iter().last().ok_or(TTanks::new()).cloned();
390435
391436static REEL: Jet = |ctx, n| {
392− let (list, gate) = n.as_cell()?;
437+ let (list, gate) = n.as_cell().ok_or(TTanks::new())?;
393438
394439 list.list_iter().collect::<Vec<_>>().iter().rfold(
395− Some(gate.clone().gate_sample()?.as_cell()?.1),
396− |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+ },
397451 )
398452};
399453
400454static ROLL: Jet = |ctx, n| {
401− let (list, gate) = n.as_cell()?;
455+ let (list, gate) = n.as_cell().ok_or(TTanks::new())?;
402456
403457 list.list_iter().fold(
404− Some(gate.clone().gate_sample()?.as_cell()?.1),
405− |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+ },
406470 )
407471};
408472
409473static SCAG: Jet = |_ctx, n| {
410− let (a, b) = n.as_cell()?;
474+ let (a, b) = n.as_cell().ok_or(TTanks::new())?;
411475
412− Some(Noun::list_refs(
476+ Ok(Noun::list_refs(
413477 b.list_iter()
414478 .take(a.as_u32().unwrap() as usize)
415479 .collect::<Vec<_>>()
416480 .iter()
417− .map(|x| x.clone()),
481+ .cloned()
482+ .cloned(),
418483 ))
419484};
420485
421486static SKID: Jet = |ctx, n| {
422− let (list, gate) = n.as_cell()?;
487+ let (list, gate) = n.as_cell().ok_or(TTanks::new())?;
423488
424− let slammed_n = traverse_iter_option(
489+ let slammed_n = traverse_iter_result(
425490 list.list_iter()
426− .map(|n| Some((slam(ctx, gate.clone(), n.clone())?, n))),
491+ .map(|n| Ok((slam_pulled_gate(ctx, gate, n)?, n))),
427492 )?;
428493 let (ys, ns): (Vec<_>, _) = slammed_n.iter().partition(|(l, _)| l.is_y());
429494
430− Some(cell(
431− Noun::list_refs(ys.iter().map(|(_, x)| x).cloned()),
432− Noun::list_refs(ns.iter().map(|(_, x)| x).cloned()),
495+ Ok(cell(
496+ &Noun::list_refs(ys.iter().map(|(_, x)| (*x).clone())),
497+ &Noun::list_refs(ns.iter().map(|(_, x)| (*x).clone())),
433498 ))
434499};
435500
436501static SKIM: Jet = |ctx, n| {
437− let (list, gate) = n.as_cell()?;
502+ let (list, gate) = n.as_cell().ok_or(TTanks::new())?;
438503
439− Some(Noun::list_refs(
440− traverse_iter_option(
504+ Ok(Noun::list_refs(
505+ traverse_iter_result(
441506 list.list_iter()
442− .map(|n| Some((slam(ctx, gate.clone(), n.clone())?, n))),
507+ .map(|n| Ok((slam_pulled_gate(ctx, gate, n)?, n))),
443508 )?
444509 .iter()
445510 .filter(|(l, _)| l.is_y())
446− .map(|(_, x)| x)
447− .cloned(),
511+ .map(|(_, x)| (*x).clone()),
448512 ))
449513};
450514
451515static SKIP: Jet = |ctx, n| {
452− let (list, gate) = n.as_cell()?;
516+ let (list, gate) = n.as_cell().ok_or(TTanks::new())?;
453517
454− Some(Noun::list_refs(
455− traverse_iter_option(
518+ Ok(Noun::list_refs(
519+ traverse_iter_result(
456520 list.list_iter()
457− .map(|n| Some((slam(ctx, gate.clone(), n.clone())?, n))),
521+ .map(|n| Ok((slam_pulled_gate(ctx, gate, n)?, n))),
458522 )?
459523 .iter()
460524 .filter(|(l, _)| l.is_y())
461− .map(|(_, x)| x)
462− .cloned(),
525+ .map(|(_, x)| (*x).clone()),
463526 ))
464527};
465528
466529static SLAG: Jet = |ctx, n| {
467− let (a, list) = n.as_cell()?;
530+ let (a, list) = n.as_cell().ok_or(TTanks::new())?;
468531
469− let mut a_iter = a.as_atom()?.iter_u32_digits();
532+ let mut a_iter = a.as_atom().ok_or(TTanks::new())?.iter_u32_digits();
470533
471534 match a_iter.len() {
472− 0 => Some(list),
473− 1 => Some(Noun::list_refs(
535+ 0 => Ok(list.clone()),
536+ 1 => Ok(Noun::list_refs(
474537 list.list_iter()
475538 .skip(a_iter.next().unwrap() as usize)
476539 .collect::<Vec<_>>()
477540 .iter()
541+ .cloned()
478542 .cloned(),
479543 )),
480− _ => Some(ctx.nouns.sig.clone()),
544+ _ => Ok(ctx.nouns.sig.clone()),
481545 }
482546};
483547
484548static SNAG: Jet = |_ctx, n| {
485− let (a, list) = n.as_cell()?;
549+ let (a, list) = n.as_cell().ok_or(TTanks::new())?;
486550
487− list.list_iter().nth(a.as_u32().unwrap() as usize)
551+ list.list_iter()
552+ .nth(a.as_u32().unwrap() as usize)
553+ .cloned()
554+ .ok_or(TTanks::new())
488555};
489556
490557static SNIP: Jet = |_ctx, n| {
491− Some(Noun::list_refs(
558+ Ok(Noun::list_refs(
492559 n.list_iter()
493560 .collect::<Vec<_>>()
494561 .iter()
495562 .rev()
496563 .skip(1)
497564 .rev()
565+ .cloned()
498566 .cloned(),
499567 ))
500568};
501569
502570static SNOC: Jet = |_ctx, n| {
503− let (list, b) = n.as_cell()?;
571+ let (list, b) = n.as_cell().ok_or(TTanks::new())?;
504572
505− Some(Noun::list_refs(
573+ Ok(Noun::list_refs(
506574 list.list_iter()
507575 .chain(once(b))
508576 .collect::<Vec<_>>()
509577 .iter()
578+ .cloned()
510579 .cloned(),
511580 ))
512581};
@@ -530,52 +599,62 @@ static SNOC: Jet = |_ctx, n| {
530599// };
531600
532601static SPIN: Jet = |ctx, n| {
533− let (list, b) = n.as_cell()?;
534− let (mut acc, gate) = b.as_cell()?;
602+ let (list, b) = n.as_cell().ok_or(TTanks::new())?;
603+ let (acc, gate) = b.as_cell().ok_or(TTanks::new())?;
535604
536605 let mut res = Vec::new();
606+ let mut acc = acc.clone();
537607
538608 for n in list.list_iter() {
539− let (el, new_acc) = slam(ctx, gate.clone(), cell(n, acc))?.as_cell()?;
540− acc = new_acc;
541− 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());
542613 }
543614
544− Some(cell(Noun::list_refs(res.iter().cloned()), acc))
615+ Ok(cell(&Noun::list_refs(res.iter().cloned()), &acc))
545616};
546617
547618static SPUN: Jet = |ctx, n| {
548− let (list, gate) = n.as_cell()?;
619+ let (list, gate) = n.as_cell().ok_or(TTanks::new())?;
549620
550621 let mut res = Vec::new();
551− let mut acc = gate.clone().gate_sample()?.as_cell()?.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();
552629
553630 for n in list.list_iter() {
554− let (el, new_acc) = slam(ctx, gate.clone(), cell(n, acc))?.as_cell()?;
555− acc = new_acc;
556− 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());
557635 }
558636
559− Some(cell(Noun::list_refs(res.iter().cloned()), acc))
637+ Ok(cell(&Noun::list_refs(res.iter().cloned()), &acc))
560638};
561639
562640static TURN: Jet = |ctx, n| {
563− let (list, gate) = n.as_cell()?;
564− Some(Noun::list_refs(
565− traverse_iter_option(list.list_iter().map(|x| slam(ctx, gate.clone(), x)))?
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)))?
566644 .iter()
567645 .cloned(),
568646 ))
569647};
570648
571649static WELD: Jet = |_ctx, n| {
572− let (a, b) = n.as_cell()?;
650+ let (a, b) = n.as_cell().ok_or(TTanks::new())?;
573651
574− Some(Noun::list_refs(
652+ Ok(Noun::list_refs(
575653 a.list_iter()
576654 .chain(b.list_iter())
577655 .collect::<Vec<_>>()
578656 .iter()
657+ .cloned()
579658 .cloned(),
580659 ))
581660};
@@ -583,35 +662,38 @@ static WELD: Jet = |_ctx, n| {
583662static WELP: Jet = WELD;
584663
585664static ZING: Jet = |_ctx, n| {
586− Some(Noun::list_refs(
665+ Ok(Noun::list_refs(
587666 n.list_iter()
588667 .map(|l| l.list_iter())
589668 .flatten()
590669 .collect::<Vec<_>>()
591670 .iter()
671+ .cloned()
592672 .cloned(),
593673 ))
594674};
595675
596676static BEX: Jet = |ctx, n| {
597− Some(Rc::new(Noun::Atom(
677+ Ok(Rc::new(Noun::Atom(
598678 &ctx.big_uints.one << n.as_u32().unwrap(),
599679 )))
600680};
601681
602682static END: Jet = |ctx, n| {
603− let (a, b) = n.as_cell()?;
683+ let (a, b) = n.as_cell().ok_or(TTanks::new())?;
604684 let bite = a.as_bite();
605685
606686 let bits = bite.bits();
607687
608688 let mask = (&ctx.big_uints.one << bits) - &ctx.big_uints.one;
609689
610− Some(Rc::new(Noun::Atom(mask & b.as_atom()?)))
690+ Ok(Rc::new(Noun::Atom(
691+ mask & b.as_atom().ok_or(TTanks::new())?,
692+ )))
611693};
612694
613695static CAN: Jet = |ctx, n| {
614− let (a, b) = n.as_cell()?;
696+ let (a, b) = n.as_cell().ok_or(TTanks::new())?;
615697 let bloq = a.as_u32().unwrap();
616698 let bloq_ = 2u32.pow(bloq);
617699
@@ -626,66 +708,57 @@ static CAN: Jet = |ctx, n| {
626708 Some((acc? << bits) | (mask & q.as_atom()?))
627709 },
628710 );
629− Some(Rc::new(Noun::Atom(atom?)))
711+ Ok(Rc::new(Noun::Atom(atom.ok_or(TTanks::new())?)))
630712};
631713
632714static CAT: Jet = |_ctx, n| {
633− let (bloq, b) = n.as_cell()?;
634− let (b, c) = b.as_cell()?;
715+ let (bloq, b) = n.as_cell().ok_or(TTanks::new())?;
716+ let (b, c) = b.as_cell().ok_or(TTanks::new())?;
635717
636− let bloq = bloq.as_u32()?;
637− let b = b.as_atom()?;
638− let c = c.as_atom()?;
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())?;
639721
640− Some(Rc::new(Noun::Atom(
641− (c << (met(bloq, b.clone()) * 2u32.pow(bloq))) | b,
722+ Ok(Rc::new(Noun::Atom(
723+ (c << (met(bloq, &b) * 2u32.pow(bloq))) | b,
642724 )))
643725};
644726
645727static MET: Jet = |_ctx, n| {
646− let (bloq, b) = n.as_cell()?;
647− let b: Atom = b.as_atom()?.clone();
728+ let (bloq, b) = n.as_cell().ok_or(TTanks::new())?;
729+ let b: Atom = b.as_atom().ok_or(TTanks::new())?.clone();
648730 let bloq = bloq.as_u32().unwrap();
649731
650− Some(Rc::new(Noun::from_u32(met(bloq, b))))
732+ Ok(Rc::new(Noun::from_u32(met(bloq, &b))))
651733};
652734
653−fn met(bloq: u32, mut a: Atom) -> u32 {
654− let bits = 2u32.pow(bloq);
655−
656− let mut c = 0;
657−
658− while a > Atom::ZERO {
659− a = a >> bits;
660− c += 1;
661− }
662−
663− c
735+fn met(bloq: u32, a: &Atom) -> u32 {
736+ (a.bits() as u32).div_ceil(2u32.pow(bloq))
664737}
665738
666739static CUT: Jet = |ctx, n| {
667− let (a, b) = n.as_cell()?;
668− let (b, d) = b.as_cell()?;
669− let (b, c) = b.as_cell()?;
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())?;
670743
671744 let bits = 2u32.pow(a.as_u32().unwrap());
672745
673746 let mask = (&ctx.big_uints.one << (bits * c.as_u32().unwrap())) - &ctx.big_uints.one;
674747
675− Some(Rc::new(Noun::Atom(
676− (d.as_atom()? >> (bits * b.as_u32().unwrap())) & mask,
748+ Ok(Rc::new(Noun::Atom(
749+ (d.as_atom().ok_or(TTanks::new())? >> (bits * b.as_u32().unwrap())) & mask,
677750 )))
678751};
679752
680753static FIL: Jet = |ctx, n| {
681− let (a, b) = n.as_cell()?;
682− let (b, c) = b.as_cell()?;
754+ let (a, b) = n.as_cell().ok_or(TTanks::new())?;
755+ let (b, c) = b.as_cell().ok_or(TTanks::new())?;
683756
684757 let bits = 2u32.pow(a.as_u32().unwrap());
685758
686759 let mask = (&ctx.big_uints.one << bits) - &ctx.big_uints.one;
687760
688− let src = c.as_atom()? & mask;
761+ let src = c.as_atom().ok_or(TTanks::new())? & mask;
689762
690763 let mut target = ctx.big_uints.zero.clone();
691764
@@ -693,44 +766,44 @@ static FIL: Jet = |ctx, n| {
693766 target = (target << bits) | &src;
694767 }
695768
696− Some(Rc::new(Noun::Atom(target)))
769+ Ok(Rc::new(Noun::Atom(target)))
697770};
698771
699772static LSH: Jet = |_ctx, n| {
700− let (a, b) = n.as_cell()?;
773+ let (a, b) = n.as_cell().ok_or(TTanks::new())?;
701774 let a = a.as_bite();
702− let b = b.as_atom()?;
775+ let b = b.as_atom().ok_or(TTanks::new())?;
703776
704− Some(Rc::new(Noun::Atom(b << a.bits())))
777+ Ok(Rc::new(Noun::Atom(b << a.bits())))
705778};
706779
707780static RSH: Jet = |_ctx, n| {
708− let (a, b) = n.as_cell()?;
781+ let (a, b) = n.as_cell().ok_or(TTanks::new())?;
709782 let a = a.as_bite();
710− let b = b.as_atom()?;
783+ let b = b.as_atom().ok_or(TTanks::new())?;
711784
712− Some(Rc::new(Noun::Atom(b >> a.bits())))
785+ Ok(Rc::new(Noun::Atom(b >> a.bits())))
713786};
714787
715−static RAP: Jet = |ctx, n| {
716− let (bloq, b) = n.as_cell()?;
788+pub static RAP: Jet = |ctx, n| {
789+ let (bloq, b) = n.as_cell().ok_or(TTanks::new())?;
717790 let bloq = bloq.as_u32().unwrap();
718791 let bits = 2u32.pow(bloq);
719792
720793 let mut target = ctx.big_uints.zero.clone();
721794
722795 for el in b.list_iter().collect::<Vec<_>>().iter().rev() {
723− let el = el.as_atom()?;
796+ let el = el.as_atom().ok_or(TTanks::new())?;
724797 if el != &ctx.big_uints.zero {
725− target = (target << (bits * met(bloq, el.clone()))) | el;
798+ target = (target << (bits * met(bloq, &el))) | el;
726799 }
727800 }
728801
729− Some(Rc::new(Noun::Atom(target)))
802+ Ok(Rc::new(Noun::Atom(target)))
730803};
731804
732805static REP: Jet = |ctx, n| {
733− let (bite, b) = n.as_cell()?;
806+ let (bite, b) = n.as_cell().ok_or(TTanks::new())?;
734807 let bite = bite.as_bite();
735808
736809 let bits = bite.bits();
@@ -739,18 +812,18 @@ static REP: Jet = |ctx, n| {
739812 let mut target = ctx.big_uints.zero.clone();
740813
741814 for el in b.list_iter().collect::<Vec<_>>().iter().rev() {
742− target = (target << bits) | (el.as_atom()? & &mask);
815+ target = (target << bits) | (el.as_atom().ok_or(TTanks::new())? & &mask);
743816 }
744817
745− Some(Rc::new(Noun::Atom(target)))
818+ Ok(Rc::new(Noun::Atom(target)))
746819};
747820
748821static REV: Jet = |ctx, n| {
749− let (bloq, b) = n.as_cell()?;
750− let (len, dat) = b.as_cell()?;
822+ let (bloq, b) = n.as_cell().ok_or(TTanks::new())?;
823+ let (len, dat) = b.as_cell().ok_or(TTanks::new())?;
751824 let bloq = bloq.as_u32().unwrap();
752825 let len = len.as_u32().unwrap();
753− let mut dat: Atom = dat.as_atom()?.clone();
826+ let mut dat: Atom = dat.as_atom().ok_or(TTanks::new())?.clone();
754827
755828 let bits = 2u32.pow(bloq);
756829 let mask = (&ctx.big_uints.one << bits) - &ctx.big_uints.one;
@@ -762,13 +835,13 @@ static REV: Jet = |ctx, n| {
762835 dat = dat >> bits;
763836 }
764837
765− Some(Rc::new(Noun::Atom(target)))
838+ Ok(Rc::new(Noun::Atom(target)))
766839};
767840
768841static RIP: Jet = |ctx, n| {
769− let (bite, b) = n.as_cell()?;
842+ let (bite, b) = n.as_cell().ok_or(TTanks::new())?;
770843 let bite = bite.as_bite();
771− let mut b: Atom = b.as_atom()?.clone();
844+ let mut b: Atom = b.as_atom().ok_or(TTanks::new())?.clone();
772845
773846 let bits = bite.bits();
774847 let mask = (&ctx.big_uints.one << bits) - &ctx.big_uints.one;
@@ -780,15 +853,15 @@ static RIP: Jet = |ctx, n| {
780853 b = b >> bits;
781854 }
782855
783− Some(Noun::list_refs(target.iter().cloned()))
856+ Ok(Noun::list_refs(target.iter().cloned()))
784857};
785858
786859static RUN: Jet = |ctx, n| {
787− let (bite, b) = n.as_cell()?;
788− let (b, gate) = b.as_cell()?;
860+ let (bite, b) = n.as_cell().ok_or(TTanks::new())?;
861+ let (b, gate) = b.as_cell().ok_or(TTanks::new())?;
789862
790863 let bite = bite.as_bite();
791− let mut b: Atom = b.as_atom()?.clone();
864+ let mut b: Atom = b.as_atom().ok_or(TTanks::new())?.clone();
792865
793866 let bits = bite.bits();
794867 let mask = (&ctx.big_uints.one << bits) - &ctx.big_uints.one;
@@ -797,19 +870,22 @@ static RUN: Jet = |ctx, n| {
797870
798871 while b > ctx.big_uints.zero {
799872 target = (target << bits)
800− | ((*slam(ctx, gate.clone(), Rc::new(Noun::Atom(&mask & &b)))?).as_atom()? & &mask);
873+ | ((*slam_pulled_gate(ctx, gate, &Rc::new(Noun::Atom(&mask & &b)))?)
874+ .as_atom()
875+ .ok_or(TTanks::new())?
876+ & &mask);
801877 b = b >> bits;
802878 }
803879
804− Some(Rc::new(Noun::Atom(target)))
880+ Ok(Rc::new(Noun::Atom(target)))
805881};
806882
807883static RUT: Jet = |ctx, n| {
808− let (bite, b) = n.as_cell()?;
809− let (b, gate) = b.as_cell()?;
884+ let (bite, b) = n.as_cell().ok_or(TTanks::new())?;
885+ let (b, gate) = b.as_cell().ok_or(TTanks::new())?;
810886
811887 let bite = bite.as_bite();
812− let mut b: Atom = b.as_atom()?.clone();
888+ let mut b: Atom = b.as_atom().ok_or(TTanks::new())?.clone();
813889
814890 let bits = bite.bits();
815891 let mask = (&ctx.big_uints.one << bits) - &ctx.big_uints.one;
@@ -817,21 +893,25 @@ static RUT: Jet = |ctx, n| {
817893 let mut target = Vec::new();
818894
819895 while b > ctx.big_uints.zero {
820− target
821− .push((*slam(ctx, gate.clone(), Rc::new(Noun::Atom(&mask & &b)))?).as_atom()? & &mask);
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+ );
822902 b = b >> bits;
823903 }
824904
825− Some(Noun::list(target.iter().cloned().map(Noun::Atom)))
905+ Ok(Noun::list(target.iter().cloned().map(Noun::Atom)))
826906};
827907
828908static SEW: Jet = |ctx, n| {
829− let (a, b) = n.as_cell()?;
830− let (b, recipient) = b.as_cell()?;
831− let (sew_start, c) = b.as_cell()?;
832− let (number_of_blocks, donor) = c.as_cell()?;
833− let recipient = recipient.as_atom()?;
834− let donor = donor.as_atom()?;
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())?;
835915
836916 let bloq = a.as_u32().unwrap();
837917 let bits = 2u32.pow(bloq);
@@ -843,16 +923,16 @@ static SEW: Jet = |ctx, n| {
843923
844924 let target = (recipient ^ apendix) | (donor & mask);
845925
846− Some(Rc::new(Noun::Atom(target)))
926+ Ok(Rc::new(Noun::Atom(target)))
847927};
848928
849929static SWP: Jet = |ctx, n| {
850− let (bloq, b) = n.as_cell()?;
930+ let (bloq, b) = n.as_cell().ok_or(TTanks::new())?;
851931 let bloq = bloq.as_u32().unwrap();
852932 let bits = 2u32.pow(bloq);
853933 let mask = (&ctx.big_uints.one << bits) - &ctx.big_uints.one;
854934
855− let mut source = b.as_atom()?.clone();
935+ let mut source = b.as_atom().ok_or(TTanks::new())?.clone();
856936 let mut target = ctx.big_uints.zero.clone();
857937
858938 while source > ctx.big_uints.zero {
@@ -860,11 +940,11 @@ static SWP: Jet = |ctx, n| {
860940 source = source >> bits;
861941 }
862942
863− Some(Rc::new(Noun::Atom(target)))
943+ Ok(Rc::new(Noun::Atom(target)))
864944};
865945
866946static XEB: Jet = |_ctx, n| {
867− let mut a = n.as_atom()?.clone();
947+ let mut a = n.as_atom().ok_or(TTanks::new())?.clone();
868948
869949 let mut c = 0;
870950
@@ -873,7 +953,7 @@ static XEB: Jet = |_ctx, n| {
873953 c += 1;
874954 }
875955
876− Some(Rc::new(Noun::from_u32(c)))
956+ Ok(Rc::new(Noun::from_u32(c)))
877957};
878958
879959static CON: Jet = |_ctx, n| BINARY_ATOM(n, |a, b| a | b);
@@ -881,14 +961,310 @@ static DIS: Jet = |_ctx, n| BINARY_ATOM(n, |a, b| a & b);
881961static MIX: Jet = |_ctx, n| BINARY_ATOM(n, |a, b| a ^ b);
882962
883963static NOT: Jet = |ctx, n| {
884− let (a, b) = n.as_cell()?;
885− let (b, c) = b.as_cell()?;
964+ let (a, b) = n.as_cell().ok_or(TTanks::new())?;
965+ let (b, c) = b.as_cell().ok_or(TTanks::new())?;
886966
887967 let bloq = a.as_u32().unwrap();
888968 let bits = 2u32.pow(bloq);
889969 let mask = (&ctx.big_uints.one << (bits * b.as_u32().unwrap())) - &ctx.big_uints.one;
890970
891− let target = c.as_atom()? ^ &mask;
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+};
8921178
893− Some(Rc::new(Noun::Atom(target)))
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+ }
8941193};
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+}