u3: refactors u3a_walk_fore/unsafe(), using road stack api

This commit is contained in:
Joe Bryan 2020-09-14 15:20:42 -07:00
parent 10a674b0a5
commit 6f39faeb7d

View File

@ -2668,59 +2668,33 @@ u3a_walk_fore(u3_noun a,
void (*pat_f)(u3_atom, void*),
c3_o (*cel_f)(u3_noun, void*))
{
// initialize signed stack offsets (relative to N or S road)
//
c3_o nor_o = u3a_is_north(u3R);
c3_ys mov_ys, off_ys;
{
c3_y wis_y = c3_wiseof(u3_noun);
mov_ys = ( c3y == nor_o ? -wis_y : wis_y );
off_ys = ( c3y == nor_o ? 0 : -wis_y );
}
u3_noun* top;
u3a_pile pil_u;
// set stack root, push argument
// initialize stack control; push argument
//
u3_noun *top, *don;
{
don = u3to(u3_noun, u3R->cap_p + off_ys);
u3R->cap_p += mov_ys;
top = u3to(u3_noun, u3R->cap_p + off_ys);
*top = a;
}
u3a_pile_prep(&pil_u, sizeof(u3_noun));
top = u3a_push(&pil_u);
*top = a;
while ( top != don ) {
while ( c3n == u3a_pile_done(&pil_u) ) {
// visit an atom, then pop the stack
//
if ( c3y == u3a_is_atom(a) ) {
pat_f(a, ptr_v);
u3R->cap_p -= mov_ys;
top = u3to(u3_noun, u3R->cap_p + off_ys);
top = u3a_pop(&pil_u);
}
// vist a cell, if c3n, pop the stack
//
else if ( c3n == cel_f(a, ptr_v) ) {
u3R->cap_p -= mov_ys;
top = u3to(u3_noun, u3R->cap_p + off_ys);
top = u3a_pop(&pil_u);
}
// otherwise, push the tail and continue into the head
//
else {
*top = u3t(a);
u3R->cap_p += mov_ys;
if ( c3y == nor_o ) {
if( !(u3R->cap_p > u3R->hat_p) ) {
u3m_bail(c3__meme);
}
}
else {
if( !(u3R->cap_p < u3R->hat_p) ) {
u3m_bail(c3__meme);
}
}
top = u3to(u3_noun, u3R->cap_p + off_ys);
*top = u3t(a);
top = u3a_push(&pil_u);
u3a_pile_sane(&pil_u);
*top = u3h(a);
}
@ -2736,48 +2710,35 @@ u3a_walk_fore_unsafe(u3_noun a,
void (*pat_f)(u3_atom, void*),
c3_o (*cel_f)(u3_noun, void*))
{
// initialize signed stack offsets (relative to N or S road)
//
c3_ys mov_ys, off_ys;
{
c3_y wis_y = c3_wiseof(u3_noun);
c3_o nor_o = u3a_is_north(u3R);
mov_ys = ( c3y == nor_o ? -wis_y : wis_y );
off_ys = ( c3y == nor_o ? 0 : -wis_y );
}
u3_noun* top;
u3a_pile pil_u;
// set stack root, push argument
// initialize stack control; push argument
//
u3_noun *top, *don;
{
don = u3to(u3_noun, u3R->cap_p + off_ys);
u3R->cap_p += mov_ys;
top = u3to(u3_noun, u3R->cap_p + off_ys);
*top = a;
}
u3a_pile_prep(&pil_u, sizeof(u3_noun));
top = u3a_push(&pil_u);
*top = a;
while ( top != don ) {
while ( c3n == u3a_pile_done(&pil_u) ) {
// visit an atom, then pop the stack
//
if ( c3y == u3a_is_atom(a) ) {
pat_f(a, ptr_v);
u3R->cap_p -= mov_ys;
top = u3to(u3_noun, u3R->cap_p + off_ys);
top = u3a_pop(&pil_u);
}
// vist a cell, if c3n, pop the stack
//
else if ( c3n == cel_f(a, ptr_v) ) {
u3R->cap_p -= mov_ys;
top = u3to(u3_noun, u3R->cap_p + off_ys);
top = u3a_pop(&pil_u);
}
// otherwise, push the tail and continue into the head
//
else {
*top = u3t(a);
u3R->cap_p += mov_ys;
top = u3to(u3_noun, u3R->cap_p + off_ys);
*top = u3h(a);
*top = u3t(a);
// NB: overflow check elided here
//
top = u3a_push(&pil_u);
*top = u3h(a);
}
a = *top;