1 // LISP-like two element cells
5 var <>linkDown, <>linkAcross;
7 *new { arg linkDown, linkAcross;
8 ^super.newCopyArgs(linkDown, linkAcross)
11 // create from nested array
12 *newFrom { arg collection;
13 var linkDown = collection.at(0);
14 var linkAcross = collection.at(1);
15 if(linkDown.isKindOf(Collection)) { linkDown = this.newFrom(linkDown) };
16 if(linkAcross.isKindOf(Collection)) { linkAcross = this.newFrom(linkAcross) };
17 ^this.new(linkDown, linkAcross)
21 size { var i = 0, link;
23 while ({ link.respondsTo('linkAcross') },{
25 link = link.linkAcross;
29 depth { var i = 0, link;
31 while ({ link.respondsTo('linkDown') },{
40 while ({ link.respondsTo('linkAcross') },{
42 res = function.value(link, i);
43 link = link.linkAcross;
48 traverse { arg function;
49 // the default traversal order
50 ^this.depthFirstPreOrderTraversal(function)
52 depthFirstPreOrderTraversal { arg function;
55 if ( linkDown.respondsTo('depthFirstPreOrderTraversal'), {
56 linkDown.depthFirstPreOrderTraversal(function);
58 // iterate linkAcross to conserve stack depth
60 while ({ link.notNil },{
62 if (link.respondsTo(\linkDown) and:
63 { link.linkDown.respondsTo('depthFirstPreOrderTraversal') }, {
64 link.linkDown.depthFirstPreOrderTraversal(function);
66 if(link.respondsTo('linkAcross')) {
67 link = link.linkAcross;
71 depthFirstPostOrderTraversal { arg function;
73 if ( linkDown.respondsTo('depthFirstPostOrderTraversal'), {
74 linkDown.depthFirstPostOrderTraversal(function);
77 // iterate linkAcross to conserve stack depth
79 while ({ link.notNil },{
80 if (link.respondsTo(\linkDown) and:
81 { link.linkDown.respondsTo('depthFirstPostOrderTraversal') }, {
82 link.linkDown.depthFirstPostOrderTraversal(function);
85 if(link.respondsTo('linkAcross')) {
86 link = link.linkAcross;
91 storeArgs { arg stream;
92 ^[linkDown, linkAcross]
96 stream << this.class.name << "(" <<* this.storeArgs << ")"
99 stream << this.class.name << "(" <<<* this.storeArgs << ")"