on 63b60ca help sign in
urbit.org/docs/nock/implementations.md
215 lines 4.5 kB history raw
1---
2navhome: /docs/
3title: Implementation
4sort: 6
5---
7# C implementation
9The actual production Nock interpreter. Note gotos for tail-call elimination,
10and manual reference counting. More about the C environment can be found
11in the [runtime system documentation](../../../runtime).
13```
14/* nock(): produce .*(bus fol). Do not virtualize.
15*/
16static u3_noun
17nock(u3_noun bus, u3_noun fol)
19 u3_noun hib, gal;
21 while ( 1 ) {
22 hib = u3h(fol);
23 gal = u3t(fol);
25 if ( c3y == u3r_du(hib) ) {
26 u3_noun poz, riv;
28 poz = nock(u3k(bus), u3k(hib));
29 riv = nock(bus, u3k(gal));
31 u3a_lose(fol);
32 return u3i_cell(poz, riv);
33 }
34 else switch ( hib ) {
35 default: return u3m_bail(c3__exit);
37 case 0: {
38 if ( c3n == u3r_ud(gal) ) {
39 return u3m_bail(c3__exit);
40 }
41 else {
42 u3_noun pro = u3k(u3at(gal, bus));
44 u3a_lose(bus); u3a_lose(fol);
45 return pro;
46 }
47 }
48 c3_assert(!"not reached");
50 case 1: {
51 u3_noun pro = u3k(gal);
53 u3a_lose(bus); u3a_lose(fol);
54 return pro;
55 }
56 c3_assert(!"not reached");
58 case 2: {
59 u3_noun nex = nock(u3k(bus), u3k(u3t(gal)));
60 u3_noun seb = nock(bus, u3k(u3h(gal)));
62 u3a_lose(fol);
63 bus = seb;
64 fol = nex;
65 continue;
66 }
67 c3_assert(!"not reached");
69 case 3: {
70 u3_noun gof, pro;
72 gof = nock(bus, u3k(gal));
73 pro = u3r_du(gof);
75 u3a_lose(gof); u3a_lose(fol);
76 return pro;
77 }
78 c3_assert(!"not reached");
80 case 4: {
81 u3_noun gof, pro;
83 gof = nock(bus, u3k(gal));
84 pro = u3i_vint(gof);
86 u3a_lose(fol);
87 return pro;
88 }
89 c3_assert(!"not reached");
91 case 5: {
92 u3_noun wim = nock(bus, u3k(gal));
93 u3_noun pro = u3r_sing(u3h(wim), u3t(wim));
95 u3a_lose(wim); u3a_lose(fol);
96 return pro;
97 }
98 c3_assert(!"not reached");
100 case 6: {
101 u3_noun b_gal, c_gal, d_gal;
103 u3x_trel(gal, &b_gal, &c_gal, &d_gal);
104 {
105 u3_noun tys = nock(u3k(bus), u3k(b_gal));
106 u3_noun nex;
108 if ( 0 == tys ) {
109 nex = u3k(c_gal);
110 } else if ( 1 == tys ) {
111 nex = u3k(d_gal);
112 } else return u3m_bail(c3__exit);
114 u3a_lose(fol);
115 fol = nex;
116 continue;
117 }
118 }
119 c3_assert(!"not reached");
121 case 7: {
122 u3_noun b_gal, c_gal;
124 u3x_cell(gal, &b_gal, &c_gal);
125 {
126 u3_noun bod = nock(bus, u3k(b_gal));
127 u3_noun nex = u3k(c_gal);
129 u3a_lose(fol);
130 bus = bod;
131 fol = nex;
132 continue;
133 }
134 }
135 c3_assert(!"not reached");
137 case 8: {
138 u3_noun b_gal, c_gal;
140 u3x_cell(gal, &b_gal, &c_gal);
141 {
142 u3_noun heb = nock(u3k(bus), u3k(b_gal));
143 u3_noun bod = u3nc(heb, bus);
144 u3_noun nex = u3k(c_gal);
146 u3a_lose(fol);
147 bus = bod;
148 fol = nex;
149 continue;
150 }
151 }
152 c3_assert(!"not reached");
154 case 9: {
155 u3_noun b_gal, c_gal;
157 u3x_cell(gal, &b_gal, &c_gal);
158 {
159 u3_noun seb = nock(bus, u3k(c_gal));
161 if ( c3n == u3r_ud(b_gal) ) {
162 return u3m_bail(c3__exit);
163 }
164 else {
165 u3_noun nex = u3k(u3at(b_gal, seb));
167 u3a_lose(fol);
168 bus = seb;
169 fol = nex;
170 continue;
171 }
172 }
173 }
174 c3_assert(!"not reached");
176 case 10: {
177 u3_noun p_gal, q_gal;
179 u3x_cell(gal, &p_gal, &q_gal);
180 {
181 u3_noun zep, hod, nex;
183 if ( c3y == u3r_du(p_gal) ) {
184 u3_noun b_gal = u3h(p_gal);
185 u3_noun c_gal = u3t(p_gal);
186 u3_noun d_gal = q_gal;
188 zep = u3k(b_gal);
189 hod = nock(u3k(bus), u3k(c_gal));
190 nex = u3k(d_gal);
191 }
192 else {
193 u3_noun b_gal = p_gal;
194 u3_noun c_gal = q_gal;
196 zep = u3k(b_gal);
197 hod = u3_nul;
198 nex = u3k(c_gal);
199 }
201 u3a_lose(zep);
202 u3a_lose(hod);
204 return nock(bus, nex);
205 }
206 }
207 c3_assert(!"not reached");
208 }
209 }
211```
213Building a Nock interpreter in another language is a fun exercise. Check out our community Nock implementations:
215<list src="../../nock/implementations" className="nock"></list>