BSD 4_3 release
[unix-history] / usr / src / usr.bin / lex / sub2.c
#ifndef lint
static char sccsid[] = "@(#)sub2.c 4.1 (Berkeley) 8/11/83";
#endif
# include "ldefs.c"
cfoll(v)
int v;
{
register int i,j,k;
char *p;
i = name[v];
if(i < NCH) i = 1; /* character */
switch(i){
case 1: case RSTR: case RCCL: case RNCCL: case RNULLS:
for(j=0;j<tptr;j++)
tmpstat[j] = FALSE;
count = 0;
follow(v);
# ifdef PP
padd(foll,v); /* packing version */
# endif
# ifndef PP
add(foll,v); /* no packing version */
# endif
if(i == RSTR) cfoll(left[v]);
else if(i == RCCL || i == RNCCL){ /* compress ccl list */
for(j=1; j<NCH;j++)
symbol[j] = (i==RNCCL);
p = left[v];
while(*p)
symbol[*p++] = (i == RCCL);
p = pcptr;
for(j=1;j<NCH;j++)
if(symbol[j]){
for(k=0;p+k < pcptr; k++)
if(cindex[j] == *(p+k))
break;
if(p+k >= pcptr)*pcptr++ = cindex[j];
}
*pcptr++ = 0;
if(pcptr > pchar + pchlen)
error("Too many packed character classes");
left[v] = p;
name[v] = RCCL; /* RNCCL eliminated */
# ifdef DEBUG
if(debug && *p){
printf("ccl %d: %d",v,*p++);
while(*p)
printf(", %d",*p++);
putchar('\n');
}
# endif
}
break;
case CARAT:
cfoll(left[v]);
break;
case STAR: case PLUS: case QUEST: case RSCON:
cfoll(left[v]);
break;
case BAR: case RCAT: case DIV: case RNEWE:
cfoll(left[v]);
cfoll(right[v]);
break;
# ifdef DEBUG
case FINAL:
case S1FINAL:
case S2FINAL:
break;
default:
warning("bad switch cfoll %d",v);
# endif
}
return;
}
# ifdef DEBUG
pfoll()
{
register int i,k,*p;
int j;
/* print sets of chars which may follow positions */
printf("pos\tchars\n");
for(i=0;i<tptr;i++)
if(p=foll[i]){
j = *p++;
if(j >= 1){
printf("%d:\t%d",i,*p++);
for(k=2;k<=j;k++)
printf(", %d",*p++);
putchar('\n');
}
}
return;
}
# endif
add(array,n)
int **array;
int n; {
register int i, *temp;
register char *ctemp;
temp = nxtpos;
ctemp = tmpstat;
array[n] = nxtpos; /* note no packing is done in positions */
*temp++ = count;
for(i=0;i<tptr;i++)
if(ctemp[i] == TRUE)
*temp++ = i;
nxtpos = temp;
if(nxtpos >= positions+maxpos)
error("Too many positions %s",(maxpos== MAXPOS?"\nTry using %p num":""));
return;
}
follow(v)
int v;
{
register int p;
if(v >= tptr-1)return;
p = parent[v];
if(p == 0) return;
switch(name[p]){
/* will not be CHAR RNULLS FINAL S1FINAL S2FINAL RCCL RNCCL */
case RSTR:
if(tmpstat[p] == FALSE){
count++;
tmpstat[p] = TRUE;
}
break;
case STAR: case PLUS:
first(v);
follow(p);
break;
case BAR: case QUEST: case RNEWE:
follow(p);
break;
case RCAT: case DIV:
if(v == left[p]){
if(nullstr[right[p]])
follow(p);
first(right[p]);
}
else follow(p);
break;
case RSCON: case CARAT:
follow(p);
break;
# ifdef DEBUG
default:
warning("bad switch follow %d",p);
# endif
}
return;
}
first(v) /* calculate set of positions with v as root which can be active initially */
int v; {
register int i;
register char *p;
i = name[v];
if(i < NCH)i = 1;
switch(i){
case 1: case RCCL: case RNCCL: case RNULLS: case FINAL: case S1FINAL: case S2FINAL:
if(tmpstat[v] == FALSE){
count++;
tmpstat[v] = TRUE;
}
break;
case BAR: case RNEWE:
first(left[v]);
first(right[v]);
break;
case CARAT:
if(stnum % 2 == 1)
first(left[v]);
break;
case RSCON:
i = stnum/2 +1;
p = right[v];
while(*p)
if(*p++ == i){
first(left[v]);
break;
}
break;
case STAR: case QUEST: case PLUS: case RSTR:
first(left[v]);
break;
case RCAT: case DIV:
first(left[v]);
if(nullstr[left[v]])
first(right[v]);
break;
# ifdef DEBUG
default:
warning("bad switch first %d",v);
# endif
}
return;
}
cgoto(){
register int i, j, s;
int npos, curpos, n;
int tryit;
char tch[NCH];
int tst[NCH];
char *q;
/* generate initial state, for each start condition */
if(ratfor){
fprintf(fout,"blockdata\n");
fprintf(fout,"common /Lvstop/ vstop\n");
fprintf(fout,"define Svstop %d\n",nstates+1);
fprintf(fout,"integer vstop(Svstop)\n");
}
else fprintf(fout,"int yyvstop[] ={\n0,\n");
while(stnum < 2 || stnum/2 < sptr){
for(i = 0; i<tptr; i++) tmpstat[i] = 0;
count = 0;
if(tptr > 0)first(tptr-1);
add(state,stnum);
# ifdef DEBUG
if(debug){
if(stnum > 1)
printf("%s:\n",sname[stnum/2]);
pstate(stnum);
}
# endif
stnum++;
}
stnum--;
/* even stnum = might not be at line begin */
/* odd stnum = must be at line begin */
/* even states can occur anywhere, odd states only at line begin */
for(s = 0; s <= stnum; s++){
tryit = FALSE;
cpackflg[s] = FALSE;
sfall[s] = -1;
acompute(s);
for(i=0;i<NCH;i++) symbol[i] = 0;
npos = *state[s];
for(i = 1; i<=npos; i++){
curpos = *(state[s]+i);
if(name[curpos] < NCH) symbol[name[curpos]] = TRUE;
else switch(name[curpos]){
case RCCL:
tryit = TRUE;
q = left[curpos];
while(*q){
for(j=1;j<NCH;j++)
if(cindex[j] == *q)
symbol[j] = TRUE;
q++;
}
break;
case RSTR:
symbol[right[curpos]] = TRUE;
break;
# ifdef DEBUG
case RNULLS:
case FINAL:
case S1FINAL:
case S2FINAL:
break;
default:
warning("bad switch cgoto %d state %d",curpos,s);
break;
# endif
}
}
# ifdef DEBUG
if(debug){
printf("State %d transitions on:\n\t",s);
charc = 0;
for(i = 1; i<NCH; i++){
if(symbol[i]) allprint(i);
if(charc > LINESIZE){
charc = 0;
printf("\n\t");
}
}
putchar('\n');
}
# endif
/* for each char, calculate next state */
n = 0;
for(i = 1; i<NCH; i++){
if(symbol[i]){
nextstate(s,i); /* executed for each state, transition pair */
xstate = notin(stnum);
if(xstate == -2) warning("bad state %d %o",s,i);
else if(xstate == -1){
if(stnum >= nstates)
error("Too many states %s",(nstates == NSTATES ? "\nTry using %n num":""));
add(state,++stnum);
# ifdef DEBUG
if(debug)pstate(stnum);
# endif
tch[n] = i;
tst[n++] = stnum;
}
else { /* xstate >= 0 ==> state exists */
tch[n] = i;
tst[n++] = xstate;
}
}
}
tch[n] = 0;
tst[n] = -1;
/* pack transitions into permanent array */
if(n > 0) packtrans(s,tch,tst,n,tryit);
else gotof[s] = -1;
}
ratfor ? fprintf(fout,"end\n") : fprintf(fout,"0};\n");
return;
}
/* Beware -- 70% of total CPU time is spent in this subroutine -
if you don't believe me - try it yourself ! */
nextstate(s,c)
int s,c; {
register int j, *newpos;
register char *temp, *tz;
int *pos, i, *f, num, curpos, number;
/* state to goto from state s on char c */
num = *state[s];
temp = tmpstat;
pos = state[s] + 1;
for(i = 0; i<num; i++){
curpos = *pos++;
j = name[curpos];
if(j < NCH && j == c
|| j == RSTR && c == right[curpos]
|| j == RCCL && member(c,left[curpos])){
f = foll[curpos];
number = *f;
newpos = f+1;
for(j=0;j<number;j++)
temp[*newpos++] = 2;
}
}
j = 0;
tz = temp + tptr;
while(temp < tz){
if(*temp == 2){
j++;
*temp++ = 1;
}
else *temp++ = 0;
}
count = j;
return;
}
notin(n)
int n; { /* see if tmpstat occurs previously */
register int *j,k;
register char *temp;
int i;
if(count == 0)
return(-2);
temp = tmpstat;
for(i=n;i>=0;i--){ /* for each state */
j = state[i];
if(count == *j++){
for(k=0;k<count;k++)
if(!temp[*j++])break;
if(k >= count)
return(i);
}
}
return(-1);
}
packtrans(st,tch,tst,cnt,tryit)
int st, *tst, cnt,tryit;
char *tch; {
/* pack transitions into nchar, nexts */
/* nchar is terminated by '\0', nexts uses cnt, followed by elements */
/* gotof[st] = index into nchr, nexts for state st */
/* sfall[st] = t implies t is fall back state for st */
/* == -1 implies no fall back */
int cmin, cval, tcnt, diff, p, *ast;
register int i,j,k;
char *ach;
int go[NCH], temp[NCH], c;
int swork[NCH];
char cwork[NCH];
int upper;
rcount += cnt;
cmin = -1;
cval = NCH;
ast = tst;
ach = tch;
/* try to pack transitions using ccl's */
if(!optim)goto nopack; /* skip all compaction */
if(tryit){ /* ccl's used */
for(i=1;i<NCH;i++){
go[i] = temp[i] = -1;
symbol[i] = 1;
}
for(i=0;i<cnt;i++){
go[tch[i]] = tst[i];
symbol[tch[i]] = 0;
}
for(i=0; i<cnt;i++){
c = match[tch[i]];
if(go[c] != tst[i] || c == tch[i])
temp[tch[i]] = tst[i];
}
/* fill in error entries */
for(i=1;i<NCH;i++)
if(symbol[i]) temp[i] = -2; /* error trans */
/* count them */
k = 0;
for(i=1;i<NCH;i++)
if(temp[i] != -1)k++;
if(k <cnt){ /* compress by char */
# ifdef DEBUG
if(debug) printf("use compression %d, %d vs %d\n",st,k,cnt);
# endif
k = 0;
for(i=1;i<NCH;i++)
if(temp[i] != -1){
cwork[k] = i;
swork[k++] = (temp[i] == -2 ? -1 : temp[i]);
}
cwork[k] = 0;
# ifdef PC
ach = cwork;
ast = swork;
cnt = k;
cpackflg[st] = TRUE;
# endif
}
}
for(i=0; i<st; i++){ /* get most similar state */
/* reject state with more transitions, state already represented by a third state,
and state which is compressed by char if ours is not to be */
if(sfall[i] != -1) continue;
if(cpackflg[st] == 1) if(!(cpackflg[i] == 1)) continue;
p = gotof[i];
if(p == -1) /* no transitions */ continue;
tcnt = nexts[p];
if(tcnt > cnt) continue;
diff = 0;
k = 0;
j = 0;
upper = p + tcnt;
while(ach[j] && p < upper){
while(ach[j] < nchar[p] && ach[j]){diff++; j++; }
if(ach[j] == 0)break;
if(ach[j] > nchar[p]){diff=NCH;break;}
/* ach[j] == nchar[p] */
if(ast[j] != nexts[++p] || ast[j] == -1 || (cpackflg[st] && ach[j] != match[ach[j]]))diff++;
j++;
}
while(ach[j]){
diff++;
j++;
}
if(p < upper)diff = NCH;
if(diff < cval && diff < tcnt){
cval = diff;
cmin = i;
if(cval == 0)break;
}
}
/* cmin = state "most like" state st */
# ifdef DEBUG
if(debug)printf("select st %d for st %d diff %d\n",cmin,st,cval);
# endif
# ifdef PS
if(cmin != -1){ /* if we can use st cmin */
gotof[st] = nptr;
k = 0;
sfall[st] = cmin;
p = gotof[cmin]+1;
j = 0;
while(ach[j]){
/* if cmin has a transition on c, then so will st */
/* st may be "larger" than cmin, however */
while(ach[j] < nchar[p-1] && ach[j]){
k++;
nchar[nptr] = ach[j];
nexts[++nptr] = ast[j];
j++;
}
if(nchar[p-1] == 0)break;
if(ach[j] > nchar[p-1]){
warning("bad transition %d %d",st,cmin);
goto nopack;
}
/* ach[j] == nchar[p-1] */
if(ast[j] != nexts[p] || ast[j] == -1 || (cpackflg[st] && ach[j] != match[ach[j]])){
k++;
nchar[nptr] = ach[j];
nexts[++nptr] = ast[j];
}
p++;
j++;
}
while(ach[j]){
nchar[nptr] = ach[j];
nexts[++nptr] = ast[j++];
k++;
}
nexts[gotof[st]] = cnt = k;
nchar[nptr++] = 0;
}
else {
# endif
nopack:
/* stick it in */
gotof[st] = nptr;
nexts[nptr] = cnt;
for(i=0;i<cnt;i++){
nchar[nptr] = ach[i];
nexts[++nptr] = ast[i];
}
nchar[nptr++] = 0;
# ifdef PS
}
# endif
if(cnt < 1){
gotof[st] = -1;
nptr--;
}
else
if(nptr > ntrans)
error("Too many transitions %s",(ntrans==NTRANS?"\nTry using %a num":""));
return;
}
# ifdef DEBUG
pstate(s)
int s; {
register int *p,i,j;
printf("State %d:\n",s);
p = state[s];
i = *p++;
if(i == 0) return;
printf("%4d",*p++);
for(j = 1; j<i; j++){
printf(", %4d",*p++);
if(j%30 == 0)putchar('\n');
}
putchar('\n');
return;
}
# endif
member(d,t)
int d;
char *t; {
register int c;
register char *s;
c = d;
s = t;
c = cindex[c];
while(*s)
if(*s++ == c) return(1);
return(0);
}
# ifdef DEBUG
stprt(i)
int i; {
register int p, t;
printf("State %d:",i);
/* print actions, if any */
t = atable[i];
if(t != -1)printf(" final");
putchar('\n');
if(cpackflg[i] == TRUE)printf("backup char in use\n");
if(sfall[i] != -1)printf("fall back state %d\n",sfall[i]);
p = gotof[i];
if(p == -1) return;
printf("(%d transitions)\n",nexts[p]);
while(nchar[p]){
charc = 0;
if(nexts[p+1] >= 0)
printf("%d\t",nexts[p+1]);
else printf("err\t");
allprint(nchar[p++]);
while(nexts[p] == nexts[p+1] && nchar[p]){
if(charc > LINESIZE){
charc = 0;
printf("\n\t");
}
allprint(nchar[p++]);
}
putchar('\n');
}
putchar('\n');
return;
}
# endif
acompute(s) /* compute action list = set of poss. actions */
int s; {
register int *p, i, j;
int cnt, m;
int temp[300], k, neg[300], n;
k = 0;
n = 0;
p = state[s];
cnt = *p++;
if(cnt > 300)
error("Too many positions for one state - acompute");
for(i=0;i<cnt;i++){
if(name[*p] == FINAL)temp[k++] = left[*p];
else if(name[*p] == S1FINAL){temp[k++] = left[*p];
if (left[*p] >NACTIONS) error("Too many right contexts");
extra[left[*p]] = 1;
}
else if(name[*p] == S2FINAL)neg[n++] = left[*p];
p++;
}
atable[s] = -1;
if(k < 1 && n < 1) return;
# ifdef DEBUG
if(debug) printf("final %d actions:",s);
# endif
/* sort action list */
for(i=0; i<k; i++)
for(j=i+1;j<k;j++)
if(temp[j] < temp[i]){
m = temp[j];
temp[j] = temp[i];
temp[i] = m;
}
/* remove dups */
for(i=0;i<k-1;i++)
if(temp[i] == temp[i+1]) temp[i] = 0;
/* copy to permanent quarters */
atable[s] = aptr;
# ifdef DEBUG
if(!ratfor)fprintf(fout,"/* actions for state %d */",s);
# endif
putc('\n',fout);
for(i=0;i<k;i++)
if(temp[i] != 0){
ratfor ? fprintf(fout,"data vstop(%d)/%d/\n",aptr,temp[i]) : fprintf(fout,"%d,\n",temp[i]);
# ifdef DEBUG
if(debug)
printf("%d ",temp[i]);
# endif
aptr++;
}
for(i=0;i<n;i++){ /* copy fall back actions - all neg */
ratfor ? fprintf(fout,"data vstop(%d)/%d/\n",aptr,neg[i]) : fprintf(fout,"%d,\n",neg[i]);
aptr++;
# ifdef DEBUG
if(debug)printf("%d ",neg[i]);
# endif
}
# ifdef DEBUG
if(debug)putchar('\n');
# endif
ratfor ? fprintf(fout,"data vstop (%d)/0/\n",aptr) : fprintf(fout,"0,\n");
aptr++;
return;
}
# ifdef DEBUG
pccl() {
/* print character class sets */
register int i, j;
printf("char class intersection\n");
for(i=0; i< ccount; i++){
charc = 0;
printf("class %d:\n\t",i);
for(j=1;j<NCH;j++)
if(cindex[j] == i){
allprint(j);
if(charc > LINESIZE){
printf("\n\t");
charc = 0;
}
}
putchar('\n');
}
charc = 0;
printf("match:\n");
for(i=0;i<NCH;i++){
allprint(match[i]);
if(charc > LINESIZE){
putchar('\n');
charc = 0;
}
}
putchar('\n');
return;
}
# endif
mkmatch(){
register int i;
char tab[NCH];
for(i=0; i<ccount; i++)
tab[i] = 0;
for(i=1;i<NCH;i++)
if(tab[cindex[i]] == 0)
tab[cindex[i]] = i;
/* tab[i] = principal char for new ccl i */
for(i = 1; i<NCH; i++)
match[i] = tab[cindex[i]];
return;
}
layout(){
/* format and output final program's tables */
register int i, j, k;
int top, bot, startup, omin;
startup = 0;
for(i=0; i<outsize;i++)
verify[i] = advance[i] = 0;
omin = 0;
yytop = 0;
for(i=0; i<= stnum; i++){ /* for each state */
j = gotof[i];
if(j == -1){
stoff[i] = 0;
continue;
}
bot = j;
while(nchar[j])j++;
top = j - 1;
# if DEBUG
if (debug)
{
printf("State %d: (layout)\n", i);
for(j=bot; j<=top;j++)
{
printf(" %o", nchar[j]);
if (j%10==0) putchar('\n');
}
putchar('\n');
}
# endif
while(verify[omin+ZCH]) omin++;
startup = omin;
# if DEBUG
if (debug) printf("bot,top %d, %d startup begins %d\n",bot,top,startup);
# endif
if(chset){
do {
++startup;
if(startup > outsize - ZCH)
error("output table overflow");
for(j = bot; j<= top; j++){
k=startup+ctable[nchar[j]];
if(verify[k])break;
}
} while (j <= top);
# if DEBUG
if (debug) printf(" startup will be %d\n",startup);
# endif
/* have found place */
for(j = bot; j<= top; j++){
k = startup + ctable[nchar[j]];
if (ctable[nchar[j]]<=0)
printf("j %d nchar %d ctable.nch %d\n",j,nchar[j],ctable[nchar[k]]);
verify[k] = i+1; /* state number + 1*/
advance[k] = nexts[j+1]+1; /* state number + 1*/
if(yytop < k) yytop = k;
}
}
else {
do {
++startup;
if(startup > outsize - ZCH)
error("output table overflow");
for(j = bot; j<= top; j++){
k = startup + nchar[j];
if(verify[k])break;
}
} while (j <= top);
/* have found place */
# if DEBUG
if (debug) printf(" startup going to be %d\n", startup);
# endif
for(j = bot; j<= top; j++){
k = startup + nchar[j];
verify[k] = i+1; /* state number + 1*/
advance[k] = nexts[j+1]+1; /* state number + 1*/
if(yytop < k) yytop = k;
}
}
stoff[i] = startup;
}
/* stoff[i] = offset into verify, advance for trans for state i */
/* put out yywork */
if(ratfor){
fprintf(fout, "define YYTOPVAL %d\n", yytop);
rprint(verify,"verif",yytop+1);
rprint(advance,"advan",yytop+1);
shiftr(stoff, stnum);
rprint(stoff,"stoff",stnum+1);
shiftr(sfall, stnum); upone(sfall, stnum+1);
rprint(sfall,"sfall",stnum+1);
bprint(extra,"extra",casecount+1);
bprint(match,"match",NCH);
shiftr(atable, stnum);
rprint(atable,"atable",stnum+1);
return;
}
fprintf(fout,"# define YYTYPE %s\n",stnum+1 > NCH ? "int" : "char");
fprintf(fout,"struct yywork { YYTYPE verify, advance; } yycrank[] ={\n");
for(i=0;i<=yytop;i+=4){
for(j=0;j<4;j++){
k = i+j;
if(verify[k])
fprintf(fout,"%d,%d,\t",verify[k],advance[k]);
else
fprintf(fout,"0,0,\t");
}
putc('\n',fout);
}
fprintf(fout,"0,0};\n");
/* put out yysvec */
fprintf(fout,"struct yysvf yysvec[] ={\n");
fprintf(fout,"0,\t0,\t0,\n");
for(i=0;i<=stnum;i++){ /* for each state */
if(cpackflg[i])stoff[i] = -stoff[i];
fprintf(fout,"yycrank+%d,\t",stoff[i]);
if(sfall[i] != -1)
fprintf(fout,"yysvec+%d,\t", sfall[i]+1); /* state + 1 */
else fprintf(fout,"0,\t\t");
if(atable[i] != -1)
fprintf(fout,"yyvstop+%d,",atable[i]);
else fprintf(fout,"0,\t");
# ifdef DEBUG
fprintf(fout,"\t\t/* state %d */",i);
# endif
putc('\n',fout);
}
fprintf(fout,"0,\t0,\t0};\n");
/* put out yymatch */
fprintf(fout,"struct yywork *yytop = yycrank+%d;\n",yytop);
fprintf(fout,"struct yysvf *yybgin = yysvec+1;\n");
if(optim){
fprintf(fout,"char yymatch[] ={\n");
if (chset==0) /* no chset, put out in normal order */
{
for(i=0; i<NCH; i+=8){
for(j=0; j<8; j++){
int fbch;
fbch = match[i+j];
if(printable(fbch) && fbch != '\'' && fbch != '\\')
fprintf(fout,"'%c' ,",fbch);
else fprintf(fout,"0%-3o,",fbch);
}
putc('\n',fout);
}
}
else
{
int *fbarr;
fbarr = myalloc(2*NCH, sizeof(*fbarr));
if (fbarr==0)
error("No space for char table reverse",0);
for(i=0; i<ZCH; i++)
fbarr[i]=0;
for(i=0; i<NCH; i++)
fbarr[ctable[i]] = ctable[match[i]];
for(i=0; i<ZCH; i+=8)
{
for(j=0; j<8; j++)
fprintf(fout, "0%-3o,",fbarr[i+j]);
putc('\n',fout);
}
cfree(fbarr, 2*NCH, 1);
}
fprintf(fout,"0};\n");
}
/* put out yyextra */
fprintf(fout,"char yyextra[] ={\n");
for(i=0;i<casecount;i+=8){
for(j=0;j<8;j++)
fprintf(fout, "%d,", i+j<NACTIONS ?
extra[i+j] : 0);
putc('\n',fout);
}
fprintf(fout,"0};\n");
return;
}
rprint(a,s,n)
char *s;
int *a, n; {
register int i;
fprintf(fout,"block data\n");
fprintf(fout,"common /L%s/ %s\n",s,s);
fprintf(fout,"define S%s %d\n",s,n);
fprintf(fout,"integer %s (S%s)\n",s,s);
for(i=1; i<=n; i++)
{
if (i%8==1) fprintf(fout, "data ");
fprintf(fout, "%s (%d)/%d/",s,i,a[i]);
fprintf(fout, (i%8 && i<n) ? ", " : "\n");
}
fprintf(fout,"end\n");
}
shiftr(a, n)
int *a;
{
int i;
for(i=n; i>=0; i--)
a[i+1]=a[i];
}
upone(a,n)
int *a;
{
int i;
for(i=0; i<=n ; i++)
a[i]++;
}
bprint(a,s,n)
char *s, *a;
int n; {
register int i, j, k;
fprintf(fout,"block data\n");
fprintf(fout,"common /L%s/ %s\n",s,s);
fprintf(fout,"define S%s %d\n",s,n);
fprintf(fout,"integer %s (S%s)\n",s,s);
for(i=1;i<n;i+=8){
fprintf(fout,"data %s (%d)/%d/",s,i,a[i]);
for(j=1;j<8;j++){
k = i+j;
if(k < n)fprintf(fout,", %s (%d)/%d/",s,k,a[k]);
}
putc('\n',fout);
}
fprintf(fout,"end\n");
}
# ifdef PP
padd(array,n)
int **array;
int n; {
register int i, *j, k;
array[n] = nxtpos;
if(count == 0){
*nxtpos++ = 0;
return;
}
for(i=tptr-1;i>=0;i--){
j = array[i];
if(j && *j++ == count){
for(k=0;k<count;k++)
if(!tmpstat[*j++])break;
if(k >= count){
array[n] = array[i];
return;
}
}
}
add(array,n);
return;
}
# endif