The following transcript gives the actual REC/C operators and predicates, and can be consulted as the final authority on how they actually work.
/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
/* definition of REC operators and predicates */
/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
int rec(z) char *z; {if (rec_c(z,rprg,PLEN,dtbl)==1) rec_x(rprg);}
int rprze() {return(options[0]==TRUE);}
int rpron() {return(options[1]==TRUE);}
int rprtw() {return(options[2]==TRUE);}
int rprth() {return(options[3]==TRUE);}
int rprla() {double ex, wy; /* complex logarithm */
if (plev>=HMAX) return;
ex = thestack[plev][0];
wy = thestack[plev][1];
thestack[plev][0] = 0.5*log(ex*ex+wy*wy+0.01);
thestack[plev][1] = atan2(wy,ex);
}
void roplc() {cgrad = r_dblpar;} /* square multiplier */
void roplf() {
thestack[plev][0] *= r_dblpar;
thestack[plev][1] *= r_dblpar;
}
void roplg() {double ex, wy;
if (plev>=HMAX) return;
ex = gmulp*thestack[plev][0];
wy = gmulp*thestack[plev][1];
PSlineto(ex+exoff,wy+wyoff);
}
void roplh() {} /* halve step */
int rprli() {double ex, wy, rr, ss; /* 1/10 integer? */
ex = thestack[plev][0];
wy = thestack[plev][1];
rr = gmulp*sqrt(ex*ex+wy*wy);
ss = (double)((int)rr);
return (rr>ss-0.01 && rr<ss+0.01);
}
void roplj() {thestack[plev][1] = -thestack[plev][1];} /* complex conjugate */
int rprll() {int c; /* pushdown accounting */
c = *r_pc++;
if (c >= '0' && c <= '9')
{if (c-'0' > pudo) return FALSE; else return TRUE;}
else if (c == '+') {pudo++; return TRUE;}
else if (c == '-') {pudo--; return TRUE;}
else if (c == 'z') {pudo = 0; return TRUE;}
else return TRUE;
}
void roplm() {qsize = r_dblpar;} /* square multiplier */
void ropln() { /* negate */
thestack[plev][0] = -thestack[plev][0];
thestack[plev][1] = -thestack[plev][1];
}
void roplo() {}
void roplp() {if (plev<1) return; plev--;} /* pop pushdown list */
void roplq() { /* show a colored rectangle */
double ex, wy, eu, ve, rr, th;
int c;
if (plev < 1) return;
eu = thestack[plev][0];
ve = thestack[plev][1];
ex = thestack[plev-1][0];
wy = thestack[plev-1][1];
PSstroke();
c = *r_pc++;
switch (c) {
case 'l': /* logarithmic absolute value */
rr = 0.5*log(eu*eu + ve*ve + 1.0);
th = atan2(ve,eu);
PSsetcmykcolor(cos(th),cos(th+2.1),cos(th+4.2),0.1*rr);
break;
case 'v': /* colored by absolute value */
th = 6.28*tanh(cgrad*(eu*eu + ve*ve));
rr = 0.1*atan2(ve,eu);
PSsetcmykcolor(0.67*cos(th+0.5),cos(th+1.8),cos(th+4.3),0.45*rr);
break;
case 'a': /* colored by phase angle */
rr = tanh(0.5*(eu*eu + ve*ve));
th = atan2(ve,eu);
PSsetcmykcolor(0.67*cos(th+0.2),cos(th+1.8),cos(th+4.3),0.45*rr);
break;
case 'r': PSsetrgbcolor(1.0,0.0,0.0); break;
case 'g': PSsetrgbcolor(0.0,1.0,0.0); break;
case 'b': PSsetrgbcolor(0.0,0.0,1.0); break;
case 'k': PSsetgray(NX_BLACK); break;
case 'c': PSsetcmykcolor(1.0,0.0,0.0,0.0); break;
case 'm': PSsetcmykcolor(0.0,1.0,0.0,0.0); break;
case 'y': PSsetcmykcolor(0.0,0.0,1.0,0.0); break;
default: PSsetgray(NX_BLACK); break;}
PSrectfill(gmulp*ex+exoff,gmulp*wy+wyoff,qsize,qsize);
}
void roplr() {double ex, wy, eu, ve, rr; /* complex square root*/
ex = thestack[plev][0];
wy = thestack[plev][1];
rr = sqrt(ex*ex+wy*wy);
eu = 0.5*(rr + ex);
ve = 0.5*(rr - ex);
thestack[plev][0] = sqrt(eu);
thestack[plev][1] = (wy>=0.0)? sqrt(ve): -sqrt(ve);
}
void ropls() {double ex, wy, eu, ve, rr, th; /* stereo colored squarelet */
if (plev < 1) return;
eu = thestack[plev][0];
ve = thestack[plev][1];
ex = gmulp*thestack[plev-1][0];
wy = gmulp*thestack[plev-1][1];
rr = 0.5*log(eu*eu + ve*ve + 1.0);
th = atan2(ve,eu);
PSsetcmykcolor(cos(th),cos(th+2.1),cos(th+4.2),0.1*rr);
PSrectfill(ex+exoff-2.0*rr-95.0,wy+wyoff,0.90,0.90);
PSrectfill(ex+exoff+2.0*rr+95.0,wy+wyoff,0.90,0.90);
}
void roplu() { /* push 0.1 */
if (plev>=HMAX) return;
plev++;
thestack[plev][0]=0.1;
thestack[plev][1]=0.0;
}
void roplv() { /* push 0.1 i */
if (plev>=HMAX) return;
plev++;
thestack[plev][0]=0.0;
thestack[plev][1]=0.1;
}
void roplx() { /* push 0.01 */
if (plev>=HMAX) return;
plev++;
thestack[plev][0]=0.025;
thestack[plev][1]=0.00;
}
void roply() { /* push 0.01 i */
if (plev>=HMAX) return;
plev++;
thestack[plev][0]=0.00;
thestack[plev][1]=0.025;
}
void roplz() {double eks, wye; /* draw circle */
PSstroke();
eks = gmulp*thestack[plev][0];
wye = gmulp*thestack[plev][1];
PSsetgray(NX_BLACK);
PSmoveto(eks+4.0,wye);
PSarc(eks, wye, 4.0, 0.0, 360.0);
PSmoveto(eks,wye);
PSstroke();
}
// -------------------------------
int rprua() {double ex, wy, th; /* is angle a multiple of 90 degrees?*/
ex = thestack[plev][0];
wy = thestack[plev][1];
th = atan2(wy,ex);
}
void ropub() {}
void ropuc() {double ex, wy; /* hyperbolic cosine */
if (plev>=HMAX) return;
ex = 0.5*thestack[plev][0];
wy = 0.5*thestack[plev][1];
thestack[plev][0] = cosh(ex)*cos(wy);
thestack[plev][1] = sinh(ex)*sin(wy);
}
void ropue() {double ex, wy, rr; /* complex exponential */
ex = thestack[plev][0];
wy = thestack[plev][1];
rr = exp(ex);
thestack[plev][0] = rr*cos(wy);
thestack[plev][1] = rr*sin(wy);
}
void ropuf() {double ex, wy, dd; /* (z+1)/(z-1) */
ex = thestack[plev][0];
wy = thestack[plev][1];
dd = ex*ex + wy*wy - 2.0*ex + 1.001;
thestack[plev][0] = (ex*ex+wy*wy-1.0)/dd;
thestack[plev][1] = -(2.0*wy)/dd;
}
void ropug() {double ex, wy; /* set up initial point of a line */
if (plev>=HMAX) return;
ex = gmulp*thestack[plev][0];
wy = gmulp*thestack[plev][1];
PSmoveto(ex+exoff,wy+wyoff);
}
void ropuh() {} /* double step */
int rprui() {double ex, wy, rr, ss; /* integer? */
ex = thestack[plev][0];
wy = thestack[plev][1];
rr = sqrt(ex*ex+wy*wy);
ss = (double)((int)rr);
return (rr>ss-0.01 && rr<ss+0.01);
}
void ropuk() {}
void ropul() {double ex, wy; /* complex logarithm */
ex = thestack[plev][0];
wy = thestack[plev][1];
thestack[plev][0] = 0.5*log(ex*ex+wy*wy+0.01);
thestack[plev][1] = atan2(wy,ex);
}
void ropum() {gmulp = r_dblpar;} /* set graphing scale */
void ropun() {} /* reflect in next edge */
void ropuo() {}
void ropup() { /* push top of stack */
if (plev>=HMAX) return;
plev++;
thestack[plev][0]=thestack[plev-1][0];
thestack[plev][1]=thestack[plev-1][1];
}
void ropuq() {double ex, wy; int c; /* show a colored rectangle */
c = *r_pc++;
switch (c) {
case 'r': PSsetrgbcolor(1.0,0.0,0.0); break;
case 'g': PSsetrgbcolor(0.0,1.0,0.0); break;
case 'b': PSsetrgbcolor(0.0,0.0,1.0); break;
case 'k': PSsetgray(NX_BLACK); break;
case 'c': PSsetcmykcolor(1.0,0.0,0.0,0.0); break;
case 'm': PSsetcmykcolor(0.0,1.0,0.0,0.0); break;
case 'y': PSsetcmykcolor(0.0,0.0,1.0,0.0); break;
default: PSsetgray(NX_BLACK); break;}
ex = thestack[plev][0];
wy = thestack[plev][1];
PSrectfill(gmulp*ex+exoff,gmulp*wy+wyoff,qsize,qsize);
}
void ropur() {int n; /* recover constant # n */
if (plev>=HMAX) return;
plev++;
n = *r_pc++-'0';
if (n<0 || n>10) return;
thestack[plev][0] = constant[n][0];
thestack[plev][1] = constant[n][1];
}
void ropus() {int n; /* save constant # n */
n = *r_pc++-'0';
if (n<0 || n>10) return;
constant[n][0] = thestack[plev][0];
constant[n][1] = thestack[plev][1];
}
void roput() {}
void ropuu() {}
void ropux() { /* push 1 */
if (plev>=HMAX) return;
plev++;
thestack[plev][0]=1.0;
thestack[plev][1]=0.0;
}
void ropuy() { /* push i */
if (plev>=HMAX) return;
plev++;
thestack[plev][0]=0.0;
thestack[plev][1]=1.0;
}
void ropuz() { /* push 0 */
if (plev>=HMAX) return;
plev++;
thestack[plev][0]=0.0;
thestack[plev][1]=0.0;
}
/* ------------ */
void ropqm() {}
void roppl() {
if (plev < 1) return;
thestack[plev-1][0] = thestack[plev-1][0] + thestack[plev][0];
thestack[plev-1][1] = thestack[plev-1][1] + thestack[plev][1];
plev--;
}
void ropmi() {
if (plev < 1) return;
thestack[plev-1][0] = thestack[plev-1][0] - thestack[plev][0];
thestack[plev-1][1] = thestack[plev-1][1] - thestack[plev][1];
plev--;
}
void ropti() {double re, im;
if (plev < 1) return;
re = thestack[plev-1][0]*thestack[plev][0] -
thestack[plev-1][1]*thestack[plev][1];
im = thestack[plev-1][0]*thestack[plev][1] +
thestack[plev-1][1]*thestack[plev][0];
thestack[plev-1][0] = re;
thestack[plev-1][1] = im;
plev--;
}
void ropdi() {double ex, wy, rr, re, im;
if (plev < 1) return;
ex = thestack[plev][0];
wy = thestack[plev][1];
rr = ex*ex+wy*wy;
if (rr < 0.00001) rr = 0.0001;
re = thestack[plev-1][0]*thestack[plev][0] +
thestack[plev-1][1]*thestack[plev][1];
im = - thestack[plev-1][0]*thestack[plev][1] +
thestack[plev-1][1]*thestack[plev][0];
thestack[plev-1][0] = re/rr;
thestack[plev-1][1] = im/rr;
plev--;
}
int rprns() {return (int)(random()&01);} /* random 1/2 pred */
int rprps() {return random()%10==1;} /* random 1/10 pred */
void ropam() {double xx; /* exchange top of stack */
if (plev>=HMAX) return;
if (plev < 1) return;
xx = thestack[plev-1][0];
thestack[plev-1][0]=thestack[plev][0];
thestack[plev][0]=xx;
xx = thestack[plev-1][1];
thestack[plev-1][1]=thestack[plev][1];
thestack[plev][1]=xx;
}