on master help sign in
actually peoperly handle gates
commita0a922b8709f7b71712b7e410124c1783d4a0e00 authoriko <mail@iko.soy> dateSun 1 Sep 2024, 00:10 (2 years ago) parent49021de
11 files changed+123−64
nock/Cargo.toml−1 nock/make.nock nock/mint.nock nock/one.hoon+1−1 nock/one.nock+1−1 nock/res/comb.nock nock/src/interpreter.rs+33−12 nock/src/jam.rs+9−9 nock/src/jets.rs+33−21 nock/src/main.rs+34−12 nock/src/noun.rs+12−7
nock/Cargo.toml−1
@@ -39,7 +39,6 @@ wasm-bindgen-test = "0.3.34"
3939[profile.release]
4040# Tell `rustc` to optimize for small code size.
4141opt-level = 3
42−debug = true
4342
4443[[bin]]
4544name = "nock"
nock/make.nocknew file

No changes to the content.

nock/mint.nocknew file

No changes to the content.

nock/one.hoon+1−1
@@ -1 +1 @@
1−|=(@ 'Hello')
1+=> ~ |=(@ 'Hello')
nock/one.nock+1−1
@@ -1 +1 @@
1−A�
1+���� �����
nock/res/comb.nocknew file

Binary file not shown.

nock/src/interpreter.rs+33−12
@@ -196,15 +196,9 @@ fn tar_u32<'a>(
196196 match ctx.jets.get(&hash) {
197197 Some(f) => f(ctx, sample),
198198 None => {
199− let (hash, sample_1, sample_2) = subj.hash_double_gate();
200− match ctx.double_jets.get(&hash) {
201− Some(f) => f(ctx, sample_1, sample_2),
202− None => {
203− let foo = tar(ctx, subj, &b)?;
204− let bar = tar(ctx, subj, &c)?;
205− tar(ctx, &foo, &bar)
206− }
207− }
199+ let foo = tar(ctx, subj, &b)?;
200+ let bar = tar(ctx, subj, &c)?;
201+ tar(ctx, &foo, &bar)
208202 }
209203 }
210204 }
@@ -311,7 +305,24 @@ pub fn tar<'a>(ctx: &InterpreterContext, subj: &'a Noun, formula: &'a Noun) -> O
311305 }
312306}
313307
314−pub fn eval_gate(ctx: &InterpreterContext, gate: &Rc<Noun>) -> Option<Rc<Noun>> {
308+pub fn eval_gate(ctx: &InterpreterContext, gate_factory: &Rc<Noun>) -> Option<Rc<Noun>> {
309+ let pulled_gate = tar(ctx, &ctx.nouns.sig, &gate_factory)?;
310+ eval_pulled_gate(ctx, &pulled_gate)
311+}
312+
313+pub fn slam(
314+ ctx: &InterpreterContext,
315+ gate_factory: &Rc<Noun>,
316+ sample: &Rc<Noun>,
317+) -> Option<Rc<Noun>> {
318+ let gate = tar(ctx, &ctx.nouns.sig, &gate_factory)?;
319+
320+ eval_pulled_gate(ctx, &replace_sample(&gate, sample)?)
321+}
322+
323+/// This is useful for evaluaing gates produced by running `.foo/nock gate-name` in the dojo.
324+/// Also for calling gates from within jets.
325+pub fn eval_pulled_gate(ctx: &InterpreterContext, gate: &Rc<Noun>) -> Option<Rc<Noun>> {
315326 tar(
316327 ctx,
317328 &gate,
@@ -322,9 +333,19 @@ pub fn eval_gate(ctx: &InterpreterContext, gate: &Rc<Noun>) -> Option<Rc<Noun>>
322333 )
323334}
324335
325−pub fn slam(ctx: &InterpreterContext, gate: &Rc<Noun>, sample: &Rc<Noun>) -> Option<Rc<Noun>> {
336+/// This is useful for evaluaing gates produced by running `.foo/nock gate-name` in the dojo.
337+/// Also for calling gates from within jets.
338+pub fn slam_pulled_gate(
339+ ctx: &InterpreterContext,
340+ gate: &Rc<Noun>,
341+ sample: &Rc<Noun>,
342+) -> Option<Rc<Noun>> {
343+ eval_pulled_gate(ctx, &replace_sample(gate, sample)?)
344+}
345+
346+pub fn replace_sample(gate: &Rc<Noun>, sample: &Rc<Noun>) -> Option<Rc<Noun>> {
326347 let (battery, payload) = gate.as_cell()?;
327348 let (_sample, context) = payload.as_cell()?;
328349
329− eval_gate(ctx, &cell(battery, &cell(sample, context)))
350+ Some(cell(battery, &cell(sample, context)))
330351}
nock/src/jam.rs+9−9
@@ -1,23 +1,23 @@
1−use std::{collections::BTreeMap, rc::Rc};
1+use std::{borrow::Borrow, collections::BTreeMap, rc::Rc};
22
33use bitvec::vec::BitVec;
44use num_traits::FromPrimitive;
55
66use crate::noun::{Atom, Noun};
77
8−pub fn jam_to_bytes(noun: Rc<Noun>) -> Vec<u8> {
8+pub fn jam_to_bytes(noun: &Rc<Noun>) -> Vec<u8> {
99 let mut vec: BitVec<u8> = BitVec::new();
1010 jam(noun, &mut vec, &mut BTreeMap::new());
1111 vec.into_vec()
1212}
1313
14−fn jam(noun: Rc<Noun>, vec: &mut BitVec<u8>, refs: &mut BTreeMap<Noun, usize>) {
14+fn jam(noun: &Rc<Noun>, vec: &mut BitVec<u8>, refs: &mut BTreeMap<Noun, usize>) {
1515 let offset = vec.len();
1616
17− match refs.get(&noun).cloned() {
17+ match refs.get(noun).cloned() {
1818 Some(id) => {
1919 let id = Atom::from_usize(id).unwrap();
20− if let Noun::Atom(a) = (*noun).clone()
20+ if let Noun::Atom(a) = noun.borrow()
2121 && a.bits() <= id.bits()
2222 {
2323 vec.push(false);
@@ -29,9 +29,9 @@ fn jam(noun: Rc<Noun>, vec: &mut BitVec<u8>, refs: &mut BTreeMap<Noun, usize>) {
2929 }
3030 }
3131 None => {
32− refs.insert((*noun).clone(), offset);
32+ refs.insert((**noun).clone(), offset);
3333
34− match (*noun).clone() {
34+ match noun.borrow() {
3535 Noun::Atom(a) => {
3636 vec.push(false);
3737 mat(&a, vec);
@@ -39,8 +39,8 @@ fn jam(noun: Rc<Noun>, vec: &mut BitVec<u8>, refs: &mut BTreeMap<Noun, usize>) {
3939 Noun::Cell { p, q, .. } => {
4040 vec.push(true);
4141 vec.push(false);
42− jam(p, vec, refs);
43− jam(q, vec, refs);
42+ jam(&p, vec, refs);
43+ jam(&q, vec, refs);
4444 }
4545 }
4646 }
nock/src/jets.rs+33−21
@@ -8,7 +8,7 @@ use std::{
88};
99
1010use crate::{
11− interpreter::{slam, InterpreterContext},
11+ interpreter::{slam, slam_pulled_gate, InterpreterContext},
1212 noun::{self, cell, Atom, Edge, Hair, Nail, Noun},
1313};
1414
@@ -359,7 +359,7 @@ static LENT: Jet = |_ctx, n| {
359359
360360static LEVY: Jet = |ctx, n| {
361361 let (a, b) = n.as_cell()?;
362− if traverse_iter_option(a.list_iter().map(|n| slam(ctx, b, n)))?
362+ if traverse_iter_option(a.list_iter().map(|n| slam_pulled_gate(ctx, b, n)))?
363363 .iter()
364364 .all(|x| x.is_y())
365365 {
@@ -371,7 +371,7 @@ static LEVY: Jet = |ctx, n| {
371371
372372static LIEN: Jet = |ctx, n| {
373373 let (a, b) = n.as_cell()?;
374− if traverse_iter_option(a.list_iter().map(|n| slam(ctx, b, n)))?
374+ if traverse_iter_option(a.list_iter().map(|n| slam_pulled_gate(ctx, b, n)))?
375375 .iter()
376376 .any(|x| x.is_y())
377377 {
@@ -386,7 +386,7 @@ static MURN: Jet = |ctx, n| {
386386
387387 Some(Noun::list_refs(
388388 a.list_iter()
389− .filter_map(|n| slam(ctx, b, n)?.as_unit().cloned())
389+ .filter_map(|n| slam_pulled_gate(ctx, b, n)?.as_unit().cloned())
390390 .collect::<Vec<_>>()
391391 .iter(),
392392 ))
@@ -407,7 +407,7 @@ static REEL: Jet = |ctx, n| {
407407 Some(gate.gate_sample()?.as_cell()?.1.clone()),
408408 |acc, next| {
409409 let acc = acc?;
410− slam(ctx, gate, &cell(&next, &acc))
410+ slam_pulled_gate(ctx, gate, &cell(&next, &acc))
411411 },
412412 )
413413};
@@ -419,7 +419,7 @@ static ROLL: Jet = |ctx, n| {
419419 Some(gate.clone().gate_sample()?.as_cell()?.1.clone()),
420420 |acc, next| {
421421 let acc = acc?;
422− slam(ctx, gate, &cell(&next, &acc))
422+ slam_pulled_gate(ctx, gate, &cell(&next, &acc))
423423 },
424424 )
425425};
@@ -439,7 +439,10 @@ static SCAG: Jet = |_ctx, n| {
439439static SKID: Jet = |ctx, n| {
440440 let (list, gate) = n.as_cell()?;
441441
442− let slammed_n = traverse_iter_option(list.list_iter().map(|n| Some((slam(ctx, gate, n)?, n))))?;
442+ let slammed_n = traverse_iter_option(
443+ list.list_iter()
444+ .map(|n| Some((slam_pulled_gate(ctx, gate, n)?, n))),
445+ )?;
443446 let (ys, ns): (Vec<_>, _) = slammed_n.iter().partition(|(l, _)| l.is_y());
444447
445448 Some(cell(
@@ -452,10 +455,13 @@ static SKIM: Jet = |ctx, n| {
452455 let (list, gate) = n.as_cell()?;
453456
454457 Some(Noun::list_refs(
455− traverse_iter_option(list.list_iter().map(|n| Some((slam(ctx, gate, n)?, n))))?
456− .iter()
457− .filter(|(l, _)| l.is_y())
458− .map(|(_, x)| *x),
458+ traverse_iter_option(
459+ list.list_iter()
460+ .map(|n| Some((slam_pulled_gate(ctx, gate, n)?, n))),
461+ )?
462+ .iter()
463+ .filter(|(l, _)| l.is_y())
464+ .map(|(_, x)| *x),
459465 ))
460466};
461467
@@ -463,11 +469,14 @@ static SKIP: Jet = |ctx, n| {
463469 let (list, gate) = n.as_cell()?;
464470
465471 Some(Noun::list_refs(
466− traverse_iter_option(list.list_iter().map(|n| Some((slam(ctx, gate, n)?, n))))?
467− .iter()
468− .filter(|(l, _)| l.is_y())
469− .map(|(_, x)| x)
470− .cloned(),
472+ traverse_iter_option(
473+ list.list_iter()
474+ .map(|n| Some((slam_pulled_gate(ctx, gate, n)?, n))),
475+ )?
476+ .iter()
477+ .filter(|(l, _)| l.is_y())
478+ .map(|(_, x)| x)
479+ .cloned(),
471480 ))
472481};
473482
@@ -545,7 +554,7 @@ static SPIN: Jet = |ctx, n| {
545554 let mut acc = acc.clone();
546555
547556 for n in list.list_iter() {
548− let foo = slam(ctx, gate, &cell(&n, &acc))?;
557+ let foo = slam_pulled_gate(ctx, gate, &cell(&n, &acc))?;
549558 let (el, new_acc) = foo.as_cell()?;
550559 acc = new_acc.clone();
551560 res.push(el.clone());
@@ -561,7 +570,7 @@ static SPUN: Jet = |ctx, n| {
561570 let mut acc = gate.gate_sample()?.as_cell()?.1.clone();
562571
563572 for n in list.list_iter() {
564− let foo = slam(ctx, gate, &cell(&n, &acc))?;
573+ let foo = slam_pulled_gate(ctx, gate, &cell(&n, &acc))?;
565574 let (el, new_acc) = foo.as_cell()?;
566575 acc = new_acc.clone();
567576 res.push(el.clone());
@@ -573,7 +582,7 @@ static SPUN: Jet = |ctx, n| {
573582static TURN: Jet = |ctx, n| {
574583 let (list, gate) = n.as_cell()?;
575584 Some(Noun::list_refs(
576− traverse_iter_option(list.list_iter().map(|x| slam(ctx, gate, x)))?.iter(),
585+ traverse_iter_option(list.list_iter().map(|x| slam_pulled_gate(ctx, gate, x)))?.iter(),
577586 ))
578587};
579588
@@ -797,7 +806,8 @@ static RUN: Jet = |ctx, n| {
797806
798807 while b > ctx.big_uints.zero {
799808 target = (target << bits)
800− | ((*slam(ctx, gate, &Rc::new(Noun::Atom(&mask & &b)))?).as_atom()? & &mask);
809+ | ((*slam_pulled_gate(ctx, gate, &Rc::new(Noun::Atom(&mask & &b)))?).as_atom()?
810+ & &mask);
801811 b = b >> bits;
802812 }
803813
@@ -817,7 +827,9 @@ static RUT: Jet = |ctx, n| {
817827 let mut target = Vec::new();
818828
819829 while b > ctx.big_uints.zero {
820− target.push((*slam(ctx, gate, &Rc::new(Noun::Atom(&mask & &b)))?).as_atom()? & &mask);
830+ target.push(
831+ (*slam_pulled_gate(ctx, gate, &Rc::new(Noun::Atom(&mask & &b)))?).as_atom()? & &mask,
832+ );
821833 b = b >> bits;
822834 }
823835
nock/src/main.rs+34−12
@@ -1,5 +1,5 @@
11use clap::{command, error::Result, Parser, Subcommand};
2−use nock::interpreter::eval_gate;
2+use nock::interpreter::{eval_gate, eval_pulled_gate, slam_pulled_gate};
33use nock::{
44 cue::cue_bytes,
55 interpreter::{generate_interpreter_context, slam},
@@ -24,12 +24,14 @@ struct Cli {
2424
2525#[derive(Subcommand)]
2626enum NockCommand {
27− Build {
27+ #[command(about = "Compiles a single Hoon file to Nock")]
28+ Compile {
2829 #[arg(value_name = "FILE.hoon")]
2930 root: PathBuf,
3031 #[arg(short, long, value_name = "FILE.nock")]
3132 output: PathBuf,
3233 },
34+ #[command(about = "Runs compiled Nock")]
3335 Run {
3436 #[command(subcommand)]
3537 command: RunCommand,
@@ -47,10 +49,17 @@ enum NockCommand {
4749 #[arg(value_name = "FILE.nock")]
4850 gate: PathBuf,
4951 },
52+ Eval {
53+ #[arg(value_name = "FILE.nock")]
54+ nock: PathBuf,
55+ },
5056}
5157
5258#[derive(Subcommand)]
5359enum RunCommand {
60+ #[command(
61+ about = "Prints the result of slamming all of standard input as a cord against the supplied compiled gate. Expects the gate to also return a cord."
62+ )]
5463 Interact {
5564 #[arg(value_name = "FILE.nock")]
5665 gate: PathBuf,
@@ -64,14 +73,19 @@ fn main() -> Result<(), std::io::Error> {
6473 NockCommand::Run { command } => match command {
6574 RunCommand::Interact { gate } => interact(gate)?,
6675 },
67− NockCommand::Build { root, output } => {
68− build(root, output).unwrap();
76+ NockCommand::Compile { root, output } => {
77+ compile(root, output).unwrap();
6978 }
7079 NockCommand::Cycle => {
7180 let mut source = Vec::new();
81+ eprintln!("reading");
7282 stdin().read_to_end(&mut source).unwrap();
83+ eprintln!("cueing");
7384 let foo = cue_bytes(&source);
74− let bat = jam_to_bytes(foo);
85+ // eprintln!("{foo}");
86+ eprintln!("jamming");
87+ let bat = jam_to_bytes(&foo);
88+ eprintln!("writing");
7589 stdout().write(&bat).unwrap();
7690 }
7791 NockCommand::HashGate { gate } => {
@@ -89,7 +103,15 @@ fn main() -> Result<(), std::io::Error> {
89103 NockCommand::EvalGate { gate } => {
90104 let gate = read_nock(&gate).unwrap();
91105
92− let result = eval_gate(&generate_interpreter_context(), &gate).unwrap();
106+ let result = eval_pulled_gate(&generate_interpreter_context(), &gate).unwrap();
107+
108+ println!("{result}");
109+ }
110+ NockCommand::Eval { nock } => {
111+ let nock = read_nock(&nock).unwrap();
112+
113+ let ctx = generate_interpreter_context();
114+ let result = eval_pulled_gate(&ctx, &nock).unwrap();
93115
94116 println!("{result}");
95117 }
@@ -145,7 +167,7 @@ fn new_spinner(txt: String) -> Spinner {
145167 Spinner::new_with_stream(spinoff::spinners::Dots, txt, None, spinoff::Streams::Stderr)
146168}
147169
148−fn build(root: PathBuf, output: PathBuf) -> Result<(), std::io::Error> {
170+fn compile(root: PathBuf, output: PathBuf) -> Result<(), std::io::Error> {
149171 println!("reaming");
150172 let root_ast = {
151173 let ream_nock = include_bytes!("../res/ream.nock");
@@ -153,7 +175,7 @@ fn build(root: PathBuf, output: PathBuf) -> Result<(), std::io::Error> {
153175
154176 let root_source = read_file(&root)?;
155177
156− slam(
178+ slam_pulled_gate(
157179 &generate_interpreter_context(),
158180 &ream_gate,
159181 &Rc::new(Noun::Atom(Atom::from_bytes_le(&root_source))),
@@ -175,11 +197,11 @@ fn build(root: PathBuf, output: PathBuf) -> Result<(), std::io::Error> {
175197 println!("minting");
176198
177199 let mint_gate = cue_bytes(include_bytes!("../res/mint.nock"));
178− let slam_result = slam(&generate_interpreter_context(), &mint_gate, &ast).unwrap();
179−
180− // println!("{slam_result}");
200+ let minted_ast =
201+ slam_pulled_gate(&generate_interpreter_context(), &mint_gate, &root_ast).unwrap();
202+ let (_type, nock) = minted_ast.as_cell().unwrap();
181203
182204 let mut output_file = File::create(output)?;
183− File::write_all(&mut output_file, &jam_to_bytes(slam_result)).unwrap();
205+ File::write_all(&mut output_file, &jam_to_bytes(nock)).unwrap();
184206 Ok(())
185207}
nock/src/noun.rs+12−7
@@ -8,7 +8,7 @@ pub type Atom = BigUint;
88
99pub type Hash = u128;
1010
11−#[derive(Clone, Debug)]
11+#[derive(Clone, Debug, Eq)]
1212pub enum Noun {
1313 Atom(Atom),
1414 Cell {
@@ -18,8 +18,6 @@ pub enum Noun {
1818 },
1919}
2020
21−impl Eq for Noun {}
22−
2321impl Ord for Noun {
2422 fn cmp(&self, other: &Self) -> Ordering {
2523 compare_nouns(self, other)
@@ -37,7 +35,14 @@ fn compare_nouns(p: &Noun, q: &Noun) -> Ordering {
3735 (Noun::Atom(_), Noun::Cell { .. }) => Ordering::Less,
3836 (Noun::Cell { .. }, Noun::Atom(_)) => Ordering::Greater,
3937 (Noun::Atom(x), Noun::Atom(y)) => x.cmp(y),
40− (Noun::Cell { hash: x, .. }, Noun::Cell { hash: y, .. }) => x.cmp(y),
38+ (
39+ Noun::Cell {
40+ p: lhs_p, q: lhs_q, ..
41+ },
42+ Noun::Cell {
43+ p: rhs_p, q: rhs_q, ..
44+ },
45+ ) => (lhs_p, lhs_q).cmp(&(rhs_p, rhs_q)),
4146 }
4247}
4348
@@ -50,14 +55,14 @@ impl PartialEq for Noun {
5055 Noun::Cell {
5156 p: lhs_p,
5257 q: lhs_q,
53− hash: lhs_hash,
58+ hash: _lhs_hash,
5459 },
5560 Noun::Cell {
5661 p: rhs_p,
5762 q: rhs_q,
58− hash: rhs_hash,
63+ hash: _rhs_hash,
5964 },
60− ) => lhs_hash == rhs_hash && lhs_p == rhs_p && lhs_q == rhs_q,
65+ ) => self.hash() == other.hash() && lhs_p == rhs_p && lhs_q == rhs_q,
6166 _ => false,
6267 }
6368 }