You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

470 lines
7.0 KiB

/*
C compiler, part 2
Copyright 1972 Bell Telephone Laboratories, Inc.
*/
ospace() {} /* fake */
waste() /* waste space */
{
waste(waste(waste),waste(waste),waste(waste));
waste(waste(waste),waste(waste),waste(waste));
waste(waste(waste),waste(waste),waste(waste));
waste(waste(waste),waste(waste),waste(waste));
waste(waste(waste),waste(waste),waste(waste));
waste(waste(waste),waste(waste),waste(waste));
waste(waste(waste),waste(waste),waste(waste));
waste(waste(waste),waste(waste),waste(waste));
}
main(argc, argv)
char argv[][];
{
extern fout, fin, nerror, line;
extern getwrd, rcexpr, ospace, tmpfil;
extern cctab[], regtab[], efftab[], sptab[];
int sp[], c, table[], tabtab[3][], tree;
if (argc<4) {
error("Arg count");
exit(1);
}
if((fin=open(argv[1],0))<0) {
error("Cant't find %s", argv[1]);
exit(1);
}
if((fout=creat(argv[3],017))<0) {
error("Can't create %s", argv[3]);
exit(1);
}
tmpfil = argv[2];
tabtab[0] = regtab;
tabtab[1] = efftab;
tabtab[2] = cctab;
tabtab[3] = sptab;
while(c=getchar()) {
if(c=='#') {
sp = ospace;
c = getwrd();
tree = getwrd();
table = tabtab[getwrd()];
line = getwrd();
while(c--)
*sp++ = getwrd();
rcexpr(tree, table, 0);
} else
putchar(c);
}
flush();
exit(nerror!=0);
}
match(tree, table, nreg)
int tree[], table[]; {
extern opdope[], dcalc, notcompat;
int op, d1, d2, t1, t2, p1[], p2[];
char mp[];
if (tree==0)
return(0);
op = *tree;
if (op>=29) /* if not leaf */
p1 = tree[3];
else
p1 = tree;
t1 = p1[1];
d1 = dcalc(p1, nreg);
if ((opdope[op]&01)!=0) { /* binary? */
p2 = tree[4];
t2 = p2[1];
d2 = dcalc(p2, nreg);
}
while(*table) {
if (*table++ == op) goto foundop;
table++;
}
return(0);
foundop:
table = *table;
nxtry:
mp = table;
if (*mp == 0)
return(0);
if (d1 > (*mp&077) | (*mp>=0100)&(*p1!=36))
goto notyet;
if (notcompat(t1, mp[1]))
goto notyet;
if ((opdope[op]&01)!=0 & p2!=0) {
if (d2 > (mp[2]&077) | (mp[2]>=0100)&(*p2!=36))
goto notyet;
if (notcompat(t2,mp[3]))
goto notyet;
}
now:
return(table[2]);
notyet:
table = table+3;
goto nxtry;
}
rcexpr(tree, table, reg)
int tree[]; {
extern cexpr, regtab, cctab, sptab, printf, error;
extern jumpc, cbranch;
if(tree==0)
return;
if(*tree >= 103) {
(*tree==103?jumpc:cbranch)(tree[1],tree[2],tree[3],0);
return;
}
if (cexpr(tree, table, reg))
return;
if (table!=regtab)
if(cexpr(tree, regtab, reg)) {
if (table==sptab)
printf("mov r%d,-(sp)\n", reg);
if (table==cctab)
printf("tst r%d\n", reg);
return;
}
error("No match for op %d", *tree);
}
cexpr(tree, table, reg)
int tree[][], table[]; {
extern match, nreg, printf, pname, putchar, regtab;
extern sptab, cctab, rcexpr, prins, rlength, popstk;
extern collcon, isn, label, branch, cbranch, fltmod;
int p1[], p2[], c, r, p[], otable[], ctable[], regtab[], cctab[];
char string[], match[];
if ((c = *tree)==100) { /* call */
p1 = tree[3];
p2 = tree[4];
r = 0;
if(p2) {
while (*p2==9) { /* comma */
rcexpr(p2[4], sptab, 0);
r =+ rlength((p=p2[4])[1]);
p2 = p2[3];
}
rcexpr(p2, sptab, 0);
r =+ rlength(p2[1]);
}
*tree = 101;
tree[2] = r; /* save arg length */
}
if(c==90) { /* ? */
cbranch(tree[3], c=isn++, 0, reg);
rcexpr(tree[4][3], table, reg);
branch(r=isn++, 0);
label(c);
rcexpr(tree[4][4], table, reg);
label(r);
return(1);
}
if ((string=match(tree, table, nreg-reg))==0)
return(0);
p1 = tree[3];
p2 = tree[4];
loop:
switch(c = *string++) {
case '\0':
p = tree;
if (*p==101 & p[2]>0) {
popstk(p[2]);
}
return(1);
/* A1 */
case 'A':
p = tree[3];
goto adr;
/* A2 */
case 'B':
p = tree[4];
goto adr;
/* A */
case 'O':
p = tree;
adr:
pname(p);
goto loop;
/* I */
case 'M':
if ((c = *string)=='\'')
string++; else
c = 0;
prins(*tree, c);
goto loop;
/* B1 */
case 'C':
p = tree[3];
goto pbyte;
/* BF */
case 'P':
p = tree;
goto pb1;
/* B2 */
case 'D':
p = tree[4];
pbyte:
if (p[1]==1) /* char type? */
putchar('b');
pb1:
if (isfloat(p))
putchar('f');
goto loop;
/* BE */
case 'L':
if (tree[3][1]==1 | tree[4][1]==1)
putchar('b');
goto loop;
/* C1 */
case 'E':
p = p1[3];
goto const;
/* C2 */
case 'F':
p = p2[3];
const:
printf("%o", p);
goto loop;
/* F */
case 'G':
p = p1;
goto subtre;
/* S */
case 'K':
p = p2;
goto subtre;
/* H */
case 'H':
p = tree;
subtre:
ctable = regtab;
r = reg;
c = *string++ - 'A';
if ((c&02)!=0)
ctable = sptab;
if ((c&04)!=0)
ctable = cctab;
if((c&010)!=0)
r = reg+1;
if((c&01)!=0)
if(*p==36) {
p = p[3];
if(collcon(p) & ctable!=sptab)
p = p[3];
}
rcexpr(p, ctable, r);
goto loop;
/* R */
case 'I':
r = reg;
goto preg;
/* R1 */
case 'J':
r = reg+1;
preg:
printf("r%d", r);
goto loop;
case '#':
p = p1[3];
goto nmbr;
case '"':
p = p2[3];
goto nmbr;
case '~':
p = tree[3];
nmbr:
if(collcon(p)) {
c = *p;
if(r = (p=p[4])[3])
printf("%o", c==40?r:-r);
}
goto loop;
/* M */
case 'N':
if ((c=isfloat(tree, &string))==fltmod)
goto loop;
printf((fltmod=c)==2?"setf\n":"setd\n");
goto loop;
/* Z */
case 'Z':
printf("$%o", p1[4]);
goto loop;
}
putchar(c);
goto loop;
}
pname(p)
int p[][][]; {
extern putchar, printf, error;
char np[];
int i;
loop:
switch(*p) {
case 21: /* const */
printf("$%o", p[3]);
return;
case 22: /* string */
printf("$l%d", p[3]);
return;
case 20: /* name */
switch(p[3]) {
case 5: /* auto, param */
printf("%o(r5)", p[4]);
return;
/* extern */
case 6:
printf("%p", &p[4]);
return;
}
printf("L%d", p[4]);
return;
case 35: /* & */
putchar('$');
p = p[3];
goto loop;
case 36: /* * */
putchar('*');
p = p[3];
goto loop;
}
error("pname called illegally");
}
dcalc(p, nreg)
int p[]; {
int op, t;
if (p==0)
return(0);
op = *p;
switch (op) {
case 20: /* name */
case 22: /* string */
case 23: /* float */
case 24: /* double */
return(12);
case 21: /* short constant */
return(p[3]==0? 4:8);
case 35: /* & */
return(12);
case 36: /* * */
if ((op=dcalc(p[3], nreg))<16)
return(16);
}
def:
return(p[2]<=nreg? 20: 24);
}
notcompat(at, st) {
if (st==0) /* word, byte */
return(at>1 & at<16);
if (st==1) /* word */
return(at>0 & at<16);
st =- 2;
if (st==2 & at==3)
at = 2;
return(st != at);
}
prins(op, c) {
extern instab[], printf;
int insp[];
insp = instab;
while(*insp) {
if (*insp++ == op) {
if ((c = insp[c!=0])==0)
goto err;
printf("%s", c);
return;
} else
insp = insp + 2;
}
err:
error("No match' for op %d", op);
}
collcon(p)
int p[]; {
int p1[];
if(*p==40 | *p==41)
if(*(p1=p[4])==21)
return(1);
return(0);
}
isfloat(t, s)
int t[];
char s[][];
{
extern opdope[];
int rt;
rt = **s - '0';
if (rt==2 | rt==4) {
(*s)++;
return(rt>2?3:2);
}
if ((opdope[t[0]]&010)!=0) /* relational */
t = t[3];
if ((rt=t[1])>=2 & rt<=3)
return(rt);
return(0);
}
nreg 4;
isn 10000;
namsiz 8;
line;
tmpfil;
nerror;
fltmod;