on master help sign in
Cleaned up main
fd668c6iko
nock/hello.hoon+1−1
@@ -1 +1 @@
1−|=(x=@t (crip (weld "Hello, " (trip x))))
1+|=(x=@t (crip (weld "Hello, " (trip !!))))
nock/hello.nock

Binary file not shown.

nock/src/interpreter.rs−4
@@ -277,7 +277,6 @@ fn tar_u32<'a>(
277 Noun::Atom(_) => tar(ctx, subj, &d),
277 Noun::Atom(_) => tar(ctx, subj, &d),
278 Noun::Cell { p, q, .. } => {
278 Noun::Cell { p, q, .. } => {
279 let eval = |ctx: &mut InterpreterContext| tar(ctx, subj.clone(), &d);
279 let eval = |ctx: &mut InterpreterContext| tar(ctx, subj.clone(), &d);
280− // println!("{p}");
281 if *p == ctx.nouns.memo {
280 if *p == ctx.nouns.memo {
282 let hash = cell(&subj, &d).hash();
281 let hash = cell(&subj, &d).hash();
283 match ctx.memo.get(&hash) {
282 match ctx.memo.get(&hash) {
@@ -289,9 +288,6 @@ fn tar_u32<'a>(
289 }
288 }
290 }
289 }
291 } else if *p == ctx.nouns.mean {
290 } else if *p == ctx.nouns.mean {
292− // let gate = tar(ctx, subj.clone(), q)?;
293− // let trace = eval_pulled_gate(ctx, gate)?;
294− println!("tracing");
295 with_trace((subj.clone(), q.clone()), eval(ctx))
291 with_trace((subj.clone(), q.clone()), eval(ctx))
296 } else {
292 } else {
297 eval(ctx)
293 eval(ctx)
nock/src/main.rs+66−68
@@ -8,6 +8,7 @@ use nock::{
8 noun::{cell, Atom, Noun},
8 noun::{cell, Atom, Noun},
9};
9};
10use spinoff::Spinner;
10use spinoff::Spinner;
11+use std::cell::LazyCell;
11use std::{
12use std::{
12 fs::File,
13 fs::File,
13 io::{stdin, stdout, Read, Write},
14 io::{stdin, stdout, Read, Write},
@@ -16,7 +17,7 @@ use std::{
16 rc::Rc,
17 rc::Rc,
17};
18};
18
19
19−const URBIT: &[u8] = include_bytes!("../res/urbit.jam");
20+static GENERATE_URBIT: fn() -> Rc<Noun> = || cue_bytes(include_bytes!("../res/urbit.jam"));
20
21
21#[derive(Parser)]
22#[derive(Parser)]
22#[command(version)]
23#[command(version)]
@@ -65,34 +66,77 @@ enum RunCommand {
65}
66}
66
67
67fn main() -> Result<(), std::io::Error> {
68fn main() -> Result<(), std::io::Error> {
69+ let urbit = LazyCell::new(GENERATE_URBIT);
70+ let mut ctx = generate_interpreter_context();
71+
68 let cli = Cli::parse();
72 let cli = Cli::parse();
69
73
70 match cli.command {
74 match cli.command {
71 NockCommand::Run { command } => match command {
75 NockCommand::Run { command } => match command {
72− RunCommand::Interact { gate } => interact(gate)?,
76+ RunCommand::Interact { gate: gate_file } => {
77+ let mut spinner = new_spinner(format!("Loading {gate_file:#?}"));
78+
79+ let (_typ, nok) = read_nock_or_compile(&mut spinner, &mut ctx, &urbit, &gate_file)?;
80+
81+ spinner.success(&format!("Loaded {gate_file:#?}"));
82+
83+ let source = get_stdin().unwrap();
84+
85+ let mut spinner = new_spinner(String::from("Slamming gate..."));
86+ let slam = match slam(&mut ctx, &nok, &source) {
87+ Ok(slam) => slam,
88+ Err(tanks) => {
89+ spinner.fail("Gate execution failed");
90+
91+ let mut spinner = new_spinner(String::from("Building trace"));
92+ let trace = wash(&mut ctx, &urbit, tanks);
93+ spinner.success("Trace built");
94+ println!("{trace}");
95+ exit(1);
96+ }
97+ };
98+ let Some(target) = slam.as_bytes() else {
99+ spinner.fail("The gate did not produce a valid atom");
100+ exit(1);
101+ };
102+ spinner.success("Gate slammed successfully");
103+
104+ stdout().write_all(&target)?;
105+ }
73 },
106 },
74 NockCommand::Compile { root, output } => {
107 NockCommand::Compile { root, output } => {
75− compile(root, output).unwrap();
108+ let mut spinner = new_spinner(format!("Compiling {root:#?}"));
109+
110+ let nock = compile_to_nock(&mut ctx, &urbit, &mut spinner, root)?;
111+
112+ spinner.update_text(format!("Writing output to {output:#?}"));
113+
114+ let mut output_file = File::create(output.clone())?;
115+ File::write_all(&mut output_file, &jam_to_bytes(&nock)).unwrap();
116+
117+ spinner.success(&*format!("Compiled {output:#?} successfully"));
118+
119+ ()
76 }
120 }
77 NockCommand::HashGate { gate } => {
121 NockCommand::HashGate { gate } => {
78− let gate = read_nock(&gate)?;
122+ let (_type, gate) = read_nock(&gate)?;
79 let (hash, _sample) = gate.hash_gate();
123 let (hash, _sample) = gate.hash_gate();
80
124
81 println!("{hash}");
125 println!("{hash}");
82 }
126 }
83 NockCommand::HashDoubleGate { gate } => {
127 NockCommand::HashDoubleGate { gate } => {
84− let gate = read_nock(&gate)?;
128+ let (_type, gate) = read_nock(&gate)?;
85 let (hash, _sample_1, _sample_2) = gate.hash_double_gate();
129 let (hash, _sample_1, _sample_2) = gate.hash_double_gate();
86
130
87 println!("{hash}");
131 println!("{hash}");
88 }
132 }
89 NockCommand::Eval { nock } => {
133 NockCommand::Eval { nock } => {
90− let mut ctx = generate_interpreter_context();
134+ let mut spinner = new_spinner(format!("Loading {nock:#?}"));
91
135
92− let nock = read_nock_or_compile(&mut ctx, nock)?;
136+ let (_typ, nok) = read_nock_or_compile(&mut spinner, &mut ctx, &urbit, &nock)?;
93
137
94 let sig = ctx.nouns.sig.clone();
138 let sig = ctx.nouns.sig.clone();
95− let result = tar(&mut ctx, sig, &nock).unwrap();
139+ let result = tar(&mut ctx, sig, &nok).unwrap();
96
140
97 println!("{result}");
141 println!("{result}");
98 }
142 }
@@ -101,42 +145,13 @@ fn main() -> Result<(), std::io::Error> {
101 Ok(())
145 Ok(())
102}
146}
103
147
104−fn interact(gate_file: PathBuf) -> Result<(), std::io::Error> {
148+type Vase = (Rc<Noun>, Rc<Noun>);
105− let urbit = cue_bytes(URBIT);
106− let mut spinner = new_spinner(format!("Loading {gate_file:#?}"));
107− let binding = read_nock(&gate_file).unwrap();
108− let Some((_gate_type, gate)) = binding.as_cell() else {
109− spinner.fail(&format!("Failed to load {gate_file:#?}"));
110− exit(1);
111− };
112− spinner.success(&format!("Loaded {gate_file:#?}"));
113−
114− let source = get_stdin().unwrap();
115−
116− let mut spinner = new_spinner(String::from("Slamming gate..."));
117− let slam = match slam(&mut generate_interpreter_context(), &gate, &source) {
118− Ok(slam) => slam,
119− Err(tanks) => {
120− spinner.fail("Gate execution failed");
121− let mut ctx = generate_interpreter_context();
122− let trace = wash(&mut ctx, &urbit, tanks);
123− println!("{trace}");
124− exit(1);
125− }
126− };
127− let Some(target) = slam.as_bytes() else {
128− spinner.fail("The gate did not produce a valid atom");
129− exit(1);
130− };
131− spinner.success("Gate slammed successfully");
132−
133− stdout().write_all(&target)?;
134−
135− Ok(())
136−}
137
149
150+/// Reads a `vase` from a `.nock` file.
138−fn read_nock(nock_file: &PathBuf) -> Result<Rc<Noun>, std::io::Error> {
151+fn read_nock(nock_file: &PathBuf) -> Result<Vase, std::io::Error> {
139− Ok(cue_bytes(&read_file(nock_file)?))
152+ let nock = cue_bytes(&read_file(nock_file)?);
153+ let (typ, nok) = nock.as_cell().unwrap();
154+ Ok((typ.clone(), nok.clone()))
140}
155}
141
156
142fn read_file(nock_file: &PathBuf) -> Result<Vec<u8>, std::io::Error> {
157fn read_file(nock_file: &PathBuf) -> Result<Vec<u8>, std::io::Error> {
@@ -156,29 +171,12 @@ fn new_spinner(txt: String) -> Spinner {
156 Spinner::new_with_stream(spinoff::spinners::Dots, txt, None, spinoff::Streams::Stderr)
171 Spinner::new_with_stream(spinoff::spinners::Dots, txt, None, spinoff::Streams::Stderr)
157}
172}
158
173
159−fn compile(root: PathBuf, output: PathBuf) -> Result<(), std::io::Error> {
160− let mut spinner = new_spinner(format!("Loading Hoon compiler"));
161−
162− let mut ctx = generate_interpreter_context();
163−
164− let nock = compile_to_nock(&mut ctx, &mut spinner, root)?;
165−
166− spinner.update_text(format!("Writing output to {output:#?}"));
167−
168− let mut output_file = File::create(output.clone())?;
169− File::write_all(&mut output_file, &jam_to_bytes(&nock)).unwrap();
170−
171− spinner.success(&*format!("Compiled {output:#?} successfully"));
172−
173− Ok(())
174−}
175−
176fn compile_to_nock(
174fn compile_to_nock(
177 ctx: &mut InterpreterContext,
175 ctx: &mut InterpreterContext,
176+ urbit: &LazyCell<Rc<Noun>>,
178 spinner: &mut Spinner,
177 spinner: &mut Spinner,
179 root: PathBuf,
178 root: PathBuf,
180) -> Result<Rc<Noun>, std::io::Error> {
179) -> Result<Rc<Noun>, std::io::Error> {
181− let urbit = cue_bytes(URBIT);
182 let hoon = slam_pulled_gate(
180 let hoon = slam_pulled_gate(
183 ctx,
181 ctx,
184 &urbit,
182 &urbit,
@@ -223,14 +221,15 @@ fn compile_to_nock(
223}
221}
224
222
225fn read_nock_or_compile(
223fn read_nock_or_compile(
224+ spinner: &mut Spinner,
226 ctx: &mut InterpreterContext,
225 ctx: &mut InterpreterContext,
226+ urbit: &LazyCell<Rc<Noun>>,
227− path: PathBuf,
227+ path: &PathBuf,
228−) -> Result<Rc<Noun>, std::io::Error> {
228+) -> Result<Vase, std::io::Error> {
229 if path.extension().and_then(|x| x.to_str()) == Some("hoon") {
229 if path.extension().and_then(|x| x.to_str()) == Some("hoon") {
230− let mut spinner = new_spinner(String::new());
231− let nock = compile_to_nock(ctx, &mut spinner, path.clone())?;
230+ let nock = compile_to_nock(ctx, urbit, spinner, path.clone())?;
232− spinner.success(&*format!("Compiled {path:#?} successfully"));
231+ let (typ, nok) = nock.as_cell().unwrap();
233− Ok(nock)
232+ Ok((typ.clone(), nok.clone()))
234 } else {
233 } else {
235 read_nock(&path)
234 read_nock(&path)
236 }
235 }
@@ -239,7 +238,6 @@ fn read_nock_or_compile(
239fn wash(ctx: &mut InterpreterContext, urbit: &Rc<Noun>, tanks: Tanks) -> String {
238fn wash(ctx: &mut InterpreterContext, urbit: &Rc<Noun>, tanks: Tanks) -> String {
240 let mut target = String::new();
239 let mut target = String::new();
241 for (subj, q) in tanks.iter() {
240 for (subj, q) in tanks.iter() {
242− eprintln!("washing {q}");
243 let gate = tar(ctx, subj.clone(), q).unwrap();
241 let gate = tar(ctx, subj.clone(), q).unwrap();
244 let tank = eval_pulled_gate(ctx, gate).unwrap();
242 let tank = eval_pulled_gate(ctx, gate).unwrap();
245 let mut str = slam_pulled_gate(
243 let mut str = slam_pulled_gate(