on master help sign in
initial optionification
commitbd361abb9d6ab2037cdeda460640d4ac709e8faa authoriko <mail@iko.soy> dateTue 27 Aug 2024, 20:43 (2 years ago) parent8c2711f
3 files changed+228−199
nock/src/interpreter.rs+58−60 nock/src/jets.rs+169−138 nock/src/main.rs+1−1
nock/src/interpreter.rs+58−60
@@ -1,4 +1,3 @@
1−use core::panic;
21use std::rc::Rc;
32
43use num_bigint::BigUint;
@@ -72,10 +71,10 @@ fn wut(ctx: &InterpreterContext, noun: Rc<Noun>) -> Rc<Noun> {
7271 }
7372}
7473
75−fn lus(noun: Rc<Noun>) -> Noun {
74+fn lus(noun: Rc<Noun>) -> Option<Noun> {
7675 match (*noun).clone() {
77− Noun::Cell { .. } => panic!(),
78− Noun::Atom(atm) => Noun::Atom(atm + 1u32),
76+ Noun::Cell { .. } => None,
77+ Noun::Atom(atm) => Some(Noun::Atom(atm + 1u32)),
7978 }
8079}
8180
@@ -87,37 +86,37 @@ fn tis(ctx: &InterpreterContext, lhs: Rc<Noun>, rhs: Rc<Noun>) -> Rc<Noun> {
8786 }
8887}
8988
90−fn fas(ctx: &InterpreterContext, addr: Atom, noun: Rc<Noun>) -> Rc<Noun> {
89+fn fas(ctx: &InterpreterContext, addr: Atom, noun: Rc<Noun>) -> Option<Rc<Noun>> {
9190 let mut addr_iter = addr.iter_u32_digits();
9291
9392 match addr_iter.len() {
9493 0 => panic!(),
95− 1 => fas_u32(addr_iter.next().unwrap(), noun),
94+ 1 => Some(fas_u32(addr_iter.next()?, noun)?),
9695 _ => {
97− let rest = fas(ctx, &addr >> 1, noun);
98− fas_u32(
96+ let rest = fas(ctx, &addr >> 1, noun)?;
97+ Some(fas_u32(
9998 if (addr & &ctx.big_uints.one) == ctx.big_uints.one {
10099 3
101100 } else {
102101 2
103102 },
104103 rest,
105− )
104+ )?)
106105 }
107106 }
108107}
109108
110−fn fas_u32(addr: u32, noun: Rc<Noun>) -> Rc<Noun> {
109+fn fas_u32(addr: u32, noun: Rc<Noun>) -> Option<Rc<Noun>> {
111110 match addr {
112− 0 => panic!(),
113− 1 => noun,
111+ 0 => None,
112+ 1 => Some(noun),
114113 n => match (*noun).clone() {
115− Noun::Atom(_) => panic!(),
114+ Noun::Atom(_) => None,
116115 Noun::Cell { p, q, .. } => match n {
117− 2 => p,
118− 3 => q,
116+ 2 => Some(p),
117+ 3 => Some(q),
119118 _ => {
120− let rest = fas_u32(n >> 1, cell(p, q));
119+ let rest = fas_u32(n >> 1, cell(p, q))?;
121120 fas_u32(if (n & 1) == 1 { 3 } else { 2 }, rest)
122121 }
123122 },
@@ -125,23 +124,28 @@ fn fas_u32(addr: u32, noun: Rc<Noun>) -> Rc<Noun> {
125124 }
126125}
127126
128−fn hax_u32(addr: u32, new_value: Rc<Noun>, target: Rc<Noun>) -> Rc<Noun> {
127+fn hax_u32(addr: u32, new_value: Rc<Noun>, target: Rc<Noun>) -> Option<Rc<Noun>> {
129128 match addr {
130− 0 => panic!(),
131− 1 => new_value,
129+ 0 => None,
130+ 1 => Some(new_value),
132131 _ => hax_u32(
133132 addr >> 1,
134133 if (addr & 1) == 1 {
135− cell(fas_u32(addr - 1, target.clone()), new_value)
134+ cell(fas_u32(addr - 1, target.clone())?, new_value)
136135 } else {
137− cell(new_value, fas_u32(addr + 1, target.clone()))
136+ cell(new_value, fas_u32(addr + 1, target.clone())?)
138137 },
139138 target,
140139 ),
141140 }
142141}
143142
144−fn hax(ctx: &InterpreterContext, addr: Atom, new_value: Rc<Noun>, target: Rc<Noun>) -> Rc<Noun> {
143+fn hax(
144+ ctx: &InterpreterContext,
145+ addr: Atom,
146+ new_value: Rc<Noun>,
147+ target: Rc<Noun>,
148+) -> Option<Rc<Noun>> {
145149 let mut addr_iter = addr.iter_u32_digits();
146150
147151 match addr_iter.len() {
@@ -152,13 +156,13 @@ fn hax(ctx: &InterpreterContext, addr: Atom, new_value: Rc<Noun>, target: Rc<Nou
152156 &addr >> 1u32,
153157 if (&addr & &ctx.big_uints.one) == ctx.big_uints.one {
154158 cell(
155− fas(ctx, addr - &ctx.big_uints.one, target.clone()),
159+ fas(ctx, addr - &ctx.big_uints.one, target.clone())?,
156160 new_value,
157161 )
158162 } else {
159163 cell(
160164 new_value,
161− fas(ctx, addr + &ctx.big_uints.one, target.clone()),
165+ fas(ctx, addr + &ctx.big_uints.one, target.clone())?,
162166 )
163167 },
164168 target,
@@ -166,15 +170,18 @@ fn hax(ctx: &InterpreterContext, addr: Atom, new_value: Rc<Noun>, target: Rc<Nou
166170 }
167171}
168172
169−fn tar_u32(ctx: &InterpreterContext, subj: Rc<Noun>, op: u32, formula: Rc<Noun>) -> Rc<Noun> {
173+fn tar_u32(
174+ ctx: &InterpreterContext,
175+ subj: Rc<Noun>,
176+ op: u32,
177+ formula: Rc<Noun>,
178+) -> Option<Rc<Noun>> {
170179 match op {
171180 0 => {
172− let Noun::Atom(b) = (*formula).clone() else {
173− panic!()
174− };
181+ let b = formula.as_atom()?.clone();
175182 fas(ctx, b, subj)
176183 }
177− 1 => formula,
184+ 1 => Some(formula),
178185 2 => {
179186 let Noun::Cell { p: b, q: c, .. } = (*formula).clone() else {
180187 panic!()
@@ -194,27 +201,23 @@ fn tar_u32(ctx: &InterpreterContext, subj: Rc<Noun>, op: u32, formula: Rc<Noun>)
194201 println!("Evaluating jet {}", hash);
195202 f(ctx, sample)
196203 }
197− None => tar(ctx, tar(ctx, subj.clone(), b), tar(ctx, subj, c)),
204+ None => tar(ctx, tar(ctx, subj.clone(), b)?, tar(ctx, subj, c)?),
198205 }
199206 }
200− _ => tar(ctx, tar(ctx, subj.clone(), b), tar(ctx, subj, c)),
207+ _ => tar(ctx, tar(ctx, subj.clone(), b)?, tar(ctx, subj, c)?),
201208 }
202209 }
203− 3 => wut(ctx, tar(ctx, subj, formula)),
204− 4 => Rc::new(lus(tar(ctx, subj, formula))),
210+ 3 => Some(wut(ctx, tar(ctx, subj, formula)?)),
211+ 4 => Some(Rc::new(lus(tar(ctx, subj, formula)?)?)),
205212 5 => {
206213 let Noun::Cell { p: b, q: c, .. } = (*formula).clone() else {
207214 panic!()
208215 };
209− tis(ctx, tar(ctx, subj.clone(), b), tar(ctx, subj, c))
216+ Some(tis(ctx, tar(ctx, subj.clone(), b)?, tar(ctx, subj, c)?))
210217 }
211218 6 => {
212− let Noun::Cell { p: b, q: c, .. } = (*formula).clone() else {
213− panic!()
214− };
215− let Noun::Cell { p: c, q: d, .. } = (*c).clone() else {
216− panic!()
217− };
219+ let (b, c) = formula.as_cell()?;
220+ let (c, d) = c.as_cell()?;
218221
219222 tar(
220223 ctx,
@@ -227,22 +230,22 @@ fn tar_u32(ctx: &InterpreterContext, subj: Rc<Noun>, op: u32, formula: Rc<Noun>)
227230 ctx,
228231 ctx.nouns.two_three.clone(),
229232 0,
230− tar_u32(ctx, subj, 4, cell(ctx.nouns.four.clone(), b)),
231− ),
232− ),
233+ tar_u32(ctx, subj, 4, cell(ctx.nouns.four.clone(), b))?,
234+ )?,
235+ )?,
233236 )
234237 }
235238 7 => {
236239 let Noun::Cell { p: b, q: c, .. } = (*formula).clone() else {
237240 panic!()
238241 };
239− tar(ctx, tar(ctx, subj, b), c)
242+ tar(ctx, tar(ctx, subj, b)?, c)
240243 }
241244 8 => {
242245 let Noun::Cell { p: b, q: c, .. } = (*formula).clone() else {
243246 panic!()
244247 };
245− tar(ctx, cell(tar(ctx, subj.clone(), b), subj), c)
248+ tar(ctx, cell(tar(ctx, subj.clone(), b)?, subj), c)
246249 }
247250 9 => {
248251 let Noun::Cell { p: b, q: c, .. } = (*formula).clone() else {
@@ -250,7 +253,7 @@ fn tar_u32(ctx: &InterpreterContext, subj: Rc<Noun>, op: u32, formula: Rc<Noun>)
250253 };
251254 tar_u32(
252255 ctx,
253− tar(ctx, subj, c),
256+ tar(ctx, subj, c)?,
254257 2,
255258 cell(ctx.nouns.sig_one.clone(), cell(ctx.nouns.sig.clone(), b)),
256259 )
@@ -266,7 +269,7 @@ fn tar_u32(ctx: &InterpreterContext, subj: Rc<Noun>, op: u32, formula: Rc<Noun>)
266269 panic!()
267270 };
268271
269− hax(ctx, b, tar(ctx, subj.clone(), c), tar(ctx, subj, d))
272+ hax(ctx, b, tar(ctx, subj.clone(), c)?, tar(ctx, subj, d)?)
270273 }
271274 11 => {
272275 let Noun::Cell { p: b, q: d, .. } = (*formula).clone() else {
@@ -276,7 +279,7 @@ fn tar_u32(ctx: &InterpreterContext, subj: Rc<Noun>, op: u32, formula: Rc<Noun>)
276279 Noun::Atom(_) => tar(ctx, subj, d),
277280 Noun::Cell { q: c, .. } => tar_u32(
278281 ctx,
279− cell(tar(ctx, subj.clone(), c), tar(ctx, subj, d)),
282+ cell(tar(ctx, subj.clone(), c)?, tar(ctx, subj, d)?),
280283 0,
281284 ctx.nouns.three.clone(),
282285 ),
@@ -286,16 +289,11 @@ fn tar_u32(ctx: &InterpreterContext, subj: Rc<Noun>, op: u32, formula: Rc<Noun>)
286289 }
287290}
288291
289−pub fn tar(ctx: &InterpreterContext, subj: Rc<Noun>, formula: Rc<Noun>) -> Rc<Noun> {
290− let Noun::Cell {
291− p: op, q: formula, ..
292− } = (*formula).clone()
293− else {
294− panic!()
295− };
296− match (*op).clone() {
297− Noun::Cell { .. } => cell(tar(ctx, subj.clone(), op), tar(ctx, subj, formula)),
298− Noun::Atom(op) => {
292+pub fn tar(ctx: &InterpreterContext, subj: Rc<Noun>, formula: Rc<Noun>) -> Option<Rc<Noun>> {
293+ let (op, formula) = formula.as_cell()?;
294+ match *op {
295+ Noun::Cell { .. } => Some(cell(tar(ctx, subj.clone(), op)?, tar(ctx, subj, formula)?)),
296+ Noun::Atom(ref op) => {
299297 let mut op_iter = op.iter_u32_digits();
300298 let op = match op_iter.len() {
301299 0 => 0,
@@ -307,7 +305,7 @@ pub fn tar(ctx: &InterpreterContext, subj: Rc<Noun>, formula: Rc<Noun>) -> Rc<No
307305 }
308306}
309307
310−pub fn eval_gate(ctx: &InterpreterContext, gate: Rc<Noun>) -> Rc<Noun> {
308+pub fn eval_gate(ctx: &InterpreterContext, gate: Rc<Noun>) -> Option<Rc<Noun>> {
311309 tar(
312310 ctx,
313311 gate,
@@ -321,7 +319,7 @@ pub fn eval_gate(ctx: &InterpreterContext, gate: Rc<Noun>) -> Rc<Noun> {
321319 )
322320}
323321
324−pub fn slam(ctx: &InterpreterContext, gate: Rc<Noun>, sample: Rc<Noun>) -> Rc<Noun> {
322+pub fn slam(ctx: &InterpreterContext, gate: Rc<Noun>, sample: Rc<Noun>) -> Option<Rc<Noun>> {
325323 let (battery, payload) = gate.as_cell().unwrap();
326324 let (_sample, context) = payload.as_cell().unwrap();
327325
nock/src/jets.rs+169−138
@@ -12,6 +12,16 @@ use crate::{
1212 noun::{self, cell, Atom, Noun},
1313};
1414
15+fn traverse_iter_option<T: Clone, I: Iterator<Item = Option<T>>>(xs: I) -> Option<Vec<T>> {
16+ let mut target: Vec<T> = Vec::new();
17+
18+ for x in xs {
19+ target.push(x.clone()?)
20+ }
21+
22+ Some(target)
23+}
24+
1525pub type Jets = BTreeMap<noun::Hash, Jet>;
1626
1727pub fn generate_jets() -> Jets {
@@ -54,7 +64,7 @@ pub fn generate_jets() -> Jets {
5464 (288515703007942177334798811660651439897, SNAG),
5565 (322006565952434408151902864454572452802, SNIP),
5666 (290837622185731774795798043954046795930, SNOC),
57− (255402796382159268271460433298209603428, SORT),
67+ // (255402796382159268271460433298209603428, SORT),
5868 (10111398404342329752608067595798409804, SPIN),
5969 (209194119090564757355985847956576215234, SPUN),
6070 (103985097318911737222583881947453560061, TURN),
@@ -86,35 +96,38 @@ pub fn generate_jets() -> Jets {
8696 ])
8797}
8898
89−pub type Jet = fn(ctx: &InterpreterContext, Rc<Noun>) -> Rc<Noun>;
99+pub type Jet = fn(ctx: &InterpreterContext, Rc<Noun>) -> Option<Rc<Noun>>;
90100
91−static BINARY_ATOM: fn(Rc<Noun>, fn(&Atom, &Atom) -> Atom) -> Rc<Noun> =
101+static BINARY_ATOM: fn(Rc<Noun>, fn(&Atom, &Atom) -> Atom) -> Option<Rc<Noun>> =
92102 |n: Rc<Noun>, f: fn(&Atom, &Atom) -> Atom| {
93− let (p, q) = n.as_cell().unwrap();
94− Rc::new(Noun::Atom(f(p.as_atom().unwrap(), q.as_atom().unwrap())))
103+ let (p, q) = n.as_cell()?;
104+ Some(Rc::new(Noun::Atom(f(p.as_atom()?, q.as_atom()?))))
95105 };
96106
97−static BINARY_ATOM_LOOB: fn(&InterpreterContext, Rc<Noun>, fn(&Atom, &Atom) -> bool) -> Rc<Noun> =
98− |ctx: &InterpreterContext, n: Rc<Noun>, f: fn(&Atom, &Atom) -> bool| {
99− let (p, q) = n.as_cell().unwrap();
107+static BINARY_ATOM_LOOB: fn(
108+ &InterpreterContext,
109+ Rc<Noun>,
110+ fn(&Atom, &Atom) -> bool,
111+) -> Option<Rc<Noun>> = |ctx: &InterpreterContext, n: Rc<Noun>, f: fn(&Atom, &Atom) -> bool| {
112+ let (p, q) = n.as_cell().unwrap();
100113
101− if f(p.as_atom().unwrap(), q.as_atom().unwrap()) {
102− ctx.nouns.sig.clone()
103− } else {
104− ctx.nouns.one.clone()
105− }
106− };
114+ if f(p.as_atom()?, q.as_atom()?) {
115+ Some(ctx.nouns.sig.clone())
116+ } else {
117+ Some(ctx.nouns.one.clone())
118+ }
119+};
107120
108−static BINARY_ATOM_PAIR: fn(Rc<Noun>, fn(&Atom, &Atom) -> (Atom, Atom)) -> Rc<Noun> =
121+static BINARY_ATOM_PAIR: fn(Rc<Noun>, fn(&Atom, &Atom) -> (Atom, Atom)) -> Option<Rc<Noun>> =
109122 |n: Rc<Noun>, f: fn(&Atom, &Atom) -> (Atom, Atom)| {
110123 let (p, q) = n.as_cell().unwrap();
111124
112125 let (a, b) = f(p.as_atom().unwrap(), q.as_atom().unwrap());
113− cell(Rc::new(Noun::Atom(a)), Rc::new(Noun::Atom(b)))
126+ Some(cell(Rc::new(Noun::Atom(a)), Rc::new(Noun::Atom(b))))
114127 };
115128
116129static ADD: Jet = |_ctx, n| BINARY_ATOM(n, |a, b| a + b);
117−static DEC: Jet = |_ctx, n| Rc::new(Noun::Atom(n.as_atom().unwrap() - 1u32));
130+static DEC: Jet = |_ctx, n| Some(Rc::new(Noun::Atom(n.as_atom().unwrap() - 1u32)));
118131static DVR: Jet = |_ctx, n| BINARY_ATOM_PAIR(n, |a, b| a.div_rem(&b));
119132static DIV: Jet = |_ctx, n| BINARY_ATOM(n, |a, b| a / b);
120133static GTE: Jet = |ctx, n| BINARY_ATOM_LOOB(ctx, n, |a, b| a >= b);
@@ -133,7 +146,7 @@ static CAP: Jet = |ctx, n| {
133146 };
134147 CAP_ATOM(ctx, n)
135148};
136−static CAP_ATOM: fn(&InterpreterContext, Atom) -> Rc<Noun> = |ctx, n: Atom| {
149+static CAP_ATOM: fn(&InterpreterContext, Atom) -> Option<Rc<Noun>> = |ctx, n: Atom| {
137150 let mut n_iter = n.iter_u32_digits();
138151
139152 match n_iter.len() {
@@ -142,10 +155,10 @@ static CAP_ATOM: fn(&InterpreterContext, Atom) -> Rc<Noun> = |ctx, n: Atom| {
142155 _ => CAP_ATOM(ctx, n >> 1),
143156 }
144157};
145−static CAP_U32: fn(ctx: &InterpreterContext, u32) -> Rc<Noun> = |ctx, n| match n {
158+static CAP_U32: fn(ctx: &InterpreterContext, u32) -> Option<Rc<Noun>> = |ctx, n| match n {
146159 0 | 1 => panic!(),
147− 2 => ctx.nouns.two.clone(),
148− 3 => ctx.nouns.three.clone(),
160+ 2 => Some(ctx.nouns.two.clone()),
161+ 3 => Some(ctx.nouns.three.clone()),
149162 n => CAP_U32(ctx, n >> 1),
150163};
151164
@@ -153,7 +166,7 @@ static MAS: Jet = |ctx, n| {
153166 let Noun::Atom(n) = (*n).clone() else {
154167 panic!()
155168 };
156− Rc::new(Noun::Atom(MAS_ATOM(ctx, n)))
169+ Some(Rc::new(Noun::Atom(MAS_ATOM(ctx, n))))
157170};
158171static MAS_ATOM: fn(&InterpreterContext, Atom) -> Atom = |ctx, n| {
159172 let mut n_iter = n.iter_u32_digits();
@@ -182,7 +195,7 @@ static PEG: Jet = |ctx, n| {
182195 panic!()
183196 };
184197
185− Rc::new(Noun::Atom(PEG_ATOM(ctx, a, b.clone())))
198+ Some(Rc::new(Noun::Atom(PEG_ATOM(ctx, a, b.clone()))))
186199};
187200static PEG_ATOM: fn(&InterpreterContext, &Atom, Atom) -> Atom = |ctx, a, b| {
188201 let mut b_iter = b.iter_u32_digits();
@@ -204,7 +217,7 @@ static PEG_U32: fn(&Atom, u32) -> Atom = |a, b| match b {
204217static FAND: Jet = |ctx, n| {
205218 let (nedl, hstk) = n.as_cell().unwrap();
206219 if nedl.is_sig() || hstk.is_sig() {
207− return ctx.nouns.sig.clone();
220+ return Some(ctx.nouns.sig.clone());
208221 }
209222
210223 let nedl: Vec<Rc<Noun>> = nedl.list_iter().collect();
@@ -228,13 +241,13 @@ static FAND: Jet = |ctx, n| {
228241 inner_iter = iter.clone();
229242 }
230243
231− Noun::list(result.iter().map(|a| Noun::from_u32(*a)))
244+ Some(Noun::list(result.iter().map(|a| Noun::from_u32(*a))))
232245};
233246
234247static FIND: Jet = |ctx, n| {
235248 let (nedl, hstk) = n.as_cell().unwrap();
236249 if nedl.is_sig() || hstk.is_sig() {
237− return ctx.nouns.sig.clone();
250+ return Some(ctx.nouns.sig.clone());
238251 }
239252
240253 let nedl: Vec<Rc<Noun>> = nedl.list_iter().collect();
@@ -250,18 +263,20 @@ static FIND: Jet = |ctx, n| {
250263 .collect::<Vec<_>>()
251264 == nedl
252265 {
253− return Rc::new(Noun::from_u32(i)).unit();
266+ return Some(Rc::new(Noun::from_u32(i)).unit());
254267 }
255268
256269 inner_iter = iter.clone();
257270 }
258271
259− return ctx.nouns.sig.clone();
272+ return Some(ctx.nouns.sig.clone());
260273};
261274
262275static FLOP: Jet = |ctx, n| {
263− n.list_iter()
264− .fold(ctx.nouns.sig.clone(), |tail, head| cell(head, tail))
276+ Some(
277+ n.list_iter()
278+ .fold(ctx.nouns.sig.clone(), |tail, head| cell(head, tail)),
279+ )
265280};
266281
267282static GULF: Jet = |_ctx, n| {
@@ -281,7 +296,7 @@ static GULF: Jet = |_ctx, n| {
281296 from += 1u32;
282297 }
283298
284− Noun::list(tmp.iter().rev().map(|a| Noun::Atom(a.clone())))
299+ Some(Noun::list(tmp.iter().rev().map(|a| Noun::Atom(a.clone()))))
285300};
286301
287302static INTO: Jet = |_ctx, n| {
@@ -291,11 +306,11 @@ static INTO: Jet = |_ctx, n| {
291306 let mut b_iter = b.as_atom().unwrap().iter_u32_digits();
292307
293308 match b_iter.len() {
294− 0 => cell(c, a),
309+ 0 => Some(cell(c, a)),
295310 1 => {
296311 let l = a.list_iter();
297312 let b = b_iter.next().unwrap() as usize;
298− Noun::list_refs(
313+ Some(Noun::list_refs(
299314 l.clone()
300315 .take(b)
301316 .chain(once(c))
@@ -303,79 +318,85 @@ static INTO: Jet = |_ctx, n| {
303318 .collect::<Vec<_>>()
304319 .iter()
305320 .map(|x| x.clone()),
306− )
321+ ))
307322 }
308− _ => Noun::list_refs(
323+ _ => Some(Noun::list_refs(
309324 a.list_iter()
310325 .chain(once(c))
311326 .collect::<Vec<_>>()
312327 .iter()
313328 .map(|x| x.clone()),
314− ),
329+ )),
315330 }
316331};
317332
318333static JOIN: Jet = |_ctx, n| {
319334 let (sep, list) = n.as_cell().unwrap();
320− Noun::list_refs(
335+ Some(Noun::list_refs(
321336 list.list_iter()
322337 .intersperse(sep)
323338 .collect::<Vec<_>>()
324339 .iter()
325340 .map(|x| x.clone()),
326− )
341+ ))
327342};
328343
329−static LENT: Jet = |_ctx, n| Rc::new(Noun::from_u32(n.list_iter().fold(0u32, |l, _| l + 1)));
344+static LENT: Jet = |_ctx, n| {
345+ Some(Rc::new(Noun::from_u32(
346+ n.list_iter().fold(0u32, |l, _| l + 1),
347+ )))
348+};
330349
331350static LEVY: Jet = |ctx, n| {
332351 let (a, b) = n.as_cell().unwrap();
333− if a.list_iter()
334− .all(|n| slam(ctx, b.clone(), n) == ctx.nouns.y)
352+ if traverse_iter_option(a.list_iter().map(|n| slam(ctx, b.clone(), n)))?
353+ .iter()
354+ .all(|x| x.is_y())
335355 {
336− ctx.nouns.y.clone()
356+ Some(ctx.nouns.y.clone())
337357 } else {
338− ctx.nouns.n.clone()
358+ Some(ctx.nouns.n.clone())
339359 }
340360};
341361
342362static LIEN: Jet = |ctx, n| {
343363 let (a, b) = n.as_cell().unwrap();
344− if a.list_iter()
345− .any(|n| slam(ctx, b.clone(), n) == ctx.nouns.y)
364+ if traverse_iter_option(a.list_iter().map(|n| slam(ctx, b.clone(), n)))?
365+ .iter()
366+ .any(|x| x.is_y())
346367 {
347− ctx.nouns.y.clone()
368+ Some(ctx.nouns.y.clone())
348369 } else {
349− ctx.nouns.n.clone()
370+ Some(ctx.nouns.n.clone())
350371 }
351372};
352373
353374static MURN: Jet = |ctx, n| {
354375 let (a, b) = n.as_cell().unwrap();
355376
356− Noun::list_refs(
377+ Some(Noun::list_refs(
357378 a.list_iter()
358− .filter_map(|n| slam(ctx, b.clone(), n).as_unit())
379+ .filter_map(|n| slam(ctx, b.clone(), n)?.as_unit())
359380 .collect::<Vec<_>>()
360381 .iter()
361382 .map(|x| x.clone()),
362− )
383+ ))
363384};
364385
365386static REAP: Jet = |_ctx, n| {
366387 let (a, b) = n.as_cell().unwrap();
367388
368− Noun::list_refs(repeat_n(b, a.as_u32().unwrap() as usize))
389+ Some(Noun::list_refs(repeat_n(b, a.as_u32().unwrap() as usize)))
369390};
370391
371−static REAR: Jet = |_ctx, n| n.list_iter().last().unwrap();
392+static REAR: Jet = |_ctx, n| n.list_iter().last();
372393
373394static REEL: Jet = |ctx, n| {
374395 let (list, gate) = n.as_cell().unwrap();
375396
376397 list.list_iter().collect::<Vec<_>>().iter().rfold(
377− gate.clone().gate_sample().unwrap().as_cell().unwrap().1,
378− |acc, next| slam(ctx, gate.clone(), cell(next.clone(), acc)),
398+ Some(gate.clone().gate_sample()?.as_cell()?.1),
399+ |acc, next| slam(ctx, gate.clone(), cell(next.clone(), acc?)),
379400 )
380401};
381402
@@ -383,58 +404,66 @@ static ROLL: Jet = |ctx, n| {
383404 let (list, gate) = n.as_cell().unwrap();
384405
385406 list.list_iter().fold(
386− gate.clone().gate_sample().unwrap().as_cell().unwrap().1,
387− |acc, next| slam(ctx, gate.clone(), cell(next.clone(), acc)),
407+ Some(gate.clone().gate_sample()?.as_cell()?.1),
408+ |acc, next| slam(ctx, gate.clone(), cell(next.clone(), acc?)),
388409 )
389410};
390411
391412static SCAG: Jet = |_ctx, n| {
392413 let (a, b) = n.as_cell().unwrap();
393414
394− Noun::list_refs(
415+ Some(Noun::list_refs(
395416 b.list_iter()
396417 .take(a.as_u32().unwrap() as usize)
397418 .collect::<Vec<_>>()
398419 .iter()
399420 .map(|x| x.clone()),
400− )
421+ ))
401422};
402423
403424static SKID: Jet = |ctx, n| {
404425 let (list, gate) = n.as_cell().unwrap();
405426
406− let (ys, ns): (Vec<Rc<Noun>>, _) = list
407− .list_iter()
408− .partition(|n| slam(ctx, gate.clone(), n.clone()).is_y());
427+ let slammed_n = traverse_iter_option(
428+ list.list_iter()
429+ .map(|n| Some((slam(ctx, gate.clone(), n.clone())?, n))),
430+ )?;
431+ let (ys, ns): (Vec<_>, _) = slammed_n.iter().partition(|(l, _)| l.is_y());
409432
410− cell(
411− Noun::list_refs(ys.iter().cloned()),
412− Noun::list_refs(ns.iter().cloned()),
413− )
433+ Some(cell(
434+ Noun::list_refs(ys.iter().map(|(_, x)| x).cloned()),
435+ Noun::list_refs(ns.iter().map(|(_, x)| x).cloned()),
436+ ))
414437};
415438
416439static SKIM: Jet = |ctx, n| {
417440 let (list, gate) = n.as_cell().unwrap();
418441
419− Noun::list_refs(
420− list.list_iter()
421− .filter(|n| slam(ctx, gate.clone(), n.clone()).is_y())
422− .collect::<Vec<_>>()
423− .iter()
424− .cloned(),
425− )
442+ Some(Noun::list_refs(
443+ traverse_iter_option(
444+ list.list_iter()
445+ .map(|n| Some((slam(ctx, gate.clone(), n.clone())?, n))),
446+ )?
447+ .iter()
448+ .filter(|(l, _)| l.is_y())
449+ .map(|(_, x)| x)
450+ .cloned(),
451+ ))
426452};
427453
428454static SKIP: Jet = |ctx, n| {
429455 let (list, gate) = n.as_cell().unwrap();
430456
431− Noun::list_refs(
432− list.list_iter()
433− .filter(|n| slam(ctx, gate.clone(), n.clone()).is_n())
434− .collect::<Vec<_>>()
435− .iter()
436− .cloned(),
437− )
457+ Some(Noun::list_refs(
458+ traverse_iter_option(
459+ list.list_iter()
460+ .map(|n| Some((slam(ctx, gate.clone(), n.clone())?, n))),
461+ )?
462+ .iter()
463+ .filter(|(l, _)| l.is_y())
464+ .map(|(_, x)| x)
465+ .cloned(),
466+ ))
438467};
439468
440469static SLAG: Jet = |ctx, n| {
@@ -443,26 +472,26 @@ static SLAG: Jet = |ctx, n| {
443472 let mut a_iter = a.as_atom().unwrap().iter_u32_digits();
444473
445474 match a_iter.len() {
446− 0 => list,
447− 1 => Noun::list_refs(
475+ 0 => Some(list),
476+ 1 => Some(Noun::list_refs(
448477 list.list_iter()
449478 .skip(a_iter.next().unwrap() as usize)
450479 .collect::<Vec<_>>()
451480 .iter()
452481 .cloned(),
453− ),
454− _ => ctx.nouns.sig.clone(),
482+ )),
483+ _ => Some(ctx.nouns.sig.clone()),
455484 }
456485};
457486
458487static SNAG: Jet = |_ctx, n| {
459488 let (a, list) = n.as_cell().unwrap();
460489
461− list.list_iter().nth(a.as_u32().unwrap() as usize).unwrap()
490+ list.list_iter().nth(a.as_u32().unwrap() as usize)
462491};
463492
464493static SNIP: Jet = |_ctx, n| {
465− Noun::list_refs(
494+ Some(Noun::list_refs(
466495 n.list_iter()
467496 .collect::<Vec<_>>()
468497 .iter()
@@ -470,38 +499,38 @@ static SNIP: Jet = |_ctx, n| {
470499 .skip(1)
471500 .rev()
472501 .cloned(),
473− )
502+ ))
474503};
475504
476505static SNOC: Jet = |_ctx, n| {
477506 let (list, b) = n.as_cell().unwrap();
478507
479− Noun::list_refs(
508+ Some(Noun::list_refs(
480509 list.list_iter()
481510 .chain(once(b))
482511 .collect::<Vec<_>>()
483512 .iter()
484513 .cloned(),
485− )
514+ ))
486515};
487516
488−static SORT: Jet = |ctx, n| {
489− let (list, lth) = n.as_cell().unwrap();
517+// static SORT: Jet = |ctx, n| {
518+// let (list, lth) = n.as_cell().unwrap();
490519
491− let mut v: Vec<_> = list.list_iter().collect();
520+// let mut v: Vec<_> = list.list_iter().collect();
492521
493− v.sort_by(|a, b| {
494− if slam(ctx, lth.clone(), cell(a.clone(), b.clone())).is_y() {
495− Ordering::Less
496− } else if slam(ctx, lth.clone(), cell(b.clone(), a.clone())).is_y() {
497− Ordering::Greater
498− } else {
499− Ordering::Equal
500− }
501− });
522+// v.sort_by(|a, b| {
523+// if slam(ctx, lth.clone(), cell(a.clone(), b.clone())) == ctx.nouns.some_y {
524+// Ordering::Less
525+// } else if slam(ctx, lth.clone(), cell(b.clone(), a.clone())) == ctx.nouns.some_y {
526+// Ordering::Greater
527+// } else {
528+// Ordering::Equal
529+// }
530+// });
502531
503− Noun::list_refs(v.iter().cloned())
504−};
532+// Some(Noun::list_refs(v.iter().cloned()))
533+// };
505534
506535static SPIN: Jet = |ctx, n| {
507536 let (list, b) = n.as_cell().unwrap();
@@ -510,12 +539,12 @@ static SPIN: Jet = |ctx, n| {
510539 let mut res = Vec::new();
511540
512541 for n in list.list_iter() {
513− let (el, new_acc) = slam(ctx, gate.clone(), cell(n, acc)).as_cell().unwrap();
542+ let (el, new_acc) = slam(ctx, gate.clone(), cell(n, acc))?.as_cell().unwrap();
514543 acc = new_acc;
515544 res.push(el);
516545 }
517546
518− cell(Noun::list_refs(res.iter().cloned()), acc)
547+ Some(cell(Noun::list_refs(res.iter().cloned()), acc))
519548};
520549
521550static SPUN: Jet = |ctx, n| {
@@ -525,51 +554,53 @@ static SPUN: Jet = |ctx, n| {
525554 let mut acc = gate.clone().gate_sample().unwrap().as_cell().unwrap().1;
526555
527556 for n in list.list_iter() {
528− let (el, new_acc) = slam(ctx, gate.clone(), cell(n, acc)).as_cell().unwrap();
557+ let (el, new_acc) = slam(ctx, gate.clone(), cell(n, acc))?.as_cell().unwrap();
529558 acc = new_acc;
530559 res.push(el);
531560 }
532561
533− cell(Noun::list_refs(res.iter().cloned()), acc)
562+ Some(cell(Noun::list_refs(res.iter().cloned()), acc))
534563};
535564
536565static TURN: Jet = |ctx, n| {
537566 let (list, gate) = n.as_cell().unwrap();
538− Noun::list_refs(
539− list.list_iter()
540− .map(|x| slam(ctx, gate.clone(), x))
541− .collect::<Vec<_>>()
567+ Some(Noun::list_refs(
568+ traverse_iter_option(list.list_iter().map(|x| slam(ctx, gate.clone(), x)))?
542569 .iter()
543570 .cloned(),
544− )
571+ ))
545572};
546573
547574static WELD: Jet = |_ctx, n| {
548575 let (a, b) = n.as_cell().unwrap();
549576
550− Noun::list_refs(
577+ Some(Noun::list_refs(
551578 a.list_iter()
552579 .chain(b.list_iter())
553580 .collect::<Vec<_>>()
554581 .iter()
555582 .cloned(),
556− )
583+ ))
557584};
558585
559586static WELP: Jet = WELD;
560587
561588static ZING: Jet = |_ctx, n| {
562− Noun::list_refs(
589+ Some(Noun::list_refs(
563590 n.list_iter()
564591 .map(|l| l.list_iter())
565592 .flatten()
566593 .collect::<Vec<_>>()
567594 .iter()
568595 .cloned(),
569− )
596+ ))
570597};
571598
572−static BEX: Jet = |ctx, n| Rc::new(Noun::Atom(&ctx.big_uints.one << n.as_u32().unwrap()));
599+static BEX: Jet = |ctx, n| {
600+ Some(Rc::new(Noun::Atom(
601+ &ctx.big_uints.one << n.as_u32().unwrap(),
602+ )))
603+};
573604
574605static END: Jet = |ctx, n| {
575606 let (a, b) = n.as_cell().unwrap();
@@ -579,7 +610,7 @@ static END: Jet = |ctx, n| {
579610
580611 let mask = (&ctx.big_uints.one << bits) - &ctx.big_uints.one;
581612
582− Rc::new(Noun::Atom(mask & b.as_atom().unwrap()))
613+ Some(Rc::new(Noun::Atom(mask & b.as_atom().unwrap())))
583614};
584615
585616static CAN: Jet = |ctx, n| {
@@ -599,7 +630,7 @@ static CAN: Jet = |ctx, n| {
599630
600631 (acc << bits) | (mask & q.as_atom().unwrap())
601632 });
602− Rc::new(Noun::Atom(atom))
633+ Some(Rc::new(Noun::Atom(atom)))
603634};
604635
605636static CAT: Jet = |_ctx, n| {
@@ -610,9 +641,9 @@ static CAT: Jet = |_ctx, n| {
610641 let b = b.as_atom().unwrap();
611642 let c = c.as_atom().unwrap();
612643
613− Rc::new(Noun::Atom(
644+ Some(Rc::new(Noun::Atom(
614645 (c << (met(bloq, b.clone()) * 2u32.pow(bloq))) | b,
615− ))
646+ )))
616647};
617648
618649static MET: Jet = |_ctx, n| {
@@ -620,7 +651,7 @@ static MET: Jet = |_ctx, n| {
620651 let b: Atom = b.as_atom().unwrap().clone();
621652 let bloq = bloq.as_u32().unwrap();
622653
623− Rc::new(Noun::from_u32(met(bloq, b)))
654+ Some(Rc::new(Noun::from_u32(met(bloq, b))))
624655};
625656
626657fn met(bloq: u32, mut a: Atom) -> u32 {
@@ -645,9 +676,9 @@ static CUT: Jet = |ctx, n| {
645676
646677 let mask = (&ctx.big_uints.one << (bits * c.as_u32().unwrap())) - &ctx.big_uints.one;
647678
648− Rc::new(Noun::Atom(
679+ Some(Rc::new(Noun::Atom(
649680 (d.as_atom().unwrap() >> (bits * b.as_u32().unwrap())) & mask,
650− ))
681+ )))
651682};
652683
653684static FIL: Jet = |ctx, n| {
@@ -666,7 +697,7 @@ static FIL: Jet = |ctx, n| {
666697 target = (target << bits) | &src;
667698 }
668699
669− Rc::new(Noun::Atom(target))
700+ Some(Rc::new(Noun::Atom(target)))
670701};
671702
672703static LSH: Jet = |_ctx, n| {
@@ -674,7 +705,7 @@ static LSH: Jet = |_ctx, n| {
674705 let a = a.as_bite().unwrap();
675706 let b = b.as_atom().unwrap();
676707
677− Rc::new(Noun::Atom(b << a.bits()))
708+ Some(Rc::new(Noun::Atom(b << a.bits())))
678709};
679710
680711static RSH: Jet = |_ctx, n| {
@@ -682,7 +713,7 @@ static RSH: Jet = |_ctx, n| {
682713 let a = a.as_bite().unwrap();
683714 let b = b.as_atom().unwrap();
684715
685− Rc::new(Noun::Atom(b >> a.bits()))
716+ Some(Rc::new(Noun::Atom(b >> a.bits())))
686717};
687718
688719static RAP: Jet = |ctx, n| {
@@ -699,7 +730,7 @@ static RAP: Jet = |ctx, n| {
699730 }
700731 }
701732
702− Rc::new(Noun::Atom(target))
733+ Some(Rc::new(Noun::Atom(target)))
703734};
704735
705736static REP: Jet = |ctx, n| {
@@ -715,7 +746,7 @@ static REP: Jet = |ctx, n| {
715746 target = (target << bits) | (el.as_atom().unwrap() & &mask);
716747 }
717748
718− Rc::new(Noun::Atom(target))
749+ Some(Rc::new(Noun::Atom(target)))
719750};
720751
721752static REV: Jet = |ctx, n| {
@@ -735,7 +766,7 @@ static REV: Jet = |ctx, n| {
735766 dat = dat >> bits;
736767 }
737768
738− Rc::new(Noun::Atom(target))
769+ Some(Rc::new(Noun::Atom(target)))
739770};
740771
741772static RIP: Jet = |ctx, n| {
@@ -753,7 +784,7 @@ static RIP: Jet = |ctx, n| {
753784 b = b >> bits;
754785 }
755786
756− Noun::list_refs(target.iter().cloned())
787+ Some(Noun::list_refs(target.iter().cloned()))
757788};
758789
759790static RUN: Jet = |ctx, n| {
@@ -770,14 +801,14 @@ static RUN: Jet = |ctx, n| {
770801
771802 while b > ctx.big_uints.zero {
772803 target = (target << bits)
773− | ((*slam(ctx, gate.clone(), Rc::new(Noun::Atom(&mask & &b))))
804+ | ((*slam(ctx, gate.clone(), Rc::new(Noun::Atom(&mask & &b)))?)
774805 .as_atom()
775806 .unwrap()
776807 & &mask);
777808 b = b >> bits;
778809 }
779810
780− Rc::new(Noun::Atom(target))
811+ Some(Rc::new(Noun::Atom(target)))
781812};
782813
783814static RUT: Jet = |ctx, n| {
@@ -794,7 +825,7 @@ static RUT: Jet = |ctx, n| {
794825
795826 while b > ctx.big_uints.zero {
796827 target.push(
797− (*slam(ctx, gate.clone(), Rc::new(Noun::Atom(&mask & &b))))
828+ (*slam(ctx, gate.clone(), Rc::new(Noun::Atom(&mask & &b)))?)
798829 .as_atom()
799830 .unwrap()
800831 & &mask,
@@ -802,7 +833,7 @@ static RUT: Jet = |ctx, n| {
802833 b = b >> bits;
803834 }
804835
805− Noun::list(target.iter().cloned().map(Noun::Atom))
836+ Some(Noun::list(target.iter().cloned().map(Noun::Atom)))
806837};
807838
808839static SEW: Jet = |ctx, n| {
@@ -823,7 +854,7 @@ static SEW: Jet = |ctx, n| {
823854
824855 let target = (recipient ^ apendix) | (donor & mask);
825856
826− Rc::new(Noun::Atom(target))
857+ Some(Rc::new(Noun::Atom(target)))
827858};
828859
829860static SWP: Jet = |ctx, n| {
@@ -840,7 +871,7 @@ static SWP: Jet = |ctx, n| {
840871 source = source >> bits;
841872 }
842873
843− Rc::new(Noun::Atom(target))
874+ Some(Rc::new(Noun::Atom(target)))
844875};
845876
846877static XEB: Jet = |_ctx, n| {
@@ -853,7 +884,7 @@ static XEB: Jet = |_ctx, n| {
853884 c += 1;
854885 }
855886
856− Rc::new(Noun::from_u32(c))
887+ Some(Rc::new(Noun::from_u32(c)))
857888};
858889
859890static CON: Jet = |_ctx, n| BINARY_ATOM(n, |a, b| a | b);
@@ -870,5 +901,5 @@ static NOT: Jet = |ctx, n| {
870901
871902 let target = c.as_atom().unwrap() ^ &mask;
872903
873− Rc::new(Noun::Atom(target))
904+ Some(Rc::new(Noun::Atom(target)))
874905};
nock/src/main.rs+1−1
@@ -13,7 +13,7 @@ fn main() {
1313
1414 let gate = cue_bytes(&jammed_input);
1515
16− let result = eval_gate(&generate_interpreter_context(), gate);
16+ let result = eval_gate(&generate_interpreter_context(), gate).unwrap();
1717
1818 println!("{result}");
1919}