/* mark - mark all accessible nodes */ LOCAL mark(ptr) LVAL ptr; { register LVAL this,prev,tmp; int type,i,n; /* initialize */ prev = NIL; this = ptr; /* mark this list */ for (;;) { /* descend as far as we can */ while (!(this->n_flags & MARK)) /* check cons and unnamed stream nodes */ if ((type = ntype(this)) == CONS || type == USTREAM) { if (tmp = car(this)) { this->n_flags |= MARK|LEFT; rplaca(this,prev); } else if (tmp = cdr(this)) { this->n_flags |= MARK; rplacd(this,prev); } else { /* both sides nil */ this->n_flags |= MARK; break; } prev = this; /* step down the branch */ this = tmp; } /* mark other node types */ else { this->n_flags |= MARK; switch (type) { case SYMBOL: case OBJECT: case VECTOR: case CLOSURE: case STRUCT: for (i = 0, n = getsize(this); --n >= 0; ++i) if (tmp = getelement(this,i)) mark(tmp); break; } break; } /* backup to a point where we can continue descending */ for (;;) /* make sure there is a previous node */ if (prev) { if (prev->n_flags & LEFT) { /* came from left side */ prev->n_flags &= ~LEFT; tmp = car(prev); rplaca(prev,this); if (this = cdr(prev)) { rplacd(prev,tmp); break; } } else { /* came from right side */ tmp = cdr(prev); rplacd(prev,this); } /* step back up the branch */ this = prev; prev = tmp; } /* no previous node, must be done */ else return; } }