on master help sign in
initial jam
commit5590be1824498a9627a17f053c50e2a12ae94ac4 authoriko <mail@iko.soy> dateTue 27 Aug 2024, 20:24 (2 years ago) parenta1c62e3
9 files changed+534−25
nock/Cargo.lock+285−9 nock/Cargo.toml+5 nock/flake.nix+1 nock/src/serialization.rs → nock/src/cue.rs+1−1 nock/src/hash-gate.rs+2−1 nock/src/jam.rs+87 nock/src/lib.rs+3−1 nock/src/main.rs+114−11 nock/src/noun.rs+36−2
nock/Cargo.lock+285−9
@@ -2,18 +2,85 @@
22# It is not intended for manual editing.
33version = 3
44
5+[[package]]
6+name = "anstream"
7+version = "0.6.15"
8+source = "registry+https://github.com/rust-lang/crates.io-index"
9+checksum = "64e15c1ab1f89faffbf04a634d5e1962e9074f2741eef6d97f3c4e322426d526"
10+dependencies = [
11+ "anstyle",
12+ "anstyle-parse",
13+ "anstyle-query",
14+ "anstyle-wincon",
15+ "colorchoice",
16+ "is_terminal_polyfill",
17+ "utf8parse",
18+]
19+
20+[[package]]
21+name = "anstyle"
22+version = "1.0.8"
23+source = "registry+https://github.com/rust-lang/crates.io-index"
24+checksum = "1bec1de6f59aedf83baf9ff929c98f2ad654b97c9510f4e70cf6f661d49fd5b1"
25+
26+[[package]]
27+name = "anstyle-parse"
28+version = "0.2.5"
29+source = "registry+https://github.com/rust-lang/crates.io-index"
30+checksum = "eb47de1e80c2b463c735db5b217a0ddc39d612e7ac9e2e96a5aed1f57616c1cb"
31+dependencies = [
32+ "utf8parse",
33+]
34+
35+[[package]]
36+name = "anstyle-query"
37+version = "1.1.1"
38+source = "registry+https://github.com/rust-lang/crates.io-index"
39+checksum = "6d36fc52c7f6c869915e99412912f22093507da8d9e942ceaf66fe4b7c14422a"
40+dependencies = [
41+ "windows-sys 0.52.0",
42+]
43+
44+[[package]]
45+name = "anstyle-wincon"
46+version = "3.0.4"
47+source = "registry+https://github.com/rust-lang/crates.io-index"
48+checksum = "5bf74e1b6e971609db8ca7a9ce79fd5768ab6ae46441c572e46cf596f59e57f8"
49+dependencies = [
50+ "anstyle",
51+ "windows-sys 0.52.0",
52+]
53+
554[[package]]
655name = "autocfg"
756version = "1.3.0"
857source = "registry+https://github.com/rust-lang/crates.io-index"
958checksum = "0c4b4d0bd25bd0b74681c0ad21497610ce1b7c91b1022cd21c80c6fbdd9476b0"
1059
60+[[package]]
61+name = "bit-vec"
62+version = "0.8.0"
63+source = "registry+https://github.com/rust-lang/crates.io-index"
64+checksum = "5e764a1d40d510daf35e07be9eb06e75770908c27d411ee6c92109c9840eaaf7"
65+
1166[[package]]
1267name = "bitter"
1368version = "0.7.0"
1469source = "registry+https://github.com/rust-lang/crates.io-index"
1570checksum = "ef3a13b71496a92e8c00ebe576b260655b56935cd5118d5a8949788b651b5e07"
1671
72+[[package]]
73+name = "bitvec"
74+version = "1.0.1"
75+source = "registry+https://github.com/rust-lang/crates.io-index"
76+checksum = "1bc2832c24239b0141d5674bb9174f9d68a8b5b3f2753311927c172ca46f7e9c"
77+dependencies = [
78+ "funty",
79+ "radium",
80+ "tap",
81+ "wyz",
82+]
83+
1784[[package]]
1885name = "bumpalo"
1986version = "3.16.0"
@@ -35,6 +102,62 @@ version = "1.0.0"
35102source = "registry+https://github.com/rust-lang/crates.io-index"
36103checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd"
37104
105+[[package]]
106+name = "clap"
107+version = "4.5.16"
108+source = "registry+https://github.com/rust-lang/crates.io-index"
109+checksum = "ed6719fffa43d0d87e5fd8caeab59be1554fb028cd30edc88fc4369b17971019"
110+dependencies = [
111+ "clap_builder",
112+ "clap_derive",
113+]
114+
115+[[package]]
116+name = "clap_builder"
117+version = "4.5.15"
118+source = "registry+https://github.com/rust-lang/crates.io-index"
119+checksum = "216aec2b177652e3846684cbfe25c9964d18ec45234f0f5da5157b207ed1aab6"
120+dependencies = [
121+ "anstream",
122+ "anstyle",
123+ "clap_lex",
124+ "strsim",
125+]
126+
127+[[package]]
128+name = "clap_derive"
129+version = "4.5.13"
130+source = "registry+https://github.com/rust-lang/crates.io-index"
131+checksum = "501d359d5f3dcaf6ecdeee48833ae73ec6e42723a1e52419c79abf9507eec0a0"
132+dependencies = [
133+ "heck",
134+ "proc-macro2",
135+ "quote",
136+ "syn",
137+]
138+
139+[[package]]
140+name = "clap_lex"
141+version = "0.7.2"
142+source = "registry+https://github.com/rust-lang/crates.io-index"
143+checksum = "1462739cb27611015575c0c11df5df7601141071f07518d56fcc1be504cbec97"
144+
145+[[package]]
146+name = "colorchoice"
147+version = "1.0.2"
148+source = "registry+https://github.com/rust-lang/crates.io-index"
149+checksum = "d3fd119d74b830634cea2a0f58bbd0d54540518a14397557951e79340abc28c0"
150+
151+[[package]]
152+name = "colored"
153+version = "2.1.0"
154+source = "registry+https://github.com/rust-lang/crates.io-index"
155+checksum = "cbf2150cce219b664a8a70df7a1f933836724b503f8a413af9365b4dcc4d90b8"
156+dependencies = [
157+ "lazy_static",
158+ "windows-sys 0.48.0",
159+]
160+
38161[[package]]
39162name = "console_error_panic_hook"
40163version = "0.1.7"
@@ -45,6 +168,24 @@ dependencies = [
45168 "wasm-bindgen",
46169]
47170
171+[[package]]
172+name = "funty"
173+version = "2.0.0"
174+source = "registry+https://github.com/rust-lang/crates.io-index"
175+checksum = "e6d5a32815ae3f33302d95fdcb2ce17862f8c65363dcfd29360480ba1001fc9c"
176+
177+[[package]]
178+name = "heck"
179+version = "0.5.0"
180+source = "registry+https://github.com/rust-lang/crates.io-index"
181+checksum = "2304e00983f87ffb38b55b444b5e3b60a884b5d30c0fca7d82fe33449bbe55ea"
182+
183+[[package]]
184+name = "is_terminal_polyfill"
185+version = "1.70.1"
186+source = "registry+https://github.com/rust-lang/crates.io-index"
187+checksum = "7943c866cc5cd64cbc25b2e01621d07fa8eb2a1a23160ee81ce38704e97b8ecf"
188+
48189[[package]]
49190name = "js-sys"
50191version = "0.3.70"
@@ -54,6 +195,12 @@ dependencies = [
54195 "wasm-bindgen",
55196]
56197
198+[[package]]
199+name = "lazy_static"
200+version = "1.5.0"
201+source = "registry+https://github.com/rust-lang/crates.io-index"
202+checksum = "bbd2bcb4c963f2ddae06a2efc7e9f3591312473c50c6685e1f298068316e66fe"
203+
57204[[package]]
58205name = "log"
59206version = "0.4.22"
@@ -74,11 +221,15 @@ dependencies = [
74221name = "nock"
75222version = "0.1.0"
76223dependencies = [
224+ "bit-vec",
77225 "bitter",
226+ "bitvec",
227+ "clap",
78228 "console_error_panic_hook",
79229 "num-bigint",
80230 "num-integer",
81231 "num-traits",
232+ "spinoff",
82233 "wasm-bindgen",
83234 "wasm-bindgen-test",
84235 "xxhash-rust",
@@ -118,6 +269,12 @@ version = "1.19.0"
118269source = "registry+https://github.com/rust-lang/crates.io-index"
119270checksum = "3fdb12b2476b595f9358c5161aa467c2438859caa136dec86c26fdd2efe17b92"
120271
272+[[package]]
273+name = "paste"
274+version = "1.0.15"
275+source = "registry+https://github.com/rust-lang/crates.io-index"
276+checksum = "57c0d7b74b563b49d38dae00a0c37d4d6de9b432382b2892f0574ddcae73fd0a"
277+
121278[[package]]
122279name = "proc-macro2"
123280version = "1.0.86"
@@ -136,6 +293,12 @@ dependencies = [
136293 "proc-macro2",
137294]
138295
296+[[package]]
297+name = "radium"
298+version = "0.7.0"
299+source = "registry+https://github.com/rust-lang/crates.io-index"
300+checksum = "dc33ff2d4973d518d823d61aa239014831e521c75da58e3df4840d3f47749d09"
301+
139302[[package]]
140303name = "same-file"
141304version = "1.0.6"
@@ -157,6 +320,23 @@ version = "1.3.0"
157320source = "registry+https://github.com/rust-lang/crates.io-index"
158321checksum = "0fda2ff0d084019ba4d7c6f371c95d8fd75ce3524c3cb8fb653a3023f6323e64"
159322
323+[[package]]
324+name = "spinoff"
325+version = "0.8.0"
326+source = "registry+https://github.com/rust-lang/crates.io-index"
327+checksum = "20aa2ed67fbb202e7b716ff8bfc6571dd9301617767380197d701c31124e88f6"
328+dependencies = [
329+ "colored",
330+ "once_cell",
331+ "paste",
332+]
333+
334+[[package]]
335+name = "strsim"
336+version = "0.11.1"
337+source = "registry+https://github.com/rust-lang/crates.io-index"
338+checksum = "7da8b5736845d9f2fcb837ea5d9e2628564b3b043a70948a3f0b778838c5fb4f"
339+
160340[[package]]
161341name = "syn"
162342version = "2.0.74"
@@ -168,12 +348,24 @@ dependencies = [
168348 "unicode-ident",
169349]
170350
351+[[package]]
352+name = "tap"
353+version = "1.0.1"
354+source = "registry+https://github.com/rust-lang/crates.io-index"
355+checksum = "55937e1799185b12863d447f42597ed69d9928686b8d88a1df17376a097d8369"
356+
171357[[package]]
172358name = "unicode-ident"
173359version = "1.0.12"
174360source = "registry+https://github.com/rust-lang/crates.io-index"
175361checksum = "3354b9ac3fae1ff6755cb6db53683adb661634f67557942dea4facebec0fee4b"
176362
363+[[package]]
364+name = "utf8parse"
365+version = "0.2.2"
366+source = "registry+https://github.com/rust-lang/crates.io-index"
367+checksum = "06abde3611657adf66d383f00b093d7faecc7fa57071cce2578660c9f1010821"
368+
177369[[package]]
178370name = "walkdir"
179371version = "2.5.0"
@@ -293,7 +485,25 @@ version = "0.1.9"
293485source = "registry+https://github.com/rust-lang/crates.io-index"
294486checksum = "cf221c93e13a30d793f7645a0e7762c55d169dbb0a49671918a2319d289b10bb"
295487dependencies = [
296− "windows-sys",
488+ "windows-sys 0.59.0",
489+]
490+
491+[[package]]
492+name = "windows-sys"
493+version = "0.48.0"
494+source = "registry+https://github.com/rust-lang/crates.io-index"
495+checksum = "677d2418bec65e3338edb076e806bc1ec15693c5d0104683f2efe857f61056a9"
496+dependencies = [
497+ "windows-targets 0.48.5",
498+]
499+
500+[[package]]
501+name = "windows-sys"
502+version = "0.52.0"
503+source = "registry+https://github.com/rust-lang/crates.io-index"
504+checksum = "282be5f36a8ce781fad8c8ae18fa3f9beff57ec1b52cb3de0789201425d9a33d"
505+dependencies = [
506+ "windows-targets 0.52.6",
297507]
298508
299509[[package]]
@@ -302,7 +512,22 @@ version = "0.59.0"
302512source = "registry+https://github.com/rust-lang/crates.io-index"
303513checksum = "1e38bc4d79ed67fd075bcc251a1c39b32a1776bbe92e5bef1f0bf1f8c531853b"
304514dependencies = [
305− "windows-targets",
515+ "windows-targets 0.52.6",
516+]
517+
518+[[package]]
519+name = "windows-targets"
520+version = "0.48.5"
521+source = "registry+https://github.com/rust-lang/crates.io-index"
522+checksum = "9a2fa6e2155d7247be68c096456083145c183cbbbc2764150dda45a87197940c"
523+dependencies = [
524+ "windows_aarch64_gnullvm 0.48.5",
525+ "windows_aarch64_msvc 0.48.5",
526+ "windows_i686_gnu 0.48.5",
527+ "windows_i686_msvc 0.48.5",
528+ "windows_x86_64_gnu 0.48.5",
529+ "windows_x86_64_gnullvm 0.48.5",
530+ "windows_x86_64_msvc 0.48.5",
306531]
307532
308533[[package]]
@@ -311,28 +536,46 @@ version = "0.52.6"
311536source = "registry+https://github.com/rust-lang/crates.io-index"
312537checksum = "9b724f72796e036ab90c1021d4780d4d3d648aca59e491e6b98e725b84e99973"
313538dependencies = [
314− "windows_aarch64_gnullvm",
315− "windows_aarch64_msvc",
316− "windows_i686_gnu",
539+ "windows_aarch64_gnullvm 0.52.6",
540+ "windows_aarch64_msvc 0.52.6",
541+ "windows_i686_gnu 0.52.6",
317542 "windows_i686_gnullvm",
318− "windows_i686_msvc",
319− "windows_x86_64_gnu",
320− "windows_x86_64_gnullvm",
321− "windows_x86_64_msvc",
543+ "windows_i686_msvc 0.52.6",
544+ "windows_x86_64_gnu 0.52.6",
545+ "windows_x86_64_gnullvm 0.52.6",
546+ "windows_x86_64_msvc 0.52.6",
322547]
323548
549+[[package]]
550+name = "windows_aarch64_gnullvm"
551+version = "0.48.5"
552+source = "registry+https://github.com/rust-lang/crates.io-index"
553+checksum = "2b38e32f0abccf9987a4e3079dfb67dcd799fb61361e53e2882c3cbaf0d905d8"
554+
324555[[package]]
325556name = "windows_aarch64_gnullvm"
326557version = "0.52.6"
327558source = "registry+https://github.com/rust-lang/crates.io-index"
328559checksum = "32a4622180e7a0ec044bb555404c800bc9fd9ec262ec147edd5989ccd0c02cd3"
329560
561+[[package]]
562+name = "windows_aarch64_msvc"
563+version = "0.48.5"
564+source = "registry+https://github.com/rust-lang/crates.io-index"
565+checksum = "dc35310971f3b2dbbf3f0690a219f40e2d9afcf64f9ab7cc1be722937c26b4bc"
566+
330567[[package]]
331568name = "windows_aarch64_msvc"
332569version = "0.52.6"
333570source = "registry+https://github.com/rust-lang/crates.io-index"
334571checksum = "09ec2a7bb152e2252b53fa7803150007879548bc709c039df7627cabbd05d469"
335572
573+[[package]]
574+name = "windows_i686_gnu"
575+version = "0.48.5"
576+source = "registry+https://github.com/rust-lang/crates.io-index"
577+checksum = "a75915e7def60c94dcef72200b9a8e58e5091744960da64ec734a6c6e9b3743e"
578+
336579[[package]]
337580name = "windows_i686_gnu"
338581version = "0.52.6"
@@ -345,30 +588,63 @@ version = "0.52.6"
345588source = "registry+https://github.com/rust-lang/crates.io-index"
346589checksum = "0eee52d38c090b3caa76c563b86c3a4bd71ef1a819287c19d586d7334ae8ed66"
347590
591+[[package]]
592+name = "windows_i686_msvc"
593+version = "0.48.5"
594+source = "registry+https://github.com/rust-lang/crates.io-index"
595+checksum = "8f55c233f70c4b27f66c523580f78f1004e8b5a8b659e05a4eb49d4166cca406"
596+
348597[[package]]
349598name = "windows_i686_msvc"
350599version = "0.52.6"
351600source = "registry+https://github.com/rust-lang/crates.io-index"
352601checksum = "240948bc05c5e7c6dabba28bf89d89ffce3e303022809e73deaefe4f6ec56c66"
353602
603+[[package]]
604+name = "windows_x86_64_gnu"
605+version = "0.48.5"
606+source = "registry+https://github.com/rust-lang/crates.io-index"
607+checksum = "53d40abd2583d23e4718fddf1ebec84dbff8381c07cae67ff7768bbf19c6718e"
608+
354609[[package]]
355610name = "windows_x86_64_gnu"
356611version = "0.52.6"
357612source = "registry+https://github.com/rust-lang/crates.io-index"
358613checksum = "147a5c80aabfbf0c7d901cb5895d1de30ef2907eb21fbbab29ca94c5b08b1a78"
359614
615+[[package]]
616+name = "windows_x86_64_gnullvm"
617+version = "0.48.5"
618+source = "registry+https://github.com/rust-lang/crates.io-index"
619+checksum = "0b7b52767868a23d5bab768e390dc5f5c55825b6d30b86c844ff2dc7414044cc"
620+
360621[[package]]
361622name = "windows_x86_64_gnullvm"
362623version = "0.52.6"
363624source = "registry+https://github.com/rust-lang/crates.io-index"
364625checksum = "24d5b23dc417412679681396f2b49f3de8c1473deb516bd34410872eff51ed0d"
365626
627+[[package]]
628+name = "windows_x86_64_msvc"
629+version = "0.48.5"
630+source = "registry+https://github.com/rust-lang/crates.io-index"
631+checksum = "ed94fce61571a4006852b7389a063ab983c02eb1bb37b47f8272ce92d06d9538"
632+
366633[[package]]
367634name = "windows_x86_64_msvc"
368635version = "0.52.6"
369636source = "registry+https://github.com/rust-lang/crates.io-index"
370637checksum = "589f6da84c646204747d1270a2a5661ea66ed1cced2631d546fdfb155959f9ec"
371638
639+[[package]]
640+name = "wyz"
641+version = "0.5.1"
642+source = "registry+https://github.com/rust-lang/crates.io-index"
643+checksum = "05f360fc0b24296329c78fda852a1e9ae82de9cf7b27dae4b7f62f118f77b9ed"
644+dependencies = [
645+ "tap",
646+]
647+
372648[[package]]
373649name = "xxhash-rust"
374650version = "0.8.12"
nock/Cargo.toml+5
@@ -22,6 +22,11 @@ num-bigint = "0.4.6"
2222num-traits = "0.2.19"
2323bitter = "0.7.0"
2424num-integer = "0.1.46"
25+clap = { version = "4.5.16", features = ["derive"] }
26+spinoff = "0.8.0"
27+bit-vec = "0.8.0"
28+bitvec = "1.0.1"
29+
2530[dependencies.xxhash-rust]
2631version = "0.8.5"
2732features = ["xxh3"]
nock/flake.nix+1
@@ -21,6 +21,7 @@
2121 ]))
2222 wasm-pack
2323 wasm-tools
24+ cargo-flamegraph
2425 ];
2526 };
2627 });
nock/src/serialization.rs → nock/src/cue.rsrenamed+1−1
@@ -39,7 +39,7 @@ fn cue_reader(
3939 let mut a_iter = a.iter_u32_digits();
4040 match a_iter.len() {
4141 0 => 0,
42− 1 => a_iter.next().expect("invariant"),
42+ 1 => a_iter.next().unwrap(),
4343 _ => panic!(),
4444 }
4545 };
nock/src/hash-gate.rs+2−1
@@ -1,6 +1,7 @@
1−use nock::serialization::cue_bytes;
21use std::io::{self, Read};
32
3+use nock::cue::cue_bytes;
4+
45fn main() {
56 let mut jammed_input = Vec::new();
67 match io::stdin().read_to_end(&mut jammed_input) {
nock/src/jam.rsnew file+87
@@ -0,0 +1,87 @@
1+use std::{collections::BTreeMap, rc::Rc};
2+
3+use bitvec::vec::BitVec;
4+use num_traits::FromPrimitive;
5+
6+use crate::noun::{Atom, Noun};
7+
8+pub fn jam_to_bytes(noun: Rc<Noun>) -> Vec<u8> {
9+ let mut vec: BitVec<u8> = BitVec::new();
10+ jam(noun, &mut vec, &mut BTreeMap::new());
11+ vec.into_vec()
12+}
13+
14+fn jam(noun: Rc<Noun>, vec: &mut BitVec<u8>, refs: &mut BTreeMap<Noun, usize>) {
15+ let offset = vec.len();
16+
17+ match refs.get(&noun).cloned() {
18+ Some(id) => {
19+ let id = Atom::from_usize(id).unwrap();
20+ if let Noun::Atom(a) = (*noun).clone()
21+ && a.bits() <= id.bits()
22+ {
23+ vec.push(false);
24+ mat(&a, vec);
25+ } else {
26+ vec.push(true);
27+ vec.push(true);
28+ mat(&id, vec);
29+ }
30+ }
31+ None => {
32+ refs.insert((*noun).clone(), offset);
33+
34+ match (*noun).clone() {
35+ Noun::Atom(a) => {
36+ vec.push(false);
37+ mat(&a, vec);
38+ }
39+ Noun::Cell { p, q, .. } => {
40+ vec.push(true);
41+ vec.push(false);
42+ jam(p, vec, refs);
43+ jam(q, vec, refs);
44+ }
45+ }
46+ }
47+ }
48+}
49+
50+fn mat(atom: &Atom, vec: &mut BitVec<u8>) {
51+ if *atom == Atom::ZERO {
52+ vec.push(true);
53+ } else {
54+ vec.push(false);
55+
56+ encode_length(atom.bits() as usize, vec);
57+
58+ for b in 0..atom.bits() {
59+ vec.push(atom.bit(b));
60+ }
61+ }
62+}
63+
64+fn encode_length(length: usize, vec: &mut BitVec<u8>) {
65+ for _ in 0..(number_of_bits(length) - 1) {
66+ vec.push(false);
67+ }
68+ vec.push(true);
69+
70+ let mut length = length;
71+
72+ while length > 1 {
73+ vec.push((length & 1) == 1);
74+ length = length >> 1;
75+ }
76+}
77+
78+fn number_of_bits(mut a: usize) -> usize {
79+ let mut target = 0;
80+
81+ while a > 0 {
82+ a = a >> 1;
83+ target += 1;
84+ }
85+
86+ target
87+}
nock/src/lib.rs+3−1
@@ -1,9 +1,11 @@
11#![feature(iter_intersperse)]
2+#![feature(let_chains)]
23#![feature(iter_repeat_n)]
4+pub mod cue;
35pub mod interpreter;
6+pub mod jam;
47mod jets;
58pub mod noun;
6−pub mod serialization;
79mod utils;
810
911use wasm_bindgen::prelude::*;
nock/src/main.rs+114−11
@@ -1,19 +1,122 @@
1+use clap::{command, error::Result, Parser, Subcommand};
12use nock::{
2− interpreter::{eval_gate, generate_interpreter_context},
3− serialization::cue_bytes,
3+ cue::cue_bytes,
4+ interpreter::{self, eval_gate, generate_interpreter_context, slam},
5+ jam::jam_to_bytes,
6+ noun::Noun,
47};
5−use std::io::{self, Read};
8+use spinoff::Spinner;
9+use std::{
10+ borrow::Borrow,
11+ fs::File,
12+ io::{self, stdin, stdout, Read, Write},
13+ panic::catch_unwind,
14+ path::PathBuf,
15+ process::exit,
16+ rc::Rc,
17+};
18+
19+#[derive(Parser)]
20+#[command(version)]
21+struct Cli {
22+ #[command(subcommand)]
23+ command: NockCommand,
24+}
25+
26+#[derive(Subcommand)]
27+enum NockCommand {
28+ Build {
29+ #[arg(value_name = "FILE.hoon")]
30+ root: PathBuf,
31+ #[arg(short, long, value_name = "FILE.nock")]
32+ output: PathBuf,
33+ },
34+ Run {
35+ #[command(subcommand)]
36+ command: RunCommand,
37+ },
38+ Cycle,
39+}
40+
41+#[derive(Subcommand)]
42+enum RunCommand {
43+ Interact {
44+ #[arg(value_name = "FILE.nock")]
45+ gate: PathBuf,
46+ },
47+}
48+
49+fn main() -> Result<(), std::io::Error> {
50+ let cli = Cli::parse();
51+
52+ match cli.command {
53+ NockCommand::Run { command } => match command {
54+ RunCommand::Interact { gate } => interact(gate)?,
55+ },
56+ NockCommand::Build { root, output } => todo!(),
57+ NockCommand::Cycle => {
58+ let mut source = Vec::new();
59+ stdin().read_to_end(&mut source).unwrap();
60+ let foo = cue_bytes(&source);
61+ let bat = jam_to_bytes(foo);
62+ stdout().write(&bat).unwrap();
63+ }
64+ }
65+
66+ Ok(())
67+
68+ // let mut jammed_input = Vec::new();
69+ // match io::stdin().read_to_end(&mut jammed_input) {
70+ // Err(err) => panic!("{err}"),
71+ // Ok(_) => (),
72+ // };
73+
74+ // let gate = cue_bytes(&jammed_input);
675
7−fn main() {
8− let mut jammed_input = Vec::new();
9− match io::stdin().read_to_end(&mut jammed_input) {
10− Err(err) => panic!("{err}"),
11− Ok(_) => (),
76+ // let result = eval_gate(&generate_interpreter_context(), gate);
77+
78+ // println!("{result}");
79+}
80+
81+fn interact(gate_file: PathBuf) -> Result<(), std::io::Error> {
82+ let mut spinner = new_spinner(format!("Loading {gate_file:#?}"));
83+ let Ok(gate) = read_nock(&gate_file) else {
84+ spinner.fail(&format!("Failed to load {gate_file:#?}"));
85+ exit(1);
86+ };
87+ spinner.success(&format!("Loaded {gate_file:#?}"));
88+
89+ let source = get_stdin().unwrap();
90+
91+ let mut spinner = new_spinner(String::from("Slamming gate..."));
92+ let Some(slam) = slam(&generate_interpreter_context(), gate, source) else {
93+ spinner.fail("Gate execution failed");
94+ exit(1);
1295 };
96+ let Some(target) = slam.as_bytes() else {
97+ spinner.fail("The gate did not produce a valid atom");
98+ exit(1);
99+ };
100+ spinner.success("Gate slammed successfully");
101+
102+ stdout().write_all(&target)?;
103+
104+ Ok(())
105+}
13106
14− let gate = cue_bytes(&jammed_input);
107+fn read_nock(nock_file: &PathBuf) -> Result<Rc<Noun>, std::io::Error> {
108+ let mut file = File::open(nock_file)?;
109+ let mut contents = Vec::new();
110+ file.read_to_end(&mut contents)?;
111+ Ok(cue_bytes(&contents))
112+}
15113
16− let result = eval_gate(&generate_interpreter_context(), gate).unwrap();
114+fn get_stdin() -> Result<Rc<Noun>, std::io::Error> {
115+ let mut contents = Vec::new();
116+ stdin().read_to_end(&mut contents)?;
117+ Ok(Rc::new(Noun::from_bytes(&contents)))
118+}
17119
18− println!("{result}");
120+fn new_spinner(txt: String) -> Spinner {
121+ Spinner::new_with_stream(spinoff::spinners::Dots, txt, None, spinoff::Streams::Stderr)
19122}
nock/src/noun.rs+36−2
@@ -1,4 +1,8 @@
1−use std::{rc::Rc, str::FromStr};
1+use std::{
2+ cmp::{self, Ordering},
3+ rc::Rc,
4+ str::FromStr,
5+};
26
37use num_bigint::BigUint;
48use std::fmt;
@@ -8,7 +12,7 @@ pub type Atom = BigUint;
812
913pub type Hash = u128;
1014
11−#[derive(Clone, Debug)]
15+#[derive(Clone, Debug, Eq)]
1216pub enum Noun {
1317 Atom(Atom),
1418 Cell {
@@ -18,6 +22,27 @@ pub enum Noun {
1822 },
1923}
2024
25+impl Ord for Noun {
26+ fn cmp(&self, other: &Self) -> Ordering {
27+ compare_nouns(self, other)
28+ }
29+}
30+
31+impl PartialOrd for Noun {
32+ fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
33+ Some(compare_nouns(self, other))
34+ }
35+}
36+
37+fn compare_nouns(p: &Noun, q: &Noun) -> Ordering {
38+ match (p, q) {
39+ (Noun::Atom(_), Noun::Cell { .. }) => Ordering::Less,
40+ (Noun::Cell { .. }, Noun::Atom(_)) => Ordering::Greater,
41+ (Noun::Atom(x), Noun::Atom(y)) => x.cmp(y),
42+ (Noun::Cell { hash: x, .. }, Noun::Cell { hash: y, .. }) => x.cmp(y),
43+ }
44+}
45+
2146impl PartialEq for Noun {
2247 fn eq(&self, other: &Self) -> bool {
2348 match (self, other) {
@@ -161,6 +186,15 @@ impl Noun {
161186 },
162187 }
163188 }
189+
190+ pub fn from_bytes(bytes: &[u8]) -> Self {
191+ Noun::Atom(Atom::from_bytes_le(bytes))
192+ }
193+
194+ pub fn as_bytes(self: &Self) -> Option<Vec<u8>> {
195+ let a = self.as_atom()?;
196+ Some(a.to_bytes_le())
197+ }
164198}
165199
166200#[derive(Clone)]