on master help sign in
Handle errors better
commitee74d88ec0b8c79511c6f404b3f7639bd3270405 authoriko <mail@iko.soy> dateThu 7 Nov 2024, 16:01 (2 years ago) parent16e9e97
5 files changed+145−66
nock/bad.hoon+1 nock/src/interpreter.rs+3 nock/src/lib.rs+37−3 nock/src/main.rs+39−39 wock-web/src/lib.rs+65−24
nock/bad.hoonnew file+1
@@ -0,0 +1 @@
1+=/ foo [1 2] +(foo)
nock/src/interpreter.rs+3
@@ -9,6 +9,7 @@ use num_bigint::BigUint;
99use crate::jets::*;
1010use crate::noun::*;
1111
12+#[derive(Clone)]
1213pub struct Nouns {
1314 pub y: Rc<Noun>,
1415 pub n: Rc<Noun>,
@@ -23,6 +24,7 @@ pub struct Nouns {
2324 pub mean: Rc<Noun>,
2425}
2526
27+#[derive(Clone)]
2628pub struct BigUints {
2729 pub zero: BigUint,
2830 pub one: BigUint,
@@ -31,6 +33,7 @@ pub struct BigUints {
3133 pub four: BigUint,
3234}
3335
36+#[derive(Clone)]
3437pub struct InterpreterContext {
3538 pub jets: Jets,
3639 pub double_jets: DoubleJets,
nock/src/lib.rs+37−3
@@ -1,10 +1,11 @@
11#![feature(iter_intersperse)]
22#![feature(let_chains)]
3−#![feature(iter_repeat_n)]
43
5−use std::rc::Rc;
4+use core::str;
5+use std::{borrow::Borrow, rc::Rc};
66
7−use noun::Noun;
7+use interpreter::{eval_pulled_gate, slam_pulled_gate, tar, InterpreterContext, Tanks};
8+use noun::{cell, Noun};
89pub mod cue;
910pub mod interpreter;
1011pub mod jam;
@@ -12,3 +13,36 @@ mod jets;
1213pub mod noun;
1314
1415pub 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+39−39
@@ -1,6 +1,7 @@
11use clap::{command, error::Result, Parser, Subcommand};
22use core::str;
33use nock::interpreter::{eval_pulled_gate, slam_pulled_gate, tar, InterpreterContext, Tanks};
4+use nock::wash;
45use nock::{
56 cue::cue_bytes,
67 interpreter::{generate_interpreter_context, slam},
@@ -8,6 +9,7 @@ use nock::{
89 noun::{cell, Atom, Noun},
910};
1011use spinoff::Spinner;
12+use std::borrow::Borrow;
1113use std::cell::LazyCell;
1214use std::{
1315 fs::File,
@@ -179,8 +181,14 @@ fn compile_to_nock(
179181 ctx,
180182 &urbit,
181183 &cell(&Rc::new(Noun::from_bytes(b"hoon")), &ctx.nouns.sig),
182− )
183− .unwrap();
184+ );
185+ let hoon = or_wash_fail(
186+ ctx,
187+ urbit,
188+ hoon,
189+ spinner,
190+ "Failed to read Hoon standard library",
191+ );
184192 let (hoon_type, hoon) = hoon.as_cell().unwrap();
185193
186194 spinner.update_text(format!("Compiling {root:#?}"));
@@ -197,25 +205,26 @@ fn compile_to_nock(
197205 &Rc::new(Noun::Atom(Atom::from_bytes_le(&root_source))),
198206 ),
199207 ),
200− )
201− .unwrap();
208+ );
209+ let target = or_wash_fail(ctx, urbit, target, spinner, "Compilation failed");
202210
203211 let (target_type, target_nock) = target.as_cell().unwrap();
204212
205213 spinner.update_text(format!("Combining Nock formulas"));
206214
207− Ok(cell(
215+ let combined_nock = slam_pulled_gate(
216+ ctx,
217+ &urbit,
218+ &cell(
219+ &Rc::new(Noun::from_bytes(b"comb")),
220+ &cell(hoon, target_nock),
221+ ),
222+ );
223+ let combined_nock = cell(
208224 target_type,
209− &slam_pulled_gate(
210− ctx,
211− &urbit,
212− &cell(
213− &Rc::new(Noun::from_bytes(b"comb")),
214− &cell(hoon, target_nock),
215− ),
216− )
217− .unwrap(),
218− ))
225+ &or_wash_fail(ctx, urbit, combined_nock, spinner, "Failed to combine Nock"),
226+ );
227+ Ok(combined_nock)
219228}
220229
221230fn read_nock_or_compile(
@@ -233,29 +242,20 @@ fn read_nock_or_compile(
233242 }
234243}
235244
236−fn wash(ctx: &mut InterpreterContext, urbit: &Rc<Noun>, tanks: Tanks) -> String {
237− let mut target = String::new();
238− for (subj, q) in tanks.iter() {
239− let gate = tar(ctx, subj.clone(), q).unwrap();
240− let tank = eval_pulled_gate(ctx, gate).unwrap();
241− let mut str = slam_pulled_gate(
242− ctx,
243− &urbit,
244− &cell(
245− &Rc::new(Noun::from_bytes(b"wash")),
246− &cell(
247− &cell(&Rc::new(Noun::from_u32(0)), &Rc::new(Noun::from_u32(80))),
248− &tank,
249− ),
250− ),
251− )
252− .unwrap()
253− .as_atom()
254− .unwrap()
255− .to_bytes_le();
256−
257− target.push_str(str::from_utf8_mut(&mut *str).unwrap())
245+fn or_wash_fail(
246+ ctx: &mut InterpreterContext,
247+ urbit: &Rc<Noun>,
248+ source: Result<Rc<Noun>, Tanks>,
249+ spinner: &mut Spinner,
250+ fail_err: &str,
251+) -> Rc<Noun> {
252+ match source {
253+ Ok(source) => source,
254+ Err(tanks) => {
255+ spinner.fail(fail_err);
256+ let washed_tanks = wash(ctx, urbit, tanks);
257+ eprintln!("{}", washed_tanks);
258+ exit(1)
259+ }
258260 }
259−
260− target
261261}
wock-web/src/lib.rs+65−24
@@ -1,12 +1,8 @@
11#![feature(iter_collect_into)]
22mod utils;
33
4−use std::{
5− borrow::BorrowMut,
6− cell::RefCell,
7− ops::{Deref, DerefMut},
8− rc::Rc,
9−};
4+use core::panic;
5+use std::{cell::RefCell, rc::Rc};
106
117use dodrio::{
128 bumpalo::{self, Bump},
@@ -16,10 +12,11 @@ use nock::{
1612 cue::cue_bytes,
1713 interpreter::{generate_interpreter_context, slam, InterpreterContext},
1814 noun::{cell, Noun},
15+ wash,
1916};
2017use wasm_bindgen::prelude::*;
21−use wasm_bindgen_futures::JsFuture;
22−use web_sys::Element;
18+use wasm_bindgen_futures::{spawn_local, JsFuture};
19+use web_sys::{console::error_1, Element};
2320
2421#[wasm_bindgen]
2522extern "C" {
@@ -32,22 +29,51 @@ extern "C" {
3229 fn error(s: &str);
3330}
3431
32+#[derive(Clone)]
3533struct WockApp {
3634 nock: Rc<Noun>,
3735 ctx: RefCell<InterpreterContext>,
3836 model: Rc<Noun>,
37+ urbit: RefCell<Option<Rc<Noun>>>,
38+}
39+
40+impl WockApp {
41+ async fn get_urbit(self: &Self) -> Rc<Noun> {
42+ match self.urbit.borrow().clone() {
43+ Some(urbit) => urbit,
44+ None => {
45+ let urbit = load_nock("/urbit.nock").await.unwrap_or_else(|err| {
46+ error_1(&err);
47+ panic!("Could not load urbit.")
48+ });
49+
50+ self.urbit.replace(Some(urbit.clone()));
51+
52+ urbit
53+ }
54+ }
55+ }
3956}
4057
4158impl<'a> Render<'a> for WockApp {
4259 fn render(&self, cx: &mut dodrio::RenderContext<'a>) -> dodrio::Node<'a> {
43− let sail = slam(
60+ match slam(
4461 &mut *self.ctx.borrow_mut(),
4562 &self.nock,
4663 &cell(&Rc::new(Noun::from_bytes(b"view")), &self.model),
47− )
48− .unwrap();
49−
50− render_sail(cx, sail)
64+ ) {
65+ Ok(sail) => render_sail(cx, sail),
66+ Err(tanks) => {
67+ let wock_app = self.clone();
68+ let mut ctx = (*self.ctx.borrow()).clone();
69+ spawn_local(async move {
70+ let urbit = wock_app.get_urbit().await;
71+ let str = wash(&mut ctx, &urbit, tanks);
72+ error_1(&JsValue::from_str(&str));
73+ });
74+ panic!("Could not render");
75+ }
76+ }
5177 }
5278}
5379
@@ -151,7 +177,10 @@ fn tape_to_bump_str<'a>(bump: &'a Bump, non: &Rc<Noun>) -> &'a str {
151177
152178#[wasm_bindgen]
153179pub async fn main(path: &str) {
154− let nock = load_nock(path).await;
180+ let nock = load_nock(path).await.unwrap_or_else(|err| {
181+ error_1(&err);
182+ panic!("Could not load nock.")
183+ });
155184
156185 let document = gloo::utils::document();
157186 let output_el: Element = document.get_element_by_id("output").unwrap();
@@ -162,8 +191,20 @@ pub async fn main(path: &str) {
162191 &mut ctx,
163192 &nock,
164193 &cell(&Rc::new(Noun::from_bytes(b"init")), &Rc::new(Noun::SIG)),
165− )
166− .unwrap();
194+ );
195+ let model = match model {
196+ Ok(model) => model,
197+ Err(tanks) => {
198+ let urbit = load_nock("/urbit.nock").await.unwrap_or_else(|err| {
199+ error_1(&err);
200+ panic!("Could not load urbit.")
201+ });
202+
203+ let str = wash(&mut ctx, &urbit, tanks);
204+ error_1(&JsValue::from_str(&str));
205+ panic!("Could not load initial model.");
206+ }
207+ };
167208
168209 dodrio::Vdom::new(
169210 &output_el,
@@ -171,26 +212,26 @@ pub async fn main(path: &str) {
171212 nock,
172213 model,
173214 ctx: RefCell::new(ctx),
215+ urbit: RefCell::new(None),
174216 },
175217 )
176218 .forget();
177219}
178220
179−pub async fn load_nock(path: &str) -> Rc<Noun> {
221+pub async fn load_nock(path: &str) -> Result<Rc<Noun>, JsValue> {
180222 let window = web_sys::window().unwrap();
181223
182− let resp = JsFuture::from(window.fetch_with_str(path)).await.unwrap();
224+ let resp = JsFuture::from(window.fetch_with_str(path)).await?;
183225 assert!(resp.is_instance_of::<web_sys::Response>());
184− let resp: web_sys::Response = resp.dyn_into().unwrap();
185− let blob = JsFuture::from(resp.blob().unwrap()).await.unwrap();
226+ let resp: web_sys::Response = resp.dyn_into()?;
227+ let blob = JsFuture::from(resp.blob()?).await?;
186228 assert!(blob.is_instance_of::<web_sys::Blob>());
187− let blob: web_sys::Blob = blob.dyn_into().unwrap();
229+ let blob: web_sys::Blob = blob.dyn_into()?;
188230
189− let nock =
190− js_sys::Uint8Array::new(&JsFuture::from(blob.array_buffer()).await.unwrap()).to_vec();
231+ let nock = js_sys::Uint8Array::new(&JsFuture::from(blob.array_buffer()).await?).to_vec();
191232
192233 let nock = cue_bytes(&*nock);
193234 let (_typ, nok) = nock.as_cell().unwrap();
194235
195− nok.clone()
236+ Ok(nok.clone())
196237}