mirror of
https://github.com/urbit/shrub.git
synced 2024-12-30 07:35:19 +03:00
u3: refactors "retreat" block of u3a_take in to do/while loop
This commit is contained in:
parent
c591eb220d
commit
fae8980660
@ -1094,25 +1094,11 @@ _ca_take_cell(u3a_cell* old_u, u3_noun hed, u3_noun tel)
|
||||
return new;
|
||||
}
|
||||
|
||||
#define TAKE_ROOT 0
|
||||
#define TAKE_HEAD 1
|
||||
#define TAKE_TAIL 2
|
||||
|
||||
// stack frame for recording head vs tail iteration
|
||||
//
|
||||
// In Hoon, this structure would be as follows:
|
||||
//
|
||||
// $% [%root ~]
|
||||
// [%head old=^]
|
||||
// [%tail old=^ hed=*]
|
||||
// ==
|
||||
//
|
||||
typedef struct takeframe
|
||||
typedef struct _ca_take
|
||||
{
|
||||
c3_y tag_y;
|
||||
u3_cell old;
|
||||
u3_weak hed;
|
||||
} takeframe;
|
||||
u3_weak hed; // taken head
|
||||
u3_cell old; // old cell
|
||||
} _ca_take;
|
||||
|
||||
static inline u3_noun
|
||||
_ca_take_next(u3a_pile* pil_u, u3_noun veb)
|
||||
@ -1176,12 +1162,11 @@ _ca_take_next(u3a_pile* pil_u, u3_noun veb)
|
||||
u3a_cell* old_u = (u3a_cell*)veb_u;
|
||||
|
||||
{
|
||||
takeframe* fam_u = u3a_push(pil_u);
|
||||
_ca_take* fam_u = u3a_push(pil_u);
|
||||
u3a_pile_sane(pil_u);
|
||||
|
||||
fam_u->tag_y = TAKE_HEAD;
|
||||
fam_u->old = veb;
|
||||
fam_u->hed = u3_none;
|
||||
fam_u->hed = u3_none;
|
||||
fam_u->old = veb;
|
||||
}
|
||||
|
||||
veb = old_u->hed;
|
||||
@ -1196,78 +1181,45 @@ _ca_take_next(u3a_pile* pil_u, u3_noun veb)
|
||||
u3_noun
|
||||
u3a_take(u3_noun veb)
|
||||
{
|
||||
u3a_pile pil_u;
|
||||
u3_noun pro;
|
||||
c3_o nor_o = u3a_is_north(u3R);
|
||||
u3a_pile pil_u;
|
||||
_ca_take* fam_u;
|
||||
u3_noun pro;
|
||||
c3_o nor_o = u3a_is_north(u3R);
|
||||
|
||||
u3t_on(coy_o);
|
||||
|
||||
c3_assert(u3_none != veb);
|
||||
|
||||
u3a_pile_prep(&pil_u, sizeof(takeframe));
|
||||
u3a_pile_prep(&pil_u, sizeof(*fam_u));
|
||||
|
||||
// push the ROOT stack frame (our termination condition)
|
||||
//
|
||||
{
|
||||
takeframe* fam_u = u3a_push(&pil_u);
|
||||
fam_u->tag_y = TAKE_ROOT;
|
||||
}
|
||||
|
||||
// read from the current noun .veb
|
||||
// commence taking
|
||||
//
|
||||
pro = _ca_take_next(&pil_u, veb);
|
||||
|
||||
// consume: popped stack frame, and .pro from above
|
||||
// process cell results
|
||||
//
|
||||
retreat: {
|
||||
takeframe* fam_u = u3a_peek(&pil_u);
|
||||
if ( c3n == u3a_pile_done(&pil_u) ) {
|
||||
fam_u = u3a_peek(&pil_u);
|
||||
|
||||
switch ( fam_u->tag_y ) {
|
||||
default: {
|
||||
c3_assert(0);
|
||||
}
|
||||
|
||||
// .fam_u is our stack root, we're done.
|
||||
do {
|
||||
// fam_u is a head-frame: stash copy and continue into the tail
|
||||
//
|
||||
case TAKE_ROOT: {
|
||||
u3a_pop(&pil_u);
|
||||
break;
|
||||
}
|
||||
|
||||
// .pro is the copied head of a cell; save a pointer to it in .new_u
|
||||
// and advance to copy the tail
|
||||
//
|
||||
case TAKE_HEAD: {
|
||||
if ( u3_none == fam_u->hed ) {
|
||||
u3a_cell* old_u = u3a_to_ptr(fam_u->old);
|
||||
c3_assert( u3_none == fam_u->hed );
|
||||
|
||||
fam_u->tag_y = TAKE_TAIL;
|
||||
fam_u->hed = pro;
|
||||
|
||||
// veb = old_u->tel;
|
||||
// goto advance;
|
||||
pro = _ca_take_next(&pil_u, old_u->tel);
|
||||
goto retreat;
|
||||
fam_u->hed = pro;
|
||||
pro = _ca_take_next(&pil_u, old_u->tel);
|
||||
fam_u = u3a_peek(&pil_u);
|
||||
}
|
||||
|
||||
// .pro is the copied tail of a cell; save a pointer to it in .new_u,
|
||||
// and produce the whole copied cell (as if it were a read from above).
|
||||
// fam_u is a tail-frame: copy cell and pop the stack
|
||||
//
|
||||
case TAKE_TAIL: {
|
||||
else {
|
||||
u3a_cell* old_u = u3a_to_ptr(fam_u->old);
|
||||
c3_assert( u3_none != fam_u->hed );
|
||||
|
||||
pro = _ca_take_cell(old_u, fam_u->hed, pro);
|
||||
u3a_pop(&pil_u);
|
||||
goto retreat;
|
||||
pro = _ca_take_cell(old_u, fam_u->hed, pro);
|
||||
fam_u = u3a_pop(&pil_u);
|
||||
}
|
||||
}
|
||||
} while ( c3n == u3a_pile_done(&pil_u) );
|
||||
}
|
||||
|
||||
// sanity check
|
||||
//
|
||||
c3_assert( c3y == u3a_pile_done(&pil_u) );
|
||||
|
||||
u3t_off(coy_o);
|
||||
|
||||
return pro;
|
||||
|
Loading…
Reference in New Issue
Block a user