@@ -1,4 +1,5 @@
1use std::borrow::Borrow;
1use std::borrow::Borrow;
2+use std::collections::BTreeMap;
2use std::rc::Rc;
3use std::rc::Rc;
4use num_bigint::BigUint;
5use num_bigint::BigUint;
@@ -16,6 +17,7 @@ pub struct Nouns {
16 pub four: Rc<Noun>,
17 pub four: Rc<Noun>,
17 pub sig_one: Rc<Noun>,
18 pub sig_one: Rc<Noun>,
18 pub two_three: Rc<Noun>,
19 pub two_three: Rc<Noun>,
21pub struct BigUints {
23pub struct BigUints {
@@ -31,6 +33,7 @@ pub struct InterpreterContext {
31 pub double_jets: DoubleJets,
33 pub double_jets: DoubleJets,
32 pub nouns: Nouns,
34 pub nouns: Nouns,
33 pub big_uints: BigUints,
35 pub big_uints: BigUints,
36+ pub memo: BTreeMap<Hash, Rc<Noun>>,
36pub fn generate_interpreter_context() -> InterpreterContext {
39pub fn generate_interpreter_context() -> InterpreterContext {
@@ -50,6 +53,7 @@ pub fn generate_interpreter_context() -> InterpreterContext {
50 let four = Rc::new(Noun::Atom(big_uints.four.clone()));
53 let four = Rc::new(Noun::Atom(big_uints.four.clone()));
51 let sig_one = cell(&sig, &one);
54 let sig_one = cell(&sig, &one);
52 let two_three = cell(&two, &three);
55 let two_three = cell(&two, &three);
56+ let memo = Rc::new(Noun::from_bytes(b"memo"));
53 InterpreterContext {
57 InterpreterContext {
55 double_jets,
59 double_jets,
@@ -63,8 +67,10 @@ pub fn generate_interpreter_context() -> InterpreterContext {
65 two_three,
69 two_three,
67 big_uints,
72 big_uints,
73+ memo: BTreeMap::new(),
@@ -172,15 +178,15 @@ fn hax(
174fn tar_u32<'a>(
180fn tar_u32<'a>(
175− ctx: &InterpreterContext,
181+ ctx: &mut InterpreterContext,
176− subj: &'a Noun,
182+ subj: Rc<Noun>,
178 formula: &'a Rc<Noun>,
184 formula: &'a Rc<Noun>,
179) -> Option<Rc<Noun>> {
185) -> Option<Rc<Noun>> {
180 match op {
186 match op {
182 let b = formula.as_atom()?;
188 let b = formula.as_atom()?;
183− fas(ctx, b, subj)
189+ fas(ctx, b, &*subj)
185 1 => Some(formula.clone()),
191 1 => Some(formula.clone()),
@@ -196,16 +202,16 @@ fn tar_u32<'a>(
196 match ctx.jets.get(&hash) {
202 match ctx.jets.get(&hash) {
197 Some(f) => f(ctx, sample),
203 Some(f) => f(ctx, sample),
198 None => {
204 None => {
199− let foo = tar(ctx, subj, &b)?;
205+ let foo = tar(ctx, subj.clone(), &b)?;
200 let bar = tar(ctx, subj, &c)?;
206 let bar = tar(ctx, subj, &c)?;
201− tar(ctx, &foo, &bar)
207+ tar(ctx, foo, &bar)
206− let foo = tar(ctx, &subj, &b)?;
212+ let foo = tar(ctx, subj.clone(), &b)?;
207− let bar = tar(ctx, &subj, &c)?;
213+ let bar = tar(ctx, subj, &c)?;
208− tar(ctx, &foo, &bar)
214+ tar(ctx, foo, &bar)
@@ -219,7 +225,7 @@ fn tar_u32<'a>(
221 let (b, c) = formula.as_cell()?;
227 let (b, c) = formula.as_cell()?;
222− let foo = tar(ctx, &subj, &b)?;
228+ let foo = tar(ctx, subj.clone(), &b)?;
223 let bar = tar(ctx, subj, &c)?;
229 let bar = tar(ctx, subj, &c)?;
224 Some(tis(ctx, &foo, &bar).clone())
230 Some(tis(ctx, &foo, &bar).clone())
@@ -227,36 +233,29 @@ fn tar_u32<'a>(
227 let (b, c) = formula.as_cell()?;
233 let (b, c) = formula.as_cell()?;
228 let (c, d) = c.as_cell()?;
234 let (c, d) = c.as_cell()?;
236− &ctx.nouns.two_three,
238− &tar_u32(ctx, subj, 4, &cell(&ctx.nouns.four, &b))?,
236+ let bar = tar_u32(ctx, subj.clone(), 4, &cell(&ctx.nouns.four.clone(), &b))?;
238+ let foo = tar_u32(ctx, ctx.nouns.two_three.clone(), 0, &bar)?;
239+ let foo = tar_u32(ctx, cell(&c, &d), 0, &foo)?;
242− tar(ctx, &subj, &foo)
241+ tar(ctx, subj, &foo)
245 let (b, c) = formula.as_cell()?;
244 let (b, c) = formula.as_cell()?;
246 let foo = tar(ctx, subj, &b)?;
245 let foo = tar(ctx, subj, &b)?;
247− tar(ctx, &foo, &c)
246+ tar(ctx, foo, &c)
250 let (b, c) = formula.as_cell()?;
249 let (b, c) = formula.as_cell()?;
251− let foo = tar(ctx, &subj, &b)?;
250+ let foo = tar(ctx, subj.clone(), &b)?;
252− tar(ctx, &cell(&foo, &Rc::new(subj.clone())), &c)
251+ tar(ctx, cell(&foo, &subj), &c)
255 let (b, c) = formula.as_cell()?;
254 let (b, c) = formula.as_cell()?;
256− let foo = tar(ctx, &subj, &c)?;
255+ let foo = tar(ctx, subj, &c)?;
261 &cell(&ctx.nouns.sig_one, &cell(&ctx.nouns.sig, &b)),
260 &cell(&ctx.nouns.sig_one, &cell(&ctx.nouns.sig, &b)),
@@ -266,17 +265,33 @@ fn tar_u32<'a>(
266 let (b, c) = b.as_cell()?;
265 let (b, c) = b.as_cell()?;
267 let b = b.as_atom()?;
266 let b = b.as_atom()?;
268+ let foo = tar(ctx, subj.clone(), &c)?;
269− hax(ctx, b, &tar(ctx, subj, &c)?, &tar(ctx, subj, &d)?)
269+ let bar = tar(ctx, subj, &d)?;
270+ hax(ctx, b, &foo, &bar)
272 let (b, d) = formula.as_cell()?;
273 let (b, d) = formula.as_cell()?;
274 match b.borrow() {
274 match b.borrow() {
275 Noun::Atom(_) => tar(ctx, subj, &d),
275 Noun::Atom(_) => tar(ctx, subj, &d),
276− Noun::Cell { q: c, .. } => {
276+ Noun::Cell { p, q, .. } => {
277+ if *p == ctx.nouns.memo {
278+ let hash = cell(&subj, formula).hash();
279+ match ctx.memo.get(&hash) {
280+ Some(target) => Some(target.clone()),
283+ &tar(ctx, subj.clone(), &q)?,
277− let foo = tar(ctx, subj, &c)?;
284+ &tar(ctx, subj.clone(), &d)?,
278− let bar = tar(ctx, subj, &d)?;
285+ );
286+ let target = tar_u32(ctx, foo, 0, &ctx.nouns.three.clone())?;
287+ ctx.memo.insert(hash, target.clone());
292+ let foo = cell(&tar(ctx, subj.clone(), &q)?, &tar(ctx, subj.clone(), &d)?);
279− tar_u32(ctx, &cell(&foo, &bar), 0, &ctx.nouns.three)
293+ tar_u32(ctx, foo, 0, &ctx.nouns.three.clone())
@@ -284,11 +299,15 @@ fn tar_u32<'a>(
287−pub fn tar<'a>(ctx: &InterpreterContext, subj: &'a Noun, formula: &'a Noun) -> Option<Rc<Noun>> {
303+ ctx: &mut InterpreterContext,
306+) -> Option<Rc<Noun>> {
288 let (op, formula) = formula.as_cell()?;
307 let (op, formula) = formula.as_cell()?;
289 match op.borrow() {
308 match op.borrow() {
290 Noun::Cell { .. } => {
309 Noun::Cell { .. } => {
291− let foo = tar(ctx, subj, &op)?;
310+ let foo = tar(ctx, subj.clone(), &op)?;
292 let bar = tar(ctx, subj, &formula)?;
311 let bar = tar(ctx, subj, &formula)?;
293 Some(cell(&foo, &bar))
312 Some(cell(&foo, &bar))
@@ -305,27 +324,27 @@ pub fn tar<'a>(ctx: &InterpreterContext, subj: &'a Noun, formula: &'a Noun) -> O
308−pub fn eval_gate(ctx: &InterpreterContext, gate_factory: &Rc<Noun>) -> Option<Rc<Noun>> {
327+pub fn eval_gate(ctx: &mut InterpreterContext, gate_factory: &Rc<Noun>) -> Option<Rc<Noun>> {
309− let pulled_gate = tar(ctx, &ctx.nouns.sig, &gate_factory)?;
328+ let pulled_gate = tar(ctx, ctx.nouns.sig.clone(), &gate_factory)?;
310− eval_pulled_gate(ctx, &pulled_gate)
329+ eval_pulled_gate(ctx, pulled_gate)
313pub fn slam(
332pub fn slam(
314− ctx: &InterpreterContext,
333+ ctx: &mut InterpreterContext,
315 gate_factory: &Rc<Noun>,
334 gate_factory: &Rc<Noun>,
316 sample: &Rc<Noun>,
335 sample: &Rc<Noun>,
317) -> Option<Rc<Noun>> {
336) -> Option<Rc<Noun>> {
318− let gate = tar(ctx, &ctx.nouns.sig, &gate_factory)?;
337+ let gate = tar(ctx, ctx.nouns.sig.clone(), &gate_factory)?;
320− eval_pulled_gate(ctx, &replace_sample(&gate, sample)?)
339+ eval_pulled_gate(ctx, replace_sample(&gate, sample)?)
323/// This is useful for evaluaing gates produced by running `.foo/nock gate-name` in the dojo.
342/// This is useful for evaluaing gates produced by running `.foo/nock gate-name` in the dojo.
324/// Also for calling gates from within jets.
343/// Also for calling gates from within jets.
325−pub fn eval_pulled_gate(ctx: &InterpreterContext, gate: &Rc<Noun>) -> Option<Rc<Noun>> {
344+pub fn eval_pulled_gate(ctx: &mut InterpreterContext, gate: Rc<Noun>) -> Option<Rc<Noun>> {
330 &Rc::new(Noun::Atom(BigUint::new(vec![9]))),
349 &Rc::new(Noun::Atom(BigUint::new(vec![9]))),
331 &cell(&ctx.nouns.two, &cell(&ctx.nouns.sig, &ctx.nouns.one)),
350 &cell(&ctx.nouns.two, &cell(&ctx.nouns.sig, &ctx.nouns.one)),
@@ -336,11 +355,11 @@ pub fn eval_pulled_gate(ctx: &InterpreterContext, gate: &Rc<Noun>) -> Option<Rc<
336/// This is useful for evaluaing gates produced by running `.foo/nock gate-name` in the dojo.
355/// This is useful for evaluaing gates produced by running `.foo/nock gate-name` in the dojo.
337/// Also for calling gates from within jets.
356/// Also for calling gates from within jets.
338pub fn slam_pulled_gate(
357pub fn slam_pulled_gate(
339− ctx: &InterpreterContext,
358+ ctx: &mut InterpreterContext,
340 gate: &Rc<Noun>,
359 gate: &Rc<Noun>,
341 sample: &Rc<Noun>,
360 sample: &Rc<Noun>,
342) -> Option<Rc<Noun>> {
361) -> Option<Rc<Noun>> {
343− eval_pulled_gate(ctx, &replace_sample(gate, sample)?)
362+ eval_pulled_gate(ctx, replace_sample(gate, sample)?)
346pub fn replace_sample(gate: &Rc<Noun>, sample: &Rc<Noun>) -> Option<Rc<Noun>> {
365pub fn replace_sample(gate: &Rc<Noun>, sample: &Rc<Noun>) -> Option<Rc<Noun>> {