@@ -1,28 +1,39 @@
1use core::panic;
1use core::panic;
2+use murmur3::murmur3_32;
2use num_integer::Integer;
3use num_integer::Integer;
4− cmp::Ordering,
5+ borrow::Borrow,
5 collections::BTreeMap,
6 collections::BTreeMap,
6 iter::{once, repeat_n, zip},
7 iter::{once, repeat_n, zip},
10use crate::{
11use crate::{
11− interpreter::{slam, InterpreterContext},
12+ interpreter::{slam_pulled_gate, InterpreterContext, TTanks, EMPTY_TANKS},
12− noun::{self, cell, Atom, Noun},
13+ noun::{self, cell, AsNoun, Atom, Edge, Hair, Nail, Noun},
15−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>>>(
18+) -> Result<Vec<T>, E> {
16 let mut target: Vec<T> = Vec::new();
19 let mut target: Vec<T> = Vec::new();
18 for x in xs {
21 for x in xs {
19 target.push(x.clone()?)
22 target.push(x.clone()?)
22− Some(target)
25+ Ok(target)
25pub type Jets = BTreeMap<noun::Hash, Jet>;
28pub type Jets = BTreeMap<noun::Hash, Jet>;
29+pub type DoubleJets = BTreeMap<noun::Hash, DoubleJet>;
31+pub fn generate_double_jets() -> DoubleJets {
33+ (210326504639957723220404138306543145797, JUST),
34+ // (255213039400865122956425872354360738044, STIR),
27pub fn generate_jets() -> Jets {
38pub fn generate_jets() -> Jets {
28 BTreeMap::from([
39 BTreeMap::from([
@@ -93,41 +104,67 @@ pub fn generate_jets() -> Jets {
93 (311027486926441687148059942599447850754, DIS),
104 (311027486926441687148059942599447850754, DIS),
94 (330927609077697663248483044495963838437, MIX),
105 (330927609077697663248483044495963838437, MIX),
95 (39579736615539990724554083585557839000, NOT),
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),
119+pub type Jet = fn(ctx: &mut InterpreterContext, &Rc<Noun>) -> Result<Rc<Noun>, TTanks>;
99−pub type Jet = fn(ctx: &InterpreterContext, Rc<Noun>) -> Option<Rc<Noun>>;
120+pub type DoubleJet = fn(ctx: &mut InterpreterContext, &Rc<Noun>, &Rc<Noun>) -> Option<Rc<Noun>>;
101−static BINARY_ATOM: fn(Rc<Noun>, fn(&Atom, &Atom) -> Atom) -> Option<Rc<Noun>> =
122+static BINARY_ATOM: fn(&Rc<Noun>, fn(&Atom, &Atom) -> Atom) -> Result<Rc<Noun>, TTanks> =
102− |n: Rc<Noun>, f: fn(&Atom, &Atom) -> Atom| {
123+ |n: &Rc<Noun>, f: fn(&Atom, &Atom) -> Atom| {
103− let (p, q) = n.as_cell()?;
124+ let (p, q) = n.as_cell().ok_or(TTanks::new())?;
104− Some(Rc::new(Noun::Atom(f(p.as_atom()?, q.as_atom()?))))
125+ Ok(Rc::new(Noun::Atom(f(
126+ p.as_atom().ok_or(TTanks::new())?,
127+ q.as_atom().ok_or(TTanks::new())?,
107static BINARY_ATOM_LOOB: fn(
131static BINARY_ATOM_LOOB: fn(
108 &InterpreterContext,
132 &InterpreterContext,
109− Rc<Noun>,
133+ &Rc<Noun>,
110 fn(&Atom, &Atom) -> bool,
134 fn(&Atom, &Atom) -> bool,
135+) -> Result<Rc<Noun>, TTanks> =
111−) -> Option<Rc<Noun>> = |ctx: &InterpreterContext, n: Rc<Noun>, f: fn(&Atom, &Atom) -> bool| {
136+ |ctx: &InterpreterContext, n: &Rc<Noun>, f: fn(&Atom, &Atom) -> bool| {
112− let (p, q) = n.as_cell().unwrap();
137+ let (p, q) = n.as_cell().ok_or(TTanks::new())?;
140+ p.as_atom().ok_or(TTanks::new())?,
141+ q.as_atom().ok_or(TTanks::new())?,
143+ Ok(ctx.nouns.sig.clone())
145+ Ok(ctx.nouns.one.clone())
114− if f(p.as_atom()?, q.as_atom()?) {
149+static BINARY_ATOM_PAIR: fn(
115− Some(ctx.nouns.sig.clone())
150+ &Rc<Noun>,
116− } else {
151+ fn(&Atom, &Atom) -> (Atom, Atom),
117− Some(ctx.nouns.one.clone())
152+) -> Result<Rc<Noun>, TTanks> = |n: &Rc<Noun>, f: fn(&Atom, &Atom) -> (Atom, Atom)| {
118− }
153+ let (p, q) = n.as_cell().ok_or(TTanks::new())?;
156+ p.as_atom().ok_or(TTanks::new())?,
157+ q.as_atom().ok_or(TTanks::new())?,
159+ Ok(cell(&Rc::new(Noun::Atom(a)), &Rc::new(Noun::Atom(b))))
121−static BINARY_ATOM_PAIR: fn(Rc<Noun>, fn(&Atom, &Atom) -> (Atom, Atom)) -> Option<Rc<Noun>> =
122− |n: Rc<Noun>, f: fn(&Atom, &Atom) -> (Atom, Atom)| {
123− let (p, q) = n.as_cell().unwrap();
125− let (a, b) = f(p.as_atom().unwrap(), q.as_atom().unwrap());
126− Some(cell(Rc::new(Noun::Atom(a)), Rc::new(Noun::Atom(b))))
129static ADD: Jet = |_ctx, n| BINARY_ATOM(n, |a, b| a + b);
162static ADD: Jet = |_ctx, n| BINARY_ATOM(n, |a, b| a + b);
130−static DEC: Jet = |_ctx, n| Some(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,
131static DVR: Jet = |_ctx, n| BINARY_ATOM_PAIR(n, |a, b| a.div_rem(&b));
168static DVR: Jet = |_ctx, n| BINARY_ATOM_PAIR(n, |a, b| a.div_rem(&b));
132static DIV: Jet = |_ctx, n| BINARY_ATOM(n, |a, b| a / b);
169static DIV: Jet = |_ctx, n| BINARY_ATOM(n, |a, b| a / b);
133static GTE: Jet = |ctx, n| BINARY_ATOM_LOOB(ctx, n, |a, b| a >= b);
170static GTE: Jet = |ctx, n| BINARY_ATOM_LOOB(ctx, n, |a, b| a >= b);
@@ -141,40 +178,42 @@ static MUL: Jet = |_ctx, n| BINARY_ATOM(n, |a, b| a * b);
141static SUB: Jet = |_ctx, n| BINARY_ATOM(n, |a, b| a - b);
178static SUB: Jet = |_ctx, n| BINARY_ATOM(n, |a, b| a - b);
143static CAP: Jet = |ctx, n| {
180static CAP: Jet = |ctx, n| {
144− let Noun::Atom(n) = (*n).clone() else {
181+ let n = n.as_atom().ok_or(TTanks::new())?;
147− CAP_ATOM(ctx, n)
182+ CAP_ATOM(ctx, n.clone())
149−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| {
150 let mut n_iter = n.iter_u32_digits();
186 let mut n_iter = n.iter_u32_digits();
152 match n_iter.len() {
188 match n_iter.len() {
153− 0 => panic!(),
189+ 0 => Err(TTanks::new()),
154 1 => CAP_U32(ctx, n_iter.next().unwrap()),
190 1 => CAP_U32(ctx, n_iter.next().unwrap()),
155 _ => CAP_ATOM(ctx, n >> 1),
191 _ => CAP_ATOM(ctx, n >> 1),
158−static CAP_U32: fn(ctx: &InterpreterContext, u32) -> Option<Rc<Noun>> = |ctx, n| match n {
194+static CAP_U32: fn(ctx: &InterpreterContext, u32) -> Result<Rc<Noun>, TTanks> = |ctx, n| match n {
159− 0 | 1 => panic!(),
195+ 0 | 1 => Err(TTanks::new()),
160− 2 => Some(ctx.nouns.two.clone()),
196+ 2 => Ok(ctx.nouns.two.clone()),
161− 3 => Some(ctx.nouns.three.clone()),
197+ 3 => Ok(ctx.nouns.three.clone()),
162 n => CAP_U32(ctx, n >> 1),
198 n => CAP_U32(ctx, n >> 1),
165static MAS: Jet = |ctx, n| {
201static MAS: Jet = |ctx, n| {
166− let Noun::Atom(n) = (*n).clone() else {
202+ let n = n.as_atom().ok_or(TTanks::new())?;
169− Some(Rc::new(Noun::Atom(MAS_ATOM(ctx, n))))
203+ Ok(Rc::new(Noun::Atom(
204+ MAS_ATOM(ctx, n.clone()).ok_or(TTanks::new())?,
171−static MAS_ATOM: fn(&InterpreterContext, Atom) -> Atom = |ctx, n| {
207+static MAS_ATOM: fn(&InterpreterContext, Atom) -> Option<Atom> = |ctx, n| {
172 let mut n_iter = n.iter_u32_digits();
208 let mut n_iter = n.iter_u32_digits();
174 match n_iter.len() {
210 match n_iter.len() {
175− 0 => panic!(),
211+ 0 => None,
212+ 1 => match n_iter.next().unwrap() {
176− 1 => Atom::new(vec![MAS_U32(n_iter.next().unwrap())]),
214+ x => Some(Atom::new(vec![MAS_U32(x)])),
177− _ => (&n & &ctx.big_uints.one) + (MAS_ATOM(ctx, &n >> 1) << 1),
216+ _ => Some((&n & &ctx.big_uints.one) + (MAS_ATOM(ctx, &n >> 1)? << 1)),
180static MAS_U32: fn(u32) -> u32 = |n| match n {
219static MAS_U32: fn(u32) -> u32 = |n| match n {
@@ -184,26 +223,24 @@ static MAS_U32: fn(u32) -> u32 = |n| match n {
186static PEG: Jet = |ctx, n| {
225static PEG: Jet = |ctx, n| {
187− let Noun::Cell { p: a, q: b, .. } = (*n).clone() else {
226+ let (a, b) = n.as_cell().ok_or(TTanks::new())?;
191− let a = a.as_atom().unwrap();
228+ let a = a.as_atom().ok_or(TTanks::new())?;
192− let b = b.as_atom().unwrap();
229+ let b = b.as_atom().ok_or(TTanks::new())?;
194 if *a == Atom::ZERO {
231 if *a == Atom::ZERO {
195− panic!()
232+ return Err(TTanks::new());
198− Some(Rc::new(Noun::Atom(PEG_ATOM(ctx, a, b.clone()))))
235+ Ok(Rc::new(Noun::Atom(PEG_ATOM(ctx, a, b.clone())?)))
200−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| {
201 let mut b_iter = b.iter_u32_digits();
238 let mut b_iter = b.iter_u32_digits();
203 match b_iter.len() {
240 match b_iter.len() {
204− 0 => panic!(),
241+ 0 => Err(TTanks::new()),
205− 1 => PEG_U32(a, b_iter.next().unwrap()),
242+ 1 => Ok(PEG_U32(a, b_iter.next().unwrap())),
206− _ => (&b & &ctx.big_uints.one) + (PEG_ATOM(ctx, a, b >> 1) << 1),
243+ _ => Ok((&b & &ctx.big_uints.one) + (PEG_ATOM(ctx, a, b >> 1)? << 1)),
209static PEG_U32: fn(&Atom, u32) -> Atom = |a, b| match b {
246static PEG_U32: fn(&Atom, u32) -> Atom = |a, b| match b {
@@ -215,12 +252,12 @@ static PEG_U32: fn(&Atom, u32) -> Atom = |a, b| match b {
217static FAND: Jet = |ctx, n| {
254static FAND: Jet = |ctx, n| {
218− let (nedl, hstk) = n.as_cell().unwrap();
255+ let (nedl, hstk) = n.as_cell().ok_or(TTanks::new())?;
219 if nedl.is_sig() || hstk.is_sig() {
256 if nedl.is_sig() || hstk.is_sig() {
220− return Some(ctx.nouns.sig.clone());
257+ return Ok(ctx.nouns.sig.clone());
223− let nedl: Vec<Rc<Noun>> = nedl.list_iter().collect();
260+ let nedl: Vec<&Rc<Noun>> = nedl.list_iter().collect();
225 let mut result: Vec<u32> = Vec::new();
262 let mut result: Vec<u32> = Vec::new();
@@ -241,16 +278,16 @@ static FAND: Jet = |ctx, n| {
241 inner_iter = iter.clone();
278 inner_iter = iter.clone();
244− Some(Noun::list(result.iter().map(|a| Noun::from_u32(*a))))
281+ Ok(Noun::list(result.iter().map(|a| Noun::from_u32(*a))))
247static FIND: Jet = |ctx, n| {
284static FIND: Jet = |ctx, n| {
248− let (nedl, hstk) = n.as_cell().unwrap();
285+ let (nedl, hstk) = n.as_cell().ok_or(TTanks::new())?;
249 if nedl.is_sig() || hstk.is_sig() {
286 if nedl.is_sig() || hstk.is_sig() {
250− return Some(ctx.nouns.sig.clone());
287+ return Ok(ctx.nouns.sig.clone());
253− let nedl: Vec<Rc<Noun>> = nedl.list_iter().collect();
290+ let nedl: Vec<&Rc<Noun>> = nedl.list_iter().collect();
255 let mut iter = zip(0.., hstk.list_iter());
292 let mut iter = zip(0.., hstk.list_iter());
@@ -263,30 +300,28 @@ static FIND: Jet = |ctx, n| {
263 .collect::<Vec<_>>()
300 .collect::<Vec<_>>()
266− return Some(Rc::new(Noun::from_u32(i)).unit());
303+ return Ok(Rc::new(Noun::from_u32(i)).unit());
269 inner_iter = iter.clone();
306 inner_iter = iter.clone();
272− return Some(ctx.nouns.sig.clone());
309+ return Ok(ctx.nouns.sig.clone());
275static FLOP: Jet = |ctx, n| {
312static FLOP: Jet = |ctx, n| {
277− n.list_iter()
313+ Ok(n.list_iter()
278− .fold(ctx.nouns.sig.clone(), |tail, head| cell(head, tail)),
314+ .fold(ctx.nouns.sig.clone(), |tail, head| cell(&head, &tail)))
282static GULF: Jet = |_ctx, n| {
317static GULF: Jet = |_ctx, n| {
283− let (from, to) = n.as_cell().unwrap();
318+ let (from, to) = n.as_cell().ok_or(TTanks::new())?;
285− let mut from = (*from.as_atom().unwrap()).clone();
320+ let mut from = (*from.as_atom().ok_or(TTanks::new())?).clone();
286− let to = to.as_atom().unwrap().clone();
321+ let to = to.as_atom().ok_or(TTanks::new())?.clone();
288 if from > to {
323 if from > to {
289− panic!()
324+ return Err(TTanks::new());
292 let mut tmp = Vec::new();
327 let mut tmp = Vec::new();
@@ -296,220 +331,251 @@ static GULF: Jet = |_ctx, n| {
296 from += 1u32;
331 from += 1u32;
299− 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()))))
302static INTO: Jet = |_ctx, n| {
337static INTO: Jet = |_ctx, n| {
303− let (a, b) = n.as_cell().unwrap();
338+ let (a, b) = n.as_cell().ok_or(TTanks::new())?;
304− let (b, c) = b.as_cell().unwrap();
339+ let (b, c) = b.as_cell().ok_or(TTanks::new())?;
306− 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();
308 match b_iter.len() {
343 match b_iter.len() {
309− 0 => Some(cell(c, a)),
344+ 0 => Ok(cell(&c, &a)),
311 let l = a.list_iter();
346 let l = a.list_iter();
312 let b = b_iter.next().unwrap() as usize;
347 let b = b_iter.next().unwrap() as usize;
313− Some(Noun::list_refs(
348+ Ok(Noun::list_refs(
314 l.clone()
349 l.clone()
316 .chain(once(c))
351 .chain(once(c))
317 .chain(l.skip(b))
352 .chain(l.skip(b))
318 .collect::<Vec<_>>()
353 .collect::<Vec<_>>()
320− .map(|x| x.clone()),
355+ .cloned()
323− _ => Some(Noun::list_refs(
359+ _ => Ok(Noun::list_refs(
324 a.list_iter()
360 a.list_iter()
325 .chain(once(c))
361 .chain(once(c))
326 .collect::<Vec<_>>()
362 .collect::<Vec<_>>()
328− .map(|x| x.clone()),
364+ .cloned()
333static JOIN: Jet = |_ctx, n| {
370static JOIN: Jet = |_ctx, n| {
334− let (sep, list) = n.as_cell().unwrap();
371+ let (sep, list) = n.as_cell().ok_or(TTanks::new())?;
335− Some(Noun::list_refs(
372+ Ok(Noun::list_refs(
336 list.list_iter()
373 list.list_iter()
337 .intersperse(sep)
374 .intersperse(sep)
338 .collect::<Vec<_>>()
375 .collect::<Vec<_>>()
340− .map(|x| x.clone()),
377+ .cloned()
344static LENT: Jet = |_ctx, n| {
382static LENT: Jet = |_ctx, n| {
345− Some(Rc::new(Noun::from_u32(
383+ Ok(Rc::new(Noun::from_u32(
346 n.list_iter().fold(0u32, |l, _| l + 1),
384 n.list_iter().fold(0u32, |l, _| l + 1),
350static LEVY: Jet = |ctx, n| {
388static LEVY: Jet = |ctx, n| {
351− let (a, b) = n.as_cell().unwrap();
389+ let (a, b) = n.as_cell().ok_or(TTanks::new())?;
352− if traverse_iter_option(a.list_iter().map(|n| slam(ctx, b.clone(), n)))?
390+ if traverse_iter_result(a.list_iter().map(|n| slam_pulled_gate(ctx, b, n)))?
354 .all(|x| x.is_y())
392 .all(|x| x.is_y())
356− Some(ctx.nouns.y.clone())
394+ Ok(ctx.nouns.y.clone())
358− Some(ctx.nouns.n.clone())
396+ Ok(ctx.nouns.n.clone())
362static LIEN: Jet = |ctx, n| {
400static LIEN: Jet = |ctx, n| {
363− let (a, b) = n.as_cell().unwrap();
401+ let (a, b) = n.as_cell().ok_or(TTanks::new())?;
364− if traverse_iter_option(a.list_iter().map(|n| slam(ctx, b.clone(), n)))?
402+ if traverse_iter_result(a.list_iter().map(|n| slam_pulled_gate(ctx, b, n)))?
366 .any(|x| x.is_y())
404 .any(|x| x.is_y())
368− Some(ctx.nouns.y.clone())
406+ Ok(ctx.nouns.y.clone())
370− Some(ctx.nouns.n.clone())
408+ Ok(ctx.nouns.n.clone())
374static MURN: Jet = |ctx, n| {
412static MURN: Jet = |ctx, n| {
375− let (a, b) = n.as_cell().unwrap();
413+ let (a, b) = n.as_cell().ok_or(TTanks::new())?;
377− Some(Noun::list_refs(
415+ Ok(Noun::list_refs(
416+ traverse_iter_result(
378− a.list_iter()
417+ a.list_iter()
379− .filter_map(|n| slam(ctx, b.clone(), n)?.as_unit())
418+ .map(|n| Ok(slam_pulled_gate(ctx, b, n)?.as_unit().cloned())),
380− .collect::<Vec<_>>()
419+ )?
382− .map(|x| x.clone()),
421+ .filter_map(|x| x.clone()),
386static REAP: Jet = |_ctx, n| {
425static REAP: Jet = |_ctx, n| {
387− let (a, b) = n.as_cell().unwrap();
426+ let (a, b) = n.as_cell().ok_or(TTanks::new())?;
389− Some(Noun::list_refs(repeat_n(b, a.as_u32().unwrap() as usize)))
428+ Ok(Noun::list_refs(repeat_n(
430+ a.as_u32().unwrap() as usize,
392−static REAR: Jet = |_ctx, n| n.list_iter().last();
434+static REAR: Jet = |_ctx, n| n.list_iter().last().ok_or(TTanks::new()).cloned();
394static REEL: Jet = |ctx, n| {
436static REEL: Jet = |ctx, n| {
395− let (list, gate) = n.as_cell().unwrap();
437+ let (list, gate) = n.as_cell().ok_or(TTanks::new())?;
397 list.list_iter().collect::<Vec<_>>().iter().rfold(
439 list.list_iter().collect::<Vec<_>>().iter().rfold(
398− Some(gate.clone().gate_sample()?.as_cell()?.1),
441+ .gate_sample()
442+ .ok_or(TTanks::new())?
444+ .ok_or(TTanks::new())?
399− |acc, next| slam(ctx, gate.clone(), cell(next.clone(), acc?)),
449+ slam_pulled_gate(ctx, gate, &cell(&next, &acc))
403static ROLL: Jet = |ctx, n| {
454static ROLL: Jet = |ctx, n| {
404− let (list, gate) = n.as_cell().unwrap();
455+ let (list, gate) = n.as_cell().ok_or(TTanks::new())?;
406 list.list_iter().fold(
457 list.list_iter().fold(
407− Some(gate.clone().gate_sample()?.as_cell()?.1),
460+ .gate_sample()
461+ .ok_or(TTanks::new())?
463+ .ok_or(TTanks::new())?
408− |acc, next| slam(ctx, gate.clone(), cell(next.clone(), acc?)),
468+ slam_pulled_gate(ctx, gate, &cell(&next, &acc))
412static SCAG: Jet = |_ctx, n| {
473static SCAG: Jet = |_ctx, n| {
413− let (a, b) = n.as_cell().unwrap();
474+ let (a, b) = n.as_cell().ok_or(TTanks::new())?;
415− Some(Noun::list_refs(
476+ Ok(Noun::list_refs(
416 b.list_iter()
477 b.list_iter()
417 .take(a.as_u32().unwrap() as usize)
478 .take(a.as_u32().unwrap() as usize)
418 .collect::<Vec<_>>()
479 .collect::<Vec<_>>()
420− .map(|x| x.clone()),
481+ .cloned()
424static SKID: Jet = |ctx, n| {
486static SKID: Jet = |ctx, n| {
425− let (list, gate) = n.as_cell().unwrap();
487+ let (list, gate) = n.as_cell().ok_or(TTanks::new())?;
427− let slammed_n = traverse_iter_option(
489+ let slammed_n = traverse_iter_result(
428 list.list_iter()
490 list.list_iter()
429− .map(|n| Some((slam(ctx, gate.clone(), n.clone())?, n))),
491+ .map(|n| Ok((slam_pulled_gate(ctx, gate, n)?, n))),
431 let (ys, ns): (Vec<_>, _) = slammed_n.iter().partition(|(l, _)| l.is_y());
493 let (ys, ns): (Vec<_>, _) = slammed_n.iter().partition(|(l, _)| l.is_y());
433− Some(cell(
495+ Ok(cell(
434− Noun::list_refs(ys.iter().map(|(_, x)| x).cloned()),
496+ &Noun::list_refs(ys.iter().map(|(_, x)| (*x).clone())),
435− Noun::list_refs(ns.iter().map(|(_, x)| x).cloned()),
497+ &Noun::list_refs(ns.iter().map(|(_, x)| (*x).clone())),
439static SKIM: Jet = |ctx, n| {
501static SKIM: Jet = |ctx, n| {
440− let (list, gate) = n.as_cell().unwrap();
502+ let (list, gate) = n.as_cell().ok_or(TTanks::new())?;
442− Some(Noun::list_refs(
504+ Ok(Noun::list_refs(
443− traverse_iter_option(
505+ traverse_iter_result(
444 list.list_iter()
506 list.list_iter()
445− .map(|n| Some((slam(ctx, gate.clone(), n.clone())?, n))),
507+ .map(|n| Ok((slam_pulled_gate(ctx, gate, n)?, n))),
448 .filter(|(l, _)| l.is_y())
510 .filter(|(l, _)| l.is_y())
449− .map(|(_, x)| x)
511+ .map(|(_, x)| (*x).clone()),
454static SKIP: Jet = |ctx, n| {
515static SKIP: Jet = |ctx, n| {
455− let (list, gate) = n.as_cell().unwrap();
516+ let (list, gate) = n.as_cell().ok_or(TTanks::new())?;
457− Some(Noun::list_refs(
518+ Ok(Noun::list_refs(
458− traverse_iter_option(
519+ traverse_iter_result(
459 list.list_iter()
520 list.list_iter()
460− .map(|n| Some((slam(ctx, gate.clone(), n.clone())?, n))),
521+ .map(|n| Ok((slam_pulled_gate(ctx, gate, n)?, n))),
463 .filter(|(l, _)| l.is_y())
524 .filter(|(l, _)| l.is_y())
464− .map(|(_, x)| x)
525+ .map(|(_, x)| (*x).clone()),
469static SLAG: Jet = |ctx, n| {
529static SLAG: Jet = |ctx, n| {
470− let (a, list) = n.as_cell().unwrap();
530+ let (a, list) = n.as_cell().ok_or(TTanks::new())?;
472− 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();
474 match a_iter.len() {
534 match a_iter.len() {
475− 0 => Some(list),
535+ 0 => Ok(list.clone()),
476− 1 => Some(Noun::list_refs(
536+ 1 => Ok(Noun::list_refs(
477 list.list_iter()
537 list.list_iter()
478 .skip(a_iter.next().unwrap() as usize)
538 .skip(a_iter.next().unwrap() as usize)
479 .collect::<Vec<_>>()
539 .collect::<Vec<_>>()
481 .cloned(),
542 .cloned(),
483− _ => Some(ctx.nouns.sig.clone()),
544+ _ => Ok(ctx.nouns.sig.clone()),
487static SNAG: Jet = |_ctx, n| {
548static SNAG: Jet = |_ctx, n| {
488− let (a, list) = n.as_cell().unwrap();
549+ let (a, list) = n.as_cell().ok_or(TTanks::new())?;
490− list.list_iter().nth(a.as_u32().unwrap() as usize)
552+ .nth(a.as_u32().unwrap() as usize)
554+ .ok_or(TTanks::new())
493static SNIP: Jet = |_ctx, n| {
557static SNIP: Jet = |_ctx, n| {
494− Some(Noun::list_refs(
558+ Ok(Noun::list_refs(
495 n.list_iter()
559 n.list_iter()
496 .collect::<Vec<_>>()
560 .collect::<Vec<_>>()
501 .cloned(),
566 .cloned(),
505static SNOC: Jet = |_ctx, n| {
570static SNOC: Jet = |_ctx, n| {
506− let (list, b) = n.as_cell().unwrap();
571+ let (list, b) = n.as_cell().ok_or(TTanks::new())?;
508− Some(Noun::list_refs(
573+ Ok(Noun::list_refs(
509 list.list_iter()
574 list.list_iter()
510 .chain(once(b))
575 .chain(once(b))
511 .collect::<Vec<_>>()
576 .collect::<Vec<_>>()
513 .cloned(),
579 .cloned(),
@@ -533,52 +599,62 @@ static SNOC: Jet = |_ctx, n| {
535static SPIN: Jet = |ctx, n| {
601static SPIN: Jet = |ctx, n| {
536− let (list, b) = n.as_cell().unwrap();
602+ let (list, b) = n.as_cell().ok_or(TTanks::new())?;
537− let (mut acc, gate) = b.as_cell().unwrap();
603+ let (acc, gate) = b.as_cell().ok_or(TTanks::new())?;
539 let mut res = Vec::new();
605 let mut res = Vec::new();
606+ let mut acc = acc.clone();
541 for n in list.list_iter() {
608 for n in list.list_iter() {
542− let (el, new_acc) = slam(ctx, gate.clone(), cell(n, acc))?.as_cell().unwrap();
609+ let foo = slam_pulled_gate(ctx, gate, &cell(&n, &acc))?;
610+ let (el, new_acc) = foo.as_cell().ok_or(TTanks::new())?;
543− acc = new_acc;
611+ acc = new_acc.clone();
544− res.push(el);
612+ res.push(el.clone());
547− Some(cell(Noun::list_refs(res.iter().cloned()), acc))
615+ Ok(cell(&Noun::list_refs(res.iter().cloned()), &acc))
550static SPUN: Jet = |ctx, n| {
618static SPUN: Jet = |ctx, n| {
551− let (list, gate) = n.as_cell().unwrap();
619+ let (list, gate) = n.as_cell().ok_or(TTanks::new())?;
553 let mut res = Vec::new();
621 let mut res = Vec::new();
554− let mut acc = gate.clone().gate_sample().unwrap().as_cell().unwrap().1;
622+ let mut acc = gate
624+ .ok_or(TTanks::new())?
626+ .ok_or(TTanks::new())?
556 for n in list.list_iter() {
630 for n in list.list_iter() {
557− let (el, new_acc) = slam(ctx, gate.clone(), cell(n, acc))?.as_cell().unwrap();
631+ let foo = slam_pulled_gate(ctx, gate, &cell(&n, &acc))?;
632+ let (el, new_acc) = foo.as_cell().ok_or(TTanks::new())?;
558− acc = new_acc;
633+ acc = new_acc.clone();
559− res.push(el);
634+ res.push(el.clone());
562− Some(cell(Noun::list_refs(res.iter().cloned()), acc))
637+ Ok(cell(&Noun::list_refs(res.iter().cloned()), &acc))
565static TURN: Jet = |ctx, n| {
640static TURN: Jet = |ctx, n| {
566− let (list, gate) = n.as_cell().unwrap();
641+ let (list, gate) = n.as_cell().ok_or(TTanks::new())?;
567− Some(Noun::list_refs(
642+ Ok(Noun::list_refs(
568− traverse_iter_option(list.list_iter().map(|x| slam(ctx, gate.clone(), x)))?
643+ traverse_iter_result(list.list_iter().map(|x| slam_pulled_gate(ctx, gate, x)))?
570 .cloned(),
645 .cloned(),
574static WELD: Jet = |_ctx, n| {
649static WELD: Jet = |_ctx, n| {
575− let (a, b) = n.as_cell().unwrap();
650+ let (a, b) = n.as_cell().ok_or(TTanks::new())?;
577− Some(Noun::list_refs(
652+ Ok(Noun::list_refs(
578 a.list_iter()
653 a.list_iter()
579 .chain(b.list_iter())
654 .chain(b.list_iter())
580 .collect::<Vec<_>>()
655 .collect::<Vec<_>>()
582 .cloned(),
658 .cloned(),
@@ -586,110 +662,103 @@ static WELD: Jet = |_ctx, n| {
586static WELP: Jet = WELD;
662static WELP: Jet = WELD;
588static ZING: Jet = |_ctx, n| {
664static ZING: Jet = |_ctx, n| {
589− Some(Noun::list_refs(
665+ Ok(Noun::list_refs(
590 n.list_iter()
666 n.list_iter()
591 .map(|l| l.list_iter())
667 .map(|l| l.list_iter())
592 .flatten()
668 .flatten()
593 .collect::<Vec<_>>()
669 .collect::<Vec<_>>()
595 .cloned(),
672 .cloned(),
599static BEX: Jet = |ctx, n| {
676static BEX: Jet = |ctx, n| {
600− Some(Rc::new(Noun::Atom(
677+ Ok(Rc::new(Noun::Atom(
601 &ctx.big_uints.one << n.as_u32().unwrap(),
678 &ctx.big_uints.one << n.as_u32().unwrap(),
605static END: Jet = |ctx, n| {
682static END: Jet = |ctx, n| {
606− let (a, b) = n.as_cell().unwrap();
683+ let (a, b) = n.as_cell().ok_or(TTanks::new())?;
607− let bite = a.as_bite().unwrap();
684+ let bite = a.as_bite();
609 let bits = bite.bits();
686 let bits = bite.bits();
611 let mask = (&ctx.big_uints.one << bits) - &ctx.big_uints.one;
688 let mask = (&ctx.big_uints.one << bits) - &ctx.big_uints.one;
613− Some(Rc::new(Noun::Atom(mask & b.as_atom().unwrap())))
690+ Ok(Rc::new(Noun::Atom(
691+ mask & b.as_atom().ok_or(TTanks::new())?,
616static CAN: Jet = |ctx, n| {
695static CAN: Jet = |ctx, n| {
617− let (a, b) = n.as_cell().unwrap();
696+ let (a, b) = n.as_cell().ok_or(TTanks::new())?;
618 let bloq = a.as_u32().unwrap();
697 let bloq = a.as_u32().unwrap();
619 let bloq_ = 2u32.pow(bloq);
698 let bloq_ = 2u32.pow(bloq);
621− let atom: Atom =
700+ let atom: Option<Atom> = b.list_iter().collect::<Vec<_>>().iter().rfold(
623− .collect::<Vec<_>>()
625− .rfold(ctx.big_uints.zero.clone(), |acc, next| {
701+ Some(ctx.big_uints.zero.clone()),
626− let (p, q) = next.as_cell().unwrap();
703+ let (p, q) = next.as_cell()?;
627− let step = p.as_u32().unwrap();
704+ let step = p.as_u32().unwrap();
628− let bits = bloq_ * step;
705+ let bits = bloq_ * step;
629− let mask = (&ctx.big_uints.one << bits) - &ctx.big_uints.one;
706+ let mask = (&ctx.big_uints.one << bits) - &ctx.big_uints.one;
631− (acc << bits) | (mask & q.as_atom().unwrap())
708+ Some((acc? << bits) | (mask & q.as_atom()?))
633− Some(Rc::new(Noun::Atom(atom)))
711+ Ok(Rc::new(Noun::Atom(atom.ok_or(TTanks::new())?)))
636static CAT: Jet = |_ctx, n| {
714static CAT: Jet = |_ctx, n| {
637− let (bloq, b) = n.as_cell().unwrap();
715+ let (bloq, b) = n.as_cell().ok_or(TTanks::new())?;
638− let (b, c) = b.as_cell().unwrap();
716+ let (b, c) = b.as_cell().ok_or(TTanks::new())?;
640− let bloq = bloq.as_u32().unwrap();
718+ let bloq = bloq.as_u32().ok_or(TTanks::new())?;
641− let b = b.as_atom().unwrap();
719+ let b = b.as_atom().ok_or(TTanks::new())?;
642− let c = c.as_atom().unwrap();
720+ let c = c.as_atom().ok_or(TTanks::new())?;
644− Some(Rc::new(Noun::Atom(
722+ Ok(Rc::new(Noun::Atom(
645− (c << (met(bloq, b.clone()) * 2u32.pow(bloq))) | b,
723+ (c << (met(bloq, &b) * 2u32.pow(bloq))) | b,
649static MET: Jet = |_ctx, n| {
727static MET: Jet = |_ctx, n| {
650− let (bloq, b) = n.as_cell().unwrap();
728+ let (bloq, b) = n.as_cell().ok_or(TTanks::new())?;
651− let b: Atom = b.as_atom().unwrap().clone();
729+ let b: Atom = b.as_atom().ok_or(TTanks::new())?.clone();
652 let bloq = bloq.as_u32().unwrap();
730 let bloq = bloq.as_u32().unwrap();
654− Some(Rc::new(Noun::from_u32(met(bloq, b))))
732+ Ok(Rc::new(Noun::from_u32(met(bloq, &b))))
657−fn met(bloq: u32, mut a: Atom) -> u32 {
735+fn met(bloq: u32, a: &Atom) -> u32 {
658− let bits = 2u32.pow(bloq);
736+ (a.bits() as u32).div_ceil(2u32.pow(bloq))
662− while a > Atom::ZERO {
670static CUT: Jet = |ctx, n| {
739static CUT: Jet = |ctx, n| {
671− let (a, b) = n.as_cell().unwrap();
740+ let (a, b) = n.as_cell().ok_or(TTanks::new())?;
672− let (b, d) = b.as_cell().unwrap();
741+ let (b, d) = b.as_cell().ok_or(TTanks::new())?;
673− let (b, c) = b.as_cell().unwrap();
742+ let (b, c) = b.as_cell().ok_or(TTanks::new())?;
675 let bits = 2u32.pow(a.as_u32().unwrap());
744 let bits = 2u32.pow(a.as_u32().unwrap());
677 let mask = (&ctx.big_uints.one << (bits * c.as_u32().unwrap())) - &ctx.big_uints.one;
746 let mask = (&ctx.big_uints.one << (bits * c.as_u32().unwrap())) - &ctx.big_uints.one;
679− Some(Rc::new(Noun::Atom(
748+ Ok(Rc::new(Noun::Atom(
680− (d.as_atom().unwrap() >> (bits * b.as_u32().unwrap())) & mask,
749+ (d.as_atom().ok_or(TTanks::new())? >> (bits * b.as_u32().unwrap())) & mask,
684static FIL: Jet = |ctx, n| {
753static FIL: Jet = |ctx, n| {
685− let (a, b) = n.as_cell().unwrap();
754+ let (a, b) = n.as_cell().ok_or(TTanks::new())?;
686− let (b, c) = b.as_cell().unwrap();
755+ let (b, c) = b.as_cell().ok_or(TTanks::new())?;
688 let bits = 2u32.pow(a.as_u32().unwrap());
757 let bits = 2u32.pow(a.as_u32().unwrap());
690 let mask = (&ctx.big_uints.one << bits) - &ctx.big_uints.one;
759 let mask = (&ctx.big_uints.one << bits) - &ctx.big_uints.one;
692− let src = c.as_atom().unwrap() & mask;
761+ let src = c.as_atom().ok_or(TTanks::new())? & mask;
694 let mut target = ctx.big_uints.zero.clone();
763 let mut target = ctx.big_uints.zero.clone();
@@ -697,45 +766,45 @@ static FIL: Jet = |ctx, n| {
697 target = (target << bits) | &src;
766 target = (target << bits) | &src;
700− Some(Rc::new(Noun::Atom(target)))
769+ Ok(Rc::new(Noun::Atom(target)))
703static LSH: Jet = |_ctx, n| {
772static LSH: Jet = |_ctx, n| {
704− let (a, b) = n.as_cell().unwrap();
773+ let (a, b) = n.as_cell().ok_or(TTanks::new())?;
705− let a = a.as_bite().unwrap();
774+ let a = a.as_bite();
706− let b = b.as_atom().unwrap();
775+ let b = b.as_atom().ok_or(TTanks::new())?;
708− Some(Rc::new(Noun::Atom(b << a.bits())))
777+ Ok(Rc::new(Noun::Atom(b << a.bits())))
711static RSH: Jet = |_ctx, n| {
780static RSH: Jet = |_ctx, n| {
712− let (a, b) = n.as_cell().unwrap();
781+ let (a, b) = n.as_cell().ok_or(TTanks::new())?;
713− let a = a.as_bite().unwrap();
782+ let a = a.as_bite();
714− let b = b.as_atom().unwrap();
783+ let b = b.as_atom().ok_or(TTanks::new())?;
716− Some(Rc::new(Noun::Atom(b >> a.bits())))
785+ Ok(Rc::new(Noun::Atom(b >> a.bits())))
719−static RAP: Jet = |ctx, n| {
788+pub static RAP: Jet = |ctx, n| {
720− let (bloq, b) = n.as_cell().unwrap();
789+ let (bloq, b) = n.as_cell().ok_or(TTanks::new())?;
721 let bloq = bloq.as_u32().unwrap();
790 let bloq = bloq.as_u32().unwrap();
722 let bits = 2u32.pow(bloq);
791 let bits = 2u32.pow(bloq);
724 let mut target = ctx.big_uints.zero.clone();
793 let mut target = ctx.big_uints.zero.clone();
726 for el in b.list_iter().collect::<Vec<_>>().iter().rev() {
795 for el in b.list_iter().collect::<Vec<_>>().iter().rev() {
727− let el = el.as_atom().unwrap();
796+ let el = el.as_atom().ok_or(TTanks::new())?;
728 if el != &ctx.big_uints.zero {
797 if el != &ctx.big_uints.zero {
729− target = (target << (bits * met(bloq, el.clone()))) | el;
798+ target = (target << (bits * met(bloq, &el))) | el;
733− Some(Rc::new(Noun::Atom(target)))
802+ Ok(Rc::new(Noun::Atom(target)))
736static REP: Jet = |ctx, n| {
805static REP: Jet = |ctx, n| {
737− let (bite, b) = n.as_cell().unwrap();
806+ let (bite, b) = n.as_cell().ok_or(TTanks::new())?;
738− let bite = bite.as_bite().unwrap();
807+ let bite = bite.as_bite();
740 let bits = bite.bits();
809 let bits = bite.bits();
741 let mask = (&ctx.big_uints.one << bits) - &ctx.big_uints.one;
810 let mask = (&ctx.big_uints.one << bits) - &ctx.big_uints.one;
@@ -743,18 +812,18 @@ static REP: Jet = |ctx, n| {
743 let mut target = ctx.big_uints.zero.clone();
812 let mut target = ctx.big_uints.zero.clone();
745 for el in b.list_iter().collect::<Vec<_>>().iter().rev() {
814 for el in b.list_iter().collect::<Vec<_>>().iter().rev() {
746− target = (target << bits) | (el.as_atom().unwrap() & &mask);
815+ target = (target << bits) | (el.as_atom().ok_or(TTanks::new())? & &mask);
749− Some(Rc::new(Noun::Atom(target)))
818+ Ok(Rc::new(Noun::Atom(target)))
752static REV: Jet = |ctx, n| {
821static REV: Jet = |ctx, n| {
753− let (bloq, b) = n.as_cell().unwrap();
822+ let (bloq, b) = n.as_cell().ok_or(TTanks::new())?;
754− let (len, dat) = b.as_cell().unwrap();
823+ let (len, dat) = b.as_cell().ok_or(TTanks::new())?;
755 let bloq = bloq.as_u32().unwrap();
824 let bloq = bloq.as_u32().unwrap();
756 let len = len.as_u32().unwrap();
825 let len = len.as_u32().unwrap();
757− let mut dat: Atom = dat.as_atom().unwrap().clone();
826+ let mut dat: Atom = dat.as_atom().ok_or(TTanks::new())?.clone();
759 let bits = 2u32.pow(bloq);
828 let bits = 2u32.pow(bloq);
760 let mask = (&ctx.big_uints.one << bits) - &ctx.big_uints.one;
829 let mask = (&ctx.big_uints.one << bits) - &ctx.big_uints.one;
@@ -766,13 +835,13 @@ static REV: Jet = |ctx, n| {
766 dat = dat >> bits;
835 dat = dat >> bits;
769− Some(Rc::new(Noun::Atom(target)))
838+ Ok(Rc::new(Noun::Atom(target)))
772static RIP: Jet = |ctx, n| {
841static RIP: Jet = |ctx, n| {
773− let (bite, b) = n.as_cell().unwrap();
842+ let (bite, b) = n.as_cell().ok_or(TTanks::new())?;
774− let bite = bite.as_bite().unwrap();
843+ let bite = bite.as_bite();
775− let mut b: Atom = b.as_atom().unwrap().clone();
844+ let mut b: Atom = b.as_atom().ok_or(TTanks::new())?.clone();
777 let bits = bite.bits();
846 let bits = bite.bits();
778 let mask = (&ctx.big_uints.one << bits) - &ctx.big_uints.one;
847 let mask = (&ctx.big_uints.one << bits) - &ctx.big_uints.one;
@@ -784,15 +853,15 @@ static RIP: Jet = |ctx, n| {
784 b = b >> bits;
853 b = b >> bits;
787− Some(Noun::list_refs(target.iter().cloned()))
856+ Ok(Noun::list_refs(target.iter().cloned()))
790static RUN: Jet = |ctx, n| {
859static RUN: Jet = |ctx, n| {
791− let (bite, b) = n.as_cell().unwrap();
860+ let (bite, b) = n.as_cell().ok_or(TTanks::new())?;
792− let (b, gate) = b.as_cell().unwrap();
861+ let (b, gate) = b.as_cell().ok_or(TTanks::new())?;
794− let bite = bite.as_bite().unwrap();
863+ let bite = bite.as_bite();
795− let mut b: Atom = b.as_atom().unwrap().clone();
864+ let mut b: Atom = b.as_atom().ok_or(TTanks::new())?.clone();
797 let bits = bite.bits();
866 let bits = bite.bits();
798 let mask = (&ctx.big_uints.one << bits) - &ctx.big_uints.one;
867 let mask = (&ctx.big_uints.one << bits) - &ctx.big_uints.one;
@@ -801,22 +870,22 @@ static RUN: Jet = |ctx, n| {
802 while b > ctx.big_uints.zero {
871 while b > ctx.big_uints.zero {
803 target = (target << bits)
872 target = (target << bits)
804− | ((*slam(ctx, gate.clone(), Rc::new(Noun::Atom(&mask & &b)))?)
873+ | ((*slam_pulled_gate(ctx, gate, &Rc::new(Noun::Atom(&mask & &b)))?)
805 .as_atom()
874 .as_atom()
806− .unwrap()
875+ .ok_or(TTanks::new())?
807 & &mask);
876 & &mask);
808 b = b >> bits;
877 b = b >> bits;
811− Some(Rc::new(Noun::Atom(target)))
880+ Ok(Rc::new(Noun::Atom(target)))
814static RUT: Jet = |ctx, n| {
883static RUT: Jet = |ctx, n| {
815− let (bite, b) = n.as_cell().unwrap();
884+ let (bite, b) = n.as_cell().ok_or(TTanks::new())?;
816− let (b, gate) = b.as_cell().unwrap();
885+ let (b, gate) = b.as_cell().ok_or(TTanks::new())?;
818− let bite = bite.as_bite().unwrap();
887+ let bite = bite.as_bite();
819− let mut b: Atom = b.as_atom().unwrap().clone();
888+ let mut b: Atom = b.as_atom().ok_or(TTanks::new())?.clone();
821 let bits = bite.bits();
890 let bits = bite.bits();
822 let mask = (&ctx.big_uints.one << bits) - &ctx.big_uints.one;
891 let mask = (&ctx.big_uints.one << bits) - &ctx.big_uints.one;
@@ -825,24 +894,24 @@ static RUT: Jet = |ctx, n| {
826 while b > ctx.big_uints.zero {
895 while b > ctx.big_uints.zero {
827 target.push(
896 target.push(
828− (*slam(ctx, gate.clone(), Rc::new(Noun::Atom(&mask & &b)))?)
897+ (*slam_pulled_gate(ctx, gate, &Rc::new(Noun::Atom(&mask & &b)))?)
829 .as_atom()
898 .as_atom()
830− .unwrap()
899+ .ok_or(TTanks::new())?
833 b = b >> bits;
902 b = b >> bits;
836− Some(Noun::list(target.iter().cloned().map(Noun::Atom)))
905+ Ok(Noun::list(target.iter().cloned().map(Noun::Atom)))
839static SEW: Jet = |ctx, n| {
908static SEW: Jet = |ctx, n| {
840− let (a, b) = n.as_cell().unwrap();
909+ let (a, b) = n.as_cell().ok_or(TTanks::new())?;
841− let (b, recipient) = b.as_cell().unwrap();
910+ let (b, recipient) = b.as_cell().ok_or(TTanks::new())?;
842− let (sew_start, c) = b.as_cell().unwrap();
911+ let (sew_start, c) = b.as_cell().ok_or(TTanks::new())?;
843− let (number_of_blocks, donor) = c.as_cell().unwrap();
912+ let (number_of_blocks, donor) = c.as_cell().ok_or(TTanks::new())?;
844− let recipient = recipient.as_atom().unwrap();
913+ let recipient = recipient.as_atom().ok_or(TTanks::new())?;
845− let donor = donor.as_atom().unwrap();
914+ let donor = donor.as_atom().ok_or(TTanks::new())?;
847 let bloq = a.as_u32().unwrap();
916 let bloq = a.as_u32().unwrap();
848 let bits = 2u32.pow(bloq);
917 let bits = 2u32.pow(bloq);
@@ -854,16 +923,16 @@ static SEW: Jet = |ctx, n| {
855 let target = (recipient ^ apendix) | (donor & mask);
924 let target = (recipient ^ apendix) | (donor & mask);
857− Some(Rc::new(Noun::Atom(target)))
926+ Ok(Rc::new(Noun::Atom(target)))
860static SWP: Jet = |ctx, n| {
929static SWP: Jet = |ctx, n| {
861− let (bloq, b) = n.as_cell().unwrap();
930+ let (bloq, b) = n.as_cell().ok_or(TTanks::new())?;
862 let bloq = bloq.as_u32().unwrap();
931 let bloq = bloq.as_u32().unwrap();
863 let bits = 2u32.pow(bloq);
932 let bits = 2u32.pow(bloq);
864 let mask = (&ctx.big_uints.one << bits) - &ctx.big_uints.one;
933 let mask = (&ctx.big_uints.one << bits) - &ctx.big_uints.one;
866− let mut source = b.as_atom().unwrap().clone();
935+ let mut source = b.as_atom().ok_or(TTanks::new())?.clone();
867 let mut target = ctx.big_uints.zero.clone();
936 let mut target = ctx.big_uints.zero.clone();
869 while source > ctx.big_uints.zero {
938 while source > ctx.big_uints.zero {
@@ -871,11 +940,11 @@ static SWP: Jet = |ctx, n| {
871 source = source >> bits;
940 source = source >> bits;
874− Some(Rc::new(Noun::Atom(target)))
943+ Ok(Rc::new(Noun::Atom(target)))
877static XEB: Jet = |_ctx, n| {
946static XEB: Jet = |_ctx, n| {
878− let mut a = n.as_atom().unwrap().clone();
947+ let mut a = n.as_atom().ok_or(TTanks::new())?.clone();
880 let mut c = 0;
949 let mut c = 0;
@@ -884,7 +953,7 @@ static XEB: Jet = |_ctx, n| {
887− Some(Rc::new(Noun::from_u32(c)))
956+ Ok(Rc::new(Noun::from_u32(c)))
890static CON: Jet = |_ctx, n| BINARY_ATOM(n, |a, b| a | b);
959static CON: Jet = |_ctx, n| BINARY_ATOM(n, |a, b| a | b);
@@ -892,14 +961,310 @@ static DIS: Jet = |_ctx, n| BINARY_ATOM(n, |a, b| a & b);
892static MIX: Jet = |_ctx, n| BINARY_ATOM(n, |a, b| a ^ b);
961static MIX: Jet = |_ctx, n| BINARY_ATOM(n, |a, b| a ^ b);
894static NOT: Jet = |ctx, n| {
963static NOT: Jet = |ctx, n| {
895− let (a, b) = n.as_cell().unwrap();
964+ let (a, b) = n.as_cell().ok_or(TTanks::new())?;
896− let (b, c) = b.as_cell().unwrap();
965+ let (b, c) = b.as_cell().ok_or(TTanks::new())?;
898 let bloq = a.as_u32().unwrap();
967 let bloq = a.as_u32().unwrap();
899 let bits = 2u32.pow(bloq);
968 let bits = 2u32.pow(bloq);
900 let mask = (&ctx.big_uints.one << (bits * b.as_u32().unwrap())) - &ctx.big_uints.one;
969 let mask = (&ctx.big_uints.one << (bits * b.as_u32().unwrap())) - &ctx.big_uints.one;
902− let target = c.as_atom().unwrap() ^ &mask;
971+ let target = c.as_atom().ok_or(TTanks::new())? ^ &mask;
973+ Ok(Rc::new(Noun::Atom(target)))
904− Some(Rc::new(Noun::Atom(target)))
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)))
983+fn last<'a>(a: &'a Hair, b: &'a Hair) -> &'a Hair {
984+ if a.line == b.line {
985+ if a.column > b.column {
991+ if a.line > b.line {
999+static TRIP: Jet = |_ctx, n| {
1000+ let a = n.as_atom().ok_or(TTanks::new())?;
1002+ a.to_bytes_le().iter().map(|b| Noun::from_u32(*b as u32)),
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())?;
1013+ Ok(Rc::new(Noun::from_u32(muk(seed, len, key))))
1016+static AOR: Jet = |ctx, n| {
1017+ let (a, b) = n.as_cell().ok_or(EMPTY_TANKS)?;
1020+ Ok(ctx.nouns.y.clone())
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, .. }) => {
1026+ AOR(ctx, &cell(a_q, b_q))
1028+ AOR(ctx, &cell(a_p, b_p))
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();
1038+ let c = a.get(i).unwrap_or(&0);
1039+ let d = b.get(i).unwrap_or(&0);
1045+ return Ok(ctx.nouns.y.clone());
1047+ return Ok(ctx.nouns.n.clone());
1056+static DOR: Jet = |ctx, n| {
1057+ let (a, b) = n.as_cell().ok_or(EMPTY_TANKS)?;
1060+ Ok(ctx.nouns.y.clone())
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, .. }) => {
1066+ DOR(ctx, &cell(a_q, b_q))
1068+ DOR(ctx, &cell(a_p, b_p))
1071+ (Noun::Atom(_), Noun::Cell { .. }) => Ok(ctx.nouns.y.clone()),
1072+ (Noun::Atom(a), Noun::Atom(b)) => {
1074+ Ok(ctx.nouns.y.clone())
1076+ Ok(ctx.nouns.n.clone())
1083+static GOR: Jet = |ctx, n| {
1084+ let (a, b) = n.as_cell().ok_or(EMPTY_TANKS)?;
1092+ Ok(ctx.nouns.y.clone())
1094+ Ok(ctx.nouns.n.clone())
1099+static GOR_PAIR: fn(&mut InterpreterContext, &Rc<Noun>, &Rc<Noun>) -> Result<bool, TTanks> =
1105+ Ok(DOR(ctx, &(a.clone(), b.clone()).as_noun())? == ctx.nouns.y)
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();
1120+ Ok(ctx.nouns.y.clone())
1122+ Ok(ctx.nouns.n.clone())
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)
1132+static LOOK_PAIR: fn(
1133+ &mut InterpreterContext,
1137+) -> Result<Rc<Noun>, TTanks> = |ctx, axe, cog, dab| {
1139+ Ok(ctx.nouns.sig.clone())
1141+ let (node, b, c) = dab.tuple_3().ok_or(EMPTY_TANKS)?;
1144+ let (p, q) = node.as_cell().ok_or(EMPTY_TANKS)?;
1145+ if b.is_sig() && c.is_sig() {
1147+ Ok((ctx.nouns.sig.clone(), Noun::Atom(axe), q.clone()).as_noun())
1149+ Ok(ctx.nouns.sig.clone())
1151+ } else if b.is_sig() {
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())
1157+ LOOK_PAIR(ctx, PEG_U32(&axe, 3), cog, r)
1159+ } else if c.is_sig() {
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)
1165+ Ok(ctx.nouns.sig.clone())
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)
1173+ LOOK_PAIR(ctx, PEG_U32(&axe, 7), cog, r)
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())
1185+ let (i, _) = nail.rest.as_cell()?;
1186+ let i = i.as_atom()?;
1188+ Some(next(nail)?.as_noun())
1190+ Some(fail(nail).as_noun())
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()?;
1200+// let mut lef = Vec::new();
1201+// let mut vex = slam(ctx, fel, tub)?.as;
1205+fn next<'a>(nail: Nail<'a>) -> Option<Edge<'a>> {
1206+ if **nail.rest == Noun::SIG {
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))))
1214+ result: Some((i, Nail { hair: zac, rest: t })),
1219+fn lust(char: Atom, hair: Hair) -> Hair {
1220+ if char == Atom::from_slice(&vec![10]) {
1222+ line: hair.line + 1,
1228+ column: hair.column + 1,
1233+fn fail(nail: Nail) -> Edge {
1240+const MUG: Jet = |__ctx, n| Ok(Rc::new(Noun::from_u32(n.mug())));
1242+pub fn mum(syd: u32, fal: u32, key: &Atom) -> u32 {
1243+ let wyd = met(3, &key);
1249+ let haz = muk(syd, wyd, &key);
1250+ let ham = (haz >> 31) ^ (haz & !(1 << 31));
1261+fn muk(seed: u32, len: u32, key: &Atom) -> u32 {
1262+ let key: Vec<_> = key
1265+ .take(len as usize)
1269+ murmur3_32(&mut &*key, seed).unwrap()