@*Introduction. This program implements the coroutines of Algorithms 7.2.1.1R and 7.2.1.1D, in the important case \$m=2\$. @d nn 10 /* we will test this value of |n| */ @c #include int p[nn]; /* program locations */ int x[nn],y[nn],t[nn],xp[nn],yp[nn],tp[nn]; /* local variables */ int n[nn]; /* the value of `|n|' in each coroutine */ @; main() { register int k,kp; @; for (k=0;k<(1<= void init(int r) { register q=r-1; n[q]=r; if (r==2) p[q]=S+1; else if (r&1) { p[q]=R; x[q]=0; init(q); }@+else { register int k,qq; qq=q>>1; p[q]=D+1; x[q]=xp[q]=2; init(qq+1); for (k=q-1;k>qq;k--) p[k]=p[k-qq],x[k]=x[k-qq],xp[k]=xp[k-qq],n[k]=n[k-qq]; } } @ @= init(nn); @ Now here's how we invoke a coroutine and obtain its next value. @= int co(int q) { switch (p[q]) { @@; } } @ Each coroutine resets its |p| before returning a value. For example, type S is the simplest. @= case S+1: p[q]=S+2;@+return 0; case S+2: p[q]=S+3;@+return 0; case S+3: p[q]=S+4;@+return 1; case S+4: p[q]=S+1;@+return 1; @ Type R is next in difficulty. I change the numbering slightly here, so that case |R| does the first part of the text's step R1. The text's |n| is |n[q-1]| in this code, because of the initialization we've done. @= R1: case R: p[q]=R+1;@+return x[q]; case R+1:@+ if (x[q]!=0 && t[q]>=n[q-1]) goto R3; R2: y[q]=co(q-1); R3: t[q]=(y[q]==1? t[q]+1: 0); R4:@+ if (t[q]==n[q-1] && x[q]!=0) goto R2; R5: x[q]=(x[q]+y[q])&1;@+goto R1; @ And finally there's the coroutine of type D. Again the text's parameter~|n| is our variable~|n[q-1]|. @= D1: case D+1:@+if (t[q]!=n[q-1] || x[q]>=2) y[q]=co(q-(n[q]>>1)); D2:@+ if (x[q]!=y[q]) x[q]=y[q],t[q]=1;@+else t[q]++; D3: p[q]=D+4;@+return x[q]; D4: case D+4: yp[q]=co(q-1); D5:@+ if (xp[q]!=yp[q]) xp[q]=yp[q],tp[q]=1;@+else tp[q]++; D6:@+if (tp[q]==n[q-1] && xp[q]<2) { if (t[q]