on master help sign in
quick refresh of nock pages for 4k spec
27b9edajoshuareagan
docs/tutorials/nock.umd+1−1
@@ -7,7 +7,7 @@
7
7
8# Nock
8# Nock
9
9
10−> Last major revision of this tutorial: 2016
10+> Last major revision of this tutorial: 2016. Minor revisions were made in October 2018 to bring it in line with the new Nock 4K spec.
11
11
12Nock is the low-level functional programming language that is interpreted by Vere. You don't need to know Nock to write Hoon, or even to work on most parts of Vere. But if you want to understand the foundations of Urbit and are mathematically-inclined, dive right in.
12Nock is the low-level functional programming language that is interpreted by Vere. You don't need to know Nock to write Hoon, or even to work on most parts of Vere. But if you want to understand the foundations of Urbit and are mathematically-inclined, dive right in.
13
13
docs/tutorials/nock/definition.umd+68−47
@@ -23,54 +23,67 @@ Hoon always become tail calls in Nock.)
23
23
24Nock is a combinator interpreter defined by the specification below.
24Nock is a combinator interpreter defined by the specification below.
25
25
26−This pseudocode (any system of axioms is properly defined in
27−pseudocode) is a system of problem reduction rules. Variables
26+This pseudocode describes a system of reduction rules. Variables
28match any noun; the first rule from the top matches.
27match any noun; the first rule from the top matches.
29
28
30−A formula that reduces to itself is an infinite loop, hence a
29+A formula that reduces to itself is an infinite loop, which we define as a
31−crash ("bottom" in formal logic). Obviously a real interpreter
30+crash ("bottom" in formal logic). A real interpreter
32can detect this crash and produce an out-of-band value instead.
31can detect this crash and produce an out-of-band value instead.
33
32
34```
33```
34+Nock 4K
35+
36+A noun is an atom or a cell. An atom is a natural number. A cell is an ordered pair of nouns.
37+
38+Reduce by the first matching pattern; variables match any noun.
39+
40+nock(a) *a
41+[a b c] [a [b c]]
42+
35−?[a b] 0
43+?[a b] 0
36−?a 1
44+?a 1
37−+[a b] +[a b]
45++[a b] +[a b]
38−+a 1 + a
46++a 1 + a
39−=[a a] 0
47+=[a a] 0
40−=[a b] 1
48+=[a b] 1
41−=a =a
49+
42−
43−/[1 a] a
50+/[1 a] a
44−/[2 a b] a
51+/[2 a b] a
45−/[3 a b] b
52+/[3 a b] b
46−/[(a + a) b] /[2 /[a b]]
53+/[(a + a) b] /[2 /[a b]]
47−/[(a + a + 1) b] /[3 /[a b]]
54+/[(a + a + 1) b] /[3 /[a b]]
48−/a /a
55+/a /a
49−
56+
57+#[1 a b] a
58+#[(a + a) b c] #[a [b /[(a + a + 1) c]] c]
59+#[(a + a + 1) b c] #[a [/[(a + a) c] b] c]
60+#a #a
61+
50−*[a [b c] d] [*[a b c] *[a d]]
62+*[a [b c] d] [*[a b c] *[a d]]
51−
63+
52−*[a 0 b] /[b a]
64+*[a 0 b] /[b a]
53−*[a 1 b] b
65+*[a 1 b] b
54−*[a 2 b c] *[*[a b] *[a c]]
66+*[a 2 b c] *[*[a b] *[a c]]
55−*[a 3 b] ?*[a b]
67+*[a 3 b] ?*[a b]
56−*[a 4 b] +*[a b]
68+*[a 4 b] +*[a b]
57−*[a 5 b] =*[a b]
69+*[a 5 b c] =[*[a b] *[a c]]
58−
70+
59−*[a 6 b c d] *[a 2 [0 1] 2 [1 c d] [1 0]
71+*[a 6 b c d] *[a *[[c d] 0 *[[2 3] 0 *[a 4 4 b]]]]
60− 2 [1 2 3] [1 0] 4 4 b]
61−*[a 7 b c] *[a 2 b 1 c]
72+*[a 7 b c] *[*[a b] c]
62−*[a 8 b c] *[a 7 [[7 [0 1] b] 0 1] c]
73+*[a 8 b c] *[[*[a b] a] c]
63−*[a 9 b c] *[a 7 c 2 [0 1] 0 b]
74+*[a 9 b c] *[*[a c] 2 [0 1] 0 b]
64−*[a 10 [b c] d] *[a 8 c 7 [0 3] d]
75+*[a 10 [b c] d] #[b *[a c] *[a d]]
76+
77+*[a 11 [b c] d] *[[*[a c] *[a d]] 0 3]
65−*[a 10 b c] *[a c]
78+*[a 11 b c] *[a c]
66−
79+
67−*a *a
80+*a *a
68```
81```
69
82
70## Operators
83## Operators
71
84
72−The pseudocode notation defines five prefix operators: `?`, `+`,
85+The pseudocode notation defines six prefix operators: `?`, `+`,
73−`=`, `/`, and `*`.
86+`=`, `/`, `#`, and `*`.
74
87
75`?[x]` reduces to `0` if `x` is a cell, `1` if an atom.
88`?[x]` reduces to `0` if `x` is a cell, `1` if an atom.
76
89
@@ -83,9 +96,13 @@ otherwise.
83is `1`; the left child of any node `n` is `2n`; the right child
96is `1`; the left child of any node `n` is `2n`; the right child
84is `2n+1`. `/[x y]` is the subtree of `y` at address `x`.
97is `2n+1`. `/[x y]` is the subtree of `y` at address `x`.
85
98
86−(For instance, `/[1 [531 25 99]]` is `[531 25 99]`; `/[2 [531 25
99+For instance, `/[1 [531 25 99]]` is `[531 25 99]`; `/[2 [531 25
8799]]` is `531`; `/[3 [531 25 99]]` is `[25 99]`; `/[6 [531 25
10099]]` is `531`; `/[3 [531 25 99]]` is `[25 99]`; `/[6 [531 25
88−99]]` is `25`; `/[12 [531 25 99]]` crashes.)
101+99]]` is `25`; `/[12 [531 25 99]]` crashes.
102+
103+`#` (`edit`) is for replacing part of a noun with another noun. `#[x y z]` replaces the value at slot `x` of `z` (i.e., `/[x z]`) with `y`.
104+
105+For instance, `#[2 11 [22 33]]` is `[11 33]`; `#[3 11 [22 33]]` is `[22 11]`; `#[4 11 [[22 33] 44]]` is `[[11 33] 44]`; and `#[5 11 [[22 33] 44]]` is `[[22 11] 44]`.
89
106
90`*[x y]` is the Nock interpreter function. `x` is the subject,
107`*[x y]` is the Nock interpreter function. `x` is the subject,
91`y` is the formula.
108`y` is the formula.
@@ -95,14 +112,14 @@ This is specified as an infinite loop, but in practice you get a crash.
95
112
96## Instructions
113## Instructions
97
114
98−A valid formula is always a cell. If the head of the formula is a
115+A valid Nock formula is always a cell. If the head of the formula is a
99cell, Nock treats both head and tail as formulas, resolves each
116cell, Nock treats both head and tail as formulas, resolves each
100against the subject, and produces the cell of their products. In
117against the subject, and produces the cell of their products. In
101other words, the Lisp program `(cons x y)` becomes the Nock
118other words, the Lisp program `(cons x y)` becomes the Nock
102formula `[x y]`.
119formula `[x y]`.
103
120
104If the head of the formula is an atom, it's an instruction from
121If the head of the formula is an atom, it's an instruction from
105−`0` to `10`.
122+`0` to `11`.
106
123
107A formula `[0 b]` reduces to the noun at tree address `b`
124A formula `[0 b]` reduces to the noun at tree address `b`
108in the subject.
125in the subject.
@@ -113,11 +130,13 @@ A formula `[2 b c]` treats `b` and `c` as formulas, resolves each
113against the subject, then computes Nock again with the product of
130against the subject, then computes Nock again with the product of
114`b` as the subject, `c` as the formula.
131`b` as the subject, `c` as the formula.
115
132
116−In formulas `[3 b]`, `[4 b]`, and `[5 b]`, `b` is another
133+In formulas `[3 b]` and `[4 b]`, `b` is another
117formula, whose product against the subject becomes the input to
134formula, whose product against the subject becomes the input to
118−an axiomatic operator. `3` is `?`, `4` is `+`, `5` is `=`.
135+an axiomatic operator. `3` is `?` and `4` is `+`
136+
137+A formula `[5 b c]` treats `b` and `c` as formulas that become the input to another axiomatic operator, `=`.
119
138
120−Instructions `6` through `10` are macros; deleting them
139+Instructions `6` through `11` are not strictly necessary for Turing completeness; deleting them
121from Nock would decrease compactness, but not expressiveness.
140from Nock would decrease compactness, but not expressiveness.
122
141
123`[6 b c d]` is *if* `b`, *then* `c`, *else* `d`. Each of `b`,
142`[6 b c d]` is *if* `b`, *then* `c`, *else* `d`. Each of `b`,
@@ -136,7 +155,9 @@ subject; from that product `d` it extracts a formula `e` at tree
136address `b`, then computes `*[d e]`. (`9` is designed to fit
155address `b`, then computes `*[d e]`. (`9` is designed to fit
137Hoon; `d` is a `core` (object), `e` points to an arm (method).)
156Hoon; `d` is a `core` (object), `e` points to an arm (method).)
138
157
158+In a formula `[10 [b c] d]`, `c` and `d` are computed with the current subject, and then `b` of the product of `d` is replaced with the product of `c`.
159+
139−`[10 b c]` is a *hint* semantically equivalent to the formula
160+`[11 b c]` is a *hint* semantically equivalent to the formula
140`c`. If `b` is an atom, it's a *static hint*, which is just
161`c`. If `b` is an atom, it's a *static hint*, which is just
141discarded. If `b` is a cell, it's a *dynamic* hint; the head of
162discarded. If `b` is a cell, it's a *dynamic* hint; the head of
142`b` is discarded, and the tail of `b` is executed as a formula
163`b` is discarded, and the tail of `b` is executed as a formula
docs/tutorials/nock/explanation.umd+76−35
@@ -210,6 +210,52 @@ is `[14 15]`
210
210
211Hopefully this isn't terribly hard to follow.
211Hopefully this isn't terribly hard to follow.
212
212
213+### Editing a Noun, `#`
214+
215+```
216+#[1 a b] a
217+#[(a + a) b c] #[a [b /[(a + a + 1) c]] c]
218+#[(a + a + 1) b c] #[a [/[(a + a) c] b] c]
219+```
220+
221+The `#` operator replaces part of a noun with another noun. `#[x y z]` replaces address `x` of `z` with the noun `y`.
222+
223+Take some noun, say, `[22 33 44 55]`. Let's replace part of it with another noun, `[123 456]`. We can replace the entire original noun as follows:
224+
225+```
226+#[1 [123 456] [22 33 44 55]]
227+```
228+
229+is
230+
231+```
232+[123 456]
233+```
234+
235+If we only want to replace the value at address `2`:
236+
237+```
238+#[2 [123 456] [22 33 44 55]]
239+```
240+
241+is
242+
243+```
244+[[123 456] 33 44 55]
245+```
246+
247+And we can replace address `3`:
248+
249+```
250+#[3 [123 456] [22 33 44 55]]
251+```
252+
253+is
254+
255+```
256+[22 123 456]
257+```
258+
213## Instructions
259## Instructions
214
260
215These rules define Nock itself - ie, the `*` operator.
261These rules define Nock itself - ie, the `*` operator.
@@ -227,6 +273,7 @@ Note that we're using Hoon syntax here. Since we do not use Nock
227from Hoon all that often (it's sort of like embedding assembly in
273from Hoon all that often (it's sort of like embedding assembly in
228C), we've left it a little cumbersome. In Hoon, instead of
274C), we've left it a little cumbersome. In Hoon, instead of
229writing `*[a 0 b]`, we write
275writing `*[a 0 b]`, we write
276+
230```
277```
231.*(a [0 b])
278.*(a [0 b])
232```
279```
@@ -281,10 +328,10 @@ This gives the same `[153 218]`
281```
328```
282*[a 3 b] ?*[a b]
329*[a 3 b] ?*[a b]
283*[a 4 b] +*[a b]
330*[a 4 b] +*[a b]
284−*[a 5 b] =*[a b]
331+*[a 5 b c] =[*[a b] *[a c]]
285```
332```
286
333
287−In lines 23-25, we meet our axiomatic functions again:
334+These are axiomatic functions:
288
335
289For instance, if `x` is a formula that calculates some product,
336For instance, if `x` is a formula that calculates some product,
290`[4 x]` calculates that product plus one. Hence:
337`[4 x]` calculates that product plus one. Hence:
@@ -322,7 +369,7 @@ We could write this line less formally:
322In other words, if you have two Nock formulas `x` and `y`, a
369In other words, if you have two Nock formulas `x` and `y`, a
323formula that computes the pair of them is just `[x y]`. We can
370formula that computes the pair of them is just `[x y]`. We can
324recognize this because no atom is a valid formula, and
371recognize this because no atom is a valid formula, and
325−every formula that *does not* use line 19 has an atomic head.
372+every formula that *does not* use distribution has an atomic head.
326
373
327If you know Lisp, you can think of this feature as a sort of
374If you know Lisp, you can think of this feature as a sort of
328"implicit cons." Where in Lisp you would write `(cons x y)`,
375"implicit cons." Where in Lisp you would write `(cons x y)`,
@@ -353,45 +400,45 @@ we get
353[43 1]
400[43 1]
354```
401```
355
402
356−Except for the crash defaults (lines 6, 10, 17, and 35), we've actually
403+Except for the crash defaults, we've actually
357completed all the _essential_ aspects of Nock. The instructions up
404completed all the _essential_ aspects of Nock. The instructions up
358through 5 provide all necessary computational functionality.
405through 5 provide all necessary computational functionality.
359Nock, though very simple, is actually much more complex than it
406Nock, though very simple, is actually much more complex than it
360formally needs to be.
407formally needs to be.
361
408
362−Operators 6 through 10 are macros. They exist because Nock is
409+Operators 6 through 11 are sugar. They exist because Nock is
363not a toy, but a practical interpreter. Let's see them all
410not a toy, but a practical interpreter. Let's see them all
364together:
411together:
365
412
366−## Macros
413+## Sugar
367
414
368```
415```
369−*[a 6 b c d] *[a 2 [0 1] 2 [1 c d] [1 0] 2 [1 2 3] [1 0] 4 4 b]
416+*[a 6 b c d] *[a *[[c d] 0 *[[2 3] 0 *[a 4 4 b]]]]
370−*[a 7 b c] *[a 2 b 1 c]
417+*[a 7 b c] *[*[a b] c]
371−*[a 8 b c] *[a 7 [[7 [0 1] b] 0 1] c]
418+*[a 8 b c] *[[*[a b] a] c]
372−*[a 9 b c] *[a 7 c 2 [0 1] 0 b]
419+*[a 9 b c] *[*[a c] 2 [0 1] 0 b]
373−*[a 10 [b c] d] *[a 8 c 7 [0 3] d]
420+*[a 10 [b c] d] #[b *[a c] *[a d]]
421+
422+*[a 11 [b c] d] *[[*[a c] *[a d]] 0 3]
374−*[a 10 b c] *[a c]
423+*[a 11 b c] *[a c]
375```
424```
376
425
377−Notice that instructions `6` through `10` are macros: each just
378−expands to a larger formula. Let's try to figure out what these
426+Let's try to figure out what these do, simplest first:
379−macros do, simplest first:
380
427
381−### `10`, hint
428+### `11`, hint
382
429
383```
430```
384−*[a 10 b c] *[a c]
431+*[a 11 b c] *[a c]
385```
432```
386
433
387If `x` is an atom and `y` is a formula, the formula `[10 x y]`
434If `x` is an atom and `y` is a formula, the formula `[10 x y]`
388appears to be equivalent to... `y`. For instance:
435appears to be equivalent to... `y`. For instance:
389
436
390```
437```
391−.*([132 19] [10 37 [4 0 3]])
438+.*([132 19] [11 37 [4 0 3]])
392```
439```
393
440
394−Why would we want to do this? `10` is actually a hint instruction.
441+Why would we want to do this? `11` is actually a hint instruction.
395The `37` in this example is discarded information - it is not
442The `37` in this example is discarded information - it is not
396used, formally, in the computation. It may help the interpreter
443used, formally, in the computation. It may help the interpreter
397compute the expression more efficiently, however.
444compute the expression more efficiently, however.
@@ -403,13 +450,13 @@ the Nock spec. Some are defined in Hoon. Indeed, a naive Nock
403interpreter not optimized for Hoon will run Hoon quite poorly.
450interpreter not optimized for Hoon will run Hoon quite poorly.
404When it gets the product, however, the product will be right.
451When it gets the product, however, the product will be right.
405
452
406−There is another instruction `10` rule:
453+There is another instruction `11` rule:
407
454
408```
455```
409−*[a 10 [b c] d] *[a 8 c 7 [0 3] d]
456+*[a 11 [b c] d] *[[*[a c] *[a d]] 0 3]
410```
457```
411
458
412−Once we see what `7` and `8` do, we'll see that this complex hint
459+This complex hint
413throws away an arbitrary `b`, but computes the formula `c`
460throws away an arbitrary `b`, but computes the formula `c`
414against the subject and... throws away the product. This formula
461against the subject and... throws away the product. This formula
415is simply equivalent to `d`. Of course, in practice the product
462is simply equivalent to `d`. Of course, in practice the product
@@ -418,12 +465,12 @@ wind up as a side effect.
418
465
419(Why do we even care that `c` is computed? Because `c` could
466(Why do we even care that `c` is computed? Because `c` could
420crash. A correct Nock cannot simply ignore it, and treat both
467crash. A correct Nock cannot simply ignore it, and treat both
421−variants of `10` as equivalent.)
468+variants of `11` as equivalent.)
422
469
423### `7`, compose
470### `7`, compose
424
471
425```
472```
426−*[a 7 b c] *[a 2 b 1 c]
473+*[a 7 b c] *[*[a b] c]
427```
474```
428
475
429Suppose we have two formulas, `b` and `c`. What is the formula
476Suppose we have two formulas, `b` and `c`. What is the formula
@@ -435,13 +482,13 @@ Suppose we have two formulas, `b` and `c`. What is the formula
435```
482```
436
483
437Good old composition, on Nock formulas. It's easy to see how
484Good old composition, on Nock formulas. It's easy to see how
438−this is built out of `2`. The data to evaluate is simply `b`,
485+this is a variant of Nock `2`. The data to evaluate is simply `b`,
439and the formula is `c` quoted.
486and the formula is `c` quoted.
440
487
441### `8`, extend
488### `8`, extend
442
489
443```
490```
444−*[a 8 b c] *[a 7 [[7 [0 1] b] 0 1] c]
491+*[a 8 b c] *[[*[a b] a] c]
445```
492```
446
493
447`8` is `7`, except that the subject for `c` is not simply the
494`8` is `7`, except that the subject for `c` is not simply the
@@ -464,22 +511,16 @@ likely to generate an `8`, because the variable is computed
464against the present subject, and used in a calculation which
511against the present subject, and used in a calculation which
465depends both on the original subject and the new variable.
512depends both on the original subject and the new variable.
466
513
467−For extra credit, explain why we can't just define
468−
469−```
470−*[a 8 b c] *[a 7 [b 0 1] c]
471−```
472−
473### `9`, invoke
514### `9`, invoke
474
515
475`9` is a calling convention:
516`9` is a calling convention:
476
517
477```
518```
478−*[a 9 b c] *[a 7 c 2 [0 1] 0 b]
519+*[a 9 b c] *[*[a c] 2 [0 1] 0 b]
479```
520```
480
521
481With `c`, we produce a noun which contains both code and data - a
522With `c`, we produce a noun which contains both code and data - a
482−*core*. We use this core as the subject, and evaulate the
523+*core*. We use this core as the subject, and evaluate the
483formula within it at slot `b`.
524formula within it at slot `b`.
484
525
485### `6`, if-then-else
526### `6`, if-then-else
@@ -487,7 +528,7 @@ formula within it at slot `b`.
487This looks much scarier than it is:
528This looks much scarier than it is:
488
529
489```
530```
490−*[a 6 b c d] *[a 2 [0 1] 2 [1 c d] [1 0] 2 [1 2 3] [1 0] 4 4 b]
531+*[a 6 b c d] *[a *[[c d] 0 *[[2 3] 0 *[a 4 4 b]]]]
491```
532```
492
533
493If `b` evaluates to `0`, we produce `c`; if `b` evaluates to `1`,
534If `b` evaluates to `0`, we produce `c`; if `b` evaluates to `1`,
docs/tutorials/nock/implementations.umd+70−26
@@ -12,10 +12,10 @@ and manual reference counting. More about the C environment can be found
12in the [runtime system documentation](../../../vere/runtime).
12in the [runtime system documentation](../../../vere/runtime).
13
13
14```
14```
15−/* nock(): produce .*(bus fol). Do not virtualize.
15+/* _n_nock_on(): produce .*(bus fol). Do not virtualize.
16*/
16*/
17static u3_noun
17static u3_noun
18−nock(u3_noun bus, u3_noun fol)
18+_n_nock_on(u3_noun bus, u3_noun fol)
19{
19{
20 u3_noun hib, gal;
20 u3_noun hib, gal;
21
21
@@ -23,11 +23,15 @@ nock(u3_noun bus, u3_noun fol)
23 hib = u3h(fol);
23 hib = u3h(fol);
24 gal = u3t(fol);
24 gal = u3t(fol);
25
25
26+#ifdef U3_CPU_DEBUG
27+ u3R->pro.nox_d += 1;
28+#endif
29+
26 if ( c3y == u3r_du(hib) ) {
30 if ( c3y == u3r_du(hib) ) {
27 u3_noun poz, riv;
31 u3_noun poz, riv;
28
32
29− poz = nock(u3k(bus), u3k(hib));
33+ poz = _n_nock_on(u3k(bus), u3k(hib));
30− riv = nock(bus, u3k(gal));
34+ riv = _n_nock_on(bus, u3k(gal));
31
35
32 u3a_lose(fol);
36 u3a_lose(fol);
33 return u3i_cell(poz, riv);
37 return u3i_cell(poz, riv);
@@ -57,8 +61,8 @@ nock(u3_noun bus, u3_noun fol)
57 c3_assert(!"not reached");
61 c3_assert(!"not reached");
58
62
59 case 2: {
63 case 2: {
60− u3_noun nex = nock(u3k(bus), u3k(u3t(gal)));
64+ u3_noun nex = _n_nock_on(u3k(bus), u3k(u3t(gal)));
61− u3_noun seb = nock(bus, u3k(u3h(gal)));
65+ u3_noun seb = _n_nock_on(bus, u3k(u3h(gal)));
62
66
63 u3a_lose(fol);
67 u3a_lose(fol);
64 bus = seb;
68 bus = seb;
@@ -70,7 +74,7 @@ nock(u3_noun bus, u3_noun fol)
70 case 3: {
74 case 3: {
71 u3_noun gof, pro;
75 u3_noun gof, pro;
72
76
73− gof = nock(bus, u3k(gal));
77+ gof = _n_nock_on(bus, u3k(gal));
74 pro = u3r_du(gof);
78 pro = u3r_du(gof);
75
79
76 u3a_lose(gof); u3a_lose(fol);
80 u3a_lose(gof); u3a_lose(fol);
@@ -81,7 +85,7 @@ nock(u3_noun bus, u3_noun fol)
81 case 4: {
85 case 4: {
82 u3_noun gof, pro;
86 u3_noun gof, pro;
83
87
84− gof = nock(bus, u3k(gal));
88+ gof = _n_nock_on(bus, u3k(gal));
85 pro = u3i_vint(gof);
89 pro = u3i_vint(gof);
86
90
87 u3a_lose(fol);
91 u3a_lose(fol);
@@ -90,7 +94,7 @@ nock(u3_noun bus, u3_noun fol)
90 c3_assert(!"not reached");
94 c3_assert(!"not reached");
91
95
92 case 5: {
96 case 5: {
93− u3_noun wim = nock(bus, u3k(gal));
97+ u3_noun wim = _n_nock_on(bus, u3k(gal));
94 u3_noun pro = u3r_sing(u3h(wim), u3t(wim));
98 u3_noun pro = u3r_sing(u3h(wim), u3t(wim));
95
99
96 u3a_lose(wim); u3a_lose(fol);
100 u3a_lose(wim); u3a_lose(fol);
@@ -103,7 +107,7 @@ nock(u3_noun bus, u3_noun fol)
103
107
104 u3x_trel(gal, &b_gal, &c_gal, &d_gal);
108 u3x_trel(gal, &b_gal, &c_gal, &d_gal);
105 {
109 {
106− u3_noun tys = nock(u3k(bus), u3k(b_gal));
110+ u3_noun tys = _n_nock_on(u3k(bus), u3k(b_gal));
107 u3_noun nex;
111 u3_noun nex;
108
112
109 if ( 0 == tys ) {
113 if ( 0 == tys ) {
@@ -124,7 +128,7 @@ nock(u3_noun bus, u3_noun fol)
124
128
125 u3x_cell(gal, &b_gal, &c_gal);
129 u3x_cell(gal, &b_gal, &c_gal);
126 {
130 {
127− u3_noun bod = nock(bus, u3k(b_gal));
131+ u3_noun bod = _n_nock_on(bus, u3k(b_gal));
128 u3_noun nex = u3k(c_gal);
132 u3_noun nex = u3k(c_gal);
129
133
130 u3a_lose(fol);
134 u3a_lose(fol);
@@ -140,7 +144,7 @@ nock(u3_noun bus, u3_noun fol)
140
144
141 u3x_cell(gal, &b_gal, &c_gal);
145 u3x_cell(gal, &b_gal, &c_gal);
142 {
146 {
143− u3_noun heb = nock(u3k(bus), u3k(b_gal));
147+ u3_noun heb = _n_nock_on(u3k(bus), u3k(b_gal));
144 u3_noun bod = u3nc(heb, bus);
148 u3_noun bod = u3nc(heb, bus);
145 u3_noun nex = u3k(c_gal);
149 u3_noun nex = u3k(c_gal);
146
150
@@ -157,18 +161,29 @@ nock(u3_noun bus, u3_noun fol)
157
161
158 u3x_cell(gal, &b_gal, &c_gal);
162 u3x_cell(gal, &b_gal, &c_gal);
159 {
163 {
160− u3_noun seb = nock(bus, u3k(c_gal));
164+ u3_noun seb = _n_nock_on(bus, u3k(c_gal));
165+ u3_noun pro;
161
166
162− if ( c3n == u3r_ud(b_gal) ) {
167+ u3t_off(noc_o);
163− return u3m_bail(c3__exit);
168+ pro = u3j_kick(seb, b_gal);
164− }
169+ u3t_on(noc_o);
165− else {
166− u3_noun nex = u3k(u3at(b_gal, seb));
167
170
171+ if ( u3_none != pro ) {
168 u3a_lose(fol);
172 u3a_lose(fol);
173+ return pro;
174+ }
175+ else {
176+ if ( c3n == u3r_ud(b_gal) ) {
177+ return u3m_bail(c3__exit);
178+ }
179+ else {
180+ u3_noun nex = u3k(u3at(b_gal, seb));
181+
182+ u3a_lose(fol);
169− bus = seb;
183+ bus = seb;
170− fol = nex;
184+ fol = nex;
171− continue;
185+ continue;
186+ }
172 }
187 }
173 }
188 }
174 }
189 }
@@ -187,7 +202,7 @@ nock(u3_noun bus, u3_noun fol)
187 u3_noun d_gal = q_gal;
202 u3_noun d_gal = q_gal;
188
203
189 zep = u3k(b_gal);
204 zep = u3k(b_gal);
190− hod = nock(u3k(bus), u3k(c_gal));
205+ hod = _n_nock_on(u3k(bus), u3k(c_gal));
191 nex = u3k(d_gal);
206 nex = u3k(d_gal);
192 }
207 }
193 else {
208 else {
@@ -199,10 +214,39 @@ nock(u3_noun bus, u3_noun fol)
199 nex = u3k(c_gal);
214 nex = u3k(c_gal);
200 }
215 }
201
216
202− u3a_lose(zep);
217+ u3a_lose(fol);
203− u3a_lose(hod);
218+ return _n_hint(zep, hod, bus, nex);
219+ }
220+ }
221+
222+ case 11: {
223+ u3_noun ref = _n_nock_on(u3k(bus), u3k(u3h(gal)));
224+ u3_noun gof = _n_nock_on(bus, u3k(u3t(gal)));
225+ u3_noun val;
204
226
205− return nock(bus, nex);
227+ u3t_off(noc_o);
228+ val = u3m_soft_esc(ref, u3k(gof));
229+ u3t_on(noc_o);
230+
231+ if ( !_(u3du(val)) ) {
232+ u3m_bail(u3nt(1, gof, 0));
233+ }
234+ if ( !_(u3du(u3t(val))) ) {
235+ //
236+ // replace with proper error stack push
237+ //
238+ u3t_push(u3nc(c3__hunk, _n_mush(gof)));
239+ return u3m_bail(c3__exit);
240+ }
241+ else {
242+ u3_noun pro;
243+
244+ u3z(gof);
245+ u3z(fol);
246+ pro = u3k(u3t(u3t(val)));
247+ u3z(val);
248+
249+ return pro;
206 }
250 }
207 }
251 }
208 c3_assert(!"not reached");
252 c3_assert(!"not reached");
@@ -211,6 +255,6 @@ nock(u3_noun bus, u3_noun fol)
211}
255}
212```
256```
213
257
214−Building a Nock interpreter in another language is a fun exercise. Check out our community Nock implementations:
258+Building a Nock interpreter in another language is a fun exercise. Check out our community Nock implementations. (Note: these were written for a slightly older version of Nock, Nock 5K. The current version is Nock 4K.):
215
259
216;list(src "../../nock/implementations");
260;list(src "../../nock/implementations");