urbit/noun/nock.c

496 lines
9.6 KiB
C
Raw Normal View History

2014-09-11 04:01:32 +04:00
/* g/n.c
2014-09-05 23:55:16 +04:00
**
*/
#include "all.h"
2014-12-03 00:53:35 +03:00
static u3_noun _n_nock_on(u3_noun bus, u3_noun fol);
2014-10-28 20:36:22 +03:00
/* u3_term_io_hija(): hijack console for cooked print.
*/
FILE*
u3_term_io_hija(void);
/* u3_term_io_loja(): release console from cooked print.
*/
void
u3_term_io_loja(int x);
/* uL, uH: wrap hijack/lojack around fprintf.
**
** uL(fprintf(uH, ...));
*/
# define uH u3_term_io_hija()
# define uL(x) u3_term_io_loja(x)
2014-12-03 00:53:35 +03:00
/* _n_hint(): process hint.
2014-09-05 23:55:16 +04:00
*/
2014-09-06 00:13:24 +04:00
static u3_noun
2014-12-03 00:53:35 +03:00
_n_hint(u3_noun zep,
u3_noun hod,
u3_noun bus,
u3_noun nex)
2014-09-05 23:55:16 +04:00
{
switch ( zep ) {
default: {
2014-11-06 03:20:01 +03:00
// u3m_p("weird zep", zep);
u3a_lose(zep);
u3a_lose(hod);
2014-09-05 23:55:16 +04:00
2014-12-03 00:53:35 +03:00
return _n_nock_on(bus, nex);
2014-09-05 23:55:16 +04:00
}
case c3__hunk:
case c3__lose:
case c3__mean:
case c3__spot: {
2014-09-06 00:13:24 +04:00
u3_noun tac = u3nc(zep, hod);
u3_noun pro;
2014-09-05 23:55:16 +04:00
2014-11-06 03:20:01 +03:00
u3t_push(tac);
2014-09-05 23:55:16 +04:00
#if 0
{
static int low_i;
if ( !low_i ) {
low_i = 1;
if ( 0 == (u3R->pro.nox_d % 65536ULL) ) {
if ( c3__spot == zep ) {
uL(fprintf(uH, "spot %d/%d : %d/%d\r\n",
u3h(u3h(u3t(hod))),
u3t(u3h(u3t(hod))),
u3h(u3t(u3t(hod))),
u3t(u3t(u3t(hod)))));
}
}
low_i = 0;
}
2014-09-05 23:55:16 +04:00
}
#endif
2014-12-03 00:53:35 +03:00
pro = _n_nock_on(bus, nex);
2014-11-06 03:20:01 +03:00
u3t_drop();
2014-09-05 23:55:16 +04:00
return pro;
}
2016-02-23 21:57:34 +03:00
case c3__live: {
if ( c3y == u3ud(hod) ) {
2016-02-23 22:18:14 +03:00
u3t_off(noc_o);
2016-02-23 21:57:34 +03:00
u3t_heck(hod);
2016-02-23 22:18:14 +03:00
u3t_on(noc_o);
2016-02-23 21:57:34 +03:00
} else {
u3z(hod);
}
return _n_nock_on(bus, nex);
}
2014-09-05 23:55:16 +04:00
case c3__slog: {
2015-05-20 03:04:08 +03:00
if ( !(u3C.wag_w & u3o_quiet) ) {
u3t_off(noc_o);
u3t_slog(hod);
u3t_on(noc_o);
}
2014-12-03 00:53:35 +03:00
return _n_nock_on(bus, nex);
2014-09-05 23:55:16 +04:00
}
case c3__germ: {
2014-12-03 00:53:35 +03:00
u3_noun pro = _n_nock_on(bus, nex);
2014-09-05 23:55:16 +04:00
2014-11-06 03:20:01 +03:00
if ( c3y == u3r_sing(pro, hod) ) {
2014-09-06 00:13:24 +04:00
u3z(pro); return hod;
2014-09-05 23:55:16 +04:00
} else {
2014-09-06 00:13:24 +04:00
u3z(hod); return pro;
2014-09-05 23:55:16 +04:00
}
}
case c3__fast: {
2014-12-03 00:53:35 +03:00
u3_noun pro = _n_nock_on(bus, nex);
2014-09-05 23:55:16 +04:00
2014-12-03 00:53:35 +03:00
u3t_off(noc_o);
2014-11-06 03:20:01 +03:00
u3j_mine(hod, u3k(pro));
2014-12-03 00:53:35 +03:00
u3t_on(noc_o);
2014-10-25 01:04:44 +04:00
return pro;
2014-09-05 23:55:16 +04:00
}
case c3__memo: {
2014-09-06 00:13:24 +04:00
u3z(hod);
2014-09-17 04:29:12 +04:00
#if 0
2014-12-03 00:53:35 +03:00
return _n_nock_on(bus, nex);
2014-09-17 04:29:12 +04:00
#else
2014-09-05 23:55:16 +04:00
{
2014-11-06 03:20:01 +03:00
u3_noun pro = u3z_find_2(c3__nock, bus, nex);
2014-09-05 23:55:16 +04:00
2014-11-06 02:36:30 +03:00
if ( pro != u3_none ) {
2014-10-11 09:32:58 +04:00
u3z(bus); u3z(nex);
2014-09-05 23:55:16 +04:00
return pro;
}
2014-12-03 00:53:35 +03:00
pro = _n_nock_on(u3k(bus), u3k(nex));
2014-09-05 23:55:16 +04:00
2015-07-02 01:28:55 +03:00
if ( &(u3H->rod_u) != u3R ) {
2015-05-14 01:23:20 +03:00
u3z_save_2(c3__nock, bus, nex, pro);
}
2014-09-06 00:13:24 +04:00
u3z(bus); u3z(nex);
2014-10-10 05:27:02 +04:00
return pro;
2014-09-05 23:55:16 +04:00
}
2014-09-17 04:29:12 +04:00
#endif
2014-09-05 23:55:16 +04:00
}
case c3__sole: {
2014-09-06 00:13:24 +04:00
u3z(hod);
2014-09-05 23:55:16 +04:00
{
2014-12-03 00:53:35 +03:00
u3_noun pro = _n_nock_on(bus, nex);
2014-09-05 23:55:16 +04:00
2014-11-06 03:20:01 +03:00
// return u3z_uniq(pro);
2014-09-17 04:29:12 +04:00
return pro;
2014-09-05 23:55:16 +04:00
}
}
}
}
/* _n_mush_in(): see _n_mush().
*/
static u3_noun
_n_mush_in(u3_noun val)
{
if ( c3n == u3du(val) ) {
return u3_nul;
}
else {
u3_noun h_val = u3h(val);
u3_noun ite;
if ( c3n == u3ud(h_val) ) {
ite = u3nc(c3__leaf, u3_nul);
} else {
ite = u3nc(c3__leaf, u3qe_trip(h_val));
}
return u3nc(ite, _n_mush_in(u3t(val)));
}
}
/* _n_mush(): tank from failed path request.
*/
static u3_noun
_n_mush(u3_noun val)
{
u3_noun pro;
pro = u3nt(c3__rose,
u3nt(u3nc('/', u3_nul), u3nc('/', u3_nul), u3_nul),
_n_mush_in(val));
u3z(val);
return pro;
}
2014-12-03 00:53:35 +03:00
/* _n_nock_on(): produce .*(bus fol). Do not virtualize.
2014-09-05 23:55:16 +04:00
*/
static u3_noun
2014-12-03 00:53:35 +03:00
_n_nock_on(u3_noun bus, u3_noun fol)
2014-09-05 23:55:16 +04:00
{
2014-09-06 00:13:24 +04:00
u3_noun hib, gal;
2014-09-05 23:55:16 +04:00
while ( 1 ) {
2014-09-06 00:13:24 +04:00
hib = u3h(fol);
gal = u3t(fol);
2014-09-05 23:55:16 +04:00
2014-09-27 06:14:24 +04:00
u3R->pro.nox_d += 1;
2014-09-16 03:56:37 +04:00
2014-11-06 03:20:01 +03:00
if ( c3y == u3r_du(hib) ) {
2014-09-06 00:13:24 +04:00
u3_noun poz, riv;
2014-09-05 23:55:16 +04:00
2014-12-03 00:53:35 +03:00
poz = _n_nock_on(u3k(bus), u3k(hib));
riv = _n_nock_on(bus, u3k(gal));
2014-09-05 23:55:16 +04:00
2014-11-06 03:20:01 +03:00
u3a_lose(fol);
return u3i_cell(poz, riv);
2014-09-05 23:55:16 +04:00
}
else switch ( hib ) {
2014-11-06 03:20:01 +03:00
default: return u3m_bail(c3__exit);
2014-09-05 23:55:16 +04:00
case 0: {
2014-11-06 03:20:01 +03:00
if ( c3n == u3r_ud(gal) ) {
return u3m_bail(c3__exit);
2014-09-05 23:55:16 +04:00
}
else {
2014-09-06 00:13:24 +04:00
u3_noun pro = u3k(u3at(gal, bus));
2014-09-05 23:55:16 +04:00
2014-11-06 03:20:01 +03:00
u3a_lose(bus); u3a_lose(fol);
2014-09-05 23:55:16 +04:00
return pro;
}
}
c3_assert(!"not reached");
case 1: {
2014-09-06 00:13:24 +04:00
u3_noun pro = u3k(gal);
2014-09-05 23:55:16 +04:00
2014-11-06 03:20:01 +03:00
u3a_lose(bus); u3a_lose(fol);
2014-09-05 23:55:16 +04:00
return pro;
}
c3_assert(!"not reached");
case 2: {
2014-12-03 00:53:35 +03:00
u3_noun nex = _n_nock_on(u3k(bus), u3k(u3t(gal)));
u3_noun seb = _n_nock_on(bus, u3k(u3h(gal)));
2014-09-05 23:55:16 +04:00
2014-11-06 03:20:01 +03:00
u3a_lose(fol);
2014-09-05 23:55:16 +04:00
bus = seb;
fol = nex;
continue;
}
c3_assert(!"not reached");
case 3: {
2014-09-06 00:13:24 +04:00
u3_noun gof, pro;
2014-09-05 23:55:16 +04:00
2014-12-03 00:53:35 +03:00
gof = _n_nock_on(bus, u3k(gal));
2014-11-06 03:20:01 +03:00
pro = u3r_du(gof);
2014-09-05 23:55:16 +04:00
2014-11-06 03:20:01 +03:00
u3a_lose(gof); u3a_lose(fol);
2014-09-05 23:55:16 +04:00
return pro;
}
c3_assert(!"not reached");
case 4: {
2014-09-06 00:13:24 +04:00
u3_noun gof, pro;
2014-09-05 23:55:16 +04:00
2014-12-03 00:53:35 +03:00
gof = _n_nock_on(bus, u3k(gal));
2014-11-06 03:20:01 +03:00
pro = u3i_vint(gof);
2014-09-05 23:55:16 +04:00
2014-11-06 03:20:01 +03:00
u3a_lose(fol);
2014-09-05 23:55:16 +04:00
return pro;
}
c3_assert(!"not reached");
case 5: {
2014-12-03 00:53:35 +03:00
u3_noun wim = _n_nock_on(bus, u3k(gal));
2014-11-06 03:20:01 +03:00
u3_noun pro = u3r_sing(u3h(wim), u3t(wim));
2014-09-05 23:55:16 +04:00
2014-11-06 03:20:01 +03:00
u3a_lose(wim); u3a_lose(fol);
2014-09-05 23:55:16 +04:00
return pro;
}
c3_assert(!"not reached");
case 6: {
2014-09-06 00:13:24 +04:00
u3_noun b_gal, c_gal, d_gal;
2014-09-05 23:55:16 +04:00
2014-11-06 03:20:01 +03:00
u3x_trel(gal, &b_gal, &c_gal, &d_gal);
2014-09-05 23:55:16 +04:00
{
2014-12-03 00:53:35 +03:00
u3_noun tys = _n_nock_on(u3k(bus), u3k(b_gal));
2014-09-06 00:13:24 +04:00
u3_noun nex;
2014-09-05 23:55:16 +04:00
if ( 0 == tys ) {
2014-09-06 00:13:24 +04:00
nex = u3k(c_gal);
2014-09-05 23:55:16 +04:00
} else if ( 1 == tys ) {
2014-09-06 00:13:24 +04:00
nex = u3k(d_gal);
2014-11-06 03:20:01 +03:00
} else return u3m_bail(c3__exit);
2014-09-05 23:55:16 +04:00
2014-11-06 03:20:01 +03:00
u3a_lose(fol);
2014-09-05 23:55:16 +04:00
fol = nex;
continue;
}
}
c3_assert(!"not reached");
case 7: {
2014-09-06 00:13:24 +04:00
u3_noun b_gal, c_gal;
2014-09-05 23:55:16 +04:00
2014-11-06 03:20:01 +03:00
u3x_cell(gal, &b_gal, &c_gal);
2014-09-05 23:55:16 +04:00
{
2014-12-03 00:53:35 +03:00
u3_noun bod = _n_nock_on(bus, u3k(b_gal));
2014-09-06 00:13:24 +04:00
u3_noun nex = u3k(c_gal);
2014-09-05 23:55:16 +04:00
2014-11-06 03:20:01 +03:00
u3a_lose(fol);
2014-09-05 23:55:16 +04:00
bus = bod;
fol = nex;
continue;
}
}
c3_assert(!"not reached");
case 8: {
2014-09-06 00:13:24 +04:00
u3_noun b_gal, c_gal;
2014-09-05 23:55:16 +04:00
2014-11-06 03:20:01 +03:00
u3x_cell(gal, &b_gal, &c_gal);
2014-09-05 23:55:16 +04:00
{
2014-12-03 00:53:35 +03:00
u3_noun heb = _n_nock_on(u3k(bus), u3k(b_gal));
2014-09-06 00:13:24 +04:00
u3_noun bod = u3nc(heb, bus);
u3_noun nex = u3k(c_gal);
2014-09-05 23:55:16 +04:00
2014-11-06 03:20:01 +03:00
u3a_lose(fol);
2014-09-05 23:55:16 +04:00
bus = bod;
fol = nex;
continue;
}
}
c3_assert(!"not reached");
case 9: {
2014-09-06 00:13:24 +04:00
u3_noun b_gal, c_gal;
2014-09-05 23:55:16 +04:00
2014-11-06 03:20:01 +03:00
u3x_cell(gal, &b_gal, &c_gal);
2014-09-05 23:55:16 +04:00
{
2014-12-03 00:53:35 +03:00
u3_noun seb = _n_nock_on(bus, u3k(c_gal));
2014-12-03 03:26:30 +03:00
u3_noun pro;
u3t_off(noc_o);
pro = u3j_kick(seb, b_gal);
u3t_on(noc_o);
2014-09-05 23:55:16 +04:00
2014-11-06 02:36:30 +03:00
if ( u3_none != pro ) {
2014-11-06 03:20:01 +03:00
u3a_lose(fol);
2014-09-05 23:55:16 +04:00
return pro;
}
else {
2014-11-06 03:20:01 +03:00
if ( c3n == u3r_ud(b_gal) ) {
return u3m_bail(c3__exit);
2014-09-05 23:55:16 +04:00
}
else {
2014-09-06 00:13:24 +04:00
u3_noun nex = u3k(u3at(b_gal, seb));
2014-09-05 23:55:16 +04:00
2014-11-06 03:20:01 +03:00
u3a_lose(fol);
2014-09-05 23:55:16 +04:00
bus = seb;
fol = nex;
continue;
}
}
}
}
c3_assert(!"not reached");
case 10: {
2014-09-06 00:13:24 +04:00
u3_noun p_gal, q_gal;
2014-09-05 23:55:16 +04:00
2014-11-06 03:20:01 +03:00
u3x_cell(gal, &p_gal, &q_gal);
2014-09-05 23:55:16 +04:00
{
2014-09-06 00:13:24 +04:00
u3_noun zep, hod, nex;
2014-09-05 23:55:16 +04:00
2014-11-06 03:20:01 +03:00
if ( c3y == u3r_du(p_gal) ) {
2014-09-06 00:13:24 +04:00
u3_noun b_gal = u3h(p_gal);
u3_noun c_gal = u3t(p_gal);
u3_noun d_gal = q_gal;
2014-09-05 23:55:16 +04:00
2014-09-06 00:13:24 +04:00
zep = u3k(b_gal);
2014-12-03 00:53:35 +03:00
hod = _n_nock_on(u3k(bus), u3k(c_gal));
2014-09-06 00:13:24 +04:00
nex = u3k(d_gal);
2014-09-05 23:55:16 +04:00
}
else {
2014-09-06 00:13:24 +04:00
u3_noun b_gal = p_gal;
u3_noun c_gal = q_gal;
2014-09-05 23:55:16 +04:00
2014-09-06 00:13:24 +04:00
zep = u3k(b_gal);
hod = u3_nul;
nex = u3k(c_gal);
2014-09-05 23:55:16 +04:00
}
2014-11-06 03:20:01 +03:00
u3a_lose(fol);
2014-12-03 00:53:35 +03:00
return _n_hint(zep, hod, bus, nex);
2014-09-05 23:55:16 +04:00
}
}
case 11: {
2016-01-26 22:03:05 +03:00
u3_noun ref = _n_nock_on(u3k(bus), u3k(u3h(gal)));
u3_noun gof = _n_nock_on(bus, u3k(u3t(gal)));
2014-12-03 03:26:30 +03:00
u3_noun val;
u3t_off(noc_o);
2016-02-02 22:52:10 +03:00
val = u3m_soft_esc(ref, u3k(gof));
2014-12-03 03:26:30 +03:00
u3t_on(noc_o);
2014-10-31 00:40:05 +03:00
2014-11-05 04:18:47 +03:00
if ( !_(u3du(val)) ) {
2014-11-06 03:20:01 +03:00
u3m_bail(u3nt(1, gof, 0));
2014-10-01 10:34:30 +04:00
}
2016-02-04 00:33:43 +03:00
if ( !_(u3du(u3t(val))) ) {
//
// replace with proper error stack push
//
u3t_push(u3nc(c3__hunk, _n_mush(gof)));
2016-02-04 00:33:43 +03:00
return u3m_bail(c3__exit);
2014-10-01 10:34:30 +04:00
}
else {
u3_noun pro;
u3z(gof);
u3z(fol);
2016-02-04 00:33:43 +03:00
pro = u3k(u3t(u3t(val)));
u3z(val);
return pro;
}
}
2014-09-05 23:55:16 +04:00
c3_assert(!"not reached");
}
}
}
2014-12-03 00:53:35 +03:00
/* u3n_nock_on(): produce .*(bus fol). Do not virtualize.
*/
u3_noun
u3n_nock_on(u3_noun bus, u3_noun fol)
{
u3_noun pro;
u3t_on(noc_o);
pro = _n_nock_on(bus, fol);
u3t_off(noc_o);
return pro;
}
2014-11-06 03:20:01 +03:00
/* u3n_kick_on(): fire `gat` without changing the sample.
2014-09-05 23:55:16 +04:00
*/
2014-09-06 00:13:24 +04:00
u3_noun
2014-11-06 03:20:01 +03:00
u3n_kick_on(u3_noun gat)
2014-09-05 23:55:16 +04:00
{
2014-11-06 03:20:01 +03:00
return u3j_kink(gat, 2);
2014-09-05 23:55:16 +04:00
}
2014-11-02 01:13:18 +03:00
c3_w exc_w;
2014-11-06 03:20:01 +03:00
/* u3n_slam_on(): produce (gat sam).
2014-09-05 23:55:16 +04:00
*/
2014-09-06 00:13:24 +04:00
u3_noun
2014-11-06 03:20:01 +03:00
u3n_slam_on(u3_noun gat, u3_noun sam)
2014-09-05 23:55:16 +04:00
{
2014-09-06 00:13:24 +04:00
u3_noun cor = u3nc(u3k(u3h(gat)), u3nc(sam, u3k(u3t(u3t(gat)))));
2014-09-05 23:55:16 +04:00
2014-11-02 01:13:18 +03:00
#if 0
if ( &u3H->rod_u == u3R ) {
if ( exc_w == 1 ) {
c3_assert(0);
}
exc_w++;
}
#endif
2014-09-06 00:13:24 +04:00
u3z(gat);
2014-11-06 03:20:01 +03:00
return u3n_kick_on(cor);
2014-09-05 23:55:16 +04:00
}
2016-02-04 00:33:43 +03:00
/* u3n_nock_et(): produce .*(bus fol), as ++toon, in namespace.
*/
u3_noun
u3n_nock_et(u3_noun gul, u3_noun bus, u3_noun fol)
{
return u3m_soft_run(gul, u3n_nock_on, bus, fol);
2016-02-04 00:33:43 +03:00
}
/* u3n_slam_et(): produce (gat sam), as ++toon, in namespace.
*/
u3_noun
u3n_slam_et(u3_noun gul, u3_noun gat, u3_noun sam)
{
return u3m_soft_run(gul, u3n_slam_on, gat, sam);
2014-09-05 23:55:16 +04:00
}
2014-11-06 03:20:01 +03:00
/* u3n_nock_an(): as slam_in(), but with empty fly.
2014-09-05 23:55:16 +04:00
*/
2014-09-06 00:13:24 +04:00
u3_noun
2014-11-06 03:20:01 +03:00
u3n_nock_an(u3_noun bus, u3_noun fol)
2014-09-05 23:55:16 +04:00
{
u3_noun gul = u3nt(u3nt(1, 0, 0), 0, 0); // |=(a/{* *} ~)
2014-10-01 10:34:30 +04:00
return u3n_nock_et(gul, bus, fol);
2014-09-05 23:55:16 +04:00
}