on master help sign in
commit5b2498909d8413f62b33381da031038a3a8bd044 authoriko <mail@iko.soy> dateThu 14 Nov 2024, 19:08 (2 years ago) parentf6a4944
4 files changed+311−24
nock/src/interpreter.rs+22−22 nock/src/main.rs+2−2 nock/src/noun.rs+104 nock/wock.hoon+183
nock/src/interpreter.rs+22−22
@@ -193,7 +193,7 @@ fn hax(
193193
194194fn tar_u32<'a>(
195195 ctx: &mut InterpreterContext,
196− subj: Rc<Noun>,
196+ subj: &'a Rc<Noun>,
197197 op: u32,
198198 formula: &'a Rc<Noun>,
199199) -> Result<Rc<Noun>, TTanks> {
@@ -216,16 +216,16 @@ fn tar_u32<'a>(
216216 match ctx.jets.get(&hash) {
217217 Some(f) => f(ctx, sample),
218218 None => {
219− let foo = tar(ctx, subj.clone(), &b)?;
219+ let foo = tar(ctx, subj, &b)?;
220220 let bar = tar(ctx, subj, &c)?;
221− tar(ctx, foo, &bar)
221+ tar(ctx, &foo, &bar)
222222 }
223223 }
224224 }
225225 _ => {
226− let foo = tar(ctx, subj.clone(), &b)?;
226+ let foo = tar(ctx, subj, &b)?;
227227 let bar = tar(ctx, subj, &c)?;
228− tar(ctx, foo, &bar)
228+ tar(ctx, &foo, &bar)
229229 }
230230 }
231231 }
@@ -236,7 +236,7 @@ fn tar_u32<'a>(
236236 4 => Ok(Rc::new(lus(&*tar(ctx, subj, &formula)?)?)),
237237 5 => {
238238 let (b, c) = formula.as_cell().ok_or(TTanks::new())?;
239− let foo = tar(ctx, subj.clone(), &b)?;
239+ let foo = tar(ctx, subj, &b)?;
240240 let bar = tar(ctx, subj, &c)?;
241241 Ok(tis(ctx, &foo, &bar).clone())
242242 }
@@ -244,29 +244,29 @@ fn tar_u32<'a>(
244244 let (b, c) = formula.as_cell().ok_or(TTanks::new())?;
245245 let (c, d) = c.as_cell().ok_or(TTanks::new())?;
246246
247− let bar = tar_u32(ctx, subj.clone(), 4, &cell(&ctx.nouns.four.clone(), &b))?;
247+ let bar = tar_u32(ctx, subj, 4, &cell(&ctx.nouns.four.clone(), &b))?;
248248
249− let foo = tar_u32(ctx, ctx.nouns.two_three.clone(), 0, &bar)?;
250− let foo = tar_u32(ctx, cell(&c, &d), 0, &foo)?;
249+ let foo = tar_u32(ctx, &ctx.nouns.two_three.clone(), 0, &bar)?;
250+ let foo = tar_u32(ctx, &cell(&c, &d), 0, &foo)?;
251251
252252 tar(ctx, subj, &foo)
253253 }
254254 7 => {
255255 let (b, c) = formula.as_cell().ok_or(TTanks::new())?;
256256 let foo = tar(ctx, subj, &b)?;
257− tar(ctx, foo, &c)
257+ tar(ctx, &foo, &c)
258258 }
259259 8 => {
260260 let (b, c) = formula.as_cell().ok_or(TTanks::new())?;
261− let foo = tar(ctx, subj.clone(), &b)?;
262− tar(ctx, cell(&foo, &subj), &c)
261+ let foo = tar(ctx, subj, &b)?;
262+ tar(ctx, &cell(&foo, &subj), &c)
263263 }
264264 9 => {
265265 let (b, c) = formula.as_cell().ok_or(TTanks::new())?;
266266 let foo = tar(ctx, subj, &c)?;
267267 tar_u32(
268268 ctx,
269− foo,
269+ &foo,
270270 2,
271271 &cell(&ctx.nouns.sig_one, &cell(&ctx.nouns.sig, &b)),
272272 )
@@ -276,7 +276,7 @@ fn tar_u32<'a>(
276276 let (b, c) = b.as_cell().ok_or(TTanks::new())?;
277277 let b = b.as_atom().ok_or(TTanks::new())?;
278278
279− let foo = tar(ctx, subj.clone(), &c)?;
279+ let foo = tar(ctx, subj, &c)?;
280280 let bar = tar(ctx, subj, &d)?;
281281 hax(ctx, b, &foo, &bar)
282282 }
@@ -285,7 +285,7 @@ fn tar_u32<'a>(
285285 match b.borrow() {
286286 Noun::Atom(_) => tar(ctx, subj, &d),
287287 Noun::Cell { p, q, .. } => {
288− let eval = |ctx: &mut InterpreterContext| tar(ctx, subj.clone(), &d);
288+ let eval = |ctx: &mut InterpreterContext| tar(ctx, subj, &d);
289289 if *p == ctx.nouns.memo {
290290 let hash = cell(&subj, &d).hash();
291291 match ctx.memo.get(&hash) {
@@ -299,7 +299,7 @@ fn tar_u32<'a>(
299299 } else if *p == ctx.nouns.mean {
300300 with_trace((subj.clone(), q.clone()), eval(ctx))
301301 } else if *p == ctx.nouns.slog {
302− let noun = tar(ctx, subj.clone(), &q)?;
302+ let noun = tar(ctx, subj, &q)?;
303303 let (_prio, tank) = noun.as_cell().ok_or(TTanks::new())?;
304304
305305 (ctx.slog)(&ram(ctx, tank.clone()).unwrap_or(String::new()));
@@ -411,7 +411,7 @@ pub fn ram_ttanks(ctx: &mut InterpreterContext, tanks: TTanks) -> String {
411411pub fn ram_ttank(ctx: &mut InterpreterContext, ttank: TTank) -> String {
412412 let (subj, q) = ttank;
413413
414− let tank = match tar(ctx, subj.clone(), &q) {
414+ let tank = match tar(ctx, &subj, &q) {
415415 Ok(gate) => match eval_pulled_gate(ctx, gate) {
416416 Ok(tank) => tank,
417417 Err(_) => {
@@ -444,13 +444,13 @@ pub const EMPTY_TANKS: TTanks = TTanks::new();
444444
445445pub fn tar<'a>(
446446 ctx: &mut InterpreterContext,
447− subj: Rc<Noun>,
447+ subj: &'a Rc<Noun>,
448448 formula: &'a Noun,
449449) -> Result<Rc<Noun>, TTanks> {
450450 let (op, formula) = formula.as_cell().ok_or(TTanks::new())?;
451451 match op.borrow() {
452452 Noun::Cell { .. } => {
453− let foo = tar(ctx, subj.clone(), &op)?;
453+ let foo = tar(ctx, subj, &op)?;
454454 let bar = tar(ctx, subj, &formula)?;
455455 Ok(cell(&foo, &bar))
456456 }
@@ -471,7 +471,7 @@ pub fn eval_gate(
471471 ctx: &mut InterpreterContext,
472472 gate_factory: &Rc<Noun>,
473473) -> Result<Rc<Noun>, TTanks> {
474− let pulled_gate = tar(ctx, ctx.nouns.sig.clone(), &gate_factory)?;
474+ let pulled_gate = tar(ctx, &ctx.nouns.sig.clone(), &gate_factory)?;
475475 eval_pulled_gate(ctx, pulled_gate)
476476}
477477
@@ -480,7 +480,7 @@ pub fn slam(
480480 gate_factory: &Rc<Noun>,
481481 sample: &Rc<Noun>,
482482) -> Result<Rc<Noun>, TTanks> {
483− let gate = tar(ctx, ctx.nouns.sig.clone(), &gate_factory)?;
483+ let gate = tar(ctx, &ctx.nouns.sig.clone(), &gate_factory)?;
484484
485485 eval_pulled_gate(ctx, replace_sample(&gate, sample)?)
486486}
@@ -490,7 +490,7 @@ pub fn slam(
490490pub fn eval_pulled_gate(ctx: &mut InterpreterContext, gate: Rc<Noun>) -> Result<Rc<Noun>, TTanks> {
491491 tar(
492492 ctx,
493− gate,
493+ &gate,
494494 &cell(
495495 &Rc::new(Noun::Atom(BigUint::new(vec![9]))),
496496 &cell(&ctx.nouns.two, &cell(&ctx.nouns.sig, &ctx.nouns.one)),
nock/src/main.rs+2−2
@@ -68,7 +68,7 @@ enum RunCommand {
6868fn main() -> Result<(), std::io::Error> {
6969 let urbit = LazyCell::new(GENERATE_URBIT);
7070 let mut ctx = InterpreterContext {
71− slog: |_| {},
71+ // slog: |_| {},
7272 ..generate_interpreter_context()
7373 };
7474
@@ -139,7 +139,7 @@ fn main() -> Result<(), std::io::Error> {
139139 let (_typ, nok) = read_nock_or_compile(&mut spinner, &mut ctx, &urbit, &nock)?;
140140
141141 let sig = ctx.nouns.sig.clone();
142− let result = tar(&mut ctx, sig, &nok).unwrap();
142+ let result = tar(&mut ctx, &sig, &nok).unwrap();
143143
144144 println!("{result}");
145145 }
nock/src/noun.rs+104
@@ -301,6 +301,110 @@ impl<'a> Noun {
301301 }
302302}
303303
304+pub trait AsNoun {
305+ fn as_noun(self: &Self) -> Rc<Noun>;
306+}
307+
308+impl AsNoun for Noun {
309+ fn as_noun(self: &Self) -> Rc<Noun> {
310+ Rc::new(self.clone())
311+ }
312+}
313+
314+impl AsNoun for Rc<Noun> {
315+ fn as_noun(self: &Self) -> Rc<Noun> {
316+ self.clone()
317+ }
318+}
319+
320+impl<A, B> AsNoun for (A, B)
321+where
322+ A: AsNoun,
323+ B: AsNoun,
324+{
325+ fn as_noun(self: &Self) -> Rc<Noun> {
326+ let (a, b) = self;
327+
328+ cell(&a.as_noun(), &b.as_noun())
329+ }
330+}
331+
332+impl<A, B, C> AsNoun for (A, B, C)
333+where
334+ A: AsNoun,
335+ B: AsNoun,
336+ C: AsNoun,
337+{
338+ fn as_noun(self: &Self) -> Rc<Noun> {
339+ let (a, b, c) = self;
340+
341+ cell(&a.as_noun(), &cell(&b.as_noun(), &c.as_noun()))
342+ }
343+}
344+
345+impl<A, B, C, D> AsNoun for (A, B, C, D)
346+where
347+ A: AsNoun,
348+ B: AsNoun,
349+ C: AsNoun,
350+ D: AsNoun,
351+{
352+ fn as_noun(self: &Self) -> Rc<Noun> {
353+ let (a, b, c, d) = self;
354+
355+ cell(
356+ &a.as_noun(),
357+ &cell(&b.as_noun(), &cell(&c.as_noun(), &d.as_noun())),
358+ )
359+ }
360+}
361+
362+impl<A, B, C, D, E> AsNoun for (A, B, C, D, E)
363+where
364+ A: AsNoun,
365+ B: AsNoun,
366+ C: AsNoun,
367+ D: AsNoun,
368+ E: AsNoun,
369+{
370+ fn as_noun(self: &Self) -> Rc<Noun> {
371+ let (a, b, c, d, e) = self;
372+
373+ cell(
374+ &a.as_noun(),
375+ &cell(
376+ &b.as_noun(),
377+ &cell(&c.as_noun(), &cell(&d.as_noun(), &e.as_noun())),
378+ ),
379+ )
380+ }
381+}
382+
383+impl<A, B, C, D, E, F> AsNoun for (A, B, C, D, E, F)
384+where
385+ A: AsNoun,
386+ B: AsNoun,
387+ C: AsNoun,
388+ D: AsNoun,
389+ E: AsNoun,
390+ F: AsNoun,
391+{
392+ fn as_noun(self: &Self) -> Rc<Noun> {
393+ let (a, b, c, d, e, f) = self;
394+
395+ cell(
396+ &a.as_noun(),
397+ &cell(
398+ &b.as_noun(),
399+ &cell(
400+ &c.as_noun(),
401+ &cell(&d.as_noun(), &cell(&e.as_noun(), &f.as_noun())),
402+ ),
403+ ),
404+ )
405+ }
406+}
407+
304408impl From<(Rc<Noun>, Rc<Noun>)> for Noun {
305409 fn from(value: (Rc<Noun>, Rc<Noun>)) -> Self {
306410 naked_cell(&value.0, &value.1)
nock/wock.hoon+183
@@ -1,5 +1,188 @@
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+ --
3186++ hop
4187 |$ step
5188 $%