on master help sign in
refs
284c591iko
nock/src/interpreter.rs+59−56
@@ -1,3 +1,4 @@
1+use std::borrow::Borrow;
1use std::rc::Rc;
2use std::rc::Rc;
2
3
3use num_bigint::BigUint;
4use num_bigint::BigUint;
@@ -67,34 +68,34 @@ pub fn generate_interpreter_context() -> InterpreterContext {
67 }
68 }
68}
69}
69
70
70−fn wut(ctx: &InterpreterContext, noun: &Noun) -> Rc<Noun> {
71+fn wut<'a>(ctx: &'a InterpreterContext, noun: &Noun) -> &'a Rc<Noun> {
71 match noun {
72 match noun {
72− Noun::Cell { .. } => ctx.nouns.sig.clone(),
73+ Noun::Cell { .. } => &ctx.nouns.sig,
73− Noun::Atom(_) => ctx.nouns.one.clone(),
74+ Noun::Atom(_) => &ctx.nouns.one,
74 }
75 }
75}
76}
76
77
77fn lus(noun: &Noun) -> Option<Noun> {
78fn lus(noun: &Noun) -> Option<Noun> {
78− match (*noun).clone() {
79+ match noun {
79 Noun::Cell { .. } => None,
80 Noun::Cell { .. } => None,
80 Noun::Atom(atm) => Some(Noun::Atom(atm + 1u32)),
81 Noun::Atom(atm) => Some(Noun::Atom(atm + 1u32)),
81 }
82 }
82}
83}
83
84
84−fn tis(ctx: &InterpreterContext, lhs: &Noun, rhs: &Noun) -> Rc<Noun> {
85+fn tis<'a>(ctx: &'a InterpreterContext, lhs: &Noun, rhs: &Noun) -> &'a Rc<Noun> {
85 if lhs == rhs {
86 if lhs == rhs {
86− ctx.nouns.sig.clone()
87+ &ctx.nouns.sig
87 } else {
88 } else {
88− ctx.nouns.one.clone()
89+ &ctx.nouns.one
89 }
90 }
90}
91}
91
92
92fn fas(ctx: &InterpreterContext, addr: &Atom, noun: &Noun) -> Option<Rc<Noun>> {
93fn fas(ctx: &InterpreterContext, addr: &Atom, noun: &Noun) -> Option<Rc<Noun>> {
93 let mut addr_iter = addr.iter_u32_digits();
94 let mut addr_iter = addr.iter_u32_digits();
94
95
95− match addr_iter.len() {
96+ match (addr_iter.next(), addr_iter.next()) {
96− 0 => None,
97+ (None, _) => None,
97− 1 => Some(fas_u32(addr_iter.next()?, noun)?),
98+ (Some(x), None) => fas_u32(x, noun),
98 _ => {
99 _ => {
99 let rest = fas(ctx, &(addr >> 1u8), noun)?;
100 let rest = fas(ctx, &(addr >> 1u8), noun)?;
100 Some(fas_u32(
101 Some(fas_u32(
@@ -113,13 +114,13 @@ fn fas_u32(addr: u32, noun: &Noun) -> Option<Rc<Noun>> {
113 match addr {
114 match addr {
114 0 => None,
115 0 => None,
115 1 => Some(Rc::new(noun.clone())),
116 1 => Some(Rc::new(noun.clone())),
116− n => match noun {
117+ n => match noun.borrow() {
117 Noun::Atom(_) => None,
118 Noun::Atom(_) => None,
118 Noun::Cell { p, q, .. } => match n {
119 Noun::Cell { p, q, .. } => match n {
119 2 => Some(p.clone()),
120 2 => Some(p.clone()),
120 3 => Some(q.clone()),
121 3 => Some(q.clone()),
121 _ => {
122 _ => {
122− let rest = fas_u32(n >> 1, &naked_cell(&p, &q))?;
123+ let rest = fas_u32(n >> 1, &cell(p, q))?;
123 fas_u32(if (n & 1) == 1 { 3 } else { 2 }, &rest)
124 fas_u32(if (n & 1) == 1 { 3 } else { 2 }, &rest)
124 }
125 }
125 },
126 },
@@ -127,65 +128,67 @@ fn fas_u32(addr: u32, noun: &Noun) -> Option<Rc<Noun>> {
127 }
128 }
128}
129}
129
130
130−fn hax_u32(addr: u32, new_value: Rc<Noun>, target: Rc<Noun>) -> Option<Rc<Noun>> {
131+fn hax_u32(addr: u32, new_value: &Rc<Noun>, target: &Rc<Noun>) -> Option<Rc<Noun>> {
131 match addr {
132 match addr {
132 0 => None,
133 0 => None,
133− 1 => Some(new_value),
134+ 1 => Some(new_value.clone()),
134− _ => hax_u32(
135+ _ => {
135− addr >> 1,
136− if (addr & 1) == 1 {
136+ let new_value = if (addr & 1) == 1 {
137 let foo = fas_u32(addr - 1, &target)?;
137 let foo = fas_u32(addr - 1, &target)?;
138− cell(&foo, &new_value)
138+ &cell(&foo, &new_value)
139 } else {
139 } else {
140 let foo = fas_u32(addr + 1, &target)?;
140 let foo = fas_u32(addr + 1, &target)?;
141− cell(&new_value, &foo)
141+ &cell(&new_value, &foo)
142− },
142+ };
143− target,
143+ hax_u32(addr >> 1, new_value, target)
144− ),
144+ }
145 }
145 }
146}
146}
147
147
148fn hax(
148fn hax(
149 ctx: &InterpreterContext,
149 ctx: &InterpreterContext,
150− addr: Atom,
150+ addr: &Atom,
151− new_value: Rc<Noun>,
151+ new_value: &Rc<Noun>,
152− target: Rc<Noun>,
152+ target: &Rc<Noun>,
153) -> Option<Rc<Noun>> {
153) -> Option<Rc<Noun>> {
154 let mut addr_iter = addr.iter_u32_digits();
154 let mut addr_iter = addr.iter_u32_digits();
155
155
156− match addr_iter.len() {
156+ match (addr_iter.next(), addr_iter.next()) {
157− 0 => None,
157+ (None, _) => None,
158− 1 => hax_u32(addr_iter.next().expect("invariant"), new_value, target),
158+ (Some(x), None) => hax_u32(x, new_value, target),
159 _ => hax(
159 _ => hax(
160 ctx,
160 ctx,
161− &addr >> 1u32,
161+ &(addr >> 1u32),
162− if (&addr & &ctx.big_uints.one) == ctx.big_uints.one {
162+ &(if (addr & &ctx.big_uints.one) == ctx.big_uints.one {
163 let foo = fas(ctx, &(addr - &ctx.big_uints.one), &target)?;
163 let foo = fas(ctx, &(addr - &ctx.big_uints.one), &target)?;
164− cell(&foo, &new_value)
164+ cell(&foo, new_value)
165 } else {
165 } else {
166 let foo = fas(ctx, &(addr + &ctx.big_uints.one), &target)?;
166 let foo = fas(ctx, &(addr + &ctx.big_uints.one), &target)?;
167 cell(&new_value, &foo)
167 cell(&new_value, &foo)
168− },
168+ }),
169 target,
169 target,
170 ),
170 ),
171 }
171 }
172}
172}
173
173
174+fn tar_u32<'a>(
174−fn tar_u32(ctx: &InterpreterContext, subj: &Noun, op: u32, formula: Rc<Noun>) -> Option<Rc<Noun>> {
175+ ctx: &InterpreterContext,
176+ subj: &'a Noun,
177+ op: u32,
178+ formula: &'a Rc<Noun>,
179+) -> Option<Rc<Noun>> {
175 match op {
180 match op {
176 0 => {
181 0 => {
177− let b = formula.as_atom()?.clone();
182+ let b = formula.as_atom()?;
178− fas(ctx, &b, subj)
183+ fas(ctx, b, subj)
179 }
184 }
180− 1 => Some(formula),
185+ 1 => Some(formula.clone()),
181 2 => {
186 2 => {
182 let (b, c) = formula.as_cell()?;
187 let (b, c) = formula.as_cell()?;
183
188
184− match (*c).clone() {
189+ match c.borrow() {
185 Noun::Cell { p, q, .. }
190 Noun::Cell { p, q, .. }
186− if *p == Noun::SIG
187− && q == ctx.nouns.two
191+ if **p == Noun::SIG && *q == ctx.nouns.two && *b == ctx.nouns.sig_one =>
188− && b == cell(&Noun::SIG, &ctx.nouns.one) =>
189 {
192 {
190 // This means we are about the evaluate a gate at the head of the current subject.
193 // This means we are about the evaluate a gate at the head of the current subject.
191 let (hash, sample) = subj.hash_gate();
194 let (hash, sample) = subj.hash_gate();
@@ -214,7 +217,7 @@ fn tar_u32(ctx: &InterpreterContext, subj: &Noun, op: u32, formula: Rc<Noun>) ->
214 }
217 }
215 3 => {
218 3 => {
216 let foo = tar(ctx, subj, &formula)?;
219 let foo = tar(ctx, subj, &formula)?;
217− Some(wut(ctx, &foo))
220+ Some(wut(ctx, &foo).clone())
218 }
221 }
219 4 => {
222 4 => {
220 let foo = tar(ctx, subj, &formula)?;
223 let foo = tar(ctx, subj, &formula)?;
@@ -224,7 +227,7 @@ fn tar_u32(ctx: &InterpreterContext, subj: &Noun, op: u32, formula: Rc<Noun>) ->
224 let (b, c) = formula.as_cell()?;
227 let (b, c) = formula.as_cell()?;
225 let foo = tar(ctx, &subj, &b)?;
228 let foo = tar(ctx, &subj, &b)?;
226 let bar = tar(ctx, subj, &c)?;
229 let bar = tar(ctx, subj, &c)?;
227− Some(tis(ctx, &foo, &bar))
230+ Some(tis(ctx, &foo, &bar).clone())
228 }
231 }
229 6 => {
232 6 => {
230 let (b, c) = formula.as_cell()?;
233 let (b, c) = formula.as_cell()?;
@@ -234,11 +237,11 @@ fn tar_u32(ctx: &InterpreterContext, subj: &Noun, op: u32, formula: Rc<Noun>) ->
234 ctx,
237 ctx,
235 &cell(&c, &d),
238 &cell(&c, &d),
236 0,
239 0,
237− tar_u32(
240+ &tar_u32(
238 ctx,
241 ctx,
239 &ctx.nouns.two_three,
242 &ctx.nouns.two_three,
240 0,
243 0,
241− tar_u32(ctx, subj, 4, cell(&ctx.nouns.four, &b))?,
244+ &tar_u32(ctx, subj, 4, &cell(&ctx.nouns.four, &b))?,
242 )?,
245 )?,
243 )?;
246 )?;
244
247
@@ -252,7 +255,7 @@ fn tar_u32(ctx: &InterpreterContext, subj: &Noun, op: u32, formula: Rc<Noun>) ->
252 8 => {
255 8 => {
253 let (b, c) = formula.as_cell()?;
256 let (b, c) = formula.as_cell()?;
254 let foo = tar(ctx, &subj, &b)?;
257 let foo = tar(ctx, &subj, &b)?;
255− tar(ctx, &cell(&foo, subj), &c)
258+ tar(ctx, &cell(&foo, &Rc::new(subj.clone())), &c)
256 }
259 }
257 9 => {
260 9 => {
258 let (b, c) = formula.as_cell()?;
261 let (b, c) = formula.as_cell()?;
@@ -261,7 +264,7 @@ fn tar_u32(ctx: &InterpreterContext, subj: &Noun, op: u32, formula: Rc<Noun>) ->
261 ctx,
264 ctx,
262 &foo,
265 &foo,
263 2,
266 2,
264− cell(&ctx.nouns.sig_one, &cell(&ctx.nouns.sig, &b)),
267+ &cell(&ctx.nouns.sig_one, &cell(&ctx.nouns.sig, &b)),
265 )
268 )
266 }
269 }
267 10 => {
270 10 => {
@@ -269,17 +272,17 @@ fn tar_u32(ctx: &InterpreterContext, subj: &Noun, op: u32, formula: Rc<Noun>) ->
269 let (b, c) = b.as_cell()?;
272 let (b, c) = b.as_cell()?;
270 let b = b.as_atom()?;
273 let b = b.as_atom()?;
271
274
272− hax(ctx, b.clone(), tar(ctx, subj, &c)?, tar(ctx, subj, &d)?)
275+ hax(ctx, b, &tar(ctx, subj, &c)?, &tar(ctx, subj, &d)?)
273 }
276 }
274 11 => {
277 11 => {
275 let (b, d) = formula.as_cell()?;
278 let (b, d) = formula.as_cell()?;
276 // println!("{b}");
279 // println!("{b}");
277− match (*b).clone() {
280+ match b.borrow() {
278 Noun::Atom(_) => tar(ctx, subj, &d),
281 Noun::Atom(_) => tar(ctx, subj, &d),
279 Noun::Cell { q: c, .. } => {
282 Noun::Cell { q: c, .. } => {
280 let foo = tar(ctx, subj, &c)?;
283 let foo = tar(ctx, subj, &c)?;
281 let bar = tar(ctx, subj, &d)?;
284 let bar = tar(ctx, subj, &d)?;
282− tar_u32(ctx, &cell(&foo, &bar), 0, ctx.nouns.three.clone())
285+ tar_u32(ctx, &cell(&foo, &bar), 0, &ctx.nouns.three)
283 }
286 }
284 }
287 }
285 }
288 }
@@ -287,9 +290,9 @@ fn tar_u32(ctx: &InterpreterContext, subj: &Noun, op: u32, formula: Rc<Noun>) ->
287 }
290 }
288}
291}
289
292
290−pub fn tar(ctx: &InterpreterContext, subj: &Noun, formula: &Noun) -> Option<Rc<Noun>> {
293+pub fn tar<'a>(ctx: &InterpreterContext, subj: &'a Noun, formula: &'a Noun) -> Option<Rc<Noun>> {
291 let (op, formula) = formula.as_cell()?;
294 let (op, formula) = formula.as_cell()?;
292− match *op {
295+ match op.borrow() {
293 Noun::Cell { .. } => {
296 Noun::Cell { .. } => {
294 let foo = tar(ctx, subj, &op)?;
297 let foo = tar(ctx, subj, &op)?;
295 let bar = tar(ctx, subj, &formula)?;
298 let bar = tar(ctx, subj, &formula)?;
@@ -303,25 +306,25 @@ pub fn tar(ctx: &InterpreterContext, subj: &Noun, formula: &Noun) -> Option<Rc<N
303 _ => None,
306 _ => None,
304 };
307 };
305 let op = op?;
308 let op = op?;
306− stacker::maybe_grow(32 * 1024, 1024 * 1024, || tar_u32(ctx, &subj, op, formula))
309+ stacker::maybe_grow(32 * 1024, 1024 * 1024, || tar_u32(ctx, subj, op, formula))
307 }
310 }
308 }
311 }
309}
312}
310
313
311−pub fn eval_gate(ctx: &InterpreterContext, gate: Rc<Noun>) -> Option<Rc<Noun>> {
314+pub fn eval_gate(ctx: &InterpreterContext, gate: &Rc<Noun>) -> Option<Rc<Noun>> {
312 tar(
315 tar(
313 ctx,
316 ctx,
314 &gate,
317 &gate,
315 &cell(
318 &cell(
316− &Noun::Atom(BigUint::new(vec![9])),
319+ &Rc::new(Noun::Atom(BigUint::new(vec![9]))),
317 &cell(&ctx.nouns.two, &cell(&ctx.nouns.sig, &ctx.nouns.one)),
320 &cell(&ctx.nouns.two, &cell(&ctx.nouns.sig, &ctx.nouns.one)),
318 ),
321 ),
319 )
322 )
320}
323}
321
324
322−pub fn slam(ctx: &InterpreterContext, gate: Rc<Noun>, sample: Rc<Noun>) -> Option<Rc<Noun>> {
325+pub fn slam(ctx: &InterpreterContext, gate: &Rc<Noun>, sample: &Rc<Noun>) -> Option<Rc<Noun>> {
323 let (battery, payload) = gate.as_cell()?;
326 let (battery, payload) = gate.as_cell()?;
324 let (_sample, context) = payload.as_cell()?;
327 let (_sample, context) = payload.as_cell()?;
325
328
326− eval_gate(ctx, cell(&battery, &cell(&sample, &context)))
329+ eval_gate(ctx, &cell(battery, &cell(sample, context)))
327}
330}
nock/src/jets.rs+53−64
@@ -108,20 +108,20 @@ pub fn generate_jets() -> Jets {
108 ])
108 ])
109}
109}
110
110
111−pub type Jet = fn(ctx: &InterpreterContext, Rc<Noun>) -> Option<Rc<Noun>>;
111+pub type Jet = fn(ctx: &InterpreterContext, &Rc<Noun>) -> Option<Rc<Noun>>;
112−pub type DoubleJet = fn(ctx: &InterpreterContext, Rc<Noun>, Rc<Noun>) -> Option<Rc<Noun>>;
112+pub type DoubleJet = fn(ctx: &InterpreterContext, &Rc<Noun>, &Rc<Noun>) -> Option<Rc<Noun>>;
113
113
114−static BINARY_ATOM: fn(Rc<Noun>, fn(&Atom, &Atom) -> Atom) -> Option<Rc<Noun>> =
114+static BINARY_ATOM: fn(&Rc<Noun>, fn(&Atom, &Atom) -> Atom) -> Option<Rc<Noun>> =
115− |n: Rc<Noun>, f: fn(&Atom, &Atom) -> Atom| {
115+ |n: &Rc<Noun>, f: fn(&Atom, &Atom) -> Atom| {
116 let (p, q) = n.as_cell()?;
116 let (p, q) = n.as_cell()?;
117 Some(Rc::new(Noun::Atom(f(p.as_atom()?, q.as_atom()?))))
117 Some(Rc::new(Noun::Atom(f(p.as_atom()?, q.as_atom()?))))
118 };
118 };
119
119
120static BINARY_ATOM_LOOB: fn(
120static BINARY_ATOM_LOOB: fn(
121 &InterpreterContext,
121 &InterpreterContext,
122− Rc<Noun>,
122+ &Rc<Noun>,
123 fn(&Atom, &Atom) -> bool,
123 fn(&Atom, &Atom) -> bool,
124−) -> Option<Rc<Noun>> = |ctx: &InterpreterContext, n: Rc<Noun>, f: 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()?;
125 let (p, q) = n.as_cell()?;
126
126
127 if f(p.as_atom()?, q.as_atom()?) {
127 if f(p.as_atom()?, q.as_atom()?) {
@@ -131,12 +131,12 @@ static BINARY_ATOM_LOOB: fn(
131 }
131 }
132};
132};
133
133
134−static BINARY_ATOM_PAIR: fn(Rc<Noun>, fn(&Atom, &Atom) -> (Atom, Atom)) -> Option<Rc<Noun>> =
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)| {
135+ |n: &Rc<Noun>, f: fn(&Atom, &Atom) -> (Atom, Atom)| {
136 let (p, q) = n.as_cell()?;
136 let (p, q) = n.as_cell()?;
137
137
138 let (a, b) = f(p.as_atom()?, q.as_atom()?);
138 let (a, b) = f(p.as_atom()?, q.as_atom()?);
139− Some(cell(&Noun::Atom(a), &Noun::Atom(b)))
139+ Some(cell(&Rc::new(Noun::Atom(a)), &Rc::new(Noun::Atom(b))))
140 };
140 };
141
141
142static ADD: Jet = |_ctx, n| BINARY_ATOM(n, |a, b| a + b);
142static ADD: Jet = |_ctx, n| BINARY_ATOM(n, |a, b| a + b);
@@ -231,7 +231,7 @@ static FAND: Jet = |ctx, n| {
231 return Some(ctx.nouns.sig.clone());
231 return Some(ctx.nouns.sig.clone());
232 }
232 }
233
233
234− let nedl: Vec<Rc<Noun>> = nedl.list_iter().collect();
234+ let nedl: Vec<&Rc<Noun>> = nedl.list_iter().collect();
235
235
236 let mut result: Vec<u32> = Vec::new();
236 let mut result: Vec<u32> = Vec::new();
237
237
@@ -261,7 +261,7 @@ static FIND: Jet = |ctx, n| {
261 return Some(ctx.nouns.sig.clone());
261 return Some(ctx.nouns.sig.clone());
262 }
262 }
263
263
264− let nedl: Vec<Rc<Noun>> = nedl.list_iter().collect();
264+ let nedl: Vec<&Rc<Noun>> = nedl.list_iter().collect();
265
265
266 let mut iter = zip(0.., hstk.list_iter());
266 let mut iter = zip(0.., hstk.list_iter());
267
267
@@ -328,7 +328,7 @@ static INTO: Jet = |_ctx, n| {
328 .chain(l.skip(b))
328 .chain(l.skip(b))
329 .collect::<Vec<_>>()
329 .collect::<Vec<_>>()
330 .iter()
330 .iter()
331− .map(|x| x.clone()),
331+ .map(|x| *x),
332 ))
332 ))
333 }
333 }
334 _ => Some(Noun::list_refs(
334 _ => Some(Noun::list_refs(
@@ -360,7 +360,7 @@ static LENT: Jet = |_ctx, n| {
360
360
361static LEVY: Jet = |ctx, n| {
361static LEVY: Jet = |ctx, n| {
362 let (a, b) = n.as_cell()?;
362 let (a, b) = n.as_cell()?;
363− if traverse_iter_option(a.list_iter().map(|n| slam(ctx, b.clone(), n)))?
363+ if traverse_iter_option(a.list_iter().map(|n| slam(ctx, b, n)))?
364 .iter()
364 .iter()
365 .all(|x| x.is_y())
365 .all(|x| x.is_y())
366 {
366 {
@@ -372,7 +372,7 @@ static LEVY: Jet = |ctx, n| {
372
372
373static LIEN: Jet = |ctx, n| {
373static LIEN: Jet = |ctx, n| {
374 let (a, b) = n.as_cell()?;
374 let (a, b) = n.as_cell()?;
375− if traverse_iter_option(a.list_iter().map(|n| slam(ctx, b.clone(), n)))?
375+ if traverse_iter_option(a.list_iter().map(|n| slam(ctx, b, n)))?
376 .iter()
376 .iter()
377 .any(|x| x.is_y())
377 .any(|x| x.is_y())
378 {
378 {
@@ -387,10 +387,9 @@ static MURN: Jet = |ctx, n| {
387
387
388 Some(Noun::list_refs(
388 Some(Noun::list_refs(
389 a.list_iter()
389 a.list_iter()
390− .filter_map(|n| slam(ctx, b.clone(), n)?.as_unit())
390+ .filter_map(|n| slam(ctx, b, n)?.as_unit().cloned())
391 .collect::<Vec<_>>()
391 .collect::<Vec<_>>()
392− .iter()
392+ .iter(),
393− .map(|x| x.clone()),
394 ))
393 ))
395};
394};
396
395
@@ -400,16 +399,16 @@ static REAP: Jet = |_ctx, n| {
400 Some(Noun::list_refs(repeat_n(b, a.as_u32().unwrap() as usize)))
399 Some(Noun::list_refs(repeat_n(b, a.as_u32().unwrap() as usize)))
401};
400};
402
401
403−static REAR: Jet = |_ctx, n| n.list_iter().last();
402+static REAR: Jet = |_ctx, n| n.list_iter().last().cloned();
404
403
405static REEL: Jet = |ctx, n| {
404static REEL: Jet = |ctx, n| {
406 let (list, gate) = n.as_cell()?;
405 let (list, gate) = n.as_cell()?;
407
406
408 list.list_iter().collect::<Vec<_>>().iter().rfold(
407 list.list_iter().collect::<Vec<_>>().iter().rfold(
409− Some(gate.clone().gate_sample()?.as_cell()?.1),
408+ Some(gate.gate_sample()?.as_cell()?.1.clone()),
410 |acc, next| {
409 |acc, next| {
411 let acc = acc?;
410 let acc = acc?;
412− slam(ctx, gate.clone(), cell(&next, &acc))
411+ slam(ctx, gate, &cell(&next, &acc))
413 },
412 },
414 )
413 )
415};
414};
@@ -418,10 +417,10 @@ static ROLL: Jet = |ctx, n| {
418 let (list, gate) = n.as_cell()?;
417 let (list, gate) = n.as_cell()?;
419
418
420 list.list_iter().fold(
419 list.list_iter().fold(
421− Some(gate.clone().gate_sample()?.as_cell()?.1),
420+ Some(gate.clone().gate_sample()?.as_cell()?.1.clone()),
422 |acc, next| {
421 |acc, next| {
423 let acc = acc?;
422 let acc = acc?;
424− slam(ctx, gate.clone(), cell(&next, &acc))
423+ slam(ctx, gate, &cell(&next, &acc))
425 },
424 },
426 )
425 )
427};
426};
@@ -441,10 +440,7 @@ static SCAG: Jet = |_ctx, n| {
441static SKID: Jet = |ctx, n| {
440static SKID: Jet = |ctx, n| {
442 let (list, gate) = n.as_cell()?;
441 let (list, gate) = n.as_cell()?;
443
442
444− let slammed_n = traverse_iter_option(
443+ let slammed_n = traverse_iter_option(list.list_iter().map(|n| Some((slam(ctx, gate, n)?, n))))?;
445− list.list_iter()
446− .map(|n| Some((slam(ctx, gate.clone(), n.clone())?, n))),
447− )?;
448 let (ys, ns): (Vec<_>, _) = slammed_n.iter().partition(|(l, _)| l.is_y());
444 let (ys, ns): (Vec<_>, _) = slammed_n.iter().partition(|(l, _)| l.is_y());
449
445
450 Some(cell(
446 Some(cell(
@@ -457,14 +453,10 @@ static SKIM: Jet = |ctx, n| {
457 let (list, gate) = n.as_cell()?;
453 let (list, gate) = n.as_cell()?;
458
454
459 Some(Noun::list_refs(
455 Some(Noun::list_refs(
460− traverse_iter_option(
456+ traverse_iter_option(list.list_iter().map(|n| Some((slam(ctx, gate, n)?, n))))?
461− list.list_iter()
462− .map(|n| Some((slam(ctx, gate.clone(), n.clone())?, n))),
463− )?
464− .iter()
457+ .iter()
465− .filter(|(l, _)| l.is_y())
458+ .filter(|(l, _)| l.is_y())
466− .map(|(_, x)| x)
459+ .map(|(_, x)| *x),
467− .cloned(),
468 ))
460 ))
469};
461};
470
462
@@ -472,14 +464,11 @@ static SKIP: Jet = |ctx, n| {
472 let (list, gate) = n.as_cell()?;
464 let (list, gate) = n.as_cell()?;
473
465
474 Some(Noun::list_refs(
466 Some(Noun::list_refs(
475− traverse_iter_option(
467+ traverse_iter_option(list.list_iter().map(|n| Some((slam(ctx, gate, n)?, n))))?
476− list.list_iter()
477− .map(|n| Some((slam(ctx, gate.clone(), n.clone())?, n))),
478− )?
479− .iter()
468+ .iter()
480− .filter(|(l, _)| l.is_y())
469+ .filter(|(l, _)| l.is_y())
481− .map(|(_, x)| x)
470+ .map(|(_, x)| x)
482− .cloned(),
471+ .cloned(),
483 ))
472 ))
484};
473};
485
474
@@ -489,7 +478,7 @@ static SLAG: Jet = |ctx, n| {
489 let mut a_iter = a.as_atom()?.iter_u32_digits();
478 let mut a_iter = a.as_atom()?.iter_u32_digits();
490
479
491 match a_iter.len() {
480 match a_iter.len() {
492− 0 => Some(list),
481+ 0 => Some(list.clone()),
493 1 => Some(Noun::list_refs(
482 1 => Some(Noun::list_refs(
494 list.list_iter()
483 list.list_iter()
495 .skip(a_iter.next().unwrap() as usize)
484 .skip(a_iter.next().unwrap() as usize)
@@ -504,7 +493,7 @@ static SLAG: Jet = |ctx, n| {
504static SNAG: Jet = |_ctx, n| {
493static SNAG: Jet = |_ctx, n| {
505 let (a, list) = n.as_cell()?;
494 let (a, list) = n.as_cell()?;
506
495
507− list.list_iter().nth(a.as_u32().unwrap() as usize)
496+ list.list_iter().nth(a.as_u32().unwrap() as usize).cloned()
508};
497};
509
498
510static SNIP: Jet = |_ctx, n| {
499static SNIP: Jet = |_ctx, n| {
@@ -551,40 +540,41 @@ static SNOC: Jet = |_ctx, n| {
551
540
552static SPIN: Jet = |ctx, n| {
541static SPIN: Jet = |ctx, n| {
553 let (list, b) = n.as_cell()?;
542 let (list, b) = n.as_cell()?;
554− let (mut acc, gate) = b.as_cell()?;
543+ let (acc, gate) = b.as_cell()?;
555
544
556 let mut res = Vec::new();
545 let mut res = Vec::new();
546+ let mut acc = acc.clone();
557
547
558 for n in list.list_iter() {
548 for n in list.list_iter() {
559− let (el, new_acc) = slam(ctx, gate.clone(), cell(&n, &acc))?.as_cell()?;
549+ let foo = slam(ctx, gate, &cell(&n, &acc))?;
550+ let (el, new_acc) = foo.as_cell()?;
560− acc = new_acc;
551+ acc = new_acc.clone();
561− res.push(el);
552+ res.push(el.clone());
562 }
553 }
563
554
564− Some(cell(&Noun::list_refs(res.iter().cloned()), &acc))
555+ Some(cell(&Noun::list_refs(res.iter()), &acc))
565};
556};
566
557
567static SPUN: Jet = |ctx, n| {
558static SPUN: Jet = |ctx, n| {
568 let (list, gate) = n.as_cell()?;
559 let (list, gate) = n.as_cell()?;
569
560
570 let mut res = Vec::new();
561 let mut res = Vec::new();
571− let mut acc = gate.clone().gate_sample()?.as_cell()?.1;
562+ let mut acc = gate.gate_sample()?.as_cell()?.1.clone();
572
563
573 for n in list.list_iter() {
564 for n in list.list_iter() {
574− let (el, new_acc) = slam(ctx, gate.clone(), cell(&n, &acc))?.as_cell()?;
565+ let foo = slam(ctx, gate, &cell(&n, &acc))?;
566+ let (el, new_acc) = foo.as_cell()?;
575− acc = new_acc;
567+ acc = new_acc.clone();
576− res.push(el);
568+ res.push(el.clone());
577 }
569 }
578
570
579− Some(cell(&Noun::list_refs(res.iter().cloned()), &acc))
571+ Some(cell(&Noun::list_refs(res.iter()), &acc))
580};
572};
581
573
582static TURN: Jet = |ctx, n| {
574static TURN: Jet = |ctx, n| {
583 let (list, gate) = n.as_cell()?;
575 let (list, gate) = n.as_cell()?;
584 Some(Noun::list_refs(
576 Some(Noun::list_refs(
585− traverse_iter_option(list.list_iter().map(|x| slam(ctx, gate.clone(), x)))?
577+ traverse_iter_option(list.list_iter().map(|x| slam(ctx, gate, x)))?.iter(),
586− .iter()
587− .cloned(),
588 ))
578 ))
589};
579};
590
580
@@ -791,7 +781,7 @@ static RIP: Jet = |ctx, n| {
791 b = b >> bits;
781 b = b >> bits;
792 }
782 }
793
783
794− Some(Noun::list_refs(target.iter().cloned()))
784+ Some(Noun::list_refs(target.iter()))
795};
785};
796
786
797static RUN: Jet = |ctx, n| {
787static RUN: Jet = |ctx, n| {
@@ -808,7 +798,7 @@ static RUN: Jet = |ctx, n| {
808
798
809 while b > ctx.big_uints.zero {
799 while b > ctx.big_uints.zero {
810 target = (target << bits)
800 target = (target << bits)
811− | ((*slam(ctx, gate.clone(), Rc::new(Noun::Atom(&mask & &b)))?).as_atom()? & &mask);
801+ | ((*slam(ctx, gate, &Rc::new(Noun::Atom(&mask & &b)))?).as_atom()? & &mask);
812 b = b >> bits;
802 b = b >> bits;
813 }
803 }
814
804
@@ -828,8 +818,7 @@ static RUT: Jet = |ctx, n| {
828 let mut target = Vec::new();
818 let mut target = Vec::new();
829
819
830 while b > ctx.big_uints.zero {
820 while b > ctx.big_uints.zero {
831− target
832− .push((*slam(ctx, gate.clone(), Rc::new(Noun::Atom(&mask & &b)))?).as_atom()? & &mask);
821+ target.push((*slam(ctx, gate, &Rc::new(Noun::Atom(&mask & &b)))?).as_atom()? & &mask);
833 b = b >> bits;
822 b = b >> bits;
834 }
823 }
835
824
@@ -956,7 +945,7 @@ static MUK: Jet = |_ctx, n| {
956static JUST: DoubleJet = |ctx, n, m| {
945static JUST: DoubleJet = |ctx, n, m| {
957 let char = n.as_atom()?;
946 let char = n.as_atom()?;
958 let nail = m.as_nail()?;
947 let nail = m.as_nail()?;
959− if nail.rest == ctx.nouns.sig {
948+ if *nail.rest == ctx.nouns.sig {
960 Some(fail(nail).as_noun())
949 Some(fail(nail).as_noun())
961 } else {
950 } else {
962 let (i, _) = nail.rest.as_cell()?;
951 let (i, _) = nail.rest.as_cell()?;
@@ -979,8 +968,8 @@ static JUST: DoubleJet = |ctx, n, m| {
979// if vex.
968// if vex.
980// };
969// };
981
970
982−fn next(nail: Nail) -> Option<Edge> {
971+fn next<'a>(nail: Nail<'a>) -> Option<Edge<'a>> {
983− if *nail.rest == Noun::SIG {
972+ if **nail.rest == Noun::SIG {
984 Some(fail(nail))
973 Some(fail(nail))
985 } else {
974 } else {
986 let (i, t) = nail.rest.as_cell()?;
975 let (i, t) = nail.rest.as_cell()?;
nock/src/main.rs+6−6
@@ -92,7 +92,7 @@ fn main() -> Result<(), std::io::Error> {
92 NockCommand::EvalGate { gate } => {
92 NockCommand::EvalGate { gate } => {
93 let gate = read_nock(&gate).unwrap();
93 let gate = read_nock(&gate).unwrap();
94
94
95− let result = eval_gate(&generate_interpreter_context(), gate).unwrap();
95+ let result = eval_gate(&generate_interpreter_context(), &gate).unwrap();
96
96
97 println!("{result}");
97 println!("{result}");
98 }
98 }
@@ -112,7 +112,7 @@ fn interact(gate_file: PathBuf) -> Result<(), std::io::Error> {
112 let source = get_stdin().unwrap();
112 let source = get_stdin().unwrap();
113
113
114 let mut spinner = new_spinner(String::from("Slamming gate..."));
114 let mut spinner = new_spinner(String::from("Slamming gate..."));
115− let Some(slam) = slam(&generate_interpreter_context(), gate, source) else {
115+ let Some(slam) = slam(&generate_interpreter_context(), &gate, &source) else {
116 spinner.fail("Gate execution failed");
116 spinner.fail("Gate execution failed");
117 exit(1);
117 exit(1);
118 };
118 };
@@ -158,8 +158,8 @@ fn build(root: PathBuf, output: PathBuf) -> Result<(), std::io::Error> {
158
158
159 slam(
159 slam(
160 &generate_interpreter_context(),
160 &generate_interpreter_context(),
161− ream_gate,
161+ &ream_gate,
162− Rc::new(Noun::Atom(Atom::from_bytes_le(&root_source))),
162+ &Rc::new(Noun::Atom(Atom::from_bytes_le(&root_source))),
163 )
163 )
164 .unwrap()
164 .unwrap()
165 };
165 };
@@ -170,7 +170,7 @@ fn build(root: PathBuf, output: PathBuf) -> Result<(), std::io::Error> {
170 let hoon_hoon_ast_nock = include_bytes!("../res/hoon-hoon-ast.nock");
170 let hoon_hoon_ast_nock = include_bytes!("../res/hoon-hoon-ast.nock");
171 let hoon_hoon_ast = cue_bytes(hoon_hoon_ast_nock);
171 let hoon_hoon_ast = cue_bytes(hoon_hoon_ast_nock);
172 cell(
172 cell(
173− &Noun::Atom(Atom::from_bytes_le(b"tsgl")),
173+ &Rc::new(Noun::Atom(Atom::from_bytes_le(b"tsgl"))),
174 &cell(&hoon_hoon_ast, &root_ast),
174 &cell(&hoon_hoon_ast, &root_ast),
175 )
175 )
176 };
176 };
@@ -178,7 +178,7 @@ fn build(root: PathBuf, output: PathBuf) -> Result<(), std::io::Error> {
178 println!("minting");
178 println!("minting");
179
179
180 let mint_gate = cue_bytes(include_bytes!("../res/mint.nock"));
180 let mint_gate = cue_bytes(include_bytes!("../res/mint.nock"));
181− let slam_result = slam(&generate_interpreter_context(), mint_gate, ast).unwrap();
181+ let slam_result = slam(&generate_interpreter_context(), &mint_gate, &ast).unwrap();
182
182
183 // println!("{slam_result}");
183 // println!("{slam_result}");
184
184
nock/src/noun.rs+45−76
@@ -1,7 +1,6 @@
1use std::{cell::Cell, cmp::Ordering, rc::Rc, str::FromStr};
1use std::{cell::Cell, cmp::Ordering, rc::Rc, str::FromStr};
2
2
3use num_bigint::BigUint;
3use num_bigint::BigUint;
4−use num_traits::ToBytes;
5use std::fmt;
4use std::fmt;
6use xxhash_rust::xxh3::xxh3_128;
5use xxhash_rust::xxh3::xxh3_128;
7
6
@@ -18,10 +17,6 @@ pub enum Noun {
18 p: Rc<Noun>,
17 p: Rc<Noun>,
19 q: Rc<Noun>,
18 q: Rc<Noun>,
20 hash: Cell<Option<Hash>>,
19 hash: Cell<Option<Hash>>,
21− compiled_gate: Option<(
22− Rc<Noun>,
23− Rc<fn(&InterpreterContext, Rc<Noun>, Rc<Noun>) -> Option<Rc<Noun>>>,
24− )>,
25 },
20 },
26}
21}
27
22
@@ -58,13 +53,11 @@ impl PartialEq for Noun {
58 p: lhs_p,
53 p: lhs_p,
59 q: lhs_q,
54 q: lhs_q,
60 hash: lhs_hash,
55 hash: lhs_hash,
61− compiled_gate: _,
62 },
56 },
63 Noun::Cell {
57 Noun::Cell {
64 p: rhs_p,
58 p: rhs_p,
65 q: rhs_q,
59 q: rhs_q,
66 hash: rhs_hash,
60 hash: rhs_hash,
67− compiled_gate: _,
68 },
61 },
69 ) => lhs_hash == rhs_hash && lhs_p == rhs_p && lhs_q == rhs_q,
62 ) => lhs_hash == rhs_hash && lhs_p == rhs_p && lhs_q == rhs_q,
70 _ => false,
63 _ => false,
@@ -72,7 +65,7 @@ impl PartialEq for Noun {
72 }
65 }
73}
66}
74
67
75−impl Noun {
68+impl<'a> Noun {
76 pub const SIG: Noun = Noun::Atom(BigUint::ZERO);
69 pub const SIG: Noun = Noun::Atom(BigUint::ZERO);
77
70
78 pub fn from_u32(a: u32) -> Noun {
71 pub fn from_u32(a: u32) -> Noun {
@@ -80,15 +73,15 @@ impl Noun {
80 }
73 }
81
74
82 pub fn list<I: Iterator<Item = Noun> + DoubleEndedIterator>(l: I) -> Rc<Noun> {
75 pub fn list<I: Iterator<Item = Noun> + DoubleEndedIterator>(l: I) -> Rc<Noun> {
83− l.rfold(Rc::new(Noun::SIG), |tail, head| cell(&head, &tail))
76+ l.rfold(Rc::new(Noun::SIG), |tail, head| cell(&Rc::new(head), &tail))
84 }
77 }
85
78
86− pub fn list_refs<I: Iterator<Item = Rc<Noun>> + DoubleEndedIterator>(l: I) -> Rc<Noun> {
79+ pub fn list_refs<I: Iterator<Item = &'a Rc<Noun>> + DoubleEndedIterator>(l: I) -> Rc<Noun> {
87− l.rfold(Rc::new(Noun::SIG), |tail, head| cell(&head, &tail))
80+ l.rfold(Rc::new(Noun::SIG), |tail, head| cell(head, &tail))
88 }
81 }
89
82
90 pub fn unit(self: Rc<Self>) -> Rc<Noun> {
83 pub fn unit(self: Rc<Self>) -> Rc<Noun> {
91− cell(&Noun::SIG, &self)
84+ cell(&Rc::new(Noun::SIG), &self)
92 }
85 }
93
86
94 pub fn from_unit(unit: Option<Rc<Noun>>) -> Rc<Noun> {
87 pub fn from_unit(unit: Option<Rc<Noun>>) -> Rc<Noun> {
@@ -115,15 +108,15 @@ impl Noun {
115 }
108 }
116 }
109 }
117
110
118− pub fn gate_sample(self: Rc<Self>) -> Option<Rc<Self>> {
111+ pub fn gate_sample(self: &Rc<Self>) -> Option<&Rc<Self>> {
119 let (_battery, payload) = self.as_cell()?;
112 let (_battery, payload) = self.as_cell()?;
120 let (sample, _context) = payload.as_cell()?;
113 let (sample, _context) = payload.as_cell()?;
121 Option::Some(sample)
114 Option::Some(sample)
122 }
115 }
123
116
124− pub fn as_cell(self: &Self) -> Option<(Rc<Noun>, Rc<Noun>)> {
117+ pub fn as_cell(self: &'a Self) -> Option<(&'a Rc<Noun>, &'a Rc<Noun>)> {
125 match self {
118 match self {
126− Noun::Cell { p, q, .. } => Option::Some((p.clone(), q.clone())),
119+ Noun::Cell { p, q, .. } => Option::Some((p, q)),
127 _ => Option::None,
120 _ => Option::None,
128 }
121 }
129 }
122 }
@@ -143,12 +136,12 @@ impl Noun {
143 !self.is_sig()
136 !self.is_sig()
144 }
137 }
145
138
146− pub fn list_iter(self: Rc<Self>) -> NounListIterator {
139+ pub fn list_iter(self: &'a Rc<Self>) -> NounListIterator<'a> {
147− NounListIterator { noun: self.clone() }
140+ NounListIterator { noun: self }
148 }
141 }
149
142
150 /// panics if malformed
143 /// panics if malformed
151− pub fn as_unit(self: &Self) -> Option<Rc<Self>> {
144+ pub fn as_unit(self: &Self) -> Option<&Rc<Self>> {
152 if self.is_sig() {
145 if self.is_sig() {
153 Option::None
146 Option::None
154 } else {
147 } else {
@@ -158,17 +151,11 @@ impl Noun {
158
151
159 pub fn hash(self: &Self) -> Hash {
152 pub fn hash(self: &Self) -> Hash {
160 match self {
153 match self {
161− Noun::Cell {
162− hash,
163− p,
164− q,
165− compiled_gate: _,
166− } => match hash.get() {
154+ Noun::Cell { hash, p, q } => match hash.get() {
167 Some(x) => x.clone(),
155 Some(x) => x.clone(),
168 None => {
156 None => {
157+ let hash_value =
169− let hash_value = stacker::maybe_grow(32 * 1024, 1024 * 1024, || {
158+ stacker::maybe_grow(32 * 1024, 1024 * 1024, || hash_pair(p, q));
170− hash_pair(p.clone(), q.clone())
171− });
172 hash.replace(Some(hash_value));
159 hash.replace(Some(hash_value));
173 hash_value
160 hash_value
174 }
161 }
@@ -178,15 +165,15 @@ impl Noun {
178 }
165 }
179
166
180 /// returns the hash and the current sample
167 /// returns the hash and the current sample
181− pub fn hash_gate(self: &Self) -> (Hash, Rc<Noun>) {
168+ pub fn hash_gate(self: &Self) -> (Hash, &Rc<Noun>) {
182 let (battery, payload) = self.as_cell().unwrap();
169 let (battery, payload) = self.as_cell().unwrap();
183 let (sample, context) = payload.as_cell().unwrap();
170 let (sample, context) = payload.as_cell().unwrap();
184
171
185− (hash_pair(battery.clone(), context), sample)
172+ (hash_pair(battery, context), sample)
186 }
173 }
187
174
188 /// returns the hash and the current sample
175 /// returns the hash and the current sample
189− pub fn hash_double_gate(self: &Self) -> (Hash, Rc<Noun>, Rc<Noun>) {
176+ pub fn hash_double_gate(self: &Self) -> (Hash, &Rc<Noun>, &Rc<Noun>) {
190 let (battery, payload) = self.as_cell().unwrap();
177 let (battery, payload) = self.as_cell().unwrap();
191 let (sample_2, context) = payload.as_cell().unwrap();
178 let (sample_2, context) = payload.as_cell().unwrap();
192 let (inner_hash, sample_1) = context.hash_gate();
179 let (inner_hash, sample_1) = context.hash_gate();
@@ -232,14 +219,17 @@ impl Noun {
232 }
219 }
233
220
234 pub fn from_hair(hair: &Hair) -> Rc<Self> {
221 pub fn from_hair(hair: &Hair) -> Rc<Self> {
222+ cell(
223+ &Rc::new(Noun::from_u32(hair.line)),
235− cell(&Noun::from_u32(hair.line), &Noun::from_u32(hair.column))
224+ &Rc::new(Noun::from_u32(hair.column)),
225+ )
236 }
226 }
237
227
238 pub fn as_nail(self: &Self) -> Option<Nail> {
228 pub fn as_nail(self: &Self) -> Option<Nail> {
239 let (hair, tape) = self.as_cell()?;
229 let (hair, tape) = self.as_cell()?;
240 Some(Nail {
230 Some(Nail {
241 hair: hair.as_hair()?,
231 hair: hair.as_hair()?,
242− rest: tape.clone(),
232+ rest: tape,
243 })
233 })
244 }
234 }
245
235
@@ -257,44 +247,21 @@ impl Noun {
257 };
247 };
258 Some(Edge { hair, result })
248 Some(Edge { hair, result })
259 }
249 }
260−
261− pub fn with_jet(
262− self: &Self,
263− jet: (
264− Rc<Noun>,
265− Rc<fn(&InterpreterContext, Rc<Noun>, Rc<Noun>) -> Option<Rc<Noun>>>,
266− ),
267− ) -> Self {
268− match self {
269− Noun::Atom(_) => self.clone(),
270− Noun::Cell {
271− p,
272− q,
273− hash,
274− compiled_gate: _,
275− } => Noun::Cell {
276− p: p.clone(),
277− q: q.clone(),
278− hash: hash.clone(),
279− compiled_gate: Some(jet),
280− },
281− }
282− }
283}
250}
284
251
285#[derive(Clone)]
252#[derive(Clone)]
286−pub struct Edge {
253+pub struct Edge<'a> {
287 pub hair: Hair,
254 pub hair: Hair,
288− pub result: Option<(Rc<Noun>, Nail)>,
255+ pub result: Option<(&'a Rc<Noun>, Nail<'a>)>,
289}
256}
290
257
291−impl Edge {
258+impl<'a> Edge<'a> {
292 pub fn as_noun(self: &Self) -> Rc<Noun> {
259 pub fn as_noun(self: &Self) -> Rc<Noun> {
293− let foo = match self.result.clone() {
260+ let foo = match &self.result {
294− None => &Noun::SIG,
261+ None => &Rc::new(Noun::SIG),
295 Some((result, nail)) => {
262 Some((result, nail)) => {
296 let foo = cell(&result, &nail.as_noun());
263 let foo = cell(&result, &nail.as_noun());
297− &cell(&Noun::SIG, &foo)
264+ &cell(&Rc::new(Noun::SIG), &foo)
298 }
265 }
299 };
266 };
300 cell(&self.hair.as_noun(), foo)
267 cell(&self.hair.as_noun(), foo)
@@ -309,17 +276,20 @@ pub struct Hair {
309
276
310impl Hair {
277impl Hair {
311 pub fn as_noun(self: &Self) -> Rc<Noun> {
278 pub fn as_noun(self: &Self) -> Rc<Noun> {
279+ cell(
280+ &Rc::new(Noun::from_u32(self.line)),
312− cell(&Noun::from_u32(self.line), &Noun::from_u32(self.column))
281+ &Rc::new(Noun::from_u32(self.column)),
282+ )
313 }
283 }
314}
284}
315
285
316#[derive(Clone)]
286#[derive(Clone)]
317−pub struct Nail {
287+pub struct Nail<'a> {
318 pub hair: Hair,
288 pub hair: Hair,
319− pub rest: Rc<Noun>,
289+ pub rest: &'a Rc<Noun>,
320}
290}
321
291
322−impl Nail {
292+impl<'a> Nail<'a> {
323 pub fn as_noun(self: &Self) -> Rc<Noun> {
293 pub fn as_noun(self: &Self) -> Rc<Noun> {
324 cell(&self.hair.as_noun(), &self.rest)
294 cell(&self.hair.as_noun(), &self.rest)
325 }
295 }
@@ -338,19 +308,19 @@ impl Bite {
338}
308}
339
309
340#[derive(Clone)]
310#[derive(Clone)]
341−pub struct NounListIterator {
311+pub struct NounListIterator<'a> {
342− noun: Rc<Noun>,
312+ noun: &'a Rc<Noun>,
343}
313}
344
314
345−impl Iterator for NounListIterator {
315+impl<'a> Iterator for NounListIterator<'a> {
346− type Item = Rc<Noun>;
316+ type Item = &'a Rc<Noun>;
347
317
348 fn next(&mut self) -> Option<Self::Item> {
318 fn next(&mut self) -> Option<Self::Item> {
349 if self.noun.is_sig() {
319 if self.noun.is_sig() {
350 Option::None
320 Option::None
351 } else {
321 } else {
352 let (p, q) = self.noun.as_cell().unwrap();
322 let (p, q) = self.noun.as_cell().unwrap();
353− self.noun = q.clone();
323+ self.noun = q;
354 Option::Some(p)
324 Option::Some(p)
355 }
325 }
356 }
326 }
@@ -394,20 +364,19 @@ fn print_noun(noun: Rc<Noun>, is_rhs: bool) -> String {
394 }
364 }
395}
365}
396
366
397−pub fn cell(p: &Noun, q: &Noun) -> Rc<Noun> {
367+pub fn cell(p: &Rc<Noun>, q: &Rc<Noun>) -> Rc<Noun> {
398 Rc::new(naked_cell(p, q))
368 Rc::new(naked_cell(p, q))
399}
369}
400
370
401−pub fn naked_cell(p: &Noun, q: &Noun) -> Noun {
371+pub fn naked_cell(p: &Rc<Noun>, q: &Rc<Noun>) -> Noun {
402 Noun::Cell {
372 Noun::Cell {
403− p: Rc::new(p.clone()),
373+ p: p.clone(),
404− q: Rc::new(q.clone()),
374+ q: q.clone(),
405 hash: Cell::new(None),
375 hash: Cell::new(None),
406− compiled_gate: None,
407 }
376 }
408}
377}
409
378
410−fn hash_pair(p: Rc<Noun>, q: Rc<Noun>) -> Hash {
379+fn hash_pair(p: &Rc<Noun>, q: &Rc<Noun>) -> Hash {
411 xxh3_128(&[p.hash().to_le_bytes(), q.hash().to_le_bytes()].as_flattened())
380 xxh3_128(&[p.hash().to_le_bytes(), q.hash().to_le_bytes()].as_flattened())
412}
381}
413
382