Merge pull request #1035 from urbit/nock-4k

nock 4K
This commit is contained in:
Joe Bryan 2018-10-12 16:17:57 -04:00 committed by GitHub
commit 15f72cd435
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
9 changed files with 338 additions and 30 deletions

View File

@ -1,5 +1,7 @@
A noun is an atom or a cell. An atom is a natural number. A cell is an ordered pair of nouns.
Reduce by the first matching pattern; variables match any noun.
nock(a) *a
[a b c] [a [b c]]
@ -9,7 +11,6 @@ nock(a) *a
+a 1 + a
=[a a] 0
=[a b] 1
=a =a
/[1 a] a
/[2 a b] a
@ -30,15 +31,15 @@ nock(a) *a
*[a 2 b c] *[*[a b] *[a c]]
*[a 3 b] ?*[a b]
*[a 4 b] +*[a b]
*[a 5 b] =*[a b]
*[a 5 b c] =[*[a b] *[a c]]
*[a 6 b c d] *[a 2 [0 1] 2 [1 c d] [1 0] 2 [1 2 3] [1 0] 4 4 b]
*[a 7 b c] *[a 2 b 1 c]
*[a 8 b c] *[a 7 [[7 [0 1] b] 0 1] c]
*[a 9 b c] *[a 7 c 2 [0 1] 0 b]
*[a 10 [b c] d] *[a 8 c 7 [0 3] d]
*[a 10 b c] *[a c]
*[a 12 [b c] d] #[b *[a c] *[a d]]
*[a 6 b c d] *[a *[[c d] 0 *[[2 3] 0 *[a 4 4 b]]]]
*[a 7 b c] *[*[a b] c]
*[a 8 b c] *[[*[a b] a] c]
*[a 9 b c] *[*[a c] 2 [0 1] 0 b]
*[a 10 [b c] d] #[b *[a c] *[a d]]
*[a 11 [b c] d] *[[*[a c] *[a d]] 0 3]
*[a 11 b c] *[a c]
*a *a

View File

@ -250,6 +250,15 @@
? u3a_north_is_senior(r, som) \
: u3a_south_is_senior(r, som) )
# define u3a_is_mutable(r, som) \
( _(u3a_is_atom(som)) \
? c3n \
: _(u3a_is_senior(r, som)) \
? c3n \
: _(u3a_is_junior(r, som)) \
? c3n \
: (u3a_botox(u3a_to_ptr(som))->use_w == 1) \
? c3y : c3n )
/** Globals.
**/

View File

@ -55,6 +55,14 @@
u3_noun
u3i_qual(u3_noun a, u3_noun b, u3_noun c, u3_noun d);
/* u3i_edit():
**
** Mutate `big` at axis `axe` with new value `som`
** `axe` is RETAINED.
*/
u3_noun
u3i_edit(u3_noun big, u3_noun axe, u3_noun som);
/* u3i_string():
**
** Produce an LSB-first atom from the C string `a`.

View File

@ -89,6 +89,7 @@
u3qf_hike(u3_noun axe,
u3_noun pac)
{
c3_assert(0);
if ( (u3_nul == pac) ) {
return u3nc(0, u3k(axe));
}

View File

@ -148,16 +148,16 @@
}
static u3_noun
_mint_coke(u3_noun nug)
_mint_cove(u3_noun nug)
{
if ( 0 == u3h(nug) ) {
return u3k(u3t(nug));
}
else if ( 10 == u3h(nug) ) {
return _mint_coke(u3t(u3t(nug)));
else if ( 11 == u3h(nug) ) {
return _mint_cove(u3t(u3t(nug)));
}
else {
return u3m_error("mint-coke");
return u3m_error("mint-cove");
}
}
@ -370,7 +370,7 @@
u3_noun wam = u3qfu_play(van, sut, p_gen);
u3_noun dok = u3nc(c3__wing, u3k(q_gen));
u3_noun vol = _mint_corn(van, sut, dok);
u3_noun axe = _mint_coke(vol);
u3_noun axe = _mint_cove(vol);
ret = u3nc(_mint_nice(van, gol, _mint_bean()),
u3qfu_fish(van, wam, axe));
@ -471,7 +471,7 @@
u3_noun viz = _mint_in(van, sut, c3__noun, q_gen);
ret = u3nc(u3k(u3h(nef)),
u3nt(11, u3nc(1, u3nc(151, u3k(u3h(nef)))), u3k(u3t(viz))));
u3nt(12, u3nc(1, u3nc(151, u3k(u3h(nef)))), u3k(u3t(viz))));
u3z(viz);
u3z(nef);
@ -683,7 +683,7 @@
_mint_corn(van, sut, u3t(p_gen)));
}
ret = u3nc(u3k(u3h(hum)),
u3nt(10, bez, u3k(u3t(hum))));
u3nt(11, bez, u3k(u3t(hum))));
u3z(hum);
return ret;
@ -786,7 +786,7 @@
u3_noun hum = _mint_in(van, sut, gol, q_gen);
u3_noun bez = u3nt(c3__spot, 1, u3k(p_gen));
ret = u3nc(u3k(u3h(hum)), u3nt(10, bez, u3k(u3t(hum))));
ret = u3nc(u3k(u3h(hum)), u3nt(11, bez, u3k(u3t(hum))));
u3z(hum);
}
u3t_drop();

View File

@ -63,16 +63,16 @@
}
}
static u3_noun
_mull_coke(u3_noun nug)
_mull_cove(u3_noun nug)
{
if ( 0 == u3h(nug) ) {
return u3k(u3t(nug));
}
else if ( 10 == u3h(nug) ) {
return _mull_coke(u3t(u3t(nug)));
else if ( 11 == u3h(nug) ) {
return _mull_cove(u3t(u3t(nug)));
}
else {
return u3m_error("mull-coke");
return u3m_error("mull-cove");
}
}
@ -109,7 +109,7 @@
u3_noun gen)
{
u3_noun fug = u3qfu_mint(van, sut, c3__noun, gen);
u3_noun axe = _mull_coke(u3t(fug));
u3_noun axe = _mull_cove(u3t(fug));
u3z(fug);
return axe;

View File

@ -262,6 +262,150 @@ u3i_qual(u3_noun a, u3_noun b, u3_noun c, u3_noun d)
return u3i_cell(a, u3i_trel(b, c, d));
}
static u3_noun
_edit_cat(u3_noun big, c3_l axe_l, u3_noun som)
{
if ( c3n == u3du(big) ) {
return u3m_bail(c3__exit);
}
else {
u3_noun pro;
switch ( axe_l ) {
case 2:
pro = u3nc(som, u3k(u3t(big)));
break;
case 3:
pro = u3nc(u3k(u3h(big)), som);
break;
default: {
c3_l mor_l = u3x_mas(axe_l);
pro = ( 2 == u3x_cap(axe_l) )
? u3nc(_edit_cat(u3k(u3h(big)), mor_l, som), u3k(u3t(big)))
: u3nc(u3k(u3h(big)), _edit_cat(u3k(u3t(big)), mor_l, som));
break;
}
}
u3z(big);
return pro;
}
}
static u3_noun
_edit(u3_noun big, u3_noun axe, u3_noun som)
{
if ( c3y == u3a_is_cat(axe) ) {
return _edit_cat(big, (c3_l) axe, som);
}
else if ( c3n == u3du(big) ) {
return u3m_bail(c3__exit);
}
else {
u3_noun mor = u3qc_mas(axe),
pro = ( 2 == u3qc_cap(axe) )
? u3nc(_edit(u3k(u3h(big)), mor, som), u3k(u3t(big)))
: u3nc(u3k(u3h(big)), _edit(u3k(u3t(big)), mor, som));
u3z(mor);
u3z(big);
return pro;
}
}
static u3_noun _edit_or_mutate_cat(u3_noun, c3_l, u3_noun);
static u3_noun _edit_or_mutate(u3_noun, u3_noun, u3_noun);
static void
_mutate_cat(u3_noun big, c3_l axe_l, u3_noun som)
{
if ( c3n == u3du(big) ) {
u3m_bail(c3__exit);
}
else {
u3a_cell* cel_u = (void*) u3a_to_ptr(big);
switch ( axe_l ) {
case 2:
u3z(cel_u->hed);
cel_u->hed = som;
break;
case 3:
u3z(cel_u->tel);
cel_u->tel = som;
break;
default: {
u3_noun* tar = ( 2 == u3x_cap(axe_l) )
? &(cel_u->hed)
: &(cel_u->tel);
*tar = _edit_or_mutate_cat(*tar, u3x_mas(axe_l), som);
}
}
}
}
static void
_mutate(u3_noun big, u3_noun axe, u3_noun som)
{
if ( c3y == u3a_is_cat(axe) ) {
_mutate_cat(big, (c3_l) axe, som);
}
else if ( c3n == u3du(big) ) {
u3m_bail(c3__exit);
}
else {
u3a_cell* cel_u = (void*) u3a_to_ptr(big);
u3_noun mor = u3qc_mas(axe);
u3_noun* tar = ( 2 == u3qc_cap(axe) )
? &(cel_u->hed)
: &(cel_u->tel);
*tar = _edit_or_mutate(*tar, mor, som);
u3z(mor);
}
}
static u3_noun
_edit_or_mutate_cat(u3_noun big, c3_l axe_l, u3_noun som)
{
if ( c3y == u3a_is_mutable(u3R, big) ) {
_mutate_cat(big, axe_l, som);
return big;
}
else {
return _edit_cat(big, axe_l, som);
}
}
static u3_noun
_edit_or_mutate(u3_noun big, u3_noun axe, u3_noun som)
{
if ( c3y == u3a_is_cat(axe) ) {
return _edit_or_mutate_cat(big, (c3_l) axe, som);
}
else if ( c3y == u3a_is_mutable(u3R, big) ) {
_mutate(big, axe, som);
return big;
}
else {
return _edit(big, axe, som);
}
}
/* u3i_edit():
**
** Mutate `big` at axis `axe` with new value `som`.
** `axe` is RETAINED.
*/
u3_noun
u3i_edit(u3_noun big, u3_noun axe, u3_noun som)
{
switch ( axe ) {
case 0:
return u3m_bail(c3__exit);
case 1:
u3z(big);
return som;
default:
return _edit_or_mutate(big, axe, som);
}
}
/* u3i_string():
**
** Produce an LSB-first atom from the C string `a`.

View File

@ -249,7 +249,7 @@ _cj_axis(u3_noun fol)
{
u3_noun p_fol, q_fol, r_fol;
while ( _(u3du(fol)) && (10 == u3h(fol)) )
while ( _(u3du(fol)) && (11 == u3h(fol)) )
{ fol = u3t(u3t(fol)); }
if ( !_(u3r_trel(fol, &p_fol, &q_fol, &r_fol)) ) {
@ -436,7 +436,7 @@ _cj_je_fsck(u3_noun clu)
if ( 0 == (nam_c = _cj_chum(p_clu)) ) {
u3z(clu); return u3_none;
}
while ( _(u3du(q_clu)) && (10 == u3h(q_clu)) ) {
while ( _(u3du(q_clu)) && (11 == u3h(q_clu)) ) {
q_clu = u3t(u3t(q_clu));
}
if ( !_(u3du(q_clu)) ) {

View File

@ -526,6 +526,22 @@ _n_nock_on(u3_noun bus, u3_noun fol)
#define SLIB 70
#define SLIS 71
#define SAVE 72
// nock 10
#define MUTH 73
#define KUTH 74
#define MUTT 75
#define KUTT 76
#define MUSM 77
#define KUSM 78
#define MUTB 79
#define MUTS 80
#define MITB 81
#define MITS 82
#define KUTB 83
#define KUTS 84
#define KITB 85
#define KITS 86
#define LAST 87
/* _n_arg(): return the size (in bytes) of an opcode's argument
*/
@ -538,6 +554,7 @@ _n_arg(c3_y cod_y)
case SAMB: case SANB: case SBIP: case SBIN:
case SLIB: case SKIB: case KICB: case TICB:
case BUSH: case BAST: case BALT:
case MUTB: case KUTB: case MITB: case KITB:
return sizeof(c3_y);
case FASK: case FASL: case FISL: case FISK:
@ -545,13 +562,14 @@ _n_arg(c3_y cod_y)
case SAMS: case SANS: case SIPS: case SINS:
case SLIS: case SKIS: case KICS: case TICS:
case SUSH: case SAST: case SALT:
case MUTS: case KUTS: case MITS: case KITS:
return sizeof(c3_s);
case SWIP: case SWIN:
return sizeof(c3_l);
default:
c3_assert( cod_y <= SAVE );
c3_assert( cod_y < LAST );
return 0;
}
}
@ -657,6 +675,7 @@ _n_melt(u3_noun ops, c3_w* byc_w, c3_w* cal_w,
case BUSH: case FIBK: case FIBL:
case SANB: case LIBL: case LIBK:
case KITB: case MITB:
a_w = (*lit_w)++;
if ( a_w <= 0xFF ) {
siz_y[i_w] = 2;
@ -854,6 +873,7 @@ _n_prog_asm(u3_noun ops, u3n_prog* pog_u, u3_noun sip)
/* 8-bit direct args */
case FABK: case FABL:
case LITB: case LILB:
case MUTB: case KUTB:
case SAMB:
buf_y[i_w--] = (c3_y) u3t(op);
buf_y[i_w] = (c3_y) cod;
@ -862,6 +882,7 @@ _n_prog_asm(u3_noun ops, u3n_prog* pog_u, u3_noun sip)
/* 16-bit direct args */
case FASK: case FASL:
case LILS: case LITS:
case MUTS: case KUTS:
case SAMS: case SIPS: case SINS: {
c3_s off_s = u3t(op);
buf_y[i_w--] = (c3_y) (off_s >> 8);
@ -885,6 +906,7 @@ _n_prog_asm(u3_noun ops, u3n_prog* pog_u, u3_noun sip)
case FIBK: case FIBL:
case LIBK: case LIBL:
case BUSH: case SANB:
case KITB: case MITB:
_n_prog_asm_inx(buf_y, &i_w, lit_s, cod);
pog_u->lit_u.non[lit_s++] = u3k(u3t(op));
break;
@ -992,6 +1014,10 @@ static char* opcode_names[] = {
"balt", "salt",
"skib", "skis", "slib", "slis",
"save",
"muth", "kuth", "mutt", "kutt",
"musm", "kusm",
"mutb", "muts", "mitb", "mits",
"kutb", "kuts", "kitb", "kits",
};
#endif
@ -1185,8 +1211,8 @@ _n_comp(u3_noun* ops, u3_noun fol, c3_o los_o, c3_o tel_o)
u3x_cell(arg, &hed, &tel);
if ( c3n == u3du(hed) ) {
tot_w += _n_comp(ops, arg, los_o, c3n);
++tot_w; _n_emit(ops, SAMC);
u3m_bail(c3__exit);
return 0;
}
else {
c3_t hec_t, tec_t;
@ -1276,12 +1302,44 @@ _n_comp(u3_noun* ops, u3_noun fol, c3_o los_o, c3_o tel_o)
}
break;
case 10:
case 10: {
u3_noun axe, nef;
u3x_cell(arg, &hed, &tel);
u3x_cell(hed, &axe, &nef);
tot_w += _n_comp(ops, tel, c3n, c3n);
++tot_w; _n_emit(ops, SWAP);
tot_w += _n_comp(ops, nef, c3n, c3n);
++tot_w;
switch ( axe ) {
case 2:
_n_emit(ops, (c3y == los_o) ? MUTH : KUTH);
break;
case 3:
_n_emit(ops, (c3y == los_o) ? MUTT : KUTT);
break;
case u3x_sam:
_n_emit(ops, (c3y == los_o) ? MUSM : KUSM);
break;
default:
op_y = (c3y == los_o)
? (axe <= 0xFF) ? MUTB : (axe <= 0xFFFF) ? MUTS : MITB // overflows to MITS
: (axe <= 0xFF) ? KUTB : (axe <= 0xFFFF) ? KUTS : KITB; // overflows to KITS
_n_emit(ops, u3nc(op_y, u3k(axe)));
break;
}
break;
}
case 11:
u3x_cell(arg, &hed, &tel);
tot_w += _n_bint(ops, hed, tel, los_o, tel_o);
break;
case 11:
case 12:
u3x_cell(arg, &hed, &tel);
tot_w += _n_comp(ops, hed, c3n, c3n);
++tot_w; _n_emit(ops, SWAP);
@ -1573,6 +1631,10 @@ _n_burn(u3n_prog* pog_u, u3_noun bus, c3_ys mov, c3_ys off)
&&do_balt, &&do_salt,
&&do_skib, &&do_skis, &&do_slib, &&do_slis,
&&do_save,
&&do_muth, &&do_kuth, &&do_mutt, &&do_kutt,
&&do_musm, &&do_kusm,
&&do_mutb, &&do_muts, &&do_mitb, &&do_mits,
&&do_kutb, &&do_kuts, &&do_kitb, &&do_kits,
};
u3j_site* sit_u;
@ -2158,6 +2220,89 @@ _n_burn(u3n_prog* pog_u, u3_noun bus, c3_ys mov, c3_ys off)
*top = x;
u3z(o);
BURN();
do_kuth:
x = _n_pep(mov, off);
top = _n_swap(mov, off);
goto muth_in;
do_muth:
x = _n_pep(mov, off);
_n_toss(mov, off);
top = _n_peek(off);
muth_in:
o = *top;
*top = u3nc(x, u3k(u3t(o)));
u3z(o);
BURN();
do_kutt:
x = _n_pep(mov, off);
top = _n_swap(mov, off);
goto mutt_in;
do_mutt:
x = _n_pep(mov, off);
_n_toss(mov, off);
top = _n_peek(off);
mutt_in:
o = *top;
*top = u3nc(u3k(u3h(o)), x);
u3z(o);
BURN();
do_kusm:
x = _n_pep(mov, off);
top = _n_swap(mov, off);
goto musm_in;
do_musm:
x = _n_pep(mov, off);
_n_toss(mov, off);
top = _n_peek(off);
musm_in:
o = *top;
*top = u3nt(u3k(u3h(o)), x, u3k(u3t(u3t(o))));
u3z(o);
BURN();
do_kitb:
x = pog_u->lit_u.non[pog[ip_w++]];
goto kut_in;
do_kits:
x = pog_u->lit_u.non[_n_resh(pog, &ip_w)];
goto kut_in;
do_kuts:
x = _n_resh(pog, &ip_w);
goto kut_in;
do_kutb:
x = pog[ip_w++];
kut_in:
o = _n_pep(mov, off);
top = _n_swap(mov, off);
goto edit_in;
do_mitb:
x = pog_u->lit_u.non[pog[ip_w++]];
goto mut_in;
do_mits:
x = pog_u->lit_u.non[_n_resh(pog, &ip_w)];
goto mut_in;
do_muts:
x = _n_resh(pog, &ip_w);
goto mut_in;
do_mutb:
x = pog[ip_w++];
mut_in:
o = _n_pep(mov, off);
_n_toss(mov, off);
top = _n_peek(off);
edit_in:
*top = u3i_edit(*top, x, o);
BURN();
}
}