§199  TEX82  PART 13: DESTROYING BOXES 69

199. Destroying boxes. When we are done with a node list, we are obliged to return it to free storage, including all of its sublists. The recursive procedure flush node list does this for us.

200. First, however, we shall consider two non-recursive procedures that do simpler tasks. The first of these, delete token ref , is called when a pointer to a token list’s reference count is being removed. This means that the token list should disappear if the reference count was null , otherwise the count should be decreased by one.

define token ref count (#) ≡ info(#) { reference count preceding a token list } procedure delete token ref (p : pointer );

{ p points to the reference count of a token list that is losing one reference } begin if token ref count (p) = null then flush list (p) else decr (token ref count (p)); end;

201. Similarly, delete glue ref is called when a pointer to a glue specification is being withdrawn.

define fast delete glue ref (#) ≡ begin if glue ref count (#) = null then free node(#, glue spec size) else decr (glue ref count (#)); end

procedure delete glue ref (p : pointer ); { p points to a glue specification } fast delete glue ref (p);

70  PART 13: DESTROYING BOXES  TEX82 §202

202. Now we are ready to delete any node list, recursively. In practice, the nodes deleted are usually charnodes (about 2/3 of the time), and they are glue nodes in about half of the remaining cases. procedure flush node list (p : pointer ); { erase list of nodes starting at p }

label done; { go here when node p has been freed } var q: pointer ; { successor to node p } begin while p ≠ null do

begin q ← link (p); if is char node(p) then free avail (p) else begin case type(p) of

hlist node, vlist node, unset node: begin flush node list (list ptr (p)); free node(p, box node size); goto done; end;

rule node: begin free node(p, rule node size); goto done;

end; ins node: begin flush node list (ins ptr (p)); delete glue ref (split top ptr (p));

free node(p, ins node size); goto done;

end; whatsit node: ⟨ Wipe out the whatsit node p and goto done 1358 ⟩; glue node: begin fast delete glue ref (glue ptr (p));

if leader ptr (p) ≠ null then flush node list (leader ptr (p)); end;

kern node, math node, penalty node: do nothing ; ligature node: flush node list (lig ptr (p)); mark node: delete token ref (mark ptr (p)); disc node: begin flush node list (pre break (p)); flush node list (post break (p));

end; adjust node: flush node list (adjust ptr (p)); ⟨ Cases of flush node list that arise in mlists only 698 ⟩ othercases confusion( ) endcases; free node(p, small node size);

done: end; p ← q; end;

end;