@@ -1,23 +1,17 @@
1use core::str;
1use core::str;
2use std::borrow::Borrow;
2use std::borrow::Borrow;
3+use std::borrow::BorrowMut;
3use std::collections::BTreeMap;
4use std::collections::BTreeMap;
4−use std::collections::HashMap;
5use std::rc::Rc;
5use std::rc::Rc;
6−use std::sync::Mutex;
6+use std::str::Utf8Error;
8use fplist::cons;
8use fplist::cons;
9use fplist::PersistentList;
9use fplist::PersistentList;
10−use lazy_static::lazy_static;
11use num_bigint::BigUint;
10use num_bigint::BigUint;
13use crate::jets::*;
12use crate::jets::*;
14use crate::noun::*;
13use crate::noun::*;
16−// #[cfg(feature = "count-jets")]
18− pub static ref JET_COUNTER: Mutex<HashMap<Atom, u32>> = Mutex::new(HashMap::new());
21#[derive(Clone)]
15#[derive(Clone)]
22pub struct Nouns {
16pub struct Nouns {
23 pub y: Rc<Noun>,
17 pub y: Rc<Noun>,
@@ -32,7 +26,6 @@ pub struct Nouns {
32 pub memo: Rc<Noun>,
26 pub memo: Rc<Noun>,
33 pub mean: Rc<Noun>,
27 pub mean: Rc<Noun>,
34 pub slog: Rc<Noun>,
28 pub slog: Rc<Noun>,
38#[derive(Clone)]
31#[derive(Clone)]
@@ -51,7 +44,6 @@ pub struct InterpreterContext {
51 pub nouns: Nouns,
44 pub nouns: Nouns,
52 pub big_uints: BigUints,
45 pub big_uints: BigUints,
53 pub memo: BTreeMap<Hash, Rc<Noun>>,
46 pub memo: BTreeMap<Hash, Rc<Noun>>,
54− pub slog: fn(&String) -> (),
57pub fn generate_interpreter_context() -> InterpreterContext {
49pub fn generate_interpreter_context() -> InterpreterContext {
@@ -74,7 +66,6 @@ pub fn generate_interpreter_context() -> InterpreterContext {
74 let memo = Rc::new(Noun::from_bytes(b"memo"));
66 let memo = Rc::new(Noun::from_bytes(b"memo"));
75 let mean = Rc::new(Noun::from_bytes(b"mean"));
67 let mean = Rc::new(Noun::from_bytes(b"mean"));
76 let slog = Rc::new(Noun::from_bytes(b"slog"));
68 let slog = Rc::new(Noun::from_bytes(b"slog"));
77− let fast = Rc::new(Noun::from_bytes(b"fast"));
78 InterpreterContext {
69 InterpreterContext {
80 double_jets,
71 double_jets,
@@ -91,11 +82,9 @@ pub fn generate_interpreter_context() -> InterpreterContext {
96 big_uints,
86 big_uints,
97 memo: BTreeMap::new(),
87 memo: BTreeMap::new(),
98− slog: |str: &String| eprintln!("{}", str),
@@ -204,7 +193,7 @@ fn hax(
205fn tar_u32<'a>(
194fn tar_u32<'a>(
206 ctx: &mut InterpreterContext,
195 ctx: &mut InterpreterContext,
207− subj: &'a Rc<Noun>,
196+ subj: Rc<Noun>,
209 formula: &'a Rc<Noun>,
198 formula: &'a Rc<Noun>,
210) -> Result<Rc<Noun>, TTanks> {
199) -> Result<Rc<Noun>, TTanks> {
@@ -227,16 +216,16 @@ fn tar_u32<'a>(
227 match ctx.jets.get(&hash) {
216 match ctx.jets.get(&hash) {
228 Some(f) => f(ctx, sample),
217 Some(f) => f(ctx, sample),
229 None => {
218 None => {
230− let foo = tar(ctx, subj, &b)?;
219+ let foo = tar(ctx, subj.clone(), &b)?;
231 let bar = tar(ctx, subj, &c)?;
220 let bar = tar(ctx, subj, &c)?;
232− tar(ctx, &foo, &bar)
221+ tar(ctx, foo, &bar)
237− let foo = tar(ctx, subj, &b)?;
226+ let foo = tar(ctx, subj.clone(), &b)?;
238 let bar = tar(ctx, subj, &c)?;
227 let bar = tar(ctx, subj, &c)?;
239− tar(ctx, &foo, &bar)
228+ tar(ctx, foo, &bar)
@@ -247,7 +236,7 @@ fn tar_u32<'a>(
247 4 => Ok(Rc::new(lus(&*tar(ctx, subj, &formula)?)?)),
236 4 => Ok(Rc::new(lus(&*tar(ctx, subj, &formula)?)?)),
249 let (b, c) = formula.as_cell().ok_or(TTanks::new())?;
238 let (b, c) = formula.as_cell().ok_or(TTanks::new())?;
250− let foo = tar(ctx, subj, &b)?;
239+ let foo = tar(ctx, subj.clone(), &b)?;
251 let bar = tar(ctx, subj, &c)?;
240 let bar = tar(ctx, subj, &c)?;
252 Ok(tis(ctx, &foo, &bar).clone())
241 Ok(tis(ctx, &foo, &bar).clone())
@@ -255,29 +244,29 @@ fn tar_u32<'a>(
255 let (b, c) = formula.as_cell().ok_or(TTanks::new())?;
244 let (b, c) = formula.as_cell().ok_or(TTanks::new())?;
256 let (c, d) = c.as_cell().ok_or(TTanks::new())?;
245 let (c, d) = c.as_cell().ok_or(TTanks::new())?;
258− let bar = tar_u32(ctx, subj, 4, &cell(&ctx.nouns.four.clone(), &b))?;
247+ let bar = tar_u32(ctx, subj.clone(), 4, &cell(&ctx.nouns.four.clone(), &b))?;
260− let foo = tar_u32(ctx, &ctx.nouns.two_three.clone(), 0, &bar)?;
249+ let foo = tar_u32(ctx, ctx.nouns.two_three.clone(), 0, &bar)?;
261− let foo = tar_u32(ctx, &cell(&c, &d), 0, &foo)?;
250+ let foo = tar_u32(ctx, cell(&c, &d), 0, &foo)?;
263 tar(ctx, subj, &foo)
252 tar(ctx, subj, &foo)
266 let (b, c) = formula.as_cell().ok_or(TTanks::new())?;
255 let (b, c) = formula.as_cell().ok_or(TTanks::new())?;
267 let foo = tar(ctx, subj, &b)?;
256 let foo = tar(ctx, subj, &b)?;
268− tar(ctx, &foo, &c)
257+ tar(ctx, foo, &c)
271 let (b, c) = formula.as_cell().ok_or(TTanks::new())?;
260 let (b, c) = formula.as_cell().ok_or(TTanks::new())?;
272− let foo = tar(ctx, subj, &b)?;
261+ let foo = tar(ctx, subj.clone(), &b)?;
273− tar(ctx, &cell(&foo, &subj), &c)
262+ tar(ctx, cell(&foo, &subj), &c)
276 let (b, c) = formula.as_cell().ok_or(TTanks::new())?;
265 let (b, c) = formula.as_cell().ok_or(TTanks::new())?;
277 let foo = tar(ctx, subj, &c)?;
266 let foo = tar(ctx, subj, &c)?;
282 &cell(&ctx.nouns.sig_one, &cell(&ctx.nouns.sig, &b)),
271 &cell(&ctx.nouns.sig_one, &cell(&ctx.nouns.sig, &b)),
@@ -287,7 +276,7 @@ fn tar_u32<'a>(
287 let (b, c) = b.as_cell().ok_or(TTanks::new())?;
276 let (b, c) = b.as_cell().ok_or(TTanks::new())?;
288 let b = b.as_atom().ok_or(TTanks::new())?;
277 let b = b.as_atom().ok_or(TTanks::new())?;
290− let foo = tar(ctx, subj, &c)?;
279+ let foo = tar(ctx, subj.clone(), &c)?;
291 let bar = tar(ctx, subj, &d)?;
280 let bar = tar(ctx, subj, &d)?;
292 hax(ctx, b, &foo, &bar)
281 hax(ctx, b, &foo, &bar)
@@ -296,7 +285,7 @@ fn tar_u32<'a>(
296 match b.borrow() {
285 match b.borrow() {
297 Noun::Atom(_) => tar(ctx, subj, &d),
286 Noun::Atom(_) => tar(ctx, subj, &d),
298 Noun::Cell { p, q, .. } => {
287 Noun::Cell { p, q, .. } => {
299− let eval = |ctx: &mut InterpreterContext| tar(ctx, subj, &d);
288+ let eval = |ctx: &mut InterpreterContext| tar(ctx, subj.clone(), &d);
300 if *p == ctx.nouns.memo {
289 if *p == ctx.nouns.memo {
301 let hash = cell(&subj, &d).hash();
290 let hash = cell(&subj, &d).hash();
302 match ctx.memo.get(&hash) {
291 match ctx.memo.get(&hash) {
@@ -310,32 +299,10 @@ fn tar_u32<'a>(
310 } else if *p == ctx.nouns.mean {
299 } else if *p == ctx.nouns.mean {
311 with_trace((subj.clone(), q.clone()), eval(ctx))
300 with_trace((subj.clone(), q.clone()), eval(ctx))
312 } else if *p == ctx.nouns.slog {
301 } else if *p == ctx.nouns.slog {
313− let noun = tar(ctx, subj, &q)?;
302+ let noun = tar(ctx, subj.clone(), &q)?;
314 let (_prio, tank) = noun.as_cell().ok_or(TTanks::new())?;
303 let (_prio, tank) = noun.as_cell().ok_or(TTanks::new())?;
316− (ctx.slog)(&ram(ctx, tank.clone()).unwrap_or(String::new()));
305+ eprintln!("{}", ram(ctx, tank.clone()).unwrap_or(String::new()));
318− } else if *p == ctx.nouns.fast {
319− if cfg!(feature = "count-jets") {
320− let tag = q.as_cell().unwrap().1.as_cell().unwrap().0.as_atom();
324− let mut counter = JET_COUNTER.lock().unwrap();
325− match counter.get(tag) {
327− counter.insert(tag.clone(), 1);
332− counter.insert(tag.clone(), v + 1);
339 eval(ctx)
306 eval(ctx)
341 eval(ctx)
308 eval(ctx)
@@ -356,22 +323,24 @@ fn ram(ctx: &mut InterpreterContext, tank: Rc<Noun>) -> Option<String> {
356 Noun::Cell { p, q, .. } => {
323 Noun::Cell { p, q, .. } => {
357 let tag = p.as_atom()?.to_bytes_le();
324 let tag = p.as_atom()?.to_bytes_le();
358 if tag == b"leaf" {
325 if tag == b"leaf" {
359− let mut bytes = crip(ctx, q.clone()).ok()?.as_bytes()?;
326+ let mut bytes = crip(ctx, q.clone()).ok()?.as_atom()?.to_bytes_le();
360 Some(String::from(str::from_utf8_mut(&mut bytes).ok()?))
327 Some(String::from(str::from_utf8_mut(&mut bytes).ok()?))
361 } else if tag == b"palm" {
328 } else if tag == b"palm" {
362− let (spacers, tanks) = q.as_cell()?;
329+ let (mid, foo) = q.as_cell()?;
363− let (mid, open, flat_open, close) = spacers.tuple_4()?;
330+ let (open, foo) = foo.as_cell()?;
331+ let (flat_open, foo) = foo.as_cell()?;
332+ let (close, tanks) = foo.as_cell()?;
365− let mut mid = crip(ctx, mid.clone()).ok()?.as_bytes()?;
334+ let mut mid = mid.as_bytes()?;
366 let mid = String::from(str::from_utf8_mut(&mut mid).ok()?);
335 let mid = String::from(str::from_utf8_mut(&mut mid).ok()?);
368− let mut open = crip(ctx, open.clone()).ok()?.as_bytes()?;
337+ let mut open = open.as_bytes()?;
369 let open = String::from(str::from_utf8_mut(&mut open).ok()?);
338 let open = String::from(str::from_utf8_mut(&mut open).ok()?);
371− let mut flat_open = crip(ctx, flat_open.clone()).ok()?.as_bytes()?;
340+ let mut flat_open = flat_open.as_bytes()?;
372 let flat_open = String::from(str::from_utf8_mut(&mut flat_open).ok()?);
341 let flat_open = String::from(str::from_utf8_mut(&mut flat_open).ok()?);
374− let mut close = crip(ctx, close.clone()).ok()?.as_bytes()?;
343+ let mut close = close.as_bytes()?;
375 let close = String::from(str::from_utf8_mut(&mut close).ok()?);
344 let close = String::from(str::from_utf8_mut(&mut close).ok()?);
377 let mut target = String::new();
346 let mut target = String::new();
@@ -394,16 +363,17 @@ fn ram(ctx: &mut InterpreterContext, tank: Rc<Noun>) -> Option<String> {
395 Some(target)
364 Some(target)
396 } else if tag == b"rose" {
365 } else if tag == b"rose" {
397− let (spacers, tanks) = q.as_cell()?;
366+ let (mid, foo) = q.as_cell()?;
398− let (mid, open, close) = spacers.tuple_3()?;
367+ let (open, foo) = foo.as_cell()?;
368+ let (close, tanks) = foo.as_cell()?;
400− let mut mid = crip(ctx, mid.clone()).ok()?.as_bytes()?;
370+ let mut mid = mid.as_bytes()?;
401 let mid = String::from(str::from_utf8_mut(&mut mid).ok()?);
371 let mid = String::from(str::from_utf8_mut(&mut mid).ok()?);
403− let mut open = crip(ctx, open.clone()).ok()?.as_bytes()?;
373+ let mut open = open.as_bytes()?;
404 let open = String::from(str::from_utf8_mut(&mut open).ok()?);
374 let open = String::from(str::from_utf8_mut(&mut open).ok()?);
406− let mut close = crip(ctx, close.clone()).ok()?.as_bytes()?;
376+ let mut close = close.as_bytes()?;
407 let close = String::from(str::from_utf8_mut(&mut close).ok()?);
377 let close = String::from(str::from_utf8_mut(&mut close).ok()?);
409 let mut target = String::new();
379 let mut target = String::new();
@@ -434,15 +404,8 @@ fn ram(ctx: &mut InterpreterContext, tank: Rc<Noun>) -> Option<String> {
434pub fn ram_ttanks(ctx: &mut InterpreterContext, tanks: TTanks) -> String {
404pub fn ram_ttanks(ctx: &mut InterpreterContext, tanks: TTanks) -> String {
435 let mut target = String::new();
405 let mut target = String::new();
437− let mut first = true;
438− for tank in tanks.iter().collect::<Vec<_>>().iter().cloned().rev() {
407+ for tank in tanks.iter() {
443 target.push_str(&*ram_ttank(ctx, tank.clone()));
408 target.push_str(&*ram_ttank(ctx, tank.clone()));
@@ -451,21 +414,17 @@ pub fn ram_ttanks(ctx: &mut InterpreterContext, tanks: TTanks) -> String {
451pub fn ram_ttank(ctx: &mut InterpreterContext, ttank: TTank) -> String {
414pub fn ram_ttank(ctx: &mut InterpreterContext, ttank: TTank) -> String {
452 let (subj, q) = ttank;
415 let (subj, q) = ttank;
454− let tank = match tar(ctx, &subj, &q) {
417+ let tank = match tar(ctx, subj.clone(), &q) {
455 Ok(gate) => match eval_pulled_gate(ctx, gate) {
418 Ok(gate) => match eval_pulled_gate(ctx, gate) {
456 Ok(tank) => tank,
419 Ok(tank) => tank,
458− return String::new();
420+ Err(_) => return String::new(),
462− return String::new();
422+ Err(_) => return String::new(),
465 ram(ctx, tank).unwrap_or(String::new())
424 ram(ctx, tank).unwrap_or(String::new())
468−pub fn crip(ctx: &mut InterpreterContext, tape: Rc<Noun>) -> Result<Rc<Noun>, TTanks> {
427+fn crip(ctx: &mut InterpreterContext, tape: Rc<Noun>) -> Result<Rc<Noun>, TTanks> {
469 RAP(ctx, &cell(&Rc::new(Noun::from_u32(3)), &tape))
428 RAP(ctx, &cell(&Rc::new(Noun::from_u32(3)), &tape))
@@ -484,13 +443,13 @@ pub const EMPTY_TANKS: TTanks = TTanks::new();
485pub fn tar<'a>(
444pub fn tar<'a>(
486 ctx: &mut InterpreterContext,
445 ctx: &mut InterpreterContext,
487− subj: &'a Rc<Noun>,
446+ subj: Rc<Noun>,
488 formula: &'a Noun,
447 formula: &'a Noun,
489) -> Result<Rc<Noun>, TTanks> {
448) -> Result<Rc<Noun>, TTanks> {
490 let (op, formula) = formula.as_cell().ok_or(TTanks::new())?;
449 let (op, formula) = formula.as_cell().ok_or(TTanks::new())?;
491 match op.borrow() {
450 match op.borrow() {
492 Noun::Cell { .. } => {
451 Noun::Cell { .. } => {
493− let foo = tar(ctx, subj, &op)?;
452+ let foo = tar(ctx, subj.clone(), &op)?;
494 let bar = tar(ctx, subj, &formula)?;
453 let bar = tar(ctx, subj, &formula)?;
495 Ok(cell(&foo, &bar))
454 Ok(cell(&foo, &bar))
@@ -511,7 +470,7 @@ pub fn eval_gate(
511 ctx: &mut InterpreterContext,
470 ctx: &mut InterpreterContext,
512 gate_factory: &Rc<Noun>,
471 gate_factory: &Rc<Noun>,
513) -> Result<Rc<Noun>, TTanks> {
472) -> Result<Rc<Noun>, TTanks> {
514− let pulled_gate = tar(ctx, &ctx.nouns.sig.clone(), &gate_factory)?;
473+ let pulled_gate = tar(ctx, ctx.nouns.sig.clone(), &gate_factory)?;
515 eval_pulled_gate(ctx, pulled_gate)
474 eval_pulled_gate(ctx, pulled_gate)
@@ -520,7 +479,7 @@ pub fn slam(
520 gate_factory: &Rc<Noun>,
479 gate_factory: &Rc<Noun>,
521 sample: &Rc<Noun>,
480 sample: &Rc<Noun>,
522) -> Result<Rc<Noun>, TTanks> {
481) -> Result<Rc<Noun>, TTanks> {
523− let gate = tar(ctx, &ctx.nouns.sig.clone(), &gate_factory)?;
482+ let gate = tar(ctx, ctx.nouns.sig.clone(), &gate_factory)?;
525 eval_pulled_gate(ctx, replace_sample(&gate, sample)?)
484 eval_pulled_gate(ctx, replace_sample(&gate, sample)?)
@@ -530,7 +489,7 @@ pub fn slam(
530pub fn eval_pulled_gate(ctx: &mut InterpreterContext, gate: Rc<Noun>) -> Result<Rc<Noun>, TTanks> {
489pub fn eval_pulled_gate(ctx: &mut InterpreterContext, gate: Rc<Noun>) -> Result<Rc<Noun>, TTanks> {
535 &Rc::new(Noun::Atom(BigUint::new(vec![9]))),
494 &Rc::new(Noun::Atom(BigUint::new(vec![9]))),
536 &cell(&ctx.nouns.two, &cell(&ctx.nouns.sig, &ctx.nouns.one)),
495 &cell(&ctx.nouns.two, &cell(&ctx.nouns.sig, &ctx.nouns.one)),