mirror of
https://github.com/urbit/shrub.git
synced 2024-12-21 18:01:32 +03:00
ur: adds ur_walk_fore - higher-ordered pre-order noun traversal
This commit is contained in:
parent
d0e5c658a9
commit
039ef019b9
@ -163,3 +163,10 @@ ur_nvec_free(ur_nvec_t *v);
|
|||||||
|
|
||||||
void
|
void
|
||||||
ur_nvec_init(ur_nvec_t *v, uint64_t size);
|
ur_nvec_init(ur_nvec_t *v, uint64_t size);
|
||||||
|
|
||||||
|
void
|
||||||
|
ur_walk_fore(ur_root_t *r,
|
||||||
|
ur_nref ref,
|
||||||
|
void *v,
|
||||||
|
void (*atom)(ur_root_t*, ur_nref, void*),
|
||||||
|
ur_bool_t (*cell)(ur_root_t*, ur_nref, void*));
|
||||||
|
@ -821,3 +821,54 @@ ur_nvec_init(ur_nvec_t *v, uint64_t size)
|
|||||||
v->fill = 0;
|
v->fill = 0;
|
||||||
v->refs = calloc(size, sizeof(ur_nref));
|
v->refs = calloc(size, sizeof(ur_nref));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
ur_walk_fore(ur_root_t *r,
|
||||||
|
ur_nref ref,
|
||||||
|
void *v,
|
||||||
|
void (*atom)(ur_root_t*, ur_nref, void*),
|
||||||
|
ur_bool_t (*cell)(ur_root_t*, ur_nref, void*))
|
||||||
|
{
|
||||||
|
uint64_t prev = 89, size = 144, fill = 0;
|
||||||
|
ur_nref *top, *don;
|
||||||
|
|
||||||
|
don = malloc(size * sizeof(*don));
|
||||||
|
top = don + ++fill;
|
||||||
|
*top = ref;
|
||||||
|
|
||||||
|
while ( top != don ) {
|
||||||
|
// visit atom, pop stack
|
||||||
|
//
|
||||||
|
if ( !ur_deep(ref) ) {
|
||||||
|
atom(r, ref, v);
|
||||||
|
top--; fill--;
|
||||||
|
}
|
||||||
|
// visit cell, pop stack if false
|
||||||
|
//
|
||||||
|
else if ( !cell(r, ref, v) ) {
|
||||||
|
top--; fill--;
|
||||||
|
}
|
||||||
|
// push the tail, continue into the head
|
||||||
|
//
|
||||||
|
else {
|
||||||
|
*top = ur_tail(r, ref);
|
||||||
|
|
||||||
|
// reallocate "stack" if full
|
||||||
|
//
|
||||||
|
if ( size == fill ) {
|
||||||
|
uint64_t next = prev + size;
|
||||||
|
don = realloc(don, next * sizeof(*don));
|
||||||
|
top = don + fill;
|
||||||
|
prev = size;
|
||||||
|
size = next;
|
||||||
|
}
|
||||||
|
|
||||||
|
top++; fill++;
|
||||||
|
*top = ur_head(r, ref);
|
||||||
|
}
|
||||||
|
|
||||||
|
ref = *top;
|
||||||
|
}
|
||||||
|
|
||||||
|
free(don);
|
||||||
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user