@@ -8,18 +8,20 @@ use std::{
88};
99
1010use crate::{
11− interpreter::{slam_pulled_gate, InterpreterContext},
11+ interpreter::{slam_pulled_gate, InterpreterContext, Tanks},
1212 noun::{self, cell, Atom, Edge, Hair, Nail, Noun},
1313};
1414
15−fn traverse_iter_option<T: Clone, I: Iterator<Item = Option<T>>>(xs: I) -> Option<Vec<T>> {
15+fn traverse_iter_result<E: Clone, T: Clone, I: Iterator<Item = Result<T, E>>>(
16+ xs: I,
17+) -> Result<Vec<T>, E> {
1618 let mut target: Vec<T> = Vec::new();
1719
1820 for x in xs {
1921 target.push(x.clone()?)
2022 }
2123
22− Some(target)
24+ Ok(target)
2325}
2426
2527pub type Jets = BTreeMap<noun::Hash, Jet>;
@@ -108,39 +110,51 @@ pub fn generate_jets() -> Jets {
108110 ])
109111}
110112
111−pub type Jet = fn(ctx: &mut InterpreterContext, &Rc<Noun>) -> Option<Rc<Noun>>;
113+pub type Jet = fn(ctx: &mut InterpreterContext, &Rc<Noun>) -> Result<Rc<Noun>, Tanks>;
112114pub type DoubleJet = fn(ctx: &mut InterpreterContext, &Rc<Noun>, &Rc<Noun>) -> Option<Rc<Noun>>;
113115
114−static BINARY_ATOM: fn(&Rc<Noun>, fn(&Atom, &Atom) -> Atom) -> Option<Rc<Noun>> =
116+static BINARY_ATOM: fn(&Rc<Noun>, fn(&Atom, &Atom) -> Atom) -> Result<Rc<Noun>, Tanks> =
115117 |n: &Rc<Noun>, f: fn(&Atom, &Atom) -> Atom| {
116− let (p, q) = n.as_cell()?;
117− Some(Rc::new(Noun::Atom(f(p.as_atom()?, q.as_atom()?))))
118+ let (p, q) = n.as_cell().ok_or(Tanks::new())?;
119+ Ok(Rc::new(Noun::Atom(f(
120+ p.as_atom().ok_or(Tanks::new())?,
121+ q.as_atom().ok_or(Tanks::new())?,
122+ ))))
118123 };
119124
120125static BINARY_ATOM_LOOB: fn(
121126 &InterpreterContext,
122127 &Rc<Noun>,
123128 fn(&Atom, &Atom) -> bool,
124−) -> Option<Rc<Noun>> = |ctx: &InterpreterContext, n: &Rc<Noun>, f: fn(&Atom, &Atom) -> bool| {
125− let (p, q) = n.as_cell()?;
126−
127− if f(p.as_atom()?, q.as_atom()?) {
128− Some(ctx.nouns.sig.clone())
129− } else {
130− Some(ctx.nouns.one.clone())
131− }
132−};
129+) -> Result<Rc<Noun>, Tanks> =
130+ |ctx: &InterpreterContext, n: &Rc<Noun>, f: fn(&Atom, &Atom) -> bool| {
131+ let (p, q) = n.as_cell().ok_or(Tanks::new())?;
132+
133+ if f(
134+ p.as_atom().ok_or(Tanks::new())?,
135+ q.as_atom().ok_or(Tanks::new())?,
136+ ) {
137+ Ok(ctx.nouns.sig.clone())
138+ } else {
139+ Ok(ctx.nouns.one.clone())
140+ }
141+ };
133142
134−static BINARY_ATOM_PAIR: fn(&Rc<Noun>, fn(&Atom, &Atom) -> (Atom, Atom)) -> Option<Rc<Noun>> =
135− |n: &Rc<Noun>, f: fn(&Atom, &Atom) -> (Atom, Atom)| {
136− let (p, q) = n.as_cell()?;
143+static BINARY_ATOM_PAIR: fn(
144+ &Rc<Noun>,
145+ fn(&Atom, &Atom) -> (Atom, Atom),
146+) -> Result<Rc<Noun>, Tanks> = |n: &Rc<Noun>, f: fn(&Atom, &Atom) -> (Atom, Atom)| {
147+ let (p, q) = n.as_cell().ok_or(Tanks::new())?;
137148
138− let (a, b) = f(p.as_atom()?, q.as_atom()?);
139− Some(cell(&Rc::new(Noun::Atom(a)), &Rc::new(Noun::Atom(b))))
140− };
149+ let (a, b) = f(
150+ p.as_atom().ok_or(Tanks::new())?,
151+ q.as_atom().ok_or(Tanks::new())?,
152+ );
153+ Ok(cell(&Rc::new(Noun::Atom(a)), &Rc::new(Noun::Atom(b))))
154+};
141155
142156static ADD: Jet = |_ctx, n| BINARY_ATOM(n, |a, b| a + b);
143−static DEC: Jet = |_ctx, n| Some(Rc::new(Noun::Atom(n.as_atom()? - 1u32)));
157+static DEC: Jet = |_ctx, n| Ok(Rc::new(Noun::Atom(n.as_atom().ok_or(Tanks::new())? - 1u32)));
144158static DVR: Jet = |_ctx, n| BINARY_ATOM_PAIR(n, |a, b| a.div_rem(&b));
145159static DIV: Jet = |_ctx, n| BINARY_ATOM(n, |a, b| a / b);
146160static GTE: Jet = |ctx, n| BINARY_ATOM_LOOB(ctx, n, |a, b| a >= b);
@@ -154,29 +168,31 @@ static MUL: Jet = |_ctx, n| BINARY_ATOM(n, |a, b| a * b);
154168static SUB: Jet = |_ctx, n| BINARY_ATOM(n, |a, b| a - b);
155169
156170static CAP: Jet = |ctx, n| {
157− let n = n.as_atom()?;
171+ let n = n.as_atom().ok_or(Tanks::new())?;
158172 CAP_ATOM(ctx, n.clone())
159173};
160174
161−static CAP_ATOM: fn(&InterpreterContext, Atom) -> Option<Rc<Noun>> = |ctx, n: Atom| {
175+static CAP_ATOM: fn(&InterpreterContext, Atom) -> Result<Rc<Noun>, Tanks> = |ctx, n: Atom| {
162176 let mut n_iter = n.iter_u32_digits();
163177
164178 match n_iter.len() {
165− 0 => None,
179+ 0 => Err(Tanks::new()),
166180 1 => CAP_U32(ctx, n_iter.next().unwrap()),
167181 _ => CAP_ATOM(ctx, n >> 1),
168182 }
169183};
170−static CAP_U32: fn(ctx: &InterpreterContext, u32) -> Option<Rc<Noun>> = |ctx, n| match n {
171− 0 | 1 => None,
172− 2 => Some(ctx.nouns.two.clone()),
173− 3 => Some(ctx.nouns.three.clone()),
184+static CAP_U32: fn(ctx: &InterpreterContext, u32) -> Result<Rc<Noun>, Tanks> = |ctx, n| match n {
185+ 0 | 1 => Err(Tanks::new()),
186+ 2 => Ok(ctx.nouns.two.clone()),
187+ 3 => Ok(ctx.nouns.three.clone()),
174188 n => CAP_U32(ctx, n >> 1),
175189};
176190
177191static MAS: Jet = |ctx, n| {
178− let n = n.as_atom()?;
179− Some(Rc::new(Noun::Atom(MAS_ATOM(ctx, n.clone())?)))
192+ let n = n.as_atom().ok_or(Tanks::new())?;
193+ Ok(Rc::new(Noun::Atom(
194+ MAS_ATOM(ctx, n.clone()).ok_or(Tanks::new())?,
195+ )))
180196};
181197static MAS_ATOM: fn(&InterpreterContext, Atom) -> Option<Atom> = |ctx, n| {
182198 let mut n_iter = n.iter_u32_digits();
@@ -197,24 +213,24 @@ static MAS_U32: fn(u32) -> u32 = |n| match n {
197213};
198214
199215static PEG: Jet = |ctx, n| {
200− let (a, b) = n.as_cell()?;
216+ let (a, b) = n.as_cell().ok_or(Tanks::new())?;
201217
202− let a = a.as_atom()?;
203− let b = b.as_atom()?;
218+ let a = a.as_atom().ok_or(Tanks::new())?;
219+ let b = b.as_atom().ok_or(Tanks::new())?;
204220
205221 if *a == Atom::ZERO {
206− return None;
222+ return Err(Tanks::new());
207223 };
208224
209− Some(Rc::new(Noun::Atom(PEG_ATOM(ctx, a, b.clone())?)))
225+ Ok(Rc::new(Noun::Atom(PEG_ATOM(ctx, a, b.clone())?)))
210226};
211−static PEG_ATOM: fn(&InterpreterContext, &Atom, Atom) -> Option<Atom> = |ctx, a, b| {
227+static PEG_ATOM: fn(&InterpreterContext, &Atom, Atom) -> Result<Atom, Tanks> = |ctx, a, b| {
212228 let mut b_iter = b.iter_u32_digits();
213229
214230 match b_iter.len() {
215− 0 => None,
216− 1 => Some(PEG_U32(a, b_iter.next().unwrap())),
217− _ => Some((&b & &ctx.big_uints.one) + (PEG_ATOM(ctx, a, b >> 1)? << 1)),
231+ 0 => Err(Tanks::new()),
232+ 1 => Ok(PEG_U32(a, b_iter.next().unwrap())),
233+ _ => Ok((&b & &ctx.big_uints.one) + (PEG_ATOM(ctx, a, b >> 1)? << 1)),
218234 }
219235};
220236static PEG_U32: fn(&Atom, u32) -> Atom = |a, b| match b {
@@ -226,9 +242,9 @@ static PEG_U32: fn(&Atom, u32) -> Atom = |a, b| match b {
226242};
227243
228244static FAND: Jet = |ctx, n| {
229− let (nedl, hstk) = n.as_cell()?;
245+ let (nedl, hstk) = n.as_cell().ok_or(Tanks::new())?;
230246 if nedl.is_sig() || hstk.is_sig() {
231− return Some(ctx.nouns.sig.clone());
247+ return Ok(ctx.nouns.sig.clone());
232248 }
233249
234250 let nedl: Vec<&Rc<Noun>> = nedl.list_iter().collect();
@@ -252,13 +268,13 @@ static FAND: Jet = |ctx, n| {
252268 inner_iter = iter.clone();
253269 }
254270
255− Some(Noun::list(result.iter().map(|a| Noun::from_u32(*a))))
271+ Ok(Noun::list(result.iter().map(|a| Noun::from_u32(*a))))
256272};
257273
258274static FIND: Jet = |ctx, n| {
259− let (nedl, hstk) = n.as_cell()?;
275+ let (nedl, hstk) = n.as_cell().ok_or(Tanks::new())?;
260276 if nedl.is_sig() || hstk.is_sig() {
261− return Some(ctx.nouns.sig.clone());
277+ return Ok(ctx.nouns.sig.clone());
262278 }
263279
264280 let nedl: Vec<&Rc<Noun>> = nedl.list_iter().collect();
@@ -274,30 +290,28 @@ static FIND: Jet = |ctx, n| {
274290 .collect::<Vec<_>>()
275291 == nedl
276292 {
277− return Some(Rc::new(Noun::from_u32(i)).unit());
293+ return Ok(Rc::new(Noun::from_u32(i)).unit());
278294 }
279295
280296 inner_iter = iter.clone();
281297 }
282298
283− return Some(ctx.nouns.sig.clone());
299+ return Ok(ctx.nouns.sig.clone());
284300};
285301
286302static FLOP: Jet = |ctx, n| {
287− Some(
288− n.list_iter()
289− .fold(ctx.nouns.sig.clone(), |tail, head| cell(&head, &tail)),
290− )
303+ Ok(n.list_iter()
304+ .fold(ctx.nouns.sig.clone(), |tail, head| cell(&head, &tail)))
291305};
292306
293307static GULF: Jet = |_ctx, n| {
294− let (from, to) = n.as_cell()?;
308+ let (from, to) = n.as_cell().ok_or(Tanks::new())?;
295309
296− let mut from = (*from.as_atom()?).clone();
297− let to = to.as_atom()?.clone();
310+ let mut from = (*from.as_atom().ok_or(Tanks::new())?).clone();
311+ let to = to.as_atom().ok_or(Tanks::new())?.clone();
298312
299313 if from > to {
300− return None;
314+ return Err(Tanks::new());
301315 }
302316
303317 let mut tmp = Vec::new();
@@ -307,105 +321,119 @@ static GULF: Jet = |_ctx, n| {
307321 from += 1u32;
308322 }
309323
310− Some(Noun::list(tmp.iter().rev().map(|a| Noun::Atom(a.clone()))))
324+ Ok(Noun::list(tmp.iter().rev().map(|a| Noun::Atom(a.clone()))))
311325};
312326
313327static INTO: Jet = |_ctx, n| {
314− let (a, b) = n.as_cell()?;
315− let (b, c) = b.as_cell()?;
328+ let (a, b) = n.as_cell().ok_or(Tanks::new())?;
329+ let (b, c) = b.as_cell().ok_or(Tanks::new())?;
316330
317− let mut b_iter = b.as_atom()?.iter_u32_digits();
331+ let mut b_iter = b.as_atom().ok_or(Tanks::new())?.iter_u32_digits();
318332
319333 match b_iter.len() {
320− 0 => Some(cell(&c, &a)),
334+ 0 => Ok(cell(&c, &a)),
321335 1 => {
322336 let l = a.list_iter();
323337 let b = b_iter.next().unwrap() as usize;
324− Some(Noun::list_refs(
338+ Ok(Noun::list_refs(
325339 l.clone()
326340 .take(b)
327341 .chain(once(c))
328342 .chain(l.skip(b))
329343 .collect::<Vec<_>>()
330344 .iter()
331− .map(|x| *x),
345+ .cloned()
346+ .cloned(),
332347 ))
333348 }
334− _ => Some(Noun::list_refs(
349+ _ => Ok(Noun::list_refs(
335350 a.list_iter()
336351 .chain(once(c))
337352 .collect::<Vec<_>>()
338353 .iter()
354+ .cloned()
339355 .cloned(),
340356 )),
341357 }
342358};
343359
344360static JOIN: Jet = |_ctx, n| {
345− let (sep, list) = n.as_cell()?;
346− Some(Noun::list_refs(
361+ let (sep, list) = n.as_cell().ok_or(Tanks::new())?;
362+ Ok(Noun::list_refs(
347363 list.list_iter()
348364 .intersperse(sep)
349365 .collect::<Vec<_>>()
350366 .iter()
367+ .cloned()
351368 .cloned(),
352369 ))
353370};
354371
355372static LENT: Jet = |_ctx, n| {
356− Some(Rc::new(Noun::from_u32(
373+ Ok(Rc::new(Noun::from_u32(
357374 n.list_iter().fold(0u32, |l, _| l + 1),
358375 )))
359376};
360377
361378static LEVY: Jet = |ctx, n| {
362− let (a, b) = n.as_cell()?;
363− if traverse_iter_option(a.list_iter().map(|n| slam_pulled_gate(ctx, b, n)))?
379+ let (a, b) = n.as_cell().ok_or(Tanks::new())?;
380+ if traverse_iter_result(a.list_iter().map(|n| slam_pulled_gate(ctx, b, n)))?
364381 .iter()
365382 .all(|x| x.is_y())
366383 {
367− Some(ctx.nouns.y.clone())
384+ Ok(ctx.nouns.y.clone())
368385 } else {
369− Some(ctx.nouns.n.clone())
386+ Ok(ctx.nouns.n.clone())
370387 }
371388};
372389
373390static LIEN: Jet = |ctx, n| {
374− let (a, b) = n.as_cell()?;
375− if traverse_iter_option(a.list_iter().map(|n| slam_pulled_gate(ctx, b, n)))?
391+ let (a, b) = n.as_cell().ok_or(Tanks::new())?;
392+ if traverse_iter_result(a.list_iter().map(|n| slam_pulled_gate(ctx, b, n)))?
376393 .iter()
377394 .any(|x| x.is_y())
378395 {
379− Some(ctx.nouns.y.clone())
396+ Ok(ctx.nouns.y.clone())
380397 } else {
381− Some(ctx.nouns.n.clone())
398+ Ok(ctx.nouns.n.clone())
382399 }
383400};
384401
385402static MURN: Jet = |ctx, n| {
386− let (a, b) = n.as_cell()?;
403+ let (a, b) = n.as_cell().ok_or(Tanks::new())?;
387404
388− Some(Noun::list_refs(
389− a.list_iter()
390− .filter_map(|n| slam_pulled_gate(ctx, b, n)?.as_unit().cloned())
391− .collect::<Vec<_>>()
392− .iter(),
405+ Ok(Noun::list_refs(
406+ traverse_iter_result(
407+ a.list_iter()
408+ .map(|n| Ok(slam_pulled_gate(ctx, b, n)?.as_unit().cloned())),
409+ )?
410+ .iter()
411+ .filter_map(|x| x.clone()),
393412 ))
394413};
395414
396415static REAP: Jet = |_ctx, n| {
397− let (a, b) = n.as_cell()?;
416+ let (a, b) = n.as_cell().ok_or(Tanks::new())?;
398417
399− Some(Noun::list_refs(repeat_n(b, a.as_u32().unwrap() as usize)))
418+ Ok(Noun::list_refs(repeat_n(
419+ b.clone(),
420+ a.as_u32().unwrap() as usize,
421+ )))
400422};
401423
402−static REAR: Jet = |_ctx, n| n.list_iter().last().cloned();
424+static REAR: Jet = |_ctx, n| n.list_iter().last().ok_or(Tanks::new()).cloned();
403425
404426static REEL: Jet = |ctx, n| {
405− let (list, gate) = n.as_cell()?;
427+ let (list, gate) = n.as_cell().ok_or(Tanks::new())?;
406428
407429 list.list_iter().collect::<Vec<_>>().iter().rfold(
408− Some(gate.gate_sample()?.as_cell()?.1.clone()),
430+ Ok(gate
431+ .gate_sample()
432+ .ok_or(Tanks::new())?
433+ .as_cell()
434+ .ok_or(Tanks::new())?
435+ .1
436+ .clone()),
409437 |acc, next| {
410438 let acc = acc?;
411439 slam_pulled_gate(ctx, gate, &cell(&next, &acc))
@@ -414,10 +442,17 @@ static REEL: Jet = |ctx, n| {
414442};
415443
416444static ROLL: Jet = |ctx, n| {
417− let (list, gate) = n.as_cell()?;
445+ let (list, gate) = n.as_cell().ok_or(Tanks::new())?;
418446
419447 list.list_iter().fold(
420− Some(gate.clone().gate_sample()?.as_cell()?.1.clone()),
448+ Ok(gate
449+ .clone()
450+ .gate_sample()
451+ .ok_or(Tanks::new())?
452+ .as_cell()
453+ .ok_or(Tanks::new())?
454+ .1
455+ .clone()),
421456 |acc, next| {
422457 let acc = acc?;
423458 slam_pulled_gate(ctx, gate, &cell(&next, &acc))
@@ -426,105 +461,111 @@ static ROLL: Jet = |ctx, n| {
426461};
427462
428463static SCAG: Jet = |_ctx, n| {
429− let (a, b) = n.as_cell()?;
464+ let (a, b) = n.as_cell().ok_or(Tanks::new())?;
430465
431− Some(Noun::list_refs(
466+ Ok(Noun::list_refs(
432467 b.list_iter()
433468 .take(a.as_u32().unwrap() as usize)
434469 .collect::<Vec<_>>()
435470 .iter()
471+ .cloned()
436472 .cloned(),
437473 ))
438474};
439475
440476static SKID: Jet = |ctx, n| {
441− let (list, gate) = n.as_cell()?;
477+ let (list, gate) = n.as_cell().ok_or(Tanks::new())?;
442478
443− let slammed_n = traverse_iter_option(
479+ let slammed_n = traverse_iter_result(
444480 list.list_iter()
445− .map(|n| Some((slam_pulled_gate(ctx, gate, n)?, n))),
481+ .map(|n| Ok((slam_pulled_gate(ctx, gate, n)?, n))),
446482 )?;
447483 let (ys, ns): (Vec<_>, _) = slammed_n.iter().partition(|(l, _)| l.is_y());
448484
449− Some(cell(
450− &Noun::list_refs(ys.iter().map(|(_, x)| *x)),
451− &Noun::list_refs(ns.iter().map(|(_, x)| *x)),
485+ Ok(cell(
486+ &Noun::list_refs(ys.iter().map(|(_, x)| (*x).clone())),
487+ &Noun::list_refs(ns.iter().map(|(_, x)| (*x).clone())),
452488 ))
453489};
454490
455491static SKIM: Jet = |ctx, n| {
456− let (list, gate) = n.as_cell()?;
492+ let (list, gate) = n.as_cell().ok_or(Tanks::new())?;
457493
458− Some(Noun::list_refs(
459− traverse_iter_option(
494+ Ok(Noun::list_refs(
495+ traverse_iter_result(
460496 list.list_iter()
461− .map(|n| Some((slam_pulled_gate(ctx, gate, n)?, n))),
497+ .map(|n| Ok((slam_pulled_gate(ctx, gate, n)?, n))),
462498 )?
463499 .iter()
464500 .filter(|(l, _)| l.is_y())
465− .map(|(_, x)| *x),
501+ .map(|(_, x)| (*x).clone()),
466502 ))
467503};
468504
469505static SKIP: Jet = |ctx, n| {
470− let (list, gate) = n.as_cell()?;
506+ let (list, gate) = n.as_cell().ok_or(Tanks::new())?;
471507
472− Some(Noun::list_refs(
473− traverse_iter_option(
508+ Ok(Noun::list_refs(
509+ traverse_iter_result(
474510 list.list_iter()
475− .map(|n| Some((slam_pulled_gate(ctx, gate, n)?, n))),
511+ .map(|n| Ok((slam_pulled_gate(ctx, gate, n)?, n))),
476512 )?
477513 .iter()
478514 .filter(|(l, _)| l.is_y())
479− .map(|(_, x)| x)
480− .cloned(),
515+ .map(|(_, x)| (*x).clone()),
481516 ))
482517};
483518
484519static SLAG: Jet = |ctx, n| {
485− let (a, list) = n.as_cell()?;
520+ let (a, list) = n.as_cell().ok_or(Tanks::new())?;
486521
487− let mut a_iter = a.as_atom()?.iter_u32_digits();
522+ let mut a_iter = a.as_atom().ok_or(Tanks::new())?.iter_u32_digits();
488523
489524 match a_iter.len() {
490− 0 => Some(list.clone()),
491− 1 => Some(Noun::list_refs(
525+ 0 => Ok(list.clone()),
526+ 1 => Ok(Noun::list_refs(
492527 list.list_iter()
493528 .skip(a_iter.next().unwrap() as usize)
494529 .collect::<Vec<_>>()
495530 .iter()
531+ .cloned()
496532 .cloned(),
497533 )),
498− _ => Some(ctx.nouns.sig.clone()),
534+ _ => Ok(ctx.nouns.sig.clone()),
499535 }
500536};
501537
502538static SNAG: Jet = |_ctx, n| {
503− let (a, list) = n.as_cell()?;
539+ let (a, list) = n.as_cell().ok_or(Tanks::new())?;
504540
505− list.list_iter().nth(a.as_u32().unwrap() as usize).cloned()
541+ list.list_iter()
542+ .nth(a.as_u32().unwrap() as usize)
543+ .cloned()
544+ .ok_or(Tanks::new())
506545};
507546
508547static SNIP: Jet = |_ctx, n| {
509− Some(Noun::list_refs(
548+ Ok(Noun::list_refs(
510549 n.list_iter()
511550 .collect::<Vec<_>>()
512551 .iter()
513552 .rev()
514553 .skip(1)
515554 .rev()
555+ .cloned()
516556 .cloned(),
517557 ))
518558};
519559
520560static SNOC: Jet = |_ctx, n| {
521− let (list, b) = n.as_cell()?;
561+ let (list, b) = n.as_cell().ok_or(Tanks::new())?;
522562
523− Some(Noun::list_refs(
563+ Ok(Noun::list_refs(
524564 list.list_iter()
525565 .chain(once(b))
526566 .collect::<Vec<_>>()
527567 .iter()
568+ .cloned()
528569 .cloned(),
529570 ))
530571};
@@ -548,53 +589,62 @@ static SNOC: Jet = |_ctx, n| {
548589// };
549590
550591static SPIN: Jet = |ctx, n| {
551− let (list, b) = n.as_cell()?;
552− let (acc, gate) = b.as_cell()?;
592+ let (list, b) = n.as_cell().ok_or(Tanks::new())?;
593+ let (acc, gate) = b.as_cell().ok_or(Tanks::new())?;
553594
554595 let mut res = Vec::new();
555596 let mut acc = acc.clone();
556597
557598 for n in list.list_iter() {
558599 let foo = slam_pulled_gate(ctx, gate, &cell(&n, &acc))?;
559− let (el, new_acc) = foo.as_cell()?;
600+ let (el, new_acc) = foo.as_cell().ok_or(Tanks::new())?;
560601 acc = new_acc.clone();
561602 res.push(el.clone());
562603 }
563604
564− Some(cell(&Noun::list_refs(res.iter()), &acc))
605+ Ok(cell(&Noun::list_refs(res.iter().cloned()), &acc))
565606};
566607
567608static SPUN: Jet = |ctx, n| {
568− let (list, gate) = n.as_cell()?;
609+ let (list, gate) = n.as_cell().ok_or(Tanks::new())?;
569610
570611 let mut res = Vec::new();
571− let mut acc = gate.gate_sample()?.as_cell()?.1.clone();
612+ let mut acc = gate
613+ .gate_sample()
614+ .ok_or(Tanks::new())?
615+ .as_cell()
616+ .ok_or(Tanks::new())?
617+ .1
618+ .clone();
572619
573620 for n in list.list_iter() {
574621 let foo = slam_pulled_gate(ctx, gate, &cell(&n, &acc))?;
575− let (el, new_acc) = foo.as_cell()?;
622+ let (el, new_acc) = foo.as_cell().ok_or(Tanks::new())?;
576623 acc = new_acc.clone();
577624 res.push(el.clone());
578625 }
579626
580− Some(cell(&Noun::list_refs(res.iter()), &acc))
627+ Ok(cell(&Noun::list_refs(res.iter().cloned()), &acc))
581628};
582629
583630static TURN: Jet = |ctx, n| {
584− let (list, gate) = n.as_cell()?;
585− Some(Noun::list_refs(
586− traverse_iter_option(list.list_iter().map(|x| slam_pulled_gate(ctx, gate, x)))?.iter(),
631+ let (list, gate) = n.as_cell().ok_or(Tanks::new())?;
632+ Ok(Noun::list_refs(
633+ traverse_iter_result(list.list_iter().map(|x| slam_pulled_gate(ctx, gate, x)))?
634+ .iter()
635+ .cloned(),
587636 ))
588637};
589638
590639static WELD: Jet = |_ctx, n| {
591− let (a, b) = n.as_cell()?;
640+ let (a, b) = n.as_cell().ok_or(Tanks::new())?;
592641
593− Some(Noun::list_refs(
642+ Ok(Noun::list_refs(
594643 a.list_iter()
595644 .chain(b.list_iter())
596645 .collect::<Vec<_>>()
597646 .iter()
647+ .cloned()
598648 .cloned(),
599649 ))
600650};
@@ -602,35 +652,36 @@ static WELD: Jet = |_ctx, n| {
602652static WELP: Jet = WELD;
603653
604654static ZING: Jet = |_ctx, n| {
605− Some(Noun::list_refs(
655+ Ok(Noun::list_refs(
606656 n.list_iter()
607657 .map(|l| l.list_iter())
608658 .flatten()
609659 .collect::<Vec<_>>()
610660 .iter()
661+ .cloned()
611662 .cloned(),
612663 ))
613664};
614665
615666static BEX: Jet = |ctx, n| {
616− Some(Rc::new(Noun::Atom(
667+ Ok(Rc::new(Noun::Atom(
617668 &ctx.big_uints.one << n.as_u32().unwrap(),
618669 )))
619670};
620671
621672static END: Jet = |ctx, n| {
622− let (a, b) = n.as_cell()?;
673+ let (a, b) = n.as_cell().ok_or(Tanks::new())?;
623674 let bite = a.as_bite();
624675
625676 let bits = bite.bits();
626677
627678 let mask = (&ctx.big_uints.one << bits) - &ctx.big_uints.one;
628679
629− Some(Rc::new(Noun::Atom(mask & b.as_atom()?)))
680+ Ok(Rc::new(Noun::Atom(mask & b.as_atom().ok_or(Tanks::new())?)))
630681};
631682
632683static CAN: Jet = |ctx, n| {
633− let (a, b) = n.as_cell()?;
684+ let (a, b) = n.as_cell().ok_or(Tanks::new())?;
634685 let bloq = a.as_u32().unwrap();
635686 let bloq_ = 2u32.pow(bloq);
636687
@@ -645,28 +696,28 @@ static CAN: Jet = |ctx, n| {
645696 Some((acc? << bits) | (mask & q.as_atom()?))
646697 },
647698 );
648− Some(Rc::new(Noun::Atom(atom?)))
699+ Ok(Rc::new(Noun::Atom(atom.ok_or(Tanks::new())?)))
649700};
650701
651702static CAT: Jet = |_ctx, n| {
652− let (bloq, b) = n.as_cell()?;
653− let (b, c) = b.as_cell()?;
703+ let (bloq, b) = n.as_cell().ok_or(Tanks::new())?;
704+ let (b, c) = b.as_cell().ok_or(Tanks::new())?;
654705
655− let bloq = bloq.as_u32()?;
656− let b = b.as_atom()?;
657− let c = c.as_atom()?;
706+ let bloq = bloq.as_u32().ok_or(Tanks::new())?;
707+ let b = b.as_atom().ok_or(Tanks::new())?;
708+ let c = c.as_atom().ok_or(Tanks::new())?;
658709
659− Some(Rc::new(Noun::Atom(
710+ Ok(Rc::new(Noun::Atom(
660711 (c << (met(bloq, &b) * 2u32.pow(bloq))) | b,
661712 )))
662713};
663714
664715static MET: Jet = |_ctx, n| {
665− let (bloq, b) = n.as_cell()?;
666− let b: Atom = b.as_atom()?.clone();
716+ let (bloq, b) = n.as_cell().ok_or(Tanks::new())?;
717+ let b: Atom = b.as_atom().ok_or(Tanks::new())?.clone();
667718 let bloq = bloq.as_u32().unwrap();
668719
669− Some(Rc::new(Noun::from_u32(met(bloq, &b))))
720+ Ok(Rc::new(Noun::from_u32(met(bloq, &b))))
670721};
671722
672723fn met(bloq: u32, a: &Atom) -> u32 {
@@ -674,28 +725,28 @@ fn met(bloq: u32, a: &Atom) -> u32 {
674725}
675726
676727static CUT: Jet = |ctx, n| {
677− let (a, b) = n.as_cell()?;
678− let (b, d) = b.as_cell()?;
679− let (b, c) = b.as_cell()?;
728+ let (a, b) = n.as_cell().ok_or(Tanks::new())?;
729+ let (b, d) = b.as_cell().ok_or(Tanks::new())?;
730+ let (b, c) = b.as_cell().ok_or(Tanks::new())?;
680731
681732 let bits = 2u32.pow(a.as_u32().unwrap());
682733
683734 let mask = (&ctx.big_uints.one << (bits * c.as_u32().unwrap())) - &ctx.big_uints.one;
684735
685− Some(Rc::new(Noun::Atom(
686− (d.as_atom()? >> (bits * b.as_u32().unwrap())) & mask,
736+ Ok(Rc::new(Noun::Atom(
737+ (d.as_atom().ok_or(Tanks::new())? >> (bits * b.as_u32().unwrap())) & mask,
687738 )))
688739};
689740
690741static FIL: Jet = |ctx, n| {
691− let (a, b) = n.as_cell()?;
692− let (b, c) = b.as_cell()?;
742+ let (a, b) = n.as_cell().ok_or(Tanks::new())?;
743+ let (b, c) = b.as_cell().ok_or(Tanks::new())?;
693744
694745 let bits = 2u32.pow(a.as_u32().unwrap());
695746
696747 let mask = (&ctx.big_uints.one << bits) - &ctx.big_uints.one;
697748
698− let src = c.as_atom()? & mask;
749+ let src = c.as_atom().ok_or(Tanks::new())? & mask;
699750
700751 let mut target = ctx.big_uints.zero.clone();
701752
@@ -703,44 +754,44 @@ static FIL: Jet = |ctx, n| {
703754 target = (target << bits) | &src;
704755 }
705756
706− Some(Rc::new(Noun::Atom(target)))
757+ Ok(Rc::new(Noun::Atom(target)))
707758};
708759
709760static LSH: Jet = |_ctx, n| {
710− let (a, b) = n.as_cell()?;
761+ let (a, b) = n.as_cell().ok_or(Tanks::new())?;
711762 let a = a.as_bite();
712− let b = b.as_atom()?;
763+ let b = b.as_atom().ok_or(Tanks::new())?;
713764
714− Some(Rc::new(Noun::Atom(b << a.bits())))
765+ Ok(Rc::new(Noun::Atom(b << a.bits())))
715766};
716767
717768static RSH: Jet = |_ctx, n| {
718− let (a, b) = n.as_cell()?;
769+ let (a, b) = n.as_cell().ok_or(Tanks::new())?;
719770 let a = a.as_bite();
720− let b = b.as_atom()?;
771+ let b = b.as_atom().ok_or(Tanks::new())?;
721772
722− Some(Rc::new(Noun::Atom(b >> a.bits())))
773+ Ok(Rc::new(Noun::Atom(b >> a.bits())))
723774};
724775
725776static RAP: Jet = |ctx, n| {
726− let (bloq, b) = n.as_cell()?;
777+ let (bloq, b) = n.as_cell().ok_or(Tanks::new())?;
727778 let bloq = bloq.as_u32().unwrap();
728779 let bits = 2u32.pow(bloq);
729780
730781 let mut target = ctx.big_uints.zero.clone();
731782
732783 for el in b.list_iter().collect::<Vec<_>>().iter().rev() {
733− let el = el.as_atom()?;
784+ let el = el.as_atom().ok_or(Tanks::new())?;
734785 if el != &ctx.big_uints.zero {
735786 target = (target << (bits * met(bloq, &el))) | el;
736787 }
737788 }
738789
739− Some(Rc::new(Noun::Atom(target)))
790+ Ok(Rc::new(Noun::Atom(target)))
740791};
741792
742793static REP: Jet = |ctx, n| {
743− let (bite, b) = n.as_cell()?;
794+ let (bite, b) = n.as_cell().ok_or(Tanks::new())?;
744795 let bite = bite.as_bite();
745796
746797 let bits = bite.bits();
@@ -749,18 +800,18 @@ static REP: Jet = |ctx, n| {
749800 let mut target = ctx.big_uints.zero.clone();
750801
751802 for el in b.list_iter().collect::<Vec<_>>().iter().rev() {
752− target = (target << bits) | (el.as_atom()? & &mask);
803+ target = (target << bits) | (el.as_atom().ok_or(Tanks::new())? & &mask);
753804 }
754805
755− Some(Rc::new(Noun::Atom(target)))
806+ Ok(Rc::new(Noun::Atom(target)))
756807};
757808
758809static REV: Jet = |ctx, n| {
759− let (bloq, b) = n.as_cell()?;
760− let (len, dat) = b.as_cell()?;
810+ let (bloq, b) = n.as_cell().ok_or(Tanks::new())?;
811+ let (len, dat) = b.as_cell().ok_or(Tanks::new())?;
761812 let bloq = bloq.as_u32().unwrap();
762813 let len = len.as_u32().unwrap();
763− let mut dat: Atom = dat.as_atom()?.clone();
814+ let mut dat: Atom = dat.as_atom().ok_or(Tanks::new())?.clone();
764815
765816 let bits = 2u32.pow(bloq);
766817 let mask = (&ctx.big_uints.one << bits) - &ctx.big_uints.one;
@@ -772,13 +823,13 @@ static REV: Jet = |ctx, n| {
772823 dat = dat >> bits;
773824 }
774825
775− Some(Rc::new(Noun::Atom(target)))
826+ Ok(Rc::new(Noun::Atom(target)))
776827};
777828
778829static RIP: Jet = |ctx, n| {
779− let (bite, b) = n.as_cell()?;
830+ let (bite, b) = n.as_cell().ok_or(Tanks::new())?;
780831 let bite = bite.as_bite();
781− let mut b: Atom = b.as_atom()?.clone();
832+ let mut b: Atom = b.as_atom().ok_or(Tanks::new())?.clone();
782833
783834 let bits = bite.bits();
784835 let mask = (&ctx.big_uints.one << bits) - &ctx.big_uints.one;
@@ -790,15 +841,15 @@ static RIP: Jet = |ctx, n| {
790841 b = b >> bits;
791842 }
792843
793− Some(Noun::list_refs(target.iter()))
844+ Ok(Noun::list_refs(target.iter().cloned()))
794845};
795846
796847static RUN: Jet = |ctx, n| {
797− let (bite, b) = n.as_cell()?;
798− let (b, gate) = b.as_cell()?;
848+ let (bite, b) = n.as_cell().ok_or(Tanks::new())?;
849+ let (b, gate) = b.as_cell().ok_or(Tanks::new())?;
799850
800851 let bite = bite.as_bite();
801− let mut b: Atom = b.as_atom()?.clone();
852+ let mut b: Atom = b.as_atom().ok_or(Tanks::new())?.clone();
802853
803854 let bits = bite.bits();
804855 let mask = (&ctx.big_uints.one << bits) - &ctx.big_uints.one;
@@ -807,20 +858,22 @@ static RUN: Jet = |ctx, n| {
807858
808859 while b > ctx.big_uints.zero {
809860 target = (target << bits)
810− | ((*slam_pulled_gate(ctx, gate, &Rc::new(Noun::Atom(&mask & &b)))?).as_atom()?
861+ | ((*slam_pulled_gate(ctx, gate, &Rc::new(Noun::Atom(&mask & &b)))?)
862+ .as_atom()
863+ .ok_or(Tanks::new())?
811864 & &mask);
812865 b = b >> bits;
813866 }
814867
815− Some(Rc::new(Noun::Atom(target)))
868+ Ok(Rc::new(Noun::Atom(target)))
816869};
817870
818871static RUT: Jet = |ctx, n| {
819− let (bite, b) = n.as_cell()?;
820− let (b, gate) = b.as_cell()?;
872+ let (bite, b) = n.as_cell().ok_or(Tanks::new())?;
873+ let (b, gate) = b.as_cell().ok_or(Tanks::new())?;
821874
822875 let bite = bite.as_bite();
823− let mut b: Atom = b.as_atom()?.clone();
876+ let mut b: Atom = b.as_atom().ok_or(Tanks::new())?.clone();
824877
825878 let bits = bite.bits();
826879 let mask = (&ctx.big_uints.one << bits) - &ctx.big_uints.one;
@@ -829,21 +882,24 @@ static RUT: Jet = |ctx, n| {
829882
830883 while b > ctx.big_uints.zero {
831884 target.push(
832− (*slam_pulled_gate(ctx, gate, &Rc::new(Noun::Atom(&mask & &b)))?).as_atom()? & &mask,
885+ (*slam_pulled_gate(ctx, gate, &Rc::new(Noun::Atom(&mask & &b)))?)
886+ .as_atom()
887+ .ok_or(Tanks::new())?
888+ & &mask,
833889 );
834890 b = b >> bits;
835891 }
836892
837− Some(Noun::list(target.iter().cloned().map(Noun::Atom)))
893+ Ok(Noun::list(target.iter().cloned().map(Noun::Atom)))
838894};
839895
840896static SEW: Jet = |ctx, n| {
841− let (a, b) = n.as_cell()?;
842− let (b, recipient) = b.as_cell()?;
843− let (sew_start, c) = b.as_cell()?;
844− let (number_of_blocks, donor) = c.as_cell()?;
845− let recipient = recipient.as_atom()?;
846− let donor = donor.as_atom()?;
897+ let (a, b) = n.as_cell().ok_or(Tanks::new())?;
898+ let (b, recipient) = b.as_cell().ok_or(Tanks::new())?;
899+ let (sew_start, c) = b.as_cell().ok_or(Tanks::new())?;
900+ let (number_of_blocks, donor) = c.as_cell().ok_or(Tanks::new())?;
901+ let recipient = recipient.as_atom().ok_or(Tanks::new())?;
902+ let donor = donor.as_atom().ok_or(Tanks::new())?;
847903
848904 let bloq = a.as_u32().unwrap();
849905 let bits = 2u32.pow(bloq);
@@ -855,16 +911,16 @@ static SEW: Jet = |ctx, n| {
855911
856912 let target = (recipient ^ apendix) | (donor & mask);
857913
858− Some(Rc::new(Noun::Atom(target)))
914+ Ok(Rc::new(Noun::Atom(target)))
859915};
860916
861917static SWP: Jet = |ctx, n| {
862− let (bloq, b) = n.as_cell()?;
918+ let (bloq, b) = n.as_cell().ok_or(Tanks::new())?;
863919 let bloq = bloq.as_u32().unwrap();
864920 let bits = 2u32.pow(bloq);
865921 let mask = (&ctx.big_uints.one << bits) - &ctx.big_uints.one;
866922
867− let mut source = b.as_atom()?.clone();
923+ let mut source = b.as_atom().ok_or(Tanks::new())?.clone();
868924 let mut target = ctx.big_uints.zero.clone();
869925
870926 while source > ctx.big_uints.zero {
@@ -872,11 +928,11 @@ static SWP: Jet = |ctx, n| {
872928 source = source >> bits;
873929 }
874930
875− Some(Rc::new(Noun::Atom(target)))
931+ Ok(Rc::new(Noun::Atom(target)))
876932};
877933
878934static XEB: Jet = |_ctx, n| {
879− let mut a = n.as_atom()?.clone();
935+ let mut a = n.as_atom().ok_or(Tanks::new())?.clone();
880936
881937 let mut c = 0;
882938
@@ -885,7 +941,7 @@ static XEB: Jet = |_ctx, n| {
885941 c += 1;
886942 }
887943
888− Some(Rc::new(Noun::from_u32(c)))
944+ Ok(Rc::new(Noun::from_u32(c)))
889945};
890946
891947static CON: Jet = |_ctx, n| BINARY_ATOM(n, |a, b| a | b);
@@ -893,23 +949,23 @@ static DIS: Jet = |_ctx, n| BINARY_ATOM(n, |a, b| a & b);
893949static MIX: Jet = |_ctx, n| BINARY_ATOM(n, |a, b| a ^ b);
894950
895951static NOT: Jet = |ctx, n| {
896− let (a, b) = n.as_cell()?;
897− let (b, c) = b.as_cell()?;
952+ let (a, b) = n.as_cell().ok_or(Tanks::new())?;
953+ let (b, c) = b.as_cell().ok_or(Tanks::new())?;
898954
899955 let bloq = a.as_u32().unwrap();
900956 let bits = 2u32.pow(bloq);
901957 let mask = (&ctx.big_uints.one << (bits * b.as_u32().unwrap())) - &ctx.big_uints.one;
902958
903− let target = c.as_atom()? ^ &mask;
959+ let target = c.as_atom().ok_or(Tanks::new())? ^ &mask;
904960
905− Some(Rc::new(Noun::Atom(target)))
961+ Ok(Rc::new(Noun::Atom(target)))
906962};
907963
908964static LAST: Jet = |_ctx, n| {
909− let (a, b) = n.as_cell()?;
910− let a = a.as_hair()?;
911− let b = b.as_hair()?;
912− Some(Noun::from_hair(last(&a, &b)))
965+ let (a, b) = n.as_cell().ok_or(Tanks::new())?;
966+ let a = a.as_hair().ok_or(Tanks::new())?;
967+ let b = b.as_hair().ok_or(Tanks::new())?;
968+ Ok(Noun::from_hair(last(&a, &b)))
913969};
914970
915971fn last<'a>(a: &'a Hair, b: &'a Hair) -> &'a Hair {
@@ -929,20 +985,20 @@ fn last<'a>(a: &'a Hair, b: &'a Hair) -> &'a Hair {
929985}
930986
931987static TRIP: Jet = |_ctx, n| {
932− let a = n.as_atom()?;
933− Some(Noun::list(
988+ let a = n.as_atom().ok_or(Tanks::new())?;
989+ Ok(Noun::list(
934990 a.to_bytes_le().iter().map(|b| Noun::from_u32(*b as u32)),
935991 ))
936992};
937993
938994static MUK: Jet = |_ctx, n| {
939− let (seed, len) = n.as_cell()?;
940− let (len, key) = len.as_cell()?;
941− let seed = seed.as_u32()?;
942− let len = len.as_u32()?;
943− let key = key.as_atom()?;
995+ let (seed, len) = n.as_cell().ok_or(Tanks::new())?;
996+ let (len, key) = len.as_cell().ok_or(Tanks::new())?;
997+ let seed = seed.as_u32().ok_or(Tanks::new())?;
998+ let len = len.as_u32().ok_or(Tanks::new())?;
999+ let key = key.as_atom().ok_or(Tanks::new())?;
9441000
945− Some(Rc::new(Noun::from_u32(muk(seed, len, key))))
1001+ Ok(Rc::new(Noun::from_u32(muk(seed, len, key))))
9461002};
9471003
9481004static JUST: DoubleJet = |ctx, n, m| {
@@ -1006,7 +1062,7 @@ fn fail(nail: Nail) -> Edge {
10061062 }
10071063}
10081064
1009−const MUG: Jet = |__ctx, n| Some(Rc::new(Noun::from_u32(n.mug())));
1065+const MUG: Jet = |__ctx, n| Ok(Rc::new(Noun::from_u32(n.mug())));
10101066
10111067pub fn mum(syd: u32, fal: u32, key: &Atom) -> u32 {
10121068 let wyd = met(3, &key);