on master help sign in
7 files changed+402−9
since splitsnapshots
unifiedsplit
nock/Cargo.lock+141−5 nock/Cargo.toml+7 nock/src/interpreter.rs+41−1 nock/src/jets.rs+171−2 nock/src/main.rs+33−1 nock/src/noun.rs+6 nock/test.hoon+3
nock/Cargo.lock+141−5
@@ -1,6 +1,6 @@
11# This file is automatically @generated by Cargo.
22# It is not intended for manual editing.
3−version = 3
3+version = 4
44
55[[package]]
66name = "anstream"
@@ -63,6 +63,12 @@ version = "0.8.0"
6363source = "registry+https://github.com/rust-lang/crates.io-index"
6464checksum = "5e764a1d40d510daf35e07be9eb06e75770908c27d411ee6c92109c9840eaaf7"
6565
66+[[package]]
67+name = "bitflags"
68+version = "2.6.0"
69+source = "registry+https://github.com/rust-lang/crates.io-index"
70+checksum = "b048fb63fd8b5923fc5aa7b340d8e156aec7ec02f0c78fa8a6ddc2613f6f71de"
71+
6672[[package]]
6773name = "bitter"
6874version = "0.7.0"
@@ -87,6 +93,12 @@ version = "3.16.0"
8793source = "registry+https://github.com/rust-lang/crates.io-index"
8894checksum = "79296716171880943b8470b5f8d03aa55eb2e645a4874bdbb28adb49162e012c"
8995
96+[[package]]
97+name = "bytecount"
98+version = "0.6.8"
99+source = "registry+https://github.com/rust-lang/crates.io-index"
100+checksum = "5ce89b21cab1437276d2650d57e971f9d548a2d9037cc231abdc0562b97498ce"
101+
90102[[package]]
91103name = "cc"
92104version = "1.1.31"
@@ -102,6 +114,12 @@ version = "1.0.0"
102114source = "registry+https://github.com/rust-lang/crates.io-index"
103115checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd"
104116
117+[[package]]
118+name = "cfg_aliases"
119+version = "0.2.1"
120+source = "registry+https://github.com/rust-lang/crates.io-index"
121+checksum = "613afe47fcd5fac7ccf1db93babcb082c5994d996f20b8b159f2ad1658eb5724"
122+
105123[[package]]
106124name = "clap"
107125version = "4.5.20"
@@ -130,10 +148,10 @@ version = "4.5.18"
130148source = "registry+https://github.com/rust-lang/crates.io-index"
131149checksum = "4ac6a0c7b1a9e9a5186361f67dfa1b88213572f427fb9ab038efb2bd8c582dab"
132150dependencies = [
133− "heck",
151+ "heck 0.5.0",
134152 "proc-macro2",
135153 "quote",
136− "syn",
154+ "syn 2.0.85",
137155]
138156
139157[[package]]
@@ -158,6 +176,22 @@ dependencies = [
158176 "windows-sys 0.48.0",
159177]
160178
179+[[package]]
180+name = "ctrlc"
181+version = "3.4.5"
182+source = "registry+https://github.com/rust-lang/crates.io-index"
183+checksum = "90eeab0aa92f3f9b4e87f258c72b139c207d251f9cbc1080a0086b86a8870dd3"
184+dependencies = [
185+ "nix",
186+ "windows-sys 0.59.0",
187+]
188+
189+[[package]]
190+name = "fnv"
191+version = "1.0.7"
192+source = "registry+https://github.com/rust-lang/crates.io-index"
193+checksum = "3f9eec918d3f24069decb9af1554cad7c880e2da24a9afd88aca000531ab82c1"
194+
161195[[package]]
162196name = "fplist"
163197version = "0.2.1"
@@ -170,6 +204,12 @@ version = "2.0.0"
170204source = "registry+https://github.com/rust-lang/crates.io-index"
171205checksum = "e6d5a32815ae3f33302d95fdcb2ce17862f8c65363dcfd29360480ba1001fc9c"
172206
207+[[package]]
208+name = "heck"
209+version = "0.4.1"
210+source = "registry+https://github.com/rust-lang/crates.io-index"
211+checksum = "95505c38b4572b2d910cecb0281560f54b440a19336cbbcb27bf6ce6adc6f5a8"
212+
173213[[package]]
174214name = "heck"
175215version = "0.5.0"
@@ -215,6 +255,18 @@ version = "0.5.2"
215255source = "registry+https://github.com/rust-lang/crates.io-index"
216256checksum = "9252111cf132ba0929b6f8e030cac2a24b507f3a4d6db6fb2896f27b354c714b"
217257
258+[[package]]
259+name = "nix"
260+version = "0.29.0"
261+source = "registry+https://github.com/rust-lang/crates.io-index"
262+checksum = "71e2746dc3a24dd78b3cfcb7be93368c6de9963d30f43a6a73998a9cf4b17b46"
263+dependencies = [
264+ "bitflags",
265+ "cfg-if",
266+ "cfg_aliases",
267+ "libc",
268+]
269+
218270[[package]]
219271name = "nock"
220272version = "0.1.0"
@@ -223,13 +275,16 @@ dependencies = [
223275 "bitter",
224276 "bitvec",
225277 "clap",
278+ "ctrlc",
226279 "fplist",
280+ "lazy_static",
227281 "murmur3",
228282 "num-bigint",
229283 "num-integer",
230284 "num-traits",
231285 "spinoff",
232286 "stacker",
287+ "tabled",
233288 "web-sys",
234289 "xxhash-rust",
235290]
@@ -268,12 +323,47 @@ version = "1.20.2"
268323source = "registry+https://github.com/rust-lang/crates.io-index"
269324checksum = "1261fe7e33c73b354eab43b1273a57c8f967d0391e80353e51f764ac02cf6775"
270325
326+[[package]]
327+name = "papergrid"
328+version = "0.12.0"
329+source = "registry+https://github.com/rust-lang/crates.io-index"
330+checksum = "c7419ad52a7de9b60d33e11085a0fe3df1fbd5926aa3f93d3dd53afbc9e86725"
331+dependencies = [
332+ "bytecount",
333+ "fnv",
334+ "unicode-width",
335+]
336+
271337[[package]]
272338name = "paste"
273339version = "1.0.15"
274340source = "registry+https://github.com/rust-lang/crates.io-index"
275341checksum = "57c0d7b74b563b49d38dae00a0c37d4d6de9b432382b2892f0574ddcae73fd0a"
276342
343+[[package]]
344+name = "proc-macro-error"
345+version = "1.0.4"
346+source = "registry+https://github.com/rust-lang/crates.io-index"
347+checksum = "da25490ff9892aab3fcf7c36f08cfb902dd3e71ca0f9f9517bea02a73a5ce38c"
348+dependencies = [
349+ "proc-macro-error-attr",
350+ "proc-macro2",
351+ "quote",
352+ "syn 1.0.109",
353+ "version_check",
354+]
355+
356+[[package]]
357+name = "proc-macro-error-attr"
358+version = "1.0.4"
359+source = "registry+https://github.com/rust-lang/crates.io-index"
360+checksum = "a1be40180e52ecc98ad80b184934baf3d0d29f979574e439af5a55274b35f869"
361+dependencies = [
362+ "proc-macro2",
363+ "quote",
364+ "version_check",
365+]
366+
277367[[package]]
278368name = "proc-macro2"
279369version = "1.0.89"
@@ -343,6 +433,17 @@ version = "0.11.1"
343433source = "registry+https://github.com/rust-lang/crates.io-index"
344434checksum = "7da8b5736845d9f2fcb837ea5d9e2628564b3b043a70948a3f0b778838c5fb4f"
345435
436+[[package]]
437+name = "syn"
438+version = "1.0.109"
439+source = "registry+https://github.com/rust-lang/crates.io-index"
440+checksum = "72b64191b275b66ffe2469e8af2c1cfe3bafa67b529ead792a6d0160888b4237"
441+dependencies = [
442+ "proc-macro2",
443+ "quote",
444+ "unicode-ident",
445+]
446+
346447[[package]]
347448name = "syn"
348449version = "2.0.85"
@@ -354,6 +455,29 @@ dependencies = [
354455 "unicode-ident",
355456]
356457
458+[[package]]
459+name = "tabled"
460+version = "0.16.0"
461+source = "registry+https://github.com/rust-lang/crates.io-index"
462+checksum = "77c9303ee60b9bedf722012ea29ae3711ba13a67c9b9ae28993838b63057cb1b"
463+dependencies = [
464+ "papergrid",
465+ "tabled_derive",
466+]
467+
468+[[package]]
469+name = "tabled_derive"
470+version = "0.8.0"
471+source = "registry+https://github.com/rust-lang/crates.io-index"
472+checksum = "bf0fb8bfdc709786c154e24a66777493fb63ae97e3036d914c8666774c477069"
473+dependencies = [
474+ "heck 0.4.1",
475+ "proc-macro-error",
476+ "proc-macro2",
477+ "quote",
478+ "syn 1.0.109",
479+]
480+
357481[[package]]
358482name = "tap"
359483version = "1.0.1"
@@ -366,12 +490,24 @@ version = "1.0.13"
366490source = "registry+https://github.com/rust-lang/crates.io-index"
367491checksum = "e91b56cd4cadaeb79bbf1a5645f6b4f8dc5bde8834ad5894a8db35fda9efa1fe"
368492
493+[[package]]
494+name = "unicode-width"
495+version = "0.1.11"
496+source = "registry+https://github.com/rust-lang/crates.io-index"
497+checksum = "e51733f11c9c4f72aa0c160008246859e340b00807569a0da0e7a1079b27ba85"
498+
369499[[package]]
370500name = "utf8parse"
371501version = "0.2.2"
372502source = "registry+https://github.com/rust-lang/crates.io-index"
373503checksum = "06abde3611657adf66d383f00b093d7faecc7fa57071cce2578660c9f1010821"
374504
505+[[package]]
506+name = "version_check"
507+version = "0.9.5"
508+source = "registry+https://github.com/rust-lang/crates.io-index"
509+checksum = "0b928f33d975fc6ad9f86c8f283853ad26bdd5b10b7f1542aa2fa15e2289105a"
510+
375511[[package]]
376512name = "wasm-bindgen"
377513version = "0.2.95"
@@ -394,7 +530,7 @@ dependencies = [
394530 "once_cell",
395531 "proc-macro2",
396532 "quote",
397− "syn",
533+ "syn 2.0.85",
398534 "wasm-bindgen-shared",
399535]
400536
@@ -416,7 +552,7 @@ checksum = "26c6ab57572f7a24a4985830b120de1594465e5d500f24afe89e16b4e833ef68"
416552dependencies = [
417553 "proc-macro2",
418554 "quote",
419− "syn",
555+ "syn 2.0.85",
420556 "wasm-bindgen-backend",
421557 "wasm-bindgen-shared",
422558]
nock/Cargo.toml+7
@@ -17,6 +17,9 @@ stacker = "0.1.17"
1717murmur3 = "0.5.2"
1818web-sys = "0.3.70"
1919fplist = "0.2.1"
20+ctrlc = "3.4.5"
21+lazy_static = "1.5.0"
22+tabled = "0.16.0"
2023
2124[dependencies.xxhash-rust]
2225version = "0.8.5"
@@ -26,6 +29,9 @@ features = ["xxh3"]
2629# Tell `rustc` to optimize for small code size.
2730opt-level = 3
2831
32+[features]
33+count-jets = []
34+
2935[[bin]]
3036name = "nock"
3137path = "src/main.rs"
@@ -33,3 +39,4 @@ path = "src/main.rs"
3339[[bin]]
3440name = "hash-gate"
3541path = "src/hash-gate.rs"
42+
nock/src/interpreter.rs+41−1
@@ -1,15 +1,23 @@
11use core::str;
22use std::borrow::Borrow;
33use std::collections::BTreeMap;
4+use std::collections::HashMap;
45use std::rc::Rc;
6+use std::sync::Mutex;
57
68use fplist::cons;
79use fplist::PersistentList;
10+use lazy_static::lazy_static;
811use num_bigint::BigUint;
912
1013use crate::jets::*;
1114use crate::noun::*;
1215
16+// #[cfg(feature = "count-jets")]
17+lazy_static! {
18+ pub static ref JET_COUNTER: Mutex<HashMap<Atom, u32>> = Mutex::new(HashMap::new());
19+}
20+
1321#[derive(Clone)]
1422pub struct Nouns {
1523 pub y: Rc<Noun>,
@@ -24,6 +32,7 @@ pub struct Nouns {
2432 pub memo: Rc<Noun>,
2533 pub mean: Rc<Noun>,
2634 pub slog: Rc<Noun>,
35+ pub fast: Rc<Noun>,
2736}
2837
2938#[derive(Clone)]
@@ -65,6 +74,7 @@ pub fn generate_interpreter_context() -> InterpreterContext {
6574 let memo = Rc::new(Noun::from_bytes(b"memo"));
6675 let mean = Rc::new(Noun::from_bytes(b"mean"));
6776 let slog = Rc::new(Noun::from_bytes(b"slog"));
77+ let fast = Rc::new(Noun::from_bytes(b"fast"));
6878 InterpreterContext {
6979 jets,
7080 double_jets,
@@ -81,6 +91,7 @@ pub fn generate_interpreter_context() -> InterpreterContext {
8191 memo,
8292 mean,
8393 slog,
94+ fast,
8495 },
8596 big_uints,
8697 memo: BTreeMap::new(),
@@ -304,6 +315,28 @@ fn tar_u32<'a>(
304315
305316 (ctx.slog)(&ram(ctx, tank.clone()).unwrap_or(String::new()));
306317 eval(ctx)
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();
321+ match tag {
322+ None => (),
323+ Some(tag) => {
324+ let mut counter = JET_COUNTER.lock().unwrap();
325+ match counter.get(tag) {
326+ None => {
327+ counter.insert(tag.clone(), 1);
328+ ()
329+ }
330+ Some(v) => {
331+ let v = *v;
332+ counter.insert(tag.clone(), v + 1);
333+ ()
334+ }
335+ }
336+ }
337+ }
338+ }
339+ eval(ctx)
307340 } else {
308341 eval(ctx)
309342 }
@@ -401,8 +434,15 @@ fn ram(ctx: &mut InterpreterContext, tank: Rc<Noun>) -> Option<String> {
401434pub fn ram_ttanks(ctx: &mut InterpreterContext, tanks: TTanks) -> String {
402435 let mut target = String::new();
403436
404− for tank in tanks.iter() {
437+ let mut first = true;
438+ for tank in tanks.iter().collect::<Vec<_>>().iter().cloned().rev() {
439+ if !first {
440+ target.push('\n');
441+ }
442+
405443 target.push_str(&*ram_ttank(ctx, tank.clone()));
444+
445+ first = false;
406446 }
407447
408448 target
nock/src/jets.rs+171−2
@@ -2,14 +2,15 @@ use core::panic;
22use murmur3::murmur3_32;
33use num_integer::Integer;
44use std::{
5+ borrow::Borrow,
56 collections::BTreeMap,
67 iter::{once, repeat_n, zip},
78 rc::Rc,
89};
910
1011use crate::{
11− interpreter::{slam_pulled_gate, InterpreterContext, TTanks},
12− noun::{self, cell, Atom, Edge, Hair, Nail, Noun},
12+ interpreter::{slam_pulled_gate, InterpreterContext, TTanks, EMPTY_TANKS},
13+ noun::{self, cell, AsNoun, Atom, Edge, Hair, Nail, Noun},
1314};
1415
1516fn traverse_iter_result<E: Clone, T: Clone, I: Iterator<Item = Result<T, E>>>(
@@ -107,6 +108,11 @@ pub fn generate_jets() -> Jets {
107108 (124976064672625230427889101290245200507, TRIP),
108109 (4078279288073906183633157465551067635, MUK),
109110 (261900159748071234702685239353558471892, MUG),
111+ (198191257620924788695943358402651905954, AOR),
112+ (299422828284010240628877806738195667652, DOR),
113+ (166326796552601297695313176538120818632, GOR),
114+ (7942398240152905363972500667649380756, MOR),
115+ (315687984998079865981003916817293521765, LOOK),
110116 ])
111117}
112118
@@ -1007,6 +1013,169 @@ static MUK: Jet = |_ctx, n| {
10071013 Ok(Rc::new(Noun::from_u32(muk(seed, len, key))))
10081014};
10091015
1016+static AOR: Jet = |ctx, n| {
1017+ let (a, b) = n.as_cell().ok_or(EMPTY_TANKS)?;
1018+
1019+ if a == b {
1020+ Ok(ctx.nouns.y.clone())
1021+ } else {
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, .. }) => {
1025+ if a_p == b_p {
1026+ AOR(ctx, &cell(a_q, b_q))
1027+ } else {
1028+ AOR(ctx, &cell(a_p, b_p))
1029+ }
1030+ }
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();
1035+
1036+ let mut i = 0;
1037+ loop {
1038+ let c = a.get(i).unwrap_or(&0);
1039+ let d = b.get(i).unwrap_or(&0);
1040+
1041+ if a[0] == b[0] {
1042+ i += 1;
1043+ } else {
1044+ if c < d {
1045+ return Ok(ctx.nouns.y.clone());
1046+ } else {
1047+ return Ok(ctx.nouns.n.clone());
1048+ }
1049+ }
1050+ }
1051+ }
1052+ }
1053+ }
1054+};
1055+
1056+static DOR: Jet = |ctx, n| {
1057+ let (a, b) = n.as_cell().ok_or(EMPTY_TANKS)?;
1058+
1059+ if a == b {
1060+ Ok(ctx.nouns.y.clone())
1061+ } else {
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, .. }) => {
1065+ if a_p == b_p {
1066+ DOR(ctx, &cell(a_q, b_q))
1067+ } else {
1068+ DOR(ctx, &cell(a_p, b_p))
1069+ }
1070+ }
1071+ (Noun::Atom(_), Noun::Cell { .. }) => Ok(ctx.nouns.y.clone()),
1072+ (Noun::Atom(a), Noun::Atom(b)) => {
1073+ if a < b {
1074+ Ok(ctx.nouns.y.clone())
1075+ } else {
1076+ Ok(ctx.nouns.n.clone())
1077+ }
1078+ }
1079+ }
1080+ }
1081+};
1082+
1083+static GOR: Jet = |ctx, n| {
1084+ let (a, b) = n.as_cell().ok_or(EMPTY_TANKS)?;
1085+ let c = a.mug();
1086+ let d = b.mug();
1087+
1088+ if c == d {
1089+ DOR(ctx, n)
1090+ } else {
1091+ if c < d {
1092+ Ok(ctx.nouns.y.clone())
1093+ } else {
1094+ Ok(ctx.nouns.n.clone())
1095+ }
1096+ }
1097+};
1098+
1099+static GOR_PAIR: fn(&mut InterpreterContext, &Rc<Noun>, &Rc<Noun>) -> Result<bool, TTanks> =
1100+ |ctx, a, b| {
1101+ let c = a.mug();
1102+ let d = b.mug();
1103+
1104+ if c == d {
1105+ Ok(DOR(ctx, &(a.clone(), b.clone()).as_noun())? == ctx.nouns.y)
1106+ } else {
1107+ Ok(c < d)
1108+ }
1109+ };
1110+
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();
1115+
1116+ if c == d {
1117+ DOR(ctx, n)
1118+ } else {
1119+ if c < d {
1120+ Ok(ctx.nouns.y.clone())
1121+ } else {
1122+ Ok(ctx.nouns.n.clone())
1123+ }
1124+ }
1125+};
1126+
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)
1130+};
1131+
1132+static LOOK_PAIR: fn(
1133+ &mut InterpreterContext,
1134+ Atom,
1135+ &Rc<Noun>,
1136+ &Rc<Noun>,
1137+) -> Result<Rc<Noun>, TTanks> = |ctx, axe, cog, dab| {
1138+ if dab.is_sig() {
1139+ Ok(ctx.nouns.sig.clone())
1140+ } else {
1141+ let (node, b, c) = dab.tuple_3().ok_or(EMPTY_TANKS)?;
1142+ let l = b;
1143+ let r = c;
1144+ let (p, q) = node.as_cell().ok_or(EMPTY_TANKS)?;
1145+ if b.is_sig() && c.is_sig() {
1146+ if cog == p {
1147+ Ok((ctx.nouns.sig.clone(), Noun::Atom(axe), q.clone()).as_noun())
1148+ } else {
1149+ Ok(ctx.nouns.sig.clone())
1150+ }
1151+ } else if b.is_sig() {
1152+ if cog == p {
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())
1156+ } else {
1157+ LOOK_PAIR(ctx, PEG_U32(&axe, 3), cog, r)
1158+ }
1159+ } else if c.is_sig() {
1160+ if cog == p {
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)
1164+ } else {
1165+ Ok(ctx.nouns.sig.clone())
1166+ }
1167+ } else {
1168+ if cog == p {
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)
1172+ } else {
1173+ LOOK_PAIR(ctx, PEG_U32(&axe, 7), cog, r)
1174+ }
1175+ }
1176+ }
1177+};
1178+
10101179static JUST: DoubleJet = |ctx, n, m| {
10111180 let char = n.as_atom()?;
10121181 let nail = m.as_nail()?;
nock/src/main.rs+33−1
@@ -1,6 +1,8 @@
11use clap::{command, error::Result, Parser, Subcommand};
22use core::str;
3−use nock::interpreter::{ram_ttanks, slam_pulled_gate, tar, InterpreterContext, TTanks};
3+use nock::interpreter::{
4+ ram_ttanks, slam_pulled_gate, tar, InterpreterContext, TTanks, JET_COUNTER,
5+};
46use nock::{
57 cue::cue_bytes,
68 interpreter::{generate_interpreter_context, slam},
@@ -65,7 +67,33 @@ enum RunCommand {
6567 },
6668}
6769
70+fn print_jet_counter() {
71+ let counter = JET_COUNTER.lock().unwrap();
72+ let mut builder = tabled::builder::Builder::new();
73+ builder.push_record(vec!["jet", "number of calls"]);
74+ let mut counters = counter.iter().collect::<Vec<_>>();
75+ counters.sort_unstable_by_key(|x| x.1);
76+ for (key, count) in counters {
77+ let key = String::from_utf8(key.to_bytes_le()).unwrap();
78+ builder.push_record(vec![key, count.to_string()]);
79+ }
80+ println!(
81+ "\n{}",
82+ builder
83+ .build()
84+ .with(tabled::settings::style::Style::rounded())
85+ );
86+}
87+
6888fn main() -> Result<(), std::io::Error> {
89+ if cfg!(feature = "count-jets") {
90+ ctrlc::set_handler(|| {
91+ print_jet_counter();
92+ exit(1);
93+ })
94+ .unwrap();
95+ }
96+
6997 let urbit = LazyCell::new(GENERATE_URBIT);
7098 let mut ctx = InterpreterContext {
7199 // slog: |_| {},
@@ -145,6 +173,10 @@ fn main() -> Result<(), std::io::Error> {
145173 }
146174 }
147175
176+ if cfg!(feature = "count-jets") {
177+ print_jet_counter()
178+ }
179+
148180 Ok(())
149181}
150182
nock/src/noun.rs+6
@@ -305,6 +305,12 @@ pub trait AsNoun {
305305 fn as_noun(self: &Self) -> Rc<Noun>;
306306}
307307
308+impl AsNoun for Atom {
309+ fn as_noun(self: &Self) -> Rc<Noun> {
310+ Rc::new(Noun::Atom(self.clone()))
311+ }
312+}
313+
308314impl AsNoun for Noun {
309315 fn as_noun(self: &Self) -> Rc<Noun> {
310316 Rc::new(self.clone())
nock/test.hoonnew file+3
@@ -0,0 +1,3 @@
1+|= *
2+=/ target (gor 'd' 'c')
3+(crip "{<target>}")