on 5513ecc help sign in
13 files changed+328−1270
since splitsnapshots
unifiedsplit
nock/Cargo.lock+5−141 nock/Cargo.toml−7 nock/hello.hoon+1−2 nock/hello.nock nock/src/interpreter.rs+54−225 nock/src/jets.rs+129−304 nock/src/lib.rs+37−2 nock/src/main.rs+18−44 nock/src/noun.rs−313 nock/test.hoon−3 nock/wock.hoon+10−198 wock-web/src/lib.rs+74−31 wock.nock
nock/Cargo.lock+5−141
@@ -1,6 +1,6 @@
11# This file is automatically @generated by Cargo.
22# It is not intended for manual editing.
3−version = 4
3+version = 3
44
55[[package]]
66name = "anstream"
@@ -63,12 +63,6 @@ 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−
7266[[package]]
7367name = "bitter"
7468version = "0.7.0"
@@ -93,12 +87,6 @@ version = "3.16.0"
9387source = "registry+https://github.com/rust-lang/crates.io-index"
9488checksum = "79296716171880943b8470b5f8d03aa55eb2e645a4874bdbb28adb49162e012c"
9589
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−
10290[[package]]
10391name = "cc"
10492version = "1.1.31"
@@ -114,12 +102,6 @@ version = "1.0.0"
114102source = "registry+https://github.com/rust-lang/crates.io-index"
115103checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd"
116104
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−
123105[[package]]
124106name = "clap"
125107version = "4.5.20"
@@ -148,10 +130,10 @@ version = "4.5.18"
148130source = "registry+https://github.com/rust-lang/crates.io-index"
149131checksum = "4ac6a0c7b1a9e9a5186361f67dfa1b88213572f427fb9ab038efb2bd8c582dab"
150132dependencies = [
151− "heck 0.5.0",
133+ "heck",
152134 "proc-macro2",
153135 "quote",
154− "syn 2.0.85",
136+ "syn",
155137]
156138
157139[[package]]
@@ -176,22 +158,6 @@ dependencies = [
176158 "windows-sys 0.48.0",
177159]
178160
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−
195161[[package]]
196162name = "fplist"
197163version = "0.2.1"
@@ -204,12 +170,6 @@ version = "2.0.0"
204170source = "registry+https://github.com/rust-lang/crates.io-index"
205171checksum = "e6d5a32815ae3f33302d95fdcb2ce17862f8c65363dcfd29360480ba1001fc9c"
206172
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−
213173[[package]]
214174name = "heck"
215175version = "0.5.0"
@@ -255,18 +215,6 @@ version = "0.5.2"
255215source = "registry+https://github.com/rust-lang/crates.io-index"
256216checksum = "9252111cf132ba0929b6f8e030cac2a24b507f3a4d6db6fb2896f27b354c714b"
257217
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−
270218[[package]]
271219name = "nock"
272220version = "0.1.0"
@@ -275,16 +223,13 @@ dependencies = [
275223 "bitter",
276224 "bitvec",
277225 "clap",
278− "ctrlc",
279226 "fplist",
280− "lazy_static",
281227 "murmur3",
282228 "num-bigint",
283229 "num-integer",
284230 "num-traits",
285231 "spinoff",
286232 "stacker",
287− "tabled",
288233 "web-sys",
289234 "xxhash-rust",
290235]
@@ -323,47 +268,12 @@ version = "1.20.2"
323268source = "registry+https://github.com/rust-lang/crates.io-index"
324269checksum = "1261fe7e33c73b354eab43b1273a57c8f967d0391e80353e51f764ac02cf6775"
325270
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−
337271[[package]]
338272name = "paste"
339273version = "1.0.15"
340274source = "registry+https://github.com/rust-lang/crates.io-index"
341275checksum = "57c0d7b74b563b49d38dae00a0c37d4d6de9b432382b2892f0574ddcae73fd0a"
342276
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−
367277[[package]]
368278name = "proc-macro2"
369279version = "1.0.89"
@@ -433,17 +343,6 @@ version = "0.11.1"
433343source = "registry+https://github.com/rust-lang/crates.io-index"
434344checksum = "7da8b5736845d9f2fcb837ea5d9e2628564b3b043a70948a3f0b778838c5fb4f"
435345
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−
447346[[package]]
448347name = "syn"
449348version = "2.0.85"
@@ -455,29 +354,6 @@ dependencies = [
455354 "unicode-ident",
456355]
457356
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−
481357[[package]]
482358name = "tap"
483359version = "1.0.1"
@@ -490,24 +366,12 @@ version = "1.0.13"
490366source = "registry+https://github.com/rust-lang/crates.io-index"
491367checksum = "e91b56cd4cadaeb79bbf1a5645f6b4f8dc5bde8834ad5894a8db35fda9efa1fe"
492368
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−
499369[[package]]
500370name = "utf8parse"
501371version = "0.2.2"
502372source = "registry+https://github.com/rust-lang/crates.io-index"
503373checksum = "06abde3611657adf66d383f00b093d7faecc7fa57071cce2578660c9f1010821"
504374
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−
511375[[package]]
512376name = "wasm-bindgen"
513377version = "0.2.95"
@@ -530,7 +394,7 @@ dependencies = [
530394 "once_cell",
531395 "proc-macro2",
532396 "quote",
533− "syn 2.0.85",
397+ "syn",
534398 "wasm-bindgen-shared",
535399]
536400
@@ -552,7 +416,7 @@ checksum = "26c6ab57572f7a24a4985830b120de1594465e5d500f24afe89e16b4e833ef68"
552416dependencies = [
553417 "proc-macro2",
554418 "quote",
555− "syn 2.0.85",
419+ "syn",
556420 "wasm-bindgen-backend",
557421 "wasm-bindgen-shared",
558422]
nock/Cargo.toml−7
@@ -17,9 +17,6 @@ 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"
2320
2421[dependencies.xxhash-rust]
2522version = "0.8.5"
@@ -29,9 +26,6 @@ features = ["xxh3"]
2926# Tell `rustc` to optimize for small code size.
3027opt-level = 3
3128
32−[features]
33−count-jets = []
34−
3529[[bin]]
3630name = "nock"
3731path = "src/main.rs"
@@ -39,4 +33,3 @@ path = "src/main.rs"
3933[[bin]]
4034name = "hash-gate"
4135path = "src/hash-gate.rs"
42−
nock/hello.hoon+1−2
@@ -1,6 +1,5 @@
11|= name=@t
2−~& name
32?+ name (crip (weld "Hello, " (trip name)))
43 'Curtis' 'Hello, daddy...'
5− %'' 'Hello, world!'
4+ '' 'Hello, world!'
65==
nock/hello.nock

Binary file not shown.

nock/src/interpreter.rs+54−225
@@ -1,23 +1,14 @@
1−use core::str;
21use std::borrow::Borrow;
32use std::collections::BTreeMap;
4−use std::collections::HashMap;
53use std::rc::Rc;
6−use std::sync::Mutex;
74
85use fplist::cons;
96use fplist::PersistentList;
10−use lazy_static::lazy_static;
117use num_bigint::BigUint;
128
139use crate::jets::*;
1410use crate::noun::*;
1511
16−// #[cfg(feature = "count-jets")]
17−lazy_static! {
18− pub static ref JET_COUNTER: Mutex<HashMap<Atom, u32>> = Mutex::new(HashMap::new());
19−}
20−
2112#[derive(Clone)]
2213pub struct Nouns {
2314 pub y: Rc<Noun>,
@@ -31,8 +22,6 @@ pub struct Nouns {
3122 pub two_three: Rc<Noun>,
3223 pub memo: Rc<Noun>,
3324 pub mean: Rc<Noun>,
34− pub slog: Rc<Noun>,
35− pub fast: Rc<Noun>,
3625}
3726
3827#[derive(Clone)]
@@ -51,7 +40,6 @@ pub struct InterpreterContext {
5140 pub nouns: Nouns,
5241 pub big_uints: BigUints,
5342 pub memo: BTreeMap<Hash, Rc<Noun>>,
54− pub slog: fn(&String) -> (),
5543}
5644
5745pub fn generate_interpreter_context() -> InterpreterContext {
@@ -73,8 +61,6 @@ pub fn generate_interpreter_context() -> InterpreterContext {
7361 let two_three = cell(&two, &three);
7462 let memo = Rc::new(Noun::from_bytes(b"memo"));
7563 let mean = Rc::new(Noun::from_bytes(b"mean"));
76− let slog = Rc::new(Noun::from_bytes(b"slog"));
77− let fast = Rc::new(Noun::from_bytes(b"fast"));
7864 InterpreterContext {
7965 jets,
8066 double_jets,
@@ -90,12 +76,9 @@ pub fn generate_interpreter_context() -> InterpreterContext {
9076 two_three,
9177 memo,
9278 mean,
93− slog,
94− fast,
9579 },
9680 big_uints,
9781 memo: BTreeMap::new(),
98− slog: |str: &String| eprintln!("{}", str),
9982 }
10083}
10184
@@ -106,7 +89,7 @@ fn wut<'a>(ctx: &'a InterpreterContext, noun: &Noun) -> &'a Rc<Noun> {
10689 }
10790}
10891
109−fn lus(noun: &Noun) -> Result<Noun, TTanks> {
92+fn lus(noun: &Noun) -> Result<Noun, Tanks> {
11093 match noun {
11194 Noun::Cell { .. } => Err(PersistentList::new()),
11295 Noun::Atom(atm) => Ok(Noun::Atom(atm + 1u32)),
@@ -121,7 +104,7 @@ fn tis<'a>(ctx: &'a InterpreterContext, lhs: &Noun, rhs: &Noun) -> &'a Rc<Noun>
121104 }
122105}
123106
124−fn fas(ctx: &InterpreterContext, addr: &Atom, noun: &Noun) -> Result<Rc<Noun>, TTanks> {
107+fn fas(ctx: &InterpreterContext, addr: &Atom, noun: &Noun) -> Result<Rc<Noun>, Tanks> {
125108 let mut addr_iter = addr.iter_u32_digits();
126109
127110 match (addr_iter.next(), addr_iter.next()) {
@@ -141,7 +124,7 @@ fn fas(ctx: &InterpreterContext, addr: &Atom, noun: &Noun) -> Result<Rc<Noun>, T
141124 }
142125}
143126
144−fn fas_u32(addr: u32, noun: &Noun) -> Result<Rc<Noun>, TTanks> {
127+fn fas_u32(addr: u32, noun: &Noun) -> Result<Rc<Noun>, Tanks> {
145128 match addr {
146129 0 => Err(PersistentList::new()),
147130 1 => Ok(Rc::new(noun.clone())),
@@ -159,7 +142,7 @@ fn fas_u32(addr: u32, noun: &Noun) -> Result<Rc<Noun>, TTanks> {
159142 }
160143}
161144
162−fn hax_u32(addr: u32, new_value: &Rc<Noun>, target: &Rc<Noun>) -> Result<Rc<Noun>, TTanks> {
145+fn hax_u32(addr: u32, new_value: &Rc<Noun>, target: &Rc<Noun>) -> Result<Rc<Noun>, Tanks> {
163146 match addr {
164147 0 => Err(PersistentList::new()),
165148 1 => Ok(new_value.clone()),
@@ -181,11 +164,11 @@ fn hax(
181164 addr: &Atom,
182165 new_value: &Rc<Noun>,
183166 target: &Rc<Noun>,
184−) -> Result<Rc<Noun>, TTanks> {
167+) -> Result<Rc<Noun>, Tanks> {
185168 let mut addr_iter = addr.iter_u32_digits();
186169
187170 match (addr_iter.next(), addr_iter.next()) {
188− (None, _) => Err(TTanks::new()),
171+ (None, _) => Err(Tanks::new()),
189172 (Some(x), None) => hax_u32(x, new_value, target),
190173 _ => hax(
191174 ctx,
@@ -204,18 +187,18 @@ fn hax(
204187
205188fn tar_u32<'a>(
206189 ctx: &mut InterpreterContext,
207− subj: &'a Rc<Noun>,
190+ subj: Rc<Noun>,
208191 op: u32,
209192 formula: &'a Rc<Noun>,
210−) -> Result<Rc<Noun>, TTanks> {
193+) -> Result<Rc<Noun>, Tanks> {
211194 match op {
212195 0 => {
213− let b = formula.as_atom().ok_or(TTanks::new())?;
196+ let b = formula.as_atom().ok_or(Tanks::new())?;
214197 fas(ctx, b, &*subj)
215198 }
216199 1 => Ok(formula.clone()),
217200 2 => {
218− let (b, c) = formula.as_cell().ok_or(TTanks::new())?;
201+ let (b, c) = formula.as_cell().ok_or(Tanks::new())?;
219202
220203 match c.borrow() {
221204 Noun::Cell { p, q, .. }
@@ -227,16 +210,16 @@ fn tar_u32<'a>(
227210 match ctx.jets.get(&hash) {
228211 Some(f) => f(ctx, sample),
229212 None => {
230− let foo = tar(ctx, subj, &b)?;
213+ let foo = tar(ctx, subj.clone(), &b)?;
231214 let bar = tar(ctx, subj, &c)?;
232− tar(ctx, &foo, &bar)
215+ tar(ctx, foo, &bar)
233216 }
234217 }
235218 }
236219 _ => {
237− let foo = tar(ctx, subj, &b)?;
220+ let foo = tar(ctx, subj.clone(), &b)?;
238221 let bar = tar(ctx, subj, &c)?;
239− tar(ctx, &foo, &bar)
222+ tar(ctx, foo, &bar)
240223 }
241224 }
242225 }
@@ -246,57 +229,57 @@ fn tar_u32<'a>(
246229 }
247230 4 => Ok(Rc::new(lus(&*tar(ctx, subj, &formula)?)?)),
248231 5 => {
249− let (b, c) = formula.as_cell().ok_or(TTanks::new())?;
250− let foo = tar(ctx, subj, &b)?;
232+ let (b, c) = formula.as_cell().ok_or(Tanks::new())?;
233+ let foo = tar(ctx, subj.clone(), &b)?;
251234 let bar = tar(ctx, subj, &c)?;
252235 Ok(tis(ctx, &foo, &bar).clone())
253236 }
254237 6 => {
255− let (b, c) = formula.as_cell().ok_or(TTanks::new())?;
256− let (c, d) = c.as_cell().ok_or(TTanks::new())?;
238+ let (b, c) = formula.as_cell().ok_or(Tanks::new())?;
239+ let (c, d) = c.as_cell().ok_or(Tanks::new())?;
257240
258− let bar = tar_u32(ctx, subj, 4, &cell(&ctx.nouns.four.clone(), &b))?;
241+ let bar = tar_u32(ctx, subj.clone(), 4, &cell(&ctx.nouns.four.clone(), &b))?;
259242
260− let foo = tar_u32(ctx, &ctx.nouns.two_three.clone(), 0, &bar)?;
261− let foo = tar_u32(ctx, &cell(&c, &d), 0, &foo)?;
243+ let foo = tar_u32(ctx, ctx.nouns.two_three.clone(), 0, &bar)?;
244+ let foo = tar_u32(ctx, cell(&c, &d), 0, &foo)?;
262245
263246 tar(ctx, subj, &foo)
264247 }
265248 7 => {
266− let (b, c) = formula.as_cell().ok_or(TTanks::new())?;
249+ let (b, c) = formula.as_cell().ok_or(Tanks::new())?;
267250 let foo = tar(ctx, subj, &b)?;
268− tar(ctx, &foo, &c)
251+ tar(ctx, foo, &c)
269252 }
270253 8 => {
271− let (b, c) = formula.as_cell().ok_or(TTanks::new())?;
272− let foo = tar(ctx, subj, &b)?;
273− tar(ctx, &cell(&foo, &subj), &c)
254+ let (b, c) = formula.as_cell().ok_or(Tanks::new())?;
255+ let foo = tar(ctx, subj.clone(), &b)?;
256+ tar(ctx, cell(&foo, &subj), &c)
274257 }
275258 9 => {
276− let (b, c) = formula.as_cell().ok_or(TTanks::new())?;
259+ let (b, c) = formula.as_cell().ok_or(Tanks::new())?;
277260 let foo = tar(ctx, subj, &c)?;
278261 tar_u32(
279262 ctx,
280− &foo,
263+ foo,
281264 2,
282265 &cell(&ctx.nouns.sig_one, &cell(&ctx.nouns.sig, &b)),
283266 )
284267 }
285268 10 => {
286− let (b, d) = formula.as_cell().ok_or(TTanks::new())?;
287− let (b, c) = b.as_cell().ok_or(TTanks::new())?;
288− let b = b.as_atom().ok_or(TTanks::new())?;
269+ let (b, d) = formula.as_cell().ok_or(Tanks::new())?;
270+ let (b, c) = b.as_cell().ok_or(Tanks::new())?;
271+ let b = b.as_atom().ok_or(Tanks::new())?;
289272
290− let foo = tar(ctx, subj, &c)?;
273+ let foo = tar(ctx, subj.clone(), &c)?;
291274 let bar = tar(ctx, subj, &d)?;
292275 hax(ctx, b, &foo, &bar)
293276 }
294277 11 => {
295− let (b, d) = formula.as_cell().ok_or(TTanks::new())?;
278+ let (b, d) = formula.as_cell().ok_or(Tanks::new())?;
296279 match b.borrow() {
297280 Noun::Atom(_) => tar(ctx, subj, &d),
298281 Noun::Cell { p, q, .. } => {
299− let eval = |ctx: &mut InterpreterContext| tar(ctx, subj, &d);
282+ let eval = |ctx: &mut InterpreterContext| tar(ctx, subj.clone(), &d);
300283 if *p == ctx.nouns.memo {
301284 let hash = cell(&subj, &d).hash();
302285 match ctx.memo.get(&hash) {
@@ -309,188 +292,37 @@ fn tar_u32<'a>(
309292 }
310293 } else if *p == ctx.nouns.mean {
311294 with_trace((subj.clone(), q.clone()), eval(ctx))
312− } else if *p == ctx.nouns.slog {
313− let noun = tar(ctx, subj, &q)?;
314− let (_prio, tank) = noun.as_cell().ok_or(TTanks::new())?;
315−
316− (ctx.slog)(&ram(ctx, tank.clone()).unwrap_or(String::new()));
317− 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)
340295 } else {
341296 eval(ctx)
342297 }
343298 }
344299 }
345300 }
346− _ => Err(TTanks::new()),
301+ _ => Err(Tanks::new()),
347302 }
348303}
349304
350−fn ram(ctx: &mut InterpreterContext, tank: Rc<Noun>) -> Option<String> {
351− match tank.borrow() {
352− Noun::Atom(str) => {
353− let mut bytes = str.to_bytes_le();
354− Some(String::from(str::from_utf8_mut(&mut bytes).ok()?))
355− }
356− Noun::Cell { p, q, .. } => {
357− let tag = p.as_atom()?.to_bytes_le();
358− if tag == b"leaf" {
359− let mut bytes = crip(ctx, q.clone()).ok()?.as_bytes()?;
360− Some(String::from(str::from_utf8_mut(&mut bytes).ok()?))
361− } else if tag == b"palm" {
362− let (spacers, tanks) = q.as_cell()?;
363− let (mid, open, flat_open, close) = spacers.tuple_4()?;
364−
365− let mut mid = crip(ctx, mid.clone()).ok()?.as_bytes()?;
366− let mid = String::from(str::from_utf8_mut(&mut mid).ok()?);
367−
368− let mut open = crip(ctx, open.clone()).ok()?.as_bytes()?;
369− let open = String::from(str::from_utf8_mut(&mut open).ok()?);
370−
371− let mut flat_open = crip(ctx, flat_open.clone()).ok()?.as_bytes()?;
372− let flat_open = String::from(str::from_utf8_mut(&mut flat_open).ok()?);
373−
374− let mut close = crip(ctx, close.clone()).ok()?.as_bytes()?;
375− let close = String::from(str::from_utf8_mut(&mut close).ok()?);
376−
377− let mut target = String::new();
378−
379− target.push_str(&*open);
380− target.push_str(&*flat_open);
381−
382− let mut is_first = true;
383− for tank in tanks.list_iter() {
384− if !is_first {
385− target.push_str(&*mid);
386− }
387−
388− target.push_str(&*(ram(ctx, tank.clone())?));
389−
390− is_first = false;
391− }
392−
393− target.push_str(&*close);
394−
395− Some(target)
396− } else if tag == b"rose" {
397− let (spacers, tanks) = q.as_cell()?;
398− let (mid, open, close) = spacers.tuple_3()?;
399−
400− let mut mid = crip(ctx, mid.clone()).ok()?.as_bytes()?;
401− let mid = String::from(str::from_utf8_mut(&mut mid).ok()?);
402−
403− let mut open = crip(ctx, open.clone()).ok()?.as_bytes()?;
404− let open = String::from(str::from_utf8_mut(&mut open).ok()?);
405−
406− let mut close = crip(ctx, close.clone()).ok()?.as_bytes()?;
407− let close = String::from(str::from_utf8_mut(&mut close).ok()?);
408−
409− let mut target = String::new();
410−
411− target.push_str(&*open);
412−
413− let mut is_first = true;
414− for tank in tanks.list_iter() {
415− if !is_first {
416− target.push_str(&*mid);
417− }
418−
419− target.push_str(&*(ram(ctx, tank.clone())?));
420−
421− is_first = false;
422− }
423−
424− target.push_str(&*close);
425−
426− Some(target)
427− } else {
428− None
429− }
430− }
431− }
432−}
433−
434−pub fn ram_ttanks(ctx: &mut InterpreterContext, tanks: TTanks) -> String {
435− let mut target = String::new();
436−
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−
443− target.push_str(&*ram_ttank(ctx, tank.clone()));
444−
445− first = false;
446− }
447−
448− target
449−}
450−
451−pub fn ram_ttank(ctx: &mut InterpreterContext, ttank: TTank) -> String {
452− let (subj, q) = ttank;
453−
454− let tank = match tar(ctx, &subj, &q) {
455− Ok(gate) => match eval_pulled_gate(ctx, gate) {
456− Ok(tank) => tank,
457− Err(_) => {
458− return String::new();
459− }
460− },
461− Err(_) => {
462− return String::new();
463− }
464− };
465− ram(ctx, tank).unwrap_or(String::new())
466−}
467−
468−pub fn crip(ctx: &mut InterpreterContext, tape: Rc<Noun>) -> Result<Rc<Noun>, TTanks> {
469− RAP(ctx, &cell(&Rc::new(Noun::from_u32(3)), &tape))
470−}
471−
472−fn with_trace<T>(tank: (Rc<Noun>, Rc<Noun>), src: Result<T, TTanks>) -> Result<T, TTanks> {
305+fn with_trace<T>(tank: (Rc<Noun>, Rc<Noun>), src: Result<T, Tanks>) -> Result<T, Tanks> {
473306 match src {
474307 Ok(a) => Ok(a),
475308 Err(tanks) => Err(cons(tank, tanks)),
476309 }
477310}
478311
479−/// Not actually a tank, but rather a thunk (subject, formula) which calculates the tank.
480−pub type TTank = (Rc<Noun>, Rc<Noun>);
481−pub type TTanks = PersistentList<TTank>;
312+pub type Tank = Rc<Noun>;
313+pub type Tanks = PersistentList<(Rc<Noun>, Rc<Noun>)>;
482314
483−pub const EMPTY_TANKS: TTanks = TTanks::new();
315+pub const EMPTY_TANKS: Tanks = Tanks::new();
484316
485317pub fn tar<'a>(
486318 ctx: &mut InterpreterContext,
487− subj: &'a Rc<Noun>,
319+ subj: Rc<Noun>,
488320 formula: &'a Noun,
489−) -> Result<Rc<Noun>, TTanks> {
490− let (op, formula) = formula.as_cell().ok_or(TTanks::new())?;
321+) -> Result<Rc<Noun>, Tanks> {
322+ let (op, formula) = formula.as_cell().ok_or(Tanks::new())?;
491323 match op.borrow() {
492324 Noun::Cell { .. } => {
493− let foo = tar(ctx, subj, &op)?;
325+ let foo = tar(ctx, subj.clone(), &op)?;
494326 let bar = tar(ctx, subj, &formula)?;
495327 Ok(cell(&foo, &bar))
496328 }
@@ -501,17 +333,14 @@ pub fn tar<'a>(
501333 1 => Some(op_iter.next().unwrap()),
502334 _ => None,
503335 };
504− let op = op.ok_or(TTanks::new())?;
336+ let op = op.ok_or(Tanks::new())?;
505337 stacker::maybe_grow(32 * 1024, 1024 * 1024, || tar_u32(ctx, subj, op, formula))
506338 }
507339 }
508340}
509341
510−pub fn eval_gate(
511− ctx: &mut InterpreterContext,
512− gate_factory: &Rc<Noun>,
513−) -> Result<Rc<Noun>, TTanks> {
514− let pulled_gate = tar(ctx, &ctx.nouns.sig.clone(), &gate_factory)?;
342+pub fn eval_gate(ctx: &mut InterpreterContext, gate_factory: &Rc<Noun>) -> Result<Rc<Noun>, Tanks> {
343+ let pulled_gate = tar(ctx, ctx.nouns.sig.clone(), &gate_factory)?;
515344 eval_pulled_gate(ctx, pulled_gate)
516345}
517346
@@ -519,18 +348,18 @@ pub fn slam(
519348 ctx: &mut InterpreterContext,
520349 gate_factory: &Rc<Noun>,
521350 sample: &Rc<Noun>,
522−) -> Result<Rc<Noun>, TTanks> {
523− let gate = tar(ctx, &ctx.nouns.sig.clone(), &gate_factory)?;
351+) -> Result<Rc<Noun>, Tanks> {
352+ let gate = tar(ctx, ctx.nouns.sig.clone(), &gate_factory)?;
524353
525354 eval_pulled_gate(ctx, replace_sample(&gate, sample)?)
526355}
527356
528357/// This is useful for evaluaing gates produced by running `.foo/nock gate-name` in the dojo.
529358/// Also for calling gates from within jets.
530−pub fn eval_pulled_gate(ctx: &mut InterpreterContext, gate: Rc<Noun>) -> Result<Rc<Noun>, TTanks> {
359+pub fn eval_pulled_gate(ctx: &mut InterpreterContext, gate: Rc<Noun>) -> Result<Rc<Noun>, Tanks> {
531360 tar(
532361 ctx,
533− &gate,
362+ gate,
534363 &cell(
535364 &Rc::new(Noun::Atom(BigUint::new(vec![9]))),
536365 &cell(&ctx.nouns.two, &cell(&ctx.nouns.sig, &ctx.nouns.one)),
@@ -544,13 +373,13 @@ pub fn slam_pulled_gate(
544373 ctx: &mut InterpreterContext,
545374 gate: &Rc<Noun>,
546375 sample: &Rc<Noun>,
547−) -> Result<Rc<Noun>, TTanks> {
376+) -> Result<Rc<Noun>, Tanks> {
548377 eval_pulled_gate(ctx, replace_sample(gate, sample)?)
549378}
550379
551−pub fn replace_sample(gate: &Rc<Noun>, sample: &Rc<Noun>) -> Result<Rc<Noun>, TTanks> {
552− let (battery, payload) = gate.as_cell().ok_or(TTanks::new())?;
553− let (_sample, context) = payload.as_cell().ok_or(TTanks::new())?;
380+pub fn replace_sample(gate: &Rc<Noun>, sample: &Rc<Noun>) -> Result<Rc<Noun>, Tanks> {
381+ let (battery, payload) = gate.as_cell().ok_or(Tanks::new())?;
382+ let (_sample, context) = payload.as_cell().ok_or(Tanks::new())?;
554383
555384 Ok(cell(battery, &cell(sample, context)))
556385}
nock/src/jets.rs+129−304
@@ -2,15 +2,14 @@ use core::panic;
22use murmur3::murmur3_32;
33use num_integer::Integer;
44use std::{
5− borrow::Borrow,
65 collections::BTreeMap,
76 iter::{once, repeat_n, zip},
87 rc::Rc,
98};
109
1110use crate::{
12− interpreter::{slam_pulled_gate, InterpreterContext, TTanks, EMPTY_TANKS},
13− noun::{self, cell, AsNoun, Atom, Edge, Hair, Nail, Noun},
11+ interpreter::{slam_pulled_gate, InterpreterContext, Tanks},
12+ noun::{self, cell, Atom, Edge, Hair, Nail, Noun},
1413};
1514
1615fn traverse_iter_result<E: Clone, T: Clone, I: Iterator<Item = Result<T, E>>>(
@@ -108,23 +107,18 @@ pub fn generate_jets() -> Jets {
108107 (124976064672625230427889101290245200507, TRIP),
109108 (4078279288073906183633157465551067635, MUK),
110109 (261900159748071234702685239353558471892, MUG),
111− (198191257620924788695943358402651905954, AOR),
112− (299422828284010240628877806738195667652, DOR),
113− (166326796552601297695313176538120818632, GOR),
114− (7942398240152905363972500667649380756, MOR),
115− (315687984998079865981003916817293521765, LOOK),
116110 ])
117111}
118112
119−pub type Jet = fn(ctx: &mut InterpreterContext, &Rc<Noun>) -> Result<Rc<Noun>, TTanks>;
113+pub type Jet = fn(ctx: &mut InterpreterContext, &Rc<Noun>) -> Result<Rc<Noun>, Tanks>;
120114pub type DoubleJet = fn(ctx: &mut InterpreterContext, &Rc<Noun>, &Rc<Noun>) -> Option<Rc<Noun>>;
121115
122−static BINARY_ATOM: fn(&Rc<Noun>, fn(&Atom, &Atom) -> Atom) -> Result<Rc<Noun>, TTanks> =
116+static BINARY_ATOM: fn(&Rc<Noun>, fn(&Atom, &Atom) -> Atom) -> Result<Rc<Noun>, Tanks> =
123117 |n: &Rc<Noun>, f: fn(&Atom, &Atom) -> Atom| {
124− let (p, q) = n.as_cell().ok_or(TTanks::new())?;
118+ let (p, q) = n.as_cell().ok_or(Tanks::new())?;
125119 Ok(Rc::new(Noun::Atom(f(
126− p.as_atom().ok_or(TTanks::new())?,
127− q.as_atom().ok_or(TTanks::new())?,
120+ p.as_atom().ok_or(Tanks::new())?,
121+ q.as_atom().ok_or(Tanks::new())?,
128122 ))))
129123 };
130124
@@ -132,13 +126,13 @@ static BINARY_ATOM_LOOB: fn(
132126 &InterpreterContext,
133127 &Rc<Noun>,
134128 fn(&Atom, &Atom) -> bool,
135−) -> Result<Rc<Noun>, TTanks> =
129+) -> Result<Rc<Noun>, Tanks> =
136130 |ctx: &InterpreterContext, n: &Rc<Noun>, f: fn(&Atom, &Atom) -> bool| {
137− let (p, q) = n.as_cell().ok_or(TTanks::new())?;
131+ let (p, q) = n.as_cell().ok_or(Tanks::new())?;
138132
139133 if f(
140− p.as_atom().ok_or(TTanks::new())?,
141− q.as_atom().ok_or(TTanks::new())?,
134+ p.as_atom().ok_or(Tanks::new())?,
135+ q.as_atom().ok_or(Tanks::new())?,
142136 ) {
143137 Ok(ctx.nouns.sig.clone())
144138 } else {
@@ -149,22 +143,18 @@ static BINARY_ATOM_LOOB: fn(
149143static BINARY_ATOM_PAIR: fn(
150144 &Rc<Noun>,
151145 fn(&Atom, &Atom) -> (Atom, Atom),
152−) -> Result<Rc<Noun>, TTanks> = |n: &Rc<Noun>, f: fn(&Atom, &Atom) -> (Atom, Atom)| {
153− let (p, q) = n.as_cell().ok_or(TTanks::new())?;
146+) -> Result<Rc<Noun>, Tanks> = |n: &Rc<Noun>, f: fn(&Atom, &Atom) -> (Atom, Atom)| {
147+ let (p, q) = n.as_cell().ok_or(Tanks::new())?;
154148
155149 let (a, b) = f(
156− p.as_atom().ok_or(TTanks::new())?,
157− q.as_atom().ok_or(TTanks::new())?,
150+ p.as_atom().ok_or(Tanks::new())?,
151+ q.as_atom().ok_or(Tanks::new())?,
158152 );
159153 Ok(cell(&Rc::new(Noun::Atom(a)), &Rc::new(Noun::Atom(b))))
160154};
161155
162156static ADD: Jet = |_ctx, n| BINARY_ATOM(n, |a, b| a + b);
163−static DEC: Jet = |_ctx, n| {
164− Ok(Rc::new(Noun::Atom(
165− n.as_atom().ok_or(TTanks::new())? - 1u32,
166− )))
167−};
157+static DEC: Jet = |_ctx, n| Ok(Rc::new(Noun::Atom(n.as_atom().ok_or(Tanks::new())? - 1u32)));
168158static DVR: Jet = |_ctx, n| BINARY_ATOM_PAIR(n, |a, b| a.div_rem(&b));
169159static DIV: Jet = |_ctx, n| BINARY_ATOM(n, |a, b| a / b);
170160static GTE: Jet = |ctx, n| BINARY_ATOM_LOOB(ctx, n, |a, b| a >= b);
@@ -178,30 +168,30 @@ static MUL: Jet = |_ctx, n| BINARY_ATOM(n, |a, b| a * b);
178168static SUB: Jet = |_ctx, n| BINARY_ATOM(n, |a, b| a - b);
179169
180170static CAP: Jet = |ctx, n| {
181− let n = n.as_atom().ok_or(TTanks::new())?;
171+ let n = n.as_atom().ok_or(Tanks::new())?;
182172 CAP_ATOM(ctx, n.clone())
183173};
184174
185−static CAP_ATOM: fn(&InterpreterContext, Atom) -> Result<Rc<Noun>, TTanks> = |ctx, n: Atom| {
175+static CAP_ATOM: fn(&InterpreterContext, Atom) -> Result<Rc<Noun>, Tanks> = |ctx, n: Atom| {
186176 let mut n_iter = n.iter_u32_digits();
187177
188178 match n_iter.len() {
189− 0 => Err(TTanks::new()),
179+ 0 => Err(Tanks::new()),
190180 1 => CAP_U32(ctx, n_iter.next().unwrap()),
191181 _ => CAP_ATOM(ctx, n >> 1),
192182 }
193183};
194−static CAP_U32: fn(ctx: &InterpreterContext, u32) -> Result<Rc<Noun>, TTanks> = |ctx, n| match n {
195− 0 | 1 => Err(TTanks::new()),
184+static CAP_U32: fn(ctx: &InterpreterContext, u32) -> Result<Rc<Noun>, Tanks> = |ctx, n| match n {
185+ 0 | 1 => Err(Tanks::new()),
196186 2 => Ok(ctx.nouns.two.clone()),
197187 3 => Ok(ctx.nouns.three.clone()),
198188 n => CAP_U32(ctx, n >> 1),
199189};
200190
201191static MAS: Jet = |ctx, n| {
202− let n = n.as_atom().ok_or(TTanks::new())?;
192+ let n = n.as_atom().ok_or(Tanks::new())?;
203193 Ok(Rc::new(Noun::Atom(
204− MAS_ATOM(ctx, n.clone()).ok_or(TTanks::new())?,
194+ MAS_ATOM(ctx, n.clone()).ok_or(Tanks::new())?,
205195 )))
206196};
207197static MAS_ATOM: fn(&InterpreterContext, Atom) -> Option<Atom> = |ctx, n| {
@@ -223,22 +213,22 @@ static MAS_U32: fn(u32) -> u32 = |n| match n {
223213};
224214
225215static PEG: Jet = |ctx, n| {
226− let (a, b) = n.as_cell().ok_or(TTanks::new())?;
216+ let (a, b) = n.as_cell().ok_or(Tanks::new())?;
227217
228− let a = a.as_atom().ok_or(TTanks::new())?;
229− let b = b.as_atom().ok_or(TTanks::new())?;
218+ let a = a.as_atom().ok_or(Tanks::new())?;
219+ let b = b.as_atom().ok_or(Tanks::new())?;
230220
231221 if *a == Atom::ZERO {
232− return Err(TTanks::new());
222+ return Err(Tanks::new());
233223 };
234224
235225 Ok(Rc::new(Noun::Atom(PEG_ATOM(ctx, a, b.clone())?)))
236226};
237−static PEG_ATOM: fn(&InterpreterContext, &Atom, Atom) -> Result<Atom, TTanks> = |ctx, a, b| {
227+static PEG_ATOM: fn(&InterpreterContext, &Atom, Atom) -> Result<Atom, Tanks> = |ctx, a, b| {
238228 let mut b_iter = b.iter_u32_digits();
239229
240230 match b_iter.len() {
241− 0 => Err(TTanks::new()),
231+ 0 => Err(Tanks::new()),
242232 1 => Ok(PEG_U32(a, b_iter.next().unwrap())),
243233 _ => Ok((&b & &ctx.big_uints.one) + (PEG_ATOM(ctx, a, b >> 1)? << 1)),
244234 }
@@ -252,7 +242,7 @@ static PEG_U32: fn(&Atom, u32) -> Atom = |a, b| match b {
252242};
253243
254244static FAND: Jet = |ctx, n| {
255− let (nedl, hstk) = n.as_cell().ok_or(TTanks::new())?;
245+ let (nedl, hstk) = n.as_cell().ok_or(Tanks::new())?;
256246 if nedl.is_sig() || hstk.is_sig() {
257247 return Ok(ctx.nouns.sig.clone());
258248 }
@@ -282,7 +272,7 @@ static FAND: Jet = |ctx, n| {
282272};
283273
284274static FIND: Jet = |ctx, n| {
285− let (nedl, hstk) = n.as_cell().ok_or(TTanks::new())?;
275+ let (nedl, hstk) = n.as_cell().ok_or(Tanks::new())?;
286276 if nedl.is_sig() || hstk.is_sig() {
287277 return Ok(ctx.nouns.sig.clone());
288278 }
@@ -315,13 +305,13 @@ static FLOP: Jet = |ctx, n| {
315305};
316306
317307static GULF: Jet = |_ctx, n| {
318− let (from, to) = n.as_cell().ok_or(TTanks::new())?;
308+ let (from, to) = n.as_cell().ok_or(Tanks::new())?;
319309
320− let mut from = (*from.as_atom().ok_or(TTanks::new())?).clone();
321− let to = to.as_atom().ok_or(TTanks::new())?.clone();
310+ let mut from = (*from.as_atom().ok_or(Tanks::new())?).clone();
311+ let to = to.as_atom().ok_or(Tanks::new())?.clone();
322312
323313 if from > to {
324− return Err(TTanks::new());
314+ return Err(Tanks::new());
325315 }
326316
327317 let mut tmp = Vec::new();
@@ -335,10 +325,10 @@ static GULF: Jet = |_ctx, n| {
335325};
336326
337327static INTO: Jet = |_ctx, n| {
338− let (a, b) = n.as_cell().ok_or(TTanks::new())?;
339− let (b, c) = b.as_cell().ok_or(TTanks::new())?;
328+ let (a, b) = n.as_cell().ok_or(Tanks::new())?;
329+ let (b, c) = b.as_cell().ok_or(Tanks::new())?;
340330
341− let mut b_iter = b.as_atom().ok_or(TTanks::new())?.iter_u32_digits();
331+ let mut b_iter = b.as_atom().ok_or(Tanks::new())?.iter_u32_digits();
342332
343333 match b_iter.len() {
344334 0 => Ok(cell(&c, &a)),
@@ -368,7 +358,7 @@ static INTO: Jet = |_ctx, n| {
368358};
369359
370360static JOIN: Jet = |_ctx, n| {
371− let (sep, list) = n.as_cell().ok_or(TTanks::new())?;
361+ let (sep, list) = n.as_cell().ok_or(Tanks::new())?;
372362 Ok(Noun::list_refs(
373363 list.list_iter()
374364 .intersperse(sep)
@@ -386,7 +376,7 @@ static LENT: Jet = |_ctx, n| {
386376};
387377
388378static LEVY: Jet = |ctx, n| {
389− let (a, b) = n.as_cell().ok_or(TTanks::new())?;
379+ let (a, b) = n.as_cell().ok_or(Tanks::new())?;
390380 if traverse_iter_result(a.list_iter().map(|n| slam_pulled_gate(ctx, b, n)))?
391381 .iter()
392382 .all(|x| x.is_y())
@@ -398,7 +388,7 @@ static LEVY: Jet = |ctx, n| {
398388};
399389
400390static LIEN: Jet = |ctx, n| {
401− let (a, b) = n.as_cell().ok_or(TTanks::new())?;
391+ let (a, b) = n.as_cell().ok_or(Tanks::new())?;
402392 if traverse_iter_result(a.list_iter().map(|n| slam_pulled_gate(ctx, b, n)))?
403393 .iter()
404394 .any(|x| x.is_y())
@@ -410,7 +400,7 @@ static LIEN: Jet = |ctx, n| {
410400};
411401
412402static MURN: Jet = |ctx, n| {
413− let (a, b) = n.as_cell().ok_or(TTanks::new())?;
403+ let (a, b) = n.as_cell().ok_or(Tanks::new())?;
414404
415405 Ok(Noun::list_refs(
416406 traverse_iter_result(
@@ -423,7 +413,7 @@ static MURN: Jet = |ctx, n| {
423413};
424414
425415static REAP: Jet = |_ctx, n| {
426− let (a, b) = n.as_cell().ok_or(TTanks::new())?;
416+ let (a, b) = n.as_cell().ok_or(Tanks::new())?;
427417
428418 Ok(Noun::list_refs(repeat_n(
429419 b.clone(),
@@ -431,17 +421,17 @@ static REAP: Jet = |_ctx, n| {
431421 )))
432422};
433423
434−static REAR: Jet = |_ctx, n| n.list_iter().last().ok_or(TTanks::new()).cloned();
424+static REAR: Jet = |_ctx, n| n.list_iter().last().ok_or(Tanks::new()).cloned();
435425
436426static REEL: Jet = |ctx, n| {
437− let (list, gate) = n.as_cell().ok_or(TTanks::new())?;
427+ let (list, gate) = n.as_cell().ok_or(Tanks::new())?;
438428
439429 list.list_iter().collect::<Vec<_>>().iter().rfold(
440430 Ok(gate
441431 .gate_sample()
442− .ok_or(TTanks::new())?
432+ .ok_or(Tanks::new())?
443433 .as_cell()
444− .ok_or(TTanks::new())?
434+ .ok_or(Tanks::new())?
445435 .1
446436 .clone()),
447437 |acc, next| {
@@ -452,15 +442,15 @@ static REEL: Jet = |ctx, n| {
452442};
453443
454444static ROLL: Jet = |ctx, n| {
455− let (list, gate) = n.as_cell().ok_or(TTanks::new())?;
445+ let (list, gate) = n.as_cell().ok_or(Tanks::new())?;
456446
457447 list.list_iter().fold(
458448 Ok(gate
459449 .clone()
460450 .gate_sample()
461− .ok_or(TTanks::new())?
451+ .ok_or(Tanks::new())?
462452 .as_cell()
463− .ok_or(TTanks::new())?
453+ .ok_or(Tanks::new())?
464454 .1
465455 .clone()),
466456 |acc, next| {
@@ -471,7 +461,7 @@ static ROLL: Jet = |ctx, n| {
471461};
472462
473463static SCAG: Jet = |_ctx, n| {
474− let (a, b) = n.as_cell().ok_or(TTanks::new())?;
464+ let (a, b) = n.as_cell().ok_or(Tanks::new())?;
475465
476466 Ok(Noun::list_refs(
477467 b.list_iter()
@@ -484,7 +474,7 @@ static SCAG: Jet = |_ctx, n| {
484474};
485475
486476static SKID: Jet = |ctx, n| {
487− let (list, gate) = n.as_cell().ok_or(TTanks::new())?;
477+ let (list, gate) = n.as_cell().ok_or(Tanks::new())?;
488478
489479 let slammed_n = traverse_iter_result(
490480 list.list_iter()
@@ -499,7 +489,7 @@ static SKID: Jet = |ctx, n| {
499489};
500490
501491static SKIM: Jet = |ctx, n| {
502− let (list, gate) = n.as_cell().ok_or(TTanks::new())?;
492+ let (list, gate) = n.as_cell().ok_or(Tanks::new())?;
503493
504494 Ok(Noun::list_refs(
505495 traverse_iter_result(
@@ -513,7 +503,7 @@ static SKIM: Jet = |ctx, n| {
513503};
514504
515505static SKIP: Jet = |ctx, n| {
516− let (list, gate) = n.as_cell().ok_or(TTanks::new())?;
506+ let (list, gate) = n.as_cell().ok_or(Tanks::new())?;
517507
518508 Ok(Noun::list_refs(
519509 traverse_iter_result(
@@ -527,9 +517,9 @@ static SKIP: Jet = |ctx, n| {
527517};
528518
529519static SLAG: Jet = |ctx, n| {
530− let (a, list) = n.as_cell().ok_or(TTanks::new())?;
520+ let (a, list) = n.as_cell().ok_or(Tanks::new())?;
531521
532− let mut a_iter = a.as_atom().ok_or(TTanks::new())?.iter_u32_digits();
522+ let mut a_iter = a.as_atom().ok_or(Tanks::new())?.iter_u32_digits();
533523
534524 match a_iter.len() {
535525 0 => Ok(list.clone()),
@@ -546,12 +536,12 @@ static SLAG: Jet = |ctx, n| {
546536};
547537
548538static SNAG: Jet = |_ctx, n| {
549− let (a, list) = n.as_cell().ok_or(TTanks::new())?;
539+ let (a, list) = n.as_cell().ok_or(Tanks::new())?;
550540
551541 list.list_iter()
552542 .nth(a.as_u32().unwrap() as usize)
553543 .cloned()
554− .ok_or(TTanks::new())
544+ .ok_or(Tanks::new())
555545};
556546
557547static SNIP: Jet = |_ctx, n| {
@@ -568,7 +558,7 @@ static SNIP: Jet = |_ctx, n| {
568558};
569559
570560static SNOC: Jet = |_ctx, n| {
571− let (list, b) = n.as_cell().ok_or(TTanks::new())?;
561+ let (list, b) = n.as_cell().ok_or(Tanks::new())?;
572562
573563 Ok(Noun::list_refs(
574564 list.list_iter()
@@ -599,15 +589,15 @@ static SNOC: Jet = |_ctx, n| {
599589// };
600590
601591static SPIN: Jet = |ctx, n| {
602− let (list, b) = n.as_cell().ok_or(TTanks::new())?;
603− let (acc, gate) = b.as_cell().ok_or(TTanks::new())?;
592+ let (list, b) = n.as_cell().ok_or(Tanks::new())?;
593+ let (acc, gate) = b.as_cell().ok_or(Tanks::new())?;
604594
605595 let mut res = Vec::new();
606596 let mut acc = acc.clone();
607597
608598 for n in list.list_iter() {
609599 let foo = slam_pulled_gate(ctx, gate, &cell(&n, &acc))?;
610− let (el, new_acc) = foo.as_cell().ok_or(TTanks::new())?;
600+ let (el, new_acc) = foo.as_cell().ok_or(Tanks::new())?;
611601 acc = new_acc.clone();
612602 res.push(el.clone());
613603 }
@@ -616,20 +606,20 @@ static SPIN: Jet = |ctx, n| {
616606};
617607
618608static SPUN: Jet = |ctx, n| {
619− let (list, gate) = n.as_cell().ok_or(TTanks::new())?;
609+ let (list, gate) = n.as_cell().ok_or(Tanks::new())?;
620610
621611 let mut res = Vec::new();
622612 let mut acc = gate
623613 .gate_sample()
624− .ok_or(TTanks::new())?
614+ .ok_or(Tanks::new())?
625615 .as_cell()
626− .ok_or(TTanks::new())?
616+ .ok_or(Tanks::new())?
627617 .1
628618 .clone();
629619
630620 for n in list.list_iter() {
631621 let foo = slam_pulled_gate(ctx, gate, &cell(&n, &acc))?;
632− let (el, new_acc) = foo.as_cell().ok_or(TTanks::new())?;
622+ let (el, new_acc) = foo.as_cell().ok_or(Tanks::new())?;
633623 acc = new_acc.clone();
634624 res.push(el.clone());
635625 }
@@ -638,7 +628,7 @@ static SPUN: Jet = |ctx, n| {
638628};
639629
640630static TURN: Jet = |ctx, n| {
641− let (list, gate) = n.as_cell().ok_or(TTanks::new())?;
631+ let (list, gate) = n.as_cell().ok_or(Tanks::new())?;
642632 Ok(Noun::list_refs(
643633 traverse_iter_result(list.list_iter().map(|x| slam_pulled_gate(ctx, gate, x)))?
644634 .iter()
@@ -647,7 +637,7 @@ static TURN: Jet = |ctx, n| {
647637};
648638
649639static WELD: Jet = |_ctx, n| {
650− let (a, b) = n.as_cell().ok_or(TTanks::new())?;
640+ let (a, b) = n.as_cell().ok_or(Tanks::new())?;
651641
652642 Ok(Noun::list_refs(
653643 a.list_iter()
@@ -680,20 +670,18 @@ static BEX: Jet = |ctx, n| {
680670};
681671
682672static END: Jet = |ctx, n| {
683− let (a, b) = n.as_cell().ok_or(TTanks::new())?;
673+ let (a, b) = n.as_cell().ok_or(Tanks::new())?;
684674 let bite = a.as_bite();
685675
686676 let bits = bite.bits();
687677
688678 let mask = (&ctx.big_uints.one << bits) - &ctx.big_uints.one;
689679
690− Ok(Rc::new(Noun::Atom(
691− mask & b.as_atom().ok_or(TTanks::new())?,
692− )))
680+ Ok(Rc::new(Noun::Atom(mask & b.as_atom().ok_or(Tanks::new())?)))
693681};
694682
695683static CAN: Jet = |ctx, n| {
696− let (a, b) = n.as_cell().ok_or(TTanks::new())?;
684+ let (a, b) = n.as_cell().ok_or(Tanks::new())?;
697685 let bloq = a.as_u32().unwrap();
698686 let bloq_ = 2u32.pow(bloq);
699687
@@ -708,16 +696,16 @@ static CAN: Jet = |ctx, n| {
708696 Some((acc? << bits) | (mask & q.as_atom()?))
709697 },
710698 );
711− Ok(Rc::new(Noun::Atom(atom.ok_or(TTanks::new())?)))
699+ Ok(Rc::new(Noun::Atom(atom.ok_or(Tanks::new())?)))
712700};
713701
714702static CAT: Jet = |_ctx, n| {
715− let (bloq, b) = n.as_cell().ok_or(TTanks::new())?;
716− let (b, c) = b.as_cell().ok_or(TTanks::new())?;
703+ let (bloq, b) = n.as_cell().ok_or(Tanks::new())?;
704+ let (b, c) = b.as_cell().ok_or(Tanks::new())?;
717705
718− let bloq = bloq.as_u32().ok_or(TTanks::new())?;
719− let b = b.as_atom().ok_or(TTanks::new())?;
720− let c = c.as_atom().ok_or(TTanks::new())?;
706+ let bloq = bloq.as_u32().ok_or(Tanks::new())?;
707+ let b = b.as_atom().ok_or(Tanks::new())?;
708+ let c = c.as_atom().ok_or(Tanks::new())?;
721709
722710 Ok(Rc::new(Noun::Atom(
723711 (c << (met(bloq, &b) * 2u32.pow(bloq))) | b,
@@ -725,8 +713,8 @@ static CAT: Jet = |_ctx, n| {
725713};
726714
727715static MET: Jet = |_ctx, n| {
728− let (bloq, b) = n.as_cell().ok_or(TTanks::new())?;
729− let b: Atom = b.as_atom().ok_or(TTanks::new())?.clone();
716+ let (bloq, b) = n.as_cell().ok_or(Tanks::new())?;
717+ let b: Atom = b.as_atom().ok_or(Tanks::new())?.clone();
730718 let bloq = bloq.as_u32().unwrap();
731719
732720 Ok(Rc::new(Noun::from_u32(met(bloq, &b))))
@@ -737,28 +725,28 @@ fn met(bloq: u32, a: &Atom) -> u32 {
737725}
738726
739727static CUT: Jet = |ctx, n| {
740− let (a, b) = n.as_cell().ok_or(TTanks::new())?;
741− let (b, d) = b.as_cell().ok_or(TTanks::new())?;
742− let (b, c) = b.as_cell().ok_or(TTanks::new())?;
728+ let (a, b) = n.as_cell().ok_or(Tanks::new())?;
729+ let (b, d) = b.as_cell().ok_or(Tanks::new())?;
730+ let (b, c) = b.as_cell().ok_or(Tanks::new())?;
743731
744732 let bits = 2u32.pow(a.as_u32().unwrap());
745733
746734 let mask = (&ctx.big_uints.one << (bits * c.as_u32().unwrap())) - &ctx.big_uints.one;
747735
748736 Ok(Rc::new(Noun::Atom(
749− (d.as_atom().ok_or(TTanks::new())? >> (bits * b.as_u32().unwrap())) & mask,
737+ (d.as_atom().ok_or(Tanks::new())? >> (bits * b.as_u32().unwrap())) & mask,
750738 )))
751739};
752740
753741static FIL: Jet = |ctx, n| {
754− let (a, b) = n.as_cell().ok_or(TTanks::new())?;
755− let (b, c) = b.as_cell().ok_or(TTanks::new())?;
742+ let (a, b) = n.as_cell().ok_or(Tanks::new())?;
743+ let (b, c) = b.as_cell().ok_or(Tanks::new())?;
756744
757745 let bits = 2u32.pow(a.as_u32().unwrap());
758746
759747 let mask = (&ctx.big_uints.one << bits) - &ctx.big_uints.one;
760748
761− let src = c.as_atom().ok_or(TTanks::new())? & mask;
749+ let src = c.as_atom().ok_or(Tanks::new())? & mask;
762750
763751 let mut target = ctx.big_uints.zero.clone();
764752
@@ -770,30 +758,30 @@ static FIL: Jet = |ctx, n| {
770758};
771759
772760static LSH: Jet = |_ctx, n| {
773− let (a, b) = n.as_cell().ok_or(TTanks::new())?;
761+ let (a, b) = n.as_cell().ok_or(Tanks::new())?;
774762 let a = a.as_bite();
775− let b = b.as_atom().ok_or(TTanks::new())?;
763+ let b = b.as_atom().ok_or(Tanks::new())?;
776764
777765 Ok(Rc::new(Noun::Atom(b << a.bits())))
778766};
779767
780768static RSH: Jet = |_ctx, n| {
781− let (a, b) = n.as_cell().ok_or(TTanks::new())?;
769+ let (a, b) = n.as_cell().ok_or(Tanks::new())?;
782770 let a = a.as_bite();
783− let b = b.as_atom().ok_or(TTanks::new())?;
771+ let b = b.as_atom().ok_or(Tanks::new())?;
784772
785773 Ok(Rc::new(Noun::Atom(b >> a.bits())))
786774};
787775
788−pub static RAP: Jet = |ctx, n| {
789− let (bloq, b) = n.as_cell().ok_or(TTanks::new())?;
776+static RAP: Jet = |ctx, n| {
777+ let (bloq, b) = n.as_cell().ok_or(Tanks::new())?;
790778 let bloq = bloq.as_u32().unwrap();
791779 let bits = 2u32.pow(bloq);
792780
793781 let mut target = ctx.big_uints.zero.clone();
794782
795783 for el in b.list_iter().collect::<Vec<_>>().iter().rev() {
796− let el = el.as_atom().ok_or(TTanks::new())?;
784+ let el = el.as_atom().ok_or(Tanks::new())?;
797785 if el != &ctx.big_uints.zero {
798786 target = (target << (bits * met(bloq, &el))) | el;
799787 }
@@ -803,7 +791,7 @@ pub static RAP: Jet = |ctx, n| {
803791};
804792
805793static REP: Jet = |ctx, n| {
806− let (bite, b) = n.as_cell().ok_or(TTanks::new())?;
794+ let (bite, b) = n.as_cell().ok_or(Tanks::new())?;
807795 let bite = bite.as_bite();
808796
809797 let bits = bite.bits();
@@ -812,18 +800,18 @@ static REP: Jet = |ctx, n| {
812800 let mut target = ctx.big_uints.zero.clone();
813801
814802 for el in b.list_iter().collect::<Vec<_>>().iter().rev() {
815− target = (target << bits) | (el.as_atom().ok_or(TTanks::new())? & &mask);
803+ target = (target << bits) | (el.as_atom().ok_or(Tanks::new())? & &mask);
816804 }
817805
818806 Ok(Rc::new(Noun::Atom(target)))
819807};
820808
821809static REV: Jet = |ctx, n| {
822− let (bloq, b) = n.as_cell().ok_or(TTanks::new())?;
823− let (len, dat) = b.as_cell().ok_or(TTanks::new())?;
810+ let (bloq, b) = n.as_cell().ok_or(Tanks::new())?;
811+ let (len, dat) = b.as_cell().ok_or(Tanks::new())?;
824812 let bloq = bloq.as_u32().unwrap();
825813 let len = len.as_u32().unwrap();
826− let mut dat: Atom = dat.as_atom().ok_or(TTanks::new())?.clone();
814+ let mut dat: Atom = dat.as_atom().ok_or(Tanks::new())?.clone();
827815
828816 let bits = 2u32.pow(bloq);
829817 let mask = (&ctx.big_uints.one << bits) - &ctx.big_uints.one;
@@ -839,9 +827,9 @@ static REV: Jet = |ctx, n| {
839827};
840828
841829static RIP: Jet = |ctx, n| {
842− let (bite, b) = n.as_cell().ok_or(TTanks::new())?;
830+ let (bite, b) = n.as_cell().ok_or(Tanks::new())?;
843831 let bite = bite.as_bite();
844− let mut b: Atom = b.as_atom().ok_or(TTanks::new())?.clone();
832+ let mut b: Atom = b.as_atom().ok_or(Tanks::new())?.clone();
845833
846834 let bits = bite.bits();
847835 let mask = (&ctx.big_uints.one << bits) - &ctx.big_uints.one;
@@ -857,11 +845,11 @@ static RIP: Jet = |ctx, n| {
857845};
858846
859847static RUN: Jet = |ctx, n| {
860− let (bite, b) = n.as_cell().ok_or(TTanks::new())?;
861− let (b, gate) = b.as_cell().ok_or(TTanks::new())?;
848+ let (bite, b) = n.as_cell().ok_or(Tanks::new())?;
849+ let (b, gate) = b.as_cell().ok_or(Tanks::new())?;
862850
863851 let bite = bite.as_bite();
864− let mut b: Atom = b.as_atom().ok_or(TTanks::new())?.clone();
852+ let mut b: Atom = b.as_atom().ok_or(Tanks::new())?.clone();
865853
866854 let bits = bite.bits();
867855 let mask = (&ctx.big_uints.one << bits) - &ctx.big_uints.one;
@@ -872,7 +860,7 @@ static RUN: Jet = |ctx, n| {
872860 target = (target << bits)
873861 | ((*slam_pulled_gate(ctx, gate, &Rc::new(Noun::Atom(&mask & &b)))?)
874862 .as_atom()
875− .ok_or(TTanks::new())?
863+ .ok_or(Tanks::new())?
876864 & &mask);
877865 b = b >> bits;
878866 }
@@ -881,11 +869,11 @@ static RUN: Jet = |ctx, n| {
881869};
882870
883871static RUT: Jet = |ctx, n| {
884− let (bite, b) = n.as_cell().ok_or(TTanks::new())?;
885− let (b, gate) = b.as_cell().ok_or(TTanks::new())?;
872+ let (bite, b) = n.as_cell().ok_or(Tanks::new())?;
873+ let (b, gate) = b.as_cell().ok_or(Tanks::new())?;
886874
887875 let bite = bite.as_bite();
888− let mut b: Atom = b.as_atom().ok_or(TTanks::new())?.clone();
876+ let mut b: Atom = b.as_atom().ok_or(Tanks::new())?.clone();
889877
890878 let bits = bite.bits();
891879 let mask = (&ctx.big_uints.one << bits) - &ctx.big_uints.one;
@@ -896,7 +884,7 @@ static RUT: Jet = |ctx, n| {
896884 target.push(
897885 (*slam_pulled_gate(ctx, gate, &Rc::new(Noun::Atom(&mask & &b)))?)
898886 .as_atom()
899− .ok_or(TTanks::new())?
887+ .ok_or(Tanks::new())?
900888 & &mask,
901889 );
902890 b = b >> bits;
@@ -906,12 +894,12 @@ static RUT: Jet = |ctx, n| {
906894};
907895
908896static SEW: Jet = |ctx, n| {
909− let (a, b) = n.as_cell().ok_or(TTanks::new())?;
910− let (b, recipient) = b.as_cell().ok_or(TTanks::new())?;
911− let (sew_start, c) = b.as_cell().ok_or(TTanks::new())?;
912− let (number_of_blocks, donor) = c.as_cell().ok_or(TTanks::new())?;
913− let recipient = recipient.as_atom().ok_or(TTanks::new())?;
914− let donor = donor.as_atom().ok_or(TTanks::new())?;
897+ let (a, b) = n.as_cell().ok_or(Tanks::new())?;
898+ let (b, recipient) = b.as_cell().ok_or(Tanks::new())?;
899+ let (sew_start, c) = b.as_cell().ok_or(Tanks::new())?;
900+ let (number_of_blocks, donor) = c.as_cell().ok_or(Tanks::new())?;
901+ let recipient = recipient.as_atom().ok_or(Tanks::new())?;
902+ let donor = donor.as_atom().ok_or(Tanks::new())?;
915903
916904 let bloq = a.as_u32().unwrap();
917905 let bits = 2u32.pow(bloq);
@@ -927,12 +915,12 @@ static SEW: Jet = |ctx, n| {
927915};
928916
929917static SWP: Jet = |ctx, n| {
930− let (bloq, b) = n.as_cell().ok_or(TTanks::new())?;
918+ let (bloq, b) = n.as_cell().ok_or(Tanks::new())?;
931919 let bloq = bloq.as_u32().unwrap();
932920 let bits = 2u32.pow(bloq);
933921 let mask = (&ctx.big_uints.one << bits) - &ctx.big_uints.one;
934922
935− let mut source = b.as_atom().ok_or(TTanks::new())?.clone();
923+ let mut source = b.as_atom().ok_or(Tanks::new())?.clone();
936924 let mut target = ctx.big_uints.zero.clone();
937925
938926 while source > ctx.big_uints.zero {
@@ -944,7 +932,7 @@ static SWP: Jet = |ctx, n| {
944932};
945933
946934static XEB: Jet = |_ctx, n| {
947− let mut a = n.as_atom().ok_or(TTanks::new())?.clone();
935+ let mut a = n.as_atom().ok_or(Tanks::new())?.clone();
948936
949937 let mut c = 0;
950938
@@ -961,22 +949,22 @@ static DIS: Jet = |_ctx, n| BINARY_ATOM(n, |a, b| a & b);
961949static MIX: Jet = |_ctx, n| BINARY_ATOM(n, |a, b| a ^ b);
962950
963951static NOT: Jet = |ctx, n| {
964− let (a, b) = n.as_cell().ok_or(TTanks::new())?;
965− let (b, c) = b.as_cell().ok_or(TTanks::new())?;
952+ let (a, b) = n.as_cell().ok_or(Tanks::new())?;
953+ let (b, c) = b.as_cell().ok_or(Tanks::new())?;
966954
967955 let bloq = a.as_u32().unwrap();
968956 let bits = 2u32.pow(bloq);
969957 let mask = (&ctx.big_uints.one << (bits * b.as_u32().unwrap())) - &ctx.big_uints.one;
970958
971− let target = c.as_atom().ok_or(TTanks::new())? ^ &mask;
959+ let target = c.as_atom().ok_or(Tanks::new())? ^ &mask;
972960
973961 Ok(Rc::new(Noun::Atom(target)))
974962};
975963
976964static LAST: Jet = |_ctx, n| {
977− let (a, b) = n.as_cell().ok_or(TTanks::new())?;
978− let a = a.as_hair().ok_or(TTanks::new())?;
979− let b = b.as_hair().ok_or(TTanks::new())?;
965+ let (a, b) = n.as_cell().ok_or(Tanks::new())?;
966+ let a = a.as_hair().ok_or(Tanks::new())?;
967+ let b = b.as_hair().ok_or(Tanks::new())?;
980968 Ok(Noun::from_hair(last(&a, &b)))
981969};
982970
@@ -997,185 +985,22 @@ fn last<'a>(a: &'a Hair, b: &'a Hair) -> &'a Hair {
997985}
998986
999987static TRIP: Jet = |_ctx, n| {
1000− let a = n.as_atom().ok_or(TTanks::new())?;
988+ let a = n.as_atom().ok_or(Tanks::new())?;
1001989 Ok(Noun::list(
1002990 a.to_bytes_le().iter().map(|b| Noun::from_u32(*b as u32)),
1003991 ))
1004992};
1005993
1006994static MUK: Jet = |_ctx, n| {
1007− let (seed, len) = n.as_cell().ok_or(TTanks::new())?;
1008− let (len, key) = len.as_cell().ok_or(TTanks::new())?;
1009− let seed = seed.as_u32().ok_or(TTanks::new())?;
1010− let len = len.as_u32().ok_or(TTanks::new())?;
1011− let key = key.as_atom().ok_or(TTanks::new())?;
995+ let (seed, len) = n.as_cell().ok_or(Tanks::new())?;
996+ let (len, key) = len.as_cell().ok_or(Tanks::new())?;
997+ let seed = seed.as_u32().ok_or(Tanks::new())?;
998+ let len = len.as_u32().ok_or(Tanks::new())?;
999+ let key = key.as_atom().ok_or(Tanks::new())?;
10121000
10131001 Ok(Rc::new(Noun::from_u32(muk(seed, len, key))))
10141002};
10151003
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−
11791004static JUST: DoubleJet = |ctx, n, m| {
11801005 let char = n.as_atom()?;
11811006 let nail = m.as_nail()?;
nock/src/lib.rs+37−2
@@ -1,9 +1,11 @@
11#![feature(iter_intersperse)]
22#![feature(let_chains)]
33
4−use std::rc::Rc;
4+use core::str;
5+use std::{borrow::Borrow, rc::Rc};
56
6−use noun::Noun;
7+use interpreter::{eval_pulled_gate, slam_pulled_gate, tar, InterpreterContext, Tanks};
8+use noun::{cell, Noun};
79pub mod cue;
810pub mod interpreter;
911pub mod jam;
@@ -11,3 +13,36 @@ mod jets;
1113pub mod noun;
1214
1315pub type Vase = (Rc<Noun>, Rc<Noun>);
16+
17+pub fn wash(ctx: &mut InterpreterContext, urbit: &Rc<Noun>, tanks: Tanks) -> String {
18+ let mut target = String::new();
19+ for (subj, q) in tanks.iter() {
20+ match tar(ctx, subj.clone(), q).unwrap().borrow() {
21+ Noun::Atom(a) => {
22+ target.push_str(str::from_utf8_mut(&mut *a.to_bytes_le()).unwrap());
23+ }
24+ gate @ Noun::Cell { .. } => {
25+ let tank = eval_pulled_gate(ctx, Rc::new(gate.clone())).unwrap();
26+ let mut str = slam_pulled_gate(
27+ ctx,
28+ &urbit,
29+ &cell(
30+ &Rc::new(Noun::from_bytes(b"wash")),
31+ &cell(
32+ &cell(&Rc::new(Noun::from_u32(0)), &Rc::new(Noun::from_u32(80))),
33+ &tank,
34+ ),
35+ ),
36+ )
37+ .unwrap()
38+ .as_atom()
39+ .unwrap()
40+ .to_bytes_le();
41+
42+ target.push_str(str::from_utf8_mut(&mut *str).unwrap())
43+ }
44+ }
45+ }
46+
47+ target
48+}
nock/src/main.rs+18−44
@@ -1,8 +1,7 @@
11use clap::{command, error::Result, Parser, Subcommand};
22use core::str;
3−use nock::interpreter::{
4− ram_ttanks, slam_pulled_gate, tar, InterpreterContext, TTanks, JET_COUNTER,
5−};
3+use nock::interpreter::{eval_pulled_gate, slam_pulled_gate, tar, InterpreterContext, Tanks};
4+use nock::wash;
65use nock::{
76 cue::cue_bytes,
87 interpreter::{generate_interpreter_context, slam},
@@ -10,6 +9,7 @@ use nock::{
109 noun::{cell, Atom, Noun},
1110};
1211use spinoff::Spinner;
12+use std::borrow::Borrow;
1313use std::cell::LazyCell;
1414use std::{
1515 fs::File,
@@ -67,38 +67,9 @@ enum RunCommand {
6767 },
6868}
6969
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−
8870fn 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−
9771 let urbit = LazyCell::new(GENERATE_URBIT);
98− let mut ctx = InterpreterContext {
99− // slog: |_| {},
100− ..generate_interpreter_context()
101− };
72+ let mut ctx = generate_interpreter_context();
10273
10374 let cli = Cli::parse();
10475
@@ -120,7 +91,7 @@ fn main() -> Result<(), std::io::Error> {
12091 spinner.fail("Gate execution failed");
12192
12293 let mut spinner = new_spinner(String::from("Building trace"));
123− let trace = ram_ttanks(&mut ctx, tanks);
94+ let trace = wash(&mut ctx, &urbit, tanks);
12495 spinner.success("Trace built");
12596 println!("{trace}");
12697 exit(1);
@@ -167,16 +138,12 @@ fn main() -> Result<(), std::io::Error> {
167138 let (_typ, nok) = read_nock_or_compile(&mut spinner, &mut ctx, &urbit, &nock)?;
168139
169140 let sig = ctx.nouns.sig.clone();
170− let result = tar(&mut ctx, &sig, &nok).unwrap();
141+ let result = tar(&mut ctx, sig, &nok).unwrap();
171142
172143 println!("{result}");
173144 }
174145 }
175146
176− if cfg!(feature = "count-jets") {
177− print_jet_counter()
178− }
179−
180147 Ok(())
181148}
182149
@@ -215,7 +182,13 @@ fn compile_to_nock(
215182 &urbit,
216183 &cell(&Rc::new(Noun::from_bytes(b"hoon")), &ctx.nouns.sig),
217184 );
218− let hoon = or_wash_fail(ctx, hoon, spinner, "Failed to read Hoon standard library");
185+ let hoon = or_wash_fail(
186+ ctx,
187+ urbit,
188+ hoon,
189+ spinner,
190+ "Failed to read Hoon standard library",
191+ );
219192 let (hoon_type, hoon) = hoon.as_cell().unwrap();
220193
221194 spinner.update_text(format!("Compiling {root:#?}"));
@@ -233,7 +206,7 @@ fn compile_to_nock(
233206 ),
234207 ),
235208 );
236− let target = or_wash_fail(ctx, target, spinner, "Compilation failed");
209+ let target = or_wash_fail(ctx, urbit, target, spinner, "Compilation failed");
237210
238211 let (target_type, target_nock) = target.as_cell().unwrap();
239212
@@ -249,7 +222,7 @@ fn compile_to_nock(
249222 );
250223 let combined_nock = cell(
251224 target_type,
252− &or_wash_fail(ctx, combined_nock, spinner, "Failed to combine Nock"),
225+ &or_wash_fail(ctx, urbit, combined_nock, spinner, "Failed to combine Nock"),
253226 );
254227 Ok(combined_nock)
255228}
@@ -271,7 +244,8 @@ fn read_nock_or_compile(
271244
272245fn or_wash_fail(
273246 ctx: &mut InterpreterContext,
274− source: Result<Rc<Noun>, TTanks>,
247+ urbit: &Rc<Noun>,
248+ source: Result<Rc<Noun>, Tanks>,
275249 spinner: &mut Spinner,
276250 fail_err: &str,
277251) -> Rc<Noun> {
@@ -279,7 +253,7 @@ fn or_wash_fail(
279253 Ok(source) => source,
280254 Err(tanks) => {
281255 spinner.fail(fail_err);
282− let washed_tanks = ram_ttanks(ctx, tanks);
256+ let washed_tanks = wash(ctx, urbit, tanks);
283257 eprintln!("{}", washed_tanks);
284258 exit(1)
285259 }
nock/src/noun.rs−313
@@ -47,10 +47,6 @@ impl PartialEq for Noun {
4747impl<'a> Noun {
4848 pub const SIG: Noun = Noun::Atom(BigUint::ZERO);
4949
50− pub fn rc(self: Self) -> Rc<Self> {
51− Rc::new(self)
52− }
53−
5450 pub fn from_u32(a: u32) -> Noun {
5551 Noun::Atom(Atom::new(vec![a]))
5652 }
@@ -104,59 +100,6 @@ impl<'a> Noun {
104100 }
105101 }
106102
107− pub fn as_cell_cloned(self: &'a Self) -> Option<(Rc<Noun>, Rc<Noun>)> {
108− match self {
109− Noun::Cell { p, q, .. } => Option::Some((p.clone(), q.clone())),
110− _ => Option::None,
111− }
112− }
113−
114− pub fn tuple_2(self: &Self) -> Option<(&Rc<Noun>, &Rc<Noun>)> {
115− self.as_cell()
116− }
117−
118− pub fn tuple_3(self: &Self) -> Option<(&Rc<Noun>, &Rc<Noun>, &Rc<Noun>)> {
119− let (a, b) = self.as_cell()?;
120− let (b, c) = b.as_cell()?;
121−
122− Some((a, b, c))
123− }
124− pub fn tuple_4(self: &Self) -> Option<(&Rc<Noun>, &Rc<Noun>, &Rc<Noun>, &Rc<Noun>)> {
125− let (a, b) = self.as_cell()?;
126− let (b, c) = b.as_cell()?;
127− let (c, d) = c.as_cell()?;
128−
129− Some((a, b, c, d))
130− }
131−
132− pub fn tuple_5(self: &Self) -> Option<(&Rc<Noun>, &Rc<Noun>, &Rc<Noun>, &Rc<Noun>, &Rc<Noun>)> {
133− let (a, b) = self.as_cell()?;
134− let (b, c) = b.as_cell()?;
135− let (c, d) = c.as_cell()?;
136− let (d, e) = d.as_cell()?;
137−
138− Some((a, b, c, d, e))
139− }
140−
141− pub fn tuple_6(
142− self: &Self,
143− ) -> Option<(
144− &Rc<Noun>,
145− &Rc<Noun>,
146− &Rc<Noun>,
147− &Rc<Noun>,
148− &Rc<Noun>,
149− &Rc<Noun>,
150− )> {
151− let (a, b) = self.as_cell()?;
152− let (b, c) = b.as_cell()?;
153− let (c, d) = c.as_cell()?;
154− let (d, e) = d.as_cell()?;
155− let (e, f) = e.as_cell()?;
156−
157− Some((a, b, c, d, e, f))
158− }
159−
160103 pub fn is_sig(self: &Self) -> bool {
161104 match self {
162105 Noun::Atom(n) if *n == Atom::ZERO => true,
@@ -301,262 +244,6 @@ impl<'a> Noun {
301244 }
302245}
303246
304−pub trait AsNoun {
305− fn as_noun(self: &Self) -> Rc<Noun>;
306−}
307−
308−impl AsNoun for Atom {
309− fn as_noun(self: &Self) -> Rc<Noun> {
310− Rc::new(Noun::Atom(self.clone()))
311− }
312−}
313−
314−impl AsNoun for Noun {
315− fn as_noun(self: &Self) -> Rc<Noun> {
316− Rc::new(self.clone())
317− }
318−}
319−
320−impl AsNoun for Rc<Noun> {
321− fn as_noun(self: &Self) -> Rc<Noun> {
322− self.clone()
323− }
324−}
325−
326−impl<A, B> AsNoun for (A, B)
327−where
328− A: AsNoun,
329− B: AsNoun,
330−{
331− fn as_noun(self: &Self) -> Rc<Noun> {
332− let (a, b) = self;
333−
334− cell(&a.as_noun(), &b.as_noun())
335− }
336−}
337−
338−impl<A, B, C> AsNoun for (A, B, C)
339−where
340− A: AsNoun,
341− B: AsNoun,
342− C: AsNoun,
343−{
344− fn as_noun(self: &Self) -> Rc<Noun> {
345− let (a, b, c) = self;
346−
347− cell(&a.as_noun(), &cell(&b.as_noun(), &c.as_noun()))
348− }
349−}
350−
351−impl<A, B, C, D> AsNoun for (A, B, C, D)
352−where
353− A: AsNoun,
354− B: AsNoun,
355− C: AsNoun,
356− D: AsNoun,
357−{
358− fn as_noun(self: &Self) -> Rc<Noun> {
359− let (a, b, c, d) = self;
360−
361− cell(
362− &a.as_noun(),
363− &cell(&b.as_noun(), &cell(&c.as_noun(), &d.as_noun())),
364− )
365− }
366−}
367−
368−impl<A, B, C, D, E> AsNoun for (A, B, C, D, E)
369−where
370− A: AsNoun,
371− B: AsNoun,
372− C: AsNoun,
373− D: AsNoun,
374− E: AsNoun,
375−{
376− fn as_noun(self: &Self) -> Rc<Noun> {
377− let (a, b, c, d, e) = self;
378−
379− cell(
380− &a.as_noun(),
381− &cell(
382− &b.as_noun(),
383− &cell(&c.as_noun(), &cell(&d.as_noun(), &e.as_noun())),
384− ),
385− )
386− }
387−}
388−
389−impl<A, B, C, D, E, F> AsNoun for (A, B, C, D, E, F)
390−where
391− A: AsNoun,
392− B: AsNoun,
393− C: AsNoun,
394− D: AsNoun,
395− E: AsNoun,
396− F: AsNoun,
397−{
398− fn as_noun(self: &Self) -> Rc<Noun> {
399− let (a, b, c, d, e, f) = self;
400−
401− cell(
402− &a.as_noun(),
403− &cell(
404− &b.as_noun(),
405− &cell(
406− &c.as_noun(),
407− &cell(&d.as_noun(), &cell(&e.as_noun(), &f.as_noun())),
408− ),
409− ),
410− )
411− }
412−}
413−
414−impl From<(Rc<Noun>, Rc<Noun>)> for Noun {
415− fn from(value: (Rc<Noun>, Rc<Noun>)) -> Self {
416− naked_cell(&value.0, &value.1)
417− }
418−}
419−
420−impl From<(Rc<Noun>, Rc<Noun>, Rc<Noun>)> for Noun {
421− fn from(value: (Rc<Noun>, Rc<Noun>, Rc<Noun>)) -> Self {
422− naked_cell(&value.0, &cell(&value.1, &value.2))
423− }
424−}
425−
426−impl From<(Rc<Noun>, Rc<Noun>, Rc<Noun>, Rc<Noun>)> for Noun {
427− fn from(value: (Rc<Noun>, Rc<Noun>, Rc<Noun>, Rc<Noun>)) -> Self {
428− naked_cell(&value.0, &cell(&value.1, &cell(&value.2, &value.3)))
429− }
430−}
431−
432−impl From<(Rc<Noun>, Rc<Noun>, Rc<Noun>, Rc<Noun>, Rc<Noun>)> for Noun {
433− fn from(value: (Rc<Noun>, Rc<Noun>, Rc<Noun>, Rc<Noun>, Rc<Noun>)) -> Self {
434− naked_cell(
435− &value.0,
436− &cell(&value.1, &cell(&value.2, &cell(&value.3, &value.4))),
437− )
438− }
439−}
440−
441−impl From<(Rc<Noun>, Rc<Noun>, Rc<Noun>, Rc<Noun>, Rc<Noun>, Rc<Noun>)> for Noun {
442− fn from(value: (Rc<Noun>, Rc<Noun>, Rc<Noun>, Rc<Noun>, Rc<Noun>, Rc<Noun>)) -> Self {
443− naked_cell(
444− &value.0,
445− &cell(
446− &value.1,
447− &cell(&value.2, &cell(&value.3, &cell(&value.4, &value.5))),
448− ),
449− )
450− }
451−}
452−
453−impl
454− From<(
455− Rc<Noun>,
456− Rc<Noun>,
457− Rc<Noun>,
458− Rc<Noun>,
459− Rc<Noun>,
460− Rc<Noun>,
461− Rc<Noun>,
462− )> for Noun
463−{
464− fn from(
465− value: (
466− Rc<Noun>,
467− Rc<Noun>,
468− Rc<Noun>,
469− Rc<Noun>,
470− Rc<Noun>,
471− Rc<Noun>,
472− Rc<Noun>,
473− ),
474− ) -> Self {
475− naked_cell(
476− &value.0,
477− &cell(
478− &value.1,
479− &cell(
480− &value.2,
481− &cell(&value.3, &cell(&value.4, &cell(&value.5, &value.6))),
482− ),
483− ),
484− )
485− }
486−}
487−
488−impl From<Noun> for Option<(Rc<Noun>, Rc<Noun>)> {
489− fn from(value: Noun) -> Self {
490− value.as_cell_cloned()
491− }
492−}
493−
494−impl From<Noun> for Option<(Rc<Noun>, Rc<Noun>, Rc<Noun>)> {
495− fn from(value: Noun) -> Self {
496− let (a, b) = value.as_cell_cloned()?;
497− let (b, c) = b.as_cell_cloned()?;
498− Some((a, b, c))
499− }
500−}
501−
502−impl From<Noun> for Option<(Rc<Noun>, Rc<Noun>, Rc<Noun>, Rc<Noun>)> {
503− fn from(value: Noun) -> Self {
504− let (a, b) = value.as_cell_cloned()?;
505− let (b, c) = b.as_cell_cloned()?;
506− let (c, d) = c.as_cell_cloned()?;
507− Some((a, b, c, d))
508− }
509−}
510−
511−impl From<Noun> for Option<(Rc<Noun>, Rc<Noun>, Rc<Noun>, Rc<Noun>, Rc<Noun>)> {
512− fn from(value: Noun) -> Self {
513− let (a, b) = value.as_cell_cloned()?;
514− let (b, c) = b.as_cell_cloned()?;
515− let (c, d) = c.as_cell_cloned()?;
516− let (d, e) = d.as_cell_cloned()?;
517− Some((a, b, c, d, e))
518− }
519−}
520−
521−impl From<Noun> for Option<(Rc<Noun>, Rc<Noun>, Rc<Noun>, Rc<Noun>, Rc<Noun>, Rc<Noun>)> {
522− fn from(value: Noun) -> Self {
523− let (a, b) = value.as_cell_cloned()?;
524− let (b, c) = b.as_cell_cloned()?;
525− let (c, d) = c.as_cell_cloned()?;
526− let (d, e) = d.as_cell_cloned()?;
527− let (e, f) = e.as_cell_cloned()?;
528− Some((a, b, c, d, e, f))
529− }
530−}
531−
532−impl From<Noun>
533− for Option<(
534− Rc<Noun>,
535− Rc<Noun>,
536− Rc<Noun>,
537− Rc<Noun>,
538− Rc<Noun>,
539− Rc<Noun>,
540− Rc<Noun>,
541− )>
542−{
543− fn from(value: Noun) -> Self {
544− let (a, b) = value.as_cell_cloned()?;
545− let (b, c) = b.as_cell_cloned()?;
546− let (c, d) = c.as_cell_cloned()?;
547− let (d, e) = d.as_cell_cloned()?;
548− let (e, f) = e.as_cell_cloned()?;
549− let (f, g) = f.as_cell_cloned()?;
550− Some((a, b, c, d, e, f, g))
551− }
552−}
553−
554−impl From<&[u8]> for Noun {
555− fn from(value: &[u8]) -> Self {
556− Noun::from_bytes(value)
557− }
558−}
559−
560247#[derive(Clone)]
561248pub struct Edge<'a> {
562249 pub hair: Hair,
nock/test.hoondeleted−3
@@ -1,3 +0,0 @@
1−|= *
2−=/ target (gor 'd' 'c')
3−(crip "{<target>}")
nock/wock.hoon+10−198
@@ -1,204 +1,16 @@
11=>
22|%
3−++ http ^?
4− |%
5− :: +header-list: an ordered list of http headers
6− ::
7− +$ header-list
8− (list [key=@t value=@t])
9− :: +method: exhaustive list of http verbs
10− ::
11− +$ method
12− $? %'CONNECT'
13− %'DELETE'
14− %'GET'
15− %'HEAD'
16− %'OPTIONS'
17− %'PATCH'
18− %'POST'
19− %'PUT'
20− %'TRACE'
21− ==
22− :: +request: a single http request
23− ::
24− +$ request
25− $: :: method: http method
26− ::
27− method=method
28− :: url: the url requested
29− ::
30− :: The url is not escaped. There is no escape.
31− ::
32− url=@t
33− :: header-list: headers to pass with this request
34− ::
35− =header-list
36− :: body: optionally, data to send with this request
37− ::
38− body=(unit octs)
39− ==
40− :: +response-header: the status code and header list on an http request
41− ::
42− :: We separate these away from the body data because we may not wait for
43− :: the entire body before we send a %progress to the caller.
44− ::
45− +$ response-header
46− $: :: status: http status code
47− ::
48− status-code=@ud
49− :: headers: http headers
50− ::
51− headers=header-list
52− ==
53− :: +http-event: packetized http
54− ::
55− :: Urbit treats Earth's HTTP servers as pipes, where Urbit sends or
56− :: receives one or more %http-events. The first of these will always be a
57− :: %start or an %error, and the last will always be %cancel or will have
58− :: :complete set to %.y to finish the connection.
59− ::
60− :: Calculation of control headers such as 'Content-Length' or
61− :: 'Transfer-Encoding' should be performed at a higher level; this structure
62− :: is merely for what gets sent to or received from Earth.
63− ::
64− +$ http-event
65− $% :: %start: the first packet in a response
66− ::
67− $: %start
68− :: response-header: first event information
69− ::
70− =response-header
71− :: data: data to pass to the pipe
72− ::
73− data=(unit octs)
74− :: whether this completes the request
75− ::
76− complete=?
77− ==
78− :: %continue: every subsequent packet
79− ::
80− $: %continue
81− :: data: data to pass to the pipe
82− ::
83− data=(unit octs)
84− :: complete: whether this completes the request
85− ::
86− complete=?
87− ==
88− :: %cancel: represents unsuccessful termination
89− ::
90− [%cancel ~]
91− ==
92− :: +get-header: returns the value for :header, if it exists in :header-list
93− ::
94− ++ get-header
95− |= [header=@t =header-list]
96− ^- (unit @t)
97− ::
98− ?~ header-list
99− ~
100− ::
101− ?: =(key.i.header-list header)
102− `value.i.header-list
103− ::
104− $(header-list t.header-list)
105− :: +set-header: sets the value of an item in the header list
106− ::
107− :: This adds to the end if it doesn't exist.
108− ::
109− ++ set-header
110− |= [header=@t value=@t =header-list]
111− ^- ^header-list
112− ::
113− ?~ header-list
114− :: we didn't encounter the value, add it to the end
115− ::
116− [[header value] ~]
117− ::
118− ?: =(key.i.header-list header)
119− [[header value] t.header-list]
120− ::
121− [i.header-list $(header-list t.header-list)]
122− :: +delete-header: removes the first instance of a header from the list
123− ::
124− ++ delete-header
125− |= [header=@t =header-list]
126− ^- ^header-list
127− ::
128− ?~ header-list
129− ~
130− :: if we see it in the list, remove it
131− ::
132− ?: =(key.i.header-list header)
133− t.header-list
134− ::
135− [i.header-list $(header-list t.header-list)]
136− :: +unpack-header: parse header field values
137− ::
138− ++ unpack-header
139− |^ |= value=@t
140− ^- (unit (list (map @t @t)))
141− (rust (cass (trip value)) values)
142− ::
143− ++ values
144− %+ more
145− (ifix [. .]:(star ;~(pose ace (just '\09'))) com)
146− pairs
147− ::
148− ++ pairs
149− %+ cook
150− ~(gas by *(map @t @t))
151− %+ most (ifix [. .]:(star ace) mic)
152− ;~(plug token ;~(pose ;~(pfix tis value) (easy '')))
153− ::
154− ++ value
155− ;~(pose token quoted-string)
156− ::
157− ++ token :: 7230 token
158− %+ cook crip
159− ::NOTE this is ptok:de-purl:html, but can't access that here
160− %- plus
161− ;~ pose
162− aln zap hax buc cen pam soq tar lus
163− hep dot ket cab tic bar sig
164− ==
165− ::
166− ++ quoted-string :: 7230 quoted string
167− %+ cook crip
168− %+ ifix [. .]:;~(less (jest '\\"') doq)
169− %- star
170− ;~ pose
171− ;~(pfix bas ;~(pose (just '\09') ace prn))
172− ;~(pose (just '\09') ;~(less (mask "\22\5c\7f") (shim 0x20 0xff)))
173− ==
174− --
175− :: +simple-payload: a simple, one event response used for generators
176− ::
177− +$ simple-payload
178− $: :: response-header: status code, etc
179− ::
180− =response-header
181− :: data: the data returned as the body
182− ::
183− data=(unit octs)
184− ==
185− --
186−++ hop
187− |$ step
188− $%
189− [%fetch request:http]
190− ==
1913++ wock-app
192− |$ [model step]
4+ |$ [model event]
1935 $_ ^?
1946 |%
1957 ++ init *model
1968 ++ view |~ model *manx
197− ++ move |~ [model step] *model
9+ ++ move |~ [model event] *model
19810 --
19911++ app
200− |* [model=mold step=mold]
201− |= app=(wock-app model step)
12+ |* [model=mold event=mold]
13+ |= app=(wock-app model event)
20214 |= [cmd=@tas args=*]
20315 ?+ cmd !!
20416 %init
@@ -206,19 +18,19 @@
20618 %view
20719 (view.app (model args))
20820 %move
209− =/ [=model step-tape=tape payload=*] (,[model tape *] args)
210− (move.app [model (step [(crip step-tape) payload])])
21+ =/ [=model event-tape=tape payload=*] (,[model tape *] args)
22+ (move.app [model (event [(crip event-tape) payload])])
21123 ==
21224--
21325=>
21426|%
215−+$ step
27++$ event
21628 $%
21729 [%inc ~]
21830 [%dec ~]
21931 ==
22032--
221−%- (app @ud step)
33+%- (app @ud event)
22234|%
22335++ view
22436 |= count=@ud
@@ -228,9 +40,9 @@
22840 ;button(on-click "inc"): +
22941 ;button(on-click "dec"): -
23042 ==
231−++ init 11
43+++ init 8
23244++ move
233− |= [model=@ud step=step]
45+ |= [model=@ud step=event]
23446 ^- @ud
23547 ?- -.step
23648 %inc +(model)
wock-web/src/lib.rs+74−31
@@ -8,17 +8,15 @@ use dodrio::{
88 bumpalo::{self, Bump},
99 Attribute, Listener, Node, NodeKey, Render, RenderContext, RootRender, VdomWeak,
1010};
11−use gloo::net::{self, http::Request};
1211use nock::{
1312 cue::cue_bytes,
14− interpreter::{generate_interpreter_context, ram_ttanks, slam, InterpreterContext},
13+ interpreter::{generate_interpreter_context, slam, InterpreterContext},
1514 noun::{cell, Noun},
15+ wash,
1616};
1717use wasm_bindgen::prelude::*;
18−use web_sys::{
19− console::{error_1, log_1},
20− Element,
21−};
18+use wasm_bindgen_futures::{spawn_local, JsFuture};
19+use web_sys::{console::error_1, Element};
2220
2321#[wasm_bindgen]
2422extern "C" {
@@ -31,11 +29,41 @@ extern "C" {
3129 fn error(s: &str);
3230}
3331
32+#[derive(Clone)]
33+struct Urbit {
34+ urbit: RefCell<Option<Rc<Noun>>>,
35+}
36+
37+impl Urbit {
38+ fn new() -> Urbit {
39+ Urbit {
40+ urbit: RefCell::new(None),
41+ }
42+ }
43+
44+ async fn get(self: &Self) -> Rc<Noun> {
45+ match self.urbit.borrow().clone() {
46+ Some(urbit) => urbit,
47+ None => {
48+ let urbit = load_nock("/urbit.nock").await.unwrap_or_else(|err| {
49+ error_1(&err);
50+ panic!("Could not load urbit.")
51+ });
52+
53+ self.urbit.replace(Some(urbit.clone()));
54+
55+ urbit
56+ }
57+ }
58+ }
59+}
60+
3461#[derive(Clone)]
3562struct WockApp {
3663 nock: Rc<Noun>,
3764 ctx: RefCell<InterpreterContext>,
3865 model: Rc<Noun>,
66+ urbit: Rc<Urbit>,
3967}
4068
4169impl<'a> Render<'a> for WockApp {
@@ -47,9 +75,13 @@ impl<'a> Render<'a> for WockApp {
4775 ) {
4876 Ok(sail) => render_sail(cx, sail),
4977 Err(tanks) => {
50− let str = ram_ttanks(&mut (*self).ctx.borrow_mut(), tanks);
51− error_1(&JsValue::from_str(&str));
52−
78+ let wock_app = self.clone();
79+ let mut ctx = (*self.ctx.borrow()).clone();
80+ spawn_local(async move {
81+ let urbit = wock_app.urbit.get().await;
82+ let str = wash(&mut ctx, &urbit, tanks);
83+ error_1(&JsValue::from_str(&str));
84+ });
5385 panic!("Could not render");
5486 }
5587 }
@@ -92,20 +124,17 @@ fn render_sail<'a>(ctx: &mut RenderContext<'a>, manx: Rc<Noun>) -> Node<'a> {
92124
93125 let binding = app.ctx.clone();
94126 let mut ctx = binding.borrow_mut();
127+
95128 let sig = ctx.nouns.sig.clone();
96129
97− let step: Rc<Noun> = Rc::new((value.clone(), sig).into());
130+ let event = cell(&value, &sig);
98131
99132 match slam(
100133 &mut ctx,
101134 &app.nock,
102− &Rc::new(
103− (
104− Noun::from_bytes(b"move").rc(),
105− app.model.clone(),
106− step.clone(),
107− )
108− .into(),
135+ &cell(
136+ &Rc::new(Noun::from_bytes(b"move")),
137+ &cell(&app.model, &event),
109138 ),
110139 ) {
111140 Ok(new_model) => {
@@ -113,14 +142,16 @@ fn render_sail<'a>(ctx: &mut RenderContext<'a>, manx: Rc<Noun>) -> Node<'a> {
113142 vdom.schedule_render();
114143 }
115144 Err(tanks) => {
145+ let urbit = app.urbit.clone();
116146 let mut ctx = ctx.borrow_mut().clone();
117−
118− let str = ram_ttanks(&mut ctx, tanks);
119− error_1(&JsValue::from_str(&str));
120−
147+ spawn_local(async move {
148+ let urbit = urbit.get().await;
149+ let str = wash(&mut ctx, &urbit, tanks);
150+ error_1(&JsValue::from_str(&str));
151+ });
121152 error(&*format!(
122153 "Application failed to process event: {}",
123− step
154+ event
124155 ))
125156 }
126157 };
@@ -168,17 +199,14 @@ fn tape_to_bump_str<'a>(bump: &'a Bump, non: &Rc<Noun>) -> &'a str {
168199#[wasm_bindgen]
169200pub async fn main(path: &str) {
170201 let nock = load_nock(path).await.unwrap_or_else(|err| {
171− error(&*err.to_string());
202+ error_1(&err);
172203 panic!("Could not load nock.")
173204 });
174205
175206 let document = gloo::utils::document();
176207 let output_el: Element = document.get_element_by_id("output").unwrap();
177208
178− let mut ctx = InterpreterContext {
179− slog: |str: &String| log_1(&JsValue::from_str(&*str)),
180− ..generate_interpreter_context()
181− };
209+ let mut ctx = generate_interpreter_context();
182210
183211 let model = slam(
184212 &mut ctx,
@@ -188,7 +216,12 @@ pub async fn main(path: &str) {
188216 let model = match model {
189217 Ok(model) => model,
190218 Err(tanks) => {
191− let str = ram_ttanks(&mut ctx, tanks);
219+ let urbit = load_nock("/urbit.nock").await.unwrap_or_else(|err| {
220+ error_1(&err);
221+ panic!("Could not load urbit.")
222+ });
223+
224+ let str = wash(&mut ctx, &urbit, tanks);
192225 error_1(&JsValue::from_str(&str));
193226 panic!("Could not load initial model.");
194227 }
@@ -200,15 +233,25 @@ pub async fn main(path: &str) {
200233 nock,
201234 model,
202235 ctx: RefCell::new(ctx),
236+ urbit: Rc::new(Urbit::new()),
203237 },
204238 )
205239 .forget();
206240}
207241
208−pub async fn load_nock(path: &str) -> Result<Rc<Noun>, net::Error> {
209− let blob = Request::get(path).send().await?.binary().await?;
242+pub async fn load_nock(path: &str) -> Result<Rc<Noun>, JsValue> {
243+ let window = web_sys::window().unwrap();
244+
245+ let resp = JsFuture::from(window.fetch_with_str(path)).await?;
246+ assert!(resp.is_instance_of::<web_sys::Response>());
247+ let resp: web_sys::Response = resp.dyn_into()?;
248+ let blob = JsFuture::from(resp.blob()?).await?;
249+ assert!(blob.is_instance_of::<web_sys::Blob>());
250+ let blob: web_sys::Blob = blob.dyn_into()?;
251+
252+ let nock = js_sys::Uint8Array::new(&JsFuture::from(blob.array_buffer()).await?).to_vec();
210253
211− let nock = cue_bytes(&*blob);
254+ let nock = cue_bytes(&*nock);
212255 let (_typ, nok) = nock.as_cell().unwrap();
213256
214257 Ok(nok.clone())
wock.nock

Binary file not shown.